Processing
This service follows the following steps:
- It reads a
CameraSensorOutput
message from thepath
stream as defined in the service.yaml file - This message should contain one or more
HorizontalScan
objects. These horizontal scans represent the edges of the track (soxLeft
is the left edge, andxRight
is the right edge) - The
xLeft
andxRight
positions are normalized between 0 and 100.0 based on theresolution
reported by theimaging
service - Then, the mid point (between
xLeft
andxRight
) is taken. This should be at 50.0 when the Rover is on the middle of the track. The difference between the desired value (50.0) and the actual value is called the error. The error is scaled and passed to a PID controller to decide how much to steer the front wheels, and in which direction - Finally, the steering value and acceleration values are encoded in the
ControllerOutput
message, which is written to thedecision
stream
What is a PID Controller?
PID stands for Proportional Integral Derivative, and in context of this application, it aims to remain as close as possible to the calculated center of the track. Before making the decision which way to turn, the controller takes into consideration all 3 terms with equal weight and acts based on the result. Below is a short description of each of the terms:
- Proportional - considers the current error, i.e. the distance between the observed center of the track and where the car currently is.
- Integral - takes the cummulative error over time, not just the current one like the Proportional term. It would try to steer the car towards the center also if it observes a small error present over a longer period of time, whereas Proportional would not make a significant enough adjustment.
- Derivative - works by taking the difference between the measured errors and divides it by the change in time. This allows it to see how fast the error is changing. While Proportional term takes into account the current value, Integral - past, Derivative tries to predict the future errors.
Each of the terms can, of course, be used as a standalone controller by itself, but it is unlikely to yield a better result. You can find a more detailed description of the mechanism here, or a very detailed description here.