Menu

RobotModels

Nikolaus Vahrenkamp Valerij Wittenbeck Dominik Muth
Attachments
Tutorial1.png (32887 bytes)
Tutorial10.png (84193 bytes)
Tutorial2.png (44429 bytes)
Tutorial3a.png (31715 bytes)
Tutorial3b.png (31714 bytes)
Tutorial4a.png (60867 bytes)
Tutorial4b.png (33697 bytes)
Tutorial5a.png (32198 bytes)
Tutorial5b.png (49744 bytes)
Tutorial6a.png (59088 bytes)
Tutorial6b.png (57787 bytes)
Tutorial7.png (29809 bytes)
Tutorial7b.png (29884 bytes)
Tutorial8.png (82693 bytes)
Tutorial8b.png (108877 bytes)
Tutorial9.png (117853 bytes)
Tutorial9b.png (77822 bytes)
Tutorial9c.png (127923 bytes)

Robot models are defined via XML files, where the kinematic structure as well as additional information (e.g. visualizations, joint definitions or physics information) is stored. A robot consists of so-called Robot Nodes, which hold joint definitions and visualization data. After loading, these data structures can be accessed through the VirtualRobot library.

In the following examples we start with a simple robot system in order to show how the XML definitions are structured. Later more complex examples are given, where you can see how advanced robot definitions can be created.

Minimal Example

This minimal example shows how to define a robot. The file can be found in the doc/tutorial folder of the simox source tree. It can be loaded with VirtualRobot's RobotViewer example (located at VirtualRobot/examples/RobotViewer).

<Robot Type="DemoRobot" RootNode="root">

   <RobotNode name="root">
   </RobotNode>

</Robot>

Visualizations

Now we add a visualization. In the following example, the Coin3D/Qt visualization support is used, indicated by the type="Inventor" attribute of the visualization's File tag (in case OpenSceneGraph is used for 3D-model importing and visualization, the attribute would be type="osg"). The location of the joint.iv file is given relatively to the location of the XML file, so that the directory iv is searched for the file joint.iv.

<Robot Type="DemoRobot" RootNode="root">

   <RobotNode name="root">
       <Visualization>
           <File type="Inventor">iv/joint.iv</File>
    </Visualization>
   </RobotNode>

</Robot>

The joint.iv file defines a cylinder in the OpenInventor format. As specified in OpenInventor, the cylinder is aligned with the y axis and it is 500 mm long. In order to set one side of the cylinder to the (local) origin, the object is moved by 250 mm.

#Inventor V2.0 ascii
Separator {
   Translation {
       translation 0 250 0
   }
   Cylinder {
       radius 40
       height 500
       parts (SIDES | TOP | BOTTOM)
   }
}

Joints

In this example the robot gets a movable joint. The Joint type is specified with the revolute attribute and the rotation axis. The Transform tag specifies a fixed transformation that is applied before the joint. Hence, a RobotNode may imply two transformations:

  • Transform This fixed transformation is applied to the parent's global pose.
  • Joint: This transformation depends on the joint value and the resulting pose specifies the location where the visualization is linked to. This final pose of the RobotNode is noted as GlobalPose in Simox. This is the starting point for computing the coordinate systems of all children.
    <Robot Type="DemoRobot" RootNode="root">
    
      <RobotNode name="root">
        <Child name="joint 1"/>
      </RobotNode>
    
      <RobotNode name="joint 1">
        <Transform>
          <Translation x="0" y="500" z="0"/>
        </Transform>
        <Joint type="revolute">
          <Axis x="0" y="0" z="1"/>
        </Joint>
        <Visualization>
          <File type="Inventor">iv/joint.iv</File>
        </Visualization>
      </RobotNode>
    
    </Robot>
    

Kinematic Chains

Now we build a longer kinematic chain by connecting multiple RobotNodes. Some of the nodes are fixed (no Joint tag), while others can be moved indicated by a <Joint type="revolute'> definition.

