For this assignment we were asked to develop a program to make a Formula 1 car follow a red line along one or multiple different types of circuits. The car given to us have an RGB camera incorporated in front of it.
The approach to this exercise can be splited into two major blocks:
Image Processing: the data exacted from the image, will have to keep track of the center of the line, and how much is the car deviated from it. Another thing to keep in mind for an improved performance is to know when the car is running on a straight line or if it is taking a curve.
Vehicle Controller: for the controller of the car, we are going to use the famous PID controller just as learned in class. By adjusting it's parameters, we can make the car follow the read line in the smoothest way possible.
Image Processing
For the perception task of the problem, we have to process the following image, which as we can see is quite easy to process thanks to the visually easy to detect red line. As we previously explained, the process consist in adquiring the middle pixel of the red line, and compare it to the middle of the whole image, with this two values, it will be possible to compute the error/deviance between the car direction and the red line.
Going on with the perception algorithm for the image, the process is to analyze a single row from our point of interest. We search inside this row of pixels for those that fall into the red spectrum. The most important values will be the first and the last red pixels and finally, with this values, we can calculate the middle point of the red line between this first and last pixel of the row.
Below, we can have a better look to what is the algorithm doing with the image. As shown in the image, the blue dot will be the center of the red line and the white dot (along the green line) shows the center of the whole image. Finally, the yellow line shows the deviance/error of the car relative to the center of the image.
Now that we have the most important part for the correct functionality of the car, it is a good idea to use multiple controllers for the car to deal with multiple situations differently. For this assignment, we thought of two major situations: when the car is on a straight line or when the car is tackling a curve. The idea for this problem is to detect the frontier, by taking advantage of the simulator itself. By this, we mean that when the car is on a straight line, the image can't detect the wall from the next curve, it shows the "sky". Now, what we do is take this space from the center of the image and analyze the percentage of "sky" detected on this crop.
As we can see in the images below, on the left we have the cropped section of the image showing tha we are very likely to be on a straight line while on the right the possibility of being on a curve is much higher.
Vehicle Controller
The controller is the algorithm that controls the movement of the car so that it follows (in the smoothest way possible) a certain path. This objective is possible thanks to the PID controller, which stands for proporcional, integral and derivative controller. The specifics of the controller is quite extensive but comprehensible, so in this page it will be shown the final formula and the overall effects of the different parts of the controller.
The first step to make when developing the algorithm, is to compute the e error so that we can correct the deviation in order to keep the car on the line. For this, we have to understand the basic functionality of the simulation where the program is tested. Then, playing a little with the simulator, we can easly conclude that it makes the car move to the left when it is given positive values to the angular velocity, and for it to move to the right the values will have to be negative.
To coherently correct the error, we compute it by calculating the difference between the midpoint of the red line respect to the midpoint of the image. Now, when the car moves to the right of the red line, (the midpoint of the red line will be on the left side of the midpoint of the image) the difference will give us a negative value, and cause we said that positive values to the angular velocity make the car turn right, by putting the minus value in front of the formula we get a correction that makes the car move to the left. And viceversa for when it moves to the left of the red line.
With the previous steps, we have calculated the value of correction when the car deviates from the red line. Our next goal is to integrate the logic behind the PID formula to tweak how much we correct the car so that it moves smoothly along the red line. Like we said previously, the PID controller consist of 3 types of controls to adjust:
PROPORTIONAL
The proportional control make the car oscilate proportionaly to the error until it reaches the desired state, meaning that if the error is small, in proportion, the correction will also be small.
DERIVATIVE
The derivative control will make the car move sharply if it separates too much from the red line. Because the derivative is calculated by the difference between the actual and previous error, if the car deviates too suddenly from the red line, it will make a strong correction. On the other hand, regardless of the error if the change is constant, so it will be the derivative control of the car.
INTEGRAL
The integral control corrects the car by accumulation of the error, which gives it a certain consistency when it has a good tunning. But on the contrary, it can cause a rather undesirable inertia to the car which can make it oscilate too suddenly.
Once we have defined and understand all the components of the PID controller, as we saw previously in its formula, each component will have a certain weight to it. This three parameters will be the ones to tune during testing to improve the driving and the timing of the Formula 1 car along different circuits.
For the assignment, we have tune the parameters by hand, and because we have two controllers, one for straight lines and other for curves, we have to try each parameters for each situation.
Testing and results
First, to understand better the parameters and the speed, the code was tested for the Default circuit without the integral part of the PID controller (for it was too much for such slow speeds at first). This test was done at first with only one controller for all the circuit and constant speed to better understand and tune the angular velocity of the car.
Parameters Kp, Kd, Ki | Speed factor | Circuit | Time |
0.001, 0.001, 0 | 1 | Default | 0:08:05 |
0.001, 0.001, 0 | 1.5 | Default | 0:05:36 |
0.001, 0.001, 0 | 2.5 | Default | 0:03:06 |
0.005, 0.01, 0 | 4 | Default | 0:02:00 |
After many attempts tweaking the parameters, we got to a point where barely any improvement could be achieved unless we added more controllers to handle both speed and angular velocity, along with the situations we talked about previously (straight and curve lines). Once we have coded the two controllers and adjusted the parameters, at speeds factors below 9, we have ourself a pretty robust Formula 1 car capable of finishing all the available circuits very quickly.
The speed factor of 10 or even more became very unstable, for it doesn't have a controller capable of dealing with tight curves at such speeds, but with the decreased robustness (by augmenting the speed factor), the car was able to finish the Default circuit in 50 seconds.
Finally, the mos stable algorithm is the one which with a speed factor of 9 can finish the Default circuit in 54 seconds. A video of the run can be seen below.
Comments