|
|  | |
4.1 My first world: mybot.wbt
As a first introduction, we are going to simulate a very simple robot made
up of a cylinder, two wheels and two infra-red sensors (see
figure 4.1). The robot is controlled by a program performing
obstacle avoidance inspired by Braitenberg's algorithm. It moves in a
simple environment which contains some obstacles to
avoid, surrounded by a wall.
 Figure 4.1: The MyBot robot
4.1.1 Setup
Before starting, please check that Webots was installed properly on your
computer (refer to the installation chapter of this manual). Next, you must
set up a working directory that will contain the files your will
create in this tutorial. To do so, create a project directory called
my_webots in your local directory. Then, create
two subdirectories called worlds and
controllers. The first one will contain the simulation
worlds you create, while the second one will contain your programs for
controlling the simulated robots. To start this tutorial,
simply copy the
mybot.wbt world from the Webots
projects / sample / mybot / worlds directory to your
local worlds directory. You will also have to copy the
textures subdirectory which contains the
mybot.png image. Finally, copy the
mybot_simple directory from the
mybot / controllers directory to
your local controllers directory.
4.1.2 Environment
This first simulated world is as simple as possible. It includes a
floor, 4 obstacles and a surrounding wall to prevent the robot from escaping. This wall is
modelled using an Extrusion
node. The coordinates of the wall are shown in
figure 4.2.
 Figure 4.2: The MyBot world
First, launch Webots and stop the current running simulation by pressing
the Stop button. Go to the File
menu, New item to create a new world. This can
also by achieved through the New button, or the
keyboard shortcut indicated in the File menu.
Then open the scene tree window from the
Scene Tree... item in the
Tools menu. This can also be achieved by double-clicking
in the 3D world. Let us start by changing the lighting of the scene:
-
Select the PointLight node, and click
on the + just in front of it. You can now see the different fields of
the PointLight node. Select
ambientIntensity and enter 0.6 as a
value, then select intensity and enter
0.6. Finally, select location and enter
[ 0.75 0.5 0.5 ] as values. Press return.
-
Select the PointLight node, copy and
paste it. Open this new PointLight node
and enter [ -0.5 0.5 0.35 ] in the location
field.
-
Repeat this paste operation twice more with [ 0.45 0.5 -0.5 ] in the
location field of the third
PointLight node, and [ -0.5 0.5 -0.35 ] in the
location field of the fourth and last
PointLight node.
-
The scene is now better lit. Open the
Preferences... dialog from the Tools
menu (Linux and Windows) or from Webots menu (Mac),
select the Rendering tab and check the
Display lights option. Click on the
OK button to leave the preferences and check that
the light sources are now visible in the scene. Try the different mouse
buttons, including the mouse wheel if any, and drag the mouse in the
scene to navigate and observe the locations of the light sources. If you
need further explanation about 3D navigation in the world, go to the
Help menu and select the
How do I navigate in 3D ? item.
Secondly, let us create the wall:
-
Select the last Transform node in
the scene tree window (which is the floor) and click on the
insert after
button.
-
Choose a Solid node.
-
Open this newly created Solid node from the + sign and type "wall"
in its name field.
-
Select the children field and
Insert after a
Shape node.
-
Open this Shape, select its
apperance field and create an
Appearance node from the
New node button. Use the same technique to create
a Material node in the
material field of the
Appearance node. Select the
diffuseColor field of the
Material node and choose a color to
define the color of the wall. Let us make it light brown. In order to
make your object change its color depending on its illumination, select the
specularColor field of the
Material node and choose a color to
define the color of the illuminated wall. Let us use an even lighter
brown to reflect the effect of the light.
-
Similarly, it also is possible to modify the colors of the ground.
To do so you will have to modify the two
color fields of the last
Transform node (the one corresponding to the
ground), which are located in the
children /
Shape /
geometry /
Color node. In our examples we have changed it to a black and white grid.
-
Now create an Extrusion node in the
geometry field of the
Shape.
-
Set the convex field to
FALSE. Then, set the wall corner
coordinates in the crossSection field as
shown in figure 4.2. You will have to re-enter the first
point (0) at the last position (10) to complete the last face of the
extrusion.
-
In the spine field, write that the
wall ranges between 0 and 0.1 along the Y axis (instead of the 0 and 1
default values).
-
As we want to prevent our robot from passing through the walls, we have to define the
boundingObject field of the wall.
Bounding objects cannot use complex geometry objects. They are limited to
box, cylinder, sphere and indexed faceset primitives. Hence, we will have to create four
boxes (representing the four walls) to define the bounding object of the
surrouding wall. Select the
boundingObject field of the wall and
create a Group node that will contain the
four walls. In this Group, insert a
Transform node in the
children field. Add
a Shape to the unique
children of the
Transform. Create a
Material in
the node Appearance and set
its diffuseColor and
specularColor
to white. This will be useful later when the robot will need to
detect obstacles, because sensor detection is based on
color. Now create a
Box as a
geometry for this
Shape node. Set the
size of the
Box to [ 0.01 0.1 1 ], so that it matches
the size of a wall. Set the translation
field of the Transform node to [ 0.495 0.05
0 ], so that it matches the position of the first wall.
-
Now, close this
Transform, and copy and paste it into the
children list. Instead of creating a new
Shape for this object, reuse the
Shape you created for the first bounding
object.
To do so, go back to the Transform node
of the previous object, open the
children node, click on the
Shape node, and you will see on the
right hand side of the window that you can enter a DEF name. Write
WALL_SHAPE as the DEF name and return to the
children of the second bounding object.
First Delete the Shape contained in it
and create a New node inside it. However, in the
Add a node dialog, you will now be able to
use the WALL_SHAPE you just defined. Select this item and click
OK. Set the
translation field of the new node to
[ -0.495 0.05 0 ], so that it matches the opposite wall. Repeat this
operation with the two remaining walls and set their
rotation fields to [ 0 1 0 1.57 ] so that
they match the orientation of the corresponding walls. You also have to
edit their translation fields as well, so
that they match the position of the corresponding walls.
-
Close the tree editor, save your file as "my_mybot.wbt" and look at the
result.
The wall in the tree editor and its result in the world editor are visible in
figure 4.3
 Figure 4.3: The wall in the tree editor and in the world
