Khepera III Toolbox/Print version
This is the print version of Khepera III Toolbox You won't see this message or any elements not part of the book's content when you print or preview this page. |
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
Download and Installation
Download
editDownloading the Package
editA 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
editThe 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
editThe 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
editWe 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
editType
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
editTwo 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
editAt 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
editThe 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
editTo 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
editFor 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
editThe 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
editIf 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
editOn 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
editTo 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)
editIf 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
editAll 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
editMost 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
editIf 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
editCore Scripts
editThe 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
editThe 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
editThe 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
editThe 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
editInfrared 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
editEach 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
editEach 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
editIn 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
editYou 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
editThe 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
editIn 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
editNMEA 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
editThe 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
editIf 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
editInstead 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
editNMEA 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
editThe 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
editLinux for Korebot
editFirst 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
editFirst 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
editAt 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
editTo 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
editRenaming a Program
editThe 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
editThe 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
editEven 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
editProgramming 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
editWe 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
editMake sure that you have a working development environment as described in Writing your Own Programs.
Creating a New Module
editTo 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
editA 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
editRenaming a Module
editThe 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
editA 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
editJust 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
editA Simple Program with One State
editA 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
editOften, 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
editFrom 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
editWhether 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
editWhen 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
editIf - 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:
- 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.
- 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
editJust 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
editAssume 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
editThere 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
editThere 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
editThe 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.
- plot battery voltage: Plot the battery voltage over time
- infrared proximity sensor response: Plot a diagram with the distance vs. infrared proximity value
- measure real speed: Measure the real speed of the robot
- odometry calibration: Calibrate the odometry of the robot
- 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
editThe 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
editThe 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
editBesides 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
editWhile 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
editBoth 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
editThere is no equivalent to the Khepera III Toolbox scripts in the code provided by K-Team.