Started:Formats

From OpenRAVE

Jump to: navigation, search

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.

Contents

KinBody

<KinBody name="TestKinBody">
  <!-- Create a rigid body named Body1 and declare it as 'dynamic'.-->
  <!-- 'dynamic' bodies are subject to physics laws, 'static' bodies will never move-->
  <!-- due to physical forces. It is recommended EVERYTHING is declared as 'dynamic' -->
  <Body name="Body1" type="dynamic">
    <!-- Note that the body transforms affects all geometry objects attached. -->
 
    <!-- translation of the body-->
    <Translation>0 0 0</Translation>
    <!--rotation of the body specified as a rotation axis. First three numbers are the axis.-->
    <RotationAxis>1 0 0 90</RotationAxis>
 
    <!-- defines mass properties for the entire kinbody. possible mass types are-->
    <!-- mimicgeom - <density>. Adds a mass equivalent to all the geometry-->
    <!--    objects. trimesh and plane are not supported.-->
    <!-- box - <density>(or <mass>), <extents> Adds a simple box-->
    <!-- sphere - <density>(or <mass>), <radius>-->
    <Mass type="mimicgeom">
      <density>1000</density>
    </Mass>
 
    <!-- Define a geometry object attached to the body. The functionality of -->
    <!-- geometry objects is to define the collision and render geometries of the body. -->
    <!-- All geometry types have Rotation(Mat/Quat), Translation, and Render components.-->
    <!-- Possible geom types are box, sphere, trimesh, plane.-->
    <!--  *box - extents-->
    <!--  *sphere - radius-->
    <!--  *cylinder - radius, height (axis is along y)-->
    <!--  *trimesh - data-->
    <Geom type="box">
      <!-- extents of the box - half width, height, length-->
      <Extents>1 1 1</Extents>
      <!-- set the translation and rotation of the box. Note that the transforamtions-->
      <!-- are all relative to the parent body.-->
      <Translation>1 0 0</Translation>
      <RotationAxis>0 1 0 45</RotationAxis>
    </Geom>
    <!-- Can create multiple geometries per body-->
    <Geom type="box">
      <Extents>2 1 2</Extents>
      <Translation>0 1 0</Translation>
      <!-- RotationMat is a 3x3 rotation matrix specified as rows first-->
      <RotationMat>1 0 0 0 1 0 0 0 1</RotationMat>
      <!-- Set the transparency of the geometry, 0 is opaque-->
      <transparency>0.4</transparency>
    </Geom>
  </Body>
 
  <Body name="Body2" type="dynamic">
    <!-- change the mass properties of the body-->
    <Mass type="mimicgeom">
      <!-- specify the total mass-->
      <total>0.40605</total>
      <!-- specify the 3x3 inertia matrix-->
      <inertia>2 0 0 0 3 0 0 0 5</inertia>
      <!-- specify the center of mass (if using ODE physics engine, should be 0)-->
      <com>0.008842 -0.000018 0.07367</com>
    </Mass>
    <!-- create a sphere-->
    <Geom type="sphere">
      <!-- although the underlying collision geometry will be a sphere,-->
      <!-- render it as a coffee pot-->
      <Render>models/objects/coffeepot.iv</Render>
      <Translation>0 -1.5 0</Translation>
      <Radius>1.5</Radius>
    </Geom>
    <!-- create a triangle mesh-->
    <Geom type="trimesh">
      <Render>models/objects/cup.iv 0.01</Render>
      <!-- use the cup triangles for collision detection.-->
      <!-- The last number is the scale, in case the iv files are scaled improperly.-->
      <data>models/objects/cup.iv 0.01</data>
      <Translation>1.5 -2 0</Translation>
    </Geom>
  </Body>
 
  <!-- Create a joint between the two bodies.-->
  <!-- Possible joint types are: hinge, slider, universal, hinge2, and spherical.-->
  <!-- Hinges are the most common joint type used in robots.-->
  <!-- For amotors, can specify mode, axis1, axis2, axis3. For each axis, first 3 values are the axis and the last value is the relative coord system (see ODE documentation).-->
  <!-- Every joint can have certain properties:-->
  <!-- <maxforce> are in number of degrees of freedom.-->
  <!-- <maxvel>, <resolution> are scalar and apply to all DOFs.-->
  <!-- <limits>, <limitsdeg>, <limitsrad> specify the joint limits -->
  <Joint name="j1" type="hinge">
    <!-- Specify the names of the bodies, names are not case sensitive.-->
    <Body>Body1</Body>
    <Body>Body2</Body>
    <!-- anchor and axis of the hinge-->
    <Anchor>0 0 0</Anchor>
    <Axis>0 1 0</Axis>
    <!-- Weight for configuration distance, mostly used in planners.-->
    <!-- for joints with > 1 DOF, specify 2+ values-->
    <Weight>1.0</Weight>
  </Joint>
