RPiPico-Holonome2023/Balise_VL53L1X.c

158 lines
6.6 KiB
C

#include <stdio.h>
#include "Geometrie_robot.h"
#include "i2c_annexe.h"
#include "Localisation.h"
#include "math.h"
#define NB_CAPTEURS 12
#define DISTANCE_OBSTACLE_IGNORE_MM 2000
#define DISTANCE_CAPTEUR_CENTRE_ROBOT_CM 4
#define DISTANCE_TROP_PRES_CM 3
#define DEMI_CONE_CAPTEUR_RADIAN 0.2225
uint8_t distance_capteur_cm[NB_CAPTEURS];
struct capteur_VL53L1X_t{
uint8_t distance_lue_cm; // Distance entre le capteur et l'obstacle.
uint8_t distance_obstacle_robot_mm; // Distance entre l'obstacle et le centre du robot.
double angle_ref_robot; // Orientation du capteur dans le référentiel du robot
double angle_ref_terrain; // Orientation du capteur dans le référentiel du terrain
double angle_ref_terrain_min; // Cone de détection du capteur (min)
double angle_ref_terrain_max; // Cone de détection du capteur (max)
uint donnee_valide;
}capteurs_VL53L1X[NB_CAPTEURS];
void actualise_VL53L1X(struct capteur_VL53L1X_t * capteur_VL53L1X, uint8_t distance_capteur_cm);
void invalide_obstacle(struct capteur_VL53L1X_t * capteur_VL53L1X, struct position_t position_robot);
void Balise_VL53L1X_gestion(){
i2c_annexe_get_distances(distance_capteur_cm);
for(uint8_t capteur=0; capteur<NB_CAPTEURS; capteur++){
actualise_VL53L1X(&(capteurs_VL53L1X[capteur]), distance_capteur_cm[capteur]);
}
}
void actualise_VL53L1X(struct capteur_VL53L1X_t * capteur_VL53L1X, uint8_t distance_capteur_cm){
struct position_t position_robot;
position_robot = Localisation_get();
// Actualisation de l'angle du capteur
capteur_VL53L1X->angle_ref_terrain = capteur_VL53L1X->angle_ref_robot + position_robot.angle_radian;
// Maintien de l'angle entre -PI et PI
while(capteur_VL53L1X->angle_ref_terrain > M_PI){
capteur_VL53L1X->angle_ref_terrain -= 2* M_PI;
}
while(capteur_VL53L1X->angle_ref_terrain < 2* -M_PI){
capteur_VL53L1X->angle_ref_terrain += 2* M_PI;
}
capteur_VL53L1X->distance_obstacle_robot_mm = 10 * (distance_capteur_cm + DISTANCE_CAPTEUR_CENTRE_ROBOT_CM);
capteur_VL53L1X->angle_ref_terrain_min = capteur_VL53L1X->angle_ref_terrain - DEMI_CONE_CAPTEUR_RADIAN;
capteur_VL53L1X->angle_ref_terrain_max = capteur_VL53L1X->angle_ref_terrain + DEMI_CONE_CAPTEUR_RADIAN;
invalide_obstacle(capteur_VL53L1X, position_robot);
}
/// @brief Definit si l'obstable doit être pris en comptre
/// @param
void invalide_obstacle(struct capteur_VL53L1X_t *capteur_VL53L1X, struct position_t position_robot){
// Positionne l'obstacle sur le terrain
struct position_t position_obstacle;
//printf("Angle:%.1f\n",capteur_VL53L1X->angle_ref_terrain);
position_obstacle.x_mm = position_robot.x_mm + cos(capteur_VL53L1X->angle_ref_terrain)* (double)(capteur_VL53L1X->distance_obstacle_robot_mm);
position_obstacle.y_mm = position_robot.y_mm + sin(capteur_VL53L1X->angle_ref_terrain)* (double)(capteur_VL53L1X->distance_obstacle_robot_mm * 10);
capteur_VL53L1X->donnee_valide=1;
// Si la distance vaut 0, à invalider
if(capteur_VL53L1X->distance_lue_cm <= DISTANCE_TROP_PRES_CM){
capteur_VL53L1X->donnee_valide=0;
}
// Si l'obstacle est à l'extérieur du terrain (on prend 50 mm de marge à l'intérieur du terrain, la balise faisant 100 mm)
//printf("X:%.1f,Y:%.1f\n", position_obstacle.x_mm, position_obstacle.y_mm);
if((position_obstacle.x_mm < 50) || (position_obstacle.y_mm < 50) || (position_obstacle.x_mm > 1950) || (position_obstacle.y_mm > 2950))
{
capteur_VL53L1X->donnee_valide=0;
}
}
void Balise_VL53L1X_init(){
capteurs_VL53L1X[9].angle_ref_robot = 0;
capteurs_VL53L1X[10].angle_ref_robot = M_PI/6;
capteurs_VL53L1X[11].angle_ref_robot = 2*M_PI/6;
capteurs_VL53L1X[0].angle_ref_robot = 3*M_PI/6;
capteurs_VL53L1X[1].angle_ref_robot = 4*M_PI/6;
capteurs_VL53L1X[2].angle_ref_robot = 5*M_PI/6;
capteurs_VL53L1X[3].angle_ref_robot = 6*M_PI/6;
capteurs_VL53L1X[4].angle_ref_robot = 7*M_PI/6;
capteurs_VL53L1X[5].angle_ref_robot = 8*M_PI/6;
capteurs_VL53L1X[6].angle_ref_robot = 9*M_PI/6;
capteurs_VL53L1X[7].angle_ref_robot = 10*M_PI/6;
capteurs_VL53L1X[8].angle_ref_robot = 11*M_PI/6;
}
uint8_t Balise_VL53L1X_get_min_distance(void){
uint8_t min_distance_cm = DISTANCE_OBSTACLE_IGNORE_MM / 10;
for(uint8_t capteur=0; capteur<NB_CAPTEURS; capteur++){
if(capteurs_VL53L1X[capteur].donnee_valide){
if(min_distance_cm> capteurs_VL53L1X[capteur].distance_lue_cm){
min_distance_cm = capteurs_VL53L1X[capteur].distance_lue_cm;
}
}
}
return min_distance_cm;
}
uint8_t Balise_VL53L1X_get_capteur_cm(uint8_t capteur){
return capteurs_VL53L1X[capteur].distance_lue_cm;
}
/// @brief Renvoi l'obstacle le plus proche en tenant compte de la direction d'avancement du robot dans le référentiel du terrain.
/// La fonction utilise 3 cônes de détection :
/// * +/- 22°, à 800 mm
/// * +/- 50°, à 580 mm
/// * +/- 90°, à 350 mm
/// @param angle_avancement_radiant : angle d'avancement du robot entre -PI et PI
/// @return
double Balise_VL53L1X_get_distance_obstacle_mm(double angle_avancement_radiant){
const uint8_t NB_CONE=3;
struct cone_t{
double distance_mm;
double angle;
} cone[NB_CONE];
cone[0].angle = 22 * DEGRE_EN_RADIAN;
cone[0].distance_mm = 800;
cone[1].angle = 50 * DEGRE_EN_RADIAN;
cone[1].distance_mm = 580;
cone[2].angle = 90 * DEGRE_EN_RADIAN;
cone[2].distance_mm = 350;
double angle_min, angle_max;
double distance_minimale = DISTANCE_OBSTACLE_IGNORE_MM;
for(uint8_t capteur=0; capteur<NB_CAPTEURS; capteur++){
for(uint8_t cone_index=0; cone_index<NB_CONE; cone_index++){
if(Geometrie_intersecte_plage_angle(
angle_avancement_radiant - cone[cone_index].angle, angle_avancement_radiant + cone[cone_index].angle,
capteurs_VL53L1X[capteur].angle_ref_terrain_min, capteurs_VL53L1X[capteur].angle_ref_terrain_max)){
if(capteurs_VL53L1X[capteur].donnee_valide){
if(capteurs_VL53L1X[capteur].distance_obstacle_robot_mm < distance_minimale){
distance_minimale = capteurs_VL53L1X[capteur].distance_obstacle_robot_mm;
}
}
}
}
}
// On enlève le rayon du robot et la taille du robot adverse
if(distance_minimale < DISTANCE_OBSTACLE_IGNORE_MM){
distance_minimale -= (RAYON_ROBOT + RAYON_ROBOT_ADVERSE_MM);
if(distance_minimale < 0){
distance_minimale = 0;
}
}
return distance_minimale;
}