IVR Practical: Robotics 1 (Week 7)


The purpose of this practical is to:
  1. Make you familiar with simulated robots using the Webots robot simulator
  2. Write some simple control programs to move a robot
  3. To unbox and get started with the Lego Mindstorms EV3 kit
You will need Matlab for all tasks on this sheet. If you do not have access to Webots, you can jump immediately to point 3.

1. Webots

This part is on the simulation of a Khepera robot within the robot simulator Webots. The robotics assignment will instead use the EV3 robot, see below in point 3. 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 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.

Download and unzip the files from: http://www.inf.ed.ac.uk/teaching/courses/ivr/practicals/khepera-Webots6.2.tar.gz.

Move it into your preferred directory, and do:

tar xvfz khepera-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 driving is not an option as you should assure that the robot stays safe.

Note that every time 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.

2. 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.

3. Lego Mindstorms EV3 robot

You will either have purchased an EV3 robot kit or you will receive a kit for your team from the demonstrator during your practical group in exchange for a signed notice of receipt for the kit. Kits obtained from the School of Informatics must be returned without any missing parts before the end of March 2016.

The EV3 come with a rechargeable battery. After unboxing, the battery should still be charged. Charging takes a while, so make sure to have this done before you are going to work with the robot. According to the distributor the operation of the robot is not recommended during charging.

There are several ways to control a Lego Mindstorms robot such as by

It is recommended to use Matlab in this course. Here is a video explaining some of the features of the Matlab support for EV3.

In order to use the Matlab package, visit this page and download the EV3 support package. This will give you a file .mlpkginstall that you can then open directly from within Matlab. To carry out the actual installation you will be asked to sign up for a (free) Mathworks account.

Meanwhile you may like to have a look at the list of functions that are available within the package. Note that the (educational) EV3 kit does not contain an IR sensor.

After the installation is completed, go through the tutorials that you can access from the package. The first task described there is to establish the communication with the brick. Use the provided bluetooth dongle when connecting from a DICE machine to the EV3. If you are using a laptop (which is recommended) you may not need the dongle, but you will have to have Matlab installed. Check that both the brick (tools menu item) and the computer (settings) have bluetooth enabled and visible.

For the robotics assignment it will be possible to communicate with the EV3 via a USB cable (in case you have problems using bluetooth), although wireless communication may be more convenient.

Now attach each of the motors (ports A to D) and sensors (ports 1 to 4) to the brick and test them using these Matlab functions. In particular, create a connection to a touch sensor by

mytouchsensor1 = touchSensor(myev3,inputport)

and use its output

pressed = readTouch(mytouchsensor1)

as a condition within a loop that starts or stops a motor. Continue to do similar experiments with the color and sonic sensors.

You may now like to try to built a robot that avoids obstacles when its touch sensors are activated. This can be realised similar to a Braitenberg vehicle (2b) which searches light while here obstacles are to be avoided. For this purpose put the brick on wheels (two wheels, driven by the large motors, one at each side, should work, if you add a castor in the front and/or in the back). Two touch sensors, one for left front and one for right front, could in principle simply activate the motor on the opposite side of the robot, but in dependence on your design of the robot, you may have to first back-up a bit before the robot can turn that close to the obstacle. Alternatively, you can try this task using the sonic sensor or the color sensor.

More information on the control of the EV3 and hints on the second assignment will be given in the next tutorial (in week 8).


Main IVR Page