Teleoperation Tutorial
Last Modified: 2006-09-08
find:

basket

Acroname Robotics  

Related
Products

Product image for Garcia Robot
Garcia Robot

Contents

Overview

This tutorial discusses a C++ program running on a host computer that uses the Garcia API to communicate with a Garcia robot.  The program takes user input from a joystick or gamepad and converts it to motion commands that are sent across the serial link. 

Note

This example will be included in Build 20 of the Garcia API and BrainStem software downloads. 

Note

This example is written for a PC.  It works best with a Garcia that has the wireless link option. 

The Task

How can I send arbitrary steering commands to the Garcia but still utilize the robot's automatic sensing capabilities?

The Design

A Garcia can perform several parameterized motions using a set of primitives: go straight, turn, hug wall, etc.  These motions are great for predetermined tasks, but can't be modified once started.  One of the behaviors built into the Garcia is a Null primitive.  The null primitive does not perform any motions at all.  Instead, this primitive waits for speed commands received across the serial link and checks the robot's sensors to make sure the commands do not cause an error.  If the speed command is safe, the robot will move. 

Using the Null primitive along with a control loop to update the motor speeds will accomplish the specified task quite effectively.  A joystick interface is used as the source of steering input in this example.  The code that actually communicates with the Garcia is quite small.  The bulk of the code will be devoted to initializing the joystick, maintaining a GUI, and processing the joystick input. 

The C++ Program

The ins and outs of Windows GUI programming and DirectX interfacing require volumes of text.  A thorough treatment of the GUI and joystick code is beyond the scope of this example.  Most of the joystick code was copied from a boilerplate example found in the DirectX SDK available on the Microsoft website.  All of the code for this particular example may be found in a download of the latest Garcia software.  The following code discussion deals with the Garcia specifics. 

In a robot with differential or "tank" steering such as the Garcia the most common method of steering is to have two throttles, one for each motor.  A typical joystick has an X axis and Y axis and does not match the two-throttle configuration.  One alternative is to let the X (left-right) axis be rotational speed and the Y (front-back) axis be linear speed.  Moving the stick left or right will make the robot pivot about its center.  Moving the stick front or back will make the robot go forward or reverse.  A combination of X and Y will make the robot perform various turns.  Pseudocode for this X-Y joystick control strategy is shown below.  After scaling and combining the wheel velocities, only two commands are required to update the robot's wheel speeds. 

// calculate linear velocity vlinear = yscale * yjoy; // calculate rotational velocity vrotateR = xscale * xjoy; vrotateL = -vrotateR; // combine linear and rotation velocity vL = vlinear + vrotateL; vR = vlinear + vrotateR; m_garcia.setFloatProperty("damped-speed-left", vL); m_garcia.setFloatProperty("damped-speed-right", vR);

The next piece of code launches the null primitive.  It's a member function of the main application class.  First it creates a null behavior called "drive-robot".  Then it assigns an acceleration.  This acceleration determines how quickly the robot will change speeds when given a new speed command.  The null primtive terminates when it detects an error condition.  The routine below alos assigns a callback function that will grab the error code when the null primitive is done.  The final step is queueing the behavior which will launch the null task on the robot. 

///////////////////////////////////////////////////////////////////// void win32_acpGarciaJoy::LaunchNullTask() { m_task = m_garcia.createBehavior("null", "drive-robot"); m_garcia.setFloatProperty(m_task, "acceleration", aJOY_ACC); m_garcia.setCallback(m_task, "completion-callback", sComplete); m_garcia.queueBehavior(m_task); } // win32_acpGarciaJoy LaunchNullTask method

A loop in the GUI application gets new joystick input data 10 times per second.  At each iteration of this loop, the application must perform some logic to drive the robot and control execution of the null primitive.  The null primitive exits if there is an error condition so it must be restarted for the robot to move again. 

The following time slice routine handles the logic.  It converts joystick data into new speed commands if the null primitive is running.  If the null primitive is not running, the routine launches it again.  Finally, the routine gives the Garcia object some time to handle its own IO.  When this routine is called several times a second in a control loop it will handle the logic and provide fluid movement of the robot in response to joystick inputs.  If the robot is in an error state, such as stopped close to a wall, the control loop will continue to launch the null primitive and process the error until the robot is given a command to back away from the wall. 

///////////////////////////////////////////////////////////////////// void win32_acpGarciaJoy::TimeSlice() { // we can reset the global error flag // and try to drive the robot if the null task is running if (!m_garcia.isIdle()) { gl_error = 0; Drive(); } // launch null primitive again if it exited // additional actions on error may be added here if (m_garcia.isIdle()) { LaunchNullTask(); } // handle the garcia object m_garcia.handleCallbacks(50); } // win32_acpGarciaJoy TimeSlice method

What's Next?

That's about it for the code.  Nothing else is required for the interface to the robot.  As stated before, the bulk of the code is for the GUI and joystick device control.  Complete source code is supplied in the Garcia download. 

Driving by joystick is fun, but it is not the only application where the null primitive is useful.  A PDA on the back of the robot could monitor sonar data and steer the robot accordingly.  A desktop computer could grab images from a camera mounted on the robot and steer in response to what the robot sees.  If an application needs interactive control of the robot, this tutorial is a good starting point. 

Garcia
Resources

 

Related Links:

Articles: BrainStem Robotic Teleoperation

voice: 720-564-0373, email: sales@acroname.com, address: 4822 Sterling Dr., Boulder CO, 80301-2350, privacy
© Copyright 1994-2012 Acroname, Inc., Boulder, Colorado. All rights reserved.