Paparazzi UAS v7.0_unstable
Paparazzi is a free software Unmanned Aircraft System.
Loading...
Searching...
No Matches
uwb_positioning.c
Go to the documentation of this file.
1/*
2 * Copyright (C) 2017 Gautier Hattenberger <gautier.hattenberger@enac.fr>
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, see
18 * <http://www.gnu.org/licenses/>.
19 */
27
28#include "std.h"
29#include "mcu_periph/uart.h"
30#include "pprzlink/messages.h"
32#include "modules/core/abi.h"
34#include "modules/gps/gps.h"
35#include "state.h"
36#include "generated/flight_plan.h"
37#include "generated/airframe.h"
38#include <stdio.h>
39#include <stdlib.h>
40#include <string.h>
41
43#ifndef UWB_POSITIONING_USE_AS_LOCAL_POS
44#define UWB_POSITIONING_USE_AS_LOCAL_POS TRUE
45#endif
46
48#ifndef UWB_POSITIONING_USE_AS_GPS
49#define UWB_POSITIONING_USE_AS_GPS FALSE
50#endif
51
53#ifndef UWB_POSITIONING_USE_EKF
54#define UWB_POSITIONING_USE_EKF TRUE
55#endif
56
63#ifndef UWB_POSITIONING_NB_ANCHORS
64#define UWB_POSITIONING_NB_ANCHORS 3
65#endif
66
68#ifndef UWB_POSITIONING_RANGE_OFFSET
69#define UWB_POSITIONING_RANGE_OFFSET { 0.f, 0.f, 0.f }
70#endif
71
73#ifndef UWB_POSITIONING_RANGE_SCALE
74#define UWB_POSITIONING_RANGE_SCALE { 1.f, 1.f, 1.f }
75#endif
76
78#ifndef UWB_POSITIONING_TAG_ID
79#define UWB_POSITIONING_TAG_ID 0
80#endif
81
83#ifndef UWB_POSITIONING_INITIAL_HEADING
84#define UWB_POSITIONING_INITIAL_HEADING 0.f
85#endif
86
88#ifndef UWB_POSITIONING_TIMEOUT
89#define UWB_POSITIONING_TIMEOUT 500
90#endif
91
93#ifndef UWB_POSITIONING_NOISE_X
94#define UWB_POSITIONING_NOISE_X 0.1f
95#endif
96
97#ifndef UWB_POSITIONING_NOISE_Y
98#define UWB_POSITIONING_NOISE_Y 0.1f
99#endif
100
101#ifndef UWB_POSITIONING_NOISE_Z
102#define UWB_POSITIONING_NOISE_Z 0.1f
103#endif
104
105#ifndef UWB_POSITIONING_VEL_NOISE_X
106#define UWB_POSITIONING_VEL_NOISE_X 0.1f
107#endif
108
109#ifndef UWB_POSITIONING_VEL_NOISE_Y
110#define UWB_POSITIONING_VEL_NOISE_Y 0.1f
111#endif
112
113#ifndef UWB_POSITIONING_VEL_NOISE_Z
114#define UWB_POSITIONING_VEL_NOISE_Z 0.1f
115#endif
116
117#if UWB_POSITIONING_USE_EKF
120
121#define UWB_POSITIONING_EKF_UNINIT 0
122#define UWB_POSITIONING_EKF_POS_INIT 1
123#define UWB_POSITIONING_EKF_RUNNING 2
124
125#ifndef UWB_POSITIONING_EKF_P0_POS
126#define UWB_POSITIONING_EKF_P0_POS 1.0f
127#endif
128
129#ifndef UWB_POSITIONING_EKF_P0_SPEED
130#define UWB_POSITIONING_EKF_P0_SPEED 1.0f
131#endif
132
133#ifndef UWB_POSITIONING_EKF_Q
134#define UWB_POSITIONING_EKF_Q 4.0f
135#endif
136
137#ifndef UWB_POSITIONING_EKF_R_DIST
138#define UWB_POSITIONING_EKF_R_DIST 0.1f
139#endif
140
141#ifndef UWB_POSITIONING_EKF_R_SPEED
142#define UWB_POSITIONING_EKF_R_SPEED 0.1f
143#endif
144
145#endif // USE_EKF
146
149#if SITL
150#ifndef UWB_POSITIONING_ANCHOR_SIM_WP
151#define UWB_POSITIONING_ANCHOR_SIM_WP { WP_ANCHOR_1, WP_ANCHOR_2, WP_ANCHOR_3 }
152#endif
153#endif
154
156#if UWB_POSITIONING_LOG
158static bool log_started;
159#endif
160
161
162
181
183
185
190
197static const float scale[] = UWB_POSITIONING_RANGE_SCALE;
198
199static void process_data(struct UwbPositioning *uwb);
200
201static void uwb_ranging_cb(uint8_t __attribute__((unused)) sender_id, uint32_t __attribute__((unused)) stamp, uint16_t src_id, uint16_t dst_id, float range)
202{
203 for (int i = 0; i < UWB_POSITIONING_NB_ANCHORS; i++) {
204 bool from_me = uwb_positioning.anchors[i].id == dst_id && UWB_POSITIONING_TAG_ID == src_id;
205 bool to_me = uwb_positioning.anchors[i].id == src_id && UWB_POSITIONING_TAG_ID == dst_id;
206
207 if (from_me || to_me) {
208 uwb_positioning.raw_dist[i] = range;
209 // median filter for EKF
210 const float dist = scale[i] * (range - offset[i]);
211 // store scaled distance
213 // TODO: use received stamp instead
216 uwb_positioning.updated = true; // at least one of the anchor is updated
217 break;
218 }
219 }
220
222}
223
224#if UWB_POSITIONING_USE_AS_GPS
225static void send_gps_uwb_small(struct UwbPositioning *uwb)
226{
227 // rotate and convert to cm integer
228 float x = uwb->pos.x * cosf(uwb->initial_heading) - uwb->pos.y * sinf(uwb->initial_heading);
229 float y = uwb->pos.x * sinf(uwb->initial_heading) + uwb->pos.y * cosf(uwb->initial_heading);
230 struct EnuCoor_i enu_pos;
231 enu_pos.x = (int32_t) (x * 100.f);
232 enu_pos.y = (int32_t) (y * 100.f);
233 enu_pos.z = (int32_t) (uwb->pos.z * 100.f);
234
235 // Convert the ENU coordinates to ECEF
236 ecef_of_enu_point_i(&(uwb->gps_uwb.ecef_pos), &(uwb->ltp_def), &enu_pos);
237 SetBit(uwb->gps_uwb.valid_fields, GPS_VALID_POS_ECEF_BIT);
238
239 lla_of_ecef_i(&(uwb->gps_uwb.lla_pos), &(uwb->gps_uwb.ecef_pos));
240 SetBit(uwb->gps_uwb.valid_fields, GPS_VALID_POS_LLA_BIT);
241
242 // Convert ENU speed to ECEF
243 struct EnuCoor_i enu_speed;
244 enu_speed.x = (int32_t) (uwb->speed.x * 100.f);
245 enu_speed.y = (int32_t) (uwb->speed.y * 100.f);
246 enu_speed.z = (int32_t) (uwb->speed.z * 100.f);
247
248 VECT3_NED_OF_ENU(uwb->gps_uwb.ned_vel, enu_speed);
249 SetBit(uwb->gps_uwb.valid_fields, GPS_VALID_VEL_NED_BIT);
250
251 ecef_of_enu_vect_i(&uwb->gps_uwb.ecef_vel , &(uwb->ltp_def) , &enu_speed);
252 SetBit(uwb->gps_uwb.valid_fields, GPS_VALID_VEL_ECEF_BIT);
253
254 uwb->gps_uwb.gspeed = (int16_t)FLOAT_VECT2_NORM(enu_speed);
255 uwb->gps_uwb.speed_3d = (int16_t)FLOAT_VECT3_NORM(enu_speed);
256
257 // HMSL
258 uwb->gps_uwb.hmsl = uwb->ltp_def.hmsl + enu_pos.z * 10;
259 SetBit(uwb->gps_uwb.valid_fields, GPS_VALID_HMSL_BIT);
260
261#if defined(SECONDARY_GPS) && AHRS_USE_GPS_HEADING
262 // a second GPS is used to get heading
263 // ugly hack: it is a datalink GPS
264 uwb->gps_uwb.course = gps_datalink.course;
265#endif
266
267 uwb->gps_uwb.num_sv = 7;
268 uwb->gps_uwb.tow = get_sys_time_msec();
269 uwb->gps_uwb.fix = GPS_FIX_3D; // set 3D fix to true
270
271 // set gps msg time
272 uwb->gps_uwb.last_msg_ticks = sys_time.nb_sec_rem;
273 uwb->gps_uwb.last_msg_time = sys_time.nb_sec;
274 uwb->gps_uwb.last_3dfix_ticks = sys_time.nb_sec_rem;
275 uwb->gps_uwb.last_3dfix_time = sys_time.nb_sec;
276
277 // publish new GPS data
279 AbiSendMsgGPS(GPS_UWB_ID, now_ts, &(uwb->gps_uwb));
280}
281#endif
282
283#if UWB_POSITIONING_USE_AS_LOCAL_POS
284static void send_pos_estimate(struct UwbPositioning *uwb)
285{
287 // send POSITION_ESTIMATE type message
289 uwb->pos.x, uwb->pos.y, uwb->pos.z,
291 // send VELOCITY_ESTIMATE type message if EKF is running
292 if (uwb_positioning_use_ekf && uwb->ekf_running) {
294 uwb->speed.x, uwb->speed.y, uwb->speed.z,
296 }
297}
298#endif
299
306{
307 const float now = get_sys_time_float();
308 for (int i = 0; i < UWB_POSITIONING_NB_ANCHORS; i++) {
309 if (now - uwb->anchors[i].time > timeout) {
310 return true;
311 }
312 }
313 return false;
314}
315
319static inline bool check_and_compute_data(struct UwbPositioning *uwb)
320{
321 const float timeout = (float)UWB_POSITIONING_TIMEOUT / 1000.;
323 if (uwb->ekf_running) {
324 // filter is running
325 if (check_anchor_timeout(uwb, 5.f*timeout)) {
326 // no more valid data for a long time
327 uwb->ekf_running = false;
328 return false;
329 } else {
330 // run filter on each updated anchor
331 for (int i = 0; i < UWB_POSITIONING_NB_ANCHORS; i++) {
332 if (uwb->anchors[i].updated) {
333 ekf_range_update_dist(&uwb->ekf_range, uwb->anchors[i].distance,
334 uwb->anchors[i].pos);
335 uwb->anchors[i].updated = false;
336 }
337 }
338 uwb->pos = ekf_range_get_pos(&uwb->ekf_range);
339 uwb->speed = ekf_range_get_speed(&uwb->ekf_range);
340 return true;
341 }
342 } else {
343 // filter is currently not running,
344 // waiting for a new valid initial position
346 // no valid data
347 return false;
348 } else {
349 if (trilateration_compute(uwb->anchors, &(uwb->pos)) == 0) {
350 // got valid initial pos
351 struct EnuCoor_f speed = { 0.f, 0.f, 0.f };
352 ekf_range_set_state(&uwb->ekf_range, uwb->pos, speed);
353 uwb->ekf_running = true;
354 return true;
355 } else {
356 // trilateration failed
357 return false;
358 }
359 }
360 }
361 } else {
362 // Direct trilateration only
363 // if no timeout on anchors, run trilateration algorithm
364 return (check_anchor_timeout(uwb, timeout) == false &&
365 trilateration_compute(uwb->anchors, &(uwb->pos)) == 0);
366 }
367}
368
369static void process_data(struct UwbPositioning *uwb) {
370 // process if new data
371 if (uwb->updated) {
372 // send result if process returns true
374#if UWB_POSITIONING_USE_AS_GPS
375 // send fake GPS message for INS filters
377#endif
378#if UWB_POSITIONING_USE_AS_LOCAL_POS
379 // send a local postion estimate
381#endif
382 }
383#if UWB_POSITIONING_LOG
384 if (log_started) {
385 struct EnuCoor_f pos = *stateGetPositionEnu_f();
386 struct EnuCoor_f speed = *stateGetSpeedEnu_f();
387 struct FloatRates *rates = stateGetBodyRates_f();
389 float omega_z = -rates->p * MAT33_ELMT(*ned_to_body, 2, 0)
390 + rates->q * MAT33_ELMT(*ned_to_body, 2, 1)
391 + rates->r * MAT33_ELMT(*ned_to_body, 2, 2);
392 sdLogWriteLog(pprzLogFile, "%.3f %.3f %.3f %3.f %.3f %.3f %.3f %.3f %.3f %.3f %.3f %.3f %.3f %.3f %.3f %.3f\n",
402 pos.x,
403 pos.y,
404 pos.z,
405 speed.x,
406 speed.y,
407 speed.z,
408 omega_z);
409 }
410#endif
411 uwb->updated = false;
412 }
413}
414
421
422#if SITL
424
425#define UWB_POSITIONING_SITL_SYNC FALSE
426
428{
429#if !UWB_POSITIONING_SITL_SYNC
430 static int i = 0; // async data update (more realistic)
431#endif
432 // position of the aircraft
433 struct FloatVect3 *pos = (struct FloatVect3 *) (stateGetPositionEnu_f());
434 float time = get_sys_time_float();
435 // compute distance to each WP/anchor
436#if UWB_POSITIONING_SITL_SYNC
437 for (uint8_t i = 0; i < UWB_POSITIONING_NB_ANCHORS; i++) {
438#endif
439 struct FloatVect3 a_pos = {
440 WaypointX(wp_ids[i]),
441 WaypointY(wp_ids[i]),
443 };
444 struct FloatVect3 diff;
445 VECT3_DIFF(diff, (*pos), a_pos);
446 uwb->anchors[i].distance = float_vect3_norm(&diff);
447 uwb->anchors[i].time = time;
448 uwb->anchors[i].updated = true;
449 uwb->updated = true;
450
452#if UWB_POSITIONING_SITL_SYNC
453 }
454#endif
455 struct EnuCoor_f t_pos;
456 // direct trilat for debug
457 if (trilateration_compute(uwb->anchors, &t_pos) == 0) {
458 uwb->raw_dist[0] = t_pos.x;
459 uwb->raw_dist[1] = t_pos.y;
460 uwb->raw_dist[2] = t_pos.z;
461 }
462}
463#endif // SITL
464
466{
467 // init UWB positioning structure
469 uwb_positioning.pos.x = 0.f;
470 uwb_positioning.pos.y = 0.f;
471 uwb_positioning.pos.z = 0.f;
472 uwb_positioning.speed.x = 0.f;
473 uwb_positioning.speed.y = 0.f;
474 uwb_positioning.speed.z = 0.f;
475 uwb_positioning.updated = false;
476 for (int i = 0; i < UWB_POSITIONING_NB_ANCHORS; i++) {
477 uwb_positioning.raw_dist[i] = 0.f;
485 }
486
487 // gps structure init
494
495 struct LlaCoor_i llh_nav0; /* Height above the ellipsoid */
497 llh_nav0.lon = NAV_LON0;
498 /* NAV_ALT0 = ground alt above msl, NAV_MSL0 = geoid-height (msl) over ellipsoid */
499 llh_nav0.alt = NAV_ALT0 + NAV_MSL0;
501
502 // init trilateration algorithm
504
512 for (int i = 0; i < UWB_POSITIONING_NB_ANCHORS; i++) {
514 }
515
517
519}
520
522{
528 }
529 } else {
530 uwb_positioning.ekf_running = false; // init sequence will be required at next run
531 }
532#if SITL
533 // compute position from WP for simulation
536#endif
537#if UWB_POSITIONING_USE_AS_GPS
538 // Check for GPS timeout
540#endif
541#if UWB_POSITIONING_LOG
542 if (pprzLogFile != -1) {
543 if (!log_started) {
545 "d1 t1 d2 t2 d3 t3 x y z gps_x gps_y gps_z vx vy vz omega\n");
546 log_started = true;
547 }
548 }
549#endif
550}
551
557
559{
560 float buf[12];
561 buf[0] = uwb_positioning.anchors[0].distance;
562 buf[1] = uwb_positioning.anchors[1].distance;
563 buf[2] = uwb_positioning.anchors[2].distance;
564 buf[3] = uwb_positioning.raw_dist[0];
565 buf[4] = uwb_positioning.raw_dist[1];
566 buf[5] = uwb_positioning.raw_dist[2];
567 buf[6] = uwb_positioning.pos.x;
568 buf[7] = uwb_positioning.pos.y;
569 buf[8] = uwb_positioning.pos.z;
570 buf[9] = uwb_positioning.speed.x;
571 buf[10] = uwb_positioning.speed.y;
572 buf[11] = uwb_positioning.speed.z;
574}
575
576
577
578
584
590
596
Main include for ABI (AirBorneInterface).
#define ABI_BROADCAST
Broadcast address.
Definition abi_common.h:59
Event structure to store callbacks in a linked list.
Definition abi_common.h:68
#define GPS_UWB_ID
uint32_t get_sys_time_usec(void)
Get the time in microseconds since startup.
uint32_t get_sys_time_msec(void)
Get the time in milliseconds since startup.
#define WaypointX(_wp)
Definition common_nav.h:45
#define WaypointAlt(_wp)
waypoint altitude in m above MSL
Definition common_nav.h:48
#define WaypointY(_wp)
Definition common_nav.h:46
void ekf_range_update_noise(struct EKFRange *ekf_range, float Q_sigma2, float R_dist, float R_speed)
Update process and measurement noises.
Definition ekf_range.c:93
void ekf_range_set_state(struct EKFRange *ekf_range, struct EnuCoor_f pos, struct EnuCoor_f speed)
Set initial state vector.
Definition ekf_range.c:55
struct EnuCoor_f ekf_range_get_speed(struct EKFRange *ekf_range)
Get current speed.
Definition ekf_range.c:84
void ekf_range_update_dist(struct EKFRange *ekf_range, float dist, struct EnuCoor_f anchor)
correction step
Definition ekf_range.c:143
struct EnuCoor_f ekf_range_get_pos(struct EKFRange *ekf_range)
Get current pos.
Definition ekf_range.c:75
void ekf_range_init(struct EKFRange *ekf_range, float P0_pos, float P0_speed, float Q_sigma2, float R_dist, float R_speed, float dt)
Init EKF_range internal struct.
Definition ekf_range.c:29
void ekf_range_predict(struct EKFRange *ekf_range)
propagate dynamic model
Definition ekf_range.c:119
EKF_range structure.
Definition ekf_range.h:43
void gps_periodic_check(struct GpsState *gps_s)
Periodic GPS check.
Definition gps.c:290
Device independent GPS code (interface)
uint32_t sacc
speed accuracy in cm/s
Definition gps.h:106
uint32_t cacc
course accuracy in rad*1e7
Definition gps.h:107
int32_t course
GPS course over ground in rad*1e7, [0, 2*Pi]*1e7 (CW/north)
Definition gps.h:102
#define GPS_VALID_VEL_ECEF_BIT
Definition gps.h:51
#define GPS_VALID_VEL_NED_BIT
Definition gps.h:52
#define GPS_VALID_POS_LLA_BIT
Definition gps.h:49
uint16_t pdop
position dilution of precision scaled by 100
Definition gps.h:108
#define GPS_FIX_NONE
No GPS fix.
Definition gps.h:42
#define GPS_VALID_POS_ECEF_BIT
Definition gps.h:48
#define GPS_VALID_HMSL_BIT
Definition gps.h:53
uint32_t pacc
position accuracy in cm
Definition gps.h:103
uint8_t comp_id
id of current gps
Definition gps.h:92
#define GPS_FIX_3D
3D GPS fix
Definition gps.h:44
uint8_t fix
status of fix
Definition gps.h:110
data structure for GPS information
Definition gps.h:90
float q
in rad/s
float p
in rad/s
float r
in rad/s
float psi
in radians
static float float_vect3_norm(const struct FloatVect3 *v)
#define FLOAT_VECT3_NORM(_v)
#define FLOAT_VECT2_NORM(_v)
rotation matrix
angular rates
#define VECT3_DIFF(_c, _a, _b)
#define MAT33_ELMT(_m, _row, _col)
int32_t lat
in degrees*1e7
int32_t y
North.
int32_t x
East.
void ecef_of_enu_vect_i(struct EcefCoor_i *ecef, struct LtpDef_i *def, struct EnuCoor_i *enu)
Rotate a vector from ENU to ECEF.
#define VECT3_NED_OF_ENU(_o, _i)
void ecef_of_enu_point_i(struct EcefCoor_i *ecef, struct LtpDef_i *def, struct EnuCoor_i *enu)
Convert a point in local ENU to ECEF.
void lla_of_ecef_i(struct LlaCoor_i *out, struct EcefCoor_i *in)
Convert a ECEF to LLA.
void ltp_def_from_lla_i(struct LtpDef_i *def, struct LlaCoor_i *lla)
vector in East North Up coordinates
vector in Latitude, Longitude and Altitude
definition of the local (flat earth) coordinate system
static struct FloatRMat * stateGetNedToBodyRMat_f(void)
Get vehicle body attitude rotation matrix (float).
Definition state.h:1308
static struct FloatEulers * stateGetNedToBodyEulers_f(void)
Get vehicle body attitude euler angles (float).
Definition state.h:1314
static struct EnuCoor_f * stateGetPositionEnu_f(void)
Get position in local ENU coordinates (float).
Definition state.h:848
static struct FloatRates * stateGetBodyRates_f(void)
Get vehicle body angular rate (float).
Definition state.h:1375
static struct EnuCoor_f * stateGetSpeedEnu_f(void)
Get ground speed in local ENU coordinates (float).
Definition state.h:1058
static FILE * pprzLogFile
uint16_t foo
Definition main_demo5.c:58
static float update_median_filter_f(struct MedianFilterFloat *filter, float new_data)
static void init_median_filter_f(struct MedianFilterFloat *filter, uint8_t size)
bool log_started
static float timeout
float y
in meters
float x
in meters
float z
in meters
vector in East North Up coordinates Units: meters
API to get/set the generic vehicle states.
volatile uint32_t nb_sec
full seconds since startup
Definition sys_time.h:72
volatile uint32_t nb_sec_rem
remainder of seconds since startup in CPU_TICKS
Definition sys_time.h:73
static float get_sys_time_float(void)
Get the time in seconds since startup.
Definition sys_time.h:168
int trilateration_init(struct Anchor *anchors)
Init internal trilateration structures.
int trilateration_compute(struct Anchor *anchors, struct EnuCoor_f *pos)
Compute trilateration based on the latest measurments.
float distance
last measured distance
struct EnuCoor_f pos
position of the anchor
uint16_t id
anchor ID
bool updated
new data available
float time
time of the last received data
Anchor structure.
arch independent UART (Universal Asynchronous Receiver/Transmitter) API
#define UWB_POSITIONING_VEL_NOISE_Z
struct EKFRange ekf_range
EKF filter.
float initial_heading
initial heading correction
#define UWB_POSITIONING_NOISE_Y
void WEAK uwb_range(uint16_t id)
Weak empty implementation.
void uwb_positioning_report(void)
struct LtpDef_i ltp_def
ltp reference
#define UWB_POSITIONING_TIMEOUT
default timeout (in ms)
static void process_data(struct UwbPositioning *uwb)
#define UWB_POSITIONING_RANGE_SCALE
default scale factor, applied to individual distances
static bool check_anchor_timeout(struct UwbPositioning *uwb, float timeout)
check timeout for each anchor
void uwb_positioning_update_ekf_q(float v)
settings handler
void uwb_positioning_update_ekf_r_dist(float v)
bool uwb_positioning_use_ekf
enable EKF filtering
#define UWB_POSITIONING_INITIAL_HEADING
default initial heading correction between anchors frame and global frame
#define UWB_POSITIONING_TAG_ID
My UWB tag id.
void uwb_positioning_init(void)
static bool check_and_compute_data(struct UwbPositioning *uwb)
check new data and compute with the proper algorithm
#define UWB_POSITIONING_VEL_NOISE_Y
bool updated
new anchor data available
struct EnuCoor_f speed
local speed in anchors frame
static const float pos_z[]
void uwb_positioning_update_ekf_r_speed(float v)
float uwb_positioning_ekf_r_speed
void uwb_positioning_reset_heading_ref(void)
Reset reference heading to current heading AHRS/INS should be aligned before calling this function.
struct Anchor anchors[UWB_POSITIONING_NB_ANCHORS]
anchors data
#define UWB_POSITIONING_NOISE_Z
#define UWB_POSITIONING_VEL_NOISE_X
struct EnuCoor_f pos
local pos in anchors frame
static abi_event uwb_ranging_ev
static const float offset[]
void uwb_positioning_range_periodic(void)
float uwb_positioning_ekf_r_dist
static const uint16_t ids[]
init arrays from airframe file
uint8_t anchor_ranging_idx
Next anchor index (in the anchors array) to be ranged.
static const float scale[]
struct GpsState gps_uwb
"fake" gps structure
#define UWB_POSITIONING_RANGE_OFFSET
default offset, applied to individual distances
float raw_dist[UWB_POSITIONING_NB_ANCHORS]
raw distance from anchors
#define UWB_POSITIONING_NOISE_X
UWB positioning output noise.
bool ekf_running
EKF logic status.
static void uwb_ranging_cb(uint8_t sender_id, uint32_t stamp, uint16_t src_id, uint16_t dst_id, float range)
#define UWB_POSITIONING_NB_ANCHORS
Number of anchors.
struct MedianFilterFloat mf[UWB_POSITIONING_NB_ANCHORS]
median filter for EKF input data
static const float pos_y[]
static const float pos_x[]
float uwb_positioning_ekf_q
process and measurements noise
void uwb_positioning_periodic(void)
static struct UwbPositioning uwb_positioning
#define UWB_POSITIONING_USE_EKF
TRUE if EKF range filter is use.
waypoints to use as anchors in simulation
unsigned short uint16_t
Typedef defining 16 bit unsigned short type.
int int32_t
Typedef defining 32 bit int type.
unsigned int uint32_t
Typedef defining 32 bit unsigned int type.
short int16_t
Typedef defining 16 bit short type.
unsigned char uint8_t
Typedef defining 8 bit unsigned char type.