-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[ctrl] Morphing quad-plane control eff (#3124)
- Loading branch information
Showing
4 changed files
with
344 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
<!DOCTYPE module SYSTEM "module.dtd"> | ||
<module name="ctrl_eff_sched_rot_wing" dir="ctrl"> | ||
<doc> | ||
<description>The control effectiveness scheduler for the rotating wing drone type</description> | ||
<section name="ROT_WING" prefix="ROT_WING_EFF_SCHED_"> | ||
<define name="IXX_BODY" value="0" description=""/> | ||
<define name="IYY_BODY" value="0" description=""/> | ||
<define name="IZZ" value="0" description=""/> | ||
<define name="IXX_WING" value="0" description=""/> | ||
<define name="IYY_WING" value="0" description=""/> | ||
<define name="M" value="0" description=""/> | ||
<define name="ROLL_ARM" value="0" description=""/> | ||
<define name="PITCH_ARM" value="0" description=""/> | ||
<define name="HOVER_DF_DPPRZ" value="0" description=""/> | ||
<define name="HOVER_ROLL_PITCH_COEF" value="{0,0}" description=""/> | ||
</section> | ||
</doc> | ||
<settings> | ||
<dl_settings> | ||
<dl_settings NAME="Eff_sched"> | ||
<dl_setting var="rotation_angle_setpoint_deg" min="0" step="1" max="90" shortname="rotation" module="modules/ctrl/ctrl_eff_sched_rot_wing"/> | ||
</dl_settings> | ||
</dl_settings> | ||
</settings> | ||
<header> | ||
<file name="ctrl_eff_sched_rot_wing.h"/> | ||
</header> | ||
<init fun="ctrl_eff_sched_rot_wing_init()"/> | ||
<periodic fun="ctrl_eff_sched_rot_wing_periodic()" freq="10.0"/> | ||
<makefile> | ||
<file name="ctrl_eff_sched_rot_wing.c"/> | ||
<test> | ||
<define name="INDI_NUM_ACT" value="4"/> | ||
<define name="INDI_OUTPUTS" value="3"/> | ||
<define name="ROT_WING_EFF_SCHED_IXX_BODY" value="1"/> | ||
<define name="ROT_WING_EFF_SCHED_IYY_BODY" value="1"/> | ||
<define name="ROT_WING_EFF_SCHED_IZZ" value="1"/> | ||
<define name="ROT_WING_EFF_SCHED_IXX_WING" value="1"/> | ||
<define name="ROT_WING_EFF_SCHED_IYY_WING" value="1"/> | ||
<define name="ROT_WING_EFF_SCHED_M" value="1"/> | ||
<define name="ROT_WING_EFF_SCHED_ROLL_ARM" value="1"/> | ||
<define name="ROT_WING_EFF_SCHED_PITCH_ARM" value="1"/> | ||
<define name="ROT_WING_EFF_SCHED_HOVER_DF_DPPRZ" value="1"/> | ||
<define name="ROT_WING_EFF_SCHED_HOVER_ROLL_PITCH_COEF" value="{1,1}"/> | ||
</test> | ||
</makefile> | ||
</module> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,231 @@ | ||
/* | ||
* Copyright (C) 2023 Dennis van Wijngaarden <D.C.vanWijngaarden@tudelft.nl> | ||
* | ||
* 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, see | ||
* <http://www.gnu.org/licenses/>. | ||
*/ | ||
|
||
/** @file "modules/ctrl/ctrl_eff_sched_rot_wing.c" | ||
* @author Dennis van Wijngaarden <D.C.vanWijngaarden@tudelft.nl> | ||
* The control effectiveness scheduler for the rotating wing drone type | ||
*/ | ||
|
||
#include "modules/ctrl/ctrl_eff_sched_rot_wing.h" | ||
|
||
#include "firmwares/rotorcraft/stabilization/stabilization_indi.h" | ||
#include "modules/core/abi.h" | ||
|
||
|
||
#ifndef ROT_WING_EFF_SCHED_IXX_BODY | ||
#error "NO ROT_WING_EFF_SCHED_IXX_BODY defined" | ||
#endif | ||
|
||
#ifndef ROT_WING_EFF_SCHED_IYY_BODY | ||
#error "NO ROT_WING_EFF_SCHED_IYY_BODY defined" | ||
#endif | ||
|
||
#ifndef ROT_WING_EFF_SCHED_IZZ | ||
#error "NO ROT_WING_EFF_SCHED_IZZ defined" | ||
#endif | ||
|
||
#ifndef ROT_WING_EFF_SCHED_IXX_WING | ||
#error "NO ROT_WING_EFF_SCHED_IXX_WING defined" | ||
#endif | ||
|
||
#ifndef ROT_WING_EFF_SCHED_IYY_WING | ||
#error "NO ROT_WING_EFF_SCHED_IYY_WING defined" | ||
#endif | ||
|
||
#ifndef ROT_WING_EFF_SCHED_M | ||
#error "NO ROT_WING_EFF_SCHED_M defined" | ||
#endif | ||
|
||
#ifndef ROT_WING_EFF_SCHED_ROLL_ARM | ||
#error "NO ROT_WING_EFF_SCHED_ROLL_ARM defined" | ||
#endif | ||
|
||
#ifndef ROT_WING_EFF_SCHED_PITCH_ARM | ||
#error "NO ROT_WING_EFF_SCHED_PITCH_ARM defined" | ||
#endif | ||
|
||
#ifndef ROT_WING_EFF_SCHED_HOVER_DF_DPPRZ | ||
#error "NO ROT_WING_EFF_SCHED_HOVER_DF_DPPRZ defined" | ||
#endif | ||
|
||
#ifndef ROT_WING_EFF_SCHED_HOVER_ROLL_PITCH_COEF | ||
#error "NO ROT_WING_EFF_SCHED_HOVER_ROLL_PITCH_COEF defined" | ||
#endif | ||
|
||
struct rot_wing_eff_sched_param_t eff_sched_p = { | ||
.Ixx_body = ROT_WING_EFF_SCHED_IXX_BODY, | ||
.Iyy_body = ROT_WING_EFF_SCHED_IYY_BODY, | ||
.Izz = ROT_WING_EFF_SCHED_IZZ, | ||
.Ixx_wing = ROT_WING_EFF_SCHED_IXX_WING, | ||
.Iyy_wing = ROT_WING_EFF_SCHED_IYY_WING, | ||
.m = ROT_WING_EFF_SCHED_M, | ||
.roll_arm = ROT_WING_EFF_SCHED_ROLL_ARM, | ||
.pitch_arm = ROT_WING_EFF_SCHED_PITCH_ARM, | ||
.hover_dFdpprz = ROT_WING_EFF_SCHED_HOVER_DF_DPPRZ, | ||
.hover_roll_pitch_coef = ROT_WING_EFF_SCHED_HOVER_ROLL_PITCH_COEF | ||
}; | ||
|
||
struct rot_wing_eff_sched_var_t eff_sched_var; | ||
|
||
float rotation_angle_setpoint_deg = 0; // Quad mode | ||
int16_t rotation_cmd = 9600; // Quad mode | ||
float pprz_angle_step = 9600. / 45.; // CMD per degree | ||
|
||
// Telemetry | ||
#if PERIODIC_TELEMETRY | ||
#include "modules/datalink/telemetry.h" | ||
static void send_rotating_wing_state(struct transport_tx *trans, struct link_device *dev) | ||
{ | ||
uint8_t state = 0; // Quadrotor | ||
float angle = eff_sched_var.wing_rotation_rad / M_PI * 180.f; | ||
pprz_msg_send_ROTATING_WING_STATE(trans, dev, AC_ID, | ||
&state, | ||
&state, | ||
&angle, | ||
&rotation_angle_setpoint_deg, | ||
0, | ||
0); | ||
} | ||
#endif | ||
|
||
|
||
/** ABI binding wing position data. | ||
*/ | ||
#ifndef CTRL_EFF_SCHED_ROT_WING_ID | ||
#define CTRL_EFF_SCHED_ROT_WING_ID ABI_BROADCAST | ||
#endif | ||
PRINT_CONFIG_VAR(CTRL_EFF_SCHED_ROT_WING_ID) | ||
static abi_event wing_position_ev; | ||
|
||
static void wing_position_cb(uint8_t sender_id UNUSED, struct act_feedback_t *pos_msg, uint8_t num_act) | ||
{ | ||
for (int i=0; i<num_act; i++){ | ||
if (pos_msg[i].set.position && (pos_msg[i].idx = 7)) | ||
{ | ||
// Get wing rotation angle from sensor | ||
eff_sched_var.wing_rotation_rad = 0.5 * M_PI - pos_msg[i].position; | ||
|
||
// Bound wing rotation angle | ||
Bound(eff_sched_var.wing_rotation_rad, 0, 0.5*M_PI); | ||
} | ||
} | ||
} | ||
|
||
|
||
inline void ctrl_eff_sched_rot_wing_update_wing_angle_sp(void); | ||
inline void ctrl_eff_sched_rot_wing_update_wing_angle(void); | ||
inline void ctrl_eff_sched_rot_wing_update_MMOI(void); | ||
inline void ctrl_eff_sched_rot_wing_update_hover_motor_effectiveness(void); | ||
|
||
void ctrl_eff_sched_rot_wing_init(void) | ||
{ | ||
// Initialize variables to quad values | ||
eff_sched_var.Ixx = eff_sched_p.Ixx_body + eff_sched_p.Ixx_wing; | ||
eff_sched_var.Iyy = eff_sched_p.Iyy_body + eff_sched_p.Iyy_wing; | ||
eff_sched_var.wing_rotation_rad = 0; | ||
eff_sched_var.cosr = 1; | ||
eff_sched_var.sinr = 0; | ||
eff_sched_var.cosr2 = 1; | ||
eff_sched_var.sinr2 = 0; | ||
eff_sched_var.cosr3 = 1; | ||
|
||
// Set moment derivative variables | ||
eff_sched_var.pitch_motor_dMdpprz = eff_sched_p.hover_dFdpprz * eff_sched_p.pitch_arm; | ||
eff_sched_var.roll_motor_dMdpprz = eff_sched_p.hover_dFdpprz * eff_sched_p.roll_arm; | ||
|
||
AbiBindMsgACT_FEEDBACK(CTRL_EFF_SCHED_ROT_WING_ID, &wing_position_ev, wing_position_cb); | ||
|
||
|
||
#if PERIODIC_TELEMETRY | ||
register_periodic_telemetry(DefaultPeriodic, PPRZ_MSG_ID_ROTATING_WING_STATE, send_rotating_wing_state); | ||
#endif | ||
} | ||
|
||
void ctrl_eff_sched_rot_wing_periodic(void) | ||
{ | ||
// your periodic code here. | ||
// freq = 10.0 Hz | ||
ctrl_eff_sched_rot_wing_update_wing_angle_sp(); | ||
ctrl_eff_sched_rot_wing_update_wing_angle(); | ||
ctrl_eff_sched_rot_wing_update_MMOI(); | ||
|
||
// Update the effectiveness values | ||
ctrl_eff_sched_rot_wing_update_hover_motor_effectiveness(); | ||
|
||
} | ||
|
||
void ctrl_eff_sched_rot_wing_update_wing_angle_sp(void) | ||
{ | ||
rotation_cmd = MAX_PPRZ - (int16_t)(rotation_angle_setpoint_deg * pprz_angle_step); | ||
// Calulcate rotation_cmd | ||
Bound(rotation_cmd, -9600, 9600); | ||
} | ||
|
||
void ctrl_eff_sched_rot_wing_update_wing_angle(void) | ||
{ | ||
// Calculate sin and cosines of rotation | ||
eff_sched_var.cosr = cosf(eff_sched_var.wing_rotation_rad); | ||
eff_sched_var.sinr = sinf(eff_sched_var.wing_rotation_rad); | ||
|
||
eff_sched_var.cosr2 = eff_sched_var.cosr * eff_sched_var.cosr; | ||
eff_sched_var.sinr2 = eff_sched_var.sinr * eff_sched_var.sinr; | ||
|
||
eff_sched_var.cosr3 = eff_sched_var.cosr2 * eff_sched_var.cosr; | ||
} | ||
|
||
void ctrl_eff_sched_rot_wing_update_MMOI(void) | ||
{ | ||
eff_sched_var.Ixx = eff_sched_p.Ixx_body + eff_sched_var.cosr2 * eff_sched_p.Ixx_wing + eff_sched_var.sinr2 * eff_sched_p.Iyy_wing; | ||
eff_sched_var.Iyy = eff_sched_p.Iyy_body + eff_sched_var.sinr2 * eff_sched_p.Ixx_wing + eff_sched_var.cosr2 * eff_sched_p.Iyy_wing; | ||
|
||
// Bound inertia | ||
Bound(eff_sched_var.Ixx, 0.01, 100.); | ||
Bound(eff_sched_var.Iyy, 0.01, 100.); | ||
} | ||
|
||
void ctrl_eff_sched_rot_wing_update_hover_motor_effectiveness(void) | ||
{ | ||
// Pitch motor effectiveness | ||
|
||
float pitch_motor_q_eff = eff_sched_var.pitch_motor_dMdpprz / eff_sched_var.Iyy; | ||
|
||
// Roll motor effectiveness | ||
|
||
float roll_motor_p_eff = eff_sched_var.roll_motor_dMdpprz * eff_sched_var.cosr / eff_sched_var.Ixx; | ||
// float roll_motor_q_eff = eff_sched_var.roll_motor_dMdpprz * eff_sched_var.sinr * | ||
// (eff_sched_p.hover_roll_pitch_coef[0] + eff_sched_p.hover_roll_pitch_coef[1] * eff_sched_var.cosr2) / eff_sched_var.Iyy; | ||
|
||
float roll_motor_q_eff = (eff_sched_var.roll_motor_dMdpprz * eff_sched_var.sinr / eff_sched_var.Iyy) * (eff_sched_p.hover_roll_pitch_coef[0] + eff_sched_p.hover_roll_pitch_coef[1] * eff_sched_var.cosr3); | ||
|
||
// Update front pitch motor q effectiveness | ||
g1g2[1][0] = pitch_motor_q_eff; // pitch effectiveness front motor | ||
|
||
// Update back motor q effectiveness | ||
g1g2[1][2] = -pitch_motor_q_eff; // pitch effectiveness back motor | ||
|
||
// Update right motor p and q effectiveness | ||
g1g2[0][1] = -roll_motor_p_eff; // roll effectiveness right motor | ||
g1g2[1][1] = roll_motor_q_eff; // pitch effectiveness right motor | ||
|
||
// Update left motor p and q effectiveness | ||
g1g2[0][3] = roll_motor_p_eff; // roll effectiveness left motor | ||
g1g2[1][3] = -roll_motor_q_eff; // pitch effectiveness left motor | ||
} | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
/* | ||
* Copyright (C) 2023 Dennis van Wijngaarden <D.C.vanWijngaarden@tudelft.nl> | ||
* | ||
* 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, see | ||
* <http://www.gnu.org/licenses/>. | ||
*/ | ||
|
||
/** @file "modules/ctrl/ctrl_eff_sched_rot_wing.h" | ||
* @author Dennis van Wijngaarden <D.C.vanWijngaarden@tudelft.nl> | ||
* The control effectiveness scheduler for the rotating wing drone type | ||
*/ | ||
|
||
#ifndef CTRL_EFF_SCHED_ROT_WING_H | ||
#define CTRL_EFF_SCHED_ROT_WING_H | ||
|
||
#include "std.h" | ||
|
||
struct rot_wing_eff_sched_param_t { | ||
float Ixx_body; // body MMOI around roll axis [kgm²] | ||
float Iyy_body; // body MMOI around pitch axis [kgm²] | ||
float Izz; // total MMOI around yaw axis [kgm²] | ||
float Ixx_wing; // wing MMOI around the chordwise direction of the wing [kgm²] | ||
float Iyy_wing; // wing MMOI around the spanwise direction of the wing [kgm²] | ||
float m; // mass [kg] | ||
float roll_arm; // distance from rotation point to roll motor [m] | ||
float pitch_arm; // distance from rotation point to pitch motor [m] | ||
float hover_dFdpprz; // derivative of delta force with respect to a delta paparazzi command [N/pprz] | ||
float hover_roll_pitch_coef[2]; // Model coefficients to correct pitch effective for roll motors | ||
}; | ||
|
||
struct rot_wing_eff_sched_var_t { | ||
float Ixx; // Total MMOI around roll axis [kgm²] | ||
float Iyy; // Total MMOI around pitch axis [kgm²] | ||
float wing_rotation_rad; // Wing rotation angle in radians | ||
float cosr; // cosine of wing rotation angle | ||
float sinr; // sine of wing rotation angle | ||
float cosr2; // cosine² of wing rotation angle | ||
float sinr2; // sine² of wing rotation angle | ||
float cosr3; // cos³ of wing rotation angle | ||
|
||
// Set during initialization | ||
float pitch_motor_dMdpprz; // derivative of delta moment with respect to a delta paparazzi command for the pitch motors [Nm/pprz] | ||
float roll_motor_dMdpprz; // derivative of delta moment with respect to a delta paparazzi command for the roll motors [Nm/pprz] | ||
}; | ||
|
||
extern float rotation_angle_setpoint_deg; | ||
extern int16_t rotation_cmd; | ||
|
||
extern void ctrl_eff_sched_rot_wing_init(void); | ||
extern void ctrl_eff_sched_rot_wing_periodic(void); | ||
|
||
#endif // CTRL_EFF_SCHED_ROT_WING_H |