Team Five

From Maslab 2013
Jump to: navigation, search

GOMBot+Friend


Number 5 wishes he could be a real boy like GOMBot

The GOMBot+Friend is anticipated to be a spectacular masterpiece.

WARNING: When looked upon directly may cause the normal man to be turned into a giant salt pillar.

The Gom is strong with this one, and he has no fear in the face of battle. He will qwebanzce his way to victory. This Bot will be more than just a robot, with his mighty wielding of GOM, this robot will be gifted with the power to warp time, space, and our hearts.

FINAL PAPER:



Overall strategy


Team 5’s strategy originally was made under the assumption that both colored balls would be We decided that the blue bin had such a large reward that we should collect all of our color balls and score them in the top bin. We would also collect our opponents color balls and score them over the yellow wall at the end of the round to prevent our opponent from clearing the field. We would also release all balls possible from the button press. When we found out that, with high likelihood, the balls on our side of the field would, in fact, be of our color, we changed our strategy. We also made further changes when we discovered how difficult scoring balls in the top bin was. When our team realized that we didn’t need a storage mechanism that also sorted balls, our strategy and design greatly simplified. We decided that instead of trying to reach the top bin unreliably, we would try to clear the field and score over the yellow wall, which would allow our robot to be significantly smaller and shorter. We originally planned to have several button presses to try to get more balls onto both sides of the field and subsequently tried to score those balls. We felt that scoring balls over the wall, especially with the speed we were planning to have, would confuse the other robot. We also hoped that we could reliably clear the field and earn the 200 point bonus, while dumping all of our balls would likely not allow the other team to clear their field. As the competition progressed, we realized that our goals were more infeasible than we first planned. By the time the final competition rolled around, we adjusted our strategy to eliminate all button presses and just try to clear and score the 8 starting balls on our side. With up to 5 ball storage, we determined that we could outperform the majority of the field.


Mechanical design/sensor

The overall design of our robot evolved greatly throughout the competition. At first, our team wanted a 14”x14” square robot with top bin scoring and sorted storage capability. After we learned more about the competition semantics, we determined that such a large robot wasn’t necessary and that a smaller, swifter robot would have done just fine. We also made several discoveries while making our peg bot. For example, we determined that large robots can lead to unwanted results. We found that our peg bot couldn’t move if we placed our battery in some places. We found that if we constrained our robot to a smaller area, we eliminated the possibility of heavy elements in our robot having enough torque on our motors to cause our robot to become immobilized. We decided to have a 6”x7” design that stored only 2-3 balls and could move just fine on our stock motors. Our design eventually expanded to 10”x10” to allow for greater ball storage and to allow our electrical components to be more easily stored. We also discovered as the competition progressed that we could integrate several steps of our ball collection process. We found that building a rubber band roller was more difficult than originally determined. We also found that our vision code was reliable and accurate enough that we could drive within 1/2” of the ball on either side. We decided to integrate our collection and lifting mechanisms into one completely new design. We constructed a metal scoop for the balls that was connected to a high torque servo. This scoop lifted balls radially into our storage area, which was made out of aluminum ductwork. This ductwork snaked around the back of our robot to the opposite side, where a metal door connected to a servo kept our balls stored until we wanted to deploy them. Our drivetrain was very simple. We used our stock kit motors and geared them down just once to ensure we had enough torque to turn reliably. We also attached bearings to our main axle to ensure that it remained correctly aligned. Our sensor scheme was also incredibly simple. Our only sensors were the webcam, the gyro, and one IR sensor. We used the webcam for all vision and the gyro for all mapping/positioning. We also were able to make some determinations for planning and re-alignment from vision. We only used the IR sensor to ensure that we didn’t stay stuck against any walls. If our robot stayed up against a wall for more than 5 seconds, we determined that our camera was seeing over the wall and we would turn it around based on the IR reading.


Software

