Paparazzi UAS v7.0_unstable
Paparazzi is a free software Unmanned Aircraft System.
Loading...
Searching...
No Matches
rotwing_state.c
Go to the documentation of this file.
1/*
2 * Copyright (C) 2023 Dennis van Wijngaarden <D.C.vanWijngaarden@tudelft.nl>
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 */
20
30#include "modules/core/abi.h"
31
32
33/* Minimum measured RPM to consider the hover motors running (RPM) */
34#ifndef ROTWING_QUAD_MIN_RPM
35#define ROTWING_QUAD_MIN_RPM 400
36#endif
37
38/* Minimum measured RPM to consider the pusher motor running (RPM) */
39#ifndef ROTWING_PUSH_MIN_RPM
40#define ROTWING_PUSH_MIN_RPM 300
41#endif
42
43/* Timeout for the RPM feedback (seconds) */
44#ifndef ROTWING_RPM_TIMEOUT
45#define ROTWING_RPM_TIMEOUT 1.0
46#endif
47
48/* Minimum thrust to consider the hover motors idling (PPRZ) */
49#ifndef ROTWING_QUAD_IDLE_MIN_THRUST
50#define ROTWING_QUAD_IDLE_MIN_THRUST 100
51#endif
52
53/* Minimum time for the hover motors to be considered idling (seconds) */
54#ifndef ROTWING_QUAD_IDLE_TIMEOUT
55#define ROTWING_QUAD_IDLE_TIMEOUT 0.4
56#endif
57
58/* Minimum measured skew angle to consider the rotating wing in fixedwing (deg) */
59#ifndef ROTWING_FW_SKEW_ANGLE
60#define ROTWING_FW_SKEW_ANGLE 85.0
61#endif
62
63/* TODO: Give a name.... */
64#ifndef ROTWING_SKEW_BACK_MARGIN
65#define ROTWING_SKEW_BACK_MARGIN 5.0
66#endif
67
68/* Maximum angle difference between the measured skew and modelled skew for skew failure detection */
69#ifndef ROTWING_SKEW_REF_MODEL_MAX_DIFF
70#define ROTWING_SKEW_REF_MODEL_MAX_DIFF 5.f
71#endif
72
73/* Skew angle at which the mininum airspeed starts its linear portion */
74#ifndef ROTWING_MIN_AIRSPEED_SLOPE_START_ANGLE
75#define ROTWING_MIN_AIRSPEED_SLOPE_START_ANGLE 30.0
76#endif
77
78/* Amount of time the airspeed needs to be below the FW_MIN_AIRSPEED */
79#ifndef ROTWING_FW_STALL_TIMEOUT
80#define ROTWING_FW_STALL_TIMEOUT 0.5
81#endif
82
83/* Fix for not having double can busses */
84#ifndef SERVO_BMOTOR_PUSH_IDX
85#define SERVO_BMOTOR_PUSH_IDX SERVO_MOTOR_PUSH_IDX
86#endif
87
88/* Fix for not having double can busses */
89#ifndef SERVO_BROTATION_MECH_IDX
90#define SERVO_BROTATION_MECH_IDX SERVO_ROTATION_MECH_IDX
91#endif
92
94#ifndef ROTWING_STATE_ACT_FEEDBACK_ID
95#define ROTWING_STATE_ACT_FEEDBACK_ID ABI_BROADCAST
96#endif
100#if PERIODIC_TELEMETRY
102static void send_rotating_wing_state(struct transport_tx *trans, struct link_device *dev)
103{
104 // Set the status
106 status.value = 0;
107 status.skew_angle_valid = rotwing_state_skew_angle_valid();
108 status.hover_motors_enabled = rotwing_state.hover_motors_enabled;
109 status.hover_motors_idle = rotwing_state_hover_motors_idling();
110 status.hover_motors_running = rotwing_state_hover_motors_running();
111 status.pusher_motor_running = rotwing_state_pusher_motor_running();
112 status.skew_forced = rotwing_state.force_skew;
113
114 // Send the message
116 uint8_t nav_state = rotwing_state.nav_state;
118 &state,
119 &nav_state,
120 &status.value,
126}
127#endif // PERIODIC_TELEMETRY
128
157
163 static float last_idle_time = 0;
164 // Check if hover motors are idling and reset timer
167 }
168
169 // Check if we exceeded the idle timeout
171 return true;
172 }
173 return false;
174}
175
177{
178 /* Get some genericly used variables */
179 static float last_stall_time = 0;
183 Bound(meas_skew_angle, 0, 90); // Bound to prevent errors
184
187 }
188
189 /* Override modes if flying with RC */
192 // Kill mode
195 }
196 // ATT and ATT_FWD
200 } else {
202 }
203 }
204 }
205
206 /* Handle the quad motors on/off state */
209 }
213 }
214 else {
216 }
217
218
219 /* Calculate min/max airspeed bounds based on skew angle */
224
228 }
229
230
231 /* Handle the skew angle setpoint */
233 // Do nothing
234 }
237 }
240 }
243 }
246 }
247 else {
248 // SKEWING function based on Vair
252 // Hysteresis do nothing
255 } else {
257 }
258 }
260
261
262 /* Handle the airspeed bounding */
267 }
271 }
275 }
279 }
280 else{
283 }
284
285 // Override failing skewing while fwd
286 /*if(meas_skew_angle > 70 && rotwing_state_.skewing_failing) {
287 rotwing_state.min_airspeed = 0; // Vstall + margin
288 rotwing_state.max_airspeed = 0; // Max airspeed FW
289 }*/
290
292 /* Set navigation/guidance settings */
293 nav_max_deceleration_sp = ROTWING_FW_MAX_DECELERATION * meas_skew_angle / 90.f + ROTWING_QUAD_MAX_DECELERATION * (90.f - meas_skew_angle) / 90.f; //TODO: Do we really want to based this on the skew?
294
295
296 /* Calculate the skew command */
297 float servo_pprz_cmd = MAX_PPRZ * (rotwing_state.sp_skew_angle_deg - 45.f) / 45.f;
299
300 // Rotate with second order filter
301 static float rotwing_state_skew_p_cmd = -MAX_PPRZ;
302 static float rotwing_state_skew_d_cmd = 0;
303
310
311#if (ROTWING_SKEW_REF_MODEL || USE_NPS)
313#else
315#endif
316#ifdef COMMAND_ROT_MECH
318#endif
319
320 /* Add simulation feedback for the skewing and RPM */
321#if USE_NPS
322 // Export to the index of the SKEW in the NPS_ACTUATOR_NAMES array
323#ifdef COMMAND_ROT_MECH
324 commands[COMMAND_ROT_MECH] = (rotwing_state.skew_cmd + MAX_PPRZ) / 2.f; // Scale to simulation command
325#else
326 actuators_pprz[INDI_NUM_ACT] = (rotwing_state.skew_cmd + MAX_PPRZ) / 2.f; // Scale to simulation command
327#endif
328 // SEND ABI Message to ctr_eff_sched, ourself and other modules that want Actuator position feedback
329 struct act_feedback_t feedback;
330 feedback.idx = SERVO_ROTATION_MECH_IDX;
331 feedback.position = 0.5f * M_PI - RadOfDeg((float) rotwing_state.skew_cmd / MAX_PPRZ * 45.f + 45.f);
332 feedback.set.position = true;
333
334 // Send ABI message (or simulate failure)
337 }
338
339 // Simulate to always have RPM if on and active feedback
345 for(uint8_t i = 0; i < 5; i++) {
347 }
348
349#ifdef SITL
351 rotwing_state.meas_rpm[0] = 0;
352 rotwing_state.meas_rpm[1] = 0;
353 rotwing_state.meas_rpm[2] = 0;
354 rotwing_state.meas_rpm[3] = 0;
355 }
356
358 rotwing_state.meas_rpm[4] = 0;
359 }
360#endif
361
362#endif
363}
364
367{
369 for (int i = 0; i < num_act_message; i++) {
370 int idx = feedback_msg[i].idx;
371
372 // Check for wing rotation feedback
374 // Get wing rotation angle from sensor
375 float skew_angle_rad = 0.5 * M_PI - feedback_msg[i].position;
378 }
379
380 // Get the RPM feedbacks of the motors
381 if (feedback_msg[i].set.rpm) {
385 } else if ((idx == SERVO_MOTOR_RIGHT_IDX) || (idx == SERVO_BMOTOR_RIGHT_IDX)) {
388 } else if ((idx == SERVO_MOTOR_BACK_IDX) || (idx == SERVO_BMOTOR_BACK_IDX)) {
391 } else if ((idx == SERVO_MOTOR_LEFT_IDX) || (idx == SERVO_BMOTOR_LEFT_IDX)) {
394 } else if ((idx == SERVO_MOTOR_PUSH_IDX) || (idx == SERVO_BMOTOR_PUSH_IDX)) {
397 }
398 }
399 }
400}
401
418
420 // Check if pusher motor is running
422 return true;
423 } else {
424 return false;
425 }
426}
427
429 // Check if the measured skew angle is timed out and the reference model is matching
432
433 return (!skew_timeout && skew_angle_match);
434}
435
439
440
441/* TODO move these rotwing navigation helper functions to an appropriate module/file */
443 // Get circle waypoint coordinates in NED
444 struct FloatVect3 circ_ned = {.x = waypoints[wp_id].enu_f.y,
445 .y = waypoints[wp_id].enu_f.x,
446 .z = -waypoints[wp_id].enu_f.z};
447
448 // Get drone position coordinates in NED
450 .y = stateGetPositionNed_f()->y,
451 .z = stateGetPositionNed_f()->z};
452
453 // Get vector pointing from drone to waypoint
456
457 static struct FloatVect3 x_axis = {.x = 1, .y = 0, .z = 0};
458 static struct FloatVect3 z_axis = {.x = 0, .y = 0, .z = 1};
459 struct FloatVect3 att_NED;
461
463
467
468 float body_to_wp_angle_rad = atan2f(y, x);
469
470 if (body_to_wp_angle_rad >= 0.f) {
471 return true; // CCW circle
472 } else {
473 return false; // CW circle
474 }
475}
476
478
479 // Get drone position coordinates in NED
481 .y = stateGetPositionNed_f()->x,
482 .z = -stateGetPositionNed_f()->z};
483
484 static struct FloatVect3 x_axis = {.x = 1, .y = 0, .z = 0};
485 struct FloatVect3 x_att_NED;
486
488
489 // set the new transition WP coordinates 100m ahead of the drone
490 target_enu.x = 100.f * x_att_NED.y + target_enu.x;
491 target_enu.y = 100.f * x_att_NED.x + target_enu.y;
492
494
495 // Send waypoint update every half second
496 RunOnceEvery(100 / 2, {
497 // Send to the GCS that the waypoint has been moved
499 &waypoints[wp_id].enu_i.x,
500 &waypoints[wp_id].enu_i.y,
501 &waypoints[wp_id].enu_i.z);
502 });
503
504}
505
506void rotwing_state_update_WP_height(uint8_t wp_id, float height) {
507 struct EnuCoor_f target_enu = {.x = waypoints[wp_id].enu_f.x,
508 .y = waypoints[wp_id].enu_f.y,
509 .z = height};
510
512
514 &waypoints[wp_id].enu_i.x,
515 &waypoints[wp_id].enu_i.y,
516 &waypoints[wp_id].enu_i.z);
517}
Main include for ABI (AirBorneInterface).
Event structure to store callbacks in a linked list.
Definition abi_common.h:67
#define ACT_FEEDBACK_BOARD_ID
static uint8_t status
#define UNUSED(x)
Hardware independent code for commands handling.
struct point waypoints[NB_WAYPOINT]
size == nb_waypoint, waypoint 0 is a dummy waypoint
Definition common_nav.c:44
float y
Definition common_nav.h:41
float x
Definition common_nav.h:40
void float_rmat_transp_vmult(struct FloatVect3 *vb, struct FloatRMat *m_b2a, struct FloatVect3 *va)
rotate 3D vector by transposed rotation matrix.
#define VECT3_CROSS_PRODUCT(_vo, _v1, _v2)
#define VECT3_DIFF(_c, _a, _b)
#define VECT3_DOT_PRODUCT(_v1, _v2)
static struct FloatRMat * stateGetNedToBodyRMat_f(void)
Get vehicle body attitude rotation matrix (float).
Definition state.h:1300
struct State state
Definition state.c:36
static struct NedCoor_f * stateGetPositionNed_f(void)
Get position in local NED coordinates (float).
Definition state.h:839
static float stateGetAirspeed_f(void)
Get airspeed (float).
Definition state.h:1590
struct FloatVect3 speed_sp
void guidance_set_min_max_airspeed(float min_airspeed, float max_airspeed)
float gi_unbounded_airspeed_sp
uint16_t foo
Definition main_demo5.c:58
Hardware independent API for actuators (servos, motor controllers).
bool position
Position is set.
Definition actuators.h:48
struct act_feedback_t::act_feedback_set_t set
Bitset registering what is set as feedback.
uint8_t idx
General index of the actuators (generated in airframe.h)
Definition actuators.h:45
float position
In radians.
Definition actuators.h:52
void waypoint_set_enu(uint8_t wp_id, struct EnuCoor_f *enu)
Set local ENU waypoint coordinates.
Definition waypoints.c:177
float nav_max_deceleration_sp
static uint32_t idx
#define MAX_PPRZ
Definition paparazzi.h:8
float x
in meters
float z
in meters
float x
in meters
float y
in meters
vector in East North Up coordinates Units: meters
Rotorcraft specific autopilot interface and initialization.
struct HorizontalGuidance guidance_h
Definition guidance_h.c:45
#define GUIDANCE_H_MODE_NONE
Definition guidance_h.h:56
bool rotwing_state_pusher_motor_running(void)
static void rotwing_state_feedback_cb(uint8_t sender_id, struct act_feedback_t *feedback_msg, uint8_t num_act)
#define ROTWING_RPM_TIMEOUT
#define ROTWING_SKEW_REF_MODEL_MAX_DIFF
bool rotwing_state_hover_motors_running(void)
#define ROTWING_FW_STALL_TIMEOUT
#define ROTWING_FW_SKEW_ANGLE
#define ROTWING_MIN_AIRSPEED_SLOPE_START_ANGLE
void rotwing_state_init(void)
#define ROTWING_PUSH_MIN_RPM
bool rotwing_state_hover_motors_idling(void)
Check if hover motors are idling (COMMAND_THRUST < ROTWING_QUAD_IDLE_MIN_THRUST) for ROTWING_QUAD_IDL...
#define ROTWING_SKEW_BACK_MARGIN
#define SERVO_BMOTOR_PUSH_IDX
bool rotwing_state_skew_angle_valid(void)
#define ROTWING_QUAD_IDLE_MIN_THRUST
#define SERVO_BROTATION_MECH_IDX
#define ROTWING_QUAD_MIN_RPM
static void send_rotating_wing_state(struct transport_tx *trans, struct link_device *dev)
void rotwing_state_set_transition_wp(uint8_t wp_id)
#define ROTWING_STATE_ACT_FEEDBACK_ID
ABI binding feedback data.
abi_event rotwing_state_feedback_ev
#define ROTWING_QUAD_IDLE_TIMEOUT
bool rotwing_state_choose_circle_direction(uint8_t wp_id)
struct rotwing_state_t rotwing_state
void rotwing_state_periodic(void)
void rotwing_state_update_WP_height(uint8_t wp_id, float height)
void rotwing_state_set(enum rotwing_states_t state)
enum rotwing_states_t state
int32_t meas_rpm[5]
float meas_skew_angle_time
float meas_rpm_time[5]
float ref_model_skew_angle_deg
float meas_skew_angle_deg
#define ROTWING_SKEW_ANGLE_STEP
rotwing_states_t
@ ROTWING_STATE_FREE
@ ROTWING_STATE_REQUEST_HOVER
@ ROTWING_STATE_FORCE_FW
@ ROTWING_STATE_FORCE_HOVER
@ ROTWING_STATE_REQUEST_FW
enum rotwing_states_t nav_state
static const ShellCommand commands[]
Definition shell_arch.c:78
struct Stabilization stabilization
uint8_t mode
current mode
#define STABILIZATION_MODE_ATTITUDE
uint8_t att_submode
current attitude sub-mode
#define STABILIZATION_ATT_SUBMODE_FORWARD
int32_t cmd[COMMANDS_NB]
output command vector, range from [-MAX_PPRZ:MAX_PPRZ] (store for messages)
#define STABILIZATION_MODE_NONE
Stabilization modes.
static const struct usb_device_descriptor dev
Definition usb_ser_hw.c:74
static float get_sys_time_float(void)
Get the time in seconds since startup.
Definition sys_time.h:138
int8_t register_periodic_telemetry(struct periodic_telemetry *_pt, uint8_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
unsigned char uint8_t
Typedef defining 8 bit unsigned char type.