editor
Now, let us create the obstacles:
-
Select the last Solid node in
the scene tree window (which is the wall) and click on the
insert after
button.
-
Choose a Solid node.
-
Open this newly created Solid node from the + sign and type "green
box" in its name field.
-
Using the same technique as for the wall, add first a
Shape, then an
Appearance and a Material.
For the color, let us make it green with a lighter green for the illuminated parts.
-
Now create a Box node in the
geometry field of the
Shape and set its
size to [ 0.23 0.1 0.1 ]. Set the DEF
name of this geometry to BOX0.
-
To create the boundingObject of this
object, create a Shape node and
reuse the previous DEF for the
geometry. Also, create
an Appearance and a
Material node and set the two colors to white, like we did for the wall.
-
Finally set the
translation field to
[ -0.05 0.05 -0.25 ], but leave its
rotation field at the default value.
-
Now repeat these steps to create the three remaining obstacles. First
create one called "blue box" which has a
geometry (called BOX1) of [ 0.1 0.1
0.1 ], a translation of [ 0.2 0.05 0.27
] and a rotation of [ 0 1 0 0.31 ]. Then
create one called "yellow box" which has a
geometry (called BOX2) of [ 0.05 0.1
0.3 ], a translation of [ -0.2 0.05 0.15
] and a rotation of [ 0 1 0 0.4 ].
Finally
create one called "red box" which has a
geometry (called BOX3) of [ 0.15 0.1
0.08 ], a translation of [ 0.42 0.05
-0.1
] and the default rotation. For all these
objects, set their colors according to their names.
4.1.3 Robot
This subsection describes how to model the MyBot robot
as a DifferentialWheels node containing
several children: a Transform node for the
body, two Solid nodes for the wheels, two
DistanceSensor nodes for the infra-red
sensors and a Shape node with a texture for the "face".
The origin and the axis of the coordinate system of the robot and its
dimensions are shown in figure 4.4.
 Figure 4.4:
Coordinate system and dimensions of the MyBot robot
To model the body of the robot:
-
Open the scene tree window.
-
Select the last Solid node.
-
Insert after a
DifferentialWheels node, set its name to
"mybot".
-
In the children field, first introduce a
Transform node that will contain a shape
with a cylinder. In the new children field,
Insert after a
Shape node. Choose a color, as described
previously. In the geometry field,
insert a Cylinder
node. Set the height field of the
cylinder to 0.08 and the radius one to
0.045. Set the DEF name of the geometry
to BODY, so that we will be able
to reuse it later. Now set the
translation values to [ 0 0.0415 0 ] in
the Transform node (see
figure 4.5)
 Figure 4.5:
