# Format:XML

(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)

# OpenRAVE Custom XML Format

TODO: Decide on the versioning scheme

OpenRAVE uses XML to store all robot and scene descriptions. The XML format is flexible enough to link one XML file from another like including already created objects/robots in an environment. It is also possible to specify vrml or iv formatted files within it to import models.

All interface types can be created. Furthermore, an <environment> tag can optionally be specified to put all bodies/interfaces in.

• Environment - specify multiple objects and robots. Can also define some GUI properties like camera start location and background color. The environment allows the creation of any OpenRAVE interfaces. Each interface can take the type attribute specifying the interface type and can define custom XML readers.
• KinBody - The basic object that all other objects derive from. A kinematic body consists of a collection of rigid bodies and joints that connect these bodies.
• Robot - The basic robot that derives from KinBody. Usually every Robot has at least one KinBody declaration inside it. A robot can also hold a list of Manipulator and AttachedSensor objects describing the manipulation/sensing capabilities of the robot. Since plugin authors can create different robots, it is also possible to define custom fields in Robot to hold other information like balance control parameters for humanoids.

## Transformations

Most tags for links/bodies/robots hold a transformation. The following fields modify this transformation:

<source lang="xml"> <translation>0 1 0</translation>

<quat>1 0 0 0</quat>

<rotationmat>1 0 0 0 1 0 0 0 1</rotationmat>

<rotationaxis>1 0 0 90</rotationaxis>

</source>

Multiple of the same tags can be specified, resulting in the transformations being compounded. During compounding, the translation and rotation are treated separately.

## KinBody

<source lang="xml"> <KinBody name="TestKinBody">

<Body name="Body1" type="dynamic">

<Translation>0 0 0</Translation>
<RotationAxis>1 0 0 90</RotationAxis>

<Mass type="mimicgeom">
<density>1000</density>
</Mass>

<Geom type="box">
<Extents>1 1 1</Extents>
<Translation>1 0 0</Translation>
<RotationAxis>0 1 0 45</RotationAxis>
</Geom>
<Geom type="box">
<Extents>2 1 2</Extents>
<Translation>0 1 0</Translation>
<RotationMat>1 0 0 0 1 0 0 0 1</RotationMat>
<transparency>0.4</transparency>
</Geom>
</Body>

<Body name="Body2" type="dynamic">
<Mass type="mimicgeom">
<total>0.40605</total>
<inertia>2 0 0 0 3 0 0 0 5</inertia>
<com>0.008842 -0.000018 0.07367</com>
</Mass>
<Geom type="sphere">
<Render>models/objects/coffeepot.iv</Render>
<Translation>0 -1.5 0</Translation>
</Geom>
<Geom type="trimesh">
<Render>models/objects/cup.iv 0.01</Render>
<collision>models/objects/cup.iv 0.01</collision>
<Translation>1.5 -2 0</Translation>
</Geom>
</Body>

<Joint name="j1" type="hinge">
<Body>Body1</Body>
<Body>Body2</Body>
<Anchor>0 0 0</Anchor>
<Axis>0 1 0</Axis>
<Weight>1.0</Weight>
<maxtorque>10</maxtorque>
</Joint>

</KinBody> </source>

### Models Directory

By default, the root directory for all models files is the folder openrave is launched at. To change this, <modelsdir> can be used to specify model files relative to where the current xml file is. For example:

<source lang="xml"> <KinBody>

<modelsdir>../mymodels</modelsdir>
<Body>
<Geom type="box">
<render>kitchen/myfile.wrl</render>
</Geom>
</Body>

</KinBody> </source>

### Circular Joints

Sometimes joints will have the upper and lower limits identified, meaning that as soon as the joint gets past one limit it will wrap around to the other. Infinitely revolving hinge joints are the most common example of circular joints where the $-\pi$ and $\pi$ limits are identified. In openrave, it is possible to set a joint as circular like this: <source lang="xml"> <joint circular="true" ...> ... </joint> </source>

Robot self-collision usually checks all pairs of non-adjacent links for collision; links are adjacent if they are connected to a joint. In order to reduce self-collision computation time and spurious collisions of small links, it is possible to force pairs of links to be treated as adjacent by specifying an <adjacent> tag.

### Scale

