Team Eleven/Paper

From Maslab 2006

Jump to: navigation, search
Maslab teams
Team 1 · 2 · 3 · 4 · 5 · 6 · 7 · 8 · 9 · 10 · 11 · 12 · 13 · 15
Team Eleven's Journal · Paper

Contents

Final Paper

Introduction

Team 11, otherwise known as Robotron, had four or so members - Nelson Elhage (nelhage), Christina Hawkes (riv), Andrea Hawksley (hawksley), and Kaia Dekker. Nelson is a freshman, prospective Course 6 major, and the only member of our team with any extraordinary coding skill. Riv is a junior, the only actual Course Six-er on the team, and really the person who decided that she wanted to do this and helped to bring the team together. Andrea is also a junior, but she hails from the somewhat unconventional major of 9. Kaia is a senior in Course 8.

Coming into Maslab, the Robotron team goal was primarily to beat the team of freshmen (Team 13: triskadekaboviphobia..or something like that). Random Hall had quite a few teams this year, and, although the three of us might not necessarily have all that much clue, it still seemed as though it would be somewhat embarassing to do worse than a team comprised entirely of freshmen.

Mechanical Design

Picture of KludgeBot 2.0
Enlarge
Picture of KludgeBot 2.0

As you might have noted above, nobody on our team had a major even vaguely resembling mechanical engineering. The mechanical design was basically derived from the reading about what people had done in the past and Andrea drafting sketches in her handy lab notebook. The result, was a rather clunky, yet functional robot that we dubbed "KludgeBot".

