1 ArtiSynth Overview

1.1 System structure

An ArtiSynth model is composed of a hierarchy of models and model components which are implemented by various Java classes. Components are broadly divided into simulation components, which include particles, rigid bodies, springs, connectors, force effectors, individual finite elements, constraints, etc., which are gathered together into models (including finite element models), and instrumentation components such as control panels, controllers and monitors, and input and output data streams (i.e., probes), which have the ability to control and record the simulation as it advances in time. Instrumentation components are presented in more detail in Chapter 5.

Every ArtiSynth component is an instance of ModelComponent, while components that contain subcomponents are instances of CompositeComponent. A ComponentList is a CompositeComponent which contains a list of other components of a specific type (such as particles, rigid bodies, springs, etc.).

All models and instrumentation components are collected together within a top-level container known as a root model. Simulation proceeds under the control of a scheduler, which advances the models through time using a physics simulator. A graphical user interface (GUI) allows users to view and edit the model hierarchy, modify component properties, and edit and temporally arrange the input and output probes using a timeline display.

1.1.1 Simulation components

Simulation components are those used to build a model or set of models to be simulated. They are roughly divided into the following categories:

Dynamic components


Components, such as particles and rigid bodies, that contain position and velocity state, and possibly mass. At present, dynamic components consist of Point, Frame, and their subclasses. All dynamic components implement the Java interface DynamicComponent.

Force effectors


Components, such as springs or finite elements, that exert forces between dynamic components. All force effectors implement the Java interface ForceEffector. Dynamic components are themselves also instances of ForceEffector, since they can exert velocity-based damping forces on themselves.

Constrainers


Components that enforce constraints between dynamic components. All constrainers implement the Java interface Constrainer.

Attachments


Components that can attach one dynamic component to another (see Section 1.2.4). While attachments are in principle the same as constraints, they are implemented using a different approach. All attachment components implement the Java interface DynamicAttachment.

Markers


Subclasses of dynamic components which are always attached to other dynamic components and contain the relevant attachment component internally. All currently implemented markers are subclasses of Marker (attached points) and AttachedFrame (attached frames).

Visual components


Components that provide graphical representation but do not actually affect the simulation. Examples of these include mesh components that are not connected to rigid bodies or FE models, and other implementations of RenderableComponent that are used for visualization only.

Models


Composite components that agglomerate simulation components into a single entity that contains state and can be advanced through time via the methods initialize(t0) and advance(t0, t1, flags), as discussed further in Section 1.2.1. All models implement the Java interface Model. The primary model types used by ArtiSynth are MechModel (Section 1.1.2), which is the primary container for a single mechanical or biomechanical model, and RootModel (Section 1.1.4), which combines one or more models together with instrumentation components to form a loadable application model.

1.1.2 The MechModel

In most ArtiSynth applications, the simulation components used to construct the model are collected under a single MechModel. This is a Model component that may contain particles, rigid bodies, FE models, constraints, attachments, various force effectors, and possibly other MechModels. When a simulation is run, the model’s advance() method invokes a physics simulator that advances these components forward in time (Section 1.2.3).

For convenience each MechModel contains a number of predefined containers for different component types, including:

container name description component type
particles 3 DOF particles dynamic
points other 3 DOF points dynamic
rigidBodies 6 DOF rigid bodies dynamic
frames other 6 DOF frames dynamic
frameMarkers points which are attached to frames marker
axialSprings point-to-point springs force
multiPointSprings point-based springs with multiple via points force
frameSprings 6 DOF springs between frames force
meshBodies 3D surface mesh objects visual
connectors joint-type connectors between bodies constrainer
constrainers general constraints constrainer
forceEffectors general force-effectors force
models FE models and other MechModels model
attachments attachments between dynamic components attachment
renderables renderable components (for visualization only) visual

Each of these is a child component of MechModel and is implemented as a ComponentList. Special methods are provided for adding and removing items from them. If not used, the containers will simply remain empty.

Applications are not required to use these containers, and may instead create any component containment structure that is appropriate, as described in Section 4.8.

1.1.3 Instrumentation components

