Exploring Tekkotsu Programming on Mobile Robots:

Postures and Motion Sequences

Prev: Robot safety
Up: Contents
Next: Walking

Contents: Postures, Constructing PostureMCs, Motion sequences, Constructing motion sequence files, Programming motion sequences

Postures

A "posture" in Tekkotsu is a set of effector states: joint positions, LED states, etc. A PostureEngine object describes a posture, and a PostureMC motion command can be used to move the robot into a desired posture. The simplest way to specify a posture is to write down a set of joint positions in a posture file. Several predefined posture files are supplied with Tekkotsu. Follow the directions below to experiment with them:

Loading a Posture File

Warning: For safety reasons, place the robot on the floor, on a stand, or far enough away from the edge of the desk or table that it cannot fall off if it moves suddenly.

  1. Let the robot move: take it out of "emergency stop" mode by clicking on the "Un-Stop" button in the lower right hand corner of the Controller GUI window. On the AIBO, you should hear a short bark in response. The status indicator in the lower left corner of the window should switch from "Stopped" (red) to "Running" (green). If you instead hear a sound like squealing tires, it means you've stopped the AIBO. In that case, hit the button again to un-stop it.

  2. From the ControllerGUI's Root Control menu, select "File Access".

  3. From the File Access menu, select "Posture Editor". Note that the Posture Editor menu includes a list of effector names and their current states, updated in real time.

  4. From the Posture Editor menu, select "Load Posture".

  5. Double click on the file LIEDOWN.POS. If the robot doesn't move, check again that the ControllerGUI status is "running", not "stopped".

  6. Now select "Load Posture" again and double click on SITUP.POS.

You can browse the memory stick file system to examine one of these posture files by starting at the "Root Control" menu, going to "File Access", selecting the "Files" submenu, and double clicking on a file or directory name. Posture files are in the directory /data/motion on the memory stick. Click on the file LIEDOWN.POS and it will be printed to cout. (Open a telnet connection on port 59000 to see it.) You can also find these files on your hard drive, in ~/project/ms/data/motion.

Posture files always begin with the comment line "#POS" and end with "#END". Here is what LIEDOWN.POS looks like on the AIBO. The first column is the joint name, the second is the joint angle, and the third is the weight, which is normally 1.0. (Weights are used by the motion manager when blending motions together.)

#POS
LFr:rotor       0.946459        1.000000
LFr:elvtr       -0.034906       1.000000
LFr:knee~       0.602027        1.000000
RFr:rotor       0.924253        1.000000
RFr:elvtr       -0.052359       1.000000
RFr:knee~       0.585458        1.000000
LBk:rotor       -2.042035       1.000000
LBk:elvtr       0.245109        1.000000
LBk:knee~       1.978277        1.000000
RBk:rotor       -2.042035       1.000000
RBk:elvtr       0.233709        1.000000
RBk:knee~       2.100212        1.000000
#END
File LIEDOWN.POS

When the AIBO is stopped, you can bend the legs, head, and tail to any desired position, and the Posture Editor will update its list of joint positions to reflect their current values. Once the AIBO is un- stopped, the Posture Editor will let you numerically edit the joint positions by selecting one or more items in the menu and entering a number in the input text field.

Once you have the posture the way you like it, you can use the "Save Posture" command to write the joint angles to the memory stick. Make sure the file name uses the 8.3 name format (no more than 8 characters, a period, and a 3 character extension), with the extension ".POS". If you do not specify a path, the files will be stored in /ms/data/motion. You should copy the file to the corresponding location in the ~/project/ms/data/motion directory on your hard drive, so that it will be in sync with your memory stick.

Constructing PostureMCs

A PostureMC has two components: a PostureEngine, which describes the posture in terms of joint angles, and a MotionCommand, which is reponsible for achieving those joint angles. The PostureEngine documentation describes the available functions for creating and manipulating postures.