</KinBody>

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:

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

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 − π and π limits are identified. In openrave, it is possible to set a joint as circular like this:

<joint circular="true" ...>
...
</joint>

Adjacent Links

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.

Robot

A simple 3DOF planar arm in XZ

<Robot name="3DOFRobot">
  <KinBody>
    <!-- Create the base body, it should never move-->
    <!-- Note that all translations and rotations are with respect to this base-->
    <!-- For example, the robot at the identity transformation is equivalent to the identity transformation of the first body.-->
    <Body name="Base" type="dynamic">
      <Translation>0.0  0.0  0.0</Translation>
      <Geom type="cylinder">
        <radius>0.03</radius>
        <height>0.02</height>
        <diffuseColor>0.05 0.05 0.05</diffuseColor>
      </Geom>
    </Body>
 
    <!-- the first movable link-->
    <Body name="Arm0" type="dynamic">
      <!-- Offset from is a fast way of specifying that the translation and rotation of this-->
      <!-- body should be relative to another link-->
      <offsetfrom>Base</offsetfrom>
      <!-- Translation relative to Base-->
      <Translation>0 0.005 0</Translation>
      <Geom type="box">
        <Translation>0.08 0 0</Translation>
        <Extents>0.08 0.005 0.01</Extents>
      </Geom>
    </Body>
    <!-- declare a circular hinge joint (circular joints have no limits) -->
    <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 1 0</axis>
      <maxvel>3</maxvel>
      <resolution>1</resolution>
    </Joint>
 
    <!-- the second movable link-->
    <Body name="Arm1" type="dynamic">
      <offsetfrom>Arm0</offsetfrom>
      <Translation>0.14 0.01 0</Translation>
      <Geom type="box">
        <Translation>0.08 0.0 0</Translation>
        <Extents>0.08 0.005 0.0075</Extents>
      </Geom>
    </Body>
    <!-- declare a circular hinge joint (circular joints have no limits) -->
    <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 1 0</axis>
      <maxvel>4</maxvel>
      <resolution>1</resolution>
    </Joint>
 
    <!-- the third movable link-->
    <Body name="Arm2" type="dynamic">
      <offsetfrom>Arm1</offsetfrom>
      <Translation>0.14 0.01 0</Translation>
      <Geom type="box">
        <Translation>0.04 0 0</Translation>
        <Extents>0.04 0.005 0.005</Extents>
      </Geom>
    </Body>
    <!-- declare a circular hinge joint (circular joints have no limits) -->
    <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 1 0</axis>
      <maxvel>2</maxvel>
      <resolution>2</resolution>
    </Joint>
 
    <!-- Create the gripper joints:-->
    <!-- right gripper-->
    <Body name="RClaw" type="dynamic">
      <offsetfrom>Arm2</offsetfrom>
      <Translation>0.08 0.005 0</Translation>
     <RotationMat>0 1 0 0 0 -1 -1 0 0</RotationMat>
      <Geom type="trimesh">
        <Data>models/puma/RClaw.iv</Data>
        <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>
 
    <!--left gripper-->
    <Body name="LClaw" type="dynamic">
      <Translation>0.08 0.005 0</Translation>
      <offsetfrom>Arm2</offsetfrom>
      <RotationMat>0 1 0 0 0 -1 -1 0 0</RotationMat>
      <Geom type="trimesh">
        <Data>models/puma/LClaw.iv</Data>
        <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>
    <!-- set the transparency of every geometry in the KinBody-->
    <transparency>0.1</transparency>
  </KinBody>
 
  <!-- Specifying the manipulator structure-->
  <Manipulator name="arm">
    <effector>Arm2</effector>   <!-- last link where end effector is attached-->
    <base>Base</base>           <!-- base link-->
    <joints>j1 j2</joints>      <!-- the gripper joints used for contact-->
    <armjoints>Arm0 Arm1 Arm2</armjoints> <!-- the joints composing of the arm-->
    <!-- the id of the inverse kinematics solver, it is not necessary to-->
    <!-- specify an ik solver for every robot. But if there is one,-->
    <!-- use iksolver field to identity it.-->
    <iksolver>MyTriDOFSolver</iksolver>
    <!-- joint values of the closed and opened positions-->
    <closingdirection>1 1</closingdirection>
    <palmdirection>1 0 0</palmdirection>
    <!-- grasp goal with respect to the effector-->
    <Translation>0.125 0 0</Translation>
    <RotationAxis>1 0 0 90</RotationAxis>
  </Manipulator>
