Team 36: Murphy's Plow of Doom

made by Matt Alaniz, Alan Asbeck, and Neil Sanchala

Physical description of our robot

Our robot was almost a foot across, a foot from front to back, and about 8 inches high.  It used a differential drive steering mechanism to move effectively.  Two small tires were driven independently by two motors apiece, and there was a freely-rotating wheel in the back, whose angle was controlled by a servo.  This method of steering worked pretty well.  We used the differential drive to make large turns while pivoting about the center of the robot, and then servo for steering while we were driving straight.  By turning the servo up to 20 or 30 degrees while both driving motors were on full power, we could make gradual turns quite accurately. The gear ratio for the driving wheels was 45:1.  This made it move at a pretty good clip, while still having lots of power.

To lift the balls over the wall, we made use of the large tires, as can be seen on the front of the robot.  These cleared the table by about half an inch, and were rotating to push objects away from the robot (the bottom was going forward, the top back towards the robot).  These were driven by one motor on each side, with a 75:1 gear ratio.  This made the linear speed of the wheels' edges about the same as the driving forward speed of our robot.  This was convenient, because then when we were pushing balls along like a plow, they would not get pushed too far ahead of the robot, but wouldn't get clogged under the wheels.  Once a ball was pushed against the wall, the side against the wall stopped moving, while the large wheels forced the side close to our robot to move upwards.  This caused the ball to effectively roll up and over the wall.  While the ball or balls were being pushed up the wall, the robot would slow down a little, and there would be a lot of strain on the motors, but it always overcame these difficulties and continued pushing until it was flush against the wall, and the ball went over.

The arms on our robot were made out of base plate melted with a heat gun and shaped using my hands and pliers when it was too hot.  The arms were designed to (1) funnel balls into the center of our robot, so they didn't get stuck underneath the arms (which happened a lot in an old version of the robot), (2) prevent the balls from getting away if they were too far in front of the robot, (3) maximize the effective ball-gathering width of the plow, and (4) to push up automatically when we approached a wall head on, and when we were turning and the arm would brush against the wall.  To achieve these requirements, I made the arms angled up at a steep angle in front, and angled out horizontally slightly from the center.  Their pivots were low on the robot.

The big sweeping arm (referred to as "arm" in the singular, as opposed to the plural "arms" on the front of the robot) was made out of a lazy tongs.  We used this design so that we could retract the arm when we weren't using it.  The arm extended most of the way across the raised platform in the center of the table when our robot was next to the wall, so that it could reach any balls on top.  The arm was extended by a servo that was connected to one side of the lazy tongs.  The other side of the lazy tongs was held fast to the body of the robot, so that the servo rotating would extend and retract the arm.

Our Sensors

To know when it was at the wall, there were two bump sensors almost underneath the arms in the front of the robot.  These would only go off if the robot was flush against the wall.  As for our other sensors, we had two shaft encoders on the driving wheels.  These were useful in making hard-coded turns, when there was no good alternative, or when that was fastest; they were also theoretically useful in detecting when our robot was stalled, although in reality the wheels kept moving most of the time even when our robot was stuck, and so they did not work for that.

For line-following, we used 6 light sensors, which were pairs of a LED and phototransistor.  Three light sensors were located on the front of the robot, just behind and under the plow wheels.  Two more were located on the back, between the servo wheel and the main chassis.  One more was located in the center of the robot, along the line which connects the axles of the two differential drive wheels.  In this way, that sensor was almost exactly on top of our pivot point whenever we did a turn using the differential drive.  This was quite useful in line-following (see the code section).  Our last sensor was the start-light sensor, also located on the bottom of our robot.
 

Our strategy

There were many possible strategies by which to score points in this year’s competition.  Robots could score many points by attacking either the middle of the arena, or the opponent’s side.  In order to attack these different areas of the board, three types of robot designs were used by the competitors: ramps, bulldozers, and ball launchers.

Perhaps the most consistent and simple of the three strategies, ramp robots took advantage of the center, elevated area of the arena.  The ramp strategy consisted of sending a ramp-like structure via arm or mini-robot to a position below the ball dropper in order to direct falling balls to its side of the table.  This strategy was the easiest to implement since it involved little to no driving.  This simplicity made for a somewhat boring robot to construct and to watch.  Bulldozer type robots would push balls from the opponent’s side of the table to their side.  While these robots were easy to build their coding was often filled with error handling procedures.  Bulldozers were entertaining to watch, but did not seem extremely fun to build.  Ball shooters seemed to be the most interesting and fun types of robots to build and watch.  It is for this reason that we chose to build this type of robot.  Ball shooters would propel opponent’s balls to their side of the table or out of the arena.

