IVR Practical Two: Introduction to Robotics 1 (Week 7)


The purpose of this practical is to:
You should be able to run your programs either controlling the real robot or the simulated webot. If you didn't use the robot last week you should start with the robot this week, otherwise start with webots and switch later in the practical.  Note that if you were working in a group last week, and did not download the IVR software to your own filespace, you will need to do so to be able to communicate with webots or the robot. It is available here: http://www.inf.ed.ac.uk/teaching/courses/ivr/kheperam-Webots6.2.tar.gz.

Webots

If, earlier, you needed to provide the computer with the path to the matlab executable using the export PATH:$PATH:/opt/matlab-R2014a/bin/ command, then this is needed before running webots. This path modification is temporary and is only valid for the terminal that it has was typed in.

To run the webots simulator, from the shell (currently there is some problem on Dell DICE machines, so use HP DICE machines) type webots (N.B. don't use webots & because webots will be sending some useful messages to the terminal window).

A window showing a simulated world with a robot or robots should appear.

To communicate with the robot we are going to use the serial protocol defined for the Kheperas (see the manual). To do this you need some extra software. Download and unzip the files from: http://www.inf.ed.ac.uk/teaching/courses/ivr/kheperam-Webots6.2.tar.gz.

Move it into your preferred directory, and do:

tar xvfz kheperam-Webots6.2.tar.gz

This will create two subdirectory directories which are used by webots.

If not already loaded, open the world file khepera.6.2.wbt from file menu in Webots. Then use the Webots editor to open the file matlabcontrol. This will start a matlab window where you can continue as follows:

Having chosen two small integers for the arguments left_speed and right_speed, you can then send a command to the robot as follows:

>>wb_differential_wheels_set_speed(left_speed, right_speed);

The robot will not react to this command until your type the word (!)

>>return;

and press the enter key. Now you should see the simulated robot start to move.

Why is the return required? Usually, the robot is supposed to be autonomous, i.e. once a command is sent the robot starts its operation until finished. In order to be able to remote-control, the robot runs in an interactive mode which requires such a confirmation of the command.

The values left_speed and right_speed set the speed of the left and right wheel, respectively. E.g. the choice left_speed=2 and right_speed=-2 should make the robot rotate.

Now, try left_speed=3 and right_speed=-1 to make it move in a curve, or left_speed=-5 and right_speed=-5 to make it go backwards. To stop it, used the values left_speed=0 and right_speed=0 not forgetting to confirm by return.

For the simulated robot also higher speeds can be used; for the real Khepera robot speedy dricing is not an option as you should assure that the robot stays safe.

Note that everytime you send the robot a command, it replies by sending the current sensor values. Either by the appropriate commands (or using the mouse and the shift key) you can move the robot near a wall. Can you make sense out of the sensor values? If you send return repeatedly while the robot is moving around, you should see the values change as it moves past obstacles.

By an assignment you can also read the value of the proximity sensors into a matlab variable.

Writing scripts in matlab

If you want to execute a sequence of matlab commands without typing each one at the interface, you can put the sequence of commands in a file called a script. The file needs to have a .m extension, e.g. my_task.m They are therefore often referred to as 'm-files'. Within matlab you can execute the script by typing the file name (without the extension) e.g.
>> my_task

N.B. the file needs to be in a directory that is in matlab's search path. The simplest thing is to make a directory under your home directory called matlab, to keep all your m-files, which will be searched automatically.

You can create the m-files in a text editor or use the built in editor in the java interface for matlab. To do the latter, under the `File' menu choose `New'. This is an emacs-like editor, that has some convenient features for debugging code.

Create a file containing the following commands:

% This line is a comment - you can leave out any of these lines
% when copying this code to save time

[x,y] = size(A);
% finds the dimensions of a matrix called A
if x > y
   shape = 'thin'
else
   shape = 'fat'
end

Save this file, in your matlab directory, as `my_task.m'. Then within matlab, first create the matrix:
>> A = [1 2 3; 4 5 6]
then run
>> my_task
to see the output. Keep in mind that a script is just a convenient way to gather a set of commands together, so any variables used in the script will have the value that they have in your workspace, and any variables created or changed will be changed in your workspace. E.g. this script will not run successfully if you haven't defined anything in the workspace called A. And running my_task created the variables `x' and `y' so after running it, you could find their values by typing:
>> x
>> y

You can read the matlab help files to find out what sorts of flow control (i.e. commands like if and while) you can use, but basically, all the common kinds of programming commands are available. For the moment we will just try using a simple script to move the robot on a specific path.

Writing a script for the robot

Let's say we want the robot to drive in a square with 10cm sides, returning to its start location. (N.B. you should try this task first using the webots simulator. For the real Khepera, please see the instructions in item 6 below.
1. Write down in everyday language what sequence of movements the robot needs to make.
2. Assuming you have closed matlab and opened webots, you can now open an m-file in the webots editor (see last week's practical). What are the commands you need to make the robot go forward, and to make it turn on the spot?
3. Write a script that makes the robot go forward for a while, then stop, then turn for a while, then stop.
(Hints: In the last practical the command was send to the robot by typing return. The same can be achieved in a script by setting the simulation time step: wb_robot_step(TIME_STEP); where TIME_STEP is the update interval of webots in milliseconds (e.g. TIME_STEP=64).
In order to specify time intervals for a behaviour of the robot, you can use the command pause(n) to pause execution of the script for n seconds.
You should also make sure that webots is running in 'real time' mode: Go to Tools -> Scene tree. Expand the WorldInfo node and select runRealTime. Check it is set to TRUE, if not alter the tick-box.)
4. How can you determine the pause length needed to travel 10cm, at a given speed?  How long does it take to turn 90 degrees? How accurately can you control the distance covered and turn sizes? What factors determine the accuracy?
5. Edit your script to make the robot drive in a square and stop. Does it end up where it started? You could run several trials and measure the error.
6. If you are using the Khepera robot, you may like to use a square with 20cm sides. See last week's practical for connecting to the robot and repeat item 1. to 5. above.

Writing functions in matlab

Functions are m-files that can accept input arguments  and return  output  arguments. They operate in their own workspace, so they cannot use, modify or add any values to the main workspace, unless they are explicitly  passed as arguments (or declared as global variables). They  start  with the keyword function followed by a specification of the input and output arguments and the function name. The name should always be the same as the filename.

For example, create a file called new_task.m containing the following

function shape =  new_task(B)
% Returns the shape of matrix B
% N.B. comments placed here will be displayed if you type
% help <function-name> at the matlab prompt

[a,b] = size(B);
if a >  b
   shape = 'thin'
else
   shape = 'fat'
end

At the matlab command line type:
>> C = [1 2; 3 4; 5 6]
>> sh = new_task(C)

This passes the matrix C to the function, assigning this to the argument B, finds the shape of this matrix and returns the shape as the value for sh. This time, B, a and b only exist in the local workspace, so you will see that they do not appear in the main workspace after running the command.

As before you can see the matlab help for more information about functions, but let's now go on to write a function for driving the robot in squares of different sizes.

Writing a function for the robot

We want to write a function that will drive the robot in a square of arbitrary size, assuming a fixed speed. I.e. we want to have a function square.m that starts

function [] =  square(size)
% This returns no values, represented by the empty matrix []
....etc

1. The unit of the robot speed is 8 mm/s. Write an expression that, given a distance, calculates the length of time  t needed to move that distance at a given speed. (If you feel keen you could also estimate the relationship between time, speed and turn angle given that the wheel-base of the robot is 53mm).
2. Write a set of commands to move the robot in a square, with each straight section taking time t.
3. Put this together into a function that takes a size, calculates the time needed, and drives the robot around the square.
4. Test how well this works for squares of different sizes.

Some useful functions

The files in the robot_commands directory of the IVR software are a group of scripts and functions to help interface to the robots.  You can look at these to see what they do. In particular, you might find it useful to look at:

wb_differential_wheels_set_speed(left_speed, right_speed) converts the integers left and right into an appropriate command string (e.g. if left =1, right = 2, it will create the string 'D,1,2') sends it to the robot, and reads the resulting robot return signal (i.e. 'd'). It is useful to read the reply because this clears it from the serial line. A more
sophisticated program would check that the reply was correct and report an error if it wasn't.

encoder_value[0] = wb_differential_wheels_get_left_encoder(); and encoder_value[1] = wb_differential_wheels_get_right_encoder(); are the commands for reading from the robots wheel-encoders. You will need to re-initialise these counters by wb_differential_wheels_set_encoders(0, 0); The encoder resolution should be set to 100 by default so the value gets incremented by 2*pi*100 for every wheel revolution.

This is not only useful if you want to use these values to determine further actions but will help you to produce more accurate robot movements than when relying only on time delays.

Making the robot react to the world

So far we have treated the robot as a blind output device. If there is an object in the way as it tries to drive around the square, it will simply run into it. However, it should be able to detect objects using the IR proximity sensors. We will now try writing a program that makes the robot drive forward, but turn left when its proximity sensors on the right go above a threshold, and right when the sensors on the left go above threshold.

To make this easier, we first want a function that sends the 'read proximity sensors' signal and then reads and converts the reply string to numbers. In order to read one of the eight sensors (say sensor i) you can use the command wb_distance_sensor_get_value(ps(i)).

When testing this command from the matlab console, you will need to type return. This is not necessary in the script. Using the read command in a loop you can obtain 8 numbers representing the readings of the sensors.

Work out which number sensors are the front right or front left ones. If you add together the output of the three sensors on each side, what would be a suitable threshold value for deciding when it was close to an obstacle?

Define the contents of a loop that will repeatedly read the sensors, calculate the left and right totals, check if they exceed threshold, and send an appropriate motor command to the robot. Put these commands inside a loop that runs forever, and try running this script on the robot.

If you have time ... get prepared for the next tutorial (in week 8)

Khepera robot

Robots will be provided by the demonstrator or can be lend from the ITO.
First you need to connect the robot to the computer serial port, and to the power supply. Ask a demonstrator to show you how the first time. If you need reminding later, see the Khepera manual at http://www.k-team.com/mobile-robotics-products/old-products/khepera-ii/manuals-downloads. Check that the robot has its dial set to mode 1 (serial communication at 9600 baud).  Also, make sure you know where to find the reset button on the robot, in case you lose communication with the robot while it is still moving (disconnecting the power should also work in an emergency!).

To open serial communication in matlab, use:
>> s = serial('/dev/ttyS0')
>> fopen(s)


You can now send commands to the robot via the defined serial port, e.g.
>> fprintf(s,'D,2,2')


Note there should not be any spaces between the characters! 'D' is for drive and the next two numbers are the speeds for the two wheels. You should see the robot start to move. Try 'D,3,1' to make it move in a curve, or 'D,-5,-5' to make it go backwards, but be very careful about where and how fast the robot is going to go! To make it stop, send 'D,0,0'.

Note that everytime you send the robot a command it replies to confirm, in this case by sending a 'd'. If you do:
>> fscanf(s)

you will see this message.  If you have just sent a series of motor commands, there may be a series of replies waiting to be read from the serial line, so repeat this command until it is clear before trying the next step.

To read from sensors you can do
>> fprintf(s,'N');
>> sensor = fscanf(s)


This returns the value from the 8 IR sensors around the robot in the same format as with the webot command. Try this again with your hands around the robot. You should see that the numbers increase because the sensors are detecting something close. Try again, holding something in front of each of the sensors in turn.

N.B. if you have already downloaded the software from the webots section, your robot_commands directory contains some functions to simplify communication with the robot. You should be able to use:
>> open_robot
>> send_command('D,2,2')
>> read_command
>> close_robot

etc. to communicate with the robot in the same way as you did with webots.

To close the serial connection use:
>> fclose(s)

If you have time, look at some of the other serial commands in the Khepera manual and try them on the robot.


So far this represented the low level communication with robot, the language the robot understands. Together with Webots you will be able to use also the commands the we have introduced in the 2nd practical.


Main IVR Page