Team Ten/Final Paper

From Maslab 2013
Jump to: navigation, search

Contents

Robot Strategy

So you've got a copy of the rules and asked questions to clarify them -- time to start designing the robot? Lifters, dumpers, belts, vision algorithms? Nope! First you have to consider strategy. You can design the best ball shooter in the competition, but if it turns out that the competition favors shoveling and dumping balls en masse you won't accumulate many points.

Original Strategy Meeting

(Note that some of these conclusions are incorrect and many changed before/while we made our robot) The first thing we did (after the info meeting, before maslab even started) was discuss strategy. By discussing possible scoring strategies, we quickly concluded that robots should only score in the center of the tower and that the reliability with which the robot could score in the center of the tower was the robot's most important quality. Correspondingly, we figured that the 200 point bonus for clearing the field was not that important (despite the big number); it was only the value of 4 balls in the tower and could easily be prevented if the opponent dumped a single ball over the wall in the last 10-20 seconds of the match.

In terms of collecting balls, we decided that the ball-dispensing button (henceforth referred to as the cyan button, although the online rules might still say that it is green) was the most efficient method of collecting balls. We figured that both robots would rush to find and press the button, positioning themselves so the released balls fell directly into a storage container. Even with a 20 second delay between button presses the robot collects a ball every 5 seconds -- a hard feat to match collecting the balls that are already scattered across the field.

Then we discussed mechanisms for accomplishing these strategies. At this point we watched a lot of videos of previous competitions -- past Maslab teams have committed a lot of time testing out designs for us, and the least we could do is take advantage of it. (Well, perhaps they were just making their own robots, but we can still benefit from their work). We chose an omni-drive to make it easy to line up with the tower (run into the tower then move sideways), a dumper (with a very large storage area) sized to line up with the center of the tower, and a roller + belt system to collect balls (from the ground or from the ball dispenser) and lift them into the dumper.

What was wrong and what changed later

First of all, we were slightly mistaken about the rules. We had thought that the towers bottomed out at the ground, leaving a lot of space for balls, but there was actually a raised floor that significantly limited the number of balls that fit in each section. But we were still correct that scoring in the center of the tower was critical to winning. The 200 point bonus for clearing the field was irrelevant, but not (as we thought) because opponent robots would prevent it from happening. In the final competition, even the best robots couldn't quite clear the field of balls. Lesson for the future: don't overestimate the robots. Maslab's challenge is hard; the robots won't be as good as you expect!