There are several ways to construct PostureMCs. Some involve advanced concepts we won't get into in detail here, but we'll quickly survey the possibilities: You could:

PostureMC implements a very simple type of motion: it moves the all joints directly to their specified target positions. For complex postural changes like moving from a sitting to a standing position, it may not be safe to move the joints directly and simultaneously to their final values: the robot could fall over. Complex actions should instead be implemented as a sequence of smaller motions designed to maintain balance and prevent interference between limbs, which could cause "jamming". Jamming will cause the AIBO to power itself down as a protective measure.

For these reasons, it is usually preferable to use a MotionSequenceMC rather than a simple PostureMC for substantial changes in posture.

Motion sequences

A motion sequence is a kind of script that moves one or more joints through a sequence of keyframes, specified by postures. By adjusting the time between keyframes you can control how quickly the joint moves from one position to the next.

Tekkotsu provides several built-in motion sequences which you can experiment with.

Running a Motion Sequence

Warning: For safety reasons, place the robot on the floor, on a stand, or far enough away from the edge of the desk or table that it cannot fall off if it moves suddenly.

  1. Turn off emergency stop mode by clicking on the Un-Stop button in the lower right hand corner of the Controller GUI window. You should hear a short bark in response. (A sound like squealing tires means you've stopped the AIBO; click on the button again to un-stop it.)

  2. From the ControllerGUIs Root Control menu, select "File Access".

  3. From the File Access menu, select "Run Motion Sequence".

  4. Double click on "PAN_HEAD.MOT".

  5. The other motion sequences involve whole body motion. Try some, taking care that the AIBO will be safe if it falls over.

Motion sequence files always begin with the comment line "#MSq" and end with "#END". Here is what PAN_HEAD.MOT looks like:

#MSq
degrees

advanceTime  50
NECK:tilt	15
NECK:roll	0

advanceTime  850
NECK:pan~	-45

advanceTime  900
NECK:pan~	45
NECK:tilt	15
NECK:roll	0
#END
File PAN_HEAD.MOT

The "degrees" command indicates that joint values are in degrees. There is also a "radians" command.

The "advanceTime n" command (also called delay in earlier versions of Tekkotsu) advances the time index by n milliseconds. The convention is that you advance the time index first, then specify the new joint positions to be achieved at that time. The system will adjust the joint velocities so that the joints arrive at their target positions at the specified times. So the motion sequence above takes 50 msec to move the head from its initial position (whatever that might be) to a neutral position (tilt 15 degrees and roll 0.). After another 850 msec the neck should be panned 45 degrees to the right. Finally, after another 900 msec, the neck should be panned 45 degrees to the left.

Other motion sequence commands include "load posturefile", which loads a set of joint angles from a file, "overlay filename", which overlays a posture file onto the sequence presently being constructed, and "setTime t", which sets the time index to an absolute time value, rather than adjusting it by a relative value as the advanceTime (or delay) command does.

Constructing motion sequence files

There are many ways to construct a motion sequence. One way is to create a motion sequence file using a text editor, and have it set joint angles directly, or load in various posture files. You can then place this file in the project//ms/data/motion directory and use "make update" to copy it onto the memory stick. Here is an example file that takes the AIBO through a series of postures:

#MSq
advanceTime 2000
load stand.pos

advanceTime 2000
load situp.pos

advanceTime 2000
load liedown.pos
#END
File STANDLIE.MOT

The STANDLIE.MOT motion sequence tells the AIBO to stand, then sit up, and then lie down. The sequence is poorly designed: if you try it with the AIBO starting out in the lying down position, you will see that going from stand to sit causes it to nearly tip over.

Testing a New Motion Sequence File

  1. Create the file STANDLIE.MOT in project/ms/data/motion.

  2. Do "make update" to copy the file onto your memory stick.

  3. Reboot the AIBO and turn off emergency stop mode by clicking on the Un-Stop button in the lower right hand corner of the Controller GUI window.

  4. From the ControllerGUI's Root Control menu, select "File Access".

  5. From the File Access menu, select "Run Motion Sequence".

  6. Double click on "STANDLIE.MOT".

A tricky aspect of motion sequences results from the fact that each joint maintains its own list of keyframes, independent of the other joints. When a new position is specified for a joint, the MotionSequenceEngine calculates a speed that will move the joint smoothly from its last position, at the time it was specified, to the new position. It doesn't matter what the other joints have been doing. This allows for head and body motions to be controlled independently, but it can lead to nonintuitive results when constructing motion sequences if you don't pay attention to when each joint was last updated. For example, supposed we want to move the head and tail to neutral positions, then shake the head left and right, return the head to neutral, and then wag the tail. The example motion sequence below will not do what we expect unless the line in red is included:

#MSq
degrees

advanceTime 50
NECK:pan~ 0
NECK:tilt 0
TAIL:pan~ 0
TAIL:tilt 0

advanceTime 1000
NECK:pan~ 90

advanceTime 1000
NECK:pan~ -90

advanceTime 500
NECK:pan~ 0
TAIL:pan~ 0

advanceTime 500
TAIL:pan~ 90

advanceTime 500
TAIL:pan~ -90

#END
File HEADWAG.MOT

The problem with HEADWAG without the red line is that the tail's position is specified as neutral at time 50, and the joint us not referenced again until the first wag position is given. So the tail wag motion will actually begin at time 50, not time 2550, and it will be spread out over 3000 msec so that the tail is at 90 degrees at time 3050. To achieve the effect we want, with the tail starting to move only after the head shake is completed at 2550, we need to re-specify the tail's position just before the tail is to begin moving. That's what the line in red is for.

Explore more:

  1. Design a better motion sequence to take the AIBO from lying down to standing to sitting, without risk of toppling over. There are a number of approaches you could take. For example, you could create an intermediate posture between stand and sit that moves the AIBO to a safer position.

  2. Stop the AIBO by clicking on the "stop" button in the ControllerGUI. Then try to run a motion sequence. What sound does the robot make? What happens when you then un-stop the robot?

  3. Suppose you want the AIBO to move to a pose and hold it for 5 seconds before moving on to another pose. The way to do this is to move to the first pose, then advance the time by 5 seconds and move to the same pose again. Then advance the time normally and move to the next pose. Try it and see how it works.

  4. Use the Posture Editor to explore the meaning of the various LED settings. Figure out how to make the AIBO's ears glow green (on the ERS-7) or its tail glow blue (on the ERS-210). Then, design a motion sequence to display s brief series of patterns and colors.

  5. Suppose you want the dog to stand up and pan its head to the left at the same time, then lie down again while panning its head to the right. Construct a posture file for panning the head to the left, and another for panning to the right. Then construct a motion sequence file that uses the load, setTime, and overlay commands to create the compound sequence described above.

Programming Motion Sequences

More sophisticated motion sequences can be constructed dynamically by creating a MotionSequeceMC motion command. The example code below demonstrates several different ways of specifying joint positions in a motion sequence: by loading a posture file; by constructing a PostureEngine object and setting some of its OutputCmds; or by inserting keyframes (OutputCmds) directly into the MotionSequenceMC. Note the use of the deg2rad function to convert degrees to radians; it's defined in Shared/mathutils.h.

#ifndef INCLUDED_DstBehavior_h_
#define INCLUDED_DstBehavior_h_
 
#include "Behaviors/BehaviorBase.h"
#include "Motion/MotionManager.h"
#include "Motion/MotionSequenceMC.h"
#include "Shared/mathutils.h"     // for deg2rad function

using namespace mathutils;

class DstBehavior : public BehaviorBase {
public:
  DstBehavior() : BehaviorBase("DstBehavior") {}
 
  virtual void DoStart() {
    BehaviorBase::DoStart();

    float const leftGlanceAngle = deg2rad(60.0);
    float const rightGlanceAngle = deg2rad(-70.0);
    float const downGlanceAngle = deg2rad(-55.0);

    SharedObject<MediumMotionSequenceMC> mseq_mc;

    // 1 sec to move head to look straight ahead
    PostureEngine lookstraight;
    lookstraight.setOutputCmd(HeadOffset+TiltOffset, 0.0);
    lookstraight.setOutputCmd(HeadOffset+PanOffset, 0.0);
    mseq_mc->advanceTime(1000);
    mseq_mc->setPose(lookstraight);

    mseq_mc->advanceTime(5000);    // 5 secs to sit up
    mseq_mc->LoadFile("situp.pos");

    mseq_mc->advanceTime(1000);    // 1 sec to glance left
    mseq_mc->setOutputCmd(HeadOffset+PanOffset, leftGlanceAngle);

    mseq_mc->advanceTime(2000);    // hold glance for 2 secs
    mseq_mc->setOutputCmd(HeadOffset+PanOffset, leftGlanceAngle);


    mseq_mc->advanceTime(1000);    // 1 sec to glance right
    mseq_mc->setOutputCmd(HeadOffset+PanOffset, rightGlanceAngle);

    mseq_mc->advanceTime(2000);    // hold glance right for 2 secs
    mseq_mc->setOutputCmd(HeadOffset+PanOffset, rightGlanceAngle);
    mseq_mc->setOutputCmd(HeadOffset+TiltOffset, 0.0);	// re-specify tilt in preparation for moving

    mseq_mc->advanceTime(1000);    // 1 sec to glance down
    PostureEngine currentpose("situp.pos");  // update body joint time indices
    currentpose.setOutputCmd(HeadOffset+TiltOffset, downGlanceAngle);  // and tilt the head down
    mseq_mc->setPose(currentpose);

    mseq_mc->advanceTime(5000);    // 5 secs to lie down
    mseq_mc->LoadFile("liedown.pos");
    mseq_mc->setOutputCmd(HeadOffset+TiltOffset, downGlanceAngle);

    motman->addPrunableMotion(mseq_mc);
    DoStop();
  }
 
};

#endif

Notice that we did not use an MMAccessor to modify the motion command. The reason is that all the operations on the MotionSequenceMC object are being performed before the motion command is registered with the motion manager. Therefore we have no need of the mutual exclusion mechanism provided by MMAccessor.

Note also that the setOutputCmd() function wants an OutputCmd object as a second argument, but the code above supplies a floating point number. OutputCmd's constructor provides an implicit type conversion that permits this shortcut, so writing setOutputCmd(j,x) is equivalent to writing setOutputCmd(j,OutputCmd(x)).

MotionSequenceMC objects must be of fixed size because of the way they are allocated in shared memory. Larger objects can store more keyframes. Tekkotsu provides a built in range of pre-sized motion sequence commands, shown below; the list is taken from MotionSequenceMC.h. The constant NumOutputs, defined in ERS7Info.h, is 47, so a TinyMotionSequenceMC, which can hold 2 completely-specified postures, has room for 94 keyframes. It can hold considerably more postures if only a few joints are being controlled at each step. For example, Tekkotsu-supplied posture files like STAND.POS specify only leg joint positions; they do not control the head or the LEDs.

Motion Sequence
Type Name
# Fully-Specified
Postures
# Keyframes
TinyMotionSequenceMC2 94
SmallMotionSequenceMC3 141
MediumMotionSequenceMC6 282
LargeMotionSequenceMC11 517
XLargeMotionSequenceMC261222

If you save a posture from the Posture Editor, all 47 output values will be saved. However, if you don't want to your posture to control certain output values, you can click on the Weights item in the Posture Editor and set their weights to zero, in which case they will not be stored in the .POS file.. Alternatively, you could manually edit the .POS file to remove outputs you don't care about.

Prev: Robot safety
Up: Contents
Next: Walking


Last modified: Mon Mar 17 02:48:41 EDT 2008