<Robot Type="DemoRobot" RootNode="root">

   <RobotNode name="root">
     <Child name="joint 1"/>
   </RobotNode>

   <RobotNode name="joint 1">
     <Joint type="revolute">
       <Axis x="0" y="0" z="1"/>
     </Joint>
     <Visualization>
       <File type="Inventor">iv/joint.iv</File>
     </Visualization>
     <Child name="node 1"/>
    </RobotNode>

    <RobotNode name="node 1">
      <Transform>
        <Translation x="0" y="500" z="0"/>
      </Transform>
      <Visualization>
        <File type="Inventor">iv/ball.iv</File>
      </Visualization>
      <Child name="joint 2"/>
    </RobotNode>

    <RobotNode name="joint 2">
      <Joint type="revolute">
        <Axis x="0" y="1" z="0"/>
      </Joint>
      <Visualization>
        <File type="Inventor">iv/joint2.iv</File>
      </Visualization>
      <Child name="node 2"/>
    </RobotNode>

    <RobotNode name="node 2">
      <Transform>
        <Translation x="0" y="0" z="500"/>
      </Transform>
      <Visualization>
        <File type="Inventor">iv/ball.iv</File>
      </Visualization>
      <Child name="joint 3"/>
    </RobotNode>

    <RobotNode name="joint 3">
      <Joint type="revolute">
        <Axis x="1" y="0" z="0"/>
      </Joint>
      <Visualization>
        <File type="Inventor">iv/joint.iv</File>
      </Visualization>
    </RobotNode> 
</Robot>

Denavit-Hartenberg Parameters

A joint can also be definied with Denavit Hartenberg paramters. Therefore the DH tag with the two translational attributes a, d and with both rotational attributes alpha and theta can be used. Please note that you have to specify the units in which the rotation is given (degree or radian). Further, the Limits tag is used to specify the lower and upper joint limits.

<Robot Type="DemoRobot" RootNode="root">

    <RobotNode name="root">
        <Child name="joint 1"/>
    </RobotNode>

    <RobotNode name="joint 1">
        <Joint type="revolute">
        <Limits lo="0" hi="120" units="degree"/>
        </Joint>
        <Visualization>
            <File type="Inventor">iv/joint2.iv</File>
        </Visualization>
        <Child name="node 1"/>
    </RobotNode>

    <RobotNode name="node 1">
        <Transform>
            <DH a="0" d="500" alpha="-90" theta="0" units="degree"/>
        </Transform>
        <Visualization>
            <File type="Inventor">iv/ball.iv</File>
        </Visualization>
        <Child name="joint 2"/>
    </RobotNode>

    <RobotNode name="joint 2">
        <Joint type="revolute">
            <Limits lo="-45" hi="45" units="degree"/>
        </Joint>
        <Visualization>
            <File type="Inventor">iv/joint2.iv</File>
        </Visualization>
        <Child name="node 2"/>
    </RobotNode>

    <RobotNode name="node 2">
        <Transform>
            <DH a="0" d="500" alpha="90" theta="0" units="degree"/>
        </Transform>
    </RobotNode>
</Robot>

Coordinate Systems

A RobotNode may cover several transformations.

  • Transform: This is a fixed transformation which is applied to the initial pose that is passed by the parent of this node.
  • Joint: This transformation depends on the joint type and the current joint value. In classical robot systems this transformation applies a rotation.

The GlobalPose of a RobotNode is always the pose that is retrieved after applying all transformations.

Collision Models

In the following example a finger is modeled with DH parameters. Additionally to the 3D models, the CollisionModel tag is used to specify visualization files that should be used for collision detection. The CollisionModels will automatically be used whenever collision detection is performed, hence usually reduced models are used in order to speed up the collision detection. If the visualization models should be used for collision detection as well you can use the <UseAsCollisionModel/> tag within a <VisualizationModel> definition, in order to avoid loading the 3D model twice. Further, bounding boxes can be automatically created to be used as CollisionModels. Therefore you have to use the attribute boundingbox="true" within the CollisionModel's File tag.

