15-494 Cognitive Robotics
Spring 2007
Course Links:  Main Lectures Labs Homeworks

Tekkotsu Links:   Tutorial Resources Bugs CVS

Cognitive Robotics: Lab 2

Part I: MotionCommand tutorial

Read through the Motion Commands section of the Tekkotsu tutorial at http://www.cs.cmu.edu/~dst/Tekkotsu/Tutorial/. If you want to try out some of the example code on the robot, you can cut and paste it into a file in your project directory.

Part II: Exercises

We only expect you to complete and demonstrate one of the following five tasks for lab today. Three more of them will form your first homework assignment, so if you finish the lab with time remaining, feel free to press on. You only have to do a total of four of these five tasks; you can pick which one to skip. Email your completed assignment to Dave by Friday, Feb. 1. Please use the subject '15-494: Handin 1', as per handin instructions.

Happy Metronome!

Use TailWagMC to wag the tail slowly, and bark each time the tail passes through the neutral position (straight up). Also, flash the LEDs each time the tail changes direction. TailWagMC posts a status event whenever a direction change occurs.

To detect when the tail goes past neutral, you will need to look for a change in sign of the value returned by TailWagMC::getPan(). By subscribing to sensorEGID events, you can be "woken up" each time a joint value changes. (Specify a source ID of SensorSrcID::UpdatedSID and omit the event type. A sensorEGID event is posted every 32 msec when the sensor values are updated. Where is SensorSrcID defined?) Compare the current pan value with the previous one, which you should cache in a member variable.

In order to play a sound, #include "Sound/SoundManager.h" and then call:
There are more options available, such as using loadFile() and c rReleaseFile() to preload the sound file in order to reduce latency. This is discussed in the SoundManager documentation and the Sound section of the tutorial. Sounds are stored in ms/data/sound of your project directory, and can be interactively played from the ControllerGUI via Root Control > File Access > Play Sound.

Listen for presses of the back buttons and use them to control the period of the cycle. (The details of how to interpret the button presses are up to you -- a tap on one button might increment the speed by a constant or a percentage, or you might have to hold the button down, etc.)

Looming Ball Indicator

Use LedMC to display the size of the pink ball in the camera image.

Note that most of the LED functionality is provided by LedMC's superclass, LedEngine, so that is the reference page you'll want to see. (The LED management is abstracted away from the MotionCommand to make it easier to recombine LED effects in other MotionCommands)

Refer to the Behaviors lecture for help with subscribing to vision events. Once you have received a vision event, you will want to use the VisionObjectEvent::getObjectArea() function to determine how large the ball is. This function returns a value in the range 0-1 reporting what percentage of the camera frame is filled by the object. (There are more accurate ways to judge distance if you are willing to make assumptions regarding the size or placement of the object, but we aren't concerned with accuracy for this task.)

Once you have determined the size of the ball, use LedEngine::displayPercentage() to display this information. Experiment with the different styles this function allows.

Wag the Dog

Why does a dog wag its tail? Because a dog is smarter than its tail.
If the tail was smarter, the tail would wag the dog.
Control the head with the tail, joystick-style. To allow the tail to be moved freely, use the following code:
#include "Motion/PIDMC.h"
Class Member:
MotionManager::MC_ID freetailID;
// The PIDMC is a motion command which controls PID parameters.
// The "0" below indicates the joints should be "disabled" (O power)
SharedObject<PIDMC> freetail(TailOffset,TailOffset+NumTailJoints,0);
Once you are able to move the tail freely, (only when the emergency stop is turned off however!) read the tail's position from state and use these values to control the head's tilt and pan (or nod and pan if you wish). Rescale the tail joint positions so they properly span the range of head joint positions. See the outputRanges variable in ERS7Info.h.


Pick a random button-associated LED, turn it on, and wait until the user pushes the corresponding button to turn it off again, then pick another. Get creative! Add sounds, LED effects, time-outs, memory testing (e.g. "Simon"), etc.

For quick reference here is a list of "button-associated" LEDs:

Button nameButton offsetWhite LED maskColor LED mask
Head buttonHeadButOffsetHeadWhiteLEDMaskHeadColorLEDMask
Front back buttonFrontBackButOffsetFrBackWhiteLEDMask   FrBackColorLEDMask
Middle back buttonMiddleBackButOffset   MdBackWhiteLEDMaskMdBackColorLEDMask   
Rear back buttonRearBackButOffsetRrBackWhiteLEDMaskRrBackColorLEDMask

In order to choose a random number between 0 and n, it's enough to simply write rand()%n. Note that '%' is the 'mod' operator in C and most derived languages. You don't need to call srand() to initialize the random number generator; that is done for you at boot.)

Curious AIBO

Using the Nod and Tilt joints together (when looking forward) can provide a sort of "zoom" feature, where the AIBO can stretch its neck to get a closer look, or pull back to get an overview.

Write a behavior to subscribe to the sensor information (sensorEGID) and monitor the distance readings (state->sensors[{Near,Far}IRDistOffset]). Use this information to try to keep the AIBO 40 mm from whatever is in front of it.

You may find the Sensor Observer control (available under Root Control > Status Reports) useful for experimenting with the IR sensor. First select the sensors you want to see from the lower section, and then you can view the values in the Controller itself by selecting "Real-time View".

Dave Touretzky and Ethan Tira-Thompson