Khepera III Toolbox/Print version


Khepera III Toolbox

The current, editable version of this book is available in Wikibooks, the open-content textbooks collection, at
https://en.wikibooks.org/wiki/Khepera_III_Toolbox

Permission is granted to copy, distribute, and/or modify this document under the terms of the Creative Commons Attribution-ShareAlike 3.0 License.

Download and Installation

Download edit

Downloading the Package edit

A more or less stable release of the toolbox is now available on the sourceforge project page. After downloading the file, uncompress it with

unzip khepera3toolbox-YYYY-MM-DD.zip

This will create a folder khepera3toolbox in your current directory with the whole toolbox.

This is the preferred way of getting the toolbox if you intend to just use it, but not make any contributions (programs, modules, bugfixes, ...) by yourself. Whenever we release a new version, you have to download a new ZIP file, and replace the whole khepera3toolbox with the new version of the toolbox.


Getting the Latest Revision from SVN edit

The latest version can be obtained by checking out the following SVN tree:

svn checkout https://svn.code.sf.net/p/khepera3toolbox/code/

This will create a folder khepera3toolbox in your current directory with the whole toolbox.

This is the preferred way of getting the toolbox if you plan on making contributions (programs, modules, bugfixes, ...) by yourself, or if you want to use the latest version of the toolbox. To update to a new revision, just type

svn update

inside the khepera3toolbox folder.

Installation edit

The toolbox does not need to be copied to a specific place - it stays in a convenient place in your home directory.

However, you need to modify two environment variables. This can either be done manually, by typing the following two lines on your bash shell:

export K3_ROOT=/path/to/your/khepera3toolbox
export PATH=$PATH:$K3_ROOT/Scripts

or automatically, by adding the above lines to your ~/.bashrc (or ~/.profile) file. Note that if you choose to do it manually, you need to it each time you open a new terminal window.

To check if you set these variables correctly, type

k3go -h

This should print a short help text for the k3go script in your terminal window.


Introduction

The Khepera III robot runs an embedded Linux (kernel 2.6) with all of the most common Linux tools, except for program compilation. Hence, programs have to be cross-compiled on another computer with a arm-linux toolchain, and can then be copied using SCP and launched over an SSH connection. This is in principle quite straightforward for a Linux adept, but can be quite cumbersome when starting from scratch.

This is where the Khepera III toolbox comes into play. The toolbox can be understood as a Swiss Army Knife for the Khepera III robot, offering three different types of tools:

  • Scripts to interact with the robot(s): A series of scripts are available to copy files on your robots, remotely execute programs, and do a number of administrative things. These scripts can deal with many robots in parallel, e.g. to copy a file onto a whole fleet of robots.
  • Programs for the Khepera III robot: A number of small programs are available to play with the sensors and actuators of the robot.
  • Modules with standard functionality: A couple of modules provide basic functionality that you can easily integrate in your own programs that you write for the Khepera III robot. Besides functions to read the sensors and configure actuators, there are also modules to parse command line arguments, simple odometry tracking, and so on.

The remainder of this chapter shows in a tutorial-like style how to do a couple of fancy things with the robot, using the scripts and the programs. The modules are discussed in a later chapter.

Preparing the Computer and the Robot edit

We assume that you installed the Khepera III Toolbox as explained in Download and Installation and that you are using a bash shell on a recent Linux system.

Switch on your Khepera III robot and connect it to your computer. For the remainder of this introduction, we will assume that your robot is connected with a USB cable. If you are using a WLAN connection, simply replace the "+usb" with "+ROBOTID" (where ROBOTID is the number of your robot).

To check if everything is all right, type

k3ping +usb

which will execute ping 192.168.1.2 for you.

Both your computer and the robot should be ready now - time to play with the robot!

Remote Control with a Keyboard edit

Type

cd Programs
k3put +usb motor_initialize motor_stop motion_arrowkeys

to copy three of the motor programs to your robot. (Note that you will need to type the root password of the robot 4 times. This password is "rootme" by default.) As you can see in the terminal, this just launches scp commands.

Now type

k3go +usb

and type the root password again to log onto the robot. If you now type ls (on the robot), you will notice that a directory with your username has been created. This is a convenient way to avoid overwriting each others files if your fellows are using the same robot as well. Hence, cd into this directory and type:

./motor_initialize
./motion_arrowkeys

The first program will initialize the motors (e.g. set PID values) and then quit. The second program keeps running until you press Ctrl-C, and allows you to steer the robot with the keys W (increase speed), A (turn left), S (stop), D (turn right) and X (decrease speed) on the keyboard.

Note that when you quit this program with Ctrl-C, the motors will keep the last speed they were told. This is a general rule for all programs of this toolbox, and should be seen as a feature - not a bug. A program which comes in handy sometimes is "motor_stop", which immediately stops the motors.

Once you have played enough with the robot, you can log out by typing

exit

on the command line. This brings you back on the computer, to the place where you were before the k3go command.

Fun with the Infrared Sensors edit

Two programs are available to query the infrared sensors: infrared_ambient and infrared_proximity. While the former simply reads all infrared receivers, the latter takes two consecutive measurements (once with the IR LED off and once with the IR LED on) with each sensor to estimate its distance to an obstacle.

Again, we first need to copy the necessary programs onto the robot. Assuming that you are still in the Programs directory, type

k3put +usb infrared_ambient infrared_proximity

Then, log on to the robot (k3go +usb) and cd to your directory.

Get an ambient IR measurement by typing

./infrared_ambient

This will give you something like:

$IRAMBIENT,0,31887,4080,4073,4080,4081,4093,4093,4094,4077,4094,4081,4094

The first two values denote the sample number (starting at 0) and the current timestamp of the main microcontroller. All other values are in the range 0 - 4096 and correspond to one sensor on the robot. The sensors are numbered clockwise (when looking from the top) from 0 (back left sensor) to 8 (back sensor). Sensors 9 and 10 are the right and left floor sensors, respectively. On a sunny day, you can cover one sensor with a finger while taking another measurement, and you should see a clear difference between the values. Similar experiments can be made in proximity mode (./infrared_proximity).

