Faizan All About Arduino Robotics
Faizan All About Arduino Robotics
The Robot
Every robot comes with different capabilities and control concerns.
Let’s get familiar with our simulated robot.
The first thing to note is that, in this guide, our robot will be
an autonomous mobile robot. This means that it will move around in
space freely, and that it will do so under its own control. This is in
contrast to, say, an RC robot (which is not autonomous) or a factory
robot arm (which is not mobile). Our robot must figure out for itself
how to achieve it’s goals and survive in its environment, which proves
to be a surprisingly difficult challenge for a novice robotics
programmer.
Control Inputs - Sensors
There are many different ways a robot may be equipped to monitor its
environment. These can include anything from proximity sensors, light
sensors, bumpers, cameras, and so forth. In addition, robots may
communicate with external sensors that give it information the robot
itself cannot directly observe.
API
In Sobot Rimulator, the separation between the robot “computer” and
the (simulated) physical world is embodied by the
file robot_supervisor_interface.py , which defines the entire API for
interacting with the “real world” as such:
read_proximity_sensors() returns an array of 9 values in the
sensors’ native format
read_wheel_encoders() returns an array of 2 values indicating total
ticks since start
set_wheel_drive_rates( v_l, v_r ) takes two values, in radians-
per-second
The Goal
Robots, like people, need purpose in life. The goal of programming
this robot will be very simple: it will attempt to make its way to a
predetermined goal point. The coordinates of the goal are
programmed into the control software before the robot is activated.
A Simple Model
First, our robot will have a very simple model. It will make many
assumptions about the world. Some of the important ones include:
R = self.robot_wheel_radius
L = self.robot_wheel_base_length
Go-to-Goal Behavior
The supreme purpose in our little robot’s existence in this
programming tutorial is to get to the goal point. So how do we make
the wheels turn to get it there? Let’s start by simplifying our worldview
a little and assume there are no obstacles in the way.
return goal
Note that we are getting the vector to the goal in the robot’s reference
frame, and NOT in the world coordinates. If the goal is on the x-axis in
the robot’s reference frame, that means it is directly in front of the
robot. Thus, the angle of this vector from the x-axis is the difference
between our heading and the heading we want to be on. In other
words, it is the error between our current state and what we want our
current state to be. We therefore want to adjust our turning rate ω
so that the angle between our heading and the goal will change
towards 0. We want to minimize the error.
# calculate the error terms
theta_d = atan2( self.gtg_heading_vector[1],
self.gtg_heading_vector[0] )
To simplify the question, let’s now forget the goal point completely and
just make the following our objective:When there are no obstacles in
front of us, move forward. When an obstacle is encountered, turn
away from it until it is no longer in front of us.
Accordingly, when there is no obstacle in front of us, we want our
reference vector to simply point forward. Then ω will be zero
and v will be maximum speed. However, as soon as we detect an
obstacle with our proximity sensors, we want the reference vector to
point in whatever direction is away from the obstacle. This will
cause ω to shoot up to turn us away from the obstacle, and
cause v to drop to make sure we don’t accidentally run into the
obstacle in the process.
A neat way to generate our desired reference vector is by turning our
nine proximity readings into vectors, and taking a weighted sum.
When there are no obstacles detected, the vectors will sum
symmetrically, resulting in a reference vector that points straight
ahead as desired. But if a sensor on, say, the right side picks up an
obstacle, it will contribute a smaller vector to the sum, and the result
will be a reference vector that is shifted towards the left.
...
The solution we will use lies in a class of machines that has the
supremely cool-sounding designation of hybrid automata. A hybrid
automaton is programmed with several different behaviors, or modes,
as well as a supervising state machine that switches between these
behaviors depending on conditions.
Equipped with our two handy behaviors, a simple logic suggests
itself: When there is no obstacle detected, use the Go-to-Goal
behavior. When an obstacle is detected, switch to Avoid-Obstacles
behavior until the obstacle is no longer detected.
As it turns out, however, this logic will produce a lot of problems. What
this system will tend to do when it encounters an obstacle is to turn
away from it, then as soon as it has moved away from it, turn right
back around and run into it again. The result is an endless loop of
rapid switching that renders the robot useless. In the worst case, the
robot may switch between behaviors with every iteration of the control
loop - a state known as a Zeno condition.
What we need, therefore, is one more behavior, which is specialized
with the task of getting around an obstacle and reaching the other
side.
With our limited information, we can’t say for certain whether it will be
faster to go around the obstacle to the left or to the right. To make up
our minds, we select the direction that will move us closer to the goal
immediately. To figure out which way that is, we need to know the
reference vectors of the Go-to-Goal behavior, the Avoid-Obstacle
behavior, as well as both of the possible Follow-Wall reference
vectors. Here is an illustration of how the final decision is made (in this
case, the robot will choose to go left):
Determining the Follow-Wall reference vectors turns out to be a bit
more involved than either the Avoid-Obstacle or Go-to-Goal reference
vectors. Take a look at follow_wall_controller.py to see how it’s
done.
Conclusion
Robots are already doing so much for us, and they are only going to
be doing more in the future. While robotics programming is a tough
field of study requiring great patience, it is also a fascinating and
immensely rewarding one. I hope you will consider getting involved in
the shaping of things to come!
Acknowledgement: I would like to thank Dr. Magnus
Egerstedt and Jean-Pierre de la Croix of the Georgia Institute of
Technology for teaching me all this stuff, and for their enthusiasm for
my work on Sobot Rimulator