The first thing when importing a new model is to check that all the units are in meters (it is very common for robots to be in millimeters), otherwise the visualization model and the collision model will be in a different scale. to check this, open the robot and go to View->Geometry->Collision, this will show the collision model. If it is not the same scale, you need to go inside your model files and change the units. You can also enter a scale factor after model filenames like this:

<source lang="xml"> <collision>mydata.iv 0.001</collision> <render>mydata.iv 0.001</render> </source>

this will scale the models by 0.001.

### Modifiable Geometry

When avoiding collision obstacles, OpenRAVE can optionally use convex decompositions to speed up the environment collision checking and pad the geometry with safety regions. By default, all geometry is modifiable, but the user can turn it off so that the mesh is never changed by setting modifiable="false" attribute in the <geom> tag.

Geometry that can make contact with the environment usually should not be modified. For example:

- gripper links since contact points are important

- markers and other place-holders used for tracking

## Robot

### A simple 3DOF planar arm in XZ

<source lang="xml"> <Robot name="3DOFRobot">

<KinBody>
<Body name="Base" type="dynamic">
<Translation>0.0  0.0  0.0</Translation>
<Geom type="cylinder">
<rotationaxis>1 0 0 90</rotationaxis>
<height>0.02</height>
<diffuseColor>0.05 0.05 0.05</diffuseColor>
</Geom>
</Body>

<Body name="Arm0" type="dynamic">
<offsetfrom>Base</offsetfrom>
<Translation>0 0 0.005</Translation>
<Geom type="box">
<Translation>0.08 0 0</Translation>
<Extents>0.08 0.01 0.005</Extents>
</Geom>
</Body>
<Joint circular="true" name="Arm0" type="hinge">
<Body>Base</Body>
<Body>Arm0</Body>
<offsetfrom>Arm0</offsetfrom>
<weight>4</weight>
<limitsdeg>-180 180</limitsdeg>
<axis>0 0 1</axis>
<maxvel>3</maxvel>
<resolution>1</resolution>
</Joint>

<Body name="Arm1" type="dynamic">
<offsetfrom>Arm0</offsetfrom>
<Translation>0.14 0 0.01</Translation>
<Geom type="box">
<Translation>0.08 0.0 0</Translation>
<Extents>0.08 0.0075 0.005</Extents>
</Geom>
</Body>
<Joint circular="true" name="Arm1" type="hinge">
<Body>Arm0</Body>
<Body>Arm1</Body>
<offsetfrom>Arm1</offsetfrom>
<weight>3</weight>
<limitsdeg>-180 180</limitsdeg>
<axis>0 0 1</axis>
<maxvel>4</maxvel>
<resolution>1</resolution>
</Joint>

<Body name="Arm2" type="dynamic">
<offsetfrom>Arm1</offsetfrom>
<Translation>0.14 0 0.01</Translation>
<Geom type="box">
<Translation>0.04 0 0</Translation>
<Extents>0.04 0.005 0.005</Extents>
</Geom>
</Body>
<Joint circular="true" name="Arm2" type="hinge">
<Body>Arm1</Body>
<Body>Arm2</Body>
<offsetfrom>Arm2</offsetfrom>
<weight>3</weight>
<limitsdeg>-180 180</limitsdeg>
<axis>0 0 1</axis>
<maxvel>2</maxvel>
<resolution>2</resolution>
</Joint>

<Body name="RClaw" type="dynamic">
<offsetfrom>Arm2</offsetfrom>
<Translation>0.08 0 0.005</Translation>
<rotationaxis>0 0 1 -90</rotationaxis>
<Geom type="trimesh">
models/puma/RClaw.iv
<Render>models/puma/RClaw.iv</Render>
</Geom>
</Body>
<Joint name="j1" type="hinge">
<Body>Arm2</Body>
<Body>RClaw</Body>
<offsetfrom>RClaw</offsetfrom>
<weight>0.2</weight>
<limitsdeg>-56 16</limitsdeg>
<axis>0 0 1</axis>
<maxvel>0.4</maxvel>
<resolution>3</resolution>
</Joint>

