rtbapi-- version 0.9 Programmer's Manual

Table of contents

About rtbapi--

rtbapi-- is a class library made to ease the construction of Real Time Battle robots in the C++ programming language.

rtbapi-- is plagiarized from^W^Wbased on Rubén's LGPLed rtbapi library for C robots. All the good ideas are his. All bugs and stupid mistakes are mine.

This library has been made in an effort to update my C++ knowledge: the C++ I know dates back from AT&T's 2.2 implementation; as such, there are some archaicisms and oddities in the source code; please, if you spot any of them, please tell me so that I can update the library and my knowledge at the same time. Thanks :-)

rtbapi-- was started in November, 2001, in a time where the author had much more important stuff to do than programming this library; doing it helped him keep himself sane.

You can download the latest version of rtbapi-- from Jacobo Tarrío's home page. You can download Rubén's original rtbapi from Rubén López's download site.

Release history

0.9 -- 2001-12-07
Second public release. Rewrite of tutorial text. Robot instance in sample.cpp renamed. Included SEND_ROBOT_COORDINATES. Made compilable with g++ 3.0.
0.8 -- 2001-12-01
First public release

This is the first release so there's not much history yet.

Copyright

rtbapi-- was programmed by Jacobo Tarrío; it is based in Rubén López's rtbapi. The license of the original rtbapi is the GNU Library General Public License; the license of rtbapi-- is a simple BSD-style license that reads as follows:

Copyright (c) Jacobo Tarrío Barreiro. All rights reserved.

Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:

  1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
  2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
  3. Neither Jacobo Tarrío Barreiro's name nor the names of his contributors may be used to endorse or promote products derived from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY JACOBO TARRÍO BARREIRO AND THE CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JACOBO TARRÍO BARREIRO OR THE CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

Have you read it carefully? Did you pay attention to the part that talks about your first born children? ;-)

Tutorial

We'll try to get you started in robot programming using rtbapi-- using some examples. You can find their source code in the src/tutorial subdirectory in the original source tarball, so that you can follow them easily.

The first robot

The first program you always see when you're learning a new programming language is the "hello world". Well, we're now going to make the "hello world" robot :-)

We must start by specialising the rtb::Robot class into a new class into which we will implement our robot. In the main() function we will create and run our robot:

#include <robot.hpp>

class HWRobot : public rtb::Robot {
public:
  HWRobot (std::string name, int colour, int colour2);
};

HWRobot::HWRobot (std::string name, int colour, int colour2)
  : Robot (name, colour, colour2) { }

int main(int argc, char *argv[]) {
  HWRobot helloworld ("Hello, world!", 0x223344, 0xddccbb);

  helloworld.Scanner ();

  return 0;
}

That's all we need to make a working robot. A constructor must be defined (C++ language constraints) as well as a main() function that creates an instance of our new robot and calls its Scanner() member function. The Scanner() member function never returns; it just waits for input messages for the robot, interprets them and executes the appropriate member functions in the robot.

You can load the robot into Real Time Battle and make it fight. You'll see a robot called "Hello, World!" that does nothing at all except stand still. Hey, we said that it would load, but we didn't say it would do a thing!

Robots that do things

That was nice but robots usually walk around and even shoot occasionally at other robots; now we'll learn how to make a robot that wanders around. To do it, we'll start with a template similar to our "hello, world" robot and extend it with a couple of member functions.

This robot runs in a straight line and when it hits something, or is hit by something, it changes its course randomly.

Look at the following function definitions in runbounce.cpp:

void RBRobot::Info (double time, double speed, double cannon_angle) {
  Accelerate (2);
}

void RBRobot::Collision (rtb::Consts::object_type object, double angle) {
  RotateAmount (rtb::Consts::ROTATE_ROBOT, 1000, ((random() % 62832) - 31416) / 10000);
}

You can see that rtbapi-- programming is event-oriented. Every method defines the behaviour the robot exhibits when a given event is received from the server (in this case Info and Collision).

The Info message is always received after the Radar message, and the Radar message is always the first message to be received in every turn, so any one of the two messages can be used to trigger stuff that must be done by the robot in every turn; in this robot, Accelerate.

The Collision message is received when the robot hits or is hit by something (a wall, a shell, another robot, ...)

You can now try this robot a couple of times; you'll probably notice a problem with it: it tends to get stuck to walls.

