5.5. Rigging Robots

If you built a robot inside Omniverse USD Composer or used importers that do not carry over joint information, you’ll need to rig the robot before it can move like an articulated robot and be controlled by Omniverse Isaac Sim APIs. This involves defining the types of joints between the body parts and setting the parameters that governs the joints’ behavior, such as stiffness and damping. This tutorial covers step-by-step instruction on how to rig a forklift.

5.5.1. Learning Objectives

In this tutorial, we will start with an unrigged forklift USD asset, and walk through the steps of turning it into a forklift that can move and driven by Omniverse Isaac Sim commands.

5.5.2. Getting Started


Reference USDs

We provide three USD assets relating to this tutorial in our sample assets,

  1. Unrigged Forklift: Isaac/Samples/Rigging/Forklift/forklift_b_unrigged_cm.usd

  2. Rigged Forklift: Isaac/Samples/Rigging/Forklift/forklift_b_rigged_cm.usd

  3. Rigged Forklift converted to meters: Isaac/Robots/Forklift/forklift_b.usd

This tutorial will guide you through the steps for going from file 1 to 3. The rigged assets serve as a reference for the final goal.

5.5.3. Rigging the Robot Identify the Joints

Before making any modifications to the asset, the first step of rigging a robot is to identify the joints on the robot, both actuated and unactuated ones. The joints govern how all the mesh components are organized, and identifying the type and their degrees of freedom (DOF) are key in making sure the robot moves as expected once rigged.

For the forklift, there are 7 DOF in total:

  • there are 4 smaller roller wheels at the front. Unactuated, revolute joints, and each have one degree of freedom for rotation about a single axis.

  • The fork has linear motion relative to the main body of the forklift as it moves up and down to pick up objects stacked on the pellet, which means there is one actuated, prismatic joint between the fork and the body.

  • The bigger wheel at the rear end is responsible for both propel the forklift, as well as turning it. So there are two actuated joints related to this wheel: a revolute joint that spins the wheel around its central axis to provides the forward/backward movement, and another revolute joint between the rear wheelbase and the forklift body, that provides the pivot to turn the forklift. Organize Hierarchy

First open the unrigged forklift asset Isaac/Samples/Rigging/Forklift/forklift_b_unrigged_cm.usd. Depending on the importer used and the original asset’s setup, the unrigged structure of the USD could have no hierarchy in terms of how parts are organized, with every single component being listed independently on the stage tree. This makes it difficult to read and navigate, but more importantly, it does not define which objects are moving as a group, like a single link of the robot, and how these groups are related to each other.

Forklift No Transform

All meshes that are children of a parent prim are expected to move together when the parent prim moves. For example, the sticker and chains on the meshes are a part of the forklift body, and the entire body, no matter how many screws or blocks are used to make up the body, it can be considered as a single link of this robot. So we should organize them under a single parent ‘body’ prim. This ensures when the ‘body’ moves, all children parts that make up the body are moving together.

To organize prims for the forklift:

  1. Create two XForms called ‘body’ and ‘lift’.

  2. Move all the meshes that make up the forklift body under the ‘body’ Xform, and the operator cab meshes under the ‘lift’ Xform. For ease of use, the meshes provided in the USD file are sorted according to their hierarchy. All meshes above ‘Looks’ are a part of the ‘lift’ XForm. Meshes below ‘Looks’ (Right Chain Wheel to Body Glass) are a part of the ‘body’ XForm. Remaining are for the wheelbase and wheels.

  3. Create new Xforms for the back wheel, back wheel swivel, and separate prims for each of the front roller supports.

  4. It will be easier to set the joints if we align the frame of the Xform to the frames of the respective wheels. To do so, for each wheel, select the mesh, and in its property tab under Transform, there are two components Translate and Translate:pivot. The newly created Xform’s transform should be the sum of those two components. For example, if translate is at \(X=x_1, Y=y_1, Z=z_1\), and translate:pivot is at \(X=x_p, Y=y_p, Z=z_p\), then the transform of the newly created Xform should be set to: \(X = x_1+ x_p , Y = y_1 + y_p , Z = z_1 + z_p\).

  5. Translate of the wheel mesh needs to be set to the inverse of the Translate:pivot property of the corresponding mesh. For example, if Translate is \(X, Y, Z\) and Translate:pivot is \(X_p, Y_p, Z_p\), so now, set the translate to \(-X_p, -Y_p, -Z_p\).

  6. Move the corresponding mesh under the XForm, this will define the parent-child relationship between them.

The resultant hierarchy should look like this:

Forklift Transform


If you got stuck in this this section, checkout the Rigged Forklift: Isaac/Samples/Rigging/Forklift/forklift_b_rigged_cm.usd asset for reference. Assign Collision Meshes

The next step is ensuring the collision properties are set correctly for the meshes. If no collision properties are set, then as the robot moves, it can self penetrate depending on the joint configuration.

The correct collision meshes for the body and the lift are already set for the USD provided, so you do not need to set them up manually. But for reference, the steps to set the collision for the ‘SM_Forklift_Body_B01_01’ are:

  1. Select the ‘SM_Forklift_Body_B01_01’ mesh under the ’lift’ Xform, right click and Add -> Physics -> Collider Preset. The default collision approximation is via Convex Hull which can be found when you scroll under the property tab for the mesh selected and find the collision section.

  2. To visualize the colliders, click on the ‘eye’ icon near the top right of the Viewport, select Show By Type -> Physics -> Colliders -> Selected. You should now be able to see a Pink outline when you select the mesh we just added collision to. This approximation is not suitable as the collision region covers large areas that are not part of the fork, and are regions that are necessary to allow other objects to exist.

  3. To make a better approximation of the collision mesh, select the ‘Convex Decomposition’ approximation. The visualization for the collision mesh should be updated and we can see that the mesh generated this time covers more of the collidable surface as it is a tighter approximation.

