2014 Eurobot fork

Dependencies:   mbed-rtos mbed QEI

Committer:
madcowswe
Date:
Wed Apr 10 20:06:29 2013 +0000
Revision:
34:e1678450feec
Parent:
33:a49197572737
Child:
36:34f4b38039bb
gains a bit more decent

Who changed what in which revision?

UserRevisionLine numberNew contents of line
rsavitski 24:50805ef8c499 1 ////////////////////////////////////////////////////////////////////////////////
rsavitski 24:50805ef8c499 2 // Motion control unit
rsavitski 24:50805ef8c499 3 ////////////////////////////////////////////////////////////////////////////////
rsavitski 24:50805ef8c499 4 // Takes current state of the robot and target waypoint,
rsavitski 24:50805ef8c499 5 // calculates desired forward and angular velocities and requests those from the motor control layer.
rsavitski 24:50805ef8c499 6 ////////////////////////////////////////////////////////////////////////////////
rsavitski 24:50805ef8c499 7
rsavitski 24:50805ef8c499 8 #include "motion.h"
rsavitski 24:50805ef8c499 9
rsavitski 24:50805ef8c499 10 namespace motion
rsavitski 24:50805ef8c499 11 {
rsavitski 24:50805ef8c499 12
rsavitski 24:50805ef8c499 13 void motionlayer(void const *dummy)
rsavitski 30:791739422122 14 {
rsavitski 24:50805ef8c499 15 // get target waypoint from AI
rsavitski 24:50805ef8c499 16 Waypoint target_waypoint = *AI::current_waypoint;
rsavitski 24:50805ef8c499 17
rsavitski 24:50805ef8c499 18 // get current state from Kalman
rsavitski 24:50805ef8c499 19 State current_state = Kalman::getState();
rsavitski 24:50805ef8c499 20
rsavitski 24:50805ef8c499 21 float delta_x = target_waypoint.x - current_state.x;
rsavitski 24:50805ef8c499 22 float delta_y = target_waypoint.y - current_state.y;
rsavitski 24:50805ef8c499 23
madcowswe 25:b16f1045108f 24 //printf("motion sees deltax: %f deltay %f\r\n", delta_x, delta_y);
rsavitski 24:50805ef8c499 25
madcowswe 25:b16f1045108f 26 float distance_err = hypot(delta_x, delta_y);
madcowswe 25:b16f1045108f 27
madcowswe 25:b16f1045108f 28 float angle_err = constrainAngle(atan2(delta_y, delta_x) - current_state.theta);
rsavitski 24:50805ef8c499 29
rsavitski 30:791739422122 30 // is the waypoint reached
rsavitski 30:791739422122 31 if (distance_err < target_waypoint.pos_threshold)
rsavitski 30:791739422122 32 {
rsavitski 30:791739422122 33 distance_err = 0;
madcowswe 33:a49197572737 34 angle_err = constrainAngle(target_waypoint.theta - current_state.theta);
madcowswe 33:a49197572737 35
madcowswe 33:a49197572737 36 if (abs(angle_err) < target_waypoint.angle_threshold)
madcowswe 33:a49197572737 37 {
madcowswe 33:a49197572737 38 angle_err = 0;
madcowswe 33:a49197572737 39 }
rsavitski 30:791739422122 40 }
madcowswe 33:a49197572737 41
rsavitski 30:791739422122 42
rsavitski 30:791739422122 43 AI::waypoint_flag_mutex.lock(); // proper way would be to construct a function to evaluate the condition and pass the function pointer to a conditional setter function for reached flag
rsavitski 30:791739422122 44 if (distance_err == 0 && angle_err == 0)
rsavitski 30:791739422122 45 {
rsavitski 30:791739422122 46 AI::setWaypointReached();
rsavitski 30:791739422122 47 return;
rsavitski 30:791739422122 48 }
rsavitski 30:791739422122 49 AI::waypoint_flag_mutex.unlock();
rsavitski 24:50805ef8c499 50
rsavitski 24:50805ef8c499 51 // angular velocity controller
madcowswe 34:e1678450feec 52 const float p_gain_av = 0.5; //TODO: tune
rsavitski 24:50805ef8c499 53
madcowswe 33:a49197572737 54 const float max_av = 0.5*PI; // radians per sec //TODO: tune
rsavitski 24:50805ef8c499 55
rsavitski 24:50805ef8c499 56 // angle error [-pi, pi]
rsavitski 24:50805ef8c499 57 float angular_v = p_gain_av * angle_err;
rsavitski 24:50805ef8c499 58
rsavitski 24:50805ef8c499 59 // constrain range
rsavitski 24:50805ef8c499 60 if (angular_v > max_av)
rsavitski 24:50805ef8c499 61 angular_v = max_av;
rsavitski 24:50805ef8c499 62 else if (angular_v < -max_av)
rsavitski 24:50805ef8c499 63 angular_v = -max_av;
rsavitski 24:50805ef8c499 64
rsavitski 24:50805ef8c499 65
rsavitski 24:50805ef8c499 66 // forward velocity controller
madcowswe 34:e1678450feec 67 const float p_gain_fv = 0.5; //TODO: tune
rsavitski 24:50805ef8c499 68
madcowswe 25:b16f1045108f 69 float max_fv = 0.2; // meters per sec //TODO: tune
rsavitski 24:50805ef8c499 70 const float angle_envelope_exponent = 8.0; //TODO: tune
rsavitski 24:50805ef8c499 71
rsavitski 24:50805ef8c499 72 // control, distance_err in meters
rsavitski 24:50805ef8c499 73 float forward_v = p_gain_fv * distance_err;
rsavitski 24:50805ef8c499 74
rsavitski 24:50805ef8c499 75 // control the forward velocity envelope based on angular error
rsavitski 24:50805ef8c499 76 max_fv = max_fv * pow(cos(angle_err/2), angle_envelope_exponent);
rsavitski 24:50805ef8c499 77
rsavitski 24:50805ef8c499 78 // constrain range
rsavitski 24:50805ef8c499 79 if (forward_v > max_fv)
rsavitski 24:50805ef8c499 80 forward_v = max_fv;
rsavitski 24:50805ef8c499 81 else if (forward_v < -max_fv)
rsavitski 24:50805ef8c499 82 forward_v = -max_fv;
madcowswe 25:b16f1045108f 83
madcowswe 25:b16f1045108f 84 //printf("fwd: %f, omega: %f\r\n", forward_v, angular_v);
rsavitski 24:50805ef8c499 85
rsavitski 30:791739422122 86 // pass values to the motor control
rsavitski 24:50805ef8c499 87 MotorControl::set_fwdcmd(forward_v);
madcowswe 25:b16f1045108f 88 MotorControl::set_omegacmd(angular_v);
rsavitski 24:50805ef8c499 89 }
rsavitski 24:50805ef8c499 90
rsavitski 24:50805ef8c499 91 } //namespace