One of the interesting properties of the arena was that each side of the table had a dip at its midpoint.  A line of paint different than the surrounding color ran along this dip.  Since this dip was the lowest point of each side of the table, the balls would collect along it.  We decided to use this characteristic of the arena to our advantage.  Our strategy would be to push the opponent’s balls out of the arena.  We chose this strategy for two reasons.  First, our ball lifting mechanism functioned extremely well.  Second, because the opponent’s balls would be collected along the “dip” line, our robot could use line following and sentry the line, pushing off any of the opponent’s points.  We believed that if our robot never had to leave the line, it would never become disoriented.

Our preliminary strategy had our robot sentry the opponent’s line for the entire match.  This strategy had many advantages over the ramp and ball launcher designs.  Any points that the ramp and ball launcher robots scored would be immediately pushed off of the table by our robot.  Thus, the worst-case scenario would be a 0-0 double win.  The problem preliminary strategy was with bulldozers.  If any bulldozer designs protected their balls (i.e. box designs), our robot could lift them off the table.  To solve this problem we attached an extendable arm onto the side of our robot.  With the arm extended our robot could rotate in place at our starting position and hit the center ball onto our side.  Our new strategy would have our robot return to its starting position at 20 and 40 seconds, and use its arm to hit the center ball onto our side.  Although this strategy would cause our robot to leave the line it was following, these extra points could give us a win against most bulldozer designs.  To complete our strategy we added timeout procedures so that our robot would not become stuck up against walls or other robots.

Our robot fared well in the competition.  We qualified for round 5 (placed in the top 16).  Our first loss occured because of errors in LED calibration which prevented our robot from starting.  However, after fixing this problem our robot was nearly unstoppable.  During the competition we beat the eventual second place team and were finally eliminated by the first place team.  Our elimination was a result of the one weakness of our strategy, ramming countermeasure.  Our robot had no way to defend itself against an actively seeking ramming robot.  The first place robot scored its points early and attacked us before we could push enough of their points off the table.  We were well aware of this weakness, but did not have enough time to deal with it.
 

Main Aspects of our Code

Our code

Wall Following
Line Following
Re-acquiring the Line
Timeouts

Wall Following

We had the simplest wall following code possible. Turn the servo slightly towards the wall, and drive straight. Thanks to physical feedback and small wheels along the side of our robot, this worked fantastically.

Line Following

The vast majority of our efforts involving code for our robot had to do with line following, and I'm pleased to say that our work did pay off in this area. We used a total of 6 light sensors for line following, in the following arrangement:
                 *  *  *        
                    *
                   * *
The spacing of the sensors was such that our ideal case occurred when the front middle sensor and both of the back sensors were on at the same time (we basically ignored the middle sensor for line following; that comes in later). If we ever hit this case, we sped up and drove straight until we hit a less ideal case. For these less ideal cases, our response was mostly just setting our rear servo at a slight angle so that we veered back toward the line, or at least where we expected it would be. If we were off the line entirely for an extended period of time, (about a second or two), we took drastic measures, which are described in the next section. 

Re-acquiring the Line

The key to re-acquiring the line was adding the sensor in the very middle of the above arrangement. We placed that sensor as close as we possibly could to the midpoint between our two front wheels, so that we would pivot about that sensor when we were turning. This was so helpful in acquiring the line because, once we got the middle sensor onto the line, it was just a matter of turning in the right direction until we hit some other sensors, and then we were lined up almost perfectly on the line. Actually getting the middle sensor onto the line was done by moving and backward and forward until it hit, or if it didn't, turning a little bit and trying again. This was quite good for finding the line, although it was sometimes much more time-consuming than it needed to be.

Timeouts

We were very liberal with timeouts all over our code, and it turned out that we were just liberal enough. Timeouts are a useful tool for making sure a task completes before a certain amount of time passes, and thus can stop the robot from going forever in the wrong direction. Our error recovery code wasn't fantastic, but just getting out of otherwise infinite loops saved us many a time. To anyone who plans on taking this class in the future, remember that timeouts are your friend, and you can never have too many friends.

Matt Alaniz, Alan Asbeck, Neil Sanchala

Main 6.270 Page