#include "math.h" #include "Strategie.h" #include "Geometrie_robot.h" #include "Commande_vitesse.h" #include "Strategie_2024_pots.h" #include "i2c_annexe.h" #include "Localisation.h" float angle_bras[6] = { 180 * DEGRE_EN_RADIAN, 120 * DEGRE_EN_RADIAN, 60 * DEGRE_EN_RADIAN, 0, -60 * DEGRE_EN_RADIAN, -120 * DEGRE_EN_RADIAN }; float distance_bras_correction_mm[6] = { -12, -7, -5, -15, 0, -25 }; enum etat_bras_t{ BRAS_LIBRE, BRAS_OCCUPE, } etat_bras[NB_BRAS]; struct position_t position_pots_dans_groupe_pot[5] = { {.x_mm = -40, .y_mm = 69.2, .angle_radian = -60 * DEGRE_EN_RADIAN}, {.x_mm = 40, .y_mm = 69.2, .angle_radian = -120 * DEGRE_EN_RADIAN}, {.x_mm = -80, .y_mm = 0, .angle_radian = -90 * DEGRE_EN_RADIAN}, {.x_mm = 80, .y_mm = 0, .angle_radian = -90 * DEGRE_EN_RADIAN}, {.x_mm = 0, .y_mm = 0, .angle_radian = -90 * DEGRE_EN_RADIAN} }; struct position_t position_groupe_pot[6] = { {.x_mm = 36.1, .y_mm = 1386.8, .angle_radian = -90 * DEGRE_EN_RADIAN}, {.x_mm = 36.1, .y_mm = 616.2, .angle_radian = -90 * DEGRE_EN_RADIAN}, {.x_mm = 1020, .y_mm = 36.4, .angle_radian = 0 * DEGRE_EN_RADIAN}, // 1020 : bidouille {.x_mm = 1980, .y_mm = 51.4, .angle_radian = 0 * DEGRE_EN_RADIAN}, // Attention bidouille !!! {.x_mm = 2963.9, .y_mm = 616.2, .angle_radian = 90 * DEGRE_EN_RADIAN}, {.x_mm = 2970, .y_mm = 1340.8, .angle_radian = 90 * DEGRE_EN_RADIAN} // bidouille : 1386.8 => 1326.8 , 2963.9 => 2970 }; enum etat_action_t Strat_2024_depose_pot(uint8_t masque_pot, uint32_t step_ms); /// @brief renvoie la position du centre du pot ainsi que l'ange par lequel l'attraper /// @param groupe_pot Position du groupe de pot /// @param num_pot Pot à prendre, entre 0 et 4 (ou utiliser les macros POT_x) struct position_t groupe_pot_get_pot(unsigned int groupe_pot, unsigned int num_pot){ struct position_t position_pot; struct position_t my_position_groupe_pot; my_position_groupe_pot = position_groupe_pot[groupe_pot]; float angle_groupe_pot = my_position_groupe_pot.angle_radian; position_pot.x_mm = my_position_groupe_pot.x_mm + cosf(angle_groupe_pot) * position_pots_dans_groupe_pot[num_pot].x_mm - sinf(angle_groupe_pot) * position_pots_dans_groupe_pot[num_pot].y_mm; position_pot.y_mm = my_position_groupe_pot.y_mm + sinf(angle_groupe_pot) * position_pots_dans_groupe_pot[num_pot].x_mm + cosf(angle_groupe_pot) * position_pots_dans_groupe_pot[num_pot].y_mm; position_pot.angle_radian = position_pots_dans_groupe_pot[num_pot].angle_radian + angle_groupe_pot; return position_pot; } /// @brief A Affiner /// @return numéro du bras libre (entre 0 et 5) int ordre_bras[NB_BRAS]={5, 0, 1, 2, 3, 4}; int get_bras_libre(void){ for (int i=0; i= 0){ tempo_ms -= step_ms; }else{ i2c_annexe_actionneur_pot(bras, BRAS_HAUT, DOIGT_TIENT); } etat_action = Strategie_tourner_et_aller_a( position_approche_pot.x_mm, position_approche_pot.y_mm, position_attrape_pot.angle_radian - angle_bras[bras], EVITEMENT_PAUSE_DEVANT_OBSTACLE, step_ms); if (etat_action == ACTION_TERMINEE){ etat_attrape_pot = AP_APPROCHE_POT; pot = get_pot_suivant(pot); if(pot > 4){ tempo_ms=250; etat_attrape_pot = AP_FINALISE; break; } position_pot = groupe_pot_get_pot(groupe_pot, pot); position_approche_pot = Geometrie_deplace(position_pot, -DISTANCE_APPROCHE_POT_MM); position_attrape_pot = Geometrie_deplace(position_pot, -DISTANCE_ATTRAPE_POT_MM); } break; case AP_FINALISE: if(tempo_ms >= 0){ tempo_ms -= step_ms; }else{ i2c_annexe_actionneur_pot(bras, BRAS_HAUT, DOIGT_TIENT); } etat_action = Strategie_tourner_et_aller_a( position_approche_pot.x_mm, position_approche_pot.y_mm, position_attrape_pot.angle_radian - angle_bras[bras], EVITEMENT_PAUSE_DEVANT_OBSTACLE, step_ms); if (etat_action == ACTION_TERMINEE){ etat_attrape_pot = AP_ALLER_VERS_GROUPE_POT; return ACTION_TERMINEE; } break; default: break; } return ACTION_EN_COURS; } /// @brief Echange les pots avant avec les pots arrière /// @param step_ms Le pas de temps /// @return ACTION_EN_COURS ou ACTION_TERMINEE enum etat_action_t Strat_2024_echange_pot_avant_arriere(uint32_t step_ms){ static struct position_t position_initiale; struct position_t position_but, position_tmp; enum etat_action_t etat_action; struct trajectoire_t trajectoire; static int tempo_ms; static enum { EPAA_DEPOSE_POT, EPAA_TOURNE, EPAA_ATTRAPE_POT, EPAA_AVANCE_1, EPAA_RECULE_1, EPAA_RECENTRE, EPAA_AVANCE_2, EPAA_RECULE_2, EPAA_LEVE, EPAA_RETOURNE, } etat_echange_pot = EPAA_DEPOSE_POT; switch (etat_echange_pot) { case EPAA_DEPOSE_POT: position_initiale = Localisation_get(); // On dépose les pots 1, 3, 4 et 6 : 0b00101101 : 0x2D if(Strat_2024_depose_pot(0x2D, step_ms) == ACTION_TERMINEE){ etat_echange_pot = EPAA_TOURNE; } break; case EPAA_TOURNE: Trajet_config(TRAJECT_CONFIG_ROTATION_PURE); Trajectoire_rotation(&trajectoire, Localisation_get().x_mm, Localisation_get().y_mm, Localisation_get().angle_radian, position_initiale.angle_radian - M_PI); if(Strategie_parcourir_trajet(trajectoire, step_ms, EVITEMENT_SANS_EVITEMENT) == ACTION_TERMINEE){ etat_echange_pot = EPAA_ATTRAPE_POT; position_initiale.angle_radian -= M_PI; i2c_annexe_actionneur_pot(0, BRAS_POT_SOL, DOIGT_TIENT); i2c_annexe_actionneur_pot(2, BRAS_POT_SOL, DOIGT_TIENT); i2c_annexe_actionneur_pot(3, BRAS_POT_SOL, DOIGT_TIENT); i2c_annexe_actionneur_pot(5, BRAS_POT_SOL, DOIGT_TIENT); tempo_ms = 500; } break; case EPAA_ATTRAPE_POT: tempo_ms--; if(tempo_ms <= 0){ etat_echange_pot = EPAA_AVANCE_1; } break; case EPAA_AVANCE_1: position_but = Geometrie_deplace(position_initiale, DISTANCE_ECHANGE_POT); Trajet_config(TRAJECT_CONFIG_AVANCE_ET_TOURNE); if(Strategie_tourner_et_aller_a(position_but.x_mm, position_but.y_mm, position_initiale.angle_radian, EVITEMENT_ARRET_DEVANT_OBSTACLE, step_ms) == ACTION_TERMINEE){ etat_echange_pot = EPAA_RECULE_1; } break; case EPAA_RECULE_1: position_but = Geometrie_deplace(position_initiale, -DISTANCE_ECHANGE_POT); Trajet_config(TRAJECT_CONFIG_AVANCE_ET_TOURNE); if(Strategie_tourner_et_aller_a(position_but.x_mm, position_but.y_mm, position_initiale.angle_radian, EVITEMENT_ARRET_DEVANT_OBSTACLE, step_ms) == ACTION_TERMINEE){ etat_echange_pot = EPAA_RECENTRE; } break; case EPAA_RECENTRE: Trajet_config(TRAJECT_CONFIG_AVANCE_ET_TOURNE); if(Strategie_tourner_et_aller_a(position_initiale.x_mm, position_initiale.y_mm, position_initiale.angle_radian, EVITEMENT_ARRET_DEVANT_OBSTACLE, step_ms) == ACTION_TERMINEE){ etat_echange_pot = EPAA_AVANCE_2; } break; case EPAA_AVANCE_2: position_tmp = position_initiale; position_tmp.angle_radian += 40. * DEGRE_EN_RADIAN ; position_but = Geometrie_deplace(position_tmp, DISTANCE_ECHANGE_POT); Trajet_config(TRAJECT_CONFIG_AVANCE_ET_TOURNE); if(Strategie_tourner_et_aller_a(position_but.x_mm, position_but.y_mm, position_initiale.angle_radian, EVITEMENT_ARRET_DEVANT_OBSTACLE, step_ms) == ACTION_TERMINEE){ etat_echange_pot = EPAA_RECULE_2; } break; case EPAA_RECULE_2: position_tmp = position_initiale; position_tmp.angle_radian += 60. * DEGRE_EN_RADIAN ; position_but = Geometrie_deplace(position_tmp, -DISTANCE_ECHANGE_POT); Trajet_config(TRAJECT_CONFIG_AVANCE_ET_TOURNE); if(Strategie_tourner_et_aller_a(position_but.x_mm, position_but.y_mm, position_initiale.angle_radian, EVITEMENT_ARRET_DEVANT_OBSTACLE, step_ms) == ACTION_TERMINEE){ etat_echange_pot = EPAA_LEVE; i2c_annexe_actionneur_pot(0, BRAS_HAUT, DOIGT_TIENT); i2c_annexe_actionneur_pot(2, BRAS_HAUT, DOIGT_TIENT); i2c_annexe_actionneur_pot(3, BRAS_HAUT, DOIGT_TIENT); i2c_annexe_actionneur_pot(5, BRAS_HAUT, DOIGT_TIENT); tempo_ms = 500; } break; case EPAA_LEVE: tempo_ms--; if(tempo_ms <= 0){ etat_echange_pot = EPAA_RETOURNE; } break; case EPAA_RETOURNE: if(Strategie_tourner_a(position_initiale.angle_radian - M_PI, step_ms) == ACTION_TERMINEE){ etat_echange_pot = EPAA_DEPOSE_POT; return ACTION_TERMINEE; } break; default: break; } return ACTION_EN_COURS; } /// @brief dépose 1 ou plusieurs pot au pied du robot. /// @param masque_pot: choisi les pots à déposer, 0x01 pour le bras 1, 0x02 pour le bras 2, 0x03 pour les bras 1 & 2 enum etat_action_t Strat_2024_depose_pot(uint8_t masque_pot, uint32_t step_ms){ static int tempo_ms; uint8_t masque=1; static enum { DP_BAISSE_BRAS, DP_BAISSE_BRAS_TEMPO, DP_RANGE_DOIGT, DP_RANGE_BRAS_TEMPO, } etat_depose_pot = DP_BAISSE_BRAS; switch (etat_depose_pot) { case DP_BAISSE_BRAS: for (int i=0; i< NB_BRAS; i++){ masque =1; masque = masque << i; if(masque_pot & masque){ i2c_annexe_actionneur_pot(i, BRAS_ECARTE, DOIGT_TIENT); } } tempo_ms=350; etat_depose_pot = DP_BAISSE_BRAS_TEMPO; break; case DP_BAISSE_BRAS_TEMPO: tempo_ms--; if(tempo_ms < 0){ for (int i=0; i< NB_BRAS; i++){ masque =1; masque = masque << i; if(masque_pot & masque){ i2c_annexe_actionneur_pot(i, BRAS_ECARTE, DOIGT_LACHE); } } tempo_ms=250; etat_depose_pot = DP_RANGE_DOIGT; } break; case DP_RANGE_DOIGT: tempo_ms--; if(tempo_ms < 0){ for (int i=0; i< NB_BRAS; i++){ masque =1; masque = masque << i; if(masque_pot & masque){ i2c_annexe_actionneur_pot(i, BRAS_PLIE, DOIGT_LACHE); tempo_ms=250; } } etat_depose_pot = DP_RANGE_BRAS_TEMPO; } break; case DP_RANGE_BRAS_TEMPO: tempo_ms--; if(tempo_ms < 0){ etat_depose_pot = DP_BAISSE_BRAS; return ACTION_TERMINEE; } break; default: break; } return ACTION_EN_COURS; }