RPiPico-Holonome2023/Trajet.c

181 lines
5.7 KiB
C
Raw Normal View History

#include <math.h>
#include "Geometrie.h"
#include "Trajectoire.h"
2022-12-19 18:32:39 +00:00
#include "Trajet.h"
#include "Asser_Position.h"
double Trajet_calcul_vitesse(double temps_s);
int Trajet_terminee(double abscisse);
double abscisse; // Position entre 0 et 1 sur la trajectoire
double position_mm; // Position en mm sur la trajectoire
double vitesse_mm_s;
double vitesse_max_trajet_mm_s=500;
double acceleration_mm_ss;
2023-04-21 20:33:29 +00:00
const double acceleration_mm_ss_obstacle = 1500;
struct trajectoire_t trajet_trajectoire;
struct position_t position_consigne;
2023-04-01 13:29:54 +00:00
double distance_obstacle_mm;
2023-04-21 20:33:29 +00:00
const double distance_pas_obstacle = 2000;
2023-04-01 13:29:54 +00:00
/// @brief Initialise le module Trajet. A appeler en phase d'initilisation
void Trajet_init(){
abscisse = 0;
vitesse_mm_s = 0;
acceleration_mm_ss = 500;
position_mm = 0;
}
/// @brief Configure la vitesse maximale et l'acceleration pour les futurs trajets
/// @param _vitesse_max_trajet_mm_s
/// @param _acceleration_mm_ss
void Trajet_config(double _vitesse_max_trajet_mm_s, double _acceleration_mm_ss){
vitesse_max_trajet_mm_s = _vitesse_max_trajet_mm_s;
acceleration_mm_ss = _acceleration_mm_ss;
}
void Trajet_debut_trajectoire(struct trajectoire_t trajectoire){
abscisse = 0;
vitesse_mm_s = 0;
position_mm = 0;
trajet_trajectoire = trajectoire;
}
/// @brief Avance la consigne de position sur la trajectoire
/// @param pas_de_temps_s : temps écoulé depuis le dernier appel en seconde
enum etat_trajet_t Trajet_avance(double pas_de_temps_s){
double distance_mm;
enum etat_trajet_t trajet_etat = TRAJET_EN_COURS;
struct point_xyo_t point;
struct position_t position;
// Calcul de la vitesse
vitesse_mm_s = Trajet_calcul_vitesse(pas_de_temps_s);
// Calcul de l'avancement en mm
distance_mm = vitesse_mm_s * pas_de_temps_s;
position_mm += distance_mm;
// Calcul de l'abscisse sur la trajectoire
abscisse = Trajectoire_avance(&trajet_trajectoire, abscisse, distance_mm);
// Obtention du point consigne
point = Trajectoire_get_point(&trajet_trajectoire, abscisse);
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);
if(Trajet_terminee(abscisse)){
Asser_Position_set_Pos_Maintien(position);
trajet_etat = TRAJET_TERMINE;
2022-12-19 18:32:39 +00:00
}
return trajet_etat;
2022-12-19 18:32:39 +00:00
}
2023-04-01 13:29:54 +00:00
void Trajet_stop(double pas_de_temps_s){
vitesse_mm_s = 0;
Trajet_avance(0);
}
/// @brief Savoir si un trajet est terminé est trivial sauf pour les courbes de Bézier
/// où les approximations font que l'abscisse peut ne pas atteindre 1.
/// @param abscisse : abscisse sur la trajectoire
/// @return 1 si le trajet est terminé, 0 sinon
int Trajet_terminee(double abscisse){
/*if(abscisse >= 0.99 ){
2023-04-01 13:29:54 +00:00
return 1;
}*/
if(trajet_trajectoire.type != TRAJECTOIRE_BEZIER){
if(abscisse >= 1 ){
return 1;
}
}else{
if(abscisse >= 0.99 ){
return 1;
}
}
return 0;
}
/// @brief Envoie la consigne de position calculée par le module trajet. Principalement pour le débug/réglage asservissement.
struct position_t Trajet_get_consigne(){
return position_consigne;
}
2022-12-19 18:32:39 +00:00
/// @brief Calcule la vitesse à partir de laccélération du robot, de la vitesse maximale et de la contrainte en fin de trajectoire
/// @param pas_de_temps_s : temps écoulé en ms
/// @return vitesse déterminée en m/s
double Trajet_calcul_vitesse(double pas_de_temps_s){
double vitesse_max_contrainte;
2023-04-21 20:33:29 +00:00
double vitesse_max_contrainte_obstacle;
2023-04-01 13:29:54 +00:00
double distance_contrainte,distance_contrainte_obstacle;
double vitesse;
// Calcul de la vitesse avec acceleration
vitesse = vitesse_mm_s + acceleration_mm_ss * pas_de_temps_s;
// Calcul de la vitesse maximale due à la contrainte en fin de trajectoire (0 mm/s)
// https://poivron-robotique.fr/Consigne-de-vitesse.html
distance_contrainte = Trajectoire_get_longueur_mm(&trajet_trajectoire) - position_mm;
// En cas de dépassement, on veut garder la contrainte, pour l'instant
if(distance_contrainte > 0){
vitesse_max_contrainte = sqrt(2 * acceleration_mm_ss * distance_contrainte);
}else{
vitesse_max_contrainte = 0;
}
2023-04-21 20:33:29 +00:00
distance_contrainte_obstacle = Trajet_get_obstacle_mm();
if(distance_contrainte_obstacle != DISTANCE_INVALIDE){
vitesse_max_contrainte_obstacle = sqrt(2 * acceleration_mm_ss_obstacle * distance_contrainte_obstacle);
if(vitesse_max_contrainte_obstacle < vitesse_max_contrainte){
vitesse_max_contrainte = vitesse_max_contrainte_obstacle;
}
}
// Selection de la vitesse la plus faible
if(vitesse > vitesse_max_contrainte){
vitesse = vitesse_max_contrainte;
}
if(vitesse > vitesse_max_trajet_mm_s){
vitesse = vitesse_max_trajet_mm_s;
}
return vitesse;
2022-12-11 14:39:30 +00:00
}
2023-04-01 13:29:54 +00:00
double Trajet_get_obstacle_mm(void){
return distance_obstacle_mm;
}
void Trajet_set_obstacle_mm(double distance_mm){
distance_obstacle_mm = distance_mm;
2023-04-21 20:33:29 +00:00
}
/// @brief Renvoi l'angle d'avancement du robot dans le référentiel du terrain
/// @return angle en radian.
double Trajet_get_orientation_avance(){
struct point_xyo_t point, point_suivant;
double avance_abscisse = 0.01;
double angle;
if(abscisse >= 1){
return 0;
}
if(abscisse + avance_abscisse >= 1){
avance_abscisse = 1 - abscisse;
}
point = Trajectoire_get_point(&trajet_trajectoire, abscisse);
point_suivant = Trajectoire_get_point(&trajet_trajectoire, abscisse + avance_abscisse);
angle = atan2(point_suivant.point_xy.y - point.point_xy.y, point_suivant.point_xy.x - point.point_xy.x);
return angle;
2023-04-01 13:29:54 +00:00
}