Triangle C++ Tutorial
Last Modified: 2007-10-04
find:

basket

Acroname Robotics PDF webpage version Triangle C++ Tutorial PDF

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 sets up the primitives required to get the robot to navigate a triangle.  This program is run from the command line and displays progress information as each of the prepared and queued behaviors executes and completes. 

The Task

How do I get the Garcia robot to move in a prescribed path and how can I gauge the progress along this path using C++?

The Concepts

The Garcia robot contains a number of built in primitives that handle common tasks.  The Garcia API manages these primitives for you much like a graphics subsystem that handles drawing lines, text, and polygons, allowing you to focus on higher level tasks. 

We will be using two specific primitives to move the robot in a triangle.  The two are move and pivot .  Behaviors are created from these primitives and the parameters are set for each to effect the motion we want.  In much the same way you would draw a triangle using a turtle graphics system, we will move as follows:

Diagram of the triangle component primitives

The Garcia Object

Most of the Garcia API centers around the Garcia object.  This object acts as the main connection to the robot and it manages the current units (distance, angles, etc), a queue of primitives (in the form of a behavior queue) and other tasks associated with the host/robot interaction.  We create a single Garcia object for the entire life-cycle of the application.  The creation of this object is all that is needed to establish the link to the robot.  The object looks for a file in the aBinary directory of your software distribution for a settings file named "garcia.config".  In this file, settings can be placed for the default baudrate, serial port name, and default units as well as other settings.  Once created, the object builds a seperate thread that manages the heartbeat serial packets between the robot and the host. 

Note:

The GarciaTool application also uses the garcia.config file for its settings.  Be sure you have this file set up properly and that this tool works (shows a heartbeat) before you proceed with this example. 

In our example, we use a stack-based Garcia object in the main routine that is constructed automatically in creating the garcia variable:

int main(int argc, char* argv[]) { acpGarcia garcia; aBehaviorRef test;

Building Behaviors

The Garcia object is used to create a behavior using the createBehavior method.  Here is the code that does this for the first move primitive:

test = garcia.createBehavior("move", "out"); garcia.setFloatProperty(test, "distance", 0.5f); garcia.setCallback(test, "execute-callback", sExecute); garcia.setCallback(test, "completion-callback", sComplete); garcia.queueBehavior(test);

Notice that after we create this first primitive, we then set several properties on it.  First is the name which just helps us (the user) identify the behavior later.  Next, we set the distance property which is in terms of the current distance units (meters is the default).  We then set two callbacks on the behavior.  The first callback, named "execute-callback" gets called when this behavior gets executed.  The second callback named "completion-callback" is called when the behavior completes (whether it succeeds or not).  These two callbacks are used in this example to print status message to STDIO as the robot progresses through the triangle. 

Note:

All objects in the API are opaque references.  These references are then always used to manipulate and access the underlying objects.  This allows a consistent interface between platforms and languages and also allows an abstraction layer. 

The final thing to do is queue the behavior.  This is done using the Garcia object's queueBehavior method.  If no other behaviors are running, the behavior will start immediately when queued.  If others are queued or executing, the Garcia object will manage the behavior and help it wait for its turn to execute. 

As the behaviors are executed and complete, the callbacks display the progress:

/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * behavior execute callback */ aErr sExecute(acpGarcia* pGarcia, aBehaviorRef behaviorRef) { printf("behavior \"%s\" with id %d executing...", pGarcia->getStringProperty(behaviorRef, "name"), pGarcia->getIntProperty(behaviorRef, "unique-id")); return aErrNone; } /* sExecute callback */ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * behavior completion callback */ aErr sComplete(acpGarcia* pGarcia, aBehaviorRef behaviorRef) { printf("completed with status = %d\n", pGarcia->getIntProperty(behaviorRef, "completion-status")); return aErrNone; } /* sComplete callback */

Notice that in the callbacks, we retrieve other information like the unique behavior ID and completion status.  If the robot encountered an obstacle with the left front IR ranger as it tried to move forward, the status return value would be the value associated with the left front IR ranger error.  This return value could be used to learn of the obstruction and the robot could then be queried for how far it actually travelled in the move primitive to figure out roughly where the obstacle lies. 

Finishing Up

So for this example, we queue 6 behaviors.  These are managed for us and all we have to do is wait around for them to complete before exiting.  The Garcia object has a method named isIdle that we can use to check to see if the behavior queue is empty.  Here we loop until this is true and check for callbacks in the meantime:

while (!garcia.isIdle()) garcia.handleCallbacks(100);

The handleCallbacks method takes a single parameter that designates the number of milliseconds the handleCallbacks method should yield until it returns, checking for callbacks as it does. 

Going Further

This is a very simple example.  It runs on all supported platforms and all the source code is included in the aExample directory of the Garcia download in the Download Section.  There are various projects to support some compilers but most any compiler can work with this code, provided you properly configure the compiler settings. 

Obviously, this is a simple example and it doesn't begin to tap the potential of Garcia.  It does, however, demonstrate the basic process of getting Garcia up and running and scheduling behaviors based on the primitives built into Garcia.  Other examples deal with more sophisticated concepts like doing your own closed-loop control from the host and getting sensor data as the robot operates. 

Garcia
Resources

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