Movement
How can we make the robot move? How can we be sure about its accuracy?
Movement
The robot embeds two tacho class engines, which can be programmed using commands to the relative drivers.
The issue with engines and movement in general is the big statistical variance of results of the same command performed on different environments. For instance, turning around on a carpet or in perfectly smooth floor has different effects due to the inertia attenuation of the two materials. So, the question we asked ourselves is: how can we be sure to obtain the expected result?
Digital controller
A little of math behind control theory
The simplest model to describe the dynamic behaviour of the position of the robot is presented in the following formula:
Of course, this is a simplistic rappresentation which does not take into account a lot of parameters and features of the real system under test: it's in just the basic model used to evaluate different control strategies.
The plot on the left shows the response of the model to a constant input (which in our case rappresents the evolution of the position over time).
To implement this control, we used a well known stategy in control theory: a proportional feedback in closed-loop.
In our implemetation, we simply choose K = 1 (i.e. engines are driven by the error itself).
Implementation
Here we propose you some pseudocode that might help you in understand how our robot can move.
In the following, we're showing how it can rotate and self-adjust if the rotation, for some reason, was not complete.
void turn_inplace_by_relative_angle(int16_t angle, int16_t speed){
robot_status = running;
error = angle;
read initial_orientation;
do {
// turn the right motor for (-error) degrees;
pthread_create(&right_tid, NULL, __turn_engine_by_angle, (void*)&right_engine_args);
// turn the left motor for (+error) degrees;
pthread_create(&left_tid, NULL, __turn_engine_by_angle, (void*)&left_engine_args);
wait for their termination;
read current_orientation;
error = angle - (final_orientation - initial_orientation);
} while (error > 1);
robot_status = not_running;
}