KludgeBot had a roller made out of a paint roller and some mousepads for picking up and dropping off balls. We wanted a mechanism that could be functioning all the time (so that we wouldn't have to worry about turning it on and off when we went to get a ball), would be relatively simple and consistent (only one motor/servo/whatever, no fancy gearage - as I said, none of us were MechE), and not require too much ability to actually "line up" with anything very well. Browsing through what people had done in the past led us to the conclusion that a "roller" mechanism would fulfil these requirements fairly successfully. Paddles have a chance of knocking balls away, it seemed as though a simple holding area would require fairly fancy movement code in order to ensure that balls weren't lost when you moved around, and we weren't sure how to manage ball drop off with a single, servo-operated gate (although I think the team that won was one that did this fairly successfully).

Many teams used circular robots in an attempt to avoid "stuck" situations that apparently showed up a lot in the past. To be honest, the main reason that we didn't do this is that the idea hadn't even occured to us before we finished building our robot, and we didn't want to do a complete redesign of something that was already working. Additionally, a round design would mean that we would need to come up with a different sort of ball collection mechanism, and we were pretty happy with what we had. As it turned out, the round robots seemed to get stuck about as much as the non-round robots, and our robot was actually one of the better robots at getting unstuck just because we had a functional robot longer than other people and were able to successfully test out more stuck conditions.

The rest of our design was sort of tacked on as we saw the sorts of stuck conditions that we were capable of getting into. A shield was added to the bottom of our robot to prevent balls from getting stuck there, and sensors were positioned so as to enable wall following, recognition of stuckedness, and etc.

In conclusion, Jessie from team six probably summarized our robot best - "Now, Robotron, for instance, didn't have a lot of machining experience, and their robot looked like a hackjob that was held together by divine providence and duct tape, but the shape, the body, where everything was placed, all actually seemed to be well-designed, thought-out. That's not the same as a robot with mechanical design issues."

Software Design

Our robot was built around a hierarchical finite state machine architecture. At the highest level, the DestroyAllHumans behavior dealt with our high level strategy -- In short, pick up balls, and once you think you have two, start looking for goals, and after three, stop looking for more balls -- and relied on lower-level behaviors such as GatherBalls, ApproachRedBall, and even lower-level ones such as TurnToAngle, which used the gyroscope to turn through or to a given angle.

Every behavior in our implementation inherited from the abstract MaslabBehavior class, which provided empty implementations of enter() and exit() methods which notified a behavior that it was being started or ended, as well as a run() method. Behaviors were non-blocking -- run() was expected to check state and return immediately. Behaviors could also set an exit code indicating completion or failure of their task.

On top of the behavior architecture, we implemented the state machine architecture, using the StateMachineBehavior subclass of MaslabBehavior. State machines employed the MaslabState and ExitCondition classes. MaslabState objects represented nodes in the state machine graph, and ExitCondition objects were the edges. Each MaslabState object was associated with a MaslabBehavior (possibly another StateMachineBehavior), and a list of ExitConditions. StateMachineBehavior, in its run() method, ran its current MaslabState, and updated its state if the current one indicated it was appropriate. MaslabState managed this by running its current behavior and checking each of its ExitConditions; If a condition returned true, the state would query that ExitCondition for the state to transition to, and return it to its parent StateMachineBehavior.

Subclasses of StateMachineBehavior worked by creating MaslabStates wrapped around various MaslabBehavior objects, and assigning them ExitConditions indicating when to transition between them. Typical ExitConditions included TimeoutCondition and SeeRedBallCondition, but MaslabBehavior objects also exposed an interface to return inner class subclasses of ExitCondition that monitored that behavior's exit code. High level states often employed private inner classes for somewhat lower-level states. For example, GetRedBall contained an inner ApproachRedBall state.

The architecture overall was quite flexible and helpful. It was sufficiently modular that separate team members could write independent behaviors and then integrate them together later. A RunBehavior class contained a main method that let us test individual behaviors from the command-line, making testing very easy.

One annoying problem with the architecture was that the logic of "When should I leave this state?" and "What state should I go to when that happens?" were both encapsulated into the ExitCondition class. We could easily write logic that said "Leave GetRedBall once we think we have collected a ball", but once that happened, we could only say "Go to GatherBalls" or "Go to DepositBalls"; There was no easy way to express, "Go to GatherBalls if num_balls < 3, else go to DepositBalls". Separating this logic into different classes would have let us express many ideas more simply than we were able to.

Overall Performance

Our robot's cameras have been generally flaky throughout (we got a second one after the first one proved to have unresolvable issues) - at one point it was actually changing the white balance every update, and it wasn't any more agreeable the day of the competition. We ran an entire round with the white balance so horribly off that it thought the walls were balls, despite having used all of the usual fixes that worked for all the other teams, and readjusting the settings obsessively just before the competition to try and get them to work correctly. Luckily for us, people apparently decided that that qualified as a "false start" and we were given another chance to prove that we hadn't built a robot that would stupidly run itself into walls whenever it got the chance.

Robotron ended up tying with several other teams for second place. Despite our best efforts to test for every stuck condition, it never even occured to us that the robot could somehow end up with not four, but five balls before getting to a goal, given that it wasn't supposed to try to pick them up if it already had three (we had occasionally had it pick up four, and had found no major issues with that). As a result, our robot had a purely mechanical stuck problem during the competition where it gathered too many balls and got stuck on the floor. I suppose it just goes to show that no matter how careful you are being, there is always some sort of stuck condition that you will forget to test for, and that will conveniently show up for the first time at the competition.

On a side note, afterwards we re-ran our robot on the same course from the same position, and it successfully scored two goals within 2 or 3 minutes, which would have let us beat out the winning team if we had done that during the actual competition.

Conclusions and Advice to Future Teams

In conclusion, I think that all of us learned quite a bit. In fact, I can think of several things that I'm very glad that we did for this competition, and several things that I would do differently if I were to rebuild the robot.

Seeing as these final papers are mostly useful to people taking Maslab in the future as a way of seeing what to do and what not to do, I'm going to attempt to list and explain various things and ideas that i think are important.

The most important thing is to finish building your final robot early. It's okay to make minor changes later, but you don't want to be doing any major shop work after the first week and a half to two weeks at the latest.

Once you have your robot built, the next most important thing is to test it. Test test test, with all of your code, in every situation that you can think of, and then come up with some new situations that you didn't think of before. Figure out how to deal with every stuck condition that could come up. How can you tell if your robot isn't moving? How will it escape? It's incredibly important to have your robot built early because it's hard to code for a robot if you don't know what the final result is going to be like, and it's impossible to code for stuck conditions that you've never seen. Maslab robots aren't ideal, and they're going to do stupid things like get balls stuck under them to prevent them from moving.

This isn't to say that you shouldn't worry about coding until the robot is 100% put together - you should! But what you should be worrying about is less specifics and more theory. What is our overall game plan? How will different behaviours be linked? If you can manage it, have half your team working on an infrastructure for your code to make it easy to deal with later, and half of your team actually designing and building the robot for the first week. After that, everything should be "write, test, write, test, write, test, fiddle with sensors, test, write test, build ball guards, test, test, write, test, write, test..."

I guess those are the three main points I have for future teams. If you are a future Maslab participant, you should definitely be looking at other people's final papers and wikis as well, though.