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/* 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
153#if PREFLIGHT_CHECKS
154/* Preflight checks */
157
158static void rotwing_state_skew_preflight(struct preflight_result_t *result) {
160 preflight_success(result, "Rotwing skew success");
161 } else {
162 preflight_error(result, "Rotwing skew error [meas: %.1f, sp: %.1f]", rotwing_state.meas_skew_angle_deg, rotwing_state.sp_skew_angle_deg);
163 }
164}
165#endif // PREFLIGHT_CHECKS
166
200
206 static float last_idle_time = 0;
207 // Check if hover motors are idling and reset timer
210 }
211
212 // Check if we exceeded the idle timeout
214 return true;
215 }
216 return false;
217}
218
220{
221 /* Get some genericly used variables */
222 static float last_stall_time = 0;
226 Bound(meas_skew_angle, 0, 90); // Bound to prevent errors
227
230 }
231
232 /* Override modes if flying with RC */
236 }
238 // Kill mode
241 }
242 // ATT and ATT_FWD
246 } else {
248 }
249 }
250 }
251
252 /* Handle the quad motors on/off state */
255 }
259 }
260 else {
262 }
263
264
265 /* Calculate min/max airspeed bounds based on skew angle */
270
274 }
275
276
277 /* Handle the skew angle setpoint */
279 // Do nothing
280 }
283 }
286 }
289 }
292 }
293 else {
294 // SKEWING function based on Vair
298 // Hysteresis do nothing
301 } else {
303 }
304 }
306
307
308 /* Handle the airspeed bounding */
313 }
317 }
321 }
325 }
326 else{
329 }
330
331 /* Bound max bank angle, climb speed and descend speed if the rotwing drone is transitioning and not in FREE mode */
337 } else {
341 }
342
343 // Override failing skewing while fwd
344 /*if(meas_skew_angle > 70 && rotwing_state_.skewing_failing) {
345 rotwing_state.min_airspeed = 0; // Vstall + margin
346 rotwing_state.max_airspeed = 0; // Max airspeed FW
347 }*/
348
350
351 /* Set navigation/guidance settings */
352 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?
353
354
355 /* Calculate the skew command */
356 float servo_pprz_cmd = MAX_PPRZ * (rotwing_state.sp_skew_angle_deg - 45.f) / 45.f;
358
359 // Rotate with second order filter
360 static float rotwing_state_skew_p_cmd = -MAX_PPRZ;
361 static float rotwing_state_skew_d_cmd = 0;
362
369
370#if (ROTWING_SKEW_REF_MODEL || USE_NPS)
372#else
374#endif
375#ifdef COMMAND_ROT_MECH
377#endif
378
379 /* Add simulation feedback for the skewing and RPM */
380#if USE_NPS
381 // Export to the index of the SKEW in the NPS_ACTUATOR_NAMES array
382#ifdef COMMAND_ROT_MECH
383 commands[COMMAND_ROT_MECH] = (rotwing_state.skew_cmd + MAX_PPRZ) / 2.f; // Scale to simulation command
384#else
385 actuators_pprz[INDI_NUM_ACT] = (rotwing_state.skew_cmd + MAX_PPRZ) / 2.f; // Scale to simulation command
386#endif
387 // SEND ABI Message to ctr_eff_sched, ourself and other modules that want Actuator position feedback
388 struct act_feedback_t feedback;
389 feedback.idx = SERVO_ROTATION_MECH_IDX;
390 feedback.position = 0.5f * M_PI - RadOfDeg((float) rotwing_state.skew_cmd / MAX_PPRZ * 45.f + 45.f);
391 feedback.set.position = true;
392
393 // Send ABI message (or simulate failure)
396 }
397
398 // Simulate to always have RPM if on and active feedback
404 for(uint8_t i = 0; i < 5; i++) {
406 }
407
408#ifdef SITL
410 rotwing_state.meas_rpm[0] = 0;
411 rotwing_state.meas_rpm[1] = 0;
412 rotwing_state.meas_rpm[2] = 0;
413 rotwing_state.meas_rpm[3] = 0;
414 }
415
417 rotwing_state.meas_rpm[4] = 0;
418 }
419#endif
420
421#endif
422}
423
426{
428 for (int i = 0; i < num_act_message; i++) {
429 int idx = feedback_msg[i].idx;
430
431 // Check for wing rotation feedback
433 // Get wing rotation angle from sensor
434 float skew_angle_rad = 0.5 * M_PI - feedback_msg[i].position;
437 }
438
439 // Get the RPM feedbacks of the motors
440 if (feedback_msg[i].set.rpm) {
444 } else if ((idx == SERVO_MOTOR_RIGHT_IDX) || (idx == SERVO_BMOTOR_RIGHT_IDX)) {
447 } else if ((idx == SERVO_MOTOR_BACK_IDX) || (idx == SERVO_BMOTOR_BACK_IDX)) {
450 } else if ((idx == SERVO_MOTOR_LEFT_IDX) || (idx == SERVO_BMOTOR_LEFT_IDX)) {
453 } else if ((idx == SERVO_MOTOR_PUSH_IDX) || (idx == SERVO_BMOTOR_PUSH_IDX)) {
456 }
457 }
458 }
459}
460
477
479 // Check if pusher motor is running
481 return true;
482 } else {
483 return false;
484 }
485}
486
488 // Check if the measured skew angle is timed out and the reference model is matching
491
492 return (!skew_timeout && skew_angle_match);
493}
494
498
499
500/* TODO move these rotwing navigation helper functions to an appropriate module/file */
502 // Get circle waypoint coordinates in NED
503 struct FloatVect3 circ_ned = {.x = waypoints[wp_id].enu_f.y,
504 .y = waypoints[wp_id].enu_f.x,
505 .z = -waypoints[wp_id].enu_f.z};
506
507 // Get drone position coordinates in NED
509 .y = stateGetPositionNed_f()->y,
510 .z = stateGetPositionNed_f()->z};
511
512 // Get vector pointing from drone to waypoint
515
516 static struct FloatVect3 x_axis = {.x = 1, .y = 0, .z = 0};
517 static struct FloatVect3 z_axis = {.x = 0, .y = 0, .z = 1};
518 struct FloatVect3 att_NED;
520
522
526
527 float body_to_wp_angle_rad = atan2f(y, x);
528
529 if (body_to_wp_angle_rad >= 0.f) {
530 return true; // CCW circle
531 } else {
532 return false; // CW circle
533 }
534}
535
537 struct EnuCoor_f wp = waypoints[wp_id].enu_f;
538 float dist2_to_wp = get_dist2_to_point(&wp);
540
541 if (autopilot.mode == AP_MODE_NAV) {
544 return true; // Necessary for flight plan
545 } else {
547 return false; // Necessary for flight plan
548 }
549 }
550
551 return false; // Necessary for flight plan
552}
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
void preflight_error(struct preflight_result_t *result, const char *fmt,...)
Register a preflight error used inside the preflight checking functions.
void preflight_success(struct preflight_result_t *result, const char *fmt,...)
Register a preflight success used inside the preflight checking functions.
void preflight_check_register(struct preflight_check_t *check, preflight_check_f func)
Register a preflight check and add it to the linked list.
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
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
unsigned char uint8_t
Typedef defining 8 bit unsigned char type.