Paparazzi UAS v7.0_unstable
Paparazzi is a free software Unmanned Aircraft System.
Loading...
Searching...
No Matches
aoa_t4.c
Go to the documentation of this file.
1/*
2 * Copyright (C) 2024 The Paparazzi Team
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
30#include "generated/airframe.h"
31#include "modules/core/abi.h"
32#include "state.h"
33#include "std.h"
34#include "mcu_periph/uart.h"
35#include "pprzlink/messages.h"
37// #include "modules/sensors/actuators_t4_uart.h"
38
40#ifndef AOA_ANGLE_OFFSET
41#define AOA_ANGLE_OFFSET M_PI
42#endif
43
45#ifndef AOA_T4_OFFSET
46#define AOA_T4_OFFSET 0.0f
47#endif
48
50#ifndef AOA_T4_USE_FILTER
51#define AOA_T4_USE_FILTER FALSE
52#endif
53
55
59#ifndef AOA_T4_FILTER
60#define AOA_T4_FILTER 0.15f
61#endif
62
64#if AOA_T4_REVERSE
65#define AOA_T4_SIGN -1
66#else
67#define AOA_T4_SIGN 1
68#endif
69
70// Enable telemetry report
71#ifndef AOA_T4_SYNC_SEND
72#define AOA_T4_SYNC_SEND FALSE
73#endif
74
76#ifndef AOA_T4_SERVO_ID
77#error "No AOA_T4_SERVO_ID defined, however it must be defined to be able to use the aoa_t4 module"
78#endif
79
80#ifdef AOA_T4_USE_FILTER
82#ifndef AOA_T4_FILTER_SAMPLING_TIME
83#define AOA_T4_FILTER_SAMPLING_TIME 0.0005 // 200Hz
84#endif
85#endif
86
88
90#ifndef AOA_T4_USE_COMPENSATION
91#define AOA_T4_USE_COMPENSATION FALSE
92#endif
93
94// linear fn; aoa += A*theta + B;
95// aoa += A1*theta+B1 when theta >= 0
96// aoa += A2*theta+B2 when theta < 0
97#ifndef AOA_T4_COMP_A1
98#define AOA_T4_COMP_A1 0.0f
99#endif
100
101#ifndef AOA_T4_COMP_B1
102#define AOA_T4_COMP_B1 0.0f
103#endif
104
105#ifndef AOA_T4_COMP_A2
106#define AOA_T4_COMP_A2 -0.5457f // TODO: Explain the magic number...
107#endif
108
109#ifndef AOA_T4_COMP_B2
110#define AOA_T4_COMP_B2 0.0f
111#endif
112
113/* SSA */
114
116#ifndef SSA_ANGLE_OFFSET
117#define SSA_ANGLE_OFFSET M_PI
118#endif
119
121#ifndef SSA_T4_OFFSET
122#define SSA_T4_OFFSET 0.0f
123#endif
124
126#ifndef SSA_T4_USE_FILTER
127#define SSA_T4_USE_FILTER FALSE
128#endif
129
130#ifndef SSA_T4_FILTER
131#define SSA_T4_FILTER 0.20f
132#endif
133
134#if SSA_T4_REVERSE
135#define SSA_T4_SIGN -1
136#else
137#define SSA_T4_SIGN 1
138#endif
139
140#ifdef SSA_T4_USE_FILTER
142//Use same AOA_T4_FILTER_SAMPLING_TIME
143#endif
144
146
148
150
156
158
159#if PERIODIC_TELEMETRY
161
162static void send_aoa(struct transport_tx *trans, struct link_device *dev)
163{
164 // FIXME: Add a "sensor_id" uint8_t to AOA message to nicer send sideslip more important, be able to combine all AOA sensors like AOA_adc, AOA_pwm etc sensors
165 switch (aoa_send_type) {
168 break;
169 case SEND_TYPE_AOA:
170 default:
172 break;
173 }
174}
175
176#endif
177
178/* The incoming angle from T4 is Degrees x 100 from -18000 to 18000 need to be re-mapped from 0 upto 36000
179 else it will not fit the raw filed with uint32 type as in default AOA raw message */
181{
182 int16_t input_min = -18000; // The default value in T4 Actuators Board code
183 int16_t input_max = 18000; // Also max default in T4 Actuators Board code
184 // Conversion range
187 // Perform the mapping
189 return result;
190}
191
193{
195
196 int16_t angle = 0;
197
198 switch (AOA_T4_SERVO_ID)
199 {
200 /*
201 Note that the T4 Actuator Board has a max of 10 serial bus servos that can give real feedback,
202 the PWM devices 11 and 12 do NOT GIVE real angle FEEDBACK
203 */
204
205 case 1:
206 angle = actuators_t4_in_ptr->servo_1_angle;
207 break;
208 case 2:
209 angle = actuators_t4_in_ptr->servo_2_angle;
210 break;
211 case 3:
212 angle = actuators_t4_in_ptr->servo_3_angle;
213 break;
214 case 4:
215 angle = actuators_t4_in_ptr->servo_4_angle;
216 break;
217 case 5:
218 angle = actuators_t4_in_ptr->servo_5_angle;
219 break;
220 case 6:
221 angle = actuators_t4_in_ptr->servo_6_angle;
222 break;
223 case 7:
224 angle = actuators_t4_in_ptr->servo_7_angle;
225 break;
226 case 8:
227 angle = actuators_t4_in_ptr->servo_8_angle;
228 break;
229 case 9:
230 angle = actuators_t4_in_ptr->servo_9_angle;
231 break;
232 case 10:
233 angle = actuators_t4_in_ptr->servo_10_angle;
234 break;
235 default:
236 break;
237 }
238
239 aoa_t4.raw = convert_angle_x100_to_raw(angle); // To adhere to default message type of uint32_t so from 0 to 36000
240
241#ifdef SSA_T4_SERVO_ID
242
243 angle = 0;
244
245 switch (SSA_T4_SERVO_ID)
246 {
247 case 1:
248 angle = actuators_t4_in_ptr->servo_1_angle;
249 break;
250 case 2:
251 angle = actuators_t4_in_ptr->servo_2_angle;
252 break;
253 case 3:
254 angle = actuators_t4_in_ptr->servo_3_angle;
255 break;
256 case 4:
257 angle = actuators_t4_in_ptr->servo_4_angle;
258 break;
259 case 5:
260 angle = actuators_t4_in_ptr->servo_5_angle;
261 break;
262 case 6:
263 angle = actuators_t4_in_ptr->servo_6_angle;
264 break;
265 case 7:
266 angle = actuators_t4_in_ptr->servo_7_angle;
267 break;
268 case 8:
269 angle = actuators_t4_in_ptr->servo_8_angle;
270 break;
271 case 9:
272 angle = actuators_t4_in_ptr->servo_9_angle;
273 break;
274 case 10:
275 angle = actuators_t4_in_ptr->servo_10_angle;
276 break;
277 default:
278 break;
279 }
280
282
283#endif //SSA_T4_SERVO_ID
284
285}
286
292
298
299void aoa_t4_init(void)
300{
301 aoa_t4.raw = 0;
302 aoa_t4.angle = 0.0f;
305
306 ssa_t4.raw = 0;
307 ssa_t4.angle = 0.0f;
310
311 aoa_send_type = SEND_TYPE_AOA; //Per default send AOA
312
313#if AOA_T4_USE_FILTER
315#endif
316
317#if SSA_T4_USE_FILTER
319#endif
320
321 // IN indicates INcoming values from the T4 Actuator Board
323
324#if PERIODIC_TELEMETRY
326#endif
327}
328
330{
331#if USE_AOA || USE_SIDESLIP
332 uint8_t flag = 0;
333#endif
334
335 /* Convert raw value of degrees x 100 (0 to 36000) to real degrees and to radians and add offsets */
336 float a_rad;
337 a_rad = AOA_T4_SIGN * ((float)(aoa_t4.raw / 100.0f) * (M_PI / 180.0f)) + aoa_t4.offset + AOA_ANGLE_OFFSET;
338 if (a_rad > M_PI) a_rad -= 2 * M_PI; // Adjust range to be from -PI to PI
340
341#if AOA_T4_USE_COMPENSATION
343 // First order fn
344 if (eulers_t4.theta >= 0)
345 {
347 }
348 else
349 {
351 }
352#endif
353
354#if AOA_T4_USE_FILTER
356#endif
357
358 a_rad = SSA_T4_SIGN * ((float)(ssa_t4.raw / 100.0f) * (M_PI / 180.0f)) + ssa_t4.offset + SSA_ANGLE_OFFSET;
359 if (a_rad > M_PI) a_rad -= 2 * M_PI;
361
362#if SSA_T4_USE_FILTER
364#endif
365
366 // Do set values in the state for AOA
367#if USE_AOA
368 SetBit(flag, 0); // Bit 1 is for AOA
369#endif
370
371// Do set values in the state for sideslip
372#ifdef USE_SIDESLIP
373 SetBit(flag, 1); // Bit 2 is for SSA
374#endif
375
376#if USE_AOA || USE_SIDESLIP
378#endif
379
380#if AOA_T4_SYNC_SEND
381 RunOnceEvery(10, send_aoa(&(DefaultChannel).trans_tx, &(DefaultDevice).device));
382#endif
383
384}
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 AOA_PWM_ID
Aoa_Type
Selection of sensor type to be send over telemetry.
Definition aoa_pwm.h:57
@ SEND_TYPE_SIDESLIP
Definition aoa_pwm.h:59
@ SEND_TYPE_AOA
Definition aoa_pwm.h:58
#define AOA_T4_COMP_B1
Definition aoa_t4.c:102
void aoa_t4_update(void)
Definition aoa_t4.c:329
float aoa_t4_a2
Definition aoa_t4.c:154
Butterworth2LowPass aoa_t4_lowpass_filter
Servo ID to use for the modified servo as AOA sensor.
Definition aoa_t4.c:81
float aoa_t4_b2
Definition aoa_t4.c:155
struct Aoa_T4 ssa_t4
Definition aoa_t4.c:145
float aoa_t4_b1
Definition aoa_t4.c:153
#define AOA_T4_FILTER
Default filter value for reasonable minimum filtering.
Definition aoa_t4.c:60
void aoa_t4_init_filters(void)
Definition aoa_t4.c:287
#define AOA_T4_OFFSET
Small offset value in radians to get the sensor perfectly lined out.
Definition aoa_t4.c:46
struct FloatEulers eulers_t4
Definition aoa_t4.c:151
Butterworth2LowPass ssa_t4_lowpass_filter
Definition aoa_t4.c:141
#define SSA_T4_OFFSET
Small offset value in radians to get the sensor perfectly lined out.
Definition aoa_t4.c:122
struct ActuatorsT4In actuators_t4_in_local
Definition aoa_t4.c:147
void ssa_t4_init_filters(void)
Definition aoa_t4.c:293
struct Aoa_T4 aoa_t4
Definition aoa_t4.c:87
void aoa_t4_init(void)
Definition aoa_t4.c:299
#define AOA_T4_COMP_A1
Definition aoa_t4.c:98
#define SSA_ANGLE_OFFSET
Default offset value (assuming 0 SSA is in the middle of the range)
Definition aoa_t4.c:117
#define AOA_T4_SIGN
To set reverse direction on readings use true.
Definition aoa_t4.c:67
static void actuators_t4_abi_in(uint8_t sender_id, struct ActuatorsT4In *actuators_t4_in_ptr, float *actuators_t4_extra_data_in_ptr)
Definition aoa_t4.c:192
static abi_event ACTUATORS_T4_IN
Definition aoa_t4.c:149
#define AOA_T4_COMP_A2
Definition aoa_t4.c:106
#define AOA_ANGLE_OFFSET
Default offset value (assuming 0 AOA is in the middle of the range)
Definition aoa_t4.c:41
float aoa_t4_a1
Definition aoa_t4.c:152
enum Aoa_Type aoa_send_type
Definition aoa_t4.c:157
uint32_t convert_angle_x100_to_raw(int16_t angle)
Definition aoa_t4.c:180
static void send_aoa(struct transport_tx *trans, struct link_device *dev)
Definition aoa_t4.c:162
#define AOA_T4_COMP_B2
Definition aoa_t4.c:110
#define SSA_T4_SIGN
Definition aoa_t4.c:137
#define SSA_T4_FILTER
Definition aoa_t4.c:131
#define AOA_T4_FILTER_SAMPLING_TIME
Definition aoa_t4.c:83
Angle of Attack and optionally Sideslip Angle sensor using T4 Actuators Board and a modified serial b...
float angle
Angle of attack in radians after applying direction and offset.
Definition aoa_t4.h:41
float filter
Filter level for sensor output, where 0.0 is no filtering and 0.95 for extreme filtering,...
Definition aoa_t4.h:43
float offset
Angle of attack offset in radians.
Definition aoa_t4.h:42
uint32_t raw
Measurement in degrees times 100 from the sensor before applying direction and offset and unit scale ...
Definition aoa_t4.h:40
float theta
in radians
void float_eulers_of_quat_zxy(struct FloatEulers *e, struct FloatQuat *q)
euler rotation 'ZXY' This rotation order is useful if you need 90 deg pitch
euler angles
static struct FloatQuat * stateGetNedToBodyQuat_f(void)
Get vehicle body attitude quaternion (float).
Definition state.h:1294
Simple first order low pass filter with bilinear transform.
static void init_butterworth_2_low_pass(Butterworth2LowPass *filter, float tau, float sample_time, float value)
Init a second order Butterworth filter.
static float update_butterworth_2_low_pass(Butterworth2LowPass *filter, float value)
Update second order Butterworth low pass filter state with a new value.
Second order low pass filter structure.
uint16_t foo
Definition main_demo5.c:58
API to get/set the generic vehicle states.
static const struct usb_device_descriptor dev
Definition usb_ser_hw.c:74
int16_t register_periodic_telemetry(struct periodic_telemetry *_pt, uint16_t _id, telemetry_cb _cb)
Register a telemetry callback function.
Definition telemetry.c:51
Periodic telemetry system header (includes downlink utility and generated code).
#define DefaultPeriodic
Set default periodic telemetry.
Definition telemetry.h:66
arch independent UART (Universal Asynchronous Receiver/Transmitter) API
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 long long uint64_t
unsigned char uint8_t
Typedef defining 8 bit unsigned char type.