There is this thing about high pressure situations – They force you to do your best work with ruthless focus and reckless abandon! I learned this when, over the weekend of September 23rd, I decided to shoot my social life in the foot and participated in the ‘Triangle Health Innovation Challenge’.
It was a two day hackathon where we had to from teams with strangers around a significant problem in health care and sweat over the weekend to develop a prototypical solution along with a compelling business case to be presented on Sunday evening. We mingled and formed teams on Friday evening and started working the following morning. Long story short, we didn’t win. But, it was one of the most fulfilling experiences of my life. The first thing you need to realize is that hackathons are rife with contagious enthusiasm. Everyone in the room is a driven, type-A person looking to make a difference. Second, once you get into a team, everyone has a singular focus – the problem that the team was built around. Add to it the crunch of time, and you the perfect recipe for a productive weekend. We lost, but we gained tremendous self knowledge about our work-ethic and our motivations. Not to mention, a potentially billion-dollar solution to a pressing problem.Win, win, win… So, on Monday when I received an email from the Duke Robotics Club about a week long hackathon to build a battle-bot and compete with our peers, I signed up instantly.
We were provided the following chassis kit…
…Along with a host of sensors:
- Ultrasonic Distance Sensor – Consists of an ultrasound speaker and a microphone. Ideally used for listening to its own echos and determining the distance of the nearest obstacle
- TCRT5000 IR “Line-tracking” Sensor – Relies on the intensity of reflected infrared light to detect a change. It can be used to follow lines such that deviations from the line would be detected and corrected. This is much like a lane departure warning system in a modern automobile. Some clever trickery can also allow you to use this sensor as an RPM reader for your wheels
- Triple-axis Magnetometer (Compass) Board – This is essentially a compass that allows you to know where your robot is headed. Since the wheels cannot possibly spin exactly at the rates specified by the controller, the robot will never move in a straight line unless a sensor detects the deviations and the robot corrects itself through feedback.
- NRF24L01 2.4GHz Transceiver – This is a radio receiver. The arena in the competition was constantly being watched by a camera placed vertically above it. It used a computer vision algorithm to detect the x,y coordinates of each robot on the arena and transmit it on a radio channel. Every robot could therefore know the position of every other robot via this receiver
…And an Arduino Mega controller along with a SainSmart L293D Motor Drive Shield
Apart from these, we had access to 3D-printers to print whatever weapons we may want our robot to have. We were given two servo motors to actuate our weapons.
We were challenged to build a fully autonomous robot that can fight other robots! The bot had to be ready in a week and had to be capable of pushing other bots off the arena, flipping them on their heads or popping their balloons (a small balloon was strapped to every robot which, if popped, would signal defeat). The arena was a 6 ft by 6 ft wooden board painted completely black except a 2 in thick orange boarder on the edge. Every round started with one robot on each corner of the arena, with a colored patch on top. This allowed the camera in the sky to read the position of each robot and transmit it to every other.
In case you have not noticed yet, the real challenge here is the ‘one week’ part. It is absolutely impossible to do anything substantial in a week, especially with classes and midterms in progress. Several teams soon realized this and quit. This included half my team. Me and my partner Huimin He found ourselves in a small minority of overconfident people who thought they could recreate what they have seen on TV since childhood.
Our strategy was as to have an implement in the front much like an earth scooper (shown below), that would activate when in contact with the enemy. If this failed to flip them over, the robot would then drive till it had pushed them off the arena. If we caught the other robot form behind, the jagged edges would pop the balloon.
We started off by trying to make our robot run in a straight line. We used a PID controller that would use the readings from the compass to keep our robot headed in a constant direction. A PID controller is the simplest and most popular kind of feedback mechanism that is used in robotics to make machines behave in a certain way. Later blog posts will delve into several theoretical aspects of control theory, but here is a great video by Brain Douglas that explains PID controllers and how they work their magic.
This took substantial time to debug. There were hours of the robot just spinning around or violently oscillating between two points. After two days we decided to rewrite our code from scratch. This worked, and after tuning the parameters for a bit, we were able to finally achieve the desired effect. The next step was to find our targets on the arena. This step was rather simple. all we had to do was find the vector between us and our target by subtracting our coordinates from theirs, then subtract the heading angel read by the compass and set that as our new desired output in the PID controller, and viola! The idea is to try to approach the nearest target. Since the desired heading is updated every loop, the robot will not be lost once it has thrown one of its targets off the arena. This step was rather easy to implement. However, an ugly problem stuck out its head and we quietly pushed it under the rug. We had been copying and pasting code from all over the place into one large file – code provided by the organizers, code written by us to make the PID controller and code that was written by several other people on the Internet. We however did not keep track of what came from where. since we changed our motor wiring several times, and since the organizers had probably wired their test motors slightly differently than us, we would often just flip a sign somewhere or hack a variable into the right place, without noting these changes. By Thursday evening, the robot was able to find its target in the arena and head straight to it. We realized that we needed some kind of a case to prevent our robot’s innards from being hurt when hit during a fight. We got rid of the acrylic chassis and designed and 3D printed ourselves a new one – A glorious plastic gray platform and a hard top-case to enclose all of the hardware. The platform at the bottom finished printing first and we quickly swapped it in for the acrylic. By now, the robot was looking something like this.
Yup, it looks like a mess. Why is there a plastic cup? it is holding up the compass (magnetometer). What is that tiny little thing in the front that is almost touching the table? Glad you asked! That is the IR Line-Tracking sensor. We placed 4 of these at the four corners of our robot. These would prevent our robot from falling off the arena. As mentioned above, the arena had a two inch orange border around it. If you have been paying close attention, you know that the IR sensor is very good at detecting change in color. Put two and two together, and you have a recipe for avoiding edges. We programmed it so that whenever the front-left sensor hit border, it would drive the robot backward in a counter-clockwise arc, and if the front – right sensor hit the border, it would do the same in a clockwise arc; and vice-versa if the back sensors encounter a border. This system worked well. We use the controllers hardware interrupts, so the reaction is triggered immediately when the sensors hit a border. However, it is was not perfect, and it could lead the robot to fall off sometimes.
By now, we were proud of our creation, but ralized that we had time to do literally nothing else. we put the robot together with the top case, and hurriedly combined our code to be ready for competition on Sunday. Folks, never combine pieces of code at the last minute. We spent some time managing wires putting the robot together:
To our Horror, the complete robot with the combined final version of the code was now displaying the same behavior as it had been after we had first programmed our first PID controller – running around in circles and oscillating violently. What followed was a painful night of debugging the code and testing the robot about a hundred times. At about 2 hours before the competition, we had our robot working again. We had built no weapons of course, and were relying on the hope that our robot would just be able to push other robots off the edge by simply running up against them. Our troubles were not over though. One of the wheels now malfunctioned – it would not spin with the shaft. We spent the next hour frantically trying to fix this problem using epoxy and super glue. Finally we reopened our shielded and boxed robot to replace and rewire the motor. We uploaded our final code to the controller and thought we were ready to compete. (In the last minute rush, we forgot to take picture of our completed robot. So, here is a picture of it on the arena with four other robots. It is the one with the green balloon at its back. )
So How did we do? Well, we came in last! We were a part of 4 fights, and in each of them our robot did an unexpected move and fell off the edge. It failed to behave as expected and actually ran in reverse. the first time the interrupts from the IR sensors failed to catch it. In the 6 minutes before our next fight, we diagnosed this to a few wires that had come lose. In the next battle, the IR sensors interrupted the robots routine, but the wheels turned the wrong way in response and the robot fell off the arena anyway. The new motor had been wired the opposite of the old one, and the code had to now be edited at every point the motor was addressed to change its velocity to the negative. As you can imagine, we missed some of these instances. For the next two round, the robot successfully avoided the edge but kept spinning in circles till someone knocked it off.
What surprised me was that we were in fact the team with the most sophisticated algorithm. Ours was the only robot that had a strategy for finding targets and protecting itself. The most common strategy was to simply use the IR sensors to prevent the robot from falling off the edge and leave the rest to chance. The winners and the runners-up belonged in this category. While the winners had manged to add a scorpion arm to their robot with a needle at the end that would keep thrusting downward at regular intervals. The runners-up had built a juggernaut with a thick plastic enclosure, so that it would be hard to push them around. The only team apart form us that made use of the camera in the sky, programmed their robot such that it would always move towards the center of the arena, and stay there. They never got around to programming their robot to detect and avoid edges, and that turned out to be their undoing, as they kept getting pushed off the arena.
There were two major mistakes we made that proved the cause of our failure
1. Version control and code management – Classic rookie mistake
Since our team consisted of just two members, we thought that it was not important to use a version control tool like Git. We simply shared with each other a Dropbox folder and started saving our code to it. We did not even discuss any naming schemes for our code. Consequently, what we had was a lot of files with similar names that differed only by a number, and a bunch of unique files named in cryptic riddles (it seemed funny at the time, but it came to bite us back again and again over the week). When we finally started building the final version of the code, we had absolutely no idea as to what files we were really copying from, and what assumptions about the robots wiring was that file written under. If we knew what assumptions any of the programs were written under, we would not have made the mistake of blindly flipping signs of numbers when we saw our motors were not turning in the desired direction. Stronger version control would have made it easy to see what changed between a working and a broken version of the code, and would have saved us the sleepless Saturday night before the competition. It might also have resulted in the robot behaving as planned.
2. Adaptable Mechanical Design
We had designed our chassis to have a strong enclosure so as to protect the hardware from damage. This enclosure had screw holes to fasten it. This is a terrible choice, especially for a hackathon. Basically, every time we needed to change something on the robot, we had to take apart this intricate mess of wires taped to the body and fitted around screw holes, to get to the actual hardware. Because of this, it was very hard to see if some wires on the controller had come lose. Even when we did see it, it was almost impossible to fix.
We would have loved to keep debugging our robot to refine and fix all our mistakes, but the organizers waned us to return all the hardware, and we never got a chance to experiment further.
That is all I have to say about the competition. I thoroughly enjoyed every second of it. OK, perhaps not the last part where our robot lost. However, it was a great opportunity to network with some incredibly enthusiastic people and feel the adrenaline rush of building robots to fight. I would highly encourage all Duke students to check out upcoming hackathons in the area. I can guarantee that you will have fun, and will learn a lot about yourself in the process. HackDuke organizes quite a few every year. You should also check out the Facebook page of Duke Robotics Club to see pictures and videos of the competition, and to stay up to date with their shenanigans.