Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
sm_servo.cpp@9:1b54bac6d9a7, 2019-10-03 (annotated)
- Committer:
- GaspardD
- Date:
- Thu Oct 03 23:28:56 2019 +0000
- Revision:
- 9:1b54bac6d9a7
- Parent:
- 8:f23601373e8b
- Child:
- 10:e63fe4080760
a tester ;
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
GaspardD | 2:e9d928fd327a | 1 | #include "sm_servo.h" |
GaspardD | 2:e9d928fd327a | 2 | |
GaspardD | 2:e9d928fd327a | 3 | PwmOut pwm_Servo(PE_9); |
GaspardD | 8:f23601373e8b | 4 | |
GaspardD | 8:f23601373e8b | 5 | // declaration des entrées analogiques |
GaspardD | 8:f23601373e8b | 6 | AnalogIn front(PA_5); |
GaspardD | 8:f23601373e8b | 7 | AnalogIn ana_left_90(PA_4); |
GaspardD | 8:f23601373e8b | 8 | AnalogIn ana_right_90(PF_10); |
GaspardD | 8:f23601373e8b | 9 | AnalogIn ana_left_45(PC_0); |
GaspardD | 8:f23601373e8b | 10 | AnalogIn ana_right_45(PF_4); |
GaspardD | 8:f23601373e8b | 11 | AnalogIn ana_left_5(PF_9); |
GaspardD | 8:f23601373e8b | 12 | AnalogIn ana_right_5(PA_6); |
GaspardD | 8:f23601373e8b | 13 | |
GaspardD | 8:f23601373e8b | 14 | AnalogIn analog_value_PF3(PF_3); |
GaspardD | 8:f23601373e8b | 15 | |
GaspardD | 2:e9d928fd327a | 16 | E_STATE_SERVO e_stateServo; |
GaspardD | 3:1b7eb426247e | 17 | bool directionCheck = false; |
GaspardD | 6:ab9f3695633f | 18 | int pulsewidth = SERVO_PULSE_MIDDLE_US;//SERVO_PULSE_MAX_US; |
GaspardD | 2:e9d928fd327a | 19 | |
GaspardD | 8:f23601373e8b | 20 | double d_last_odom_asservissement = 0; |
GaspardD | 8:f23601373e8b | 21 | |
GaspardD | 8:f23601373e8b | 22 | double d_prev_dist_left_90; |
GaspardD | 8:f23601373e8b | 23 | double d_prev_dist_right_90; |
GaspardD | 8:f23601373e8b | 24 | double d_dist_left_90; |
GaspardD | 8:f23601373e8b | 25 | double d_dist_right_90; |
GaspardD | 8:f23601373e8b | 26 | |
GaspardD | 9:1b54bac6d9a7 | 27 | double d_prev_dist_left_45; |
GaspardD | 9:1b54bac6d9a7 | 28 | double d_prev_dist_right_45; |
GaspardD | 9:1b54bac6d9a7 | 29 | double d_dist_left_45; |
GaspardD | 9:1b54bac6d9a7 | 30 | double d_dist_right_45; |
GaspardD | 9:1b54bac6d9a7 | 31 | |
GaspardD | 9:1b54bac6d9a7 | 32 | double d_positionOnTrack; |
GaspardD | 9:1b54bac6d9a7 | 33 | |
GaspardD | 8:f23601373e8b | 34 | double coef_positionnement; |
GaspardD | 8:f23601373e8b | 35 | double coef_angle_correction_bordure; |
GaspardD | 8:f23601373e8b | 36 | double angle_correction_final ; |
GaspardD | 8:f23601373e8b | 37 | double angle_correction_position; |
GaspardD | 8:f23601373e8b | 38 | double angle_correction_bordure; |
GaspardD | 8:f23601373e8b | 39 | double distance_parcourue; |
GaspardD | 8:f23601373e8b | 40 | |
GaspardD | 9:1b54bac6d9a7 | 41 | double ponderation_angle[6]; |
GaspardD | 9:1b54bac6d9a7 | 42 | double d_mediane; |
GaspardD | 9:1b54bac6d9a7 | 43 | double distCapt; |
GaspardD | 8:f23601373e8b | 44 | |
GaspardD | 2:e9d928fd327a | 45 | void init_sm_servo() |
GaspardD | 2:e9d928fd327a | 46 | { |
GaspardD | 2:e9d928fd327a | 47 | e_stateServo = SERVO_INIT; |
GaspardD | 2:e9d928fd327a | 48 | } |
GaspardD | 2:e9d928fd327a | 49 | |
GaspardD | 8:f23601373e8b | 50 | double pwmFromAngle(double angleDeg) |
GaspardD | 8:f23601373e8b | 51 | { |
GaspardD | 8:f23601373e8b | 52 | //on a une regression linéaire entre l'angle et la pwm on centre sur 0 puis on applique |
GaspardD | 9:1b54bac6d9a7 | 53 | pulsewidth = (d_CHASSIS_inversion*angleDeg * 11.0) + SERVO_PULSE_MIDDLE_US; |
GaspardD | 9:1b54bac6d9a7 | 54 | //rs_LOG_pc.printf("pulsewidth = %d =(%f * 11.0) + 1500\r\n",pulsewidth,angleDeg); |
GaspardD | 8:f23601373e8b | 55 | if(pulsewidth > SERVO_PULSE_MAX_US) { |
GaspardD | 8:f23601373e8b | 56 | pulsewidth = SERVO_PULSE_MAX_US; |
GaspardD | 8:f23601373e8b | 57 | } else if(pulsewidth < SERVO_PULSE_MIN_US) { |
GaspardD | 8:f23601373e8b | 58 | pulsewidth = SERVO_PULSE_MIN_US; |
GaspardD | 8:f23601373e8b | 59 | } |
GaspardD | 9:1b54bac6d9a7 | 60 | s_LOG_history[i_LOG_index_data].pwm_dir = pulsewidth; |
GaspardD | 8:f23601373e8b | 61 | return pulsewidth; |
GaspardD | 8:f23601373e8b | 62 | } |
GaspardD | 8:f23601373e8b | 63 | |
GaspardD | 8:f23601373e8b | 64 | |
GaspardD | 8:f23601373e8b | 65 | |
GaspardD | 8:f23601373e8b | 66 | double getDistCapteur(AnalogIn* p) |
GaspardD | 8:f23601373e8b | 67 | { |
GaspardD | 9:1b54bac6d9a7 | 68 | distCapt = 0.182/(double)p->read() ; |
GaspardD | 9:1b54bac6d9a7 | 69 | if (distCapt > 1.5) { |
GaspardD | 9:1b54bac6d9a7 | 70 | distCapt = 1.5 ; |
GaspardD | 9:1b54bac6d9a7 | 71 | } |
GaspardD | 9:1b54bac6d9a7 | 72 | return distCapt ; |
GaspardD | 8:f23601373e8b | 73 | } |
GaspardD | 8:f23601373e8b | 74 | |
GaspardD | 9:1b54bac6d9a7 | 75 | //renvoie un double entre 0 et 1 avec 0 position extrème gauche et 1 extrème droite |
GaspardD | 9:1b54bac6d9a7 | 76 | double positionOnTrack() |
GaspardD | 9:1b54bac6d9a7 | 77 | { |
GaspardD | 9:1b54bac6d9a7 | 78 | d_positionOnTrack = 0.25*(3*(d_dist_left_90/(d_dist_left_90 + d_dist_right_90)) + (d_dist_left_45/(d_dist_left_45 + d_dist_right_45) )); |
GaspardD | 8:f23601373e8b | 79 | |
GaspardD | 9:1b54bac6d9a7 | 80 | return d_positionOnTrack; |
GaspardD | 9:1b54bac6d9a7 | 81 | } |
GaspardD | 8:f23601373e8b | 82 | |
GaspardD | 8:f23601373e8b | 83 | double compute_angle_correction(double consignePos) |
GaspardD | 8:f23601373e8b | 84 | { |
GaspardD | 8:f23601373e8b | 85 | //aquisition |
GaspardD | 9:1b54bac6d9a7 | 86 | coef_positionnement = 0.1;//0.05 |
GaspardD | 8:f23601373e8b | 87 | coef_angle_correction_bordure = 1.0; |
GaspardD | 9:1b54bac6d9a7 | 88 | d_dist_left_90 = getDistCapteur(&ana_left_90) + 0.016; |
GaspardD | 9:1b54bac6d9a7 | 89 | d_dist_right_90 = getDistCapteur(&ana_right_90) + 0.016; |
GaspardD | 9:1b54bac6d9a7 | 90 | d_dist_left_45 = getDistCapteur(&ana_left_45) + 0.042; |
GaspardD | 9:1b54bac6d9a7 | 91 | d_dist_right_45 = getDistCapteur(&ana_right_45) + 0.042; |
GaspardD | 9:1b54bac6d9a7 | 92 | |
GaspardD | 8:f23601373e8b | 93 | |
GaspardD | 8:f23601373e8b | 94 | angle_correction_final = 0.0; |
GaspardD | 8:f23601373e8b | 95 | angle_correction_position = 0.0; |
GaspardD | 8:f23601373e8b | 96 | angle_correction_bordure = 0.0; |
GaspardD | 8:f23601373e8b | 97 | |
GaspardD | 8:f23601373e8b | 98 | update_speed(); |
GaspardD | 8:f23601373e8b | 99 | |
GaspardD | 9:1b54bac6d9a7 | 100 | distance_parcourue = d_ODOM_computed_pos_m - d_last_odom_asservissement ; |
GaspardD | 9:1b54bac6d9a7 | 101 | |
GaspardD | 9:1b54bac6d9a7 | 102 | //left 90 |
GaspardD | 9:1b54bac6d9a7 | 103 | ponderation_angle[0] = atan2( (d_prev_dist_left_90 - d_dist_left_90), distance_parcourue)*57.296 ; |
GaspardD | 9:1b54bac6d9a7 | 104 | //right 90 |
GaspardD | 9:1b54bac6d9a7 | 105 | ponderation_angle[1] = -atan2( (d_prev_dist_right_90 - d_dist_right_90), distance_parcourue)*57.296 ; |
GaspardD | 9:1b54bac6d9a7 | 106 | //left 45 |
GaspardD | 9:1b54bac6d9a7 | 107 | ponderation_angle[2] = atan2( ((d_prev_dist_left_45 - d_dist_left_45)*0.7071), distance_parcourue)*57.296 ; |
GaspardD | 9:1b54bac6d9a7 | 108 | //right 45 |
GaspardD | 9:1b54bac6d9a7 | 109 | ponderation_angle[3] = -atan2( ((d_prev_dist_right_45 - d_dist_right_45)*0.7071), distance_parcourue)*57.296 ; |
GaspardD | 9:1b54bac6d9a7 | 110 | |
GaspardD | 9:1b54bac6d9a7 | 111 | //angle detecte entre le 45 et le 90 gauche |
GaspardD | 9:1b54bac6d9a7 | 112 | ponderation_angle[4] = atan(1.4142*(d_prev_dist_left_90/d_prev_dist_left_45) - 1)*57.296; |
GaspardD | 9:1b54bac6d9a7 | 113 | //rs_LOG_pc.printf("d_prev_dist_left_90:%f,d_prev_dist_left_45:%f;angle cote gauche = %f;angle 90 gauche: %f\n\r",d_prev_dist_left_90,d_prev_dist_left_45,ponderation_angle[4],ponderation_angle[0]); |
GaspardD | 9:1b54bac6d9a7 | 114 | |
GaspardD | 9:1b54bac6d9a7 | 115 | //angle detecte entre le 45 et le 90 droite |
GaspardD | 9:1b54bac6d9a7 | 116 | ponderation_angle[5] = -atan(1.4142*(d_prev_dist_right_90/d_prev_dist_right_45) - 1)*57.296; |
GaspardD | 9:1b54bac6d9a7 | 117 | //rs_LOG_pc.printf("angle cote droit = %f\n\r",ponderation_angle[5] ); |
GaspardD | 9:1b54bac6d9a7 | 118 | |
GaspardD | 9:1b54bac6d9a7 | 119 | |
GaspardD | 9:1b54bac6d9a7 | 120 | //votation |
GaspardD | 9:1b54bac6d9a7 | 121 | bubbleSort(ponderation_angle,6); |
GaspardD | 9:1b54bac6d9a7 | 122 | d_mediane = (ponderation_angle[2] + ponderation_angle[3])*0.5; |
GaspardD | 9:1b54bac6d9a7 | 123 | //si la valeur la plus extreme est le min, on prend juste les 5 dernières valeurs |
GaspardD | 9:1b54bac6d9a7 | 124 | /*if((d_mediane - ponderation_angle[0]) > (ponderation_angle[5] - d_mediane)) { |
GaspardD | 9:1b54bac6d9a7 | 125 | for(int i=1; i<6; i++) { |
GaspardD | 9:1b54bac6d9a7 | 126 | angle_correction_bordure = ponderation_angle[i]; |
GaspardD | 9:1b54bac6d9a7 | 127 | } |
GaspardD | 9:1b54bac6d9a7 | 128 | } else { |
GaspardD | 9:1b54bac6d9a7 | 129 | for(int i=0; i<5; i++) { |
GaspardD | 9:1b54bac6d9a7 | 130 | angle_correction_bordure = ponderation_angle[i]; |
GaspardD | 9:1b54bac6d9a7 | 131 | } |
GaspardD | 9:1b54bac6d9a7 | 132 | } |
GaspardD | 9:1b54bac6d9a7 | 133 | */ |
GaspardD | 9:1b54bac6d9a7 | 134 | angle_correction_bordure = d_mediane; |
GaspardD | 9:1b54bac6d9a7 | 135 | |
GaspardD | 9:1b54bac6d9a7 | 136 | |
GaspardD | 9:1b54bac6d9a7 | 137 | angle_correction_position = atan2((consignePos - positionOnTrack()), (0.04*d_ODOM_speed_mps))*57.296; |
GaspardD | 9:1b54bac6d9a7 | 138 | |
GaspardD | 9:1b54bac6d9a7 | 139 | //rs_LOG_pc.printf("distance_parcourue = %f = %f - %f + 0.001 \n\r",distance_parcourue,d_ODOM_computed_pos_m,d_last_odom_asservissement ); |
GaspardD | 9:1b54bac6d9a7 | 140 | //rs_LOG_pc.printf("angle_correction_bordure = %f = -atan((%f - %f)/ %f) \n\r",angle_correction_bordure,d_prev_dist_left_90,d_dist_left_90,distance_parcourue) ; |
GaspardD | 9:1b54bac6d9a7 | 141 | //rs_LOG_pc.printf("angle_correction_position = %f = atan((%f - %f)/ (0.04* %f ))*57.296,##### TIME: %d\r\n",angle_correction_position,consignePos,d_dist_left_90,d_ODOM_speed_mps,t_utils_timerSinceStart.read_ms()); |
GaspardD | 9:1b54bac6d9a7 | 142 | |
GaspardD | 8:f23601373e8b | 143 | angle_correction_final = angle_correction_position * coef_positionnement + angle_correction_bordure*coef_angle_correction_bordure ; |
GaspardD | 9:1b54bac6d9a7 | 144 | rs_LOG_pc.printf("angle correction: %f;angle correction bordure: %f ;angle correction position: %f\r\n",angle_correction_final,angle_correction_bordure,angle_correction_position); |
GaspardD | 8:f23601373e8b | 145 | |
GaspardD | 8:f23601373e8b | 146 | d_last_odom_asservissement = d_ODOM_computed_pos_m; |
GaspardD | 8:f23601373e8b | 147 | d_prev_dist_left_90 = d_dist_left_90; |
GaspardD | 8:f23601373e8b | 148 | d_prev_dist_right_90 = d_dist_right_90; |
GaspardD | 9:1b54bac6d9a7 | 149 | d_prev_dist_left_45 = d_dist_left_45; |
GaspardD | 9:1b54bac6d9a7 | 150 | d_prev_dist_right_45 = d_dist_right_45; |
GaspardD | 9:1b54bac6d9a7 | 151 | |
GaspardD | 9:1b54bac6d9a7 | 152 | //logging |
GaspardD | 9:1b54bac6d9a7 | 153 | s_LOG_history[i_LOG_index_data].left_90 = d_dist_left_90; |
GaspardD | 9:1b54bac6d9a7 | 154 | s_LOG_history[i_LOG_index_data].right_90 = d_dist_right_90; |
GaspardD | 9:1b54bac6d9a7 | 155 | s_LOG_history[i_LOG_index_data].left_45 = d_dist_left_45; |
GaspardD | 9:1b54bac6d9a7 | 156 | s_LOG_history[i_LOG_index_data].right_45 = d_dist_right_45; |
GaspardD | 9:1b54bac6d9a7 | 157 | s_LOG_history[i_LOG_index_data].odom = d_ODOM_distFromGlobalStart_m; |
GaspardD | 9:1b54bac6d9a7 | 158 | s_LOG_history[i_LOG_index_data].speed = d_ODOM_speed_mps; |
GaspardD | 9:1b54bac6d9a7 | 159 | |
GaspardD | 9:1b54bac6d9a7 | 160 | log_check(); |
GaspardD | 9:1b54bac6d9a7 | 161 | |
GaspardD | 8:f23601373e8b | 162 | return angle_correction_final; |
GaspardD | 8:f23601373e8b | 163 | } |
GaspardD | 8:f23601373e8b | 164 | |
GaspardD | 8:f23601373e8b | 165 | |
GaspardD | 2:e9d928fd327a | 166 | void update_sm_servo() |
GaspardD | 2:e9d928fd327a | 167 | { |
GaspardD | 3:1b7eb426247e | 168 | E_STATE_SERVO next_state = e_stateServo; |
GaspardD | 2:e9d928fd327a | 169 | |
GaspardD | 2:e9d928fd327a | 170 | switch(e_stateServo) { |
GaspardD | 2:e9d928fd327a | 171 | case SERVO_INIT: |
GaspardD | 3:1b7eb426247e | 172 | if(directionCheck) { |
GaspardD | 3:1b7eb426247e | 173 | next_state = SERVO_COMMAND; |
GaspardD | 3:1b7eb426247e | 174 | } |
GaspardD | 2:e9d928fd327a | 175 | break; |
GaspardD | 2:e9d928fd327a | 176 | case SERVO_COMMAND: |
GaspardD | 8:f23601373e8b | 177 | //si on detecte une nouvelle acquisition, on traite le signal |
GaspardD | 8:f23601373e8b | 178 | d_dist_left_90 = getDistCapteur(&ana_left_90); |
GaspardD | 9:1b54bac6d9a7 | 179 | //rs_LOG_pc.printf("d_dist_left_90 : %f;d_dist_right_90 : %f;d_positionOnTrack: %f\r\n",d_dist_left_90,d_dist_right_90,d_positionOnTrack); |
GaspardD | 8:f23601373e8b | 180 | if(d_dist_left_90 != d_prev_dist_left_90) { |
GaspardD | 8:f23601373e8b | 181 | |
GaspardD | 9:1b54bac6d9a7 | 182 | //rs_LOG_pc.printf("compute angle et updateSpeed\r\n"); |
GaspardD | 8:f23601373e8b | 183 | pulsewidth = pwmFromAngle( compute_angle_correction(s_UTILS_currentSection->consigne_position) ); |
GaspardD | 8:f23601373e8b | 184 | |
GaspardD | 8:f23601373e8b | 185 | d_prev_dist_left_90 = d_dist_left_90; |
GaspardD | 8:f23601373e8b | 186 | |
GaspardD | 8:f23601373e8b | 187 | } |
GaspardD | 8:f23601373e8b | 188 | |
GaspardD | 8:f23601373e8b | 189 | |
GaspardD | 2:e9d928fd327a | 190 | break; |
GaspardD | 2:e9d928fd327a | 191 | default: |
GaspardD | 3:1b7eb426247e | 192 | break; |
GaspardD | 3:1b7eb426247e | 193 | } |
GaspardD | 2:e9d928fd327a | 194 | |
GaspardD | 2:e9d928fd327a | 195 | e_stateServo = next_state; |
GaspardD | 2:e9d928fd327a | 196 | return; |
GaspardD | 2:e9d928fd327a | 197 | } |
GaspardD | 2:e9d928fd327a | 198 | |
GaspardD | 2:e9d928fd327a | 199 | void output_sm_servo() |
GaspardD | 2:e9d928fd327a | 200 | { |
GaspardD | 3:1b7eb426247e | 201 | switch(e_stateServo) { |
GaspardD | 3:1b7eb426247e | 202 | case SERVO_INIT: |
GaspardD | 9:1b54bac6d9a7 | 203 | rs_LOG_pc.printf("init servo with pulse %d us\r\n",SERVO_PULSE_MIDDLE_US); |
GaspardD | 3:1b7eb426247e | 204 | pwm_Servo.period_ms(SERVO_PERIOD_DURATION_MS); |
GaspardD | 3:1b7eb426247e | 205 | pwm_Servo.pulsewidth_us(SERVO_PULSE_MIDDLE_US); |
GaspardD | 3:1b7eb426247e | 206 | directionCheck = true; |
GaspardD | 3:1b7eb426247e | 207 | break; |
GaspardD | 3:1b7eb426247e | 208 | case SERVO_COMMAND: |
GaspardD | 9:1b54bac6d9a7 | 209 | //pwm_Servo.pulsewidth_us(pulsewidth); |
GaspardD | 9:1b54bac6d9a7 | 210 | pwm_Servo.pulsewidth_us(SERVO_PULSE_MIDDLE_US); |
GaspardD | 4:efa207509f63 | 211 | |
GaspardD | 3:1b7eb426247e | 212 | break; |
GaspardD | 3:1b7eb426247e | 213 | default: |
GaspardD | 3:1b7eb426247e | 214 | break; |
GaspardD | 3:1b7eb426247e | 215 | } |
GaspardD | 3:1b7eb426247e | 216 | return; |
GaspardD | 2:e9d928fd327a | 217 | } |