- 1 Introduction
- 2 Software
- 3 Programming interface
Aseba is a set of tools which allow novices to program robots easily and efficiently, refer to https://www.thymio.org/en:start for more information.
The following steps neeed to be done only once:
- The communication between Aseba and Elisa-3 is done through the USB (serial communication is used) cable so you need to install the driver, refer to section Elisa-3 requirements; in the future we will maybe add RF support too
- Download and install Aseba https://www.thymio.org/en:wininstall; be sure to get version 1.5.5 by looking in the version history
- Download the Elisa-3 target for Aseba elisa3-aseba.hex and upload it to the robot (refer to section Elisa-3 Programming)
Connection with AsebaStudio
The following steps explain how to start playing with the Aseba Studio:
- Connect the robot to the computer if not already done and turn it on
- Download the following script based on your platform and modify its content specifying the AsebaStudio installation folder and the robot port:
- Windows: asebaswitch_elisa3.bat; spcifiy the installation folder (e.g.
C:\Program Files (x86)\AsebaStudio) and the port number (e.g.
- Linux: asebaswitch_elisa3.sh; specifiy the installation folder (e.g.
/usr/bin) and the port (e.g.
- Mac OS [asebaswitch_elisa3] to be placed in
- Windows: asebaswitch_elisa3.bat; spcifiy the installation folder (e.g.
- Start the asebaswitch tool by issueing the command:
asebaswitch -d -v "ser:port=104;baud=57600;stop=1;parity=none;fc=none;bits=8"
you need only to specify the correct
portnumber (COMx). The robot will blink if the connection is correctly opened.
For more information about the parameters refer to https://github.com/aseba-community/dashel/tree/master/docs.
You can find asebaswitch in the AsebaStudio installation folder (e.g.
C:\Program Files (x86)\AsebaStudio).
- Start AsebaStudio and select
Portto open the connection with the robot
- If the connection is correctly established you should see the Elisa-3 variables on the left side of AsebaStudio as shown in the following figure:
Have a look also at the following video:
Once the connection is opened click on the checkbox auto to start updating the sensors data automatically; we can now interact with the robot, for instance on the left side we can see all the sensors values (proximity, ground, accelerometer, ...) and we can change the motor speed and turn on/off all the leds.
First of all hava a look at some of the examples proposed in the following section AsebaStudio examples.
Then when you're ready you can start programming the robot on your own, refer to section Programming interface; moreover you can have a look at https://www.thymio.org/en:start for more information.
Pay attention that you have 100 bytes availables for your script due to memory constraints.
If you want to have a look behind the scene refer to section Contribute to the Elisa-3 Aseba target.
You can download all the following examples from aseba-elisa3-examples.zip; in order to launch an example follow these steps:
- place the robot selector in position 5. When the robot is turned on, the position of the selector (from 0 to 9) define the node name in AsebaStudio, in our case the node name will be
elisa3-5(where 5 is the selector position)
- extract the zip, the directory contains some file with aesl extension, this is the AsebaStudio code extension
- connect the robot with AsebaStudio as explained previously
- click on menu
File => Open...and select one of the examples extracted from the zip
- click on button
Loadand then on
Run; now the code is running on the robot but it isn't stored in EEPROM, thus when you turn off the robot it returns to its initial state
If you want to save the program in memory you need to click on
Tools => Write the program(s)... => inside the elisa3 and wait for the programming termination (the green leds around the robot will be turned on while the memory is written); pay attention to uncheck the auto update of the robot variables in AsebaStudio before starting the writing (with the auto update enabled the writing could block).
Simple obstacle avoidance
var i = 1 while (i==1) do if ((prox > 50) or (prox > 50) or (prox > 50)) then mot.left.target = -20 mot.right.target = 20 else mot.left.target = 20 mot.right.target = 20 end end
To fully see the results of this example you need to write the code into the robot. Then let it move with some objects around.
onevent ir.sensors if (prox > 20) then # avoid noise led.rgb = prox else led.rgb = 0 end if (prox > 20) then # avoid noise led.rgb = prox else led.rgb = 0 end if (prox > 20) then # avoid noise led.rgb = prox else led.rgb = 0 end
Once the code is loaded on the robot you can "control" the intensity of the red, green and blue with the prox, prox and prox respectively. Try to get the primary and secondary colors (https://en.wikipedia.org/wiki/Primary_color)...hint: you need two fingers.
Working with events
var color = 0 onevent ir.sensors led.green = 1 - led.green led.green = 1 - led.green led.green = 1 - led.green led.green = 1 - led.green onevent acc led.green = 1 - led.green led.green = 1 - led.green led.green = 1 - led.green led.green = 1 - led.green onevent timer led.rgb[color] = 255 - led.rgb[color] onevent button if (color == 2) then color = 0 else color++ end led.rgb = 0 led.rgb = 0 led.rgb = 0
The green leds shows the update frequency of the proximity and accelerometer sensors (you can measure it with an oscilloscope if you have one). You can change the value of the variable
timer.period to change the frequency of the RGB LED, the resolution is 1 ms (e.g. by putting 1000 you'll get the RGB LED blinking at 1 Hz). Moreover you can try pressing the button and see what happen (probably you will deduce from the code...).
onevent rc5 if rc5 == 2 then # forward mot.left.target = 20 mot.right.target = 20 elseif rc5 == 5 then # stop mot.left.target = 0 mot.right.target = 0 elseif rc5 == 8 then # backward mot.left.target = -20 mot.right.target = -20 elseif rc5 == 4 then # left mot.left.target = 0 mot.right.target = 20 elseif rc5 == 6 then # right mot.left.target = 20 mot.right.target = 0 else # error led.rgb = 255 end
To fully see the results of this example you need to write the code into the robot. Maybe you should adapt the values used for the various motions and then you can for sure extend the functionalities using others codes (e.g. change RGB LED color).
Simple local communication
In this example we need to connect two robots at the same time to AsebaStudio, to accomplish this asebaswitch need to be called with a different command that is:
asebaswitch -d -v "ser:port=104;baud=57600;stop=1;parity=none;fc=none;bits=8" "ser:port=69;baud=57600;stop=1;parity=none;fc=none;bits=8"
Basically there are two targets instead of one; you need to specify the correct
port number for both the robots. Moreover you need to place the robot receiver selector in position 5 and the robot transmitter selector to another position (from 0 to 9). Both the robots will blink if the connection is correctly opened.
Load the following code to the receiver robot:
call prox.comm.enable(1) onevent prox.comm led.green = 0 led.green = 0 led.green = 0 led.green = 0 led.green = 0 led.green = 0 led.green = 0 led.green = 0 led.green[prox.comm.rx.id] = 1 if (prox.comm.rx == 1) then led.rgb = 255 led.rgb = 0 led.rgb = 0 elseif (prox.comm.rx == 2) then led.rgb = 0 led.rgb = 255 led.rgb = 0 elseif (prox.comm.rx == 3) then led.rgb = 0 led.rgb = 0 led.rgb = 255 end
Load the following line code to the transmitter robot:
Now you can change the
prox.comm.tx values (from 1 to 3) on the transmitter tab and see the effect on the receiver robot; also
prox.comm.rx.id on the receiver tab will change accordingly. You can easily transform the id to an angle by knowing that each sensor is placed at 45 degrees from each other. Remember to place the robots near each other (< 5 cm).
In this example we exploit the onboard odometry to let the robot move in a square path. You have two possibilities: either running on a vertical wall or running on an horizontal plane, both cases are handled automatically. When the Elisa-3 is turned on, it calibrates the sensors (when is placed vertically it rotates around itself for a while with the green led turned on); when the calibration process is finished you can start the square by "touching" the back side proximity. Pay attention that the robot must be placed with the front pointing right when placed vertically.
var DISTANCE = 100 # given in mm var start = 0 var state = 0 var isVertical
sub updateState if start == 1 then if (state == 0) then mot.left.target = 20 mot.right.target = 20 led.rgb = 255 led.rgb = 0 led.rgb = 0 if (odom.x >= DISTANCE) then state = 1 end elseif (state == 1) then mot.left.target = 0 mot.right.target = 15 led.rgb = 0 led.rgb = 255 led.rgb = 0 if (odom.theta >= 90) then state = 2 end elseif (state == 2) then mot.left.target = 20 mot.right.target = 20 led.rgb = 0 led.rgb = 0 led.rgb = 255 if (odom.y >= DISTANCE) then state = 3 end elseif (state == 3) then mot.left.target = 0 mot.right.target = 20 led.rgb = 255 led.rgb = 255 led.rgb = 0 call robot.isVertical(isVertical) if (isVertical == 1) then if (odom.theta < 0) then state = 4 end else if (odom.theta >= 180) then state = 4 end end elseif (state == 4) then mot.left.target = 20 mot.right.target = 20 led.rgb = 255 led.rgb = 0 led.rgb = 255 if (odom.x <= 0) then state = 5 end elseif (state == 5) then mot.left.target = 0 mot.right.target = 20 led.rgb = 0 led.rgb = 255 led.rgb = 255 call robot.isVertical(isVertical) if (isVertical == 1) then if ((odom.theta >= -90) and (odom.theta < 0) ) then state = 6 end else if (odom.theta >= 270) then state = 6 end end elseif (state == 6) then mot.left.target = 20 mot.right.target = 20 led.rgb = 0 led.rgb = 0 led.rgb = 0 if (odom.y <= 0) then state = 7 end elseif (state == 7) then mot.left.target = 0 mot.right.target = 20 led.rgb = 0 led.rgb = 0 led.rgb = 0 call robot.isVertical(isVertical) if (isVertical == 1) then if (odom.theta >= 0) then state = 8 end else if (odom.theta >= 360) then state = 8 end end elseif (state == 8) then mot.left.target = 0 mot.right.target = 0 start = 0 end end onevent ir.sensors if (start == 0) then if (prox > 200) then call reset.odometry() state = 0 start = 1 end end callsub updateState
Contribute to the Elisa-3 Aseba target
You can get the source code of the Elisa-3 Aseba target from github.
The repo contains all Arduino targets, the Elisa-3 target is placed in the directory elisa3. To build the project follow these steps:
- clone the repo by issueing the command:
git clone --recursive https://github.com/gctronic/aseba-targets-arduino.git
- download Atmel Studio 7 since this IDE was used to create the project; the installation of Atmel Studio includes also the toolchain so you should be able to build the project without any modification
- to open the project double click
The project depends also on the Elisa-3 library contained in the Elisa-3 advanced firmware revision 221.
This page describes the programming capabilities of Elisa-3. It lists the different variables, events and functions and indicates to which elements of the robot they refer (see section Hardware to know where is the actual position on the robot of the sensors and actuators). Each variable is marked with either [R] or [W] to indicate whether the variable is used to read a value from the robot or write a value to the robot respectively. This page refers to firmware revision 0 and later.
You can find a document that summarizes the programming interface in the following link elisa3-aseba-cheatsheet.png.
The Elisa-3 comes with the Aseba standard library of native functions, documented on its own page.
You can change the wheel speeds by writing in these variables:
motor.left.target[W]: requested speed for left wheel
motor.right.target[W]: requested speed for right wheel
You can read the real wheel speeds from these variables:
motor.left.speed[R]: real speed of left wheel
motor.right.speed[R]: real speed of right wheel
The values range from -127 to 127, one unit = 5 mm/s. A value of 127 approximately corresponds to a linear speed of 60 cm/s.
8 green LEDs make up a circle on the bottom of the robot.
led.green[0..7] [W]: index 0 sets the intensity of the LED at the front of the robot, the others are numbered clockwise.
There is one RGB LED in the center of the robot, its light is smoothly spread out through the top diffuser.
led.rgb[0..2] [W]: the indexes 0, 1 and 2 set respectively the intensity of the red, green and blue.
The values range from 0 (off) to 255 (max intensity).
There are 3 IR transmitters pointing upwards, two placed in the front side of the robot and one placed in the back side. You can control their state by writing these variables:
ir.tx.front[W]: 0 means that both front IRs are turned off, 1 means that both front IRs are turned on
ir.tx.back[W]: 0 means that the back IR is turned off, 1 means that the back IR is turned off
There is a small button in the back side of the Elisa-3. The variable
button [R] holds the state of this button (1 = released, 0 = pressed).
Elisa-3 generates the
button event when it is pressed or released.
Elisa-3 has 8 proximity sensors around its periphery (placed at 45 degrees from each other). Two arrays of 8 variables hold the values of these sensors, the first is
prox [R] and represents the proximity to an object, the second is
prox.ambient [R] and represents the ambient light intensity:
prox.ambient: front right
prox.ambient: back right
prox.ambient: back left
prox.ambient: front left
The values in the
prox array vary from 0 (the robot does not see anything) to 255 (the robot is very close to an obstacle); the values of the
prox.ambient array start from 1023 when completely dark and decrease with light increase. Elisa-3 updates these arrays at a frequency of about 80 Hz (when local communication is disabled), and generates the
ir.sensors event after every update.
Elisa-3 holds 4 ground proximity sensors. These sensors are located at the front of the robot. As black grounds appear like no ground at all (black absorbs the infrared light), these sensors can be used to follow a line on the ground and also to avoid falling from the table. Two arrays of 4 variables hold the values of these sensors, the first is
ground [R] and represents the proximity to the ground or the presence of a black line, the second is
ground.ambient [R] and represents the ambient light intensity at the ground:
ground.ambient: front left
ground.ambient: front right
The values in the
ground array normally vary from about 600 (white surface) to about 300 (black surface or no ground); the values of the
prox.ambient array start from 1023 when completely dark and decrease with light increase. Elisa-3 updates these arrays at a frequency of about 80 Hz (when local communication is disabled), and generates the same
ir.sensors event after every update.
Elisa-3 contains a 3-axes accelerometer. An array of 3 variables,
acc [R], holds the values of the acceleration along these 3 axes:
acc: x-axis (from back to front, positive forward)
acc: y-axis (from left to right, positive towards right)
acc: z-axis (from bottom to top, positive upward)
The values in this array vary from -128 to 128, with 1 g (the acceleration of the earth's gravity) corresponding to the value 64. Elisa-3 generates the
acc event after every update.
The z-axis is used also to know the current orientation of the robot, that is if it is moving vertically or horizontally; the current orientation can be accessed using the function
dest will be 1 if it is vertical or 0 if it is horizontal.
selector [R] shows the current position of the selector (from 0 to 15). Elisa-3 generates the
sel event everytime its position is changed.
Elisa-3 contains a receiver for infrared remote controls compatible with the RC5 protocol. When Elisa-3 receives an RC5 code, it generates the
rc5 event. In this case, the variables
rc5 [R] is updated.
bat.percent [R] give you an estimate of the current battery charge given in percentage (100% means you have still a lot of playful time, 0% means you need to wait a little and put the robot in charge). The sampled value can be accessed with the variable
_bat.adc [R] (this is an hidden variable); the values range from 0 to 1023.
Elisa-3 can use its infrared proximity sensors to communicate with other robots within a range of about 5 cm. For more detailed information refer to section Local communication.
To use the communication, call the
prox.comm.enable(state) function, with 1 in state to enable communication or 0 to turn it off. If the communication is enabled, the value in the
prox.comm.tx [W] variable is transmitted to others robots from all the sensors. When Elisa-3 receives a value, the event
prox.comm is fired and the value is in the
prox.comm.rx [R] variable; moreover the
prox.comm.rx.id [R] variable contains the id of the sensors (from 0 to 7, where 0 is the front sensor, sensors id increases clockwise) that received the data.
Elisa-3 is capable of estimating how much distance has traveled each wheel resulting in a robot position given in cartesian coordinates (x, y); when moving horizontally the orientation is estimated through the distance traveled by each wheel, instead when moving vertically (what?? vertically?? yes Elisa-3 can move vertically thanks to its magnetic wheels) the orientation is given directly by the accelerometer and it's very precise.
odom.theta [R] contains the current orientation of the robot given in degrees: when moving horizontally the orientation continuously decreases when moving clockwise and continuously increases when moving counter-clockwise; when moving vertically the orientation is from -180 to 180 degrees. The variables
odom.x [R] and
odom.y [R] contain the current position of the robot given in millimeters.
By calling the function
reset.odometry all the data are reset to zero.
Elisa-3 provides a user-defined timer. The variable
timer.period [W] allows to specify the period of the timer in milliseconds. The timer starts the countdown when it is initialized (value > 0). When the period expires, the timer generates a
timer event. This events is managed in the same way as all the others and cannot interrupt an already executing event handler. The maximum value is 32767 ms (about 32 seconds).
Elisa-3 include two onboard behaviors that can be activated or deactivated at will that are obstacle avoidance and cliff detection. To use obstacle avoidance, call the
behavior.oa.enable(state) function, with 1 in state to enable obstacle avoidance or 0 to disable it; when activated the motors speed will be adapted in order to avoid obstacles. To use cliff detection, call the
behavior.cliff.enable(state) function, with 1 in state to enable cliff detection or 0 to disable it; when activated the Elisa-3 will stop as soon as it detect a cliff (pay attention that the robot can detect the void only when going forward).