
Download the source code (Please register before proceeding to download)
You can compile the code I propose in this page using Xamarin Studio 5.10.1 (Build 6), with Mono 4.2.1 as active runtime and the Monobrick Firmware Library 1.2.0.39486 to let it work on board the Lego Mindstorms Ev3 with the Monobrick firmware.
The source code above is happily shared under the Code Project Open Licence (CPOL) 1.02.
← Part 1 – The track following problem
→ Part 3 – The (simple) code architecture
The control strategy
As discussed in Part 1, the task of keeping the vehicle on the track can be translated in maintaining the feedback of the Ev3 Color sensor on a predefined set point .
To achieve this goal, assuming that we want that the vehicle follows the left edge of a black stripe on a light grey floor, we program the vehicle to steer to the left if the sensor feedback value is smaller than the set point (the vehicle is mostly on the black stripe) and to steer to the right if the feedback is instead greater than the set point (the vehicle is mostly on the floor).
The strategy is then to design two nested control loops. The external loop, I call it the Drive loop, determines how much to steer and in which direction; the internal loop, I call it the Steer loop, takes the input from the external loop and steer accordingly.

The picture above represents the strategy where:
is the reflected light set point; the vehicle will steer to keep the sensor readings as close to this value as possible;
is the proportional controller that computes how much to steer to compensate for the track following error;
is the output of the
controller, and it is the set point for the
proportional integrative controller;
is the output of the
controller, and it is the torque requested to the Ev3 Medium Motor to steer;
is the Ev3 Medium Motor;
is the vehicle equipped with the Ev3 Color Sensor
;
is the Ev3 Medium Motor tachometer;
is the Ev3 Color Sensor in reflected light mode;
is the reading of Ev3 Medium Motor tachometer;
is the reading of Ev3 Color Sensor.
Here are the parameters I have chosen for the Drive loop, which is a proportional controller with a saturation , a dead band
and a sample time
:
,
,
,
,
.
And for the Steer loop, which is instead a proportional integrative controller with a saturation and a sample time $latex T_{s1}$:
,
,
,
.
← Part 1 – The track following problem
→ Part 3 – The (simple) code architecture