#include "hardware/gpio.h" #include "i2c_annexe.h" #include "Asser_Position.h" #include "Balise_VL53L1X.h" #include "Geometrie_robot.h" #include "Localisation.h" #include "Moteurs.h" #include "Strategie_prise_cerises.h" #include "Strategie.h" #include "Trajet.h" #include "math.h" #define SEUIL_RECAL_DIST_MM 75 #define SEUIL_RECAL_ANGLE_RADIAN (5 * DEGREE_EN_RADIAN) #define DISTANCE_OBSTACLE_CM 35 enum etat_action_t calage_angle(enum longer_direction_t longer_direction, double x_mm, double y_mm, double angle_radian); enum etat_action_t lance_balles(uint32_t step_ms); enum etat_strategie_t etat_strategie=STRATEGIE_INIT; void Homologation(uint32_t step_ms){ enum etat_action_t etat_action; enum etat_trajet_t etat_trajet; struct trajectoire_t trajectoire; switch(etat_strategie){ case STRATEGIE_INIT: Localisation_set(775., 109., -60. * DEGREE_EN_RADIAN); etat_strategie = APPROCHE_CERISE_1_A; break; case APPROCHE_CERISE_1_A: Trajet_config(250, 500); Trajectoire_droite(&trajectoire,775, 109, 857, 156, -60. * DEGREE_EN_RADIAN, +30. * DEGREE_EN_RADIAN); Trajet_debut_trajectoire(trajectoire); etat_strategie = APPROCHE_CERISE_1_B; break; case APPROCHE_CERISE_1_B: etat_trajet = Trajet_avance(step_ms/1000.); if(etat_trajet == TRAJET_TERMINE){ etat_strategie = ATTRAPE_CERISE_1; } break; case ATTRAPE_CERISE_1: etat_action = cerise_attraper_bordure(LONGER_VERS_C, step_ms); if(etat_action == ACTION_TERMINEE){ etat_strategie = APPROCHE_PANIER_1; } break; case APPROCHE_PANIER_1: Trajet_config(500, 500); Trajectoire_bezier(&trajectoire,Localisation_get().x_mm, Localisation_get().y_mm, 485, Localisation_get().y_mm, 465, 857, 465,2830, +30. * DEGREE_EN_RADIAN, +120. * DEGREE_EN_RADIAN); if(parcourt_trajet_simple(trajectoire, step_ms) == ACTION_TERMINEE){ etat_strategie = CALAGE_PANIER_1; } break; case APPROCHE_PANIER_2: Trajectoire_droite(&trajectoire,Localisation_get().x_mm, Localisation_get().y_mm, 265,2830, +120. * DEGREE_EN_RADIAN, +120. * DEGREE_EN_RADIAN); if(parcourt_trajet_simple(trajectoire, step_ms) == ACTION_TERMINEE){ etat_strategie = CALAGE_PANIER_1; } break; case CALAGE_PANIER_1: if(calage_angle(LONGER_VERS_A, RAYON_ROBOT, 3000 - (RAYON_ROBOT/(RACINE_DE_3/2.)), 120. *DEGREE_EN_RADIAN) == ACTION_TERMINEE){ etat_strategie = RECULE_PANIER; } break; case RECULE_PANIER: Trajet_config(250, 500); Trajectoire_droite(&trajectoire,Localisation_get().x_mm, Localisation_get().y_mm, 180, 3000 - (RAYON_ROBOT/(RACINE_DE_3/2)) - 80, 120. * DEGREE_EN_RADIAN, +270. * DEGREE_EN_RADIAN); if(parcourt_trajet_simple(trajectoire, step_ms) == ACTION_TERMINEE){ etat_strategie = LANCE_DANS_PANIER; } break; case LANCE_DANS_PANIER: Asser_Position_maintien(); if(lance_balles(step_ms) == ACTION_TERMINEE){ etat_strategie = STRATEGIE_FIN; } break; case STRATEGIE_FIN: Moteur_Stop(); break; } } /// @brief Active le propulseur, ouvre la porte, attend qql secondes. /// @param step_ms : pas de temps. /// @return ACTION_EN_COURS ou ACTION_TERMINEE enum etat_action_t lance_balles(uint32_t step_ms){ enum etat_action_t etat_action = ACTION_EN_COURS; uint32_t tempo_ms; static enum{ LANCE_PROPULSEUR_ON, LANCE_TEMPO_PROP_ON, LANCE_PORTE_OUVERTE, } etat_lance_balle = LANCE_PROPULSEUR_ON; switch(etat_lance_balle){ case LANCE_PROPULSEUR_ON: i2c_annexe_active_propulseur(); tempo_ms = 2000; etat_lance_balle = LANCE_TEMPO_PROP_ON; break; case LANCE_TEMPO_PROP_ON: if (tempo_ms < step_ms){ //etat_lance_balle = LANCE_PORTE_OUVERTE; etat_lance_balle = LANCE_TEMPO_PROP_ON; i2c_annexe_ouvre_porte(); tempo_ms = 6000; }else{ tempo_ms -= step_ms; } break; case LANCE_PORTE_OUVERTE: if (tempo_ms < step_ms){ etat_lance_balle = LANCE_PROPULSEUR_ON; i2c_annexe_desactive_propulseur(); etat_action = ACTION_TERMINEE; }else{ tempo_ms -= step_ms; } break; } return etat_action; } /// @brief Envoie le robot se caler dans l'angle en face de lui, recale la localisation enum etat_action_t calage_angle(enum longer_direction_t longer_direction, double x_mm, double y_mm, double angle_radian){ enum etat_action_t etat_action = ACTION_EN_COURS; struct position_t position; avance_puis_longe_bordure(longer_direction); if( ((longer_direction == LONGER_VERS_A) && (i2c_annexe_get_contacteur_butee_A() == CONTACTEUR_ACTIF) ) || ((longer_direction == LONGER_VERS_C) && (i2c_annexe_get_contacteur_butee_C() == CONTACTEUR_ACTIF) ) ){ etat_action = ACTION_TERMINEE; position = Localisation_get(); if(fabs(position.x_mm - x_mm) < SEUIL_RECAL_DIST_MM){ Localisation_set_x(x_mm); } if(fabs(position.y_mm - y_mm) < SEUIL_RECAL_DIST_MM){ Localisation_set_y(y_mm); } if(fabs(position.angle_radian - angle_radian) < SEUIL_RECAL_ANGLE_RADIAN){ Localisation_set_angle(angle_radian); } } return etat_action; } enum etat_action_t parcourt_trajet_simple(struct trajectoire_t trajectoire, uint32_t step_ms){ enum etat_action_t etat_action = ACTION_EN_COURS; enum etat_trajet_t etat_trajet; static enum { PARCOURS_INIT, PARCOURS_AVANCE, } etat_parcourt=PARCOURS_INIT; switch (etat_parcourt){ case PARCOURS_INIT: Trajet_debut_trajectoire(trajectoire); etat_parcourt = PARCOURS_AVANCE; break; case PARCOURS_AVANCE: if(Balise_VL53L1X_get_min_distance()