The technology stack used for our code is as follows: Arduino (C) Python C++ The code is divided in to 3 segments: the sensory inputs + system actuation, the Python-Arduino interface, and the system control loop. The Arduino is responsible for all of the sensor data collection, motor controls, and servo controls. The majority of this code was given to us by the MASLAB firmware file initially provided. We did modify this file to read the gyro data to give 2-decimal accuracy. Furthermore, we added a small calibration phase to account for gyro drift. The only other small changes we made to the arduino firmware related to servo controls. While staying up late one night, we discovered a bug in the originally provided code that prevented servos from actuating along the desired ~180 degree span. It turns out that casting an 8-bit signed character to a 16 bit signed character is a bad idea! If an input signal greater than 127 was sent to the servo actuation function, the input would be interpreted as a negative number! We found this bug and mentioned it to one of the MASLAB staff. It was repaired shortly after. Our code actually just uses the fix as implemented by ourselves Our Python code is very minimal. Its primary purpose is to pull data from the Arduino interface (as provided by MASLABs starter code) and pipe it to C++ for advanced processing. We spent some time early on figuring out how to call C++ modules from Python. It turns out to be very easy and extraordinarily fast. Our python code is responsible for calling C++ image processing code, setting motor/servo values, and terminating operation at 3 minutes. Our main reason for using C++ is the great speed advantage. A quick benchmark showed that doing the processing in Python versus C++ was 300 times slower in Python while running identically optimized code. No processing was done in Python in our final implementation. The C++ code is our baby. It is beautiful. The C++ modules are split in to two portions: the Image Processing and the Behavior State Machine. The Image processing code takes the three stupidly simple steps of color classification, wall detection, and ball detection. Color classification simply requires pulling the image RGB values and classifying them independently of adjacent pixels. Each RGB value is classified in to a particular “color cone.” The color cones are simply vectors in the RGB space that span a volume of colors. If the RGB value falls within the appropriate color cone, then that pixel will be classified with that color. This code is fast! We’re talking 50 assembly instructions fast. So that’s plenty fast for our purposes. After color classification, we compute angles and distances to walls. Using the 3D rasterization rendering equations, we can convert differences in image y values to distances and image x values to relative angles. This basic conversion only works because we know about the heights of particular field elements and the field of view for the given camera. We successfully determined the distances to walls within 2 inches. Angles were determined to within 5% error which is plenty for our purposes. Finally, the ball detection code is also dirt simple. We run a simple blob detection algorithm to find massive blobs of green or red. If those blobs are big enough and satisfy basic criteria of ball classification, then we call them balls. This works exceptionally well since there are only red and green BALLS on the field and nothing else! The classification is rather loose and would not work for many other purposes. The ball classification criteria check for the ratio of width and height being near 1:1 and for the fraction of points within a square region being near pi/4. A perfect ball would have a width/height ratio of 1, and a perfect ball would occupy exactly pi*N/4 pixels from a sqrt(N) by sqrt(N) square. The final Image processing code required only 3 milliseconds of runtime. Our frame rate bottleneck was actually the camera capture time. Our camera would run at 30 FPS at most. Therefore, our final code only ran at 28 to 30 FPS. Finally, our code needs to use all of this wonderful image processing output to make decisions. We had a super simple state machine that contained only 4 states. The possible states were: Explore, Collect Ball, Deploy, and Reposition. The exploration state used data from the Image Processor to navigate the field based on immediate decisions. We had no aggregate map data, only immediate map data. If a ball was found, we would enter the ball collection state. If a goal was found and we had collected balls, we would enter the deploy state. The Ball Collection state focused on slowly approaching balls in a careful manner. Once our robot was close enough to a ball, we could easily charge towards it and collect it reliably. Some basic timeouts were set in this state to prevent us from ever getting stuck on unreachable balls. As another safeguard to getting stuck, we told our Image Processor to identify balls that were “unreachable” by our bot due to them being partially occluded or too close to walls. Upon collection, we return to the Exploration state. The Deploy state would focus on scoring. It would first check if there is a goal in its range of vision, and then prepare to score. We noticed that our scoring mechanism require precision, so we couldn’t simply score from any direction we wanted; we had to reorient our robot before scoring. Given our slick Image Processing data, we could actually detect the normal to walls and reorient ourselves accordingly. So, upon recognizing a scoring wall, we would reorient our robot 16 inches in front of the wall such that we were parallel to the normal of the wall. Afterwards, we would score by driving forward and opening the deployment hatch. The Reposition state focused on travelling in a certain direction for a set time, and the leaving the robot in a desired final orientation (or heading). When the reposition state terminates, it always returns the state machine to the previously inhabited state. For example, if we are repositioning our robot for scoring, we would return to the Deploy state upon completion of reorientation. Overall, our code was small, slick, optimized, and effective for the purposes of MASLAB. If this code were to be deployed on a larger scale system, it would have to be refactored heavily.


Overall Performance

Our team feels that our robot massively underperformed at competition for a few reasons. Most importantly, We feel that our team wasn’t nearly as cohesive and prepared as we needed to be. Much of this had to do with our team composition and our team demands. We had only one mechanical engineer, and we couldn’t ever agree on a stable design. Our team built five separate robots in one month. Unfortunately, so many build periods in such a short amount of time gave our coders extraordinarily little time to code, which caused our robot to massively fall short of expectations. At the end of the competition, our robot could not move on the field because of a mechanical problem. On the left side of our robot, one of the bearings became loose, which caused our axle to become unstable. When our robot tried to turn, the gear system became disconnected because of the axle’s mobility. This caused one of our main wheels to be unable to be moved, which made our robot unmovable when it tried to turn in one direction, or made it turn around itself when it tried to drive straight. Other than our drivetrain, the mechanical aspects of our robot turned out fine. Our lifting scoop worked just as we needed it to. In fact, we found that at the length we built it, our servo could lift an entire textbook. Also, our storage and deployment mechanism was somewhat reliable. When adjusted correctly, the ductwork acted like a continuous ramp, and the deployment door worked properly. The only issue with the ductwork was that it was flexible, and its position was not definite. This caused it to sometimes become turned out of position, which let balls become stuck when waiting for deployment. Code-wise, our robot performed flawlessly. Our vision code not only distinguished game elements, and created localized mapping, but did so at 30ms/frame. Our state machine had flawless transitions and our robot was able to re-align against the scoring wall perfectly.



Suggestions

For next year there are a few things specific to team five that we would like to see. Firstly, we’d like to see the opportunity for great strategy to trump a “lucky” design. This has more to do with the in-game choices. For example, when our team believed we would regularly be handling our opponent’s balls, our strategy and design was far more complicated and complex. While we know that such a suggestion may seem crazy, moving away from a simpler game, but we feel that when students are prompted with difficult design choices, their final products are more interesting. The only other suggestion is that we’d like to see the staff keep teams from making bad decisions and forming bad habits early in the competition. The staff has spent more time around the competition and can understand when the students are making a mistake by a particular re-design or code tweak. These changes might be crucial to a teams at the end of the competition, but we feel that at the beginning of the competition, it is essential to make a design and stick with it, leaving a lot of time to make minor changes down the road if need be. Overall, Team 5 greatly enjoyed MASLab and some members of our team will likely participate again.

Personal tools