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
- Committer:
- GaspardD
- Date:
- 2019-10-03
- Revision:
- 9:1b54bac6d9a7
- Parent:
- 8:f23601373e8b
- Child:
- 10:e63fe4080760
File content as of revision 9:1b54bac6d9a7:
#include "sm_servo.h" PwmOut pwm_Servo(PE_9); // declaration des entrées analogiques AnalogIn front(PA_5); AnalogIn ana_left_90(PA_4); AnalogIn ana_right_90(PF_10); AnalogIn ana_left_45(PC_0); AnalogIn ana_right_45(PF_4); AnalogIn ana_left_5(PF_9); AnalogIn ana_right_5(PA_6); AnalogIn analog_value_PF3(PF_3); E_STATE_SERVO e_stateServo; bool directionCheck = false; int pulsewidth = SERVO_PULSE_MIDDLE_US;//SERVO_PULSE_MAX_US; double d_last_odom_asservissement = 0; double d_prev_dist_left_90; double d_prev_dist_right_90; double d_dist_left_90; double d_dist_right_90; double d_prev_dist_left_45; double d_prev_dist_right_45; double d_dist_left_45; double d_dist_right_45; double d_positionOnTrack; double coef_positionnement; double coef_angle_correction_bordure; double angle_correction_final ; double angle_correction_position; double angle_correction_bordure; double distance_parcourue; double ponderation_angle[6]; double d_mediane; double distCapt; void init_sm_servo() { e_stateServo = SERVO_INIT; } double pwmFromAngle(double angleDeg) { //on a une regression linéaire entre l'angle et la pwm on centre sur 0 puis on applique pulsewidth = (d_CHASSIS_inversion*angleDeg * 11.0) + SERVO_PULSE_MIDDLE_US; //rs_LOG_pc.printf("pulsewidth = %d =(%f * 11.0) + 1500\r\n",pulsewidth,angleDeg); if(pulsewidth > SERVO_PULSE_MAX_US) { pulsewidth = SERVO_PULSE_MAX_US; } else if(pulsewidth < SERVO_PULSE_MIN_US) { pulsewidth = SERVO_PULSE_MIN_US; } s_LOG_history[i_LOG_index_data].pwm_dir = pulsewidth; return pulsewidth; } double getDistCapteur(AnalogIn* p) { distCapt = 0.182/(double)p->read() ; if (distCapt > 1.5) { distCapt = 1.5 ; } return distCapt ; } //renvoie un double entre 0 et 1 avec 0 position extrème gauche et 1 extrème droite double positionOnTrack() { 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) )); return d_positionOnTrack; } double compute_angle_correction(double consignePos) { //aquisition coef_positionnement = 0.1;//0.05 coef_angle_correction_bordure = 1.0; d_dist_left_90 = getDistCapteur(&ana_left_90) + 0.016; d_dist_right_90 = getDistCapteur(&ana_right_90) + 0.016; d_dist_left_45 = getDistCapteur(&ana_left_45) + 0.042; d_dist_right_45 = getDistCapteur(&ana_right_45) + 0.042; angle_correction_final = 0.0; angle_correction_position = 0.0; angle_correction_bordure = 0.0; update_speed(); distance_parcourue = d_ODOM_computed_pos_m - d_last_odom_asservissement ; //left 90 ponderation_angle[0] = atan2( (d_prev_dist_left_90 - d_dist_left_90), distance_parcourue)*57.296 ; //right 90 ponderation_angle[1] = -atan2( (d_prev_dist_right_90 - d_dist_right_90), distance_parcourue)*57.296 ; //left 45 ponderation_angle[2] = atan2( ((d_prev_dist_left_45 - d_dist_left_45)*0.7071), distance_parcourue)*57.296 ; //right 45 ponderation_angle[3] = -atan2( ((d_prev_dist_right_45 - d_dist_right_45)*0.7071), distance_parcourue)*57.296 ; //angle detecte entre le 45 et le 90 gauche ponderation_angle[4] = atan(1.4142*(d_prev_dist_left_90/d_prev_dist_left_45) - 1)*57.296; //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]); //angle detecte entre le 45 et le 90 droite ponderation_angle[5] = -atan(1.4142*(d_prev_dist_right_90/d_prev_dist_right_45) - 1)*57.296; //rs_LOG_pc.printf("angle cote droit = %f\n\r",ponderation_angle[5] ); //votation bubbleSort(ponderation_angle,6); d_mediane = (ponderation_angle[2] + ponderation_angle[3])*0.5; //si la valeur la plus extreme est le min, on prend juste les 5 dernières valeurs /*if((d_mediane - ponderation_angle[0]) > (ponderation_angle[5] - d_mediane)) { for(int i=1; i<6; i++) { angle_correction_bordure = ponderation_angle[i]; } } else { for(int i=0; i<5; i++) { angle_correction_bordure = ponderation_angle[i]; } } */ angle_correction_bordure = d_mediane; angle_correction_position = atan2((consignePos - positionOnTrack()), (0.04*d_ODOM_speed_mps))*57.296; //rs_LOG_pc.printf("distance_parcourue = %f = %f - %f + 0.001 \n\r",distance_parcourue,d_ODOM_computed_pos_m,d_last_odom_asservissement ); //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) ; //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()); angle_correction_final = angle_correction_position * coef_positionnement + angle_correction_bordure*coef_angle_correction_bordure ; 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); d_last_odom_asservissement = d_ODOM_computed_pos_m; d_prev_dist_left_90 = d_dist_left_90; d_prev_dist_right_90 = d_dist_right_90; d_prev_dist_left_45 = d_dist_left_45; d_prev_dist_right_45 = d_dist_right_45; //logging s_LOG_history[i_LOG_index_data].left_90 = d_dist_left_90; s_LOG_history[i_LOG_index_data].right_90 = d_dist_right_90; s_LOG_history[i_LOG_index_data].left_45 = d_dist_left_45; s_LOG_history[i_LOG_index_data].right_45 = d_dist_right_45; s_LOG_history[i_LOG_index_data].odom = d_ODOM_distFromGlobalStart_m; s_LOG_history[i_LOG_index_data].speed = d_ODOM_speed_mps; log_check(); return angle_correction_final; } void update_sm_servo() { E_STATE_SERVO next_state = e_stateServo; switch(e_stateServo) { case SERVO_INIT: if(directionCheck) { next_state = SERVO_COMMAND; } break; case SERVO_COMMAND: //si on detecte une nouvelle acquisition, on traite le signal d_dist_left_90 = getDistCapteur(&ana_left_90); //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); if(d_dist_left_90 != d_prev_dist_left_90) { //rs_LOG_pc.printf("compute angle et updateSpeed\r\n"); pulsewidth = pwmFromAngle( compute_angle_correction(s_UTILS_currentSection->consigne_position) ); d_prev_dist_left_90 = d_dist_left_90; } break; default: break; } e_stateServo = next_state; return; } void output_sm_servo() { switch(e_stateServo) { case SERVO_INIT: rs_LOG_pc.printf("init servo with pulse %d us\r\n",SERVO_PULSE_MIDDLE_US); pwm_Servo.period_ms(SERVO_PERIOD_DURATION_MS); pwm_Servo.pulsewidth_us(SERVO_PULSE_MIDDLE_US); directionCheck = true; break; case SERVO_COMMAND: //pwm_Servo.pulsewidth_us(pulsewidth); pwm_Servo.pulsewidth_us(SERVO_PULSE_MIDDLE_US); break; default: break; } return; }