The reason is simple: when it hits a wall it starts rotating, but as the robot is still accelerating, it will most likely hit the wall again before finishing its rotation, so it starts rotating to a different random angle, but as it is still accelerating it will hit... You get the idea.

To avoid this problem, we'll make a different robot (runbounce2.cpp) that won't start a new rotation until the old one is finished. We'll do that in two steps: first, a boolean flag (stored in the boolean variable stop) is set to 'true' when the robot starts rotating and set to false when it finishes its rotation; second, if there's a collision, it will start a rotation only when the flag is false.

void RB2Robot::Collision (rtb::Consts::object_type object, double angle) {
  if (!stop) {
    RotateAmount (rtb::Consts::ROTATE_ROBOT, 1000, ((random() % 62832) - 31416) / 10000);
    stop = true;
  }
}

void RB2Robot::RotationReached (rtb::Consts::rotate_type what) {
  stop = false;
}

Try it; run the two robots at the same time and see which one gets stuck to walls.

A robot that shoots at other robots

As we stated in the previous tutorial, a Radar message is generated in every turn by the server. The Radar message informs about the objects detected in that turn by the robot's radar: other robots, walls, cookies, mines, shots, or even nothing at all. It also reports the distance and the radar's angle at the moment of detection.

After every Radar message the server issues an Info message that gives information about the time elapsed since the game started, the robot's speed and the cannon's angle.

Finally, if the object detected by the radar is a robot, there's a third message, RobotInfo, which reports the other robot's energy level and says if it's a team mate or not.

The robot we are now going to build is a shooting robot; when it detects a robot, it will shoot at it and try to follow it, by rotating towards it (to the angle reported by the Radar message). Look at shooter.cpp for the full source code.

First, we need to define the robot's behaviour when it receives a Radar message: if the object detected is a robot, it will shoot at it and head towards it:

void SRobot::Radar (double distance, rtb::Consts::object_type object, double angle) {
  if (object == rtb::Consts::IS_ROBOT) {
    Shoot (1.5);
    RotateAmount (rtb::Consts::ROTATE_ROBOT, 1000, angle);
  }
}

Unfortunately, this isn't enough, since the radar can only detect things that are straight in front of it, so the robot will only be able to detect robots that are just in its front.

That can be solved by moving the radar in a sweeping fashion; in this way it will be able to cover a relatively big area in front of the robot. To be able to shoot at the same time that the radar detects the robot, we'll make the cannon follow the same sweeping movement at the same time. There's a command for that kind of movement, that will be sent when the game starts:

void SRobot::GameStarts () {
  Sweep (rtb::Consts::ROTATE_CANNON_RADAR, 1000, -0.5, 0.5);
}

If you try this robot you'll see that it, at least, tries to shoot at robots and follow them. This is not a good robot by any means; it should do more things, such as trying to eat cookies, avoid mines and collisions, some strategies, etc. There's a better robot in the src/sample subdirectory in the original source tarball.

Reference

This section describes the rtbapi-- API: what messages robots can send, and what messages that can be sent to robots.

Constructor

Robot ()

Default constructor. If it is used, the robot is responsible to send its name and colours when it receives the GameStarts message, by sending the messages Name and Colour.

Robot (std::string name, int colour, int away_colour)

If this constructor is used, the robot itself will send its name and colours to the server when the GameStarts message is received.

Messages from robots

RobotOption (Consts::robot_option_type option, int value)

This message is sent automatically by the robot when the Scanner() function is called, to set certain options. Look at the possible values of option in Consts::robot_option_type for more information.

Name (std::string name)

This message sends the robot's name to the server. It should be sent only after receiving the Initialize message with a parameter of 1, along with the Colour message.

Colour (int colour, int away_colour)

This message sends to the server the robot's desired colour, and an alternative colour. It should be sent along with the Name message after receiving the Initialize message with a parameter of 1.

Rotate (Consts::rotate_type what, double angular)

Rotates the robot, the radar and/or the cannon with a given angular velocity, given in radians/second. You can choose what to rotate via the what variable; see Consts::rotate_type for more information.

RotateTo (Consts::rotate_type what, double angular, double end)

Rotates the radar and/or the cannon with a given angular velocity, in radians/second, until a certain end angle, in radians, is reached. You can choose what to rotate via the what variable; see Consts::rotate_type for more information. Be aware that you cannot rotate the robot itself; to do that you should use RotateAmount instead.

RotateAmount (Consts::rotate_type what, double angular, double angle)

Rotates the robot, the radar and/or the cannon with a given angular velocity, in radians/second, until a certain angle, in radians, is reached, relative to the current angle. You can choose what to rotate via the what variable; see Consts::rotate_type for more information.

Sweep (Consts::rotate_type what, double angular, double left, double right)

Starts a sweeping movement in the radar and/or the cannon with a given angular velocity, in radians/second, with a pair of given maximum left and right angles. You can choose what to sweep via the what variable; see Consts::rotate_type for more information. Be aware that you cannot sweep the robot itself.

Accelerate (double value)

Sets the robot's acceleration value. The acceleration is applied continuously, until it is changed to another value.

Brake (double portion)

Sets the robot's brakes. The value of portion ranges from 1 (full brakes) to 0 (no brakes).

Shoot (double energy)

Shoots a shell with the given energy.

Print (std::string message)

Prints a message to the message window.

Debug (std::string message)

Prints a message to the message window, if debug mode is enabled.

DebugLine (double angle1, double radius1, double angle2, double radius2)

Draws a line in the arena, if debug mode is enabled at its highest level. The line's starting point is located at angle angle1 and distance radius1 relative to the robot; the endpoint is located at angle angle2 and distance radius2 relative to the robot.

DebugCircle (double center_angle, double center_radius, double circle_radius)

Draws a circle in the arena, if debug mode is enabled at its highest level. The circle's center is located at angle center_angle and distance center_radius relative to the robot; the circle's radius is circle_radius.

Messages to robots

Initialize (int first)

This is the first message that will be received by the robot. If the argument is 1, this is the first sequence in this game, and the robot should send Name and Colour to the server; otherwise it should just wait for the YourName and YourColour messages.

YourName (std::string name)

This message contains the robot's real name.

YourColour (int colour)

This message reports the robot's real colour.

GameOption (Consts::game_option_type option, double value)

This and other GameOption messages are sent to the robot at the beginning of each game; each gives the value of some game option; together they report the settings for the current game, which can be useful for the robots.

GameStarts ()

This message is sent when the game starts.

Radar (double distance, Consts::object_type object, double radar_angle)

The robot will receive one of these messages in every turn, containing information about the object currently detected by the radar. The radar_angle is relative to the robot's front, and is given in radians.

Info (double time, double speed, double cannon_angle)

This message always follows the Radar message; it contains information about the robot's state. The time is relative to the beginning of the game, and given in seconds (may be scaled time instead of real time). The robot's speed is also reported. The cannon_angle is relative to the robot's front, and given in radians.

RobotInfo (double energy, int teammate)

If the radar detects a robot, this message follows the Info message, and gives information about the detected robot's status: its energy level and an integer with value 0 if it's an enemy robot and 1 if it's a teammate.

Coordinates (double x, double y, double z)

Reports the robot's current position (x, y and z coordinates). The coordinates can be absolute or relative to the robot's initial position; it depends on the value of the Consts::SEND_ROBOT_COORDINATES Consts::game_option_type sent via the GameOption message.

RotationReached (Consts::rotate_type what)

This message is received when the robot, the radar and/or the cannon finishes a rotation.

Energy (double energy)

This message gives an approximation of the robot's energy level.

RobotsLeft (int number)

This message is sent at the beginning of the game and when a robot dies to all remaining robots, and reports the number of robots alive.

Collision (Consts::object_type object, double angle)

This message is received by the robot when it hits or is hit by something. The robot gets to know the angle (relative to the robot's front) of the point of impact and the type of object that collided with the robot.

Warning (Consts::warning_type type, std::string message)

This message is sent when the server needs to issue a warning. There are several types of warning, and a message is included to clarify.

Dead ()

This message is sent when the robot has died; no more messages should be sent to the server until the end of the game.

GameFinishes ()

This message is received when the current game ends.

ExitRobot ()

The robot's process should be finished when the robot receives this message; otherwise, it will be killed by the server.

Data types and enumerations

Consts::rotate_type

Possible values:

The last three 'composite' values are added to allow the rotation of multiple parts at once; their numerical value is the same as the component parts' numbers Or-ed together.

Consts::object_type

Possible values:

These object types cannot be composed together. I think that the last one is not used in practice, but this might change (be warned).

Consts::warning_type

Possible values:

Consts::game_option_type

Possible values:

Consts::robot_option_type

Possible values:


Jacobo Tarrio
Last modified: Fri Dec 7 16:35:54 CET 2001