Robot secondaire
Dependencies: RoboClaw mbed StepperMotor
Fork of RoboClaw by
Odometry/Odometry.cpp@4:3e6e78d6d3d9, 2015-11-24 (annotated)
- Committer:
- sype
- Date:
- Tue Nov 24 21:56:23 2015 +0000
- Revision:
- 4:3e6e78d6d3d9
- Parent:
- 3:62e9d715de65
- Child:
- 10:ae3178aa94e9
Mise en forme
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
sype | 0:ad9600df4a70 | 1 | #include "Odometry.h" |
sype | 0:ad9600df4a70 | 2 | |
sype | 0:ad9600df4a70 | 3 | // M1 = Moteur droit, M2 = Moteur gauche |
sype | 0:ad9600df4a70 | 4 | |
sype | 4:3e6e78d6d3d9 | 5 | Odometry::Odometry(double diameter_right, double diameter_left, double v, RoboClaw &rc) : roboclaw(rc){ |
sype | 0:ad9600df4a70 | 6 | m_v = v; |
sype | 0:ad9600df4a70 | 7 | m_distPerTick_left = diameter_left*PI/37400; |
sype | 0:ad9600df4a70 | 8 | m_distPerTick_right = diameter_right*PI/37400; |
sype | 4:3e6e78d6d3d9 | 9 | |
sype | 3:62e9d715de65 | 10 | roboclaw.ForwardM1(ADR, 0); |
sype | 3:62e9d715de65 | 11 | roboclaw.ForwardM2(ADR, 0); |
sype | 4:3e6e78d6d3d9 | 12 | |
sype | 4:3e6e78d6d3d9 | 13 | // Erreur autorisée sur le déplacement en angle |
sype | 3:62e9d715de65 | 14 | erreur_ang = 0.01; |
sype | 4:3e6e78d6d3d9 | 15 | |
sype | 0:ad9600df4a70 | 16 | m_pulses_right = 0; |
sype | 0:ad9600df4a70 | 17 | m_pulses_left = 0; |
sype | 2:abdf8c6823a1 | 18 | wait_ms(100); |
sype | 0:ad9600df4a70 | 19 | } |
sype | 0:ad9600df4a70 | 20 | |
sype | 4:3e6e78d6d3d9 | 21 | void Odometry::setPos(double x, double y, double theta){ |
sype | 0:ad9600df4a70 | 22 | this->x = x; |
sype | 0:ad9600df4a70 | 23 | this->y = y; |
sype | 0:ad9600df4a70 | 24 | this->theta = theta; |
sype | 0:ad9600df4a70 | 25 | } |
sype | 0:ad9600df4a70 | 26 | |
sype | 4:3e6e78d6d3d9 | 27 | void Odometry::setX(double x){ |
sype | 0:ad9600df4a70 | 28 | this->x = x; |
sype | 0:ad9600df4a70 | 29 | } |
sype | 0:ad9600df4a70 | 30 | |
sype | 4:3e6e78d6d3d9 | 31 | void Odometry::setY(double y){ |
sype | 0:ad9600df4a70 | 32 | this->y = y; |
sype | 0:ad9600df4a70 | 33 | } |
sype | 0:ad9600df4a70 | 34 | |
sype | 4:3e6e78d6d3d9 | 35 | void Odometry::setTheta(double theta){ |
sype | 0:ad9600df4a70 | 36 | this->theta = theta; |
sype | 0:ad9600df4a70 | 37 | } |
sype | 0:ad9600df4a70 | 38 | |
sype | 4:3e6e78d6d3d9 | 39 | void Odometry::update_odo(void){ |
sype | 3:62e9d715de65 | 40 | int32_t delta_right = roboclaw.ReadEncM1(ADR) - m_pulses_right; |
sype | 0:ad9600df4a70 | 41 | m_pulses_right = roboclaw.ReadEncM1(ADR); |
sype | 3:62e9d715de65 | 42 | int32_t delta_left = roboclaw.ReadEncM2(ADR) - m_pulses_left; |
sype | 0:ad9600df4a70 | 43 | m_pulses_left = roboclaw.ReadEncM2(ADR); |
sype | 4:3e6e78d6d3d9 | 44 | |
sype | 0:ad9600df4a70 | 45 | double deltaS = (m_distPerTick_left*delta_left + m_distPerTick_right*delta_right) / 2.0f; |
sype | 2:abdf8c6823a1 | 46 | double deltaTheta = (m_distPerTick_right*delta_right - m_distPerTick_left*delta_left)*C / m_v; |
sype | 4:3e6e78d6d3d9 | 47 | |
sype | 2:abdf8c6823a1 | 48 | double radius = deltaS/deltaTheta; |
sype | 2:abdf8c6823a1 | 49 | double xO = x - radius*sin(theta); |
sype | 2:abdf8c6823a1 | 50 | double yO = y + radius*cos(theta); |
sype | 4:3e6e78d6d3d9 | 51 | |
sype | 0:ad9600df4a70 | 52 | theta += deltaTheta; |
sype | 4:3e6e78d6d3d9 | 53 | |
sype | 2:abdf8c6823a1 | 54 | x = xO + radius*sin(theta); |
sype | 2:abdf8c6823a1 | 55 | y = yO - radius*cos(theta); |
sype | 4:3e6e78d6d3d9 | 56 | |
sype | 0:ad9600df4a70 | 57 | while(theta > PI) theta -= 2*PI; |
sype | 0:ad9600df4a70 | 58 | while(theta <= -PI) theta += 2*PI; |
sype | 0:ad9600df4a70 | 59 | } |
sype | 0:ad9600df4a70 | 60 | |
sype | 4:3e6e78d6d3d9 | 61 | void Odometry::GotoXYT(double x_goal, double y_goal, double theta_goal){ |
sype | 0:ad9600df4a70 | 62 | double theta_ = atan2(y_goal-y, x_goal-x); |
sype | 3:62e9d715de65 | 63 | double dist_ = sqrt(carre(x_goal-x)+carre(y_goal-y)); |
sype | 2:abdf8c6823a1 | 64 | GotoThet(theta_); |
sype | 3:62e9d715de65 | 65 | GotoDist(dist_); |
sype | 0:ad9600df4a70 | 66 | } |
sype | 2:abdf8c6823a1 | 67 | |
sype | 4:3e6e78d6d3d9 | 68 | void Odometry::GotoThet(double theta_) { |
sype | 2:abdf8c6823a1 | 69 | double distance_ticks_left; |
sype | 2:abdf8c6823a1 | 70 | double distance_ticks_right; |
sype | 4:3e6e78d6d3d9 | 71 | |
sype | 4:3e6e78d6d3d9 | 72 | // Le calcul d'erreur est bon (testé), tu peux le vérifier par dessin |
sype | 3:62e9d715de65 | 73 | double erreur_theta = theta_ - getTheta(); |
sype | 3:62e9d715de65 | 74 | bool arrived = false; |
sype | 4:3e6e78d6d3d9 | 75 | |
sype | 3:62e9d715de65 | 76 | while(erreur_theta >= PI) erreur_theta -= 2*PI; |
sype | 2:abdf8c6823a1 | 77 | while(erreur_theta <= -PI) erreur_theta += 2*PI; |
sype | 4:3e6e78d6d3d9 | 78 | |
sype | 4:3e6e78d6d3d9 | 79 | if(erreur_theta <= 0) { |
sype | 2:abdf8c6823a1 | 80 | distance_ticks_left = -(erreur_theta*m_v/2)/m_distPerTick_left; |
sype | 2:abdf8c6823a1 | 81 | distance_ticks_right = (erreur_theta*m_v/2)/m_distPerTick_right; |
sype | 4:3e6e78d6d3d9 | 82 | } else { |
sype | 2:abdf8c6823a1 | 83 | distance_ticks_left = (erreur_theta*m_v/2)/m_distPerTick_left; |
sype | 2:abdf8c6823a1 | 84 | distance_ticks_right = -(erreur_theta*m_v/2)/m_distPerTick_right; |
sype | 2:abdf8c6823a1 | 85 | } |
sype | 3:62e9d715de65 | 86 | pc.printf("TV %3.2f\tTh %3.2f\tET %3.2f\n\r",theta_*180/PI,getTheta()*180/PI,erreur_theta*180/PI); |
sype | 3:62e9d715de65 | 87 | roboclaw.SpeedAccelDeccelPositionM1M2(ADR, 150000, 150000, 100000, (int32_t)distance_ticks_right, 150000, 150000, 100000, (int32_t)distance_ticks_left, 1); |
sype | 4:3e6e78d6d3d9 | 88 | // Il faut ici faire un espèce de bouclage pour vérifier qu'il est bien arrivé, j'avais pensé à : |
sype | 4:3e6e78d6d3d9 | 89 | /* |
sype | 4:3e6e78d6d3d9 | 90 | while(!arrived){ |
sype | 4:3e6e78d6d3d9 | 91 | |
sype | 4:3e6e78d6d3d9 | 92 | } |
sype | 4:3e6e78d6d3d9 | 93 | */ |
sype | 2:abdf8c6823a1 | 94 | } |
sype | 2:abdf8c6823a1 | 95 | |
sype | 4:3e6e78d6d3d9 | 96 | void Odometry::GotoDist(double distance) { |
sype | 3:62e9d715de65 | 97 | double temp1 = roboclaw.ReadEncM1(ADR), temp2 = roboclaw.ReadEncM2(ADR); |
sype | 3:62e9d715de65 | 98 | double distance_ticks_left = distance/m_distPerTick_left - temp2; |
sype | 3:62e9d715de65 | 99 | double distance_ticks_right = distance/m_distPerTick_right - temp1; |
sype | 3:62e9d715de65 | 100 | roboclaw.SpeedAccelDeccelPositionM1M2(ADR, 150000, 200000, 150000, (int32_t)distance_ticks_right, 150000, 200000, 150000, (int32_t)distance_ticks_left, 1); |
sype | 2:abdf8c6823a1 | 101 | } |
sype | 2:abdf8c6823a1 | 102 | |
sype | 4:3e6e78d6d3d9 | 103 | bool Odometry::isArrivedRot(double theta_) { |
sype | 3:62e9d715de65 | 104 | if(abs_d(getTheta()) <= abs_d(theta_+erreur_ang)) return true; |
sype | 3:62e9d715de65 | 105 | else if(abs_d(getTheta()) >= abs_d(theta_-erreur_ang)) return true; |
sype | 2:abdf8c6823a1 | 106 | else return false; |
sype | 2:abdf8c6823a1 | 107 | } |