IVR Practical Two: Introduction to Robotics 1 (Week 7)
The purpose of this practical is to:
- Make you familiar with using scripts and functions in matlab
- Write some simple control programs to move a robot in a specified
path
- If there is time, try using sensing from the robot to control its
movements
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