Body of the MyBot robot: a cylinder
To model the left wheel of the robot:
-
Select the Transform node corresponding
to the body of the robot and
Insert after a
Solid node which will model the left
wheel. Type "left wheel" in the name
field, so that this Solid node is
recognized as the left wheel of the robot and will rotate according to
the motor command.
-
The axis of rotation of the wheel is x. The wheel
will be made of a Cylinder rotated by
pi/2 radians around the z axis.
To obtain proper movement of the wheel, you must be careful not to
confuse these two rotations. Consequently, you must add a
Transform node to the
children of the
Solid node.
-
After adding this Transform node,
introduce inside it a Shape with a
Cylinder in its
geometry field. Don't forget to set
an appearance as explained previously. The dimensions of the cylinder
should be 0.01 for the height and
0.025 for the radius. Set the
rotation to [ 0 0 1 1.57 ]. Pay
attention to the sign of the rotation; if it is wrong, the wheel will
turn in the wrong direction.
-
In the Solid node, set the translation
to [-0.045 0.025 0] to position the left wheel, and set the rotation of
the wheel around the x axis: [1 0 0 0].
-
Give a DEF name to your
Transform: WHEEL; notice that you
defined the wheel translation at the level of the
Solid node, so that you can reuse the
WHEEL Transform for the right wheel.
To model the right wheel of the robot:
-
Select the left wheel Solid node and
insert after another
Solid node. Type "right wheel" in the
name field. Set the translation to [0.045 0.025 0] and the rotation to
[1 0 0 0].
-
In the children,
Insert after
USE WHEEL.
-
Close the tree window and save the file.
You can examine your robot in the world editor, move it and zoom in on
it.
The robot and its two wheels are shown in figure 4.6.
 Figure 4.6:
Wheels of the MyBot robot
The two infra-red sensors are defined as two cylinders on the front of the
robot body. Their diameter is 0.016 m and their height is 0.004 m. You must
position these sensors properly so that the sensor rays point in the right
direction, toward the front of the robot.
-
In the children of the
DifferentialWheels node,
insert after a
DistanceSensor node.
-
Type the name "ir0". It will be used by the controller program.
-
Attach a cylinder shape to this sensor: In the
children list of the
DistanceSensor node,
Insert after a
Transform node. Give a
DEF name to it: INFRARED, which you will
reuse for the second IR sensor.
-
In the children of the
Transform node,
insert after a
Shape node. Define an appearance and
insert a Cylinder
in the geometry field. Type 0.004 for
the height and 0.008 for the radius.
-
Set the rotation for the Transform node
to [0 0 1 1.57] to adjust the orientation of the cylinder.
-
In the DistanceSensor node, set the
translation to position the sensor and its ray: [-0.02 0.063 -0.042].
In the Preferences dialog, in the Rendering tab,
check the Display sensor rays box. In order to have
the ray directed toward the front of the robot, you must set the
rotation to [0 1 0 2.07].
-
In the DistanceSensor node, you must
enter some distance measurement values for the sensors in the
lookupTable field, according to
figure 4.7. These values are:
lookupTable [ 0 1024 0,
0.05 1024 0,
0.15 0 0 ]
|
 Figure 4.7:
Distance measurements of the MyBot sensors.
-
To model the second IR sensor, select the
DistanceSensor node and
Insert after a new
DistanceSensor node. Type "ir1" as a
name. Set its translation to [0.02 0.063 -0.042] and its rotation to
[0 1 0 1.07]. In the children,
insert after USE
INFRARED. In the
lookupTable field, type the same values
as shown above.
-
In order to better detect the obstacles, we will use two rays per
DistanceSensor. To do so, open
both DistanceSensor nodes and set the
value of the numberOfRay field to 2
and the aperture field of each to
1.
The robot and its two sensors are shown in figure 4.8.
 Figure 4.8:
