ArtiSynth User Interface Guide

12 Jython Interaction and Scripting

ArtiSynth supports a Jython console that provides a command line interface to all the internal structures associated with ArtiSynth and its models. Jython ( www.jython.org) is a Java implementation of Python that combines Python commands and syntax with the ability to access and call all publicly accessible attributes and methods of Java objects. It can be used to interactively load, query and run models, or to run simulation scripts, either interactively (Section 12.3) or in batch mode (Section 12.6).

Use of the Jython interface currently requires that ArtiSynth is run under Java 8, which is why we recommend using this Java version. If you experience trouble running the Jython console, verify that you do in fact have Java 8 installed, and, if you are using an integrated development environment (IDE), that the IDE is also using Java 8. Details on installing Java 8 can be found in the installation guides for Windows, MacOS, and Linux.

The syntax, language semantics, and common packages for Jython are the same as for Python 2.7, so Python 2.7 language references can be used to learn how to to program in Jython.

The Jython console can be started by either

  1. 1.

    Choosing View > Show Jython Console in the GUI, or

  2. 2.

    Specifying the option -showJythonConsole on the command line.

The Jython console currently appears in a separate Window frame (Figure 43).

Figure 43: ArtiSynth application showing the Jython console.

12.1 Querying ArtiSynth structures and models

Once the Jython console is open, it can be used to query ArtiSynth structures and model components. Every publicly accessible method of every Java object can be called via the interface. To easily access particular components of a model, the predefined list variable sel provides access to the current ArtiSynth selection list. That means you can select items in the ArtiSynth GUI (using either the viewer or navigation panel) and then access these in Jython. By itself, sel supplies the entire selection list. Specific selected components can be accessed by indexing into this list, so that sel[i] returns the i-th entry (where the index i is 0-based).

For example, if two particles are currently selected in ArtiSynth, then sel can be used as follows:

   >>> sel    # get the entire selection list
   [artisynth.core.mechmodels.Particle@709da188, artisynth.core.mechmodels.Particle@750eba3f]
   >>>
   >>> sel[0] # get the first item on the list
   artisynth.core.mechmodels.Particle@709da188

Once a component has been selected, then one has access to all its public methods. This can be quite useful for setting or querying items are that are not normally available via the ArtiSynth GUI. For example, if we want to find the number of nodes in a FemModel3d, then we can select the FEM and then in the console do

   >>> fem = sel[0]
   >>>
   >>> fem.numNodes()
   16

12.2 Object creation and importing classes

Java objects can also be created by calling their constructors directly, without the need for the keyword new. For example,

   >> vec = Vector3d (1, 2, 3)

creates a new instance of Vector3d and initializes it to (1, 2, 3).

As with Java code, Java class definitions need to be imported into Jython in order for them to be visible. For example,

   >> import maspack.matrix

will import all classes defined in the package maspack.matrix. However, unlike in Java, classes imported into Jython this way will still need to be accessed using their fully qualified class names (e.g., maspack.matrix.Vector3d, maspack.matrix.Matrix3d, etc.). In order to make classes visible using only their basic names, one may use the from statement, as in

   >> from java.io import File
   >> from maspack.matrix import Vector3d

To import all classes within a package by basic name, one may employ the wildcard *:

   >> from maspack.matrix import *

although this may occasionally miss certain classes.

For convenience, the ArtiSynth Jython console already fully imports, by basic name, the classes from the following packages:

   maspack.util
   maspack.matrix
   maspack.geometry
   maspack.collision
   maspack.render
   maspack.solvers
   artisynth.core.mechmodels
   artisynth.core.femmodels
   artisynth.core.materials
   artisynth.core.modelbase
   artisynth.core.driver
   artisynth.core.workspace
   artisynth.core.inverse
   java.lang
   java.io

12.3 Running simulations and scripting

Jython can also be used to run simulations, using various built-in functions that allow models to be loaded and run. A full summary of these is given in Section 12.7. In particular, it is possible to load a model and then run or single step a simulation.

To load a model, one may use the function

  loadModel (name, args...)

where name is the classname of the model’s RootModel, and args... is an optional variable-length list of string arguments that are used to form the args argument of the model’s build() method (see the section “Implementing the build() method” in the ArtiSynth Modeling Guide). In general, the name argument should be the fully qualified name of the root model class, as in

   >> ah.loadModel (’artisynth.demos.mech.RigidBodyDemo’)

However, if the model has been previously loaded by ArtiSynth, the class’s simple name should work as well:

   >> ah.loadModel (’RigidBodyDemo’)

Once loaded, simulation may be controlled using functions such as play(), pause(), step(), or reset(). The play() function may take a time argument indicating the length of time the simulation should be run for; if this argument is omitted, the simulation will run indefinitely or until a breakpoint is encountered. Play requests are issued asynchronously; to make the Jython console wait for simulation to halt, one may use the waitForStop() function:

   >> loadModel (’RigidBodyDemo’)
   >> play (2.5)
   >> waitForStop()

When controlling simulations, it is often easiest to create a script of Jython commands in a Python-style .py file and then "source" them into the Jython console. In Python, one can use exec() or execfile() to do this. However, in ArtiSynth it is recommended to use the ArtiSynth supplied script() function, as in

   >>> script (’contactTest.py’)

This is particularly true for longer scripts, since script() interacts better with the GUI and allows the script commands to be displayed in the console as they are being executed.

