Simulation Construction Set

Simulation Construction Set

  • IHMC Home
  • All IHMC Docs
  • About IHMC

›Creating Robot with Multiple Joints

Getting Started

  • Quick Start
  • Requirements
  • Using IHMC Open Robotics Software .jar releases with Maven/Gradle
  • Building .jars
  • Depending Directly on the Source

Using the SCS GUI

  • Running a simulation
  • Changing the Camera Settings
  • SCS Variables
  • Graphing Variables
  • Simulation Replay
  • Data Buffer
  • Exporting Data
  • Export Snapshots and Video of the 3D View

Creating a New Simulation

  • Summary
  • Create a New Project
  • SimplePendulumSimulation.java
  • SimplePendulumRobot.java
  • Run the simulation

Adding Control to a Simulation

  • Summary
  • Adding control to a simulation
  • Run the simulation

Creating Links

  • Summary
  • Creating Links
  • Run the Simulation

Creating Robot with Multiple Joints

  • Summary
  • Create a New Package
  • Mobile Simulation
  • Initial Variables in MobileRobot Class
  • MobileRobot Class Description

Ground Contact Modeling

  • Summary
  • Create a New Package
  • Create a New Class FallingBrickSimulation
  • Create a New Class FallingBrickRobot
  • Create a New Class WavyGroundProfile
  • Description and Analysis

Implementing Closed-Chain Mechanisms Using External Force Points

  • Summary
  • Implementing Closed-Chain Mechanisms
  • FlyballGovernorSimulation Class
  • FlyballGovernorRobot Class
  • FlyballGovernorSimpleClosedLoopConstraintController Class
  • FlyballGovernorCommonControlParameters Class
  • Description and Analysis

MobileRobot Class Description

1. Add the following code to the MobileRobot Class

Examine the lines where the 3 different levels of gimbal joints are defined. Note how in Java, Strings can be concatenated using " " + " ", and that integers will be turned into Strings in this way. For example, if i=3, then "gimbal1_" + i "_x" will result in "gimbal1_3_x".

Look at the offset Vector3d for each joint level.

  • The first offset, (0.0, 0.0, 1.0), simply places the mobile into the air.
  • The second is (xOffset, yOffset, -L1/2.0) where (xOffset, yOffset) is either (L1, 0), (-L1, 0), (0, L1), or (0, -L1).
    • This is from the second level of 4 gimbal joints to each of their parent joint, which is the first gimbal joint.
    • The top crossbar goes down L1/2.0 and in each of the four directions by L1. Therefore, the given offsets should work.
  • The third is (xOffset, yOffset, -L2/2.0) where (xOffset, yOffset) is either (L2, 0), (-L2, 0), (0, L2), or (0, -L2).
    • This is the final level of 16 gimbals from their parents above them. The smaller crossbars go down L2/2.0 and in each of the four directions by L2. Therefore, the given offsets should work.

Note that the joint offsets are completely independent of any translations or rotations which are performed while specifying links:

firstGimbal = new GimbalJoint("gimbal_x", "gimbal_y","gimbal_z", new Vector3d(0.0,0.0,1.0), this, Axis.X, Axis.Y, Axis.Z);

nextGimbal = new GimbalJoint("gimbal1_" + i + "_x", "gimbal1_" + i + "_y", "gimbal1_" + i + "_z", new Vector3d(xOffset, yOffset, -L1 / 2.0), this, Axis.X, Axis.Y, Axis.Z);

finalGimbal = new GimbalJoint("gimbal2_" + i + "_" + j + "_x", "gimbal2_" + i + "_" + j + "_y", "gimbal2_" + i + "_" + j + "_z", new Vector3d(xOffset, yOffset, -L2 / 2.0), this, Axis.X, Axis.Y, Axis.Z);

Note that viscous damping is set for each joint

Viscous damping of the form tau=damping * velocity will be added on top of any torques due to joint limits or a control system. For this simulation, the mobile is completely passive and damping is the only source of joint torque:

firstGimbal.setDamping(DAMP1);
nextGimbal.setDamping(DAMP2);
finalGimbal.setDamping(DAMP3);

