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.
Simulation components are those used to build a model or set of models to be simulated. They are roughly divided into the following categories:
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.
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.
Components that enforce constraints between dynamic components.
All constrainers implement the Java interface
Constrainer.
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.
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).
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.
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.
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.
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.
GUI components that an application can create to interactively edit property
values of simulation components. They are described in
Section 5.1.
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.
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.
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.
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.
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).
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
, where
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 5and components 2 and 4 are then removed, the remaining components will have numbers
0 1 3 5whereas 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.