CS 154 - Lab Projects

Marissa Anderson . Matt Livianu . Daniel Lowd . Eric Wu

Project 2: WallBot


Following up on our first project, FlameBot, we are adding a sonar sensor to the Handyboard and attempting to implement a right-wall-following algorithm. The goal of our project is to construct an autonomous robot out of Legos which can wall-follow using motors, sonar, and IR sensors connected to a Handyboard controller.


We have drafted an initial design outline.


The chassis for WallBot is significantly different than FlameBot. Since one of the major problems with FlameBot was a significant lack of accuracy in fine steering control, we have attempted to improve on our design. WallBot has one motor powering the two rear wheels, which are connected via a differential shell in an attempt to reduce slippage during turns. The front two wheels are controlled with a standard motor turning a rack and pinion assembly.

In retrospect, the differential shell for the rear wheels may have been unnecessary. The current design of the rack and pinion steering on the front wheels restricts turning to fairly wide arcs. We had hoped to have an extra position-controlled servo motor to accurately control steering, but we have a reasonable alternative using the standard motor to steer and a bump sensor which theoretically would be able to tell us if the front axle was currently pointed straight forward. In practice, this didn't work very accurately, so we have incorporated a rotation sensor instead, which in conjunction with the motor and some experimentation, simulates a position-controlled servo reasonably well.

We ran into a problem with the weight of the chassis bending the axles of the rear wheels, causing them to turn very slowly, held back by friction. The initial support structure for the rear wheels did not hold them in place very well and while it reduced the friction considerably, there were too many movable parts to eliminate friction (see first HallBot pictures below). The current design is much more stable and does not allow the axles to bend in the slightest. Woohoo!


The control program is broken up into two processes, since each process needs to sleep occasionally and run continuously the rest of the time. The moveServo() function continuously sweeps the sonar, takes readings, and sets global variables describing the current state of the world. The wallFollow() function then reads those variables and attempts to stay within a certain predefined distance from the walls. The code is available here.


The sonar sensor is mounted on a servo motor which allows it to move from side to side. The sonar sweeps through 5 regions of 30 degrees each, from straight ahead to 60 degrees backwards and right. In each region, it records the average distance for that region in an array. Originally we also attempted to use the minimum values for each region instead of the average. We found that a single erroneously low reading would then confuse WallBot for an entire cycle of the sonar, or at least several seconds. But by taking the minimum of the averages instead, WallBot can more accurately determine its current orientation with respect to the wall. WallBot used a PD control to manage its distance from the wall. The proportional term is based on the difference between the current distance from the wall and the desired distance and the derivative term is the difference between the previous average reading in a region and the current reading. We had some trouble calibrating the PD control gain variables. The total PD error is erratic because we only have one interfaced sonar to work with and the sonar turns rather slowly as compared to the movement of the robot. The PD control only affects side range errors and the front range is maintained separately.

We discovered that the long hallways of the Libra Complex resulted in erroneous sonar values from far walls. Essentially, the sonar detected echos from previous blips while in the same scanning region and this produced very close readings. We hacked a solution by changing "extremely close" sonar readings to very far sonar readings, essentially imitating what the sonar should have outputted in the first place.


The wallFollow() function simply reads the global variables set by moveServo and attempts to steer in the correct direction. Most of the logic is actually kept in the other function; however, since turning the wheels and correcting for overshoot from the motor takes time, the actual steering needs to be done in a separate process. We had many problems with the robot turning left, away from the wall, and moving away before the sonar could read the distance to the right wall and apply a correction. The solution was to slow the robot down and attempt to speed up the computation of sonar error values in order to speed up rotation of the servo motor.

For the rack-and-pinion steering, we ran into friciton problems. The system was designed so that the bump sensor would be depressed when the wheels pointed the robot straight. The piece which depressed the bump sensor was sandwiched between two pieces (ideally frictionless, but amazingly enough, frictionless LEGOs do not exist). We redesigned the steering system such that the actuator for the bump sensor was suspended rather than sandwiched, and steering accuracy improved tremendously.

Steering essentially works by turning towards the wall when the error value is too high and away from the wall when the error value is too low. The rotation sensor notifies the robot that it has reached a certain turning angle. When the wheels reach this angle, they then return to the center position. The wheels are programmed to always return to center because otherwise, the robot turns too much before the sonar has a chance to read the first regaions again and so the robot runs into the wall it is following instead of simply getting closer to it.

Other Time Consuming Issues

Things to avoid next time:

  • Wondering why the sonar does not function correctly before noticing the broken ground wire
  • Wondering why the digital bump sensor always reads one before noticing that the wires are touching
  • Pretending that we can solder by simply melting the solder with the iron and not actually heating the wires up. Why? Because it was faster.
  • HallBot with the sonar mounted to the front.