Follow the same process for other meshes as well which will interact with each other via joints. Set the Convex Decomposition approximation for the ‘SM_Forklift_BackWheelbase_B01_01’ mesh which will be a part of the swivel.

Forklift Convex Decomposition
Forklift Convex Hull

The process for the wheels is a little different, any collision approximation which is not smooth and captures the exact shape and curvature of the wheel will cause ‘bumpy’ motion when attempting to drive the wheel. This can be avoided by using a cylinder to approximate the collision mesh.

  1. Go to Create -> Shape -> Cylinder.

  2. Set the scale to X=0.16, Y=0.16, Z=0.08 and Orient along Y=90.

  3. Right click and create 4 duplicates of this cylinder, for each of the 4 front roller wheels.

  4. Drag the cylinders first under the respective wheel’s Xform and change their transform about all axes to 0. This will align the cylinder axis and the Xform axis completely.

  5. Right click on the cylinder and Add -> Physics -> Collider.

  6. Following the same process for the back wheel, the cylinder scale should be modified to X=0.3, Y=0.3, Z=0.1, orient along Y=90. because of its bigger size.

  7. Ensure all xforms have physics set to rigid body by clicking Add>Physics>Rigid Body. Remember rigid body prims cannot have children that are also rigid bodies.

We have now set up all the appropriate collision meshes and properties and can move on to adding the joints.

Forklift Cylinder Collision Approximation Add Joints, Drives, and Articulations

In this step, we will add appropriate joints for the Forklift.

Prismatic Joint

The first joint which we will look at is the joint between the forklift body and the fork. We want linear motion between the two bodies, and the fork should move up and down relative to the body of the forklift.

  1. Select the ‘lift’ Xform and while holding the ‘Ctrl’ key select the ‘body’ Xform. While the two prims are highlighted, right click and Create -> Physics-> Joints -> Prismatic Joint.

  2. Find the newly created prismatic joint, select it. Under the properties tab, set the axis to ‘Z’ axis, this denotes that the linear motion between the two bodies is in along the Z-axis.

  3. Set the limits for the joint in the Property tab, for now let’s set it to -15 and 200.

  4. Add a Linear Drive for this joint by Left clicking on the joint, and selecting Add -> Physics -> Linear Drive.

  5. Set the Damping = 10000 and Stiffness to 100000. Set target position to -15 so that the fork can start its initial position close to the ground.

    Forklift Prismatic Joints

Revolute Joints

For all the roller support wheels, we need to create revolute joints.

  1. Select the ‘body’ XForm, holding the ‘Ctrl’ key select any of the roller wheel XForms. Right click -> Create -> Physics -> Joint -> Revolute Joint. You should see a Revolute joint added under the Xform for the wheel.

  2. The joints should appear in the expected location. If not, make sure that the location of the joint matches the with the rotation axis of the wheel, and make sure to set the rotation axis to “X”.

  3. Follow the same process for the three remaining roller supports of the forklift.

Next, we will add the last two joints which will be responsible for driving and turning the forklift.

  1. Select the ‘back_wheel_swivel’ and ‘back_wheel’ XForms and add a revolute joint between them. The location of this joint should match with the center of the back wheel.

  2. Add an angular drive to this joint with the following properties: Damping=10000, stiffness = 100

  3. Select the ‘body’ and ‘back_wheel_swivel’ XForm and add a joint between them. Make sure the axis of rotation is set to Z.

  4. This joint will enable turning of the forklift so change the axis of the joint to Z axis and lower, upper limits as -60 and 60. This is the range of the angles in degrees that the wheelbase would rotate.

  5. Add an angular drive with the following properties: Damping = 100, stiffness=100000.

  6. Remember to add a Physics Scene and Ground Plane before hiting Play

    Forklift Revolute Joints

Add Articulation

The last step is adding articulation to the Forklift, and put all the joints into a single articulation chain, which makes it easier for the physics solver when solving for articulated objects such as a robot. This has already been added for the prim in the reference usd assets. But if not, to put select and right click on the ‘SMV_Forklift_B01_01’ Xform and Add -> Physics -> Articulation Root. Under properties, disable the ‘Self collision’ check box.

The asset you have at this point should be similar to the Rigged Forklift asset provided. Converting Asset to a Different Unit

Our original asset is in centimeters, we can convert it to meters by using the USD Unit Converter tool under Isaac Utils from the top menu bar options. In case the wheels look out of place after processing, set the Transform:Pivot component of the corresponding meshes to zero (front 4 roller wheels, back wheel and back wheel swivel). The asset you have at this point should match the Rigged Forklift in Meters asset provided.

We can now play around with the Forklift, set the back wheel velocity to -200 in the Angular Drive section for the joint. On hitting play, you should be able to see the forklift move forward.

5.5.4. Summary

In this tutorial, we took an unrigged forklift USD asset, organized its structure, and added collision, joints, and drives, and turned it into a forklift that can move and driven by Omniverse Isaac Sim commands. Troubleshooting Tips

  • If upon “playing” the simulation or after some movements, your robot explodes, check if any of the collision meshes are colliding with each other.