<Robot Type="DemoRobot" RootNode="root">

  <RobotNode name="root">
    <Child name="Finger Joint1"/>
  </RobotNode>

  <RobotNode name="Finger Joint1">
    <Joint type="revolute">
      <Limits unit="degree" lo="-25" hi="25"/>
    </Joint>
    <Visualization enable="true">
      <File type="Inventor">iv/LeftIndexFinger/leftIndexFinger0.iv</File>
    </Visualization>
    <CollisionModel>
      <File type="Inventor">iv/LeftIndexFinger/col_leftIndexFinger0.iv</File>
    </CollisionModel>
    <Child name="BaseToFinger"/>
  </RobotNode>

  <RobotNode name="BaseToFinger">
    <Transform>
      <DH a="14.8" d="0" theta="0" alpha="90" units="degree"/>
    </Transform>
    <Child name="Finger Joint2"/>
  </RobotNode>

  <RobotNode name="Finger Joint2">
    <Transform>
      <DH a="0" d="1.75" theta="0" alpha="0" units="degree"/>
    </Transform>
    <Joint type="revolute">
      <Limits unit="degree" lo="0" hi="90"/>
    </Joint>
    <Visualization enable="true">
      <File type="Inventor">iv/LeftIndexFinger/leftIndexFinger1.iv</File>
    </Visualization>
    <CollisionModel>
      <File type="Inventor">iv/LeftIndexFinger/col_leftIndexFinger1.iv</File>
    </CollisionModel>
    <Child name="Finger Joint3"/>
  </RobotNode>

  <RobotNode name="Finger Joint3">
    <Transform>
      <DH a="25.9" d="0" theta="0" alpha="0" units="degree"/>
    </Transform>
    <Joint type="revolute">
      <Limits unit="degree" lo="0" hi="90"/>
    </Joint>
    <Visualization enable="true">
      <File type="Inventor">iv/LeftIndexFinger/leftIndexFinger2.iv</File>
    </Visualization>
    <CollisionModel>
      <File type="Inventor">iv/LeftIndexFinger/col_leftIndexFinger2.iv</File>
    </CollisionModel>
    <Child name="Finger Joint4"/>
  </RobotNode>

  <RobotNode name="Finger Joint4">
    <Transform>
      <DH a="22" d="0" theta="0" alpha="0" units="degree"/>
    </Transform>
    <Joint type="revolute">
      <Limits unit="degree" lo="0" hi="90"/>
    </Joint>
    <Visualization enable="true">
      <File type="Inventor">iv/LeftIndexFinger/leftIndexFingerTip.iv</File>
    </Visualization>
    <CollisionModel>
      <File type="Inventor">iv/LeftIndexFinger/col_leftIndexFingerTip.iv</File>
    </CollisionModel>
  </RobotNode>

</Robot>

Multiple Files

When building complex robot models, usually several parts of the robot can be separated. In order to reflect this fact, robots can be assembled from multiple files. In the following example a robot imports another robot and connects the root node to Joint1. Further, you can see how coordinate axis visualizations are enabled and that a RobotNode can have multiple children, allowing to build tree-like kinematic structures.

<Robot Type="robot1" RootNode="Joint1">

    <RobotNode name="Joint1">
        <Joint type="revolute">
            <Limits unit="degree" lo="-90" hi="45"/>
        </Joint>
        <!-- Imports the kinematic structure form otherRobot.xml and adds otherRobot's rootnode as a child to this node -->
        <ChildFromRobot>
            <File importEEF="true">robot_howto7b.xml</File>
        </ChildFromRobot>
        <Child name="node2.1"/>
    </RobotNode>

    <RobotNode name="node2.1">
        <Transform>
            <DH a="0" d="500" theta="-30" alpha="0" units="degree"/>
        </Transform>
    </RobotNode>

</Robot>

The second file (robot_howto7b.xml) looks like this. The file can also be used as a independent robot model.

<Robot Type="robot2" RootNode="node1">

 <RobotNode name="node1">
   <Child name="node2"/>
   <Child name="node3"/>
 </RobotNode>

 <RobotNode name="node2">
   <Transform>
       <Translation x="0" y="500" z="0"/>
   </Transform>
   <Visualization enable="true">
     <CoordinateAxis type="Inventor" enable="true" scaling="1" text="TCP1"/>
   </Visualization>
 </RobotNode>

 <RobotNode name="node3">
   <Transform>
       <Translation x="0" y="-500" z="0"/>
   </Transform>
   <Visualization enable="true">
     <CoordinateAxis type="Inventor" enable="true" scaling="1" text="TCP2"/>
   </Visualization>
 </RobotNode>

</Robot>

Robot Node Sets

