Group 6
CMPS 479 Final Design Write-up
by Andrew Reitz (ajr9@po.cwru.edu)
December 16, 1996
Mechanical structure
At the start of this assignment, we were asked to meet with our other group, group 5, and plan out some form of team strategy. Well, Steve had been kicking around the idea of a small, speedy robot that was capable of picking up just one egg, no matter what the color, and delivering it to the appropriate nest. The six of us discussed this idea together, and it seamed very feasible. It had the intrinsic benefit that our robots wouldn’t have to waste much time finding a specific egg – the first thing that it found it could use. Also, with this design we didn’t have to be concerned with blockers and other radical strategies – if one nest was blocked, our robot could simply perform all of its scoring with the other nest. Another possible feature that we thought would be useful was wall hugging. It was generally noted that as the competition waned, the eggs generally tended to spread out towards the walls of the arena. Therefore, we reasoned, a robot that could drive along the wall would always have a plentiful supply of eggs to draw upon.
On a more personal note, we wanted to make a robot that did everything, most especially win. To start with, based upon our previous experiences we felt that a holistic design was best. Chris, Steve, and I all agreed that an integrated design, one that incorporated the sensors, drivetrain, etc. into frame, was definitely the platform of choice. Also, we all knew that we would be satisfied with any design that at least competed in the final competition. We didn’t want anything that fell apart, or spent 7 minutes driving into a wall. So long as we fielded a robot that spent 10 minutes attempting to do something beneficial for our team, we were happy. Fortunately, that’s exactly what we got…
Preliminaries
Up until this point, all of our previous designs had relied on a two motor drivetrain system. In this system, power is provided to two forward-mounted wheels. By allowing the back end of the robot to move freely, and driving one wheel forwards, and the other wheel backwards the robot can turn. This system proved to be consistently simple to implement, and offered us a good balance of speed verses power. Unfortunately, one flaw kept nagging at us: the darned thing would never drive straight.
It seemed that no matter what we did, any design based upon the two motor approach would eventually curve with varying degrees after driving for awhile. We noticed that some times it would curve right away, and other times it would go straight for a little bit, then take on a slow, gradual curve. At first, we attributed these problems solely to power differentials in the motors, and differing frictions in the geartrains. We figured, and rightly so, that one wheel moving at a different speed than the other would cause enough of a differential in order to cause the robot to curve. However, as we further observed the curvy-behavior of this design, we also noticed that the free-floating caster wheel had an even greater effect on the direction that our robot took. To digress for a second: the caster wheel was simply an off-center wheel that was free to turn in any direction, somewhat like the wheel on a shopping cart. This wheel was the key in enabling our robot to turn. However, as it turns out, after completing any sort of turn, the caster remained pointed in the turning direction. Therefore, whenever the robot started going straight, it would curve at first while the caster wheel straightened.
As a direct consequence of the aforementioned flaws of the two wheel, two motor design, we decided to spend three and a half class sessions devoted to experimenting with different drivetrains. Immediately, we realized that the hardest part of designing a straight-shooting robot was not in actually getting it to go straight, but rather in making a straight moving design turn. We kicked around many ideas, but only fully explored two: a tank design, and a unique design that featured a centrally mounted turning wheel.
Our most innovative design centered on a central wheel that was mounted perpendicular to the drive wheels. Whenever it needed to turn, the robot simply dropped this wheel to the floor, lifting its front off of the ground. This wheel was powered, so by simply turning the motor either forward or backward the robot could turn left or right. In the process of making a functional prototype, this robot passed through the hands of each group member. In the end, however, Steve and I gave up on the design before it was ever completed. It seemed like it was practically impossible to implement. Nevertheless, Chris didn’t give up, and after several modifications to the mechanism that lowered the wheel, and the wheel column itself, he finally produced a working prototype.
This robot, which was internally referred to as the "Crisco ‘bot" (don’t ask), was able to drive straight as an arrow. Although it still used two motors driving two separate wheels, the back wheels were fixed, so that no curve could creep into its motion. As previously mentioned, the Crisco ‘bot hurdled the task of turning by lowering a centrally mounted wheel, and in turn raising the front of the robot off of the ground. This was accomplished by using the servomotor in conjunction with a rack gear. A Lego column that contained a wheel, motor, and the appropriate gearing in between was also constructed. The servo was then able to lower the wheel, raising the robot, then raise the wheel back up, so that the robot could continue forward.
With the exception of some reliability problems, the Crisco ‘bot worked great. It moved forwards and backwards quickly, and could turn on a dime. However, this system took up lots of real estate. Thus, there was little room left over for an egg collector, and the various sensors that the bot needed. Also, the fact that the front of the robot lifted off of the ground in order to turn made designing an egg collector a special challenge. Finally, the servomotor had a tendency to separate from the rack gear, causing the turning mechanism to stop functioning. All in all, we decided that this design couldn’t form the basis of an adequate robot.
The tank never evolved beyond a simple proof of concept device. The basic theory behind this design was that real tanks, using treads, are able to turn and go straight. Therefore, emulating a similar design in Lego’s should give us the same benefits. However, the Lego tread combined with the grain of the carpet provided an environment within which our tank robot couldn’t really turn very well.
One final design that was also considered, albeit briefly, was the split design, as inspired by the construction vehicles parked outside of the new Kelvin Smith Library. Steve’s idea was that a robot that was able to turn in the middle might satisfy our going straight requirement. Unfortunately, this idea proved to be very difficult to implement, even with the turntable. Also, this design had a very limited turning radius, and even lost quite a bit of power when turning.
Version 1
After spending almost two weeks working on different designs, we still hadn’t found a solution to our curvature problems. At this point, it was time to be locking in our final design, so that we would have plenty of time to work on our code. So we reverted back to type, and adopted the one motor per wheel design again – despite its flaws. We did manage to differ from previous designs in several ways, however.
First and foremost – this first serious attempt at a final design was the smallest robot that we had ever built. Before coming into class, I had an idea for a frame that would incorporate room for sensor assemblies, motors, geartrain, and an egg all in a unified structure. The crux of my idea relied on V shaped design. At the tips of the V we placed the bump sensors, then the drivetrain was placed further down the body. This was somewhat of a departure from previous designs, in that, the drive wheels weren’t as far forward as possible. This didn’t seem to hinder our design at all. Furthermore, this initial design featured integrated locations for two separate sensor arrays: the egg discriminator and breakbeam sensors. The breakbeam sensors were mounted in the holes of a Lego beam, so that the infrared beam stretched right across the front of the egg inlet. It should be noted, however, that this sensor array was placed as close to the front of the robot as possible. The other integrated set of sensors was the egg discrimination light/phototransistor pair. The general idea was that as soon as an egg crossed the breakbeam, we would turn on the light, grab a reading off of the phototransistor, and we would know what type of egg that had been captured. This idea seemed to work pretty well, and was further solidified in the next version of the robot.
The drivetrain that we chose for our initial design also varied from previous designs. Steve was hepped up on the "chain drive" philosophy at the time, and decided that it was the way to go. Hence, the gearbox in the preliminary version of our final design combined the chain with a 16 gear in order to make a really "unique" gearbox. Unfortunately, this system ultimately had two problems: reliability and speed, or lack thereof. The use of the chain introduced a severe unreliability factor. It was easy for things to get caught on the chain, or for it to simply fail. The second problem was the really slow speed produced by the geartrain. According to Steve’s calculations, the gearing went something like this: 8~40~24~16~40, where the ~ represents one gear meshing with another. The final gear ratio came out to be something like 30-1, or so. Although this design had quite a bit of torque, it didn’t quite have the speed that we were looking for in such a small design.
Despite all of the benefits of this design, it ultimately needed to be scrapped for several reasons. The primary flaw to this robot was in the way the angled V shaped Lego’s encroached upon the egg holding pen. As it turns out, if the incoming egg was turned so that it was coming in at it’s maximum width, the edge of the slanted bricks would stop the egg from entering the detection area. We placed a prime importance on the easy access of eggs into the robot – we wanted it to be able to collect as many as it could! Furthermore, since it was impossible for us to shave off the offending corners, at the very least the front of the robot needed a redesign. Another reason that this design needed to be scrapped was because of the slow geartrain. In a word, it was horrible. However, because it was integrated into the frame, it couldn’t simply be removed and replaced with something better.
Version 2
After scrapping the first version of our final design, we looked back on what had been done. I was still in favor of the V shaped design, so much so that we decided to keep it, so long as eggs could freely move into the robot. My solution was to widen the egg holding pen by two Lego units. This gave the robot more that enough leeway in order to let eggs of any orientation in. The other, hidden benefit of this was that in the new scheme of things, our robot was bigger. This added space made fitting all of the necessary equipment less of a challenge.
In the first version of the robot, we recognized the fact that we needed some sort of arm in order to keep the single egg trapped inside of the robot. However, by the time we were ready to design such an arm, we had also decided to scrap this first design. Therefore, the servo-driven swing arm wasn’t actually built until the second revision of our final design was well under way. We saw two possible methods of powering our arm: either via the servo, or by using the "blue dot" motor. Well, we all knew that the "blue dot" was pretty pathetic, and although it served us well for the Lego launcher, it really wasn’t suitable for the arm. So, the main design challenge was to fit the unwieldy servomotor onto our robot. As it turns out, we mounted the servo horizontally on port side of the robot. This formed the basis of a simple arm structure: a 6-long axle, to which we connected a rectangle formed by 8-long axles. Not only was this simple to construct, but our placement of the servo was integrated into the Lego assembly used to mount the head. Finally, Steve added a back flap, in order to push the egg back up against the discriminator. This flap wasn’t securely mounted, however, so he added a rubber band in order to keep it from scraping along the floor, and knocking out eggs.
Another significant change we made over the previous version concerned the placement of the breakbeam sensors. In the previous version, I had placed them right at the front of the egg holding pen. However, my good friend Chris pointed out that it would make much more sense if the sensors were placed near the egg detectors. In that configuration, whenever an egg is detected, we know that it’s right up against the egg discriminator – ripe for detection! This sure was a good idea, as demonstrated by the fact that we had no problems discriminating between eggs. In order to make this happen, we needed to apply a little "hack" to the breakbeam sensors – namely, they needed to be bent. As given to us, the breakbeam sensors are pretty long, so long in fact, that they jutted into an area of our frame occupied by the gearbox. So, thanks to a soldering iron and the steady hand of Dr. Drushel, our breakbeam sensors were crafted into an L shape, which fitted perfectly into our design.
Besides driving straight, nest discrimination gave us the most problems throughout our final design. At first we decided to use our little polarized sensor array, developed during the drivetrain testing. This head was simply two photoresistors with opposing polarizing films, mounted in parallel. There was practically no shielding whatsoever. This was in stark contrast to our main head, which was 6"x4"x1". This head was designed way back in assignment 4, back when our design emphasis was placed on shielding. This head had served us well throughout the semester, but Chris and Steve weren’t too thrilled with its ungainly, bulky design (I liked it because, well, I built it!). So it was time for us to take a paradigm shift in polarized light detection. We tried to use the little head for about a week. Unfortunately, we couldn’t get a handle on the light values that it was reporting – they just seemed to be all over the place. Consequently, we gave up yet another new idea, and slapped the big, klunky head back on. This head continued to perform well, although it was somewhat hampered by the fact that the robot wasn’t exactly level.1
Finally, several other improvements were made over the previous design. For the drivetrain, Steve went back to a tried and true design of 8~40~8~40. This design offered us a 25-1 gear ratio, in turn giving us all of the speed, and torque, that we needed. Also, the front bump sensors were just bare switches placed on the two front-most parts of the robot. Unfortunately, the robot had enough power to sometimes mangle, or even shear off the switches. Consequently, two things were done. Firstly, some Lego’s were added behind the switch, in order to provide some reinforcement upon impact. Secondly, some electrical tape was added across the front of the switch, preventing the cap from popping off. With this design, our little robot survived just about every type of impact possible, with only a few bump sensor-related casualties. The rear bump sensors consisted of naked knife switches, pointed inwards. We originally had them pointed outwards, but they kept getting sheared off on other robots or even on the arena itself. After some structural modifications, we found it possible to re-arrange the switches, so that they pointed inwards. After making this modification, we experienced no major switch failures. Finally, some mention needs to be given to the nest detection sensors. This sensor array consisted of another light/phototransistor pair, aimed towards the floor. Consequently, by monitoring this sensor, the robot could tell when it was in the nest. The only flaw to this scheme is where we chose to mount it: towards the rear of the robot, behind the egg discriminator. Occasionally, situations popped up where the robot got turned around, and the nest detectors were legitimately inside of the nest, while the egg was still outside. This was a rare occurrence, however and generally didn’t affect our performance to any great extent.
Code structure
On the whole, we didn’t really want our code to do anything exceptional. Sure, it would be nice to have different behaviors based upon time factors, etc. In reality, however, we just needed to have a robot that worked autonomously. In fact, achieving this main design goal took all of the time that we set aside for programming, if not more.
Version 1
Around about assignment 6 or so, we all got somewhat displeased with the spaghetti code that we had been hacking together from the previous assignments. It was at that point that Chris came up with what I thought was a really brilliant idea – that of centering our code on the Finite State Machine concept. In this method of software design, the behaviors of the robot are broken up into specific states, for example bumping, driving, and scanning. The actual behaviors are then coded, and the robot simply flips between states based upon incoming stimuli. The real beauty of this methodology, however, was the fact that all motor control was centralized in the main() function. Consequently, we immediately avoided any issues of motor/sensor contention. I felt that this code was decently elegant, and provided a welcome addition to all of our designs. The only flaw was in the fact that it was somewhat difficult to extend to new behaviors, for example adding the "I have an egg…" behavior required the addition of another FSM. Yet, on the whole this methodology showed some promise.
Version 2
Moving ahead in, our first approach to code for our final robot was simply to port what was written in assignment 7, namely Chris’s FSM over to our final design. This went fairly smoothly, until we hit a snag in the "with egg" behavior. Whenever the robot had an egg, it was supposed to figure out what type of egg it had, and navigates to the proper nest. Well, the FSM code was having some problems performing this procedure, and in the process of debugging it, Steve felt that it was just too complex and unwieldy. Consequently, Steve scrapped this code, and decided to start from scratch.
Steve practiced the "dæmon does more approach" philosophy of design, in which the main() portion of the program was kept as linear as possible. Consequently, more functionality, such as motor control, was moved to the processes. This made his program somewhat simpler, in that, for any given time, the main() portion of the program was only doing one of two things: finding an egg or delivering an egg to a nest. In the end, we’ll never know which code base was the "better" one. Steve’s approach managed to perform all of the functions required of it, so it all worked out in the end.
The last bit of coding came during the "tweaking" stage. At this point, we had completed both our physical design and our code, and were looking to make the final touches. One of the best changes we made was some software that attempted to compensate for the motion inaccuracies propagated by the caster. We noticed earlier that whenever the robot turned, the caster was pointed in the direction of the turn. Consequently, we figured that if we started moving at a slower pace, then gradually brought the robot up to speed, then the effects of straightening out the caster would be minimized. This approach worked fairly well, and was a welcome addition to our robot’s behavior.
Results
When evaluating our finished product, goofball, there’s a couple of different ways that it can be looked at. First and foremost, collectively as Abort, Retry, Fail?, we won the "LEGO my EGG-o" final egg hunt. In fact, I’d like to think that little goofball played a rather significant role in this victory. This was really a great thrill, because it proved that despite all of the dubious design decisions that we made throughout the project, we were still able to make a really great robot. In fact, he succeeded despite the fact that we failed to add timeouts, special behaviors, etc. proving that sometimes, simpler is better. In fact, we never did design any wall-hugging behavior, as we had originally intended. From another point of view, I think our final design was pretty good because I was proud of it. In the beginning, I maintained some serious doubts as to whether or not a small robot would actually fare well in the final competition. I tend to make large, bulky, albeit sturdy designs, so trying to build small was somewhat of a challenge for me. However, our design did okay. I’m proud of what we accomplished in this class, and I think that I’ll always look back at it with fond memories.