Scripts are particularly useful for running multiple simulations with varying inputs and outputs. Arguments supplied to a model’s build() method provide a convenient way to adjust input and output parameters between simulations.

As will be seen below, it is also possible to pass command-line style arguments to the script itself. Within the script, such arguments can the retrieved from sys.argv, as illustrated by the following code fragment:

   import sys
   print(’Number of arguments:’ + str(len(sys.argv)))
   print(’Argument List:’ + str(sys.argv))

Jython commands, including scripts, can be aborted by clicking the stop-all button to the right of the play controls (Section 7.2.1).

12.4 Using the script menu

Figure 44: The ArtiSynth script selection menu.

For convenience, ArtiSynth provides a Scripts menu in the main application menu bar that is similar in function to the Models menu and can be used to run script files from predefined menu entries (Figure 44). By default, the upper part of this menu contains a single submenu:

Demo scripts - expands to all scripts within src/artisynth/demos/scripts under the ArtiSynth install folder.

Selecting a submenu entry will cause the Jython console to be opened (if necessary) and the associated script to be executed. At the time of this writing, “Demo scripts” contains a single entry for a demonstration script named demoScript.py.

The lower part of the script menu, beneath the separator, contains entries for reloading recent scripts (”Run recent ...”), running a script from an explicitly specified file (“Run script ...”, Section 12.5), and adding custom entries to the upper part of the script menu ( “Edit menu ...”, Section 13).

12.5 Selecting a script file

To explicitly specify a script file, choose “Run script ...” from the lower part of the script menu, which will bring up a script selection dialog as shown in Figure 45.

Figure 45: Dialog for selecting a script file.

Users should specify the folder containing the script in the “Script folder” field at the top. This folder will then be searched for files ending in .py and .jy, with the results listed in the “Script file” panel, from which the user can then select the desired script by clicking on it. If the script requires command-line style arguments (Section 12.3), these can be entered in the “Args” field near the dialog bottom. Arguments should be separated by white space, with those containing white space placed between with double quotes ‘"’.

When all desired settings have been made, the user runs the script using the Run button.

12.6 Specifying scripts on the command line

It is possible to specify Jython scripts directly on the ArtiSynth command line using the -script option. For example,

   artisynth -script experiment.py

will start ArtiSynth and then immediately invoke the script experiment.py. Scripts can also be run in "batch" mode, without starting the GUI or explicitly opening the Jython console. This can be useful when running ArtiSynth remotely, or in parallel on a cluster of machines. To run a script in batch mode, simply add the -noGui command line option:

   artisynth -noGui -script experiment.py

Since there is no GUI, Jython will then be initiated using a terminal console instead of the usual GUI-based text window. When the script finishes, the console will remain available for interactive operation.

One may also simply start with a Jython console, with no initial script:

   artisynth -noGui -showJythonConsole

Finally, arguments may be passed to scripts invoked using -script, by placing them immediately after the script specification, enclosed within square brackets [ ]. For example,

   artisynth -script myscript.py [ -xxx 123 -off ]

will pass the strings "-xxx", "123" and "-off" to the script myscript.py. Within the script, these arguments can the retrieved from sys.argv, as described in Section 12.3.

12.7 Built-in functions

The following is a summary of the built-in Jython console functions:

getMain()

Returns the ArtiSynth Main object.

loadModel (name, args...)

Loads the named model along with optional arguments. name is the classname of the model’s RootModel and args... is an optional variable-length list of string arguments that are used to form the args argument of the model’s build() method. Nominally, name should be a fully-qualified classname (for example, artisynth.demos.mech.RigidBodyDemo), but if the model has been loaded before, the simple class name should work as well (e.g., RigidBodyDemo).

loadModelFile (filename)

Loads a model from an ArtiSynth file. filename is a string giving the file’s path.

saveModelFile (filename)

Save a model to an ArtiSynth file.

saveModelFile (filename, saveWayPointData, coreCompsOnly)

Save a model to an ArtiSynth file. The options saveWayPointData and coreCompsOnly specify whether to (a) save waypoint data, and (b) save only components from artisynth_core.

play()

Starts the simulation running.

play(t)

Starts and runs the simulation for t seconds.

pause()

Pauses the simulation.

step()

Single steps the simulation.

reset()

Resets the simulation to time 0.

forward()

Forwards the simulation to the next waypoint.

rewind()

Rewinds the simulation to the last waypoint.

delay(t)

Delays execution for t seconds.

waitForStop()

Blocks until the simulation has completed.

isPlaying()

Returns true if simulation is still running.

getTime()

Returns current ArtiSynth simulation time in seconds.

reload()

Reloads the current model.

addWayPoint(t)

Adds a simulation waypoint at time t, where t is a floating point value giving the time in seconds.

addBreakPoint(t)

Adds a breakpoint at time t.

removeWayPoint(t)

Removes any waypoint or breakpoint at time t.

clearWayPoints()

Removes all waypoints and breakpoints.

saveWayPoints (filename)

Save waypoints and their data to a specified file

loadWayPoints (fileName)

Load waypoints and their data from a specified file

root()

Returns the current RootModel.

find (path)

Finds a component defined by path with respect to the current RootModel.

getsel()

Returns the current ArtiSynth selection list (which is the same as the built-in variable sel).

getsel(i)

Returns the i-th selection list item (where i is 0-based).

quit()

Quits ArtiSynth.