In VirtualRobot so-called RobotNodeSets are used to group joints or to define kinematic chains. A robot node set consists of a set of robot nodes and optionally

  • A root node, defining the topmost node which has to be updated in order to internally re-compute the kinematic structure, e.g. when changing joint values. If not given, the root of the robot is used.
  • A RobotNode defining the Tool Center Point (TCP) coordinate system. This node specifies a TCP for a kinematic chain. The following example shows how a RobotNodeSet is defined. Please note that the order of the joint definitions is preserved for later use.
    <Robot Type="DemoRobot" RootNode="root">
    
       <RobotNode name="root">
         <Child name="joint 1"/>
       </RobotNode>
    
       <RobotNode name="joint 1">
         <Joint type="revolute">
            <Axis x="0" y="0" z="1"/>
         </Joint>
         <Visualization>
           <File type="Inventor">iv/joint.iv</File>
         </Visualization>
         <Child name="node 1"/>
       </RobotNode>
    
      <RobotNode name="node 1">
         <Transform>
             <Translation x="0" y="500" z="0"/>
         </Transform>
         <Visualization>
           <File type="Inventor">iv/ball.iv</File>
         </Visualization>
         <Child name="joint 2"/>
       </RobotNode>
    
       <RobotNode name="joint 2">
         <Joint type="revolute">
           <Axis x="0" y="1" z="0"/>
         </Joint>
         <Visualization>
           <File type="Inventor">iv/joint2.iv</File>
         </Visualization>
         <Child name="node 2"/>
       </RobotNode>
    
       <RobotNode name="node 2">
           <Transform>
               <Translation x="0" y="0" z="500"/>
           </Transform>
           <Visualization>
               <File type="Inventor">iv/ball.iv</File>
           </Visualization>
           <Child name="joint 3"/>
       </RobotNode>
    
       <RobotNode name="joint 3">
           <Joint type="revolute">
             <Axis x="1" y="0" z="0"/>
           </Joint>
           <Visualization>
             <File type="Inventor">iv/joint.iv</File>
           </Visualization>
           <Child name="tcp"/>
       </RobotNode>
    
       <RobotNode name="tcp">
           <Transform>
             <Translation x="0" y="500" z="0"/>
           </Transform>
           <Visualization>
             <File type="Inventor">iv/ball.iv</File>
           </Visualization>
       </RobotNode>
    
       <RobotNodeSet name="my kinematic chain" kinematicRoot="joint1" tcp="tcp">
         <Node name="joint 1"/>
         <Node name="joint 2"/>
         <Node name="joint 3"/>
       </RobotNodeSet>
    
    </Robot>
    

End Effector Definitions

When complex robot systems, such as humanoid robots, should be modeled a logical definition of their end-effectors is helpful especially in the context of grasp and manipulation planning. In order to access the robot's end-effector conveniently it can be defined in the robot's XML definition. An end-effector is a logical collection of static RobtoNodes and so-called actors which are lists of RobotNodes defining a finger. Please note that the RobotNodes have to be defined within the robot's XML definition. The static parts are not moved when the end-effector is accessed (e.g. closed or opened), whereas the actors are moved. As shown in the example below, actors consist of a set of RobotNodes and for each node several options can be specified:

  • name: The name string of the RobotNode. This node must be present in the robot's definition.
  • considerCollisions: Here the behavior for collision detection can be adjusted. Possible options are
    • all (standard): Collisions between the static part and the RobotNode and between other actors and the RobotNode are considered.
    • none The node is not considered for collision detection. E.g. when closing the hand an actor will not stop if this node is in collision.
    • actors: Collisions between the static part of teh hand and the node are not considered, but collisions between other actors and the RobotNode are.
    • static: Only collisions between this node and the static part of the end-effector are considered, while collision between this node and other actors are not considered.
  • direction: Here the moving direction can be inverted by setting this value to -1. Further, the relative speed of moving can be adjusted (the standard value is 1).
    <Robot Type="iCub Left Hand" RootNode="root">
        ...
        <Endeffector name="Left Hand" base="Left Hand Init" tcp="Left Arm TCP" gcp="Left Arm GCP">
            <Preshape name="Grasp Preshape">
                <Node name="Left Hand Thumb Joint1" unit="radian" value="1.3"/>
            </Preshape>
    
            <Static>
                <Node name="Left Hand Palm"/>
                <Node name="Left Hand Thumb Joint1"/>
            </Static>
    
            <Actor name="Left Hand Thumb">
                <Node name="Left Hand Thumb Joint2" considerCollisions="Actors"/>
                <Node name="Left Hand Thumb Joint3" considerCollisions="All"/>
                <Node name="Left Hand Thumb Joint4" considerCollisions="All"/>
            </Actor>
            <Actor name="Left Hand Index">
                <Node name="Left Hand Index Joint2" considerCollisions="Actors"/>
                <Node name="Left Hand Index Joint3" considerCollisions="All"/>
                <Node name="Left Hand Index Joint4" considerCollisions="All"/>
            </Actor>
            <Actor name="Left Hand Middle">
                <Node name="Left Hand Middle Joint2" considerCollisions="Actors"/>
                <Node name="Left Hand Middle Joint3" considerCollisions="All"/>
                <Node name="Left Hand Middle Joint4" considerCollisions="All"/>
            </Actor>
            <Actor name="Left Hand Ring">
                <Node name="Left Hand Ring Joint2" considerCollisions="Actors"/>
                <Node name="Left Hand Ring Joint3" considerCollisions="All"/>
                <Node name="Left Hand Ring Joint4" considerCollisions="All"/>
            </Actor>
            <Actor name="Left Hand Pinky">
                <Node name="Left Hand Pinky Joint2" considerCollisions="Actors"/>
                <Node name="Left Hand Pinky Joint3" considerCollisions="All"/>
                <Node name="Left Hand Pinky Joint4" considerCollisions="All"/>
            </Actor>
        </Endeffector>
    </Robot>
    