</Robot>

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; 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

<Manipulator name="arm">
  <base>wam0</base>
  <effector>wam7</effector>
  <Translation>0 0 0.22</Translation>
  <joints>JF1 JF2 JF3 JF4</joints>
  <closingdirection>1 1 1 0</closingdirection>
  <direction>0 0 1</direction>
  <iksolver>WAM7ikfast 0.05</iksolver>
</Manipulator>

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.

Attaching Robot Sensors

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

<Robot>
  <!-- ... usual robot definitions ... -->
 
  <!-- Specify an attached sensor-->
  <AttachedSensor name="MyFirstLaser">
    <link>wam1</link> <!-- the robot link that the sensor is attached to. As the robot moves, the sensor will move with it-->
    <translation>0 0.2 0.4</translation> <!-- the local translation in the attached link's frame-->
    <rotationaxis>1 0 0 45</rotationaxis> <!-- the local rotation in the attached link's frame-->
    <!-- specify the real sensor attached-->
    <!-- 'type' is the sensor interface identifier-->
    <!-- 'args' are the arguments passed to SensorBase::Init-->
    <sensor type="BaseLaser2D" args="">
      <!-- The rest are specific fields to BaseLaser2D, these change as the type changes-->
      <!-- The best way to find out what fields are supported is to look for the documentation-->
      <!-- for the type of sensor using-->
      <minangle>-135</minangle> <!-- degrees -->
      <maxangle>135</maxangle> <!-- degrees -->
      <resolution>0.35</resolution> <!-- degrees between laser points-->
      <maxrange>5</maxrange> <!-- max range of robot-->
    </sensor>
  </AttachedSensor>
</Robot>

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.

<Environment>
  <!-- set the background color of the environment-->
  <bkgndcol>0.3 0.7 0.8</bkgndcol>
  <!-- set the initial camera translation-->
  <camtrans>1.418 -1.234 2.963</camtrans>
  <!-- set the initial camera rotation specified by rotation-axis-->
  <camrotaxis>0.724 0.302 0.619 68</camrotaxis>
 
  <!-- import the segway model and place it somewhere-->
  <KinBody file="data/segway.kinbody.xml">
    <Translation>-0.0671   -0.0819    0.7550</Translation>
  </KinBody>
 
  <!-- import a robot file and add an additional body for a cylindrical base-->
  <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>
          <radius>0.08</radius>
          <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>
 
  <!-- add the floor as a box-->
  <KinBody name="floor">
    <!-- floor should never move, so make it static-->
    <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>

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:

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

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

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