Instead of launching the command several times, you can tell the program to take several (here: 10) measurements in a row

./infrared_ambient -r 10

or to take measurements until pressing Ctrl-C

./infrared_ambient -r

Output Format edit

At this point, you may be wondering about the output format, notably the $IRAMBIENT the beginning of all lines. This is NMEA 0183, a very simple text-based communication format which has become widespread through GPS devices (which almost always use this format). More information about this format is written in the chapter Parsing Program Output.

Measuring Distances with the Ultrasound Sensors edit

 
Ultrasound sensors are located around the perimeter of the robot shown here.

The Khepera III robot is equipped with 5 ultrasound sensors which can be used to detect obstacles. When switched on, these sensors send out an ultrasound pulse and record its echo. Since the propagation of acoustic waves in the air is almost constant, this technique can be used to measure distances to objects in the environment. Note that the story is slightly more complicated, though. What you record when sending out a pulse is a combination of a whole series of echos, reflected by various objects in the environment. Fortunately, the robot processes the signal for you and provides you the most prominent echos in the received signal.

Type

cd Programs
k3put +usb ultrasound ultrasound_enable

to copy these two programs onto your robot. Now log on to the robot (k3go +usb) and cd to your directory.

Point your robot towards a wall and type

./ultrasound front

You will get something like this

TODO

Each line corresponds to one received echo and contains its amplitude as well as the estimated object distance. In our example, we got a very strong echo from an object at a distance of 0.98 m, and two less strong echos from objects at 0.45 m and 1.22 m distance. Note that the accuracy is in the order of a few centimeters, and you may get slightly different values each time.

By default, only the front sensor is enabled. To activate the left and the right sensor as well, type

./ultrasound_enable left front right

This program will configures the robot accordingly reports the active sensors. Now, you can also take measurements with the sensors on the left and on the right:

./ultrasound left
./ultrasound right

Getting Help edit

To get help about one of the standard programs, simply invoke the program with the -h option:

./battery -h

Reading this help and a little bit of imagination should make the use of all standard programs straightforward.

More Tutorials and Hands-On Exercises edit

For more tutorials, have a look at the Examples section. These examples are written in such a way that you can reproduce them with your own Khepera III robot, and gradually learn more about it.


Network Setup

USB edit

The USB port on the Khepera III robot can be used to establish a network connection between the robot and a Linux computer. Start by connecting your robot and your computer with a USB cable.

Connecting for the first time edit

If you just bought your Khepera III robot, the USB network interface is disabled. To enable it, connect your robot with a serial cable (using a KoreConnect, for example), log in with username "root" and type:

modprobe g_ether
ifconfig usb0 192.168.1.2

The first line loads the driver, while the second line configures an IP address. On your computer, you can now set a corresponding IP address by typing

sudo ifconfig usb0 192.168.1.1

in a terminal, or using your network configuration program. (Note that "usb0" might be called differently on some computers. To get a list of all network endpoints, simply type "ifconfig".)

Connecting after the install scripts have been run edit

On a Khepera III robot on which the install scripts have been run, the USB network interface will automatically appear with IP address 192.168.1.2 when you connect the cable. Hence, you only need to configure your computer by typing

sudo ifconfig usb0 192.168.1.1

in a terminal, or using your network configuration program. (Note that "usb0" might be called differently on some computers. To get a list of all network endpoints, simply type "ifconfig".)

Testing the connection edit

To test if the connection works, type

ping 192.168.1.1

on your robot, or

ping 192.168.1.2

on your computer. Ping should work in both directions.

Wireless LAN (802.11) edit

If you are working with more than one robot, or if you want to communicate with your Khepera III while it is running an experiment, you will probably put a WLAN card in the available CompactFlash slot. This adds a new network interface, which is not configured by default. There is an install script, however, which automatically adds the necessary configuration and configures the interface with an IP address 192.168.141.ID, where ID corresponds to the robot ID.


The Toolbox

The Khepera III Toolbox offers mainly three types of tools:

  • Scripts: Scripts make your daily work with the robot(s) more efficient by offering easy ways to copy files (e.g. programs) onto multiple robots, logging in to robots, and so on.
  • Programs: The Programs folder contains a series of useful standard programs for the Khepera III robot. Among them are programs to sample the sensors, set the motor speed, and track the robot's position with odometry measurements. In addition, these programs may serve as starting points for your own programs.
  • Modules: This folder contains modules to conveniently access the sensors and actuators on the robots (Modules/khepera3) and a series of other functions. These modules are used by the available programs and can be used in your own programs as well.

In addition, there is a fourth folder which is less frequently used:

  • Install Scripts: This folder contains a few scripts to set up WLAN and a few other things on the robot.


The Toolbox/Scripts

The Scripts folder in the Khepera III Toolbox contains a series of scripts that simplify working with a Khepera III robot, or with a fleet of such robots. These scripts simplify common and often-used tasks, such as copying files onto robots, setting up SSH public key authentication, or shutting down robots. Rare and complicated tasks can always be performed using ssh, scp and other commands directly.


Using the Scripts and Getting Help edit

All scripts start with the letters k3.... Hence, if you type k3 in a bash shell, followed by pressing the tab key twice, all scripts are listed. This is especially useful for those scripts that you do not use daily. In addition, all scripts print a short help text when called with the -h option, e.g.

k3put -h

Selecting Robots edit

Most scripts require you to specify the robots you are working with. This is done with +... arguments on the command line. Four methods for selecting robots are available:

  • By robot ID, e.g. +203 (which translates into the IP address 192.168.141.203)
  • By a range of robot IDs, e.g. +203-205 (which is the same as +203 +204 +205)
  • By IP address, e.g. +192.168.141.203
  • By the name of a robot or a fleet, e.g. +bob (which looks up the IP addresses or robot IDs in the environment variable K3_BOB)

