For the second project we are using the Handyboard controller and Legos
in order to create a system that can push small objects (ie, pieces of
paper) off of a table while simultaneously avoiding obstacles in our
robot's path. This problem is an example of surface coverage, which
has many applications in robotics such as lawnmowing and snowblowing.
We are hoping to implement a working system and, if sufficiently
interested, improve upon our robot for the final project.
Our task is not as difficult as the first project's, as we are already
familiar with the programming language of the Handyboard (Interactive
C), and even have a better developing environment for this project.
Additionally, the Handyboard offers more freedom than the clunky
Rugwarrior did. Our plan was to familiarize ourselves with the
Handyboard, build a Lego chassis to support the Handyboard, and get
used to the sensors and their inputs and outputs. From there, we
wanted to write code that would make our robot move, followed by
full-fledged testing via trial-and-error on a sample environment.
Week 1 Code
The first thing we did was build a chassis to support our Handyboard.
We followed the diagrams for an RCX chassis and scaled it to the
larger Handyboard. We also decided upon a tank design using smaller
wheels, which kept the robot's center of gravity lower, hopefully
giving the robot greater stability. Initially the tank bands caused
the robot to move slightly irregularly, but once we replaced a band it
moved much smoother. We attached a motor to each of the back wheels,
a light sensor to the front of the robot, and a touch sensor dangling
in order to force motion. The touch sensor will be placed on the robot
in the future once we have more details of our environment.
With our bare-bones system in place, we wrote some code to make sure
that the robot would move as we intended. We got it to move at 90
degree angles, and to stop when the light sensor sensed a white piece
of paper. Now that we have confidence in the structure of our robot,
we will test it on a more complete system, allowing us to implement
and test more advanced features such as trash pushing (once we have
pushing capabilities). We will also want to make sure that our robot
can survive in the environment for a considerable length of time
without falling off the edge or being stuck by obstacles. Once we get
to this more serious testing phase we will likely have more interesting
results and pitfalls to report.
Figure 1 -- Table Sweeper v.1.0
Week 2-3 Code
This past week we tried extending our robot, but ultimately scrapped it
and redesigned our "Table Sweeper" from scratch. With our original
robot (Figure 2), we used a non-Lego touch sensor and got it to perform as
desired. Since the sensor was not a Lego, however, we worried about its
stability on a more complete system, figuring that a moderate collision
would knock the sensor out of place. Additionally, as we built up the
robot, it got heavier, pushing its chassis dangerous close to the ground,
which opened up the possibility of it scraping against the table
surface as it moved. Finally, while our tank design looked nice, the
size of the wheels restricted growth of the robot, as it forced us to
stick with a relatively compact design.
Figure 2 -- Table Sweeper 1.5
We thought that rebuilding the Table Sweeper with larger wheels would
fix these last two problems. We began by building a much sturdier
chassis than the original design had. This chassis was
rectangle-shaped, and we chose to attach the wheels so that the robot
would have a wider base for greater stability and potential for
growth. We attached a light sensor in the front, rewrote our code to
handle the new wheel base, and attempted to get the robot to move and
detect white tape, the specified edge of a table.
We found that our code did not work, and it took us a couple hours to
find the problem. Incredibly, when we commented out the line "if
1 < 2" the code would work, but when we put it back in the code
crashed. When we changed that line to "if 1 > 2" the code worked.
This bug made it seem like the less than operator did not work in
Interactive C, but when we tried loading our original robot's code,
which has a less than operator, the code ran, so we still do not know
what exactly the problem was. Nevertheless, with a working code base,
we successfully got our robot to detect the white edge of the table.
By the time we tested our robot on the table in the new graphics lab,
we had also attached our new bump sensor, which was Lego-compatible.
Attaching this component was tricky, since we needed to
expand it so that it would encompass a larger detection area. We used
two sets of "crab-shaped" lego attachments that pointed up, so that
they would detect obstacles but not garbage, and ran a rod between each
set connecting them, so that if the rods were hit they would touch the
sensor. This design, while effective when the rods were hit head-on,
were unstable and caused the bump sensor module to break off after
three or four collisions. We addressed this problem by removing the
outer set of crab-shaped pieces, which gave the robot more stability by
decreasing the torque applied to the detector, which was able to rotate,
and also slightly compacted the center of mass of the Table Sweeper.
After this round of testing, we made a few minor modifications to the
Table Sweeper in order to clean things up. We moved the wheels slightly
closer to the front for greater balance. We put a claw-like lego piece
on each side of the front of the robot in order to catch the crumpled
pieces of paper, and in so doing protect the wheels from getting stuck
on the paper. Finally, we stabilized the bump sensor so that it did not
fall off as often.
Figure 3 -- Table Sweeper 2.0
While our algorithm for the Table Sweeper differs from the Rug Warrior's,
each robot performed similar tasks. The Rug Warrior had to move in a
straight line, head towards the wall for alignment, and handle bumping
into the wall. Similarly, the Table Sweeper also has a purely reactive
control. It has a subsumption-based architecture as described by
Brooks, and its main behaviors are wandering, avoiding obstacles, and
detecting light changes on the table (tape detection). Let us briefly
describe the behaviors of the robot.
By default, the robot begins in wander mode. In this mode it gets a
reading from the light sensor every .2 seconds, and if it detects a
delta of 16, it stops and triggers the tape detection code. Similarly,
if the bump sensor is triggered, the robot reacts with the obstacle
avoidance code. The goal of our wandering algorithm is similar to the
purpose of the RRT. "The key idea is to bias the exploration toward
unexplored portions of the space by sampling points in the state space,
and incrementally 'pulling' the search tree toward them" (RRTs). By
varying the distance our robot backs up when it hits an obstacle, we are
tending to pull the robot into areas of the map that it has not yet
explored. This behavior increases as a function of the number of
obstacles encountered. While this is not nearly as polished and
motivated as the search trees for RRT, the basic idea remains the same.
If the light sensor detects a delta of 16 or greater in the lighter
direction, the edge detection code triggers, causing the robot to
stop, then back up. The delta approach allows us to handle the case
where there is a shadow, which could cause problems if we used a
straight value approach.
If an obstacle is detected (bump sensor triggered), the robot backs up
and turns. The time the robot backs up for scales with the number of
obstacles encountered. The idea behind this is that we are basically
tracing the edge of the environment. Once we have traversed the edge,
we should back up farther on the next traversal in order to gain access
to the interior (or course this doesn't actually happen in the real
world, since there are so many things that make tracing the edge of the
environment imprecise). The turn direction is determined in the
following way: turn the same way as the previous time, but for every
fourth obstacle encountered turn an additional time in the same
direction. For every third obstacle encountered, toggle the state of
the last turn (ie, turn the opposite way next time). This ordering is
to prevent getting stuck in corners. Finally, if we hit more than a
specified number of obstacles, then stop the robot. At this point, we
have hopefully cleared the table. “The filter is very powerful in
several aspects: it supports estimations of past, present, and even
future states, and it can do so even when the precise nature of the
modeled system is unknown” (Kalman). These sorts of estimates could be
of great use to a table-clearing robot. If we were able to estimate
our future state as either hitting an obstacle or reaching the edge,
then the robots behavior could be adjusted accordingly. Specifically,
if we are going to hit an obstacle, then a motorized gripper could any
debris the robot is currently pushing. However, if we were going to
hit the edge, then we would want to release the grips so the debris
would fall off the edge as the robot stops just short of the boundary.
A major limitation of our robot is its inability to test its
assumptions. Given our limited sensory input from the world (A touch
and a light sensor), we are unable test the assumptions our wandering
algorithm has made. Dervish is a robot that used assumption testing
with great success. "Dervish navigates well in spite of incomplete
knowledge about the environment because it maintains a state set that
explicitly captures uncertainty and because it can retract its
assumptions if they are found to be invalid" (Dervish the Office
Navigating Robot). If we were to add side mounted sonar sensors,
then our robot could verify the assumption that it is following a wall.
As it stands now, the robot executes a 90 degree turn and hopes that it
will approximately follow the obstacle.
Most of our other problems came from a challenge we would like to call
"The Joe Malone problem." We spent most of Wednesday night
constructing our robot, and at this point, many of the desirable Lego
pieces had been claimed. We had to make do with what we could find,
but it resulted in a less than optimal design. Additionally, having
only one light sensor and one bump sensor caused some issues. The
robot performed beautifully when approaching an obstacle or a table
edge head on, but when it approached them at an angle the limitations
in our design became apparent. Sometimes the light sensor would not
pick up the tape until it the robot had almost fallen off the table
edge, and sometimes the bump sensor would not register if its
extensions were hit at an angle. Both of these problems could have
been solved by adding an additional sensor of each type to the robot,
allowing us to put one on each front wheel.
A final desire of ours was to obtain a motor for the front of the robot,
so that the robot could push away debris when it encountered the
crumpled paper. Not having this resulted in some lost debris that had
already been collected when the robot was forced to turn. Another
debris helper we would have liked would be some sort of trapper piece
that could keep paper from escaping the grasp of the mighty Table