Compare commits

..

2 Commits

Author SHA1 Message Date
530eb4b343 Interface entre la communication et le déplacement: commandes ok sauf trajectoire
Il reste les trajectoires à gérer, la lecture de position et le forçage de position
2026-01-29 21:09:38 +01:00
d33bd356cd Fusion du code de communication applicative avec le code de déplacement 2026-01-29 20:25:02 +01:00
11 changed files with 309 additions and 16 deletions

View File

@ -19,6 +19,7 @@ add_executable(Mon_Projet
Geometrie.c Geometrie.c
i2c_maitre.c i2c_maitre.c
messagerie.c messagerie.c
messagerie_applicative.c
Moteurs.c Moteurs.c
Localisation.c Localisation.c
main.c main.c

Binary file not shown.

111
Readme.md
View File

@ -6,12 +6,19 @@ Basé sur le code du PAMI 2025 de l'équipe Poivron Robotique.
Principales évolutions: Principales évolutions:
- Ajout de la communication USB - Ajout de la communication USB
- Définition des messages applicatifs
Méthode de test Méthode de test
--------------- ---------------
* Éteindre la LED avec la trame : `echo -e "\xFF\xFF\x06rD\x00\x01\x36\x00" > /dev/ttyACM0` * É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` * 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 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 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 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) 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<br>Mouvement terminé : 0 |
| 0x0D | RW | uint8_t | Mode<br>0 : arrêt des moteurs<br>1 : pilotage des moteurs PWM<br>2 : pilotage en vitesse des roues<br>3 : pilotage avec la loi de commande<br>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 davance du robot |
| 0x1B | RW | Flottant 32 bits | Consigne davance du robot |
| 0x1C | RW | Flottant 32 bits | Consigne davance du robot |
| 0x1D | RW | Flottant 32 bits | Consigne davance 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 :<br>0 : Droite<br>1 : Circulaire<br>2 : Bézier<br>3 : Composée<br>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 |

View File

@ -135,17 +135,14 @@ struct point_xyo_t Trajectoire_get_point(struct trajectoire_t * trajectoire, dou
switch(trajectoire->type){ switch(trajectoire->type){
case TRAJECTOIRE_DROITE: case TRAJECTOIRE_DROITE:
point_xyo.point_xy = Trajectoire_droite_get_point(trajectoire, abscisse); point_xyo.point_xy = Trajectoire_droite_get_point(trajectoire, abscisse);
point_xyo.orientation = Trajectoire_get_orientation_rad(trajectoire, abscisse);
break; break;
case TRAJECTOIRE_CIRCULAIRE: case TRAJECTOIRE_CIRCULAIRE:
point_xyo.point_xy = Trajectoire_circulaire_get_point(trajectoire, abscisse); point_xyo.point_xy = Trajectoire_circulaire_get_point(trajectoire, abscisse);
point_xyo.orientation = Trajectoire_get_orientation_rad(trajectoire, abscisse);
break; break;
case TRAJECTOIRE_BEZIER: case TRAJECTOIRE_BEZIER:
point_xyo.point_xy = Trajectoire_bezier_get_point(trajectoire, abscisse); point_xyo.point_xy = Trajectoire_bezier_get_point(trajectoire, abscisse);
point_xyo.orientation = Trajectoire_get_orientation_rad(trajectoire, abscisse);
break; break;
case TRAJECTOIRE_COMPOSEE: case TRAJECTOIRE_COMPOSEE:

View File

@ -11,12 +11,11 @@ enum trajectoire_type_t{
}; };
struct point_xy_t{ struct point_xy_t{
double x, y; float x, y;
}; };
struct point_xyo_t{ struct point_xyo_t{
struct point_xy_t point_xy; struct point_xy_t point_xy;
float orientation;
}; };
struct trajectoire_t { struct trajectoire_t {

View File

@ -76,7 +76,6 @@ enum etat_trajet_t Trajet_avance(float pas_de_temps_s){
position.x_mm = point.point_xy.x; position.x_mm = point.point_xy.x;
position.y_mm = point.point_xy.y; position.y_mm = point.point_xy.y;
position.angle_radian = point.orientation;
position_consigne=position; position_consigne=position;
Asser_Position(position); Asser_Position(position);

96
main.c
View File

@ -14,6 +14,7 @@
#include "i2c_maitre.h" #include "i2c_maitre.h"
#include "Localisation.h" #include "Localisation.h"
#include "messagerie.h" #include "messagerie.h"
#include "messagerie_applicative.h"
#include "Moteurs.h" #include "Moteurs.h"
#include "Strategie.h" #include "Strategie.h"
#include "Servomoteur.h" #include "Servomoteur.h"
@ -104,15 +105,16 @@ void main(void)
// TODO: A remettre - quand on aura récupéré un capteur // TODO: A remettre - quand on aura récupéré un capteur
if(get_identifiant() != 0){ if(get_identifiant() != 0){
//multicore_launch_core1(gestion_VL53L8CX); //multicore_launch_core1(gestion_VL53L8CX);
multicore_launch_core1(gestion_affichage); //multicore_launch_core1(gestion_affichage);
}else{ }else{
multicore_launch_core1(gestion_affichage); //multicore_launch_core1(gestion_affichage);
} }
enum etat_trajet_t etat_trajet=TRAJET_EN_COURS; enum etat_trajet_t etat_trajet=TRAJET_EN_COURS;
uint8_t mode=0;
while(1){ while(1){
@ -132,6 +134,68 @@ void main(void)
// données[1]: id de la carte // données[1]: id de la carte
// données[2]: 1er registre // données[2]: 1er registre
// données[3 à tailles_données -1]: valeurs // 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<message_applicatif.taille_donnees; num_octet++){
écriture_données(message_applicatif.adresse_registre + num_octet, message_applicatif.donnees_applicative.donnees[num_octet]);
}
if(mise_a_jour_position){
struct msg_propulsion_position_t msg_propulsion_position;
get_données_reçues((uint8_t *) &msg_propulsion_position, sizeof(msg_propulsion_position), REG_PROPULSION_POSITION);
printf("mise à jour de la position, x:%2.2f, y:%2.2f, orientation: %2.2f\n", msg_propulsion_position.position_x_mm,
msg_propulsion_position.position_y_mm, msg_propulsion_position.orientation_rad);
}
if(mise_a_jour_mode){
get_données_reçues(&mode, sizeof(mode), REG_PROPULSION_MODE);
printf("mode:%d\n", mode);
}
if(mise_a_jour_pwm){
struct msg_propulsion_pwm_t msg_propulsion_pwm;
get_données_reçues((uint8_t *) &msg_propulsion_pwm, sizeof(msg_propulsion_pwm), REG_PROPULSION_PWM);
// Consigne
Moteur_SetVitesse(MOTEUR_A, msg_propulsion_pwm.pwm_droit);
Moteur_SetVitesse(MOTEUR_B, msg_propulsion_pwm.pwm_gauche);
printf("pwm_gauche:%d, pwm_droit:%d\n", msg_propulsion_pwm.pwm_gauche, msg_propulsion_pwm.pwm_droit);
}
if(mise_a_jour_vitesse_roues){
struct msg_propulsion_vitesse_roues_t msg_propulsion_vitesse_roues;
get_données_reçues((uint8_t *) &msg_propulsion_vitesse_roues, sizeof(msg_propulsion_vitesse_roues), REG_PROPULSION_VITESSE_ROUES);
printf("vitesse_roue_gauche:%f, vitesse_roue_droite:%f\n", msg_propulsion_vitesse_roues.vitesse_gauche_mm_s, msg_propulsion_vitesse_roues.vitesse_droite_mm_s);
AsserMoteur_setConsigne_mm_s(MOTEUR_A, msg_propulsion_vitesse_roues.vitesse_droite_mm_s);
AsserMoteur_setConsigne_mm_s(MOTEUR_B, msg_propulsion_vitesse_roues.vitesse_gauche_mm_s);
}
if(mise_a_jour_vitesse_robot){
struct msg_propulsion_vitesse_robot_t msg_propulsion_vitesse_robot;
get_données_reçues((uint8_t *) &msg_propulsion_vitesse_robot, sizeof(msg_propulsion_vitesse_robot), REG_PROPULSION_VITESSE_ROBOT);
printf("avance_robot (mm/s) : %f, rotation (rad/s): %f\n", msg_propulsion_vitesse_robot.avance_mm_s,
msg_propulsion_vitesse_robot.rotation_rad_s);
commande_vitesse(msg_propulsion_vitesse_robot.avance_mm_s, msg_propulsion_vitesse_robot.rotation_rad_s);
}
if(mise_a_jour_trajectoire){
// Oh la la !
}
}
id_carte = message.donnees[1]; id_carte = message.donnees[1];
registre = message.donnees[2]; registre = message.donnees[2];
if(id_carte == 'D'){ if(id_carte == 'D'){
@ -158,11 +222,31 @@ void main(void)
if(temps_ms % step_ms == 0){ if(temps_ms % step_ms == 0){
QEI_update(); QEI_update();
Localisation_gestion(); Localisation_gestion();
gestion_PAMI(step_ms, &asser_pos); struct msg_propulsion_pwm_t msg_propulsion_pwm;
if(asser_pos){ switch(mode){
AsserMoteur_Gestion(step_ms); case 0:
Moteur_Stop();
break;
case 1:
/*
get_données_reçues((uint8_t *) &msg_propulsion_pwm, sizeof(msg_propulsion_pwm), REG_PROPULSION_PWM);
Moteur_SetVitesse(MOTEUR_A, msg_propulsion_pwm.pwm_gauche);
Moteur_SetVitesse(MOTEUR_B, msg_propulsion_pwm.pwm_droit);*/
break;
case 2:
case 3:
case 4:
AsserMoteur_Gestion(step_ms);
break;
} }
//gestion_PAMI(step_ms, &asser_pos);
/*if(asser_pos){
AsserMoteur_Gestion(step_ms);
}*/
// Récupération des valeurs pour les mettre dans la mémoire d'échange
// TODO
} }
} }

View File

@ -1,13 +1,12 @@
#include "pico/stdlib.h" #include "pico/stdlib.h"
#include "messages_propulsion.h"
#define MESSAGE_TIMEOUT_US 2000 #define MESSAGE_TIMEOUT_US 2000
struct message_t{ struct message_t{
uint8_t type; // 'd' pour demande, 'r' pour une réception de données, 'w' pour écrire des données, '>' pour des logs uint8_t type; // 'b' pour binaire, '>' 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 taille_donnees; uint8_t taille_donnees;
uint8_t donnees[255]; uint8_t donnees[255];
}; };
struct message_requete_t{ struct message_requete_t{
@ -17,6 +16,20 @@ struct message_requete_t{
uint8_t taille_donnees; 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(); bool messagerie_message_disponible();
struct message_t messagerie_get_message(); struct message_t messagerie_get_message();

50
messagerie_applicative.c Normal file
View File

@ -0,0 +1,50 @@
#include <string.h>
#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;
}

12
messagerie_applicative.h Normal file
View File

@ -0,0 +1,12 @@
#include <stdint.h>
#include <stdbool.h>
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;

27
messages_propulsion.h Normal file
View File

@ -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