Objects and Scenes

Scenes can be defined via XML files, allowing to specify a setup for robots and obstacles. Further, configurations can be defined allowing to easily access them later on. The following tags can be used:

  • Robot: Define a robot with a name and an optional initial configuration initConfig.
    • The File tag specifies the robot's XML file from which the model should be loaded.
    • Files are searched in all dataPaths which are specified in VirtualRobot::RuntimeEnvironment (initially some simox-related standard data paths are set).
    • Optional the attribute path can set to absolute or relative, in order to force absolute or relative (w.r.t. the scene file) path names.
    • Multiple Configurations can be defined, which can be accessed via their name strings.
    • A Configuration is a list of RobotNodes with corresponding joint values.
    • A GlobalPose tag encapsulates a Transfrom tag which can be used to position the robot in the scene.
  • Obstacles can be loaded from files. Here the same syntax is provided as when setting Visualization tags for a RobotNode:
    • The type of 3d model must be specified in the File tag. Again the file names are searched in the paths, defined in VirtualRobot::RuntimeEnvironment. Optionally the attributes path='absolute' or path='relative' allow to specify absolute or scene-file-relative file names.
    • A GlobalPose can be used to position the object.
    • The <UseAsCollisionModel/> tag ensures that the visualization model is used as a collision model.
  • A ManipulationObject is basically a 3d object with predefined grasping information. These objects can also be positioned via the GlobalPose tag.
    <Scene name="Armar3Scene">
    
        <Robot name="Armar3" initConfig="start">
            <File>robots/ArmarIII/ArmarIII.xml</File>
            <Configuration name="start">
                <Node name="Shoulder 1 L" unit="radian" value="-0.85"/>
                <Node name="Shoulder 2 L" unit="radian" value="-0.8"/>
                <Node name="Upperarm L" unit="radian" value="-0.85"/>
                <Node name="Shoulder 1 R" unit="radian" value="-0.85"/>
                <Node name="Shoulder 2 R" unit="radian" value="0.8"/>
                <Node name="Upperarm R" unit="radian" value="0.85"/>
            </Configuration>
            <GlobalPose>
                <Transform>
                    <Translation x="1000" y="0" z="0"/>
                </Transform>
            </GlobalPose>
        </Robot>
    
        <Robot name="Armar3b">
            <File>robots/ArmarIII/ArmarIII.xml</File>           
        </Robot>
    
        <Obstacle name="Box">
            <Visualization>
                <File type="Inventor">objects/iv/box1000x500x300.iv</File>
                <UseAsCollisionModel/>
            </Visualization>
            <GlobalPose>
                <Transform>
                    <Translation x="9000" y="1500" z="150"/>
                    <rollpitchyaw units="degree" roll="0" pitch="0" yaw="90"/>
                </Transform>
            </GlobalPose>
        </Obstacle>
    
        <ManipulationObject name="Plate">
            <File>objects/plate.xml</File>    
            <GlobalPose>
                <Transform>
                    <Translation x="-250" y="0" z="600"/>
                    <rollpitchyaw units="degree" roll="90" pitch="0" yaw="90"/>
                </Transform>
            </GlobalPose>
        </ManipulationObject>
    
    </Scene>
    


Related

Wiki: FileFormat
Wiki: VirtualRobot