1. A robot can reference other robots through:

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

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:

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

Now all links and joints will either start with left_ or right_.

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).

Attaching Separate Links

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:

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

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 COLLADA Files

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.

<robot>
 <robot file="robots/kuka-kr5-r650.robot.xml"></robot>
 <robot prefix="hand_" file="schunkSDHhand.dae"></robot>
 <kinbody>
   <body name="hand_root">
     <offsetfrom>link6</offsetfrom>
     <translation>0.03 0 0</translation>
     <rotationaxis>0 1 0 90</rotationaxis>
   </body>
   <joint type="hinge" enable="false">
     <body>link6</body>
     <body>hand_root</body>
     <limits>0 0</limits>
   </joint>
 </kinbody>
</robot>

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.

<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>
    <!-- left arm -->
    <KinBody prefix="l_" file="schunk-lwa3.kinbody.xml">
      <RotationAxis>1 0 0 90</RotationAxis>
      <translation>0 -0.1 0.7</translation>
    </KinBody>
    <!-- right arm -->
    <KinBody prefix="r_" file="schunk-lwa3.kinbody.xml">
      <RotationAxis>1 0 0 -90</RotationAxis>
      <translation>0 0.1 0.7</translation>
    </KinBody>
    <!-- connect the two arms with dummy joints -->
    <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>
  <!-- define the manipulators -->
  <Manipulator name="leftarm">
    <base>l_base</base>
    <effector>l_link7</effector>
    <armjoints>l_j0 l_j1 l_j2 l_j3 l_j4 l_j5 l_j6</armjoints>
  </Manipulator>
  <Manipulator name="rightarm">
    <base>r_base</base>
    <effector>r_link7</effector>
    <armjoints>r_j0 r_j1 r_j2 r_j3 r_j4 r_j5 r_j6</armjoints>
  </Manipulator>
</Robot>

Single arm:

Dual arm:

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:

<data>mydata.iv 0.001</data>
<render>mydata.iv 0.001</render>

this will scale the models by 0.001.

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:

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

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 problem instance 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.

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
  probleminstance - 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
kinbody - attributes: name, file, prefix, type, makejoinedlinksadjacent
  adjacent - 2 body names
  body - attributes: name, type (dynamic, static)
    geom - attributes: name, type (box, sphere, trimesh, cylinder), render (true,false), modifiable (true,false)
      ambientcolor - 3 float
      data - string
      diffusecolor - 3 float
      extents - 3 float [box]
      height - float [cylinder]
      quat - 4 float
      radius - float [cylinder, sphere]
      render - string
      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
      radius - float
      total - float
  joint - attributes: enable (true, false), mimic (joint_name c0 c1), type (hinge, slider, universal, hinge2, spherical), circular(true, false)
    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
    mode - int [amotor]
    offsetfrom - link name
    resolution - float
    weight - dof floats
  jointvalues
  kinbody - attributes: name, file, prefix
  mass - attributes: type (box, sphere, custom)
    density - float
    radius - 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
    link
    quat
    rotationaxis
    rotationmat
    translation
    sensor - attributes: type, arguments
      ... - fields defined by SensorBase class instantiated by type
  controller - controllertype arguments
  jointvalues
  kinbody - name
  manipulator - attributes: name
    armjoints - n joint names
    base - link name
    closed - k floats
    effector - link name
    iksolver - string
    gripperjoints - k joint names
    closingdirection - k floats
    palmdirection - 3 floats
    quat - 4 floats
    rotationaxis - 4 floats
    rotationmat - 9 floats
    translation - 3 floats
  quat - 4 float
  robot - name, file, type
  rotationaxis - 4 float
  rotationmat - 9 float
  translation - 3 float
Personal tools