Compiling and Running your Code

The purpose of this page is to explain how to write your own software to control the robot. There are several manufacturer supplied libraries for integrating your software with the robot. Aria and Colbert are examples of two interface libraries. Aria comes in both C++ and Java versions. The interface (API) described here is Aria (ActivMedia Robot Interface for Application).

A r i a

Aria is an object-oriented library of control routines. It allows you to query the robot for its speed, direction, location, sonar readings, etc. You can control motion, create sounds, open and close the gripper, etc. Here is a link to chapter one of the Aria Reference Manual.

The most important class in Aria is the ArRobot class. Here is a link to the ArRobot Class Manual Page. Many of the links off this page don't work because there are just too many other manual pages to post here.

You must create an instance of this class:
          ArRobot robot;
The instance stored in the variable named "robot" contains quite a bit of "state reflection" data along with hundreds of methods to control the robot. The state reflection data is a copy of some the data that is stored inside the robot. For example, current speed, X location, Y location, sonar readings, etc. The state data is updated several times per second. So, when your client gets a sonar reading, the client is actually calling a method that accesses data that is part of the robot class. There are other methods that can tell your client how long it has been since that sonar reading data has been updated.

Much of the client-side data is initialized via the Aria initialize method
          Aria::Init()
which is one of first things done inside main().

C o m m u n i c a t i o n

Your control software is a client application that communicates back and forth with the robot server. The server may be a real robot or the simulator. The client communicates to the simulator server via a TCP connection.
          ArTcpConnection con;
The variable con must be tied to a port number (see other page's section on "Running the Simulator"). Then the port must be opened and tied to the robot variable. Since all of this takes really nasty looking code, it is highly recommended that students use the this skeleton C++ program code written by Dannelly.

S O N A R

The robot detects objects by using its sonar, much like a bat. The sonars detect objects up to five meters away, but not closer than a few inches. So, if you run into a wall, the wall may be too close to be detected. My experience is that it is a good idea to stay at least a foot (or about 300mm) away from objects. If the nearest object is beyond 5 meters away, the sonars should report values of 5000.

The sonars are numbered 0 to 7. There are several sonar methods in the ArRobot class. You can control the firing rate, turn on/off particular sonars, etc. The most useful function is getSonarRange().

Here is an example of using the sonars to move forward until a wall is reached.

  robot.setVel(200);
  while(1)
    { 
      ArUtil::sleep(500);
      if ((robot.getSonarRange(2) < 300) ||
          (robot.getSonarRange(3) < 300))
         break;
    }
  robot.setVel(0);
The robot starts moving at 200mm/sec and continues moving until either sonar 2 or 3 (the ones that face the most forward) detect an object within 300mm. The sleep in the loop just slows done the processor by waiting a half second (500 miliseconds) between each sonar read - there is no need to check the sonars thousands of times per second.

Note that this is not a great piece of code. If the robot is headed straight or almost straight into a wall it works fine. But, if the robot is running along a wall and drifting into the wall, then the side of the robot will crash into the wall without the forward sonars ever seeing the wall. To be safe when moving around, look both in front and to the sides of the robot.

M o v e m e n t

There are dozens of class methods to control movement. You can move a specific distance, or move at a given speed, or go straight to a specific X,Y coordinate, etc. Here are a few of the basic movement commands.

S a m p l e       C o d e

Here is a bit of sample movement code. This will first report the intial sonar readings for the left and right sides and the initial direction (will always be zero at startup), then move forward one meter, then turn to the left 90 degrees, then move again, and finally report the final sonar readings.

For some reason, sonars don't report correctly until the motors have turned a bit. Hence the initial very short move. The for loops after each move and turn cause the client program to pause until the move or turn has finished.

  // get initial left and right sonars and the initial direction
  robot.move(10);
  ArUtil::sleep(1000);
  printf("initial sonar 0 = %d \t sonar 5 = %d \t theta = %.2f\n",
         robot.getSonarRange(0),robot.getSonarRange(5),robot.getTh());

  // first move forward one meter
  robot.move(1000);
  for(ArUtil::sleep(2000); robot.getVel() !=0; ArUtil::sleep(500));

  // turn left 90 degrees
  robot.setDeltaHeading(90);
  for(ArUtil::sleep(2000); robot.getRotVel() !=0; ArUtil::sleep(500));

  // second move forward one meter
  robot.move(1000);
  for(ArUtil::sleep(2000); robot.getVel() !=0; ArUtil::sleep(500));

  // print final sonar readings and direction
  printf("final sonar 0 = %d \t sonar 5 = %d \t theta = %.2f\n",
         robot.getSonarRange(0),robot.getSonarRange(5),robot.getTh());

S a m p l e     B a d     C o d e

The following are two bad attempts to have the robot move forward until the front facing sonar detects something within 1 meter. The first attempt crashes into the wall. The second attempt does not crash, but does unnecessarily hijack the client machine's CPU.

The following code's while loop checks the front sonars. While the robot is more than a meter away from a wall, the robot is safe to move forward. A movement of half a meter is a conservative and safe baby step.

   while ((robot.getSonarRange(2) > 1000) && (robot.getSonarRange(3) > 1000))
      robot.move (500);
The robot crashes into the wall because the move routine is a "non-blocking function". In other words, the program does not wait for the half meter move to be complete before executing the next command.

For example... Assuming the robot starts away from a wall, the robot does not see a wall and begins moving. Before the first move is complete (or maybe even started), the sonars once again indicate a clear path, so the robot is told to move another half meter. Before the first move command has been executed by the robot, the client has probably issued hundreds of subsequent move commands. So by the time a wall is seen just one meter ahead, the robot has buffered thousands of move commands. Crash!!!

The following code attempts to fix the crash by moving forward at a particular rate until a wall is seen. The while just checks the sonar over and over until a wall is seen (note that the ; at the end of the while is intentional.) As soon as a wall is noticed, the speed is set to zero (stop).

   robot.setVel (200);
   while ((robot.getSonarRange(2) > 1000) && (robot.getSonarRange(3) > 1000));
   robot.setVel (0);
This code does not crash, but it does consume far too much client CPU time. The while loop will call getSonar thousands of times per second. In fact, it is likely that the forward sonars are polled several hundred times before the robot is able to even start moving. To prevent the CPU meter from going to max until a wall is reached, the while loop should slow down and call the sleep utility function. A sleep of 500 would still allow the client to check the robot's sonars twice per second - which is plenty fast enough reflexes - and your client machine will not freeze up.