Note that the function initJoint is called for each joint

initJoint creates random values for the position and velocity of each of the 3 degrees of freedom for the GimbalJoint and sets the state using GimbalJoint.setInitialState();
joint.setInitialState(init_q1, init_qd1, init_q2, init_qd2, init_q3, init_qd3);

Creation of the joints, including their offsets, damping, and initialization should be clear

  • If not, review the above joint generation.

  • Note that creation of the joints is completely independent of the creation of the link shapes, and that the joint locations and functions will be the same no matter which links are attached to them.

2. Now let's create the links

Add the following to MobileRobot after super("Mobile");

We start with the top link, which is a flattened cylinder. We add it to the robot using Robot.addStaticLink(Link) since it is not attached to any joints and therefore cannot move. Since the first joint of the robot had an offset of (0.0, 0.0, 1.0), we need to translate to (0.0, 0.0, 1.0+R1/2.0) before adding this link:

Link topLink = new Link("top");
LinkGraphicsDescription topLinkGraphics = new LinkGraphicsDescription();
topLinkGraphics.translate(0.0, 0.0, 1.0+R1/2.0);
topLinkGraphics.addCylinder(L1/60.0, L1/3.0, YoAppearance.DarkBlue());
topLink.setLinkGraphics(topLinkGraphics);
this.addStaticLink(topLink);

3. Next, we will add and examine the steps creating the crossbar geometry

Add the following to MobileRobot:

We first create the upper sphere-capped cylinder which projects downward. Since the origin of a cylinder is the center of its base, we must first translate down the length of the upper cylinder (length/2.0) before adding it:

linkGraphics.addSphere(R1, YoAppearance.Red());
linkGraphics.translate(0.0, 0.0, -length/2.0);
linkGraphics.addCylinder(length/2.0, radius);

Now look at creating the 2 horizontal cylinders, capped with red spheres on both ends

They both are created identically, except that they are translated and rotated differently. The first one is created as follows:

  • This line brings us back to the gimbal joint: linkGraphics.identity();

  • Translate down length/2.0 and in the X direction by length: linkGraphics.translate(length, 0.0, -length/2.0);

  • Rotate by –Math.PI/2.0 about the Y axis. This will now make the Z axis point in the direction in which we wish to place our cylinder (along the original X axis): linkGraphics.rotate(-Math.PI/2.0, Axis.Y);

  • Add the cylinder: linkGraphics.addCylinder(2.0*length, radius);

  • Add a sphere to cap this end of the cylinder: linkGraphics.addSphere(radius, YoAppearance.Red());

  • Translate along the Z axis to the other end of the cylinder: linkGraphics.translate(0.0, 0.0, 2.0*length);

  • Cap the other end of the cylinder: linkGraphics.addSphere(radius, YoAppearance.Red());

The second cylinder is identical to the first, except for the initial translation and rotation

  • Translate down length/2.0 and in the Y direction by length: linkGraphics.translate(0.0, length, -length/2.0);

  • Rotate by Math.PI/2.0 about the X axis. This will now make the Z axis point in the direction in which we wish to place our cylinder (along the original Y axis): linkGraphics.rotate(Math.PI/2.0, Axis.X);

4. Add the following randomShape code to the MobileRobot Class

This method will randomly select a string length, an appearance and a shape for each of the 16 toys at the ends of the mobile. How this code works should now be clear to you.

If not, try to experiment with it, or try making a simulation of a different style of mobile to become comfortable with joints and links.

For more detailed information on joints check out the Robots and Joint API Page

Full Code for Classes

MobileSimulation Class

MobileRobot Class

← Initial Variables in MobileRobot ClassSummary →
  • 1. Add the following code to the MobileRobot Class
  • 2. Now let's create the links
  • 3. Next, we will add and examine the steps creating the crossbar geometry
  • 4. Add the following randomShape code to the MobileRobot Class
  • Full Code for Classes
Simulation Construction Set
Docs
Quick StartSoftware Documentation
Community
GitHubFacebookTwitterYouTube
Copyright © 2018 IHMC Robotics