We later talked to a MechEE non team member who talked us out of using belts (they're too unreliable). With his help we tried to design a four-bar linkage but couldn't get the dimensions to work (the tower was too far up and out from the robot) and switched to an elevator.

We also talked to Maslab TAs who told us that previous teams had tried omni-wheels but they hadn't turned out to be that useful. We switched back to normal wheels with the plan of using PID control to aim at the tower.

Robot Design

Mechanical Design

CADing

It's a good idea. I taught myself to use SolidWorks over winter break -- if you're reading this before IAP you should too.

Collisions with walls

Robots get stuck on walls. A lot. Either by getting lost in a corner or by hitting a pole/wall without triggering bump sensors. You need to think about this before you design your robot -- how will you keep your robot from suffering such a fate? We designed the robot to be surrounded by bump sensors (front-left, front-right, back-left, back-right) such that it couldn't hit the wall without a sensor triggering. Of course the final robot didn't have these sensors... but more on that later. They're a good idea.

Assembly

We designed the robot to be assembled with slots and tabs held together by screws (see picture). It worked well and was easy to assemble, but it took a while to CAD (perhaps saving time overall, though). It also imposed the requirement that most/all parts be laser cut. This is a good idea, but make sure it is possible. And that you have someone on your team who can laser cut; we had 3 or 4 laser cutting plans fall through for various reasons. Be really sure you can laser cut if that's how you want to make your robot.

Materials

Maslab ran out of acrylic and we were forced to find other materials for the final iteration of the robot. We discovered medium density fiberboard (MDF), which costs about $5 for a 2x4 .25" thick sheet at Home Depot. It is strong enough and easy to machine. Maslab staff: you should consider using it instead of acrylic next year. Maslab students: you should consider using it regardless. One note on laser cutting: the Architecture department didn't want to laser cut MDF for some reason, but MITERS was willing to (they love MDF and say you can use similar settings to plywood (just cut slightly slower to be safe)). The laser-cut MDF came out a lot nicer than the acrylic and we could easily machine it by hand as necessary afterwards.

Jamming

Just as your robot can jam on walls, moving parts an also jam on parts of the robot. Be aware of this and design around it. Our lifter didn't end up working because it jammed on its sliders and we were unable to fix it in time. Of course we did have time problems... but try to design around it anyway.

Electronics and wiring

This can get kind of messy. You should design in space for electronics in the CAD and, if possible, make zip tie holes for wire routing. It will make your life so much better! We did this, at least to some extent, and a Maslab TA told us we had the neatest wire of all the robots.

Code Design

Code Structure

Everyone knows you want multi-threaded code. There will be a Maslab lecture on that. But there's a lot more to code design than multi-threaded code. We broke the code down into the following modules:

  • Arduino I/O
  • Image Acquisition
  • Image Processing
  • Control (generates high level commands)
  • Pilot (translates high level commands into motor commands)

Really Arduino Input and Arduino Output should have been separate modules, but we didn't know how thread-safe the arduino library was and decided not to mess with it. But there was some stuff we could have done with locks an signals to make it work anyway. And we probably should have done that.

This design is useful because it is easy to test components. For example, you can make an alternative to ImageAcquisition which reads from files and using ImageProcessing without modifying it. Or you can make a joystick control mode for testing mechanisms (this is probably a good idea, but I didn't do it) and make it interchangeable with the Control module.

I made a class called StoppableThread which implements some useful communication methods and allows threads to be stopped cleanly by other thread. See the code for details.

Threads vs. Processes

When I actually ran the first fully-assembled version of the code, vision processing happened a lot more slowly than expected. After a lot of debugging/researching, I discovered that this is because of how python handles threading. In particular, it switches threads after every 100 bytecode, and for the ImageAcquisition thread 100 bytecode was more than one acquisition cycle. So it would always acquire several images in a row before switching to other threads. So I switched over to using processes, which uses a remarkably similar API (although I had to send data between them differently). And it all worked right.

Control Loops (most likely PID)

Don't control based off of the camera. Really. Perhaps you're getting info from the camera at 10 Hz; if you really optimize it you can read images at 30 Hz (the max provided from the camera). Whereas if you read from the IMU (we had a compass, you might have a gyro) at more like 1000 Hz. Use the camera to find the angle to the ball; use the IMU with your control loop to turn to that angle.

Mapping

It's a red herring. Don't do it. Seriously. I don't even know why there are Maslab lecture about it; even if your robot is entirely finished you're probably better off testing and improving your mechanisms and code than implementing any type of mapping. Just follow walls (or do something else to get to other parts of the field) and look for balls as you go.

Vision

You want vision to be fast and reliable, but keep in mind that it only has to distinguish between field objects. In my year (and I think in general) color was sufficient to distinguish field elements.

  • Don't operate on the full image; it takes 2 times as long to operate on an image with 2 times the area. Shrink the image if you can. And you can.
  • HSV (mainly hue) segmentation + blob detection is sufficient, but you can make your ball-finding algorithm work really well by calling cv2.findMinEnclosingCircle(contour) (or something like that). I did, and even when the algorithm did a bad job of identifying ball pixels vs. non-ball pixels it generally found the the correct enclosing circle.
  • Don't worry about speed too much. If vision works at ~10Hz, that's plenty fast. Just use your IMU for feedback.
  • Consider where your camera is going to be mounted. If it's mounted below wall height you can just look for balls below horizontal on the camera. If it's mounted higher it's harder to say what's in the field and what isn't. And what's on the close side of a wall and what isn't.

Control Algorithm

I made an extensible system using behaviors. There were behaviors like "DriveStraight", "AvoidWall", "Uncrash", and "ApproachBall". They do what you think they do. And then when I wanted to add something about scoring over the yellow wall I just added a few more behaviors. Certain behaviors (DriveStraight, ApproachBall) were top level behaviors -- they could be selected on their own. Other behaviors, such as AvoidWall, were only selected from other behaviors (it would be bad to automatically avoid walls when you're trying to approach the yellow wall or the cyan button). Behaviors can be added to the behaviorStack, and when they complete the behavior beneath them executes. If the stack is empty a top level behavior is selected. There is also a priority system (top level behaviors have a getPriority() method, which can return a value depending on the current input), allowing ApproachBall to take priority over DriveStraight when the robot finds a ball but not when it sees no balls. Check out my code -- this was a reasonably complicated system but I think it worked well. And as I mentioned, it is very extensible and easy to modify. And it makes it very easy to test behaviors, since they're all isolated from each other.

Performance in the Mock, Seeding, and Final Competitions

My team had some membership problems. We started with 3 members, while most teams had 4, but then Taibo broke his arm and decided he couldn't do maslab. And Yaroslav was taking other classes and didn't participate that actively. Adam joined, but he was already busy over IAP and it was on the understanding that he was busy and wouldn't be a fully active team member. Erons, who didn't want to be an official team member, was unofficially a team member for the last ~2 weeks of Maslab. But Maslab is still too much work for 2 people; you really need a full team. Taibo and I had originally thought that it would be ok to register as a partial team (as per the website), but this actually doesn't work. Find some friends (it doesn't really matter that much if they know a lot about robots) and do Maslab with them. Partial teams don't work; don't make that mistake.

Given the team membership problems, it's not surprising that we had trouble meeting deadlines. The mock competitions were significant setbacks to our team; we weren't ready to have a complete robot, but we had to make one. So we basically wasted 1 to 1.5 days before each mock competition preparing a robot for the competition. And after that we backtracked and went back to finishing our actual robot. Mock competitions are a good idea and are probably helpful in general, but teams shouldn't be forced to compete in them. Only encouraged. With another 2-3 days we might have actually had a mostly-functional final robot rather than a fully constructed but non-functional robot. We weren't ready for the seeding competition and had barely tested the code on the final robot (which didn't have a working lifter) before competition. Surprise: it didn't work. But hopefully in a week or so (when I'm not sick of working on the robot any more) I'll debug the problems from competition and finish the robot. We'll see how that works with my spring course schedule.

Suggestions

I've already listed most of them elsewhere in the paper, but I'll try to consolidate them here (and add a few I didn't mention).

Suggestions for Running Maslab

  • Make Mock competitions optional (but recommended)
  • Talk to teams more often (e.g. checkpoints 3 and 7); teams don't talk to staff enough on their own
  • Use MDF instead of acrylic. It's cheaper, more available, and easier to machine by hand.
  • Use stock motors that have encoders attached
  • Tell teams about processes (see Threads vs. Processes)
  • Make the lectures more helpful to teams
    • Drop the lecture on mapping (or at least make it optional and after everything else) -- it puts teams on the wrong path.
    • Add a lecture about basic mechanical design/construction. People like me (programmers) would find that very helpful, while I found the lectures on state machines and threading less useful.
      • Have multiple lectures at the same time. For example, the lecture on basic mechanical design/construction could happen at the same time as the one on threading. Team members go to whichever they think will be most useful. Everyone should attend lectures (e.g.) on strategy, state machines (prioritized behaviors?), and types of mechanisms since they're important to understanding the robot.
  • Try to make the rules clear from the beginning.

Suggestions for Maslab Students

  • Make sure you've got a good team. Aka a sufficient number of sufficiently involved people.
  • Start by choosing your strategy. Then figure out your mechanisms. Then protype and test them. Then build your robot.
  • Figure out your construction method. Laser cutting is nice. But make sure you can really do it.
  • Talk to the TAs. They're smart and experienced and can answer your questions. Like "how do I make this?" or "do you think this mechanism will work?" or "Help, my robot just doesn't work and I can't figure out why and it's emitting smoke when I try to make it move"
  • Print debugging information to the screen and to files (python has a nice Logger class). Also record video during the Mock competitions so you can test your algorithm on it later.
  • Mount your camera below wall height.
  • Use the IMU (not the camera) for control loop feedback
Personal tools