A special robot is '+usb' which always translates to 192.168.1.2, the address of a robot connected via USB.

Working with a Fleet of Robots edit

If you are frequently working with a whole fleet of robots, it is Pinnacle Hip Lawsuit advantageous to give this fleet a name and define it as an environment variable. For instance, if you are working with robots 203, 204, 209, 210, 211 and 212, add the following line to your .bashrc file:

export K3_MYFLEET=+203 +204 +209-212

and reload that file (source ~/.bashrc). From now on, you can select these robots using +myfleet as script argument. For instance, to copy the infrared_proximity program onto these robots, type

k3put +myfleet infrared_proximity

List of Available Scripts edit

Core Scripts edit

The following scripts are often used:

Script Description and example
k3put Copies files onto your fleet of robots. In the Programs folder, you only need to provide the folder name and the script automatically looks for the binary inside this folder.
k3put +203 +204 battery motor_* motion_*
k3get Copies files from your robots to the PC. The files are put in folders named k3-ROBOTIP on the PC. These folders are automatically created if necessary. If the destination file exists, it is overwritten without mercy!
k3get +203 +204 my_measurements

This will create the two folders k3-192.168.141.203 and k3-192.168.141.204, and copy my_measurements from both robots into the respective folder.

k3go Connects via SSH to one robot and opens an interactive shell.
k3go +203
k3run Executes a command on all robots and optionally stores the output in folders named k3-ROBOTIP on the PC. For instance, you can record 10 infrared proximity measurements on two robots by typing
k3run +203 +204 -o my_infrared_measurements -e my_stderr - /root/your_username/infrared_proximity -r 10

This will create the two folders k3-192.168.141.203 and k3-192.168.141.204, and save the output of the program to a file called my_infrared_measurements within these folders. Just as with k3get, existing destination files are overwritten without merci. Note that the programs are started in parallel on all robots. However, program execution is not synchronized, i.e. one robot may start the program before another robot. Differences in starting times mostly depend on the WLAN channel and are usually in the order of 10 - 100 ms, but can be several seconds if the WLAN channel is heavily loaded or jammed. If you start programs that do not quit automatically, you can stop them using k3kill.

k3halt Shuts robots down by executing the halt command on each robot.
k3halt +203 +204
k3ping Pings one robot continuously, e.g.
k3ping +203

or reports for multiple robots whether they are alive, by sending 3 ping packets:

k3ping +203 +204
k3kill Stops a running program on all robots.
k3kill +203 +204 infrared_proximity

Development Scripts edit

The following scripts are used for developing new programs and modules:

Script Description and example
k3-create-program Creates a new program on the computer.
k3-create-program my_new_program

Note that this script does not interact with any robot. For more information, check out the program development section.

k3-create-module Creates a new module on the computer.
k3-create-module my_new_module

Note that this script does not interact with any robot. For more information, check out the module development section.

Administration Scripts edit

The following scripts help with a couple of administrative tasks and are less frequently needed:

Script Description and example
k3-ssh-keysetup Adds your SSH key on the robots.
k3-ssh-keysetup +203 +204
k3-erase-userfiles Erases your folder (/root/your_username) on the selected robots:
k3-erase-userfiles +203 +204

Optionally, a username can be specified to delete those folders instead of yours on the robots:

k3-erase-userfiles another_username +203 +204
k3-diskusage Reports disk usage of each robot.
k3-diskusage +203 +204

Filter Scripts edit

The following scripts convert program output into another format:

Script Description and example
k3-nmea-to-csv Converts NMEA messages of a certain type (command) to CSV (comma separated values) format.
k3-nmea-to-csv IRPROXIMITY < my_nmea_file > my_csv_file

A more detailed description can be found in the section on program output parsing


The Toolbox/Programs

The Programs folder contains a series of useful programs and algorithms that run on the Khepera III robot, and interact with its sensors and actuators (motors). These programs are also useful templates to implement your own algorithms. In this chapter, we briefly explain how to use these programs.

Program List edit

Infrared sensors (including the two infrared floor sensors):

  • infrared_ambient: Measures the ambient infrared light with all infrared sensors.
  • infrared_proximity: Measures the proximity to obstacles with all infrared sensors.

Motors:

  • motor_initialize: Initializes both motors. This program must be launched after switching on the robot.
  • motor_setspeed: Sets the motor speed.
  • motor_stop: Stops both motors immediately.
  • motor_setposition: Sets the current position of the motor encoders.
  • motor_gotoposition: Drives the motor to a specific motor encoder position.
  • motor_getposition: Returns the current position of the motor encoders.
  • motor_configuration: Prints the complete configuration (registers) of both motors.
  • motor_setspeedprofile: Sets the trapezoidal speed profile.

Ultrasound:

  • ultrasound_enable: Enables or disables the ultrasound sensors.
  • ultrasound: Measures the proximity to obstacles with the ultrasound sensors.

Battery:

  • battery: Returns the current state of the battery.

General:

  • firmware_version: Returns the firmware version of the dsPIC and the motor PICs.
  • test_math: Tests a couple of mathematical functions. This program serves more as a template rather than a useful program.
  • tcp_server: Demonstrates how to write a program which accepts a TCP connection.
  • i2c: General I2C utility.
  • i2c_readstream*: Reads a data stream from an I2C device.

Motion:

  • motion_braitenberg: Implements object following, obstacle avoidance and wall following using the Braitenberg algorithm.
  • motion_arrowkeys: Allows to drive the robot around using the keyboard.
  • motion_followline: Makes the robot follow a line on the ground.
  • motion_forwardbackward: Makes the robot continuously move forward and backward.
  • motion_random: Drives the robot randomly around.
  • motion_spiral: Makes the robot move along a spiral.

