Second Place Solution in Summer 2023 Simulation Racing Series
Written by Mark Menaker, Arvind Krishna Sivakumar, Saul Statman
GitHub: https://github.com/ROARInventors/CarCode
Table of Contents
Introduction
The Summer 2023 ROAR S1/S2 Series Challenge is an autonomous racing competition held by the University of California, Berkeley. Competitors use Python to automate a simulated Tesla Model 3 in the virtual Carla research environment, which was developed for the testing of self-driving car algorithms. We raced on the Berkley Major v4 map this year. Unfortunately, this will be the last year on this map, but there is some valuable advice that can still be used in the next competition regardless of the map itself.In this article, we will discuss how our team improved upon the previous solution developed by Aaron Xie, resulting in 26.4 seconds faster lap time.
Main Changes
We did not modify the latitudinal controller responsible for steering and instead focused on the longitudinal controller which produced throttle and brake values. We were looking for a general solution which can work for other tracks, but were only partially successful in that. Due to limited time we decided to add track-specific workarounds to make sure the car was ready to race on time.
General Part of the Solution
Our main change to the code was to make the throttle setting depend on a target speed instead of on the direction error. Throttle was previously set based on current speed and 2 direction errors (one to a close point and one to a far point), but we decided to change this. Instead, we used 3 specifically chosen waypoints ahead to compute the radius of an upcoming turn (we found the Menger curvature formula to be very helpful). Using the radius and the formula forcentripetal acceleration
we were able to compute the maximum allowable speed by setting max acceleration to
From there, we were able to mathematically compute the maximum allowable speed at the current location (since we knew the distance to the start of the turn and how fast the car can decelerate). We repeated this procedure by analyzing the upcoming turn for 3 different distances ahead (0, 30, 60 meters) which produced 3 speed values. We chose the smallest of the 3 speeds as the safe max allowable speed at the current point.
Knowing the max allowable speed enabled us to fine-tune our settings for throttle and brake. After trying several strategies, we settled on the following. If the current speed was over the max allowable speed by a certain amount, we applied full brakes, but if it was under, we kept full throttle. If the current speed was within a few % of allowable speed we would use less-than-full throttle with a goal of maintaining speed without overshooting too far.
Track-specific workarounds
Converting brake points to slow-down points
One of the challenges of this track is the uneven character of the surface in the z-direction. Going over bumps or dips too fast makes the car fly off the track. Aaron Xie’s solution dealt with this challenge by listing a set of waypoints indicating the “brake points”, locations where the brake was applied for a fixed amount of time. However, this did not work well for us, because every time we made improvements, the car would arrive at the “brake points” with different speed. As a result, we had to constantly test and change the amount of brake to be applied. After revising brake amounts a few times we looked for a new and better approach. We decided that instead of indicating how much brake to apply at each “brake point” we can specify the target speed for each of the “slow-down points”. Then we let the car (algorithm described above) decide when to apply the brake and for how long. This was possible because of our previous work which made the car respect the target speed. It turned out that some of the brake points became unnecessary and we were able to reduce the number of special cases from 13 “brake points” to 7 “slow-down” points.
Generating waypoints
We wanted to update waypoints to follow a good racing line, but we had difficulty generating new waypoints. None of us had a joystick and driving the car with arrow keys did not produce a good racing line
Luckily, we found a promising idea by browsing existing code in smooth_waypoint_following_local_planner.py. This code is “averaging” locations of the next 400 waypoints to produce 1 new smoothed waypoint. After experimenting with the code we realized that the car became more aggressive in the turns (good!). It turned-in sooner and followed a better racing line, closer to the inside. We also noticed that averaging 400 points was too much, the car was hitting the side of the road before the turn. By experimentation we found a suitable number of points to average and kept this code since it improved the overall result.
Tuning the Braking
One thing our team noticed when running the simulator was that the car was braking very suddenly. The fastest way to take a corner is to break lightly then increase the break as we approach the corner and let go gradually as we get to the apex and swap with the accelerator gradually. The previous code had only an on or off setting so it would get close enough and fully brake and fully let go of the throttle. This increased the time it takes to accelerate out of the corner.
Debugging
We found it very helpful to add print statements to print detailed information about the state of our controller. It allowed us to trace how we produced values for throttle and brake. In one instance, we were repeatedly adjusting steering parameters Kp, Ki, Kd and observing that the car was alternating between turning too much and turning too little. After enabling debugging statements it became apparent that the car was turning at much higher speed than the computed maximum for that turn. So, what was challenging to fix with steering changes, turned out to be a speed problem that was corrected by adjusting speed control logic.
Debugging
We were surprised to see gear changes in the previous solution, since Teslas have a 1-speed direct-drive transmission. We tested the code without the gear changes (always setting gear = 1) and realized that the car became slower! As a result we decided to keep this excellent (even if unrealistic) find introduced by Daniel Chuang.
Conclusion
Thank you very much Dr. Allen Yang and your team of experts for ROAR Academy, and all the effort put into the inspiring in-person weekend at Berkeley. The in-person sessions were great to get a deeper understanding on more complex real world applications of AI, and it was also very nice to connect in real life with our teammates and other students. We enjoyed participating in the summer competition and found it to be a valuable learning experience to expand our knowledge and skills.