<Body name="LClaw" type="dynamic">
<Translation>0.08 0.005 0</Translation>
<rotationaxis>0 0 1 -90</rotationaxis>
<offsetfrom>Arm2</offsetfrom>
<Geom type="trimesh">
models/puma/LClaw.iv
<Render>models/puma/LClaw.iv</Render>
</Geom>
</Body>
<Joint name="j2" type="hinge">
<Body>Arm2</Body>
<Body>LClaw</Body>
<offsetfrom>LClaw</offsetfrom>
<weight>0.2</weight>
<limitsdeg>-56 16</limitsdeg>
<axis>0 0 -1</axis>
<maxvel>0.4</maxvel>
<resolution>3</resolution>
</Joint>
<transparency>0.1</transparency>
</KinBody>

<Manipulator name="arm">
<effector>Arm2</effector>
<base>Base</base>
<joints>j1 j2</joints>
<closingdirection>1 1</closingdirection>
<direction>1 0 0</direction>
<Translation>0.125 0 0</Translation>
</Manipulator>

</Robot> </source>

3DOFRobot Robot:

### Defining Manipulators

A robot manipulator defines a kinematic chain of the robot joint hierarchy along with optional gripper joint values that are not used in the inverse kinematics computation but are needed for grasping purposes (chains for heads, legs do not need the joint values). A manipulator defines a new frame of reference with respect to the end effector link (<effector>); all inverse kinematics computations are computed using it. Furthermore, a manipulator can have a <direction> tag specifying an axis for approaching objects or line-of-sight. For example the robots/barrettwam.robot.xml gripper is defined by

<source lang="xml"> <Manipulator name="arm">

<base>wam0</base>
<effector>wam7</effector>
<Translation>0 0 0.22</Translation>
<rotationaxis>1 0 0 90</rotationaxis>
<joints>JF1 JF2 JF3 JF4</joints>
<closingdirection>1 1 1 0</closingdirection>
<direction>0 0 1</direction>
<iksolver>WAM7ikfast 0.05</iksolver>

</Manipulator> </source>

The manipulator can optionally define a <iksolver> tag specifying the iksolver interface that is used for getting IK solutions, or a shared object (DLL) to load an ikfast solver from.

### Closed-chains and Mimic Joints

OpenRAVE allows closed-chains and complex kinematics to be simulated using mimic joints. A mimic joint's position, velocity, and acceleration values are computed from user-specified formulas using the values of other joints. OpenRAVE uses the Function Parser library to allow any formula to be specified. Refer to the documentation for more information here.

A mimic joint requires at least the position equation and its partial derivatives (for velocity) to be manually entered.

For example, the Barrett Hand mimic joints are defined as:

<source lang="xml"> <Joint type="hinge" name="JF1">

...

</Joint> <Joint name="JF1mimic" type="hinge" enable="false" mimic_pos="JF1/3+0.8727" mimic_vel="|JF1 0.33333">

....

</Joint> </source>

Of course, it is possible to have a mimic joint depend on more than one other joint:

<source lang="xml"> <Joint type="hinge" name="a">

...

</Joint> <Joint type="hinge" name="b">

...

</Joint> <Joint name="c" type="hinge" mimic_pos="a+b+atan(a)" mimic_vel="|a 1 + 1/(1+a*a) |b 1" mimic_accel="|a -2*a/((1+a*a)*(1+a*a)) |b 0">

....

</Joint> </source>

When using mimic joints, it is important to still make all the correct joint connections so that loops are discovered and forces can be computed correctly.

If a joint has more than one degree of freedom, attach the axis index at the end. For example: "mimic_pos0", "mimic_pos1", "mimic_vel0", "mimic_vel1", "mimic_accel0", and "mimic_accel1".

### Attaching Robot Sensors

Every robot can be attached a number of sensors onto it. The way to specify this in XML is:

<source lang="xml"> <Robot>

<AttachedSensor name="MyFirstLaser">
<translation>0 0.2 0.4</translation>
<rotationaxis>1 0 0 45</rotationaxis>
<sensor type="BaseLaser2D">
<minangle>-135</minangle>
<maxangle>135</maxangle>
<resolution>0.35</resolution>
<maxrange>5</maxrange>
</sensor>
</AttachedSensor>

</Robot> </source>

### Setting joint values for initial state

Sometimes the robot's initial state is not when all the joints are at 0. Instead of transforming each of the geometry to the zero pose, it is possible to set the initial angle to use using the <initial> tag inside the <joint>. The definition for setting the initial angle to pi/2 radius is:

<source lang="xml"> <joint type="hinge">

<initial>1.570796326794</initial>

</joint> </source>

