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:

$$ T(s) = \dfrac{1}{s^2+2s+1} $$

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.

This structure, since it doesn't add zeros or poles, for positive value of K, the system is always observable, controllable and stable. In fact, if a system defined by a transfer function $$ T(s) = \dfrac{1}{\prod_{i=0} ^ n (s-z_i)} $$ using proportional controller, the complete system is stable $$ H(s) = \dfrac{K T(s)}{1+K T(s)} $$

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;
}