By Peize Fen, Hang Du, and Shanlin Sun
This is the story about how the three of us (Peize, Hang, and Shanlin) won a self-driving car competition with no previous experience. And also about how you can do the same.
Last semester one of our PhD students, Valeriu Balaban, with the support of our department and the Ming Hsieh Institute, organized a competition called Race On. The idea was to give masters and undergrads real hands on work with computer vision, control, and self-driving car related algorithms. This is a really important area for students because a lot of jobs today expect us to have some experience in this field, so we decided to join as a team.
Each team was given a self-driving model car kit (paid for by the Ming Hsieh Institute), and basic instructions on how to build the car. Our job was to come up with the best algorithms and parameters possible to run our car on a track. After months of work we ended up winning the entire competition. So how did we do it and what did we learn along the way?
Self-Driving Car Assembly
Before we could even begin with the high-tech work, we had to assemble the car – a much harder task that we had anticipated. We used all kinds of tools: hammers, pliers, screwdrivers - even a soldering iron! Along the way, we managed to ruin our first set of tires by covering them in glue and broke the front fender by crashing into a wall on our very first test-run.
Coding and Algorithms
Eventually we got the car built. At the pre-race workshops run by Valeriu, we learned how to control the camera and the movement of the car. Next, we built an algorithm that can detect the track from camera images. To test the algorithm, we wrote a program that controls the car manually from a keyboard. This let us monitor the front view in real-time and compare with the output of our algorithm. Once the track detection algorithm was ready, we coupled it with a simple PID controller to always keep the car in the middle of the track.
We talked a lot as a team about how to make our car recognize the track reliably at high speeds. We ran the car many times with different configurations, analyzing the car’s performance each time to predict what values to use in the next run. We eventually realized we might have reached maximum efficiency. We had to find a new solution.
More Tweaks and the New Algorithm
We then implemented a modified version of a PID controller that adjusted the response automatically at different speeds. Again, each new test run presented new problems. This is one of the best and challenging things about engineering: the more you learn, the more challenges always face you.
We had to switch out our original algorithm and replace it with one that could better detect the track at high speed. We also added more blocks of code to patch the other problems that kept popping up. Finally, we were able to create a mechanism to improve the robustness of track detection. As the final detail, to make our car ignore small deviation errors from the planned trajectory but quickly respond to big deviations, we designed a quadratic cost function of these deviations which the controller was working to bring to zero and thus precisely follow the planned trajectory.
The Final Competition
Seeing our lap time decrease little by little motivated us to do more. On the night before the final check, we didn’t sleep. We still believed we could make our little car faster. We changed our algorithms and adjusted our parameters again and again until we felt there was nothing more we could do.
When the race started, the room was filled with dozens of teams. We had three attempts to record the fastest time. First attempt: 14.7 seconds. Good but not fast enough to win. Adjusted some parameters, next run: 15.26 seconds. Not what we expected! We changed the algorithm parameters again. Our self-driving car finished its run just as we expected, 13.72 seconds – the fastest lap of the competition. All of our effort had paid off. We hadn’t been this excited in years!
And Most Importantly...What Did We Learn??
We experienced coding on Raspberry Pi and we also gained a huge amount of hardware experience – something that was really useful to us as ECE students. More importantly, we learned a lot of lessons about success. First, we discovered how valuable having a good team is. When one of us was struggling, we had the others there to inspire and motivate us. By working together, we were able to do more than we ever could have alone.
We also learned about communicating and coding as a team. People sometimes think of coding as a solitary practice coding together as a group has given us some real skills for our futures.
Finally, we learned how to be practical. What do we mean by that? In school we usually learn about the best way to do something. But in the real world you’re often constrained by things like time and resources. Sometimes you have to choose a method that is the most suitable to your situation, even if it’s not the best on paper. We didn’t win this competition because we were smarter than everyone else. We won because we worked together, were never satisfied with our first result, and approached the challenge with confidence and practicality. This is the best advice we can give to future engineers, no matter what the challenge is!
Hang, Peize, and Shanlin graduated from the Ming Hsieh Department of Electrical and Computer Engineering Master's Program in Spring of 2019.