From 19875f6343d27e117eef7d6f24481e998c3076d7 Mon Sep 17 00:00:00 2001 From: Christophe De Wagter Date: Tue, 3 Oct 2023 08:18:02 +0200 Subject: [PATCH] quadplane guidance (#3122) * quadplane guidance * Function doc and ifdef protect for normal guidance --- .../guidance/guidance_indi_hybrid.c | 224 ++++++++++++++---- .../guidance/guidance_indi_hybrid.h | 19 ++ .../guidance_indi_hybrid_quadplanes.h | 38 +++ .../guidance_indi_hybrid_tailsitters.h | 33 +++ 4 files changed, 270 insertions(+), 44 deletions(-) create mode 100644 sw/airborne/firmwares/rotorcraft/guidance/guidance_indi_hybrid_quadplanes.h create mode 100644 sw/airborne/firmwares/rotorcraft/guidance/guidance_indi_hybrid_tailsitters.h diff --git a/sw/airborne/firmwares/rotorcraft/guidance/guidance_indi_hybrid.c b/sw/airborne/firmwares/rotorcraft/guidance/guidance_indi_hybrid.c index 173ca84cef..4b947ddf8c 100644 --- a/sw/airborne/firmwares/rotorcraft/guidance/guidance_indi_hybrid.c +++ b/sw/airborne/firmwares/rotorcraft/guidance/guidance_indi_hybrid.c @@ -55,11 +55,6 @@ #define GUIDANCE_INDI_POS_GAINZ 0.5 #endif -#ifndef GUIDANCE_INDI_MIN_PITCH -#define GUIDANCE_INDI_MIN_PITCH -120 -#define GUIDANCE_INDI_MAX_PITCH 25 -#endif - #ifndef GUIDANCE_INDI_LIFTD_ASQ #define GUIDANCE_INDI_LIFTD_ASQ 0.20 #endif @@ -91,13 +86,31 @@ struct guidance_indi_hybrid_params gih_params = { #endif float guidance_indi_max_airspeed = GUIDANCE_INDI_MAX_AIRSPEED; +// Quadplanes can hover at various pref pitch +float guidance_indi_pitch_pref_deg = 0; + + +#if GUIDANCE_INDI_QUADPLANE +#ifndef GUIDANCE_INDI_THRUST_Z_EFF +#error "You need to define GUIDANCE_INDI_THRUST_Z_EFF" +#else +float guidance_indi_thrust_z_eff = GUIDANCE_INDI_THRUST_Z_EFF; +#endif + +#ifndef GUIDANCE_INDI_THRUST_X_EFF +#error "You need to define GUIDANCE_INDI_THRUST_X_EFF" +#else +float guidance_indi_thrust_x_eff = GUIDANCE_INDI_THRUST_X_EFF; +#endif +#endif + // If using WLS, check that the matrix size is sufficient #if GUIDANCE_INDI_HYBRID_USE_WLS -#if 3 > WLS_N_U +#if GUIDANCE_INDI_HYBRID_U > WLS_N_U #error Matrix-WLS_N_U too small: increase WLS_N_U in airframe file #endif -#if 3 > WLS_N_V +#if GUIDANCE_INDI_HYBRID_V > WLS_N_V #error Matrix-WLS_N_V too small: increase WLS_N_V in airframe file #endif #endif @@ -168,31 +181,33 @@ Butterworth2LowPass roll_filt; Butterworth2LowPass pitch_filt; Butterworth2LowPass thrust_filt; Butterworth2LowPass accely_filt; +Butterworth2LowPass accel_bodyz_filt; struct FloatVect2 desired_airspeed; -float Ga[3][3]; +float Ga[GUIDANCE_INDI_HYBRID_V][GUIDANCE_INDI_HYBRID_U]; struct FloatVect3 euler_cmd; #if GUIDANCE_INDI_HYBRID_USE_WLS #include "math/wls/wls_alloc.h" -float du_min_gih[3]; -float du_max_gih[3]; -float du_pref_gih[3]; -float *Bwls_gih[3]; +float du_min_gih[GUIDANCE_INDI_HYBRID_U]; +float du_max_gih[GUIDANCE_INDI_HYBRID_U]; +float du_pref_gih[GUIDANCE_INDI_HYBRID_U]; +float *Bwls_gih[GUIDANCE_INDI_HYBRID_V]; #ifdef GUIDANCE_INDI_HYBRID_WLS_PRIORITIES -float Wv_gih[3] = GUIDANCE_INDI_HYBRID_WLS_PRIORITIES; +float Wv_gih[GUIDANCE_INDI_HYBRID_V] = GUIDANCE_INDI_HYBRID_WLS_PRIORITIES; #else -float Wv_gih[3] = { 100.f, 100.f, 1.f }; // X,Y accel, Z accel +float Wv_gih[GUIDANCE_INDI_HYBRID_V] = { 100.f, 100.f, 1.f }; // X,Y accel, Z accel #endif #ifdef GUIDANCE_INDI_HYBRID_WLS_WU -float Wu_gih[3] = GUIDANCE_INDI_HYBRID_WLS_WU; +float Wu_gih[GUIDANCE_INDI_HYBRID_U] = GUIDANCE_INDI_HYBRID_WLS_WU; #else -float Wu_gih[3] = { 1.f, 1.f, 1.f }; +float Wu_gih[GUIDANCE_INDI_HYBRID_U] = { 1.f, 1.f, 1.f }; #endif #endif float filter_cutoff = GUIDANCE_INDI_FILTER_CUTOFF; +float bodyz_filter_cutoff = 0.2; float guidance_indi_hybrid_heading_sp = 0.f; struct FloatEulers guidance_euler_cmd; @@ -209,7 +224,7 @@ struct FloatVect3 indi_vel_sp = {0.0, 0.0, 0.0}; float time_of_vel_sp = 0.0; void guidance_indi_propagate_filters(void); -static void guidance_indi_calcg_wing(float Gmat[3][3]); +void guidance_indi_calcg_wing(float Gmat[GUIDANCE_INDI_HYBRID_V][GUIDANCE_INDI_HYBRID_U], struct FloatVect3 a_diff, float v_body[GUIDANCE_INDI_HYBRID_V]); #if PERIODIC_TELEMETRY #include "modules/datalink/telemetry.h" @@ -250,7 +265,7 @@ void guidance_indi_init(void) init_butterworth_2_low_pass(&accely_filt, tau, sample_time, 0.0); #if GUIDANCE_INDI_HYBRID_USE_WLS - for (int8_t i = 0; i < 3; i++) { + for (int8_t i = 0; i < GUIDANCE_INDI_HYBRID_V; i++) { Bwls_gih[i] = Ga[i]; } #endif @@ -274,6 +289,7 @@ void guidance_indi_enter(void) { guidance_indi_hybrid_heading_sp = stateGetNedToBodyEulers_f()->psi; float tau = 1.0 / (2.0 * M_PI * filter_cutoff); + float tau_bodyz = 1.0/(2.0*M_PI*bodyz_filter_cutoff); float sample_time = 1.0 / PERIODIC_FREQUENCY; for (int8_t i = 0; i < 3; i++) { init_butterworth_2_low_pass(&filt_accel_ned[i], tau, sample_time, 0.0); @@ -286,6 +302,7 @@ void guidance_indi_enter(void) { init_butterworth_2_low_pass(&pitch_filt, tau, sample_time, eulers_zxy.theta); init_butterworth_2_low_pass(&thrust_filt, tau, sample_time, thrust_in); init_butterworth_2_low_pass(&accely_filt, tau, sample_time, 0.0); + init_butterworth_2_low_pass(&accel_bodyz_filt, tau_bodyz, sample_time, -9.81); } #include "firmwares/rotorcraft/navigation.h" @@ -350,30 +367,25 @@ struct StabilizationSetpoint guidance_indi_run(struct FloatVect3 *accel_sp, floa #endif #endif - // Calculate matrix of partial derivatives - guidance_indi_calcg_wing(Ga); + + // Create the control objective + float v_gih[3]; + + // Calculate matrix of partial derivatives and control objective + guidance_indi_calcg_wing(Ga, a_diff, v_gih); #if GUIDANCE_INDI_HYBRID_USE_WLS - // Set lower limits - du_min_gih[0] = -guidance_indi_max_bank - roll_filt.o[0]; // roll - du_min_gih[1] = RadOfDeg(guidance_indi_min_pitch) - pitch_filt.o[0]; // pitch - du_min_gih[2] = (MAX_PPRZ - actuator_state_filt_vect[0]) * g1g2[3][0] + (MAX_PPRZ - actuator_state_filt_vect[1]) * g1g2[3][1] + (MAX_PPRZ - actuator_state_filt_vect[2]) * g1g2[3][2] + (MAX_PPRZ - actuator_state_filt_vect[3]) * g1g2[3][3]; - // Set upper limits limits - du_max_gih[0] = guidance_indi_max_bank - roll_filt.o[0]; //roll - du_max_gih[1] = RadOfDeg(GUIDANCE_INDI_MAX_PITCH) - pitch_filt.o[0]; // pitch - du_max_gih[2] = -(actuator_state_filt_vect[0]*g1g2[3][0] + actuator_state_filt_vect[1]*g1g2[3][1] + actuator_state_filt_vect[2]*g1g2[3][2] + actuator_state_filt_vect[3]*g1g2[3][3]); + // Calculate the maximum deflections + guidance_indi_hybrid_set_wls_settings(v_gih, roll_filt.o[0], pitch_filt.o[0]); - // Set prefered states - du_pref_gih[0] = -roll_filt.o[0]; // prefered delta roll angle - du_pref_gih[1] = -pitch_filt.o[0]; // prefered delta pitch angle - du_pref_gih[2] = du_max_gih[2]; + float du_gih[GUIDANCE_INDI_HYBRID_U]; // = {0.0f, 0.0f, 0.0f}; - float v_gih[3] = { a_diff.x, a_diff.y, a_diff.z }; - float du_gih[3]; int num_iter UNUSED = wls_alloc( du_gih, v_gih, du_min_gih, du_max_gih, - Bwls_gih, 0, 0, Wv_gih, Wu_gih, du_pref_gih, 100000, 10, 3, 3); + Bwls_gih, 0, 0, Wv_gih, Wu_gih, du_pref_gih, 100000, 10, + GUIDANCE_INDI_HYBRID_U, GUIDANCE_INDI_HYBRID_V); + euler_cmd.x = du_gih[0]; euler_cmd.y = du_gih[1]; euler_cmd.z = du_gih[2]; @@ -387,8 +399,12 @@ struct StabilizationSetpoint guidance_indi_run(struct FloatVect3 *accel_sp, floa #endif struct FloatVect3 thrust_vect; - thrust_vect.x = 0.0; // Fill for quadplanes - thrust_vect.y = 0.0; +#if GUIDANCE_INDI_HYBRID_U > 3 + thrust_vect.x = du_gih[3]; +#else + thrust_vect.x = 0; +#endif + thrust_vect.y = 0; thrust_vect.z = euler_cmd.z; AbiSendMsgTHRUST(THRUST_INCREMENT_ID, thrust_vect); @@ -686,7 +702,6 @@ struct StabilizationSetpoint guidance_indi_run_mode(bool in_flight UNUSED, struc } } -#ifdef GUIDANCE_INDI_SPECIFIC_FORCE_GAIN /** * Filter the thrust, such that it corresponds to the filtered acceleration */ @@ -698,7 +713,6 @@ void guidance_indi_filter_thrust(void) // same filter as for the acceleration update_butterworth_2_low_pass(&thrust_filt, thrust_act); } -#endif /** * Low pass the accelerometer measurements to remove noise from vibrations. @@ -718,6 +732,10 @@ void guidance_indi_propagate_filters(void) { // Propagate filter for sideslip correction float accely = ACCEL_FLOAT_OF_BFP(stateGetAccelBody_i()->y); update_butterworth_2_low_pass(&accely_filt, accely); + + // Propagate filter for thrust/lift estimate + float accelz = ACCEL_FLOAT_OF_BFP(stateGetAccelBody_i()->z); + update_butterworth_2_low_pass(&accel_bodyz_filt, accelz); } /** @@ -725,9 +743,12 @@ void guidance_indi_propagate_filters(void) { * w.r.t. the NED accelerations, taking into account the lift of a wing that is * horizontal at -90 degrees pitch * - * @param Gmat array to write the matrix to [3x3] + * @param Gmat Dynamics matrix + * @param a_diff acceleration errors in earth frame + * @param body_v 3D vector to write the control objective v */ -void guidance_indi_calcg_wing(float Gmat[3][3]) { +#if GUIDANCE_INDI_HYBRID_USE_WLS +void WEAK guidance_indi_calcg_wing(float Gmat[GUIDANCE_INDI_HYBRID_V][GUIDANCE_INDI_HYBRID_U], struct FloatVect3 a_diff, float v_gih[GUIDANCE_INDI_HYBRID_V]) { /*Pre-calculate sines and cosines*/ float sphi = sinf(eulers_zxy.phi); @@ -760,7 +781,122 @@ void guidance_indi_calcg_wing(float Gmat[3][3]) { Gmat[0][2] = stheta*cpsi + sphi*ctheta*spsi; Gmat[1][2] = stheta*spsi - sphi*ctheta*cpsi; Gmat[2][2] = cphi*ctheta; + + v_gih[0] = a_diff.x; + v_gih[1] = a_diff.y; + v_gih[2] = a_diff.z; } +#elif defined(GUIDANCE_INDI_QUADPLANE) +/** + * Perform WLS + * + * @param Gmat Dynamics matrix + * @param a_diff acceleration errors in earth frame + * @param body_v 3D vector to write the control objective v + */ +void WEAK guidance_indi_calcg_wing(float Gmat[GUIDANCE_INDI_HYBRID_V][GUIDANCE_INDI_HYBRID_U], struct FloatVect3 a_diff, float body_v[GUIDANCE_INDI_HYBRID_V]) { + /*Pre-calculate sines and cosines*/ + float sphi = sinf(eulers_zxy.phi); + float cphi = cosf(eulers_zxy.phi); + float stheta = sinf(eulers_zxy.theta); + float ctheta = cosf(eulers_zxy.theta); + float spsi = sinf(eulers_zxy.psi); + float cpsi = cosf(eulers_zxy.psi); + +#ifndef GUIDANCE_INDI_PITCH_EFF_SCALING +#define GUIDANCE_INDI_PITCH_EFF_SCALING 1.0 +#endif + + /*Amount of lift produced by the wing*/ + float lift_thrust_bz = accel_bodyz_filt.o[0]; // Sum of lift and thrust in boxy z axis (level flight) + + // get the derivative of the lift wrt to theta + float liftd = guidance_indi_get_liftd(0.0f, 0.0f); + + Gmat[0][0] = -sphi*stheta*lift_thrust_bz; + Gmat[1][0] = -cphi*lift_thrust_bz; + Gmat[2][0] = -sphi*ctheta*lift_thrust_bz; + + Gmat[0][1] = cphi*ctheta*lift_thrust_bz*GUIDANCE_INDI_PITCH_EFF_SCALING; + Gmat[1][1] = sphi*stheta*lift_thrust_bz*GUIDANCE_INDI_PITCH_EFF_SCALING - sphi*liftd; + Gmat[2][1] = -cphi*stheta*lift_thrust_bz*GUIDANCE_INDI_PITCH_EFF_SCALING + cphi*liftd; + + Gmat[0][2] = cphi*stheta; + Gmat[1][2] = -sphi; + Gmat[2][2] = cphi*ctheta; + + Gmat[0][3] = ctheta; + Gmat[1][3] = 0; + Gmat[2][3] = -stheta; + + // Convert acceleration error to body axis system + body_v[0] = cpsi * a_diff.x + spsi * a_diff.y; + body_v[1] = -spsi * a_diff.x + cpsi * a_diff.y; + body_v[2] = a_diff.z; +} + +#else + +void WEAK guidance_indi_calcg_wing(float Gmat[GUIDANCE_INDI_HYBRID_V][GUIDANCE_INDI_HYBRID_U] UNUSED, struct FloatVect3 a_diff UNUSED, float body_v[GUIDANCE_INDI_HYBRID_V] UNUSED) {} + +#endif +/** + * + * @param body_v + * + * WEAK function to set the quadplane wls settings + */ +#if GUIDANCE_INDI_HYBRID_USE_WLS +void WEAK guidance_indi_hybrid_set_wls_settings(float body_v[3] UNUSED, float roll_angle, float pitch_angle) +{ + // Set lower limits + du_min_gih[0] = -guidance_indi_max_bank - roll_angle; // roll + du_min_gih[1] = RadOfDeg(guidance_indi_min_pitch) - pitch_angle; // pitch + du_min_gih[2] = (MAX_PPRZ - actuator_state_filt_vect[0]) * g1g2[3][0] + (MAX_PPRZ - actuator_state_filt_vect[1]) * g1g2[3][1] + (MAX_PPRZ - actuator_state_filt_vect[2]) * g1g2[3][2] + (MAX_PPRZ - actuator_state_filt_vect[3]) * g1g2[3][3]; + + // Set upper limits limits + du_max_gih[0] = guidance_indi_max_bank - roll_angle; //roll + du_max_gih[1] = RadOfDeg(GUIDANCE_INDI_MAX_PITCH) - pitch_angle; // pitch + du_max_gih[2] = -(actuator_state_filt_vect[0]*g1g2[3][0] + actuator_state_filt_vect[1]*g1g2[3][1] + actuator_state_filt_vect[2]*g1g2[3][2] + actuator_state_filt_vect[3]*g1g2[3][3]); + + // Set prefered states + du_pref_gih[0] = -roll_angle; // prefered delta roll angle + du_pref_gih[1] = -pitch_angle; // prefered delta pitch angle + du_pref_gih[2] = du_max_gih[2]; +} +#elif defined(GUIDANCE_INDI_QUADPLANE) +#warning We have GUIDANCE_INDI_QUADPLANE +void WEAK guidance_indi_hybrid_set_wls_settings(float body_v[3], float roll_angle, float pitch_angle) +{ + float roll_limit_rad = GUIDANCE_H_MAX_BANK; + float max_pitch_limit_rad = RadOfDeg(GUIDANCE_INDI_MAX_PITCH); + float min_pitch_limit_rad = RadOfDeg(GUIDANCE_INDI_MIN_PITCH); + + float pitch_pref_rad = RadOfDeg(guidance_indi_pitch_pref_deg); + + // Set lower limits + du_min_gih[0] = -roll_limit_rad - roll_angle; //roll + du_min_gih[1] = min_pitch_limit_rad - pitch_angle; // pitch + du_min_gih[2] = (MAX_PPRZ - stabilization_cmd[COMMAND_THRUST]) * guidance_indi_thrust_z_eff; + du_min_gih[3] = -stabilization_cmd[COMMAND_THRUST_X]*guidance_indi_thrust_x_eff; + + // Set upper limits limits + du_max_gih[0] = roll_limit_rad - roll_angle; //roll + du_max_gih[1] = max_pitch_limit_rad - pitch_angle; // pitch + du_max_gih[2] = -stabilization_cmd[COMMAND_THRUST] * guidance_indi_thrust_z_eff; + du_max_gih[3] = (MAX_PPRZ - stabilization_cmd[COMMAND_THRUST_X])*guidance_indi_thrust_x_eff; + + // Set prefered states + du_pref_gih[0] = -roll_angle; // prefered delta roll angle + du_pref_gih[1] = -pitch_angle + pitch_pref_rad;// prefered delta pitch angle + du_pref_gih[2] = du_max_gih[2]; // Low thrust better for efficiency + du_pref_gih[3] = body_v[0]; // solve the body acceleration +} +#else +void WEAK guidance_indi_hybrid_set_wls_settings(float body_v[3] UNUSED, float roll_angle UNUSED, float pitch_angle UNUSED) { + +} +#endif /** * @brief Get the derivative of lift w.r.t. pitch. @@ -845,21 +981,21 @@ int32_t guidance_v_run_pos(bool in_flight UNUSED, struct VerticalGuidance *gv) { _gv = gv; _v_mode = GUIDANCE_INDI_HYBRID_V_POS; - return (int32_t)thrust_in; // nothing to do + return (int32_t)stabilization_cmd[COMMAND_THRUST]; // nothing to do } int32_t guidance_v_run_speed(bool in_flight UNUSED, struct VerticalGuidance *gv) { _gv = gv; _v_mode = GUIDANCE_INDI_HYBRID_V_SPEED; - return (int32_t)thrust_in; // nothing to do + return (int32_t)stabilization_cmd[COMMAND_THRUST]; // nothing to do } int32_t guidance_v_run_accel(bool in_flight UNUSED, struct VerticalGuidance *gv) { _gv = gv; _v_mode = GUIDANCE_INDI_HYBRID_V_ACCEL; - return (int32_t)thrust_in; // nothing to do + return (int32_t)stabilization_cmd[COMMAND_THRUST]; // nothing to do } #endif diff --git a/sw/airborne/firmwares/rotorcraft/guidance/guidance_indi_hybrid.h b/sw/airborne/firmwares/rotorcraft/guidance/guidance_indi_hybrid.h index c59e7ca8e8..c687b96f89 100644 --- a/sw/airborne/firmwares/rotorcraft/guidance/guidance_indi_hybrid.h +++ b/sw/airborne/firmwares/rotorcraft/guidance/guidance_indi_hybrid.h @@ -37,11 +37,20 @@ #include "firmwares/rotorcraft/guidance.h" #include "firmwares/rotorcraft/stabilization.h" +#ifdef GUIDANCE_INDI_QUADPLANE +#include "firmwares/rotorcraft/guidance/guidance_indi_hybrid_quadplanes.h" +#define GUIDANCE_INDI_HYBRID_USE_WLS true +#else +#include "firmwares/rotorcraft/guidance/guidance_indi_hybrid_tailsitters.h" +#endif + + // TODO change names for _indi_hybrid_ extern void guidance_indi_init(void); extern void guidance_indi_enter(void); extern float guidance_indi_get_liftd(float pitch, float theta); +extern void guidance_indi_hybrid_set_wls_settings(float body_v[3], float roll_angle, float pitch_angle); enum GuidanceIndiHybrid_HMode { GUIDANCE_INDI_HYBRID_H_POS, @@ -72,6 +81,16 @@ struct guidance_indi_hybrid_params { extern struct FloatVect3 sp_accel; extern struct FloatVect3 gi_speed_sp; +extern float guidance_indi_pitch_pref_deg; + +extern float Wu_gih[GUIDANCE_INDI_HYBRID_U]; +extern float Wv_gih[GUIDANCE_INDI_HYBRID_V]; +extern float du_min_gih[GUIDANCE_INDI_HYBRID_U]; +extern float du_max_gih[GUIDANCE_INDI_HYBRID_U]; +extern float du_pref_gih[GUIDANCE_INDI_HYBRID_U]; +extern float guidance_indi_thrust_z_eff; +extern float guidance_indi_thrust_x_eff; + extern struct guidance_indi_hybrid_params gih_params; extern float guidance_indi_specific_force_gain; extern float guidance_indi_max_airspeed; diff --git a/sw/airborne/firmwares/rotorcraft/guidance/guidance_indi_hybrid_quadplanes.h b/sw/airborne/firmwares/rotorcraft/guidance/guidance_indi_hybrid_quadplanes.h new file mode 100644 index 0000000000..793e04f8f9 --- /dev/null +++ b/sw/airborne/firmwares/rotorcraft/guidance/guidance_indi_hybrid_quadplanes.h @@ -0,0 +1,38 @@ +/* + * Copyright (C) 2023 TUDelft + * + * This file is part of paparazzi. + * + * paparazzi is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * paparazzi is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with paparazzi; see the file COPYING. If not, write to + * the Free Software Foundation, 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + + + +// Guidance actuators: (roll, pitch, thrust, push) for quadplanes +#define GUIDANCE_INDI_HYBRID_U 4 + +// Guidance control objectives: ax, ay, ay for quadplanes +#define GUIDANCE_INDI_HYBRID_V 3 + + + +#ifndef GUIDANCE_INDI_MIN_PITCH +#define GUIDANCE_INDI_MIN_PITCH -20 +#define GUIDANCE_INDI_MAX_PITCH 20 +#endif + + + diff --git a/sw/airborne/firmwares/rotorcraft/guidance/guidance_indi_hybrid_tailsitters.h b/sw/airborne/firmwares/rotorcraft/guidance/guidance_indi_hybrid_tailsitters.h new file mode 100644 index 0000000000..e0f4165de6 --- /dev/null +++ b/sw/airborne/firmwares/rotorcraft/guidance/guidance_indi_hybrid_tailsitters.h @@ -0,0 +1,33 @@ +/* + * Copyright (C) 2023 TUDelft + * + * This file is part of paparazzi. + * + * paparazzi is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * paparazzi is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with paparazzi; see the file COPYING. If not, write to + * the Free Software Foundation, 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + + + +// Guidance actuators: (roll, pitch, thrust) for tailsitters +#define GUIDANCE_INDI_HYBRID_U 3 + +// Guidance control objectives: ax, ay, ay for tailsitters +#define GUIDANCE_INDI_HYBRID_V 3 + +#ifndef GUIDANCE_INDI_MIN_PITCH +#define GUIDANCE_INDI_MIN_PITCH -120 +#define GUIDANCE_INDI_MAX_PITCH 25 +#endif