From 308a698bf41edcdf2b0ff3b25dc59486319db7da Mon Sep 17 00:00:00 2001 From: Christophe De Wagter Date: Wed, 5 Jun 2024 14:58:07 +0200 Subject: [PATCH] [tudelft] Rot Wing Updates V3 (#3278) * max bank in deg * takeoff no attitude msec timer * Prepared elevator moment compensation fix * [EHVB_rotwing fp] Updated takeoff stratgey with roll and pitch check and added standby_free to flightplan * [fp EHVB] Takeoff 3 seconds on att 0,0 * increase filter freq and setting for max acc * [rot_wing_eff_sched] Elevator 5 degrees higher * [rot_wing] Decreased cutoff frequencies of filters * [modules] Support dual ublox GPS modules * [ekf2] Add failsafe remove yaw * Reverted acceleration limits * takeoff procedure update * [flight_plan] Takeoff when hover motors are running * scale elevator ctrl eff in transition * [conf] Fix takeoff * Higher pitch gains * Fix conf * Add extra throttle for spinup * Update calibration * max_bank in Radians only except in xml/gcs with auto-conversion * cleanup * Use flightplan variables instead... * fix test * revert debugging action * cleanup unused * cleanup more * Fix compile bug * [pfc] Fix actuators * Add follow tests * reduce pitch weight in forward flight * correctly set cmd thrust in INDI * fix takeoff unequal roll effectiveness and not in_flight * Fix heading in approach * fix double define and roll scaling setting * settings names and roll scaling in right settings * moving simulator stuff * [flight_plan] Update angel for takeoff * Update conf * Conf update * [conf] Update checks * land in approach * Fix flightplan * Update sw/ground_segment/python/moving_base/moving_base.py * input params for moving base sim * no elevator compensation --------- Co-authored-by: Ewoud Smeur Co-authored-by: Dennis van Wijngaarden <32736330+Dennis-Wijngaarden@users.noreply.github.com> Co-authored-by: Freek van Tienen --- conf/airframes/tudelft/rot_wing_25kg.xml | 5 +- conf/airframes/tudelft/rot_wing_v3b.xml | 9 +- conf/airframes/tudelft/rot_wing_v3d.xml | 9 +- conf/airframes/tudelft/rot_wing_v3e.xml | 9 +- conf/airframes/tudelft/rot_wing_v3f.xml | 9 +- conf/airframes/tudelft/rot_wing_v3g.xml | 24 +- conf/airframes/tudelft/rot_wing_v3h.xml | 13 +- .../tudelft/rotating_wing_EHR8.xml | 31 +- .../tudelft/rotating_wing_EHVB.xml | 36 +- conf/modules/eff_scheduling_rot_wing.xml | 3 +- conf/modules/ins_ekf2.xml | 2 +- conf/modules/parachute.xml | 2 +- conf/modules/pfc_actuators.xml | 2 +- conf/userconf/tudelft/conf.xml | 41 +- conf/userconf/tudelft/control_panel.xml | 357 +++++++++--------- .../stabilization/stabilization_indi.c | 22 +- .../modules/ctrl/approach_moving_target.c | 4 +- .../modules/ctrl/eff_scheduling_rot_wing.c | 28 +- .../modules/ctrl/eff_scheduling_rot_wing.h | 2 + .../modules/rot_wing_drone/rotwing_state.c | 26 +- .../modules/rot_wing_drone/rotwing_state.h | 1 + .../python/moving_base/moving_base.py | 46 ++- 22 files changed, 436 insertions(+), 245 deletions(-) diff --git a/conf/airframes/tudelft/rot_wing_25kg.xml b/conf/airframes/tudelft/rot_wing_25kg.xml index 23f865050f..dd349dd45f 100644 --- a/conf/airframes/tudelft/rot_wing_25kg.xml +++ b/conf/airframes/tudelft/rot_wing_25kg.xml @@ -281,7 +281,8 @@ - + + @@ -446,7 +447,7 @@ - + diff --git a/conf/airframes/tudelft/rot_wing_v3b.xml b/conf/airframes/tudelft/rot_wing_v3b.xml index ecc5690b7a..a757334d76 100644 --- a/conf/airframes/tudelft/rot_wing_v3b.xml +++ b/conf/airframes/tudelft/rot_wing_v3b.xml @@ -338,7 +338,8 @@ - + + @@ -426,10 +427,10 @@ - + - + @@ -490,7 +491,7 @@ - + diff --git a/conf/airframes/tudelft/rot_wing_v3d.xml b/conf/airframes/tudelft/rot_wing_v3d.xml index 730822a27a..888a077243 100644 --- a/conf/airframes/tudelft/rot_wing_v3d.xml +++ b/conf/airframes/tudelft/rot_wing_v3d.xml @@ -326,7 +326,8 @@ - + + @@ -414,10 +415,10 @@ - + - + @@ -477,7 +478,7 @@ - + diff --git a/conf/airframes/tudelft/rot_wing_v3e.xml b/conf/airframes/tudelft/rot_wing_v3e.xml index f72ef8cd26..f983c536a6 100644 --- a/conf/airframes/tudelft/rot_wing_v3e.xml +++ b/conf/airframes/tudelft/rot_wing_v3e.xml @@ -326,7 +326,8 @@ - + + @@ -414,10 +415,10 @@ - + - + @@ -477,7 +478,7 @@ - + diff --git a/conf/airframes/tudelft/rot_wing_v3f.xml b/conf/airframes/tudelft/rot_wing_v3f.xml index 4ed1a1519c..0c49a0899c 100644 --- a/conf/airframes/tudelft/rot_wing_v3f.xml +++ b/conf/airframes/tudelft/rot_wing_v3f.xml @@ -326,7 +326,8 @@ - + + @@ -414,10 +415,10 @@ - + - + @@ -477,7 +478,7 @@ - + diff --git a/conf/airframes/tudelft/rot_wing_v3g.xml b/conf/airframes/tudelft/rot_wing_v3g.xml index 94353f1450..6142367873 100644 --- a/conf/airframes/tudelft/rot_wing_v3g.xml +++ b/conf/airframes/tudelft/rot_wing_v3g.xml @@ -30,6 +30,7 @@ + @@ -323,14 +324,15 @@ - + - + + @@ -339,7 +341,6 @@ -
@@ -421,10 +422,10 @@ - + - + @@ -484,7 +485,7 @@ - + @@ -502,6 +503,7 @@ +
@@ -512,12 +514,16 @@
- - + +
+
+ +
+
@@ -553,7 +559,9 @@ Check tail connection Check wings taped and secured Check attitude and heading + Airspeed sensor calibration Put UAV on take-off location + Automated actuator check Check flight plan Switch to correct flight block Switch on camera diff --git a/conf/airframes/tudelft/rot_wing_v3h.xml b/conf/airframes/tudelft/rot_wing_v3h.xml index caf1cf2d64..8f8648b082 100644 --- a/conf/airframes/tudelft/rot_wing_v3h.xml +++ b/conf/airframes/tudelft/rot_wing_v3h.xml @@ -30,6 +30,7 @@ + @@ -330,7 +331,8 @@ - + + @@ -339,7 +341,6 @@ -
@@ -354,7 +355,7 @@
- + @@ -421,10 +422,10 @@ - + - + @@ -484,7 +485,7 @@ - + diff --git a/conf/flight_plans/tudelft/rotating_wing_EHR8.xml b/conf/flight_plans/tudelft/rotating_wing_EHR8.xml index 49c2874f26..3eeea527a2 100644 --- a/conf/flight_plans/tudelft/rotating_wing_EHR8.xml +++ b/conf/flight_plans/tudelft/rotating_wing_EHR8.xml @@ -41,9 +41,14 @@ + + + + + - + @@ -59,7 +64,7 @@ - + @@ -68,16 +73,25 @@ + + - + + + + + - - + + + + + @@ -92,6 +106,13 @@ + + + + + + + - - + + @@ -41,10 +41,15 @@ + + + + + - + + + @@ -68,16 +73,25 @@ + + - + + + + + - - + + + + + @@ -162,6 +176,10 @@ --> + + + + diff --git a/conf/modules/eff_scheduling_rot_wing.xml b/conf/modules/eff_scheduling_rot_wing.xml index f436729246..0a055a22b5 100644 --- a/conf/modules/eff_scheduling_rot_wing.xml +++ b/conf/modules/eff_scheduling_rot_wing.xml @@ -22,6 +22,7 @@ + @@ -32,7 +33,7 @@ - + diff --git a/conf/modules/ins_ekf2.xml b/conf/modules/ins_ekf2.xml index 5e061d81a8..d32f9d00e8 100644 --- a/conf/modules/ins_ekf2.xml +++ b/conf/modules/ins_ekf2.xml @@ -49,7 +49,7 @@ - + diff --git a/conf/modules/parachute.xml b/conf/modules/parachute.xml index ea547beb4b..e821b27058 100644 --- a/conf/modules/parachute.xml +++ b/conf/modules/parachute.xml @@ -7,7 +7,7 @@ - + diff --git a/conf/modules/pfc_actuators.xml b/conf/modules/pfc_actuators.xml index a8d9a3eb2d..0593b54417 100644 --- a/conf/modules/pfc_actuators.xml +++ b/conf/modules/pfc_actuators.xml @@ -12,7 +12,7 @@ - + diff --git a/conf/userconf/tudelft/conf.xml b/conf/userconf/tudelft/conf.xml index 9264f8ba41..fd0959c924 100644 --- a/conf/userconf/tudelft/conf.xml +++ b/conf/userconf/tudelft/conf.xml @@ -557,7 +557,7 @@ telemetry="telemetry/highspeed_rotorcraft.xml" flight_plan="flight_plans/tudelft/rotating_wing_EHVB.xml" settings="settings/rotorcraft_basic.xml" - settings_modules="modules/air_data.xml modules/airspeed_ms45xx_i2c.xml modules/airspeed_uavcan.xml modules/approach_moving_target.xml modules/electrical.xml modules/gps.xml modules/gps_ublox.xml modules/guidance_indi_hybrid.xml modules/guidance_rotorcraft.xml modules/imu_common.xml modules/imu_heater.xml modules/ins_ekf2.xml modules/logger_sd_chibios.xml modules/nav_hybrid.xml modules/nav_rotorcraft.xml modules/preflight_checks.xml modules/rot_wing_automation.xml modules/rotwing_state.xml modules/stabilization_indi.xml modules/sys_id_auto_doublets.xml modules/sys_id_doublet.xml modules/target_pos.xml" + settings_modules="modules/air_data.xml modules/airspeed_ms45xx_i2c.xml modules/airspeed_uavcan.xml modules/approach_moving_target.xml modules/eff_scheduling_rot_wing.xml modules/electrical.xml modules/gps.xml modules/gps_ublox.xml modules/guidance_indi_hybrid.xml modules/guidance_rotorcraft.xml modules/imu_common.xml modules/imu_heater.xml modules/ins_ekf2.xml modules/logger_sd_chibios.xml modules/nav_hybrid.xml modules/nav_rotorcraft.xml modules/preflight_checks.xml modules/rot_wing_automation.xml modules/rotwing_state.xml modules/stabilization_indi.xml modules/sys_id_auto_doublets.xml modules/sys_id_doublet.xml modules/target_pos.xml" gui_color="red" /> + + + diff --git a/conf/userconf/tudelft/control_panel.xml b/conf/userconf/tudelft/control_panel.xml index 8703b84f77..8e7a2a12dc 100644 --- a/conf/userconf/tudelft/control_panel.xml +++ b/conf/userconf/tudelft/control_panel.xml @@ -66,6 +66,66 @@
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -138,110 +198,6 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -264,15 +220,19 @@ - - - - + + + + + + + + - + - + @@ -299,7 +259,7 @@ - + @@ -310,57 +270,6 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -368,6 +277,59 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -401,10 +363,33 @@ - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -449,18 +434,46 @@ - + - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
diff --git a/sw/airborne/firmwares/rotorcraft/stabilization/stabilization_indi.c b/sw/airborne/firmwares/rotorcraft/stabilization/stabilization_indi.c index 4861954efa..c2642ec09a 100644 --- a/sw/airborne/firmwares/rotorcraft/stabilization/stabilization_indi.c +++ b/sw/airborne/firmwares/rotorcraft/stabilization/stabilization_indi.c @@ -282,6 +282,7 @@ Butterworth2LowPass estimation_input_lowpass_filters[INDI_NUM_ACT]; Butterworth2LowPass measurement_lowpass_filters[3]; Butterworth2LowPass estimation_output_lowpass_filters[3]; Butterworth2LowPass acceleration_lowpass_filter; +Butterworth2LowPass acceleration_body_x_filter; #if STABILIZATION_INDI_FILTER_RATES_SECOND_ORDER Butterworth2LowPass rates_filt_so[3]; #else @@ -462,6 +463,9 @@ void init_filters(void) init_butterworth_2_low_pass(&estimation_input_lowpass_filters[i], tau_est, sample_time, 0.0); } + // Filtering the bodyx acceleration with same cutoff as gyroscope + init_butterworth_2_low_pass(&acceleration_body_x_filter, tau, sample_time, 0.0); + // Filtering of the accel body z init_butterworth_2_low_pass(&acceleration_lowpass_filter, tau_est, sample_time, 0.0); @@ -520,11 +524,19 @@ void stabilization_indi_rate_run(bool in_flight, struct StabilizationSetpoint *s /* Propagate the filter on the gyroscopes */ struct FloatRates *body_rates = stateGetBodyRates_f(); float rate_vect[3] = {body_rates->p, body_rates->q, body_rates->r}; + + // Get the acceleration in body axes + struct Int32Vect3 *body_accel_i; + body_accel_i = stateGetAccelBody_i(); + ACCELS_FLOAT_OF_BFP(body_accel_f, *body_accel_i); + int8_t i; for (i = 0; i < 3; i++) { update_butterworth_2_low_pass(&measurement_lowpass_filters[i], rate_vect[i]); update_butterworth_2_low_pass(&estimation_output_lowpass_filters[i], rate_vect[i]); + update_butterworth_2_low_pass(&acceleration_body_x_filter, body_accel_f.x); + //Calculate the angular acceleration via finite difference angular_acceleration[i] = (measurement_lowpass_filters[i].o[0] - measurement_lowpass_filters[i].o[1]) * PERIODIC_FREQUENCY; @@ -620,6 +632,14 @@ void stabilization_indi_rate_run(bool in_flight, struct StabilizationSetpoint *s // This term compensates for the spinup torque in the yaw axis float g2_times_u = float_vect_dot_product(g2, indi_u, INDI_NUM_ACT)/INDI_G_SCALING; + if (in_flight) { + // Limit the estimated disturbance in yaw for drones that are stable in sideslip + BoundAbs(angular_acc_disturbance_estimate[2], stablization_indi_yaw_dist_limit); + } else { + // Not in flight, so don't estimate disturbance + float_vect_zero(angular_acc_disturbance_estimate, INDI_OUTPUTS); + } + // The control objective in array format indi_v[0] = (angular_accel_ref.p - angular_acc_disturbance_estimate[0]); indi_v[1] = (angular_accel_ref.q - angular_acc_disturbance_estimate[1]); @@ -672,7 +692,7 @@ void stabilization_indi_rate_run(bool in_flight, struct StabilizationSetpoint *s //update thrust command such that the current is correctly estimated cmd[COMMAND_THRUST] = 0; for (i = 0; i < INDI_NUM_ACT; i++) { - cmd[COMMAND_THRUST] += actuator_state[i] * -((int32_t) act_is_servo[i] - 1); + cmd[COMMAND_THRUST] += actuator_state[i] * (int32_t) act_is_thruster_z[i]; } cmd[COMMAND_THRUST] /= num_thrusters; diff --git a/sw/airborne/modules/ctrl/approach_moving_target.c b/sw/airborne/modules/ctrl/approach_moving_target.c index 55e8842757..61defc1210 100644 --- a/sw/airborne/modules/ctrl/approach_moving_target.c +++ b/sw/airborne/modules/ctrl/approach_moving_target.c @@ -201,7 +201,7 @@ void follow_diagonal_approach(void) // just filtering the heading will go wrong if it wraps, instead do: // take the diff with current heading_filtered, wrap that, add to current, insert in filter and wrap again? // example: target_heading - target_heading_filt (170 - -170 = 340), -> -20 -> -190 -> into filter -> wrap - float heading_diff = target_heading - target_heading_filt.o[0]; + float heading_diff = RadOfDeg(target_heading) - target_heading_filt.o[0]; FLOAT_ANGLE_NORMALIZE(heading_diff); float target_heading_input = target_heading_filt.o[0] + heading_diff; update_butterworth_2_low_pass(&target_heading_filt, target_heading_input); @@ -220,7 +220,7 @@ void follow_diagonal_approach(void) // Reference model float gamma_ref = RadOfDeg(amt.slope_ref); - float psi_ref = RadOfDeg(target_heading_filt_wrapped + amt.psi_ref); + float psi_ref = target_heading_filt_wrapped + RadOfDeg(amt.psi_ref); amt.rel_unit_vec.x = cosf(gamma_ref) * cosf(psi_ref); amt.rel_unit_vec.y = cosf(gamma_ref) * sinf(psi_ref); diff --git a/sw/airborne/modules/ctrl/eff_scheduling_rot_wing.c b/sw/airborne/modules/ctrl/eff_scheduling_rot_wing.c index 5e789190d5..942c998128 100644 --- a/sw/airborne/modules/ctrl/eff_scheduling_rot_wing.c +++ b/sw/airborne/modules/ctrl/eff_scheduling_rot_wing.c @@ -30,6 +30,8 @@ #include "firmwares/rotorcraft/stabilization/stabilization_indi.h" +#include "autopilot.h" + #include "modules/actuators/actuators.h" #include "modules/core/abi.h" @@ -144,7 +146,9 @@ struct rot_wing_eff_sched_param_t eff_sched_p = { .k_lift_tail = ROT_WING_EFF_SCHED_K_LIFT_TAIL }; -float eff_sched_pusher_time = 0.002; +float eff_sched_pusher_time = 0.002; + +float roll_eff_scaling = 1.f; struct rot_wing_eff_sched_var_t eff_sched_var; @@ -282,9 +286,17 @@ void eff_scheduling_rot_wing_update_hover_motor_effectiveness(void) float pitch_motor_q_eff = eff_sched_var.pitch_motor_dMdpprz / eff_sched_var.Iyy; + float cmd_right = actuator_state_filt_vect[1]; + float cmd_left = actuator_state_filt_vect[3]; + Bound(cmd_right, 3500, MAX_PPRZ); + Bound(cmd_left, 3500, MAX_PPRZ); + // Roll motor effectiveness - float dM_dpprz_right = (eff_sched_p.DMdpprz_hover_roll[0] + actuator_state_filt_vect[1] * eff_sched_p.DMdpprz_hover_roll[1]) / 10000.; - float dM_dpprz_left = (eff_sched_p.DMdpprz_hover_roll[0] + actuator_state_filt_vect[3] * eff_sched_p.DMdpprz_hover_roll[1]) / 10000.; + float dM_dpprz_right = (eff_sched_p.DMdpprz_hover_roll[0] + cmd_right * eff_sched_p.DMdpprz_hover_roll[1]) / 10000.; + float dM_dpprz_left = (eff_sched_p.DMdpprz_hover_roll[0] + cmd_left * eff_sched_p.DMdpprz_hover_roll[1]) / 10000.; + + dM_dpprz_right = dM_dpprz_right * roll_eff_scaling; + dM_dpprz_left = dM_dpprz_left * roll_eff_scaling; // Bound dM_dpprz to half and 2 times the hover effectiveness Bound(dM_dpprz_right, eff_sched_var.roll_motor_dMdpprz * 0.5, eff_sched_var.roll_motor_dMdpprz * 2.0); @@ -294,8 +306,10 @@ void eff_scheduling_rot_wing_update_hover_motor_effectiveness(void) Bound(roll_motor_p_eff_right, -1, -0.00001); float roll_motor_p_eff_left = (dM_dpprz_left * eff_sched_var.cosr + eff_sched_p.hover_roll_roll_coef[0] * eff_sched_var.wing_rotation_rad * eff_sched_var.wing_rotation_rad * eff_sched_var.airspeed * eff_sched_var.cosr) / eff_sched_var.Ixx; - float roll_motor_airspeed_compensation = eff_sched_p.hover_roll_roll_coef[1] * eff_sched_var.airspeed * eff_sched_var.cosr / eff_sched_var.Ixx; - roll_motor_p_eff_left += roll_motor_airspeed_compensation; + if(autopilot.in_flight) { + float roll_motor_airspeed_compensation = eff_sched_p.hover_roll_roll_coef[1] * eff_sched_var.airspeed * eff_sched_var.cosr / eff_sched_var.Ixx; + roll_motor_p_eff_left += roll_motor_airspeed_compensation; + } Bound(roll_motor_p_eff_left, 0.00001, 1); float roll_motor_q_eff = (eff_sched_p.hover_roll_pitch_coef[0] * eff_sched_var.wing_rotation_rad + eff_sched_p.hover_roll_pitch_coef[1] * eff_sched_var.wing_rotation_rad * eff_sched_var.wing_rotation_rad * eff_sched_var.sinr) / eff_sched_var.Iyy; @@ -324,6 +338,10 @@ void eff_scheduling_rot_wing_update_elevator_effectiveness(void) eff_sched_p.k_elevator[1] * eff_sched_var.cmd_pusher_scaled * eff_sched_var.cmd_pusher_scaled * eff_sched_var.airspeed + eff_sched_p.k_elevator[2] * eff_sched_var.airspeed2) / 10000.; + // scale the effectiveness of the elevator down if it has a large deflection to encourage it to become flat quickly (pragmatic, not physically inpsired) + float elevator_ineffectiveness_scaling = (50-de)/40; + Bound(elevator_ineffectiveness_scaling, 0.5, 1.0); + float dMydpprz = dMyde * eff_sched_p.k_elevator_deflection[1]; // Convert moment to effectiveness diff --git a/sw/airborne/modules/ctrl/eff_scheduling_rot_wing.h b/sw/airborne/modules/ctrl/eff_scheduling_rot_wing.h index b80997c175..464fa97de9 100644 --- a/sw/airborne/modules/ctrl/eff_scheduling_rot_wing.h +++ b/sw/airborne/modules/ctrl/eff_scheduling_rot_wing.h @@ -77,6 +77,8 @@ struct rot_wing_eff_sched_var_t { float airspeed2; }; +extern float roll_eff_scaling; + extern float rotation_angle_setpoint_deg; extern int16_t rotation_cmd; diff --git a/sw/airborne/modules/rot_wing_drone/rotwing_state.c b/sw/airborne/modules/rot_wing_drone/rotwing_state.c index f3c295e3b2..c22bd7ac8f 100644 --- a/sw/airborne/modules/rot_wing_drone/rotwing_state.c +++ b/sw/airborne/modules/rot_wing_drone/rotwing_state.c @@ -78,6 +78,9 @@ #endif // FW hov mot off state identification +#ifndef ROTWING_HOV_MOT_RUN_RPM_TH +#define ROTWING_HOV_MOT_RUN_RPM_TH 800 +#endif #ifndef ROTWING_HOV_MOT_OFF_RPM_TH #define ROTWING_HOV_MOT_OFF_RPM_TH 50 #endif @@ -137,6 +140,7 @@ float rotwing_state_max_hover_speed = 7; bool hover_motors_active = true; bool bool_disable_hover_motors = false; +float Wu_gih_original[GUIDANCE_INDI_HYBRID_U] = GUIDANCE_INDI_WLS_WU; inline void rotwing_check_set_current_state(void); inline void rotwing_switch_state(void); @@ -220,7 +224,7 @@ void periodic_rotwing_state(void) bool_disable_hover_motors = false; } - + } // Function to request a state @@ -604,7 +608,7 @@ void rotwing_state_free_processor(void) /* Calculations - */ + */ // speed over pos_error projection struct FloatVect2 pos_error_norm; VECT2_COPY(pos_error_norm, pos_error); @@ -612,9 +616,9 @@ void rotwing_state_free_processor(void) float dist_to_target = sqrtf(nav_rotorcraft_base.goto_wp.dist2_to_wp); float max_speed_decel2 = fabsf(2.f * dist_to_target * nav_max_deceleration_sp); // dist_to_wp can only be positive, but just in case float max_speed_decel = sqrtf(max_speed_decel2); - + // Check if speed setpoint above set airspeed - struct FloatVect2 desired_airspeed_v; + struct FloatVect2 desired_airspeed_v; struct FloatVect2 groundspeed_sp; groundspeed_sp.x = pos_error.x * nav_hybrid_pos_gain; groundspeed_sp.y = pos_error.y * nav_hybrid_pos_gain; @@ -708,6 +712,18 @@ static void rotwing_state_feedback_cb(uint8_t __attribute__((unused)) sender_id, } } +bool rotwing_state_hover_motors_running(void) { + // Check if hover motors are running + if (rotwing_state_hover_rpm[0] > ROTWING_HOV_MOT_RUN_RPM_TH + && rotwing_state_hover_rpm[1] > ROTWING_HOV_MOT_RUN_RPM_TH + && rotwing_state_hover_rpm[2] > ROTWING_HOV_MOT_RUN_RPM_TH + && rotwing_state_hover_rpm[3] > ROTWING_HOV_MOT_RUN_RPM_TH) { + return true; + } else { + return false; + } +} + void guidance_indi_hybrid_set_wls_settings(float body_v[3], float roll_angle, float pitch_angle) { // adjust weights @@ -756,9 +772,11 @@ void guidance_indi_hybrid_set_wls_settings(float body_v[3], float roll_angle, fl float pitch_angle_range = 3.; if (rotwing_state_skewing.wing_angle_deg < 55) { scheduled_pitch_angle = 0; + Wu_gih[1] = Wu_gih_original[1]; } else { float pitch_progression = (rotwing_state_skewing.wing_angle_deg - 55) / 35.; scheduled_pitch_angle = pitch_angle_range * pitch_progression; + Wu_gih[1] = Wu_gih_original[1] * (1.f - pitch_angle_range*0.9); } if (!hover_motors_active) { scheduled_pitch_angle = 8.; diff --git a/sw/airborne/modules/rot_wing_drone/rotwing_state.h b/sw/airborne/modules/rot_wing_drone/rotwing_state.h index c9faea1833..981f7977b1 100644 --- a/sw/airborne/modules/rot_wing_drone/rotwing_state.h +++ b/sw/airborne/modules/rot_wing_drone/rotwing_state.h @@ -92,5 +92,6 @@ extern void periodic_rotwing_state(void); extern void request_rotwing_state(uint8_t state); extern void rotwing_request_configuration(uint8_t configuration); extern void rotwing_state_skew_actuator_periodic(void); +extern bool rotwing_state_hover_motors_running(void); #endif // ROTWING_STATE_H diff --git a/sw/ground_segment/python/moving_base/moving_base.py b/sw/ground_segment/python/moving_base/moving_base.py index 25400a04c7..4507b43ce7 100755 --- a/sw/ground_segment/python/moving_base/moving_base.py +++ b/sw/ground_segment/python/moving_base/moving_base.py @@ -52,19 +52,22 @@ class UAV: self.timeout = 0 class Base: - def __init__(self, freq=10., use_ground_ref=False, ignore_geo_fence=False, verbose=False): + def __init__(self, freq=10., use_ground_ref=False, verbose=False, speed=0, heading=0, turn_rate=0, id=[]): self.step = 1. / freq self.use_ground_ref = use_ground_ref self.enabled = True # run sim by default self.verbose = verbose - self.ids = [5] + self.ids = [] self.uavs = [UAV(i) for i in self.ids] self.time = time.mktime(time.gmtime()) - self.speed = 1 # m/s + self.speed = speed # m/s self.course = -90 # deg - self.heading = -90 # deg - self.lat = 38.08000040764657 #deg - self.lon = -9.1 #deg + self.heading = heading # deg + self.turn_rate = turn_rate #deg/s + # self.lat = 38.08000040764657 #deg + # self.lon = -9.1 #deg + self.lat = 52.926 #deg + self.lon = 4.499 #deg self.altitude = 2.0 # starts from 1 m high # Start IVY interface @@ -72,6 +75,9 @@ class Base: # bind to GPS_INT message def ins_cb(ac_id, msg): + if ac_id not in self.ids: + self.ids.append(ac_id) + self.uavs.append(UAV(ac_id)) if ac_id in self.ids and msg.name == "GPS_INT": uav = self.uavs[self.ids.index(ac_id)] i2p = 1. / 2**8 # integer to position @@ -153,6 +159,23 @@ class Base: msg['heading'] = self.heading self._interface.send(msg) + msg2 = PprzMessage("ground", "FLIGHT_PARAM") + msg2['ac_id'] = "GCS" + msg2['roll'] = 0.0 + msg2['pitch'] = 0.0 + msg2['heading'] = self.heading + msg2['lat'] = self.lat + msg2['long'] = self.lon + msg2['speed'] = self.speed + msg2['course'] = self.course + msg2['alt'] = 0.0 + msg2['climb'] = 0.0 + msg2['agl'] = 0.0 + msg2['unix_time'] = 0.0 + msg2['itow'] = 0 + msg2['airspeed'] = self.speed + self._interface.send(msg2) + def run(self): try: # The main loop @@ -165,6 +188,9 @@ class Base: # Send base position if self.enabled: + #integrate derivatives + self.heading += self.step*self.turn_rate + self.course = self.heading dn = self.speed*m.cos(self.course/180.0*m.pi) de = self.speed*m.sin(self.course/180.0*m.pi) self.move_base(self.step*dn,self.step*de) @@ -177,7 +203,13 @@ class Base: if __name__ == '__main__': import argparse + parser = argparse.ArgumentParser(description="Moving base simulator") + parser.add_argument('-s', '--speed', dest='speed', default=1, type=float, help="Speed of the ship (m/s).") + parser.add_argument('-he', '--heading', dest='heading', default=0, type=float, help="Heading of the ship (deg).") + parser.add_argument('-t', '--turn_rate', dest='turn_rate', default=0, type=float, help="Turn rate of the ship (deg/s).") + parser.add_argument('-i', '--id', dest='id', default=0, type=float, help="Aircraft ID.") + args = parser.parse_args() - base = Base() + base = Base(speed=args.speed, heading=args.heading, turn_rate=args.turn_rate, id=args.id) base.run()