Odometry:

  • odometry_track: Tracks the position of the robot based on differential-drive odometry using the encoder values.
  • odometry_goto: Drives the robot to a given target position, while keeping track of its position using odometry.

Programs marked with an asterisk (*) are currently incomplete and need some reworking to be done.

Launching a Program edit

Each program is stored - with its source code, a Makefile, a compiled binary and possibly additional material - in a subfolder of Programs. The binaries are compiled for the Korebot platform (ARM processor running a Linux kernel 2.4) and therefore only run on the Korebot.

To use a program, copy it onto your robot first:

cd Programs
k3put +usb infrared_proximity

(If your robot is connected via WLAN, replace the +usb by +RobotID.) Then, log on to your robot by typing

k3go +usb

and launch the program there

cd your_username
./infrared_proximity

The program will write its output directly in the terminal window.

Getting Help edit

Each program prints a little help text when launched with the -h option, e.g.

./infrared_proximity -h

Redirecting the Output of a Program to a File edit

In some cases, you may want to write the output of a program (e.g. infrared proximity measures) to a file instead of displaying it on the screen. The standard Linux tools offer several ways to achieve that:

To write the output to a file on the robot, simply redirect the output to a file when launching the program:

./infrared_proximity > my_infrared_proximity_measures

Note that there is only about 1 MB of space available on the robot.

To write the output to a file on your computer, launch your program via SSH and redirect the output to a file. For those not so familiar with SSH, this may get a bit tricky. But fortunately, there is a Khepera III script which does all that for you automatically:

k3run +usb -o my_output_file /root/your_username/infrared_proximity -r

If your robot is connected via WLAN, replace the +usb by +RobotID. This transfers the output of the program over the network connection and stores it in the file my_output_file in the folder k3-192.168.1.2 on the computer. This is actually faster than writing the output to a file on the robot (even if this sounds counter-intuitive), because WLAN transmission is usually faster than writing to the flash memory on the robot.

Running Multiple Programs at the Same Time edit

You can run several programs on the robot at the same time. This can make sense, for instance, if you want to steer your robot with the keyboard (motion_arrowkeys) and log infrared sensor measurements at the same time (infrared_ambient, infrared_proximity), or track the path of the robot (odometry_track). This is also useful for monitoring the battery level with a program running in the background.

To achieve that, you can log in several times on the same robot (k3go), run one program in the background (e.g. ./infrared_ambient > my_measures &), or launch some programs from the computer (k3run).

There are a few things to keep in mind, however:

  • It does not make sense to run two programs which both set motor speeds. Each time one programs sets the speed, the old speed is overwritten, resulting in quite unpredictable behavior.
  • One program may slow down the other program. The CPU is a shared and limited resource (use top to check CPU usage), but even more so is the I2C bus which is used to communicate with the sensors and actuators of the robot. You should therefore avoid reading the same sensor value with several programs in parallel.

Important note: If you are running programs based on the libkorebot library from K-Team, you should never run any other program accessing the sensors or actuators in parallel, as this may cause such programs to obtain wrong sensor values or crash.


The Toolbox/Modules

The Modules folder contains code libraries with functionality useful in many programs. These modules are used by the programs in the Programs folder, and can also be used in your own programs that you write for the Khepera III robot.

Module List edit

  • commandline: A simple command line parser.
  • i2cal: An easy-to-use interface for I2C communication.
  • i2c stream: An interface for I2C data streaming.
  • khepera3: Functions to access the sensors and actuators of the Khepera III robot. This module requires the i2cal module.
  • measurement: A general interface for all programs reporting sensor values.
  • nmea: A NMEA parser.
  • odometry track: Tracks the robot position (x, y, angle) by measuring the wheel rotation. This module requires the khepera3 module.
  • odometry goto: Drives the robot to a specific position (x, y). This module requires the odometry_track module.


The Toolbox/Install Scripts

The folder InstallScripts in the top folder of the Khepera III Tools contains scripts to set up a couple of useful things on the robot. These scripts require a Khepera III robot to be connected via USB to the computer.

Before launching the install scripts, we suggest you to set up SSH public key authentication between your computer and the robot. This can be done with one of the Khepera III Toolbox scripts:

cd Scripts
./k3-ssh-keysetup +usb
cd ..

To launch all install scripts, type

cd InstallScripts/Kernel-2.6
./install

If you are launching this install procedure for the first time with your robot, the script will first ask you to give your robot an ID. This ID is used to assign a WLAN IP address for the robot, and may also be used by programs running on the robot as a unique identifier of the robot. Needless to say that this ID must be unique among your fleet of robot. If the robot has been given an ID before, the same robot ID will be used.

If your robot is not connected via USB, but some other mechanism, invoke the install script with the IP address of the robot, e.g.:

./install 192.168.141.200

Default Install Scripts edit

The install script will invoke the following three install scripts (which can also be executed separately if necessary):

  • install_robotid SSHHOST ROBOTID: Sets up the robot ID. Invoke this script separately if you wish to change the robot ID of a robot which already has an ID.
  • install_profile SSHHOST ROBOTID: Copies a bash profile with a bunch of useful aliases (l, .., ...) onto the robot.
  • install_network SSHHOST ROBOTID: Sets up the WLAN network interface. The IP address assigned to the interface is 192.168.141.ROBOTID.

Creating Your Own Install Scripts edit

In some circumstances, you may want to install your own things in addition to the default install scripts. To do that, take a copy of install_my_own_stuff.template and write your install commands in there. Do not forget to add your script to install.


Parsing Program Output

The Khepera III Toolbox (notably the programs) uses NMEA 0183 messages as output data format. NMEA 0183 is a message-oriented communication protocol known from GPS receivers, which is about equally simple to read for humans and for computers.

NMEA 0183 Messages edit

NMEA 0183 is a communication standard specifying electrical characteristics as well as data format characteristics. Here, we are only using the message format of NMEA.

An NMEA message (or sentence) looks as follows:

$SPEED,10000,15000

