Paparazzi UAS v7.0_unstable
Paparazzi is a free software Unmanned Aircraft System.
Loading...
Searching...
No Matches
lidar_correction.c
Go to the documentation of this file.
1/*
2 * Copyright (C) 2025 Alejandro Rochas Fernández <alrochas@ucm.es>
3 *
4 * This file is part of paparazzi.
5 *
6 * paparazzi is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2, or (at your option)
9 * any later version.
10 *
11 * paparazzi is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with paparazzi; see the file COPYING. If not, write to
18 * the Free Software Foundation, 59 Temple Place - Suite 330,
19 * Boston, MA 02111-1307, USA.
20 */
21
22// ------------------------------------
23
24
25#include "lidar_correction.h"
27#include "modules/ins/ins_int.h"
28
29#include "math/pprz_algebra.h"
30#include <math.h>
31#include <float.h>
32#include <state.h>
33
34
35struct WallSystem wall_system; // Global wall system
36
37#ifndef OBSTACLE_WALLS
38#error "OBSTACLE_WALLS is not defined. Please define it in your configuration."
39#endif
40
41#ifdef USE_GRID
43#endif
44
45
46// Calculates the distance from a point P to a wall defined by points A and B
47// taking into account the orientation theta.
48float distance_to_wall(float theta, const struct FloatVect2 *P, const struct FloatVect2 *A,
49 const struct FloatVect2 *B)
50{
51
52 float denom = (B->x - A->x) * sinf(theta) - (B->y - A->y) * cosf(theta);
53
54 // If the denominator is 0, the lines are parallel
55 if (fabsf(denom) < 1e-6f) {
56 return 0;
57 }
58
59 // Calculate t (distance) and s (wall parameter)
60 float t = ((A->y - B->y) * (A->x - P->x) - (A->x - B->x) * (A->y - P->y)) / denom;
61 float s = (cosf(theta) * (A->y - P->y) - sinf(theta) * (A->x - P->x)) / denom;
62
63
64 // Check if the intersection is valid
65 if (t > 0.0f && s >= 0.0f && s <= 1.0f) {
66 return t;
67 } else {
68 return 0;
69 }
70}
71
72
73
74// Calculates the distance from a point P to a segment AB and returns the closest point C
75static float distance_to_segment(const struct FloatVect2 *P, const struct FloatVect2 *A,
76 const struct FloatVect2 *B, struct FloatVect2 *C)
77{
78
79 struct FloatVect2 vecAB = {B->x - A->x, B->y - A->y};
80 struct FloatVect2 vecAP = {P->x - A->x, P->y - A->y};
81
82 float length_sq = vecAB.x * vecAB.x + vecAB.y * vecAB.y;
83 float dot_product = vecAP.x * vecAB.x + vecAP.y * vecAB.y;
84 float t = (length_sq != 0) ? dot_product / length_sq : 0.0f;
85
86 t = (t < 0.0f) ? 0.0f : ((t > 1.0f) ? 1.0f : t);
87
88 C->x = A->x + t * vecAB.x;
89 C->y = A->y + t * vecAB.y;
90
91 float dx = P->x - C->x;
92 float dy = P->y - C->y;
93 return sqrtf(dx * dx + dy * dy);
94}
95
96
98{
99
101 return FLT_MAX;
102 }
103
104 float min_distance = FLT_MAX;
105 float psi = 10; // psi = [-pi, pi]
106
107 // Iterate over all walls
108 for (uint8_t w = 0; w < wall_system.wall_count; w++) {
109 struct Wall *wall = &wall_system.walls[w];
110
111 // Iterate over all segments of the wall
112 for (uint8_t p = 0; p < wall->count - 1; p++) {
113 struct FloatVect2 p1 = wall->points_ltp[p];
114 struct FloatVect2 p2 = wall->points_ltp[p + 1];
115
116 // Calculate distance to the line segment
117 // p1 and p2 are the ends of the wall. The result is stored in aux_point
118 struct FloatVect2 aux_point = {0.0f, 0.0f};
119 float distance = distance_to_segment(obstacle_pos, &p1, &p2, &aux_point);
120
121 if (distance < min_distance) {
122 psi = atan2f(-(p2.y - p1.y), p2.x - p1.x);
123 min_distance = distance;
125 }
126 }
127 }
128
129 return min_distance;
130}
131
132
133
134/*******************************************************************************
135 * *
136 * Wall functions *
137 * *
138 ******************************************************************************/
139
140// Include the obstacles configuration file
142
143// Parse of obstacles (defined in the map file)
144void init_walls(void)
145{
146 uint8_t wall_count = sizeof(obstacle_walls) / sizeof(obstacle_walls[0]);
147
148 wall_system.wall_count = wall_count;
149
150 for (int w = 0; w < wall_count; w++) {
151 const struct WallConfig *cfg = &obstacle_walls[w];
152 struct Wall *wall = &wall_system.walls[w];
153 wall->count = cfg->count;
154
155 for (int p = 0; p < wall->count; p++) {
156 wall->points_wgs84[p] = (struct LlaCoor_f){
157 .lat = RadOfDeg(cfg->points[p].lat_deg),
158 .lon = RadOfDeg(cfg->points[p].lon_deg),
159 .alt = cfg->points[p].alt
160 };
161 }
162 }
163
165}
166
167
169{
171
172 for (int w = 0; w < wall_system.wall_count; w++) {
173 for (int p = 0; p < wall_system.walls[w].count; p++) {
174 struct NedCoor_f ned = {0.0f, 0.0f, 0.0f};
176
179 }
180 wall_system.walls[w].converted = true;
181 }
183}
184
#define B
#define A
static struct LtpDef_f * stateGetNedOrigin_f(void)
Get the coordinate NED frame origin (float)
Definition state.h:566
static bool stateIsLocalCoordinateValid(void)
Test if local coordinates are valid.
Definition state.h:613
static float p[2][2]
INS for rotorcrafts combining vertical and horizontal filters.
const struct WallConfig obstacle_walls[]
static float distance_to_segment(const struct FloatVect2 *P, const struct FloatVect2 *A, const struct FloatVect2 *B, struct FloatVect2 *C)
float find_nearest_wall(const struct FloatVect2 *obstacle_pos, struct FloatVect2 *nearest_point)
float distance_to_wall(float theta, const struct FloatVect2 *P, const struct FloatVect2 *A, const struct FloatVect2 *B)
void convert_walls_to_ltp(void)
void init_walls(void)
struct WallSystem wall_system
struct FloatVect2 points_ltp[MAX_POINTS]
uint8_t wall_count
bool converted
struct Wall walls[MAX_WALLS]
struct LlaCoor_f points_wgs84[MAX_POINTS]
uint8_t count
struct ObstaclePoint points[MAX_POINTS]
static uint32_t s
uint16_t foo
Definition main_demo5.c:58
Paparazzi generic algebra macros.
void ned_of_lla_point_f(struct NedCoor_f *ned, struct LtpDef_f *def, struct LlaCoor_f *lla)
vector in Latitude, Longitude and Altitude
vector in North East Down coordinates Units: meters
API to get/set the generic vehicle states.
driver for the TFMini lidar
static float P[3][3]
unsigned char uint8_t
Typedef defining 8 bit unsigned char type.