### Changing the Body Coordinate System

Sometimes the robot origin and rotation should be defined in a different coordinate system. It is possible to create a new robot file that references the old one and changes its origin. This requires adding a new root link before the robot is defined. For example, consider the robots/barrettwam.robot.xml file whre the first link's name is 'wam0':

<source lang="xml"> <robot>

<kinbody>
<body name="root">
</body>
</kinbody>
<robot file="robots/barrettwam.robot.xml">
<kinbody>
<body name="wam0">
<rotationaxis>1 0 0 90</rotationaxis>
<translation>0.3 0.4 0.3</translation>
</body>
<joint name="dummy" type="hinge">
<body>root</body>
<body>wam0</body>
<limitsdeg>0 0</limitsdeg>
</joint>
</kinbody>
</robot>

</robot> </source>

## Environment Example

This example is part of the bin/data/intel/lab1.env.xml file. The most important thing to note about this example is the use of the file= attribute to import other XML files. The filename specified with file= has to be relative to the current directory where the file calling it resides. Note the differences between segway.kinbody.xml and barrettwam.robot.xml.

<source lang="xml"> <Environment>

<bkgndcolor>0.3 0.7 0.8</bkgndcolor>
<camtrans>1.418 -1.234 2.963</camtrans>
<camrotaxis>0.724 0.302 0.619 68</camrotaxis>

<KinBody file="data/segway.kinbody.xml">
<Translation>-0.0671   -0.0819    0.7550</Translation>
</KinBody>

<Robot file="../../robots/barrettwam.robot.xml" name="BarrettWAM">
<KinBody>
<Translation>-.22 -.14 -.346</Translation>
<Body type="dynamic">
<Geom type="cylinder">
<RotationAxis>1 0 0 -90</RotationAxis>
<height>0.6</height>
<diffusecolor>0.3 0.3 0.3</diffusecolor>
<Translation> 0.2286 0.1397 -0.346</Translation>
</Geom>
</Body>
</KinBody>
<translation>-0.754 0.3265 1.036</translation>
</Robot>

<KinBody name="floor">
<Body type="static">
<Geom type="box">
<extents>2 2 0.005</extents>
<diffuseColor>.6 .6 .6</diffuseColor>
<ambientColor>0.6 0.6 0.6</ambientColor>
</Geom>
</Body>
</KinBody>

</Environment> </source>

### Setting Robot Joint Values

It is possible to set the joint values of the kinbody in the scene using the <jointvalues> tag. The order of the values should be the order of the DOF indices of each joint (passive/mimic joints are ignored).

<source lang="xml"> <environment>

<robot file="robots/barrettwam.robot.xml">
<jointvalues>1 1 0 0 0 0 0 0.5 0 0 0</jointvalues>
</robot>

</environment> </source>

## Robot Composition

The way we recommend managing robots composed of several sub-robots (like a humanoid composed of arms, legs, hands, etc) is to first create separate .kinbody files for just the kinematics and geometry of each separate part (ie a hand.kinbody.xml and a arm.kinbody.xml). Then create a robot file that includes both the kinematics and defines the manipulators, sensors, and controllers:

<source lang="xml"> <robot>

<kinbody file="arm.kinbody.xml"/>
<kinbody file="hand.kinbody.xml"/>
<attachedsensor>
....
</attachedsensor>
<manipulator>
....
</manipulator>

</robot> </source>

Sometimes for grasp planning, the hand needs to be treated as a robot, so we create a hand.robot.xml file as follows:

<source lang="xml"> <robot>

<kinbody file="hand.kinbody.xml"/>
<manipulator>
....
</manipulator>

</robot> </source>

1. A robot can reference other robots through:

<source lang="xml"> <Robot>

<Robot file="a.robot.xml"/>
<Robot file="b.robot.xml"/>

</Robot> </source>

Both a's and b's <Manipulator> and <AttachedSensor> tags will be used in the parent robot, so you don' t have to copy their definitions.

2. It is possible to prefix the links and joints of a child robot by using the 'prefix' attribute:

<source lang="xml"> <Robot>

<KinBody prefix="left_" file="arm.kinbody.xml"/>
<KinBody prefix="right_" file="arm.kinbody.xml"/>

</Robot> </source>