Messages always start with a $ sign, followed by a command and a list of arguments. The command as well as the arguments are separted by commas. Optionally, the message contain a trailing checksum (e.g., *4D), but none of the Khepera III programs writes this checksum.

The original NMEA specification does not allow the command to be longer than 5 characters. The Khepera III toolbox, however, does not use this restriction in favor of longer and more explicit command names.

A stream of NMEA messages can contain different types of messages, e.g.

$STATE,random_motion
$SPEED,10000,15000
$SPEED,11000,14000
$SPEED,12000,13000
$STATE,follow_wall
$SPEED,5000,5000

which is very handy for reporting results.

Advantages of NMEA 0183 edit

The NMEA 0183 message format has several advantages:

  • It is human readable.
  • It is easy to parse by computers and the checksum (if any) is easy to calculate.
  • As it uses a start of message character ($) and an end of message character (CRLF), you can break a data stream apart at any point, and the parser will be able to resynchronize (i.e., read all complete messages).
  • It starts with a message type and therefore allows messages of different types to be interleaved in the same stream.
  • It optionally allows for a checksum, which is useful when the data is transmitted over lossy channels.
  • It can be converted to a CSV file with search-and-replace (see below).

Converting NMEA messages to CSV with a Text Editor edit

If you have a file with messages of one single type, e.g.

$SPEED,10000,15000
$SPEED,11000,14000
$SPEED,12000,13000
$SPEED,5000,5000

you can use any text editor to transform it into CSV. Simply replace $SPEED, by nothing, and save the file. The resulting file can be loaded in almost any program (Matlab, Microsoft Excel, ...).

Converting NMEA messages to CSV with k3-nmea-to-csv edit

Instead of using a text editor, you can also use the k3-nmea-to-csv filter script to convert NMEA messages to CSV. Just pipe your file through that script, by providing the NMEA command of the messages to extract, e.g.:

k3-nmea-to-csv SPEED < my_nmea_file > my_csv_file

All messages that are not of type SPEED will be ignored.

Note that you can use this filter script with any program to convert its output to CSV. For example,

./infrared_proximity -r | k3-nmea-to-csv IRPROXIMITY

would output the IR proximity sensor values as CSV.

Parsing NMEA with Scripts edit

NMEA can easily be processed with Perl, Python, Ruby or similar scripting languages. Example scripts can be found in the Examples section.

Parsing NMEA on the Robot edit

The modules section contains an NMEA parser (module nmea) written in C with can be used to parse NMEA messages on the robot. This can be useful to read a configuration file, for instance.


Writing your Own Programs

Even though the standard programs allow you to interact with all sensors and actuators of the robot, you probably want to implement your own algorithms. The Khepera III Toolbox provides you with a nice and easy-to-use API for accessing the sensors and actuators of the robot, and several hundred lines of sample code in C. In addition, a Makefile is available.

Preparing the Environment edit

Linux for Korebot edit

First of all, make sure that make is available on your computer by typing

make -h

If the computer complains that he could not find make, install it using the package management system of your Linux distribution.

Next, you need to install the ARM compiler toolchain. Download the file korebot-tools-i386-0.1.2.tar.gz (KoreBot Compilation Toolchain for Linux i386 host) from the K-Team website and unzip it somewhere in your home directory, or in /usr/local/

tar -xfz korebot-tools-i386-0.1.2.tar.gz

Add the bin directory to your PATH environment variable, preferably by adding the following line to your .bashrc file:

export PATH=$PATH:/path/to/your/arm/toolchain/bin

and restarting your bash shell (terminal).

At this point, your computer should not complain any more if you just type

arm-linux-gcc --help

Linux for Korebot 2 edit

First of all, make sure that make is available on your computer by typing

make -h

If the computer complains that he could not find make, install it using the package management system of your Linux distribution.

Next, you need to install the ARM compiler toolchain. Download the file korebot2-oetools-light-1.0-kb1.2.tar.bz2 from the K-Team website and unzip it somewhere in /usr/local/. Doing it in /usr/local is necessary so the compiler can find the libraries.

wget http://ftp.k-team.com/KorebotII/software/light_toolchain/korebot2-oetools-light-1.0-kb1.2.tar.bz2
tar xvjf korebot2-oetools-light-1.0-kb1.2.tar.bz2
sudo mv korebot2-oetools-1.0/ /usr/local/

Add the bin directory to your PATH environment variable, preferably by adding the following line to your .bashrc file:

export PATH=$PATH:/usr/local/korebot2-oetools-1.0/tmp/cross/bin/

and restarting your bash shell (terminal).

At this point, your computer should not complain any more if you just type

arm-angstrom-linux-gnueabi-gcc --help

Mac OS X edit

At the time of writing, we are not aware of any ARM compiler toolchain for Mac OS X, although I'm pretty sure there must be one out there. All other steps should be the same as on Linux (see above).

Creating a New Program edit

To create a new program, type

cd my_khepera3_project_directory
k3-create-program my_new_program

where my_new_program denotes the name of your program. This creates a folder my_new_program and copies a sample main.c file as well as a Makefile in there.

To check if everything is all right, try to compile the new program:

cd my_new_program
make

This should create a binary executable my_new_program which you can copy onto the robot and execute there.

You can now edit the file main.c and implement your algorithm there. In case you have a complex algorithm to implement, you can of course create additional *.c and *.h files. All *.c in the project folder will automatically be passed to the compiler when launching make.

Miscellaneous edit

Renaming a Program edit

The name of the binary executable can be changed in the Makefile by modifying the line

TARGET := my_new_program

Note that by convention, the executable should always have the same name as the project folder. (The script k3put relies on that when specifying a program folder.)

Including Modules edit

The Makefile also contains a list of modules that must be compiled with your program. Most programs will use the following modules:

MODULES := khepera3 commandline i2cal

If your program needs another modules (e.g. measurement), simply add these modules to that line.

Including the libkorebot Library edit