The DistanceSensor nodes of the MyBot robot
Note:
A texture can only be mapped on an
IndexedFaceSet shape. The
texCoord and
texCoordIndex entries must be filled.
The image used as a texture must be a .png or a
.jpg file, and its size must be
(2n) * (2n) pixels (for example 8x8, 16x16, 32x32,
64x64, 128x128 or 256x256 pixels). Transparent images are allowed in
Webots. Moreover, PNG images should use either the 24 or 32 bit per pixel
mode (lower bpp or gray levels are not
supported). Beware of limits on texture images imposed by your
3D graphics board: some old 3D graphics boards are limited to
256x256 texture images, while more powerful ones will accept 2048x2048
texture images.
To paste a texture on the face of the robot:
-
Select the last DistanceSensor node and
Insert after a
Shape node.
-
Create an Appearance node in the
appearance field. Create an
ImageTexture node in the
texture field of this node,
with the following url: "textures/mybot.png".
This URL path is relative to the worlds
directory.
-
In the geometry field, create an
IndexedFaceSet node, with a
Coordinate node in the
coord field. Type the coordinates of
the points in the point field:
[ 0.015 0.038 -0.041,
0.015 0.023 -0.041,
0 0.023 -0.0455,
-0.015 0.023 -0.041,
-0.015 0.038 -0.041,
0 0.038 -0.0455 ]
|
and Insert after in the
coordIndex field the following values:
0, 1, 2, 5, -1, 5, 2, 3, 4, -1. The -1 value is there to mark the end
of a face. It is useful when defining several faces for the same
IndexedFaceSet node.
-
In the texCoord field, create a
TexureCoordinate node. In the
point field, enter the coordinates of
the texture:
[ 0 0
0.5 0
1 0
1 1
0.5 1
0 1 ]
|
and in the texCoordIndex field, type: 5,
0, 1, 4, -1, 4, 1, 2, 3, -1. This is the standard VRML97 way to explain how the texture
should be mapped to the object.
-
In our example, we have also modified the value of the
creaseAngle of
the IndexedFaceSet. This field
modifies the way the transition of illumination between the different faces of the
IndexedFaceSet is done. In
our example, we have set its value to 0.9 so that the illumination
transition is smooth between the two faces.
-
The texture values are shown in figure 4.9.
 Figure 4.9: Defining the texture of the MyBot robot
To finish with the DifferentialWheels
node, you must fill in a few more fields:
-
In the controller field, select "mybot_simple,"
which should appear in the popup controller list when you press the file
selection button. It is used to determine which controller program
controls the robot.
-
The boundingObject field can contain a
Transform node with a
Cylinder, as a cylinder as bounding object for
collision detection is sufficient to approximately bound this
robot. Create a
Transform node in the
boundingObject field, with the
translation set to [ 0 0.0415 0 ]. Reuse the BODY node
defined previously, and add it to the children of the transform.
-
In the axleLength field, enter the
length of the axle between the two wheels: 0.09 (according to
figure 4.4).
-
In the wheelRadius field, enter the
radius of the wheels: 0.025.
-
Values for other fields and
the finished robot in its world are shown in
figure 4.10.
 Figure 4.10: The other fields of the DifferentialWheels node
The mybot.wbt file is included in the Webots distribution,
in the worlds directory.
4.1.4 A simple controller
This first controller is very simple, and therefore appropriately named
mybot_simple. The controller program simply reads the sensor
values and sets the two motors' speeds in such a way that
MyBot avoids the obstacles.
Below is the source code for the mybot_simple.c controller:
#include <device/robot.h>
#include <device/differential_wheels.h>
#include <device/distance_sensor.h>
#define SPEED 60
#define TIME_STEP 64
static void reset(void);
static int run(int);
static DeviceTag ir0, ir1;
static void reset(void)
{
ir0 = robot_get_device("ir0");
ir1 = robot_get_device("ir1");
distance_sensor_enable(ir0, TIME_STEP);
distance_sensor_enable(ir1, TIME_STEP);
return;
}
static int run(int ms)
{
int left_speed, right_speed;
unsigned short ir0_value, ir1_value;
ir0_value = distance_sensor_get_value(ir0);
ir1_value = distance_sensor_get_value(ir1);
if (ir1_value > 500) {
if (ir0_value > 500) {
left_speed = -SPEED;
right_speed = -SPEED / 2;
} else {
left_speed = -ir1_value / 10;
right_speed = (ir0_value / 10) + 5;
}
} else if (ir0_value > 500) {
left_speed = (ir1_value / 10) + 5;
right_speed = -ir0_value / 10;
} else {
left_speed = SPEED;
right_speed = SPEED;
}
differential_wheels_set_speed(left_speed, right_speed);
return TIME_STEP;
}
int main()
{
robot_live(reset);
robot_run(run);
return 0;
}
|
This controller is found in the mybot_simple subdirectory of the
controllers directory (in the
projects / samples / mybot directory of Webots).

^ page top ^
|