First Place Solution in Spring 2022 ROAR S1/S2 Series
Written by Aaron Xie, our ROAR ambassador from Campolindo High School, describing his experience and solution for his first place solution in Spring 2022 ROAR S1/S2 Series Competition.
Table of Contents
In this article, I will discuss the solution I used to compete in the ROAR S Series 2022 Spring Race. In previous races, the Berkeley Minor Map was used, but this time the race was held on the newly-created Berkeley Major Map. Since this map was much longer and contained winding roads up and down hills, coming up with a working agent on the Major Map was a much greater challenge.
This solution, similar to the one I used in the last competition, is still based off of the ROAR platform’s PID Agent. A PID (Proportional Integral Derivative) controller is a type of control system that calculates a car’s error from a waypoint and adjusts the steering accordingly. The PID controller has been modified to achieve greater speeds on the map.
My code for this solution is open-source and can be accessed through this link. Parts of this code will be referred to throughout the article.
The Major Map first goes around the UC Berkeley campus, which contains straight roads with 90 degree turns. To maximize the agent’s speed in this region, I set the throttle to max (throttle = 1) until it was necessary to brake at incoming turns. The PID controller calculates an “error” value that measures how far off a car is in comparison to the next waypoint. Once a high enough error is measured, I set my agent to brake as fast as possible until it reaches a speed safe enough to make the narrow turn.
When the map reaches the hills east of Berkeley, the road becomes more unpredictable, featuring several winding turns and large slopes. These conditions make it too dangerous for my current agent to pass this region because the braking mechanism only detects sharp turns, not gradual ones. To solve this issue, I dynamically decreased the throttle as the error increased. This allows the car to slow down and safely make a winding turn without having to brake entirely, optimizing speed.
The hills still pose one more threat to the safety of the agent: bumps on the road. If the car drives too fast past a bump, it can go airborne and fly off the road. To deal with this issue, I created a pitch detector that tells the agent to brake whenever it detects a sharp decrease in pitch (or slope), which is indicative of a dangerous bump on the road.
I also decided to create custom waypoints for the map. Using the pre-existing special agent WaypointGeneratingAgent in the ROAR platform, I manually drove around the map to create a waypoint file, trying my best to plot the waypoints in the center. This way, the waypoints are more forgiving by providing the agent a better chance to stay on the road if it veers off from the waypoint path.
To implement my ideas from above, I first created a new agent called “FastPIDAgent“, which is based off of a copy of the existing PID Agent. I replaced the original longitudinal PID controller (which controls speed) with a simple throttle/brake controller that detects when to brake or slow down from the cases aforementioned in the Strategy section. The throttle/brake controller acquires the turning error value from the latitudinal PID controller (which controls steering), and if the error is great enough, the controller will brake the car until it reaches a safe enough speed.
In the hills, decreasing the throttle is required to safely drive through the winding turns. To do this, I made the throttle decrease when both the error and current speed increased. After a couple tweaks, I found that this formula worked well:
By using a third power function, the throttle does not decrease linearly with the error and current speed. This increases the amount of throttle the car receives, hence optimizing speed.
Lastly, the pitch detector was implemented by making use of the custom waypoint file’s data. Not only did the file record the car’s 3D coordinates, but it also recorded the pitch, yaw, and roll of the car at each coordinate. Since I drove the car slowly while creating the waypoints, we can assume that the pitch of the car accurately reflects the pitch of the road, which is what we need. By extracting the pitch data from the waypoint file and sending it to the controller, I was able to calculate the change in the pitch:
I programmed my controller to brake whenever “delta_pitch” was too great, which enabled my agent to pass through most bumps safely.
The manifestation of my agent’s design was an iterative process, and only after several tests of trial-and-error was I able to create a working implementation. Some major roadblocks I faced were manually tuning the PID values and dealing with unusual corner cases on the road.
To maximize speed, my agent would drive at over 200 kph in the straight roads before coming to a full brake. This meant that, at these dangerously fast speeds, the PID values will have to be very insensitive in order to prevent any slight movements of the car’s steering from drifting it out of control. After some testing, I was able to come up with these working PID values for high speeds (180-300 kph):
In addition to tuning the PID values, there were some exceptional places on the map where the shape of the road was too unique for my agent to handle accordingly. One such example is this sudden jump in the road:
My agent was unable to drive through this part safely, so I had to manually add a brake in this region. To do this, I altered the pitch values at this spot in the waypoint file and set the values to a special code that will tell the controller to make a special exception and brake. There were a couple of other locations similar to this one where I also had to manually add in brake exceptions.
After competing consecutively in 3 ROAR Racing competitions, I feel accomplished to have finally achieved first place. I would like to thank Dr. Allen Yang and Aman Saraf for their assistance during weekly ROAR Ambassador meetings as well as my family for their encouragement. I would not have been able to come this far in learning about the world of artificial intelligence and autonomous driving if it were not for their continued support.
For the next competition, I intend to attempt creating an AI-based agent, using DQN Reinforcement Learning. Even though I have yet to create one yet, I believe that it is now possible with the valuable experience I gained interacting with the ROAR platform in previous competitions.