Paparazzi UAS  v7.0_unstable
Paparazzi is a free software Unmanned Aircraft System.
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 
28 #include "modules/core/commands.h"
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
98 static void rotwing_state_feedback_cb(uint8_t sender_id, struct act_feedback_t *feedback_msg, uint8_t num_act);
100 #if PERIODIC_TELEMETRY
102 static 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;
117  pprz_msg_send_ROTATING_WING_STATE(trans, dev, AC_ID,
118  &state,
119  &nav_state,
120  &status.value,
126 }
127 #endif // PERIODIC_TELEMETRY
128 
130 {
131  // Initialize rotwing state
135  rotwing_state.fw_min_airspeed = ROTWING_FW_MIN_AIRSPEED;
136  rotwing_state.cruise_airspeed = ROTWING_FW_CRUISE_AIRSPEED;
141  rotwing_state.force_skew = false;
142  for (int i = 0; i < 5; i++) {
143  rotwing_state.meas_rpm[i] = 0;
145  }
150  // Bind ABI messages
152 
153 #if PERIODIC_TELEMETRY
154  register_periodic_telemetry(DefaultPeriodic, PPRZ_MSG_ID_ROTATING_WING_STATE, send_rotating_wing_state);
155 #endif
156 }
157 
163  static float last_idle_time = 0;
164  // Check if hover motors are idling and reset timer
165  if(stabilization.cmd[COMMAND_THRUST] > ROTWING_QUAD_IDLE_MIN_THRUST) {
166  last_idle_time = get_sys_time_float();
167  }
168 
169  // Check if we exceeded the idle timeout
170  if(get_sys_time_float() - last_idle_time > ROTWING_QUAD_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;
180  float current_time = get_sys_time_float();
181  float meas_airspeed = stateGetAirspeed_f();
182  float meas_skew_angle = rotwing_state.meas_skew_angle_deg;
183  Bound(meas_skew_angle, 0, 90); // Bound to prevent errors
184 
185  if(meas_airspeed > rotwing_state.fw_min_airspeed) {
186  last_stall_time = current_time;
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  }
210  else if((current_time - last_stall_time) < ROTWING_FW_STALL_TIMEOUT && rotwing_state_hover_motors_idling() && rotwing_state_pusher_motor_running() && meas_skew_angle >= ROTWING_FW_SKEW_ANGLE
213  }
214  else {
216  }
217 
218 
219  /* Calculate min/max airspeed bounds based on skew angle */
220  float skew_min_airspeed = ROTWING_FW_QUAD_MIN_AIRSPEED * (meas_skew_angle - ROTWING_MIN_AIRSPEED_SLOPE_START_ANGLE) / (90.f - ROTWING_MIN_AIRSPEED_SLOPE_START_ANGLE);
221  float skew_max_airspeed = ROTWING_QUAD_MAX_AIRSPEED + (ROTWING_FW_MAX_AIRSPEED - ROTWING_QUAD_MAX_AIRSPEED) * meas_skew_angle / ROTWING_FW_SKEW_ANGLE;
222  Bound(skew_min_airspeed, 0, rotwing_state.fw_min_airspeed);
223  Bound(skew_max_airspeed, ROTWING_QUAD_MAX_AIRSPEED, ROTWING_FW_MAX_AIRSPEED);
224 
226  skew_min_airspeed = rotwing_state.fw_min_airspeed;
227  skew_max_airspeed = ROTWING_FW_MAX_AIRSPEED;
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
249  if (meas_airspeed < ROTWING_SKEW_DOWN_AIRSPEED) {
251  } else if (meas_airspeed < ROTWING_SKEW_UP_AIRSPEED) {
252  // Hysteresis do nothing
253  } else if (meas_airspeed < ROTWING_QUAD_MAX_AIRSPEED) {
255  } else {
256  rotwing_state.sp_skew_angle_deg = ((meas_airspeed - ROTWING_QUAD_MAX_AIRSPEED)) / (rotwing_state.fw_min_airspeed - ROTWING_QUAD_MAX_AIRSPEED) * (90.f - ROTWING_SKEW_ANGLE_STEP) + ROTWING_SKEW_ANGLE_STEP;
257  }
258  }
259  Bound(rotwing_state.sp_skew_angle_deg, 0.f, 90.f);
260 
261 
262  /* Handle the airspeed bounding */
263  Bound(rotwing_state.cruise_airspeed, rotwing_state.fw_min_airspeed, ROTWING_FW_MAX_AIRSPEED);
267  }
270  rotwing_state.max_airspeed = ROTWING_QUAD_NOPUSH_AIRSPEED;
271  }
273  rotwing_state.min_airspeed = skew_min_airspeed;
274  rotwing_state.max_airspeed = fmax(ROTWING_QUAD_MAX_AIRSPEED, skew_min_airspeed);
275  }
277  rotwing_state.min_airspeed = fmin(rotwing_state.cruise_airspeed, skew_max_airspeed);
278  rotwing_state.max_airspeed = fmin(rotwing_state.cruise_airspeed, skew_max_airspeed);
279  }
280  else{
281  rotwing_state.min_airspeed = skew_min_airspeed;
282  rotwing_state.max_airspeed = skew_max_airspeed;
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;
298  BoundAbs(servo_pprz_cmd, MAX_PPRZ);
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 
304  float speed_sp = ROTWING_SKEW_REF_MODEL_P_GAIN * (servo_pprz_cmd - rotwing_state_skew_p_cmd);
305  BoundAbs(speed_sp, ROTWING_SKEW_REF_MODEL_MAX_SPEED);
306  rotwing_state_skew_d_cmd += ROTWING_SKEW_REF_MODEL_D_GAIN * (speed_sp - rotwing_state_skew_d_cmd);
307  rotwing_state_skew_p_cmd += rotwing_state_skew_d_cmd;
308  BoundAbs(rotwing_state_skew_p_cmd, MAX_PPRZ);
309  rotwing_state.ref_model_skew_angle_deg = 45.0 / MAX_PPRZ * rotwing_state_skew_p_cmd + 45.0;
310 
311 #if (ROTWING_SKEW_REF_MODEL || USE_NPS)
312  rotwing_state.skew_cmd = rotwing_state_skew_p_cmd;
313 #else
314  rotwing_state.skew_cmd = servo_pprz_cmd;
315 #endif
316 #ifdef COMMAND_ROT_MECH
317  commands[COMMAND_ROT_MECH] = rotwing_state.skew_cmd;
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)
336  AbiSendMsgACT_FEEDBACK(ACT_FEEDBACK_BOARD_ID, &feedback, 1);
337  }
338 
339  // Simulate to always have RPM if on and active feedback
340  rotwing_state.meas_rpm[0] = (actuators[SERVO_MOTOR_FRONT_IDX].pprz_val >= 0)? (ROTWING_QUAD_MIN_RPM + 100) : 0;
341  rotwing_state.meas_rpm[1] = (actuators[SERVO_MOTOR_RIGHT_IDX].pprz_val >= 0)? (ROTWING_QUAD_MIN_RPM + 100) : 0;
342  rotwing_state.meas_rpm[2] = (actuators[SERVO_MOTOR_BACK_IDX].pprz_val >= 0)? (ROTWING_QUAD_MIN_RPM + 100) : 0;
343  rotwing_state.meas_rpm[3] = (actuators[SERVO_MOTOR_LEFT_IDX].pprz_val >= 0)? (ROTWING_QUAD_MIN_RPM + 100) : 0;
344  rotwing_state.meas_rpm[4] = (actuators[SERVO_MOTOR_PUSH_IDX].pprz_val >= 0)? (ROTWING_PUSH_MIN_RPM + 100) : 0;
345  for(uint8_t i = 0; i < 5; i++) {
346  rotwing_state.meas_rpm_time[i] = current_time;
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 
365 static void rotwing_state_feedback_cb(uint8_t __attribute__((unused)) sender_id,
366  struct act_feedback_t UNUSED *feedback_msg, uint8_t UNUSED num_act_message)
367 {
368  float current_time = get_sys_time_float();
369  for (int i = 0; i < num_act_message; i++) {
370  int idx = feedback_msg[i].idx;
371 
372  // Check for wing rotation feedback
373  if ((feedback_msg[i].set.position) && (idx == SERVO_ROTATION_MECH_IDX || idx == SERVO_BROTATION_MECH_IDX)) {
374  // Get wing rotation angle from sensor
375  float skew_angle_rad = 0.5 * M_PI - feedback_msg[i].position;
376  rotwing_state.meas_skew_angle_deg = DegOfRad(skew_angle_rad);
377  rotwing_state.meas_skew_angle_time = current_time;
378  }
379 
380  // Get the RPM feedbacks of the motors
381  if (feedback_msg[i].set.rpm) {
382  if ((idx == SERVO_MOTOR_FRONT_IDX) || (idx == SERVO_BMOTOR_FRONT_IDX)) {
383  rotwing_state.meas_rpm[0] = feedback_msg->rpm;
384  rotwing_state.meas_rpm_time[0] = current_time;
385  } else if ((idx == SERVO_MOTOR_RIGHT_IDX) || (idx == SERVO_BMOTOR_RIGHT_IDX)) {
386  rotwing_state.meas_rpm[1] = feedback_msg->rpm;
387  rotwing_state.meas_rpm_time[1] = current_time;
388  } else if ((idx == SERVO_MOTOR_BACK_IDX) || (idx == SERVO_BMOTOR_BACK_IDX)) {
389  rotwing_state.meas_rpm[2] = feedback_msg->rpm;
390  rotwing_state.meas_rpm_time[2] = current_time;
391  } else if ((idx == SERVO_MOTOR_LEFT_IDX) || (idx == SERVO_BMOTOR_LEFT_IDX)) {
392  rotwing_state.meas_rpm[3] = feedback_msg->rpm;
393  rotwing_state.meas_rpm_time[3] = current_time;
394  } else if ((idx == SERVO_MOTOR_PUSH_IDX) || (idx == SERVO_BMOTOR_PUSH_IDX)) {
395  rotwing_state.meas_rpm[4] = feedback_msg->rpm;
396  rotwing_state.meas_rpm_time[4] = current_time;
397  }
398  }
399  }
400 }
401 
403  float current_time = get_sys_time_float();
404  // Check if hover motors are running
409  && (current_time - rotwing_state.meas_rpm_time[0]) < ROTWING_RPM_TIMEOUT
410  && (current_time - rotwing_state.meas_rpm_time[1]) < ROTWING_RPM_TIMEOUT
411  && (current_time - rotwing_state.meas_rpm_time[2]) < ROTWING_RPM_TIMEOUT
412  && (current_time - rotwing_state.meas_rpm_time[3]) < ROTWING_RPM_TIMEOUT) {
413  return true;
414  } else {
415  return false;
416  }
417 }
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 
438 }
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
449  struct FloatVect3 pos_ned = {.x = stateGetPositionNed_f()->x,
450  .y = stateGetPositionNed_f()->y,
451  .z = stateGetPositionNed_f()->z};
452 
453  // Get vector pointing from drone to waypoint
454  struct FloatVect3 vect_pos_circ;
455  VECT3_DIFF(vect_pos_circ, circ_ned, pos_ned);
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;
460  struct FloatVect3 cross_att_circ;
461 
462  float_rmat_transp_vmult(&att_NED, stateGetNedToBodyRMat_f(), &x_axis);
463 
464  VECT3_CROSS_PRODUCT(cross_att_circ, vect_pos_circ, att_NED);
465  float y = VECT3_DOT_PRODUCT(cross_att_circ, z_axis);
466  float x = VECT3_DOT_PRODUCT(vect_pos_circ, att_NED);
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
480  struct EnuCoor_f target_enu = {.x = stateGetPositionNed_f()->y,
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 
487  float_rmat_transp_vmult(&x_att_NED, stateGetNedToBodyRMat_f(), &x_axis);
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 
493  waypoint_set_enu(wp_id, &target_enu);
494 
495  // Send waypoint update every half second
496  RunOnceEvery(100 / 2, {
497  // Send to the GCS that the waypoint has been moved
498  DOWNLINK_SEND_WP_MOVED_ENU(DefaultChannel, DefaultDevice, &wp_id,
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 
506 void 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 
511  waypoint_set_enu(wp_id, &target_enu);
512 
513  DOWNLINK_SEND_WP_MOVED_ENU(DefaultChannel, DefaultDevice, &wp_id,
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
pprz_t commands[COMMANDS_NB]
Definition: commands.c:30
Hardware independent code for commands handling.
uint8_t last_wp UNUSED
struct point waypoints[NB_WAYPOINT]
size == nb_waypoint, waypoint 0 is a dummy waypoint
Definition: common_nav.c:39
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)
Definition: pprz_algebra.h:244
#define VECT3_DIFF(_c, _a, _b)
Definition: pprz_algebra.h:182
#define VECT3_DOT_PRODUCT(_v1, _v2)
Definition: pprz_algebra.h:250
static struct FloatRMat * stateGetNedToBodyRMat_f(void)
Get vehicle body attitude rotation matrix (float).
Definition: state.h:1137
struct State state
Definition: state.c:36
static struct NedCoor_f * stateGetPositionNed_f(void)
Get position in local NED coordinates (float).
Definition: state.h:710
static float stateGetAirspeed_f(void)
Get airspeed (float).
Definition: state.h:1407
struct FloatVect3 speed_sp
Definition: guidance_indi.c:73
void guidance_set_min_max_airspeed(float min_airspeed, float max_airspeed)
float gi_unbounded_airspeed_sp
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
uint8_t status
#define MAX_PPRZ
Definition: paparazzi.h:8
float y
in meters
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
Definition: rotwing_state.c:45
#define ROTWING_SKEW_REF_MODEL_MAX_DIFF
Definition: rotwing_state.c:70
bool rotwing_state_hover_motors_running(void)
#define ROTWING_FW_STALL_TIMEOUT
Definition: rotwing_state.c:80
#define ROTWING_FW_SKEW_ANGLE
Definition: rotwing_state.c:60
#define ROTWING_MIN_AIRSPEED_SLOPE_START_ANGLE
Definition: rotwing_state.c:75
void rotwing_state_init(void)
#define ROTWING_PUSH_MIN_RPM
Definition: rotwing_state.c:40
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
Definition: rotwing_state.c:65
#define SERVO_BMOTOR_PUSH_IDX
Definition: rotwing_state.c:85
bool rotwing_state_skew_angle_valid(void)
#define ROTWING_QUAD_IDLE_MIN_THRUST
Definition: rotwing_state.c:50
#define SERVO_BROTATION_MECH_IDX
Definition: rotwing_state.c:90
#define ROTWING_QUAD_MIN_RPM
Definition: rotwing_state.c:35
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.
Definition: rotwing_state.c:95
abi_event rotwing_state_feedback_ev
Definition: rotwing_state.c:97
#define ROTWING_QUAD_IDLE_TIMEOUT
Definition: rotwing_state.c:55
bool rotwing_state_choose_circle_direction(uint8_t wp_id)
struct rotwing_state_t rotwing_state
Definition: rotwing_state.c:99
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
Definition: rotwing_state.h:63
int32_t meas_rpm[5]
Definition: rotwing_state.h:82
float meas_skew_angle_time
Definition: rotwing_state.h:71
float meas_rpm_time[5]
Definition: rotwing_state.h:83
bool hover_motors_enabled
Definition: rotwing_state.h:65
float ref_model_skew_angle_deg
Definition: rotwing_state.h:69
float sp_skew_angle_deg
Definition: rotwing_state.h:68
float meas_skew_angle_deg
Definition: rotwing_state.h:70
#define ROTWING_SKEW_ANGLE_STEP
Definition: rotwing_state.h:33
rotwing_states_t
Definition: rotwing_state.h:41
@ ROTWING_STATE_FREE
Definition: rotwing_state.h:46
@ ROTWING_STATE_REQUEST_HOVER
Definition: rotwing_state.h:43
@ ROTWING_STATE_FORCE_FW
Definition: rotwing_state.h:44
@ ROTWING_STATE_FORCE_HOVER
Definition: rotwing_state.h:42
@ ROTWING_STATE_REQUEST_FW
Definition: rotwing_state.h:45
enum rotwing_states_t nav_state
Definition: rotwing_state.h:64
struct Stabilization stabilization
Definition: stabilization.c:41
uint8_t mode
current mode
#define STABILIZATION_MODE_ATTITUDE
Definition: stabilization.h:41
uint8_t att_submode
current attitude sub-mode
#define STABILIZATION_ATT_SUBMODE_FORWARD
Definition: stabilization.h:47
int32_t cmd[COMMANDS_NB]
output command vector, range from [-MAX_PPRZ:MAX_PPRZ] (store for messages)
#define STABILIZATION_MODE_NONE
Stabilization modes.
Definition: stabilization.h:38
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.
Definition: vl53l1_types.h:98