Paparazzi UAS v7.0_unstable
Paparazzi is a free software Unmanned Aircraft System.
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Modules Pages
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/* Maximum measured skew angle to consider the rotating wing drone in quad (deg) */
64#ifndef ROTWING_QUAD_SKEW_ANGLE
65#define ROTWING_QUAD_SKEW_ANGLE 25.0
66#endif
67
68/* Maximum bank angle while the rotwing is skewing */
69#ifndef ROTWING_TRANSITION_MAX_BANK
70#define ROTWING_TRANSITION_MAX_BANK RadOfDeg(20)
71#endif
72
73/* Maximum climb speed while the rotwing is transitioning */
74#ifndef ROTWING_TRANSITION_MAX_CLIMB_SPEED
75#define ROTWING_TRANSITION_MAX_CLIMB_SPEED 0.5
76#endif
77
78/* Maximum descend speed while the rotwing is transitioning */
79#ifndef ROTWING_TRANSITION_MAX_DESCEND_SPEED
80#define ROTWING_TRANSITION_MAX_DESCEND_SPEED -0.5
81#endif
82
83/* TODO: Give a name.... */
84#ifndef ROTWING_SKEW_BACK_MARGIN
85#define ROTWING_SKEW_BACK_MARGIN 5.0
86#endif
87
88/* Maximum angle difference between the measured skew and modelled skew for skew failure detection */
89#ifndef ROTWING_SKEW_REF_MODEL_MAX_DIFF
90#define ROTWING_SKEW_REF_MODEL_MAX_DIFF 5.f
91#endif
92
93/* Skew angle at which the mininum airspeed starts its linear portion */
94#ifndef ROTWING_MIN_AIRSPEED_SLOPE_START_ANGLE
95#define ROTWING_MIN_AIRSPEED_SLOPE_START_ANGLE 30.0
96#endif
97
98/* Amount of time the airspeed needs to be below the FW_MIN_AIRSPEED */
99#ifndef ROTWING_FW_STALL_TIMEOUT
100#define ROTWING_FW_STALL_TIMEOUT 0.5
101#endif
102
103#ifndef ROTWING_STATE_MIN_FW_DIST
104#define ROTWING_STATE_MIN_FW_DIST 200.0
105#endif
106
107/* Fix for not having double can busses */
108#ifndef SERVO_BMOTOR_PUSH_IDX
109#define SERVO_BMOTOR_PUSH_IDX SERVO_MOTOR_PUSH_IDX
110#endif
111
112/* Fix for not having double can busses */
113#ifndef SERVO_BROTATION_MECH_IDX
114#define SERVO_BROTATION_MECH_IDX SERVO_ROTATION_MECH_IDX
115#endif
116
118#ifndef ROTWING_STATE_ACT_FEEDBACK_ID
119#define ROTWING_STATE_ACT_FEEDBACK_ID ABI_BROADCAST
120#endif
124#if PERIODIC_TELEMETRY
126static void send_rotating_wing_state(struct transport_tx *trans, struct link_device *dev)
127{
128 // Set the status
130 status.value = 0;
131 status.skew_angle_valid = rotwing_state_skew_angle_valid();
132 status.hover_motors_enabled = rotwing_state.hover_motors_enabled;
133 status.hover_motors_idle = rotwing_state_hover_motors_idling();
134 status.hover_motors_running = rotwing_state_hover_motors_running();
135 status.pusher_motor_running = rotwing_state_pusher_motor_running();
136 status.skew_forced = rotwing_state.force_skew;
137
138 // Send the message
140 uint8_t nav_state = rotwing_state.nav_state;
142 &state,
143 &nav_state,
144 &status.value,
150}
151#endif // PERIODIC_TELEMETRY
152
181
187 static float last_idle_time = 0;
188 // Check if hover motors are idling and reset timer
191 }
192
193 // Check if we exceeded the idle timeout
195 return true;
196 }
197 return false;
198}
199
201{
202 /* Get some genericly used variables */
203 static float last_stall_time = 0;
207 Bound(meas_skew_angle, 0, 90); // Bound to prevent errors
208
211 }
212
213 /* Override modes if flying with RC */
217 }
219 // Kill mode
222 }
223 // ATT and ATT_FWD
227 } else {
229 }
230 }
231 }
232
233 /* Handle the quad motors on/off state */
236 }
240 }
241 else {
243 }
244
245
246 /* Calculate min/max airspeed bounds based on skew angle */
251
255 }
256
257
258 /* Handle the skew angle setpoint */
260 // Do nothing
261 }
264 }
267 }
270 }
273 }
274 else {
275 // SKEWING function based on Vair
279 // Hysteresis do nothing
282 } else {
284 }
285 }
287
288
289 /* Handle the airspeed bounding */
294 }
298 }
302 }
306 }
307 else{
310 }
311
312 /* Bound max bank angle, climb speed and descend speed if the rotwing drone is transitioning and not in FREE mode */
318 } else {
322 }
323
324 // Override failing skewing while fwd
325 /*if(meas_skew_angle > 70 && rotwing_state_.skewing_failing) {
326 rotwing_state.min_airspeed = 0; // Vstall + margin
327 rotwing_state.max_airspeed = 0; // Max airspeed FW
328 }*/
329
331
332 /* Set navigation/guidance settings */
333 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?
334
335
336 /* Calculate the skew command */
337 float servo_pprz_cmd = MAX_PPRZ * (rotwing_state.sp_skew_angle_deg - 45.f) / 45.f;
339
340 // Rotate with second order filter
341 static float rotwing_state_skew_p_cmd = -MAX_PPRZ;
342 static float rotwing_state_skew_d_cmd = 0;
343
350
351#if (ROTWING_SKEW_REF_MODEL || USE_NPS)
353#else
355#endif
356#ifdef COMMAND_ROT_MECH
358#endif
359
360 /* Add simulation feedback for the skewing and RPM */
361#if USE_NPS
362 // Export to the index of the SKEW in the NPS_ACTUATOR_NAMES array
363#ifdef COMMAND_ROT_MECH
364 commands[COMMAND_ROT_MECH] = (rotwing_state.skew_cmd + MAX_PPRZ) / 2.f; // Scale to simulation command
365#else
366 actuators_pprz[INDI_NUM_ACT] = (rotwing_state.skew_cmd + MAX_PPRZ) / 2.f; // Scale to simulation command
367#endif
368 // SEND ABI Message to ctr_eff_sched, ourself and other modules that want Actuator position feedback
369 struct act_feedback_t feedback;
370 feedback.idx = SERVO_ROTATION_MECH_IDX;
371 feedback.position = 0.5f * M_PI - RadOfDeg((float) rotwing_state.skew_cmd / MAX_PPRZ * 45.f + 45.f);
372 feedback.set.position = true;
373
374 // Send ABI message (or simulate failure)
377 }
378
379 // Simulate to always have RPM if on and active feedback
385 for(uint8_t i = 0; i < 5; i++) {
387 }
388
389#ifdef SITL
391 rotwing_state.meas_rpm[0] = 0;
392 rotwing_state.meas_rpm[1] = 0;
393 rotwing_state.meas_rpm[2] = 0;
394 rotwing_state.meas_rpm[3] = 0;
395 }
396
398 rotwing_state.meas_rpm[4] = 0;
399 }
400#endif
401
402#endif
403}
404
407{
409 for (int i = 0; i < num_act_message; i++) {
410 int idx = feedback_msg[i].idx;
411
412 // Check for wing rotation feedback
414 // Get wing rotation angle from sensor
415 float skew_angle_rad = 0.5 * M_PI - feedback_msg[i].position;
418 }
419
420 // Get the RPM feedbacks of the motors
421 if (feedback_msg[i].set.rpm) {
425 } else if ((idx == SERVO_MOTOR_RIGHT_IDX) || (idx == SERVO_BMOTOR_RIGHT_IDX)) {
428 } else if ((idx == SERVO_MOTOR_BACK_IDX) || (idx == SERVO_BMOTOR_BACK_IDX)) {
431 } else if ((idx == SERVO_MOTOR_LEFT_IDX) || (idx == SERVO_BMOTOR_LEFT_IDX)) {
434 } else if ((idx == SERVO_MOTOR_PUSH_IDX) || (idx == SERVO_BMOTOR_PUSH_IDX)) {
437 }
438 }
439 }
440}
441
458
460 // Check if pusher motor is running
462 return true;
463 } else {
464 return false;
465 }
466}
467
469 // Check if the measured skew angle is timed out and the reference model is matching
472
473 return (!skew_timeout && skew_angle_match);
474}
475
479
480
481/* TODO move these rotwing navigation helper functions to an appropriate module/file */
483 // Get circle waypoint coordinates in NED
484 struct FloatVect3 circ_ned = {.x = waypoints[wp_id].enu_f.y,
485 .y = waypoints[wp_id].enu_f.x,
486 .z = -waypoints[wp_id].enu_f.z};
487
488 // Get drone position coordinates in NED
490 .y = stateGetPositionNed_f()->y,
491 .z = stateGetPositionNed_f()->z};
492
493 // Get vector pointing from drone to waypoint
496
497 static struct FloatVect3 x_axis = {.x = 1, .y = 0, .z = 0};
498 static struct FloatVect3 z_axis = {.x = 0, .y = 0, .z = 1};
499 struct FloatVect3 att_NED;
501
503
507
508 float body_to_wp_angle_rad = atan2f(y, x);
509
510 if (body_to_wp_angle_rad >= 0.f) {
511 return true; // CCW circle
512 } else {
513 return false; // CW circle
514 }
515}
516
518 struct EnuCoor_f wp = waypoints[wp_id].enu_f;
519 float dist2_to_wp = get_dist2_to_point(&wp);
521
522 if (autopilot.mode == AP_MODE_NAV) {
525 return true; // Necessary for flight plan
526 } else {
528 return false; // Necessary for flight plan
529 }
530 }
531
532 return false; // Necessary for flight plan
533}
Main include for ABI (AirBorneInterface).
Event structure to store callbacks in a linked list.
Definition abi_common.h:67
#define ACT_FEEDBACK_BOARD_ID
struct pprz_autopilot autopilot
Global autopilot structure.
Definition autopilot.c:49
uint8_t mode
current autopilot mode
Definition autopilot.h:63
static uint8_t status
#define UNUSED(x)
Hardware independent code for commands handling.
float dist2_to_wp
Definition common_nav.c:39
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
#define GUIDANCE_INDI_QUAD_DESCEND_SPEED
Descend speed when navigation is doing direct lines.
void guidance_set_max_bank_angle(float max_bank)
#define GUIDANCE_INDI_FWD_DESCEND_SPEED
Descend speed when navigation is making turns instead of direct lines.
void guidance_set_max_climb_speed(float max_climb_speed_quad, float max_climb_speed_fwd)
#define GUIDANCE_INDI_QUAD_CLIMB_SPEED
Climb speed when navigation is doing direct lines.
#define GUIDANCE_INDI_FWD_CLIMB_SPEED
Climb speed when navigation is making turns instead of direct lines.
void guidance_set_min_max_airspeed(float min_airspeed, float max_airspeed)
void guidance_set_max_descend_speed(float max_descend_speed_quad, float max_descend_speed_fwd)
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
float nav_max_deceleration_sp
static uint32_t idx
#define MAX_PPRZ
Definition paparazzi.h:8
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.
#define AP_MODE_NAV
#define AP_MODE_FAILSAFE
struct HorizontalGuidance guidance_h
Definition guidance_h.c:45
#define GUIDANCE_H_MODE_NONE
Definition guidance_h.h:56
#define GUIDANCE_H_MAX_BANK
Max bank controlled by guidance.
Definition guidance_h.h:64
float get_dist2_to_point(struct EnuCoor_f *p)
Returns squared horizontal distance to given point.
Definition navigation.c:308
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_TRANSITION_MAX_BANK
#define ROTWING_MIN_AIRSPEED_SLOPE_START_ANGLE
#define ROTWING_STATE_MIN_FW_DIST
void rotwing_state_init(void)
#define ROTWING_PUSH_MIN_RPM
#define ROTWING_TRANSITION_MAX_DESCEND_SPEED
#define ROTWING_TRANSITION_MAX_CLIMB_SPEED
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_SKEW_ANGLE
#define ROTWING_QUAD_MIN_RPM
static void send_rotating_wing_state(struct transport_tx *trans, struct link_device *dev)
bool rotwing_state_choose_state_by_dist(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_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.