3. When the xml parser sees a body with the same name as another body, it 'appends' the specified geometries to the original body. This allows the same link to be referenced/defined in multiple robot files (Note that it is not possible to change the original body coordinate system).

When a robot is composed of multiple parts defined in different files, it is necessary to attach links from the different files together so that the robot hierarchy can be complete. This is done by defining disabled dummy joints that attach two links together. These disabled joints do not show up in the robot's description and are only present to maintain the relative transformation between two links. For example, the robot robots/pa10schunk.robot.xml is composed of robots/pa10.kinbody.xml and robots/schunk_manip.kinbody.xml, in order to join the two, the robot is defined in the following way:

<source lang="xml">

<KinBody file="pa10.kinbody.xml">
<KinBody file="schunk_manip.kinbody.xml"/>
<Joint name="dummy" type="hinge" enable="False">
<body>gripper_base</body>
<limits>0 0</limits>
</Joint>
</KinBody>

</source>

where link7 is a link of the pa10 arm and gripper_base is a link of the gripper. The lower and upper joint limits are all 0, which OpenRAVE recognizes as a dummy joint.

### Joining A Robot Arm and Hand

It is possible to load robots and bodies from COLLADA files by specifying the collada filename through the file attribute. For example, the following robot is a combination of an arm defined in OpenRAVE XML and a hand defined in COLLADA (download schunkSDHHand from OpenGrasp). The dummy joint is used to join the arm end effector with the hand base.

<source lang="xml"> <robot>

<robot file="robots/kuka-kr5-r650.robot.xml"></robot>
<robot prefix="hand_" file="schunkSDHhand.dae"></robot>
<kinbody>
<body name="hand_root">
<translation>0.03 0 0</translation>
<rotationaxis>0 1 0 90</rotationaxis>
</body>
<joint type="hinge" enable="false">
<body>hand_root</body>
<limits>0 0</limits>
</joint>
</kinbody>
<manipulator name="arm">
<base>base</base>
<joints>hand_Bone_B1_Joint hand_Bone_B2_Joint hand_Bone_B3_Joint hand_Bone_A1_Joint hand_Bone_A2_Joint hand_Bone_A3_Joint hand_Bone_C1_Joint hand_Bone_C2_Joint hand_Bone_C3_Joint</joints>
<closingdirection>0 1 1 0 1 1 0 1 1</closingdirection>
<direction>1 0 0</direction>
</manipulator>

</robot> </source>

Final robot:

### Dual-arm example

Here is an example file of having a robot composed of two arms attached to a common link named chest.

<source lang="xml"> <Robot name="schunk-dualarm">

<KinBody>
<body name="chest">
<geom type="box">
<extents>0.1 0.1 0.4</extents>
<translation>0 0 0.4</translation>
</geom>
</body>
<KinBody>
<KinBody prefix="l_" file="schunk-lwa3.kinbody.xml"></KinBody>
<RotationAxis>1 0 0 90</RotationAxis>
<translation>0 -0.1 0.7</translation>
</KinBody>
<KinBody>
<KinBody>prefix="r_" file="schunk-lwa3.kinbody.xml"></KinBody>
<RotationAxis>1 0 0 -90</RotationAxis>
<translation>0 0.1 0.7</translation>
</KinBody>
<joint name="leftdummy" type="hinge" enable="false">
<body>chest</body>
<body>l_base</body>
<limits>0 0</limits>
</joint>
<joint name="rightdummy" type="hinge" enable="false">
<body>chest</body>
<body>r_base</body>
<limits>0 0</limits>
</joint>
</KinBody>
<Manipulator name="leftarm">
<base>l_base</base>
</Manipulator>
<Manipulator name="rightarm">
<base>r_base</base>
</Manipulator>

</Robot> </source>

Single arm:

Dual arm:

## Custom XML

Openrave provides much more flexibility in creating and defining custom XML readers for interfaces. First the <environment> XML tag supports creating any interface type and supports loading plugins. For example:

<source lang="xml"> <Environment>

<robot name="wam" file="robots/barrettwam.robot.xml"/>
<controller type="CustomController" robot="wam" args="">
..custom data....
</controller>
<module type="basemanipulation" args="wam"/>

</Environment> </source>

In this example, openrave will first load the plugin, then will create a robot, and then will create a controller that is attached to the robot, then will create the basemanipulation module giving it the robot name as the argument.

