From d33bd356cda7f438ac3bbeb37cf33a1f50322202 Mon Sep 17 00:00:00 2001 From: Samuel Date: Thu, 29 Jan 2026 20:25:02 +0100 Subject: [PATCH] =?UTF-8?q?Fusion=20du=20code=20de=20communication=20appli?= =?UTF-8?q?cative=20avec=20le=20code=20de=20d=C3=A9placement?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CMakeLists.txt | 1 + Messagerie_propulsion2026.ods | Bin 0 -> 29704 bytes Readme.md | 111 ++++++++++++++++++++++++++++++++++ Trajectoire.c | 3 - Trajectoire.h | 3 +- Trajet.c | 1 - main.c | 67 +++++++++++++++++++- messagerie.h | 21 +++++-- messagerie_applicative.c | 50 +++++++++++++++ messagerie_applicative.h | 12 ++++ messages_propulsion.h | 27 +++++++++ 11 files changed, 283 insertions(+), 13 deletions(-) create mode 100644 Messagerie_propulsion2026.ods create mode 100644 messagerie_applicative.c create mode 100644 messagerie_applicative.h create mode 100644 messages_propulsion.h diff --git a/CMakeLists.txt b/CMakeLists.txt index fdfe7c6..208c5b0 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -19,6 +19,7 @@ add_executable(Mon_Projet Geometrie.c i2c_maitre.c messagerie.c + messagerie_applicative.c Moteurs.c Localisation.c main.c diff --git a/Messagerie_propulsion2026.ods b/Messagerie_propulsion2026.ods new file mode 100644 index 0000000000000000000000000000000000000000..8a7ece9823d139b2cad772aa9c1a380440e68b66 GIT binary patch literal 29704 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 literal 0 HcmV?d00001 diff --git a/Readme.md b/Readme.md index 92cb5c3..2328981 100644 --- a/Readme.md +++ b/Readme.md @@ -6,12 +6,19 @@ Basé sur le code du PAMI 2025 de l'équipe Poivron Robotique. Principales évolutions: - Ajout de la communication USB +- Définition des messages applicatifs Méthode de test --------------- + * Éteindre la LED avec la trame : `echo -e "\xFF\xFF\x06rD\x00\x01\x36\x00" > /dev/ttyACM0` + * Allumer la LED avec la trame : `echo -e "\xFF\xFF\x06rD\x00\x01\x06\x00" > /dev/ttyACM0` +* Tester la réception de la position + + `echo -e "\xFF\xFF\x11rP\x00\x0C\x01\x01\x01\x01\x05\x05\x05\x05\x09\x09\x09\x09\x00" > /dev/ttyACM0` + Difficultés ----------- Il suffit d'une petite modification du code (ajout d'un `printf` par exemple), pour que la communication se bloque côté PC @@ -19,3 +26,107 @@ Il suffit d'une petite modification du code (ajout d'un `printf` par exemple), p L'utilisation du second cœur pour envoyer la télémétrie peut perturber le débug avec printf => Augment grandement le délai de réponse La communication crash rapidement : à cause de la danse du PAMI => Suppression de la dance du PAMI (c'était codé à l'arrache) + +Les points des trajectoires sont des `double`, il faut les mettre en `float`. + +Pas de trajectoire rotation sur soi-même ? + +Annexes +======= + +Tables des registres +-------------------- + + +Table des registres : +--------------------- + +| Adresse | R/W | Type | Donnée | +| ------- | --- | ---------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| 0x00 | RW | flottant 32 bits | Position X en mm | +| 0x01 | RW | flottant 32 bits | Position X en mm | +| 0x02 | RW | flottant 32 bits | Position X en mm | +| 0x03 | RW | flottant 32 bits | Position X en mm | +| 0x04 | RW | flottant 32 bits | Position Y en mm | +| 0x05 | RW | flottant 32 bits | Position Y en mm | +| 0x06 | RW | flottant 32 bits | Position Y en mm | +| 0x07 | RW | flottant 32 bits | Position Y en mm | +| 0x08 | RW | flottant 32 bits | Orientation en radian | +| 0x09 | RW | flottant 32 bits | Orientation en radian | +| 0x0A | RW | flottant 32 bits | Orientation en radian | +| 0x0B | RW | flottant 32 bits | Orientation en radian | +| 0x0C | R | Boolean | Mouvement en cours : 1
Mouvement terminé : 0 | +| 0x0D | RW | uint8_t | Mode
0 : arrêt des moteurs
1 : pilotage des moteurs PWM
2 : pilotage en vitesse des roues
3 : pilotage avec la loi de commande
4 : Trajectoire | +| 0x0E | RW | int_16 | Commande PWM moteur gauche | +| 0x0F | RW | int_16 | Commande PWM moteur gauche | +| 0x10 | RW | int_16 | Commande PWM moteur droit | +| 0x11 | RW | int_16 | Commande PWM moteur droit | +| 0x12 | RW | Flottant 32 bits | Consigne vitesse gauche en mm/s | +| 0x13 | RW | Flottant 32 bits | Consigne vitesse gauche en mm/s | +| 0x14 | RW | Flottant 32 bits | Consigne vitesse gauche en mm/s | +| 0x15 | RW | Flottant 32 bits | Consigne vitesse gauche en mm/s | +| 0x16 | RW | Flottant 32 bits | Consigne vitesse gauche en mm/s | +| 0x17 | RW | Flottant 32 bits | Consigne vitesse gauche en mm/s | +| 0x18 | RW | Flottant 32 bits | Consigne vitesse gauche en mm/s | +| 0x19 | RW | Flottant 32 bits | Consigne vitesse gauche en mm/s | +| 0x1A | RW | Flottant 32 bits | Consigne d’avance du robot | +| 0x1B | RW | Flottant 32 bits | Consigne d’avance du robot | +| 0x1C | RW | Flottant 32 bits | Consigne d’avance du robot | +| 0x1D | RW | Flottant 32 bits | Consigne d’avance du robot | +| 0x1E | RW | Flottant 32 bits | Consigne de rotation du robot | +| 0x1F | RW | Flottant 32 bits | Consigne de rotation du robot | +| 0x20 | RW | Flottant 32 bits | Consigne de rotation du robot | +| 0x21 | RW | Flottant 32 bits | Consigne de rotation du robot | +| 0x22 | RW | Enum 8 bits | Trajectoire, type :
0 : Droite
1 : Circulaire
2 : Bézier
3 : Composée
4 : Rotation | +| 0x23 | RW | Flottant 32 bits | Point 1, X | +| 0x24 | RW | Flottant 32 bits | Point 1, X | +| 0x25 | RW | Flottant 32 bits | Point 1, X | +| 0x26 | RW | Flottant 32 bits | Point 1, X | +| 0x27 | RW | Flottant 32 bits | Point 1, Y | +| 0x28 | RW | Flottant 32 bits | Point 1, Y | +| 0x29 | RW | Flottant 32 bits | Point 1, Y | +| 0x2A | RW | Flottant 32 bits | Point 1, Y | +| 0x2B | RW | Flottant 32 bits | Point 2, X | +| 0x2C | RW | Flottant 32 bits | Point 2, X | +| 0x2D | RW | Flottant 32 bits | Point 2, X | +| 0x2E | RW | Flottant 32 bits | Point 2, X | +| 0x2F | RW | Flottant 32 bits | Point 2, Y | +| 0x30 | RW | Flottant 32 bits | Point 2, Y | +| 0x31 | RW | Flottant 32 bits | Point 2, Y | +| 0x32 | RW | Flottant 32 bits | Point 2, Y | +| 0x33 | RW | Flottant 32 bits | Point 3, X | +| 0x34 | RW | Flottant 32 bits | Point 3, X | +| 0x35 | RW | Flottant 32 bits | Point 3, X | +| 0x36 | RW | Flottant 32 bits | Point 3, X | +| 0x37 | RW | Flottant 32 bits | Point 3, Y | +| 0x38 | RW | Flottant 32 bits | Point 3, Y | +| 0x39 | RW | Flottant 32 bits | Point 3, Y | +| 0x3A | RW | Flottant 32 bits | Point 3, Y | +| 0x3B | RW | Flottant 32 bits | Point 4, X | +| 0x3C | RW | Flottant 32 bits | Point 4, X | +| 0x3D | RW | Flottant 32 bits | Point 4, X | +| 0x3E | RW | Flottant 32 bits | Point 4, X | +| 0x3F | RW | Flottant 32 bits | Point 4, Y | +| 0x40 | RW | Flottant 32 bits | Point 4, Y | +| 0x41 | RW | Flottant 32 bits | Point 4, Y | +| 0x42 | RW | Flottant 32 bits | Point 4, Y | +| 0x43 | RW | Flottant 32 bits | orientation_debut_rad | +| 0x44 | RW | Flottant 32 bits | orientation_debut_rad | +| 0x45 | RW | Flottant 32 bits | orientation_debut_rad | +| 0x46 | RW | Flottant 32 bits | orientation_debut_rad | +| 0x47 | RW | Flottant 32 bits | orientation_fin_rad | +| 0x48 | RW | Flottant 32 bits | orientation_fin_rad | +| 0x49 | RW | Flottant 32 bits | orientation_fin_rad | +| 0x4A | RW | Flottant 32 bits | orientation_fin_rad | +| 0x4B | RW | Flottant 32 bits | rayon mm | +| 0x4C | RW | Flottant 32 bits | rayon mm | +| 0x4D | RW | Flottant 32 bits | rayon mm | +| 0x4E | RW | Flottant 32 bits | rayon mm | +| 0x4F | RW | Flottant 32 bits | Angle début rad | +| 0x50 | RW | Flottant 32 bits | Angle début rad | +| 0x51 | RW | Flottant 32 bits | Angle début rad | +| 0x52 | RW | Flottant 32 bits | Angle début rad | +| 0x53 | RW | Flottant 32 bits | Angle fin rad | +| 0x54 | RW | Flottant 32 bits | Angle fin rad | +| 0x55 | RW | Flottant 32 bits | Angle fin rad | +| 0x56 | RW | Flottant 32 bits | Angle fin rad | \ No newline at end of file diff --git a/Trajectoire.c b/Trajectoire.c index 063ec36..89ee335 100644 --- a/Trajectoire.c +++ b/Trajectoire.c @@ -135,17 +135,14 @@ struct point_xyo_t Trajectoire_get_point(struct trajectoire_t * trajectoire, dou switch(trajectoire->type){ case TRAJECTOIRE_DROITE: point_xyo.point_xy = Trajectoire_droite_get_point(trajectoire, abscisse); - point_xyo.orientation = Trajectoire_get_orientation_rad(trajectoire, abscisse); break; case TRAJECTOIRE_CIRCULAIRE: point_xyo.point_xy = Trajectoire_circulaire_get_point(trajectoire, abscisse); - point_xyo.orientation = Trajectoire_get_orientation_rad(trajectoire, abscisse); break; case TRAJECTOIRE_BEZIER: point_xyo.point_xy = Trajectoire_bezier_get_point(trajectoire, abscisse); - point_xyo.orientation = Trajectoire_get_orientation_rad(trajectoire, abscisse); break; case TRAJECTOIRE_COMPOSEE: diff --git a/Trajectoire.h b/Trajectoire.h index a072781..7bcd770 100644 --- a/Trajectoire.h +++ b/Trajectoire.h @@ -11,12 +11,11 @@ enum trajectoire_type_t{ }; struct point_xy_t{ - double x, y; + float x, y; }; struct point_xyo_t{ struct point_xy_t point_xy; - float orientation; }; struct trajectoire_t { diff --git a/Trajet.c b/Trajet.c index 7808b21..1abfee1 100644 --- a/Trajet.c +++ b/Trajet.c @@ -76,7 +76,6 @@ enum etat_trajet_t Trajet_avance(float pas_de_temps_s){ position.x_mm = point.point_xy.x; position.y_mm = point.point_xy.y; - position.angle_radian = point.orientation; position_consigne=position; Asser_Position(position); diff --git a/main.c b/main.c index bbc28c1..981d803 100644 --- a/main.c +++ b/main.c @@ -14,6 +14,7 @@ #include "i2c_maitre.h" #include "Localisation.h" #include "messagerie.h" +#include "messagerie_applicative.h" #include "Moteurs.h" #include "Strategie.h" #include "Servomoteur.h" @@ -104,9 +105,9 @@ void main(void) // TODO: A remettre - quand on aura récupéré un capteur if(get_identifiant() != 0){ //multicore_launch_core1(gestion_VL53L8CX); - multicore_launch_core1(gestion_affichage); + //multicore_launch_core1(gestion_affichage); }else{ - multicore_launch_core1(gestion_affichage); + //multicore_launch_core1(gestion_affichage); } @@ -132,6 +133,64 @@ void main(void) // données[1]: id de la carte // données[2]: 1er registre // données[3 à tailles_données -1]: valeurs + struct message_applicatif_t message_applicatif; + + memcpy(&message_applicatif, message.donnees, message.taille_donnees); + printf("id_carte:%c %d\n", message_applicatif.id_carte, message_applicatif.id_carte); + + + if(message_applicatif.id_carte == 'P'){ + + mise_a_jour_position = false; + mise_a_jour_mode = false; + mise_a_jour_pwm = false; + mise_a_jour_vitesse_roues = false; + mise_a_jour_vitesse_robot = false; + mise_a_jour_trajectoire = false; + + // Copie des données dans la mémoire d'échange + // Et actualisation des variables "mise_a_jour_..." + for (int num_octet=0; num_octet' pour des logs - uint8_t id_carte; // Identifiant de la carte (on reprend les adresses I2C) - uint8_t adresse_registre; // Adresse du registre lu + uint8_t type; // 'b' pour binaire, '>' pour des logs uint8_t taille_donnees; - uint8_t donnees[255]; + uint8_t donnees[255]; }; struct message_requete_t{ @@ -17,6 +16,20 @@ struct message_requete_t{ uint8_t taille_donnees; }; +struct message_applicatif_t{ + uint8_t commande; // 'r' : réception de données, 'd' : demande de données + uint8_t id_carte; // Identifiant de la carte (on reprend les adresses I2C) + uint8_t adresse_registre; // Adresse du registre lu ou écrit + uint8_t taille_donnees; + union{ + uint8_t donnees[100]; +#ifdef MESSAGE_PROPULSION_H + struct msg_propulsion_position_t msg_propulsion_position; +#endif + + }donnees_applicative; + +}; bool messagerie_message_disponible(); struct message_t messagerie_get_message(); diff --git a/messagerie_applicative.c b/messagerie_applicative.c new file mode 100644 index 0000000..44b86a5 --- /dev/null +++ b/messagerie_applicative.c @@ -0,0 +1,50 @@ +#include +#include "messagerie_applicative.h" + +uint8_t memoire_echange[200]; + + + +bool mise_a_jour_position = false; +bool mise_a_jour_mode = false; +bool mise_a_jour_pwm = false; +bool mise_a_jour_vitesse_roues = false; +bool mise_a_jour_vitesse_robot = false; +bool mise_a_jour_trajectoire = false; + +void get_données_reçues(uint8_t * dst, unsigned int taille, unsigned int registre){ + memcpy(dst, &(memoire_echange[registre]), taille); +} + + +void écriture_données(unsigned int adresse, uint8_t donnée){ + if( adresse <= 11){ + // Position du robot + mise_a_jour_position = true; + }else if(adresse <= 12){ + // Read only + + }else if(adresse <= 13){ + // Mode + mise_a_jour_mode = true; + }else if(adresse <= 17){ + // PWM moteur + mise_a_jour_pwm = true; + }else if(adresse <= 25){ + // Vitesse roues + mise_a_jour_vitesse_roues = true; + }else if(adresse <= 33){ + // Vitesse robot + mise_a_jour_vitesse_robot = true; + }else if(adresse <= 86){ + // Trajectoire + mise_a_jour_trajectoire = true; + }else if(adresse >86){ + // Hors mémoire + return; + } + + memoire_echange[adresse] = donnée; + + +} diff --git a/messagerie_applicative.h b/messagerie_applicative.h new file mode 100644 index 0000000..cf05b5f --- /dev/null +++ b/messagerie_applicative.h @@ -0,0 +1,12 @@ +#include +#include + +void écriture_données(unsigned int adresse, uint8_t donnée); +void get_données_reçues(uint8_t * dst, unsigned int taille, unsigned int registre); + +extern bool mise_a_jour_position; +extern bool mise_a_jour_mode; +extern bool mise_a_jour_pwm; +extern bool mise_a_jour_vitesse_roues; +extern bool mise_a_jour_vitesse_robot; +extern bool mise_a_jour_trajectoire; \ No newline at end of file diff --git a/messages_propulsion.h b/messages_propulsion.h new file mode 100644 index 0000000..8317e15 --- /dev/null +++ b/messages_propulsion.h @@ -0,0 +1,27 @@ +#ifndef MESSAGE_PROPULSION_H +#define MESSAGE_PROPULSION_H +#define USB_ID_PROPULSION 'P' + +#define REG_PROPULSION_POSITION 0x00 +#define REG_PROPULSION_MODE 0x0D +#define REG_PROPULSION_PWM 0x0E +#define REG_PROPULSION_VITESSE_ROUES 0x12 +#define REG_PROPULSION_VITESSE_ROBOT 0x1A + +struct msg_propulsion_position_t{ + float position_x_mm, position_y_mm, orientation_rad; +}; + +struct msg_propulsion_pwm_t{ + uint16_t pwm_gauche, pwm_droit; +}; + +struct msg_propulsion_vitesse_roues_t{ + float vitesse_gauche_mm_s, vitesse_droite_mm_s; +}; + +struct msg_propulsion_vitesse_robot_t { + float avance_mm_s, rotation_rad_s; +}; + +#endif \ No newline at end of file