35 #ifndef ROTWING_QUAD_MIN_RPM
36 #define ROTWING_QUAD_MIN_RPM 400
40 #ifndef ROTWING_PUSH_MIN_RPM
41 #define ROTWING_PUSH_MIN_RPM 300
45 #ifndef ROTWING_RPM_TIMEOUT
46 #define ROTWING_RPM_TIMEOUT 1.0
50 #ifndef ROTWING_QUAD_IDLE_MIN_THRUST
51 #define ROTWING_QUAD_IDLE_MIN_THRUST 100
55 #ifndef ROTWING_QUAD_IDLE_TIMEOUT
56 #define ROTWING_QUAD_IDLE_TIMEOUT 0.4
60 #ifndef ROTWING_FW_SKEW_ANGLE
61 #define ROTWING_FW_SKEW_ANGLE 85.0
65 #ifndef ROTWING_SKEW_ANGLE_STEP
66 #define ROTWING_SKEW_ANGLE_STEP 55.0
70 #ifndef ROTWING_SKEW_BACK_MARGIN
71 #define ROTWING_SKEW_BACK_MARGIN 5.0
75 #ifndef ROTWING_SKEW_REF_MODEL_MAX_DIFF
76 #define ROTWING_SKEW_REF_MODEL_MAX_DIFF 5.f
80 #ifndef ROTWING_MIN_AIRSPEED_SLOPE_START_ANGLE
81 #define ROTWING_MIN_AIRSPEED_SLOPE_START_ANGLE 30.0
85 #ifndef ROTWING_QUAD_PREF_PITCH
86 #define ROTWING_QUAD_PREF_PITCH -5.0
90 #ifndef ROTWING_FW_STALL_TIMEOUT
91 #define ROTWING_FW_STALL_TIMEOUT 0.5
95 #ifndef SERVO_BMOTOR_PUSH_IDX
96 #define SERVO_BMOTOR_PUSH_IDX SERVO_MOTOR_PUSH_IDX
100 #ifndef SERVO_BROTATION_MECH_IDX
101 #define SERVO_BROTATION_MECH_IDX SERVO_ROTATION_MECH_IDX
105 #ifndef ROTWING_STATE_ACT_FEEDBACK_ID
106 #define ROTWING_STATE_ACT_FEEDBACK_ID ABI_BROADCAST
117 #if PERIODIC_TELEMETRY
134 pprz_msg_send_ROTATING_WING_STATE(trans,
dev, AC_ID,
159 for (
int i = 0; i < 5; i++) {
171 #if PERIODIC_TELEMETRY
181 static float last_idle_time = 0;
197 static float last_stall_time = 0;
201 Bound(meas_skew_angle, 0, 90);
204 last_stall_time = current_time;
239 float skew_max_airspeed = ROTWING_QUAD_MAX_AIRSPEED + (ROTWING_FW_MAX_AIRSPEED - ROTWING_QUAD_MAX_AIRSPEED) * meas_skew_angle /
ROTWING_FW_SKEW_ANGLE;
241 Bound(skew_max_airspeed, ROTWING_QUAD_MAX_AIRSPEED, ROTWING_FW_MAX_AIRSPEED);
245 skew_max_airspeed = ROTWING_FW_MAX_AIRSPEED;
267 if (meas_airspeed < ROTWING_SKEW_DOWN_AIRSPEED) {
269 }
else if (meas_airspeed < ROTWING_SKEW_UP_AIRSPEED) {
271 }
else if (meas_airspeed < ROTWING_QUAD_MAX_AIRSPEED) {
313 nav_max_deceleration_sp = ROTWING_FW_MAX_DECELERATION * meas_skew_angle / 90.f + ROTWING_QUAD_MAX_DECELERATION * (90.f - meas_skew_angle) / 90.f;
321 static float rotwing_state_skew_p_cmd = -
MAX_PPRZ;
322 static float rotwing_state_skew_d_cmd = 0;
324 float speed_sp = ROTWING_SKEW_REF_MODEL_P_GAIN * (servo_pprz_cmd - rotwing_state_skew_p_cmd);
325 BoundAbs(
speed_sp, ROTWING_SKEW_REF_MODEL_MAX_SPEED);
326 rotwing_state_skew_d_cmd += ROTWING_SKEW_REF_MODEL_D_GAIN * (
speed_sp - rotwing_state_skew_d_cmd);
327 rotwing_state_skew_p_cmd += rotwing_state_skew_d_cmd;
328 BoundAbs(rotwing_state_skew_p_cmd,
MAX_PPRZ);
331 #if (ROTWING_SKEW_REF_MODEL || USE_NPS)
345 feedback.
idx = SERVO_ROTATION_MECH_IDX;
360 for(
uint8_t i = 0; i < 5; i++) {
384 for (
int i = 0; i < num_act_message; i++) {
385 int idx = feedback_msg[i].idx;
390 float skew_angle_rad = 0.5 * M_PI - feedback_msg[i].position;
396 if (feedback_msg[i].
set.
rpm) {
397 if ((
idx == SERVO_MOTOR_FRONT_IDX) || (
idx == SERVO_BMOTOR_FRONT_IDX)) {
400 }
else if ((
idx == SERVO_MOTOR_RIGHT_IDX) || (
idx == SERVO_BMOTOR_RIGHT_IDX)) {
403 }
else if ((
idx == SERVO_MOTOR_BACK_IDX) || (
idx == SERVO_BMOTOR_BACK_IDX)) {
406 }
else if ((
idx == SERVO_MOTOR_LEFT_IDX) || (
idx == SERVO_BMOTOR_LEFT_IDX)) {
448 return (!skew_timeout && skew_angle_match);
455 Bound(fixed_wing_percentile, 0, 1);
456 #define AIRSPEED_IMPORTANCE_IN_FORWARD_WEIGHT 16
458 float Wv_original[GUIDANCE_INDI_HYBRID_V] = GUIDANCE_INDI_WLS_PRIORITIES;
461 wls_guid_p.Wv[0] = Wv_original[0] * (1.0f + fixed_wing_percentile *
470 Bound(du_min_thrust_z, -50., 0.);
473 Bound(du_max_thrust_z, 0., 50.);
480 float quad_pitch_limit_rad = RadOfDeg(5.0);
484 float scheduled_pitch_angle = 0.f;
485 float pitch_angle_range = 3.;
487 Bound(meas_skew_angle, 0, 90);
491 max_pitch_limit_rad = quad_pitch_limit_rad;
494 Bound(pitch_progression, 0.f, 1.f);
495 scheduled_pitch_angle = pitch_angle_range * pitch_progression +
ROTWING_QUAD_PREF_PITCH*(1.f-pitch_progression);
496 wls_guid_p.Wu[1] =
Wu_gih_original[1] * (1.f - pitch_progression*0.99);
497 max_pitch_limit_rad = quad_pitch_limit_rad + (fwd_pitch_limit_rad - quad_pitch_limit_rad) * pitch_progression;
500 scheduled_pitch_angle = 8.;
501 max_pitch_limit_rad = fwd_pitch_limit_rad;
503 Bound(scheduled_pitch_angle, -5., 8.);
509 wls_guid_p.u_min[0] = -roll_limit_rad - roll_angle;
510 wls_guid_p.u_min[1] = min_pitch_limit_rad - pitch_angle;
513 wls_guid_p.u_max[0] = roll_limit_rad - roll_angle;
514 wls_guid_p.u_max[1] = max_pitch_limit_rad - pitch_angle;
517 wls_guid_p.u_min[2] = du_min_thrust_z;
518 wls_guid_p.u_max[2] = du_max_thrust_z;
520 wls_guid_p.u_min[2] = 0.;
521 wls_guid_p.u_max[2] = 0.;
526 wls_guid_p.u_max[3] = 9.0;
528 wls_guid_p.u_min[3] = 0.;
529 wls_guid_p.u_max[3] = 0.;
533 wls_guid_p.u_pref[0] = 0;
534 wls_guid_p.u_pref[1] = -pitch_angle + pitch_pref_rad;
535 wls_guid_p.u_pref[2] = wls_guid_p.u_max[2];
536 wls_guid_p.u_pref[3] = body_v[0];
560 static struct FloatVect3 x_axis = {.
x = 1, .y = 0, .z = 0};
561 static struct FloatVect3 z_axis = {.
x = 0, .y = 0, .z = 1};
571 float body_to_wp_angle_rad = atan2f(
y,
x);
573 if (body_to_wp_angle_rad >= 0.f) {
587 static struct FloatVect3 x_axis = {.
x = 1, .y = 0, .z = 0};
593 target_enu.
x = 100.f * x_att_NED.
y + target_enu.
x;
594 target_enu.
y = 100.f * x_att_NED.
x + target_enu.
y;
599 RunOnceEvery(100 / 2, {
Main include for ABI (AirBorneInterface).
Event structure to store callbacks in a linked list.
#define ACT_FEEDBACK_BOARD_ID
struct point waypoints[NB_WAYPOINT]
size == nb_waypoint, waypoint 0 is a dummy waypoint
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
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).
static struct FloatQuat * stateGetNedToBodyQuat_f(void)
Get vehicle body attitude quaternion (float).
static struct NedCoor_f * stateGetPositionNed_f(void)
Get position in local NED coordinates (float).
static float stateGetAirspeed_f(void)
Get airspeed (float).
float guidance_indi_max_bank
struct FloatVect3 speed_sp
float guidance_indi_pitch_pref_deg
struct FloatEulers eulers_zxy
state eulers in zxy order
float gi_unbounded_airspeed_sp
void guidance_indi_set_min_max_airspeed(float min_airspeed, float max_airspeed)
A guidance mode based on Incremental Nonlinear Dynamic Inversion Come to ICRA2016 to learn more!
#define GUIDANCE_INDI_MAX_PITCH
#define GUIDANCE_INDI_MIN_PITCH
Hardware independent API for actuators (servos, motor controllers).
bool position
Position is set.
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)
float position
In radians.
void waypoint_set_enu(uint8_t wp_id, struct EnuCoor_f *enu)
Set local ENU waypoint coordinates.
float nav_max_deceleration_sp
vector in East North Up coordinates Units: meters
Rotorcraft specific autopilot interface and initialization.
struct HorizontalGuidance guidance_h
#define GUIDANCE_H_MODE_NONE
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
#define ROTWING_QUAD_PREF_PITCH
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
static const float Wu_gih_original[GUIDANCE_INDI_HYBRID_U]
#define ROTWING_SKEW_BACK_MARGIN
#define SERVO_BMOTOR_PUSH_IDX
#define AIRSPEED_IMPORTANCE_IN_FORWARD_WEIGHT
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)
static bool rotwing_state_hover_motors_idling(void)
Check if hover motors are idling (COMMAND_THRUST < ROTWING_QUAD_IDLE_MIN_THRUST) for ROTWING_QUAD_IDL...
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)
#define ROTWING_SKEW_ANGLE_STEP
struct rotwing_state_t rotwing_state
void guidance_indi_hybrid_set_wls_settings(float body_v[3], float roll_angle, float pitch_angle)
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
float meas_skew_angle_time
bool hover_motors_enabled
float ref_model_skew_angle_deg
float meas_skew_angle_deg
@ ROTWING_STATE_REQUEST_HOVER
@ ROTWING_STATE_FORCE_HOVER
@ ROTWING_STATE_REQUEST_FW
enum rotwing_states_t nav_state
struct Stabilization stabilization
#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.
float g1g2[INDI_OUTPUTS][INDI_NUM_ACT]
float actuator_state_filt_vect[INDI_NUM_ACT]
static const struct usb_device_descriptor dev
static float get_sys_time_float(void)
Get the time in seconds since startup.
int8_t register_periodic_telemetry(struct periodic_telemetry *_pt, uint8_t _id, telemetry_cb _cb)
Register a telemetry callback function.
Periodic telemetry system header (includes downlink utility and generated code).
#define DefaultPeriodic
Set default periodic telemetry.
unsigned char uint8_t
Typedef defining 8 bit unsigned char type.