Instrumentation components consist primarily of control panels, which provide the ability to interactively adjust properties of simulation components, and simulation agents, which are used to set inputs and monitor outputs as a simulation proceeds (Section 1.2.1). Both are described in detail in Chapter 5.

Control panels


GUI components that an application can create to interactively edit property values of simulation components. They are described in Section 5.1.

Input probes


Simulation agents that provide streams of input data to control the simulation. Such data may include external force values, muscle excitation levels, and position or velocity data for dynamic components which are being controlled parametrically. Input probes work via an apply(t) method, which is called before each simulation step to determine the value of the input data for time t and (typically) use this to set property values of simulation components associated with the probe. They are described in more detail in Section 5.4.

Controllers


Simulation agents that perform computations, based on input probe data or the state of the model, that are used to control the simulation. As with input probes, computed quantities typically include external forces, excitation levels, and positions or velocities. Computations are performed by an apply(t0,t1) method that is called before the simulation step between time t0 and t1. Controllers are often custom-defined by the application, but predefined controllers (such as the inverse tracking controller described in Chapter 10) are also available. They are described in more detail in Section 5.3.

Monitors


Simulation agents that compute simulation results, based on the state of the model. These results can be directed to an output probe, saved to a specific file, or just printed to the application console. Monitors are generally used to compute quantities that are not explicitly available as properties within the simulation components. Computations are performed by an apply(t0,t1) method that is called after the simulation step between time t0 and t1. Monitors are typically custom-defined by the application, and are described in more detail in Section 5.3.

Output probes


Simulation agents that provide streams of output data to record the results of the simulation. Such data may correspond directly to simulation component properties, or to values computed by Monitors. Common output probe data includes reaction forces, contact pressures, and the position or velocity data for dynamic components. Output probes work via an apply(t) method, which is called after a simulation step to determine and store the data for simulation time t; typically this data is determined from property values of simulation components associated with the probe. Output probes are described in more detail in Section 5.4.

1.1.4 The RootModel

The top-level component in the hierarchy is the root model, which is an application-specific subclass of RootModel and which contains a list of simulation models, along with containers for instrumentation components used to control and interact with these models. The containers in RootModel include:

container name description
models top-level simulation models of the component hierarchy
inputProbes input data streams for controlling the simulation
controllers functions for controlling the simulation
monitors functions for observing the simulation
outputProbes output data streams for observing the simulation
controlPanels application defined control panels for property editing
renderables renderable components (for visualization only)

Root models are created either by applications overriding the root model’s build() method, or by reading the model directly from a .art file (Section 1.5.3).

When a simulation is run, the root model’s advance(,,) method is used to advance the simulation forward by a single time step. This involves applying any input probes and controllers, calling the advance() method for each of the simulation models, and then applying any monitors and output probes (Section 1.2.1).

1.1.5 Component numbers, names and path names

Whenever a component is added to the component hierarchy, it is assigned a unique number relative to its parent; the parent and number can be obtained using the methods getParent() and getNumber(), respectively. Components may also be assigned a name (using setName()) which is then returned using getName().

A component’s number is not the same as its index. The index gives the component’s sequential list position within the parent, and is always in the range 0\ldots n-1, where n is the parent’s number of child components. While indices and numbers frequently are the same, they sometimes are not. For example, a component’s number is guaranteed to remain unchanged as long as it remains attached to its parent; this is different from its index, which will change if any preceding components are removed from the parent. For example, if we have a set of components with numbers

0 1 2 3 4 5

and components 2 and 4 are then removed, the remaining components will have numbers

0 1 3 5

whereas the indices will be 0 1 2 3. This consistency of numbers is why they are used to identify components.

The names and/or numbers of a component and its ancestors can be used to form a component path name. This path has a construction analogous to Unix file path names, with the ’/’ character acting as a separator. Absolute paths start with ’/’, which indicates the root model. Relative paths omit the leading ’/’ and can begin lower down in the hierarchy. A typical path name might be

  /models/JawHyoidModel/axialSprings/lad

For nameless components in the path, their numbers can be used instead. Numbers can also be used for components that have names. Hence the path above could also be represented using only numbers, as in

  /0/0/1/5

although this would most likely appear only in machine-generated output.