Furthermore, using EnvironmentBase::RegisterXMLReader, it is possible to set a parser for custom XML tags for each interface type. For those curious on how to take advantage of custom readers, please refer to examples/plugincpp/customreader.cpp on how to attach a custom XML reader to a controller.

These changes will allow people to setup all their specific environment settings in the XML files without having to rely on external scripts or other programs to do it. Note that OpenRAVE processes tags in depth first order.

## Sensor

It is possible to have XML files that declare a sensor and its internal parameters. For example, data/camera.sensor.xml can look like:

<source lang="xml"> <sensor type="BaseCamera">

<KK>640 640 320 240</KK>
<width>640</width>
<height>480</height>
<framerate>5</framerate>
<color>0.5 0.5 1</color>

</sensor> </source>

In order to attach a sensor defined by a file to a robot link do:

<source lang="xml"> <Robot>

<AttachedSensor name="MyCamera">
<sensor file="camera.sensor.xml">
</sensor>
</AttachedSensor>

</Robot> </source>

It is also possible to put a sensor directly in the environment without a robot. Such a sensor will not have any geometry associated with it, and will only act as a sensing source.

<source lang="xml"> <Environment>

<sensor name="mysensor" file="camera.sensor.xml">
<translation>0 1 0</translation>
<rotationaxis>1 0 0 45</rotationaxis>
</sensor>

</Environment> </source>

## XML Reference

Note: All XML handling is done in src/libopenrave-core/xmlreaders.cpp. If there's any parameters that are not explained well, make sure to check out that source file for further reference.

Here's a list of all possible fields the XML supports in a hierarchical structure.

environment - attributes: file
bkgndcolor - 3 floats
camrotaxis - 4 floats
camtrans - 3 floats
kinbody - attributes: name, file
robot - attributes: name, file
planner - attributes: type, file
sensorsystem - attributes: type, file
controller - attributes: type, file, robot, args
module - attributes: type, file
inversekinematicssolver - attributes: type, file
physicsengine - attributes: type, file
sensor - attributes: type, file
collisionchecker - attributes: type, file
trajectory - attributes: type, file
viewer - attributes: type, file
server - attributes: type, file
body - attributes: name, type (dynamic, static), file, skipgeometry, scalegeometry, enable
geom - attributes: name, type (box, sphere, trimesh, cylinder), render (true,false), modifiable (true,false)
ambientcolor - 3 float
collision - attributes: file, scale
diffusecolor - 3 float
extents - 3 float [box]
height - float [cylinder]
quat - 4 float
render - attributes: file, scale
rotationaxis - 4 float
rotationmat - 9 float
translation - 3 float
transparency - 1 float
vertices - 9*N floats where each 9 values defines 1 triangle with 3 vertices
mass - attributes: type (box, sphere, custom)
com - 3 float
density - float
inertia - 9 float
total - float
joint - attributes: enable (true, false), type (hinge, slider, universal, hinge2, spherical), circular(true, false), mimic_pos (math equation), mimic_vel (math equation), mimic_accel (math equation)
anchor - 3 floats [hinge, hinge2, universal, spherical]
axis - 3 floats [hinge, slider]
axis1 - 3 floats [hinge2, universal]
axis2 - 3 floats [hinge2, universal]
body - string
limits - 2*dof floats in radians if applicable (first two specify first joint limits, etc)
limitsdeg - 2*dof floats in degrees if applicable (first two specify first joint limits, etc)
limitsrad - 2*dof floats in radians if applicable (first two specify first joint limits, etc)
maxvel - dof floats
maxveldeg - dof floats
maxaccel - dof floats
maxacceldeg - dof floats
mode - int [amotor]
resolution - float
weight - dof floats
initial - dof floats
maxtorque - dof floats
jointvalues
kinbody - attributes: name, file, prefix
mass - attributes: type (box, sphere, custom)
density - float
total - float
modelsdir - string
offsetfrom - bodyname
quat - 4 float
rotationaxis - 4 float
rotationmat - 9 float
translation - 3 float
transparency - 1 float
robot - attributes: name, file, prefix, type (robot plugin type)
attachedsensor - attributes: name
quat
rotationaxis
rotationmat
translation
sensor - attributes: type
... - fields defined by SensorBase class instantiated by type
controller - type args
jointvalues
kinbody - name
manipulator - attributes: name
closed - k floats