Even though the Khepera III Toolbox does not need the libkorebot library (and implements nearly its whole functionality), you may have code that needs to be compiled against that library. To do that, add the following lines to your Makefile:

LIBKOREBOT := /path/to/libkorebot-1.10/build-korebot/
INCS_ADD   := -I $(LIBKOREBOT)/include 
LIBS_ADD   := -L $(LIBKOREBOT)/lib -lkorebot

Note that the compiled programs will only work if the library libkorebot.so is available on the robot.

Programming Style edit

Programming style is an art rather than an exact science. The Khepera III Toolbox uses a rather compact programming style, but does not follow any specific convention. For your own programs, you are of course free to stick to your own coding style.

There are tools available to automatically format your source code conforming to some rules. One of these tools is Artistic Style, a very easy to use open source program. After installing this program, the following command applies minimal formatting (even spacing between the operators and indentation using tabs):

astyle -p --indent=tab main.c

A copy of the original file will be saved as main.c.orig.

SVN / Versioning System Issues edit

We strongly suggest using a versioning system such as SVN (Subversion) to store your Khepera III programs. SVN is probably the most prominent system today, and easy to set up and use.

If you are using a versioning system, you should check in the following files of your program:

  • All source files (*.c, *.h)
  • The Makefile
  • The compiled program (such that a compiled copy is available for those who don't have a compiler set up)
  • Any additional files that the program needs

You should not check in:

  • Intermediate compilation files (*.o, *.d)


Writing your Own Modules

If you add want to use the same piece of code in multiple programs (i.e. a sensor board interface, or a common algorithm), it may be useful to create a module. Such a module can be included and used in all your programs.

The Khepera III Toolbox provides you with a module template and a Makefile.

Preparing the Environment edit

Make sure that you have a working development environment as described in Writing your Own Programs.

Creating a New Module edit

To create a new module, type

cd my_khepera3_module_directory
k3-create-module my_new_module

where my_new_module denotes the name of your module. This creates a folder my_new_module with a header and an implementation file (my_new_module.h ,my_new_module.c). A Makefile is created as well.

To check if everything is all right, try to compile the new module:

cd my_new_module
make

This should create an archive my_new_module.a.

You can now edit the files my_new_module.h and my_new_module.c. In case your module is more complex, you can of course create additional my_new_module_*.c and my_new_module_*.h files (note the prefix my_new_module_!). All these additional files will automatically be compiled and available to the programs including the module.

Testing the Module edit

A module cannot be executed by itself. To test a module, you must create a program that includes this module. To include your module, add the following line to the Makefile of your program:

MY_MODULES := path/to/my_new_module

This will tell the compiler to look for the *.h files of that module, and to integrate the my_new_module.a archive into the program. (If your program needs multiple modules, simply add them on the same line. Note that all module folders must reside at the same location.)

Now, you can use the functions of the module in your program, and test them therewith. Note that whenever you change code in your module, you need to first recompile the module, and then recompile the program.

Miscellaneous edit

Renaming a Module edit

The name of the binary executable can be changed in the Makefile by modifying the line

ARCHIVE := my_new_module.a

Note that the archive should always have the same name as the project folder, suffixed by .a.

Including Modules in a Module edit

A module can include other modules. To include standard modules, add the following line (with the modules you want to add, of course) to the Makefile:

MODULES := khepera3 commandline i2cal

To include other modules that you wrote on your own, add

MY_MODULES := path/to/my_other_module_1 path/to/my_other_module_2

to the Makefile.

SVN / Versioning System Issues edit

Just as for programs, we strongly suggest using a versioning system such as SVN (Subversion) to store your Khepera III modules. SVN is probably the most prominent system today, and easy to set up and use.

If you are using a versioning system, you should check in the following files of your module:

  • All source files (*.c, *.h)
  • The Makefile
  • The compiled archive (*.a) (such that a compiled copy is available for those who don't have a compiler set up)
  • Any additional files that the program needs

You should not check in:

  • Intermediate compilation files (*.o, *.d)


Programming Hints

Writing programs for the Khepera III robot is pretty straightforward. Nevertheless, a good program structure and doing things right the first time will save you time - a lot of time! In this chapter, we therefore discuss a couple of design choices when implementing such programs.

General Structure of a Program edit

A Simple Program with One State edit

A simple program will have the following structure:

// Program initialization
commandline_init();
...
commandline_parse(argc, argv);
...
khepera3_init();

// Algorithm initialization
algorithm.configuration.wall_threshold = 1000;
...
khepera3_drive_start();

// Main loop
while (true) {
    // Read sensors
    khepera3_infrared_proximity();
    ...

    // Calculate actuator response
    speed_left = ...
    speed_right = ...

    // Termination condition
    if (...) {
        break;
    }

    // Set actuators
    khepera3_drive_set_speed(speed_left, speed_right);
    ...

    // Sleep for a while
    usleep(algorithm.configuration.wait_us);
}

// Algorithm termination/cleanup if necessary
khepera3_drive_set_speed(0, 0)

Most programs consist of a main loop which is executed after an initialization phase. The main loop implements the so-called perception-to-action loop - the loop which reads the sensor values, derives the action to take, and sets the actuators (motors) accordingly. The main loop sometimes also contains a termination condition which quits the program as soon as the goal has been reached.

If you are looking at the code of existing programs (e.g. motion_followline), you will notice that the above structure implemented in different functions. Typically, the structure is broken up into the following functions

  • help: Prints a help text.
  • algorithm_init: Initializes the algorithm.
  • algorithm_run: Executes the main loop.
  • main: Initializes the program and calls the above functions.

In addition, a structure holding the configuration and the state (if necessary) of the algorithm is defined:

// Algorithm configuration and state variables
struct sAlgorithm {
    struct {
        int wall_threshold;
        ...
        int verbosity;
    } configuration;
    struct {
        int remaining_targets;
        ...
    } state;
};

// Declare an instance of that structure
struct sAlgorithm algorithm;

// Access to the variables
algorithm.configuration.wall_threshold = ...
algorithm.state.remaining_targets = ...

Even if this looks complicated at first sight, using this nested structure has two advantages. First of all, all algorithm variables are declared in one place. If you want to reuse that algorithm somewhere else, you see at a glance which variables are needed. Second, the classification into configuration variables and state variables will help you implementing the algorithm in a clean way. Configuration variables will only be written during the initialization phase and should only be read in the main loop. State variables, however, are read and written in the main loop.

Programs with Multiple States edit

Often, programs have more than one state. A robot engaged in a search task, for instance, will maybe have an exploration state in which it walks randomly around, and a gradient following state in which it tries to move towards the target.

The simplest way to implement that is with different main loops, i.e. one main loop per state. A code skeleton for that looks as follows (note that the template program created by the k3-create-program script uses exactly this skeleton):

// Algorithm variables
struct sAlgorithm {
    ...
    struct {
        void (*hook)(); // Pointer to the current state function
        ...
    } state;
};

// Forward declaration of states
void state_exploration();
void state_gradient_follow();
void state_success();

// Algorithm initialization
void algorithm_init() {
    ...

    // Set the initial state
    algorithm.state.hook = state_exploration;
}

// The algorithm just switches from state to state by calling the current state function
void algorithm_run() {
    while (1) {
        algorithm.state.hook();
    }
}

void state_exploration() {
    // State initialization
    ...

    // Main loop
    while (1) {
        // Read sensors
        ...
    
        // State change condition
        if (...) {
            algorithm.state.hook = state_gradient_follow;  // Switch to the gradient follow state
            return;
        }

        // Set actuators
        ...

        // Sleep for a while
        usleep(algorithm.configuration.wait_us);
    }
}

void state_gradient_follow() {
    // State initialization
    ...

    // Main loop
    while (1) {
        // Read sensors
        ...
    
        // State change condition
        if (...) {
            algorithm.state.hook = state_exploration;  // Switch to the exploration state
            return;
        }

        // Termination condition
        if (...) {
            algorithm.state.hook = state_success;  // Switch to the success state, which terminates the program
            return;
        }

        // Set actuators
        ...

        // Sleep for a while
        usleep(algorithm.configuration.wait_us);
    }
}

void state_success() {
    // We are done
    exit(0);
}

Do not fear the function pointer (algorithm.state.hook)! Its declaration may look complicated, but it is very easy to use, as you can see in the state functions above. Adding, moving or removing states becomes extremely easy, as you can treat a state as one contiguous block of code. In case the robot does not behave as desired in one particular state, you can modify its code without hurting other states (which is typically the case if you put everything in one main loop with a series of if's).

Moreover, if you draw your algorithm as a state machine on a paper first, you can implement the code right away following exactly the schema on your paper. Each state will correspond to one function, and each arrow to one state change condition.

Stability and Execution Speed edit

From your control theory course, you probably know that the perception-to-action loop has to run at a certain minimum frequency such that the stability criterion is fulfilled. On the other hand, running that loop at higher speed also consumes more energy.

The speed of the perception-to-action loop shown in the code examples above is determined by three factors:

  • The communication overhead, i.e. the time required to read the sensors and set the actuators.
  • The processing overhead, i.e. the time required to derive the action from the current perception.
  • The waiting time (usleep(algorithm.configuration.wait_us)), which can be adjusted at will.

The communication overhead can only be optimized up to some point. There is a hard limit on the number of bytes you need to transfer between the robot and the Korebot board (processor board) to get a certain piece of information, and the communication channel (I2C bus) has a fixed speed of roughly 10 KB/s. Hence, a call to the khepera3_infrared_proximity function to obtain infrared proximity sensor values will return after about 3.1 ms (if the I2C bus is free), as it has to transfer 31 bytes from and to the microcontroller. The number of bytes transferred by each function can be found in the .h files of the khepera3 module.

Similarly, a certain amount of operations will be necessary for deriving the action given the sensor readings and the current state. Basic mathematical operations are fast as compared to the communication overhead, but making extensive use of log, exp or trigonometric functions will slow down the main loop. In addition, everything that has to be written to, or read from disk will involve substantial overhead as well. Last but not least, the printf can severly slow down your program depending on where the output is redirected.

While the communication overhead can be accurately calculated, the processing overhead needs to be measured in the environment the program is running (e.g. with stdout redirected to where it will be redirected for the real experiments). The waiting time can then be adjusted to achieve the desired perception-to-action loop frequency.

To Thread or Not To Thread edit

Whether to use threads or not is a huge debate in computer science. The Khepera III Toolbox does not force you to use or not use threads, but it has been written with the idea in mind that most programs won't be multithreaded.

If you are using the code skeleton provided above, you will naturally not use threads (or a single thread, if you want). This makes sense, considering that there is not much to parallelize: the robot can only be in one state at a time, and the inside of a perception-to-action loop has to be executed in a precise order.

Asynchronous IO and the select Syscall edit

When writing programs that are waiting for some data to arrive on open filehandles, the select syscall will be useful. This syscall takes a list of filehandles, and returns if either data is available on one of them, or a timeout has occurred. The select syscall is the solution to most problems where programmers think they need threads.

As an example for this, have a look at the motion_arrowkeys program, which waits (in an non-blocking fashion) for user input on the standard input and executes the main loop at the same time.

Using Threads anyway edit

If - for one reason or another - you need go for multiple threads, some care has to be taken when accessing the robot sensors and actuators. Basically, you are not allowed to access the khepera3 module or the i2cal module in a concurrent way, as these modules use statically allocated variables and are therefore not thread-safe. There are two solutions to that:

  1. Design your program in such a way that only the main thread (or another dedicated thread) is accessing these modules. This is straightforward in some cases, but can get extremely complicated in other situations.
  2. Synchronize all calls to the khepera3 module and all i2cal transactions. They need to be synchronized with the same mutex, as the khepera3 module uses the i2cal module to communicate with the sensors, i.e. a most khepera3 functions are transactions on the I2C bus.

In case you wonder: the current implementation is intentionally not thread-safe, since that would make the function calls more complicated and more error-prone for single-threaded applications. In the future, however, a thread-safe implementation may be added (e.g. as a separate module).

Splitting Up Algorithms into Independent Parts edit

Just as we break down the implementation of algorithms into functions that implement one state each, we could also split them up into different programs that implement a subset of the states each, and execute them the right order. This works, and is actually a very good technique in many situations!

The Maze Traversal Example edit

Assume you want to test different algorithms to traverse a maze. The maze entrance is on the left, and the exit on the right side of your arena. Since you want to run the experiment several times, you want your robot to automatically go back to the entrance once it has reached the exit, e.g. by following a line on the ground. You could of course add a new state (state_go_back_to_entrance) to all your algorithms, and switch to that state when the exit has been reached. However, you could also implement this as a separate program (maze_go_back_to_entrance) which you call immediately after any of your maze traversing programs.

Overhead and Speed Considerations edit

There is some processing overhead in starting and quitting programs, but from an operating system point of view, this overhead is small. You should be careful about your initialization phase, though. For instance, if you have to load big files (e.g. maps, ...) at program start, this may introduce some significant delay. In addition, if you launch your programs remotely over a WLAN connection, there is a small transmission delay (~ 10 ms) to take into account.

Splitting Rules edit

There is no definite answer on when to split and how much to implement in the same program. However, here are a couple of thoughts:

  • Do split if this helps you testing and debugging individual parts of your algorithm.
  • Do split if this avoids having exactly the same pieces of code in several programs (as in the maze traversal example above).
  • Do split if you think you can reuse at least one part somewhere else.
  • Do split if the two parts have nothing in common.
  • Do not split if the transition is complex (e.g. multiple target states possible)
  • Do not split if the precise timings or low delays are an issue.
  • Do not split if the two parts share state variables or a lot of data.

In addition, it is usually preferred to implement an algorithm to run exactly once, and then quit. If want to test your algorithm in multiple runs, simply launch that program multiple times (with a script, for example) and redirect the output to a different file each time. This approach is much more flexible and robust.

Code Examples edit

The measure_real_speed example uses a script to run the same program multiple times with different parameters.


Examples

In this chapter, we give examples on how to use the Khepera III Toolbox. Some of these examples are common tasks (e.g. odometry calibration) which you may need one day. Others are rather didactical or meant as a starting point for your own projects.

The files needed to run these examples are stored in the Examples folder the Khepera III Toolbox.

  1. plot battery voltage: Plot the battery voltage over time
  2. infrared proximity sensor response: Plot a diagram with the distance vs. infrared proximity value
  3. measure real speed: Measure the real speed of the robot
  4. odometry calibration: Calibrate the odometry of the robot
  5. i2c odorboard: Use the i2c and i2c_stream_read programs to access an extension board


Advantages of the Khepera III Toolbox

The Khepera III robot comes with a library called libkorebot to access the sensors and actuators of the Khepera III robot. In addition, a program called khepera3_test can be used to read sensor values on the command line. The Khepera III Toolbox is more or less a clean rewrite of these two pieces of software. Note, however, that the libkorebot library is compatible with several robots produced by K-Team, whereas the Khepera III Toolbox - as its name suggests - is made for the Khepera III robot only.

In this chapter, we motivate why the Khepera III Toolbox should be used instead of the libkorebot library.

A Nicer, Simpler and Safer API edit

The Khepera III Toolbox provides an easy-to-use API to access the sensors and actuators of the robot. Values read from sensors are parsed and put inside a data structure for easy access. To read the floor sensor, for example, the following code can be used:

int floor_sum;
khepera3_infrared_proximity();
floor_sum = khepera3.infrared_proximity.sensor[cKhepera3SensorsInfrared_FloorLeft] + khepera3.infrared_proximity.sensor[cKhepera3SensorsInfrared_FloorRight];

Note that re-entrant versions for programs with multiple threads exist as well, and are just slightly more complicated to use.

The libkorebot library only reads messages and provides the programmer with a buffer, which he has to parse by himself. This is very error-prone and makes the resulting code hard to read. The following piece of code is equivalent to the code above:

char buffer[MAXBUFFERSIZE];
int floor_left, floor_right, floor_sum;
kh3_proximity_ir(buffer, dsPic);
floor_left = buffer[15] | buffer[16] << 8;
floor_right = buffer[17] | buffer[18] << 8;
floor_sum = floor_left + floor_right;

Synchronization Issues when Running Multiple Programs at the Same Time edit

The libkorebot was written with the idea in mind that only a single program would run on the robot at the same time. The code used to access the sensor values is therefore not safe when two or more programs are running at the same time. E.g., if a program is reading infrared proximity values, and another program ambient infrared values, the programs may occasionally get the wrong type of measurements for their request.

There is not technical reason why running multiple programs at the same time should cause problems, especially when they are working with a different subset of sensors and actuators.

The Khepera III Toolbox communicates with the sensors and actuators in an atomic fashion, and therefore enables running programs side by side.

Additional Modules edit

Besides the khepera3 module, the Khepera III Toolbox offers a series of other useful modules to write programs for the robot. Among them are a module to parse command line arguments, a module to send messages over the I2C bus, and a module to track the robot position using wheel odometry.

Programs edit

While the khepera3_test program provided by K-Team is one monolithic program intended for testing, the Khepera III Toolbox provides a series of small programs that can be used for testing and serious experiments.

Speed edit

Both the libkorebot and the Khepera III Toolbox have comparable speed. The time required to read sensor values or send motor commands mostly depends on the speed of the I2C bus and the length of the messages. The processing overhead is negligibly small.

Scripts edit

There is no equivalent to the Khepera III Toolbox scripts in the code provided by K-Team.