Skip to content

Commit 773c91c

Browse files
Georacertridge
authored andcommitted
ArduPlane: Added minimum throttle during TAKEOFF mode
This is a rework so that servos.cpp is responsible for setting the throttle limits under more circumstances and always notifies TECS when it does so. Additionally, the TAKEOFF mode has been improved with a new parameters TKOFF_MODE and TKOFF_THR_MIN that extend the throttle behaviour.
1 parent b163e13 commit 773c91c

File tree

9 files changed

+87
-17
lines changed

9 files changed

+87
-17
lines changed

ArduPlane/Attitude.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -448,6 +448,10 @@ void Plane::stabilize()
448448
}
449449

450450

451+
/*
452+
* Set the throttle output.
453+
* This is called by TECS-enabled flight modes, e.g. AUTO, GUIDED, etc.
454+
*/
451455
void Plane::calc_throttle()
452456
{
453457
if (aparm.throttle_cruise <= 1) {
@@ -458,6 +462,7 @@ void Plane::calc_throttle()
458462
return;
459463
}
460464

465+
// Read the TECS throttle output and set it to the throttle channel.
461466
float commanded_throttle = TECS_controller.get_throttle_demand();
462467
SRV_Channels::set_output_scaled(SRV_Channel::k_throttle, commanded_throttle);
463468
}

ArduPlane/Parameters.cpp

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -142,12 +142,28 @@ const AP_Param::Info Plane::var_info[] = {
142142

143143
// @Param: TKOFF_THR_MAX_T
144144
// @DisplayName: Takeoff throttle maximum time
145-
// @Description: This sets the time that maximum throttle will be forced during a fixed wing takeoff without an airspeed sensor. If an airspeed sensor is being used then the throttle is set to maximum until the takeoff airspeed is reached.
145+
// @Description: This sets the time that maximum throttle will be forced during a fixed wing takeoff.
146146
// @Units: s
147147
// @Range: 0 10
148148
// @Increment: 0.5
149149
// @User: Standard
150150
ASCALAR(takeoff_throttle_max_t, "TKOFF_THR_MAX_T", 4),
151+
152+
// @Param: TKOFF_THR_MIN
153+
// @DisplayName: Takeoff minimum throttle
154+
// @Description: The minimum throttle to use in takeoffs in AUTO and TAKEOFF flight modes, when TKOFF_MODE=1. Also, the minimum throttle to use in a quadpane forward transition. This can be useful to ensure faster takeoffs or transitions on aircraft where the normal throttle control leads to a slow takeoff or transition. It is used when it is larger than THR_MIN, otherwise THR_MIN is used instead.
155+
// @Units: %
156+
// @Range: 0 100
157+
// @Increment: 1
158+
// @User: Standard
159+
ASCALAR(takeoff_throttle_min, "TKOFF_THR_MIN", 60),
160+
161+
// @Param: TKOFF_MODE
162+
// @DisplayName: Takeoff mode
163+
// @Description: This selects the mode of the takeoff in AUTO and TAKEOFF flight modes. 0: During the takeoff, the maximum allowed throttle is always used (THR_MAX or TKOFF_THR_MAX). 1: During the takeoff TECS is allowed to operate between a minimum (THR_MIN or TKOFF_THR_MIN) and a maximum (THR_MAX or TKOFF_THR_MAX) limit. Applicable only when using an airspeed sensor.
164+
// @Values: 0:Traditional,1:Throttle range
165+
// @User: Advanced
166+
ASCALAR(takeoff_mode, "TKOFF_MODE", 0),
151167

152168
// @Param: TKOFF_TDRAG_ELEV
153169
// @DisplayName: Takeoff tail dragger elevator

ArduPlane/Parameters.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -357,6 +357,8 @@ class Parameters {
357357
k_param_acro_yaw_rate,
358358
k_param_takeoff_throttle_max_t,
359359
k_param_autotune_options,
360+
k_param_takeoff_throttle_min,
361+
k_param_takeoff_mode,
360362
};
361363

362364
AP_Int16 format_version;

ArduPlane/Plane.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1117,6 +1117,7 @@ class Plane : public AP_Vehicle {
11171117
bool auto_takeoff_check(void);
11181118
void takeoff_calc_roll(void);
11191119
void takeoff_calc_pitch(void);
1120+
void takeoff_calc_throttle(const bool use_max_throttle=false);
11201121
int8_t takeoff_tail_hold(void);
11211122
int16_t get_takeoff_pitch_min_cd(void);
11221123
void landing_gear_update(void);

ArduPlane/altitude.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -520,9 +520,9 @@ int32_t Plane::adjusted_altitude_cm(void)
520520
}
521521

522522
/*
523-
return home-relative altitude adjusted for ALT_OFFSET This is useful
523+
return home-relative altitude adjusted for ALT_OFFSET. This is useful
524524
during long flights to account for barometer changes from the GCS,
525-
or to adjust the flying height of a long mission
525+
or to adjust the flying height of a long mission.
526526
*/
527527
int32_t Plane::adjusted_relative_altitude_cm(void)
528528
{

ArduPlane/commands_logic.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -376,7 +376,7 @@ void Plane::do_takeoff(const AP_Mission::Mission_Command& cmd)
376376
next_WP_loc.lat = home.lat + 10;
377377
next_WP_loc.lng = home.lng + 10;
378378
auto_state.takeoff_speed_time_ms = 0;
379-
auto_state.takeoff_complete = false; // set flag to use gps ground course during TO. IMU will be doing yaw drift correction
379+
auto_state.takeoff_complete = false; // set flag to use gps ground course during TO. IMU will be doing yaw drift correction.
380380
auto_state.height_below_takeoff_to_level_off_cm = 0;
381381
// Flag also used to override "on the ground" throttle disable
382382

ArduPlane/mode_takeoff.cpp

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -22,11 +22,11 @@ const AP_Param::GroupInfo ModeTakeoff::var_info[] = {
2222
// @Increment: 1
2323
// @Units: m
2424
// @User: Standard
25-
AP_GROUPINFO("LVL_ALT", 2, ModeTakeoff, level_alt, 5),
25+
AP_GROUPINFO("LVL_ALT", 2, ModeTakeoff, level_alt, 10),
2626

2727
// @Param: LVL_PITCH
2828
// @DisplayName: Takeoff mode altitude initial pitch
29-
// @Description: This is the target pitch for the initial climb to TKOFF_LVL_ALT
29+
// @Description: This is the target pitch during the takeoff.
3030
// @Range: 0 30
3131
// @Increment: 1
3232
// @Units: deg
@@ -149,11 +149,11 @@ void ModeTakeoff::update()
149149

150150
if (plane.flight_stage == AP_FixedWing::FlightStage::TAKEOFF) {
151151
//below TAKOFF_LVL_ALT
152-
SRV_Channels::set_output_scaled(SRV_Channel::k_throttle, 100.0);
153152
plane.takeoff_calc_roll();
154153
plane.takeoff_calc_pitch();
154+
plane.takeoff_calc_throttle(true);
155155
} else {
156-
if ((altitude_cm >= alt * 100 - 200)) { //within 2m of TKOFF_ALT ,or above and loitering
156+
if ((altitude_cm >= alt * 100 - 200)) { //within 2m of TKOFF_ALT, or above and loitering
157157
#if AP_FENCE_ENABLED
158158
if (!plane.have_autoenabled_fences) {
159159
plane.fence.auto_enable_fence_after_takeoff();
@@ -164,7 +164,7 @@ void ModeTakeoff::update()
164164
plane.calc_nav_pitch();
165165
plane.calc_throttle();
166166
} else { // still climbing to TAKEOFF_ALT; may be loitering
167-
plane.calc_throttle();
167+
plane.takeoff_calc_throttle();
168168
plane.takeoff_calc_roll();
169169
plane.takeoff_calc_pitch();
170170
}

ArduPlane/servos.cpp

Lines changed: 32 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -499,47 +499,72 @@ void Plane::throttle_watt_limiter(int8_t &min_throttle, int8_t &max_throttle)
499499
#endif // #if AP_BATTERY_WATT_MAX_ENABLED
500500

501501
/*
502-
Apply min/max limits to throttle
502+
Apply min/max safety limits to throttle.
503503
*/
504504
float Plane::apply_throttle_limits(float throttle_in)
505505
{
506-
// convert 0 to 100% (or -100 to +100) into PWM
506+
// Pull the base throttle limits.
507+
// These are usually set to map the ESC operating range.
507508
int8_t min_throttle = aparm.throttle_min.get();
508509
int8_t max_throttle = aparm.throttle_max.get();
509510

510511
#if AP_ICENGINE_ENABLED
511-
// apply idle governor
512+
// Apply idle governor.
512513
g2.ice_control.update_idle_governor(min_throttle);
513514
#endif
514515

516+
// If reverse thrust is enabled not allowed right now, the minimum throttle must not fall below 0.
515517
if (min_throttle < 0 && !allow_reverse_thrust()) {
516518
// reverse thrust is available but inhibited.
517519
min_throttle = 0;
518520
}
519521

520-
const bool use_takeoff_throttle_max =
522+
// Query the conditions where TKOFF_THR_MAX applies.
523+
const bool use_takeoff_throttle =
521524
#if HAL_QUADPLANE_ENABLED
522525
quadplane.in_transition() ||
523526
#endif
524527
(flight_stage == AP_FixedWing::FlightStage::TAKEOFF) ||
525528
(flight_stage == AP_FixedWing::FlightStage::ABORT_LANDING);
526529

527-
if (use_takeoff_throttle_max) {
530+
if (use_takeoff_throttle) {
528531
if (aparm.takeoff_throttle_max != 0) {
532+
// Replace max throttle with the takeoff max throttle setting.
533+
// This is typically done to protect against long intervals of large power draw.
534+
// Or (in contrast) to give some extra throttle during the initial climb.
529535
max_throttle = aparm.takeoff_throttle_max.get();
530536
}
537+
// Do not allow min throttle to go below a lower threshold.
538+
// This is typically done to protect against premature stalls close to the ground.
539+
if (aparm.takeoff_mode.get() == 0 || !ahrs.using_airspeed_sensor()) {
540+
// Use a constant max throttle throughout the takeoff or when airspeed readings are not available.
541+
min_throttle = MAX(min_throttle, aparm.takeoff_throttle_max.get());
542+
} else if (aparm.takeoff_mode.get() == 1) { // Use a throttle range through the takeoff.
543+
if (aparm.takeoff_throttle_min.get() != 0) { // This is enabled by TKOFF_MODE==1.
544+
min_throttle = MAX(min_throttle, aparm.takeoff_throttle_min.get());
545+
}
546+
}
531547
} else if (landing.is_flaring()) {
548+
// Allow throttle cutoff when flaring.
549+
// This is to allow the aircraft to bleed speed faster and land with a shut off thruster.
532550
min_throttle = 0;
533551
}
534552

535-
// compensate for battery voltage drop
553+
// Compensate the limits for battery voltage drop.
554+
// This relaxes the limits when the battery is getting depleted.
536555
g2.fwd_batt_cmp.apply_min_max(min_throttle, max_throttle);
537556

538557
#if AP_BATTERY_WATT_MAX_ENABLED
539-
// apply watt limiter
558+
// Ensure that the power draw limits are not exceeded.
540559
throttle_watt_limiter(min_throttle, max_throttle);
541560
#endif
542561

562+
// Do a sanity check on them. Constrain down if necessary.
563+
min_throttle = MIN(min_throttle, max_throttle);
564+
565+
// Let TECS know about the updated throttle limits.
566+
TECS_controller.set_throttle_min(0.01f*min_throttle);
567+
TECS_controller.set_throttle_max(0.01f*max_throttle);
543568
return constrain_float(throttle_in, min_throttle, max_throttle);
544569
}
545570

ArduPlane/takeoff.cpp

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -219,7 +219,28 @@ void Plane::takeoff_calc_pitch(void)
219219
}
220220

221221
/*
222-
* get the pitch min used during takeoff. This matches the mission pitch until near the end where it allows it to levels off
222+
* Set the throttle limits to run at during a takeoff.
223+
*/
224+
void Plane::takeoff_calc_throttle(const bool use_max_throttle) {
225+
// This setting will take effect at the next run of TECS::update_pitch_throttle().
226+
227+
// Set the maximum throttle limit.
228+
if (aparm.takeoff_throttle_max != 0) {
229+
TECS_controller.set_throttle_max(0.01f*aparm.takeoff_throttle_max);
230+
}
231+
232+
// Set the minimum throttle limit.
233+
if (aparm.takeoff_mode==0 || !ahrs.using_airspeed_sensor() || use_max_throttle) { // Traditional takeoff throttle limit.
234+
TECS_controller.set_throttle_min(0.01f*aparm.takeoff_throttle_max);
235+
} else { // TKOFF_MODE == 1, allow for a throttle range.
236+
if (aparm.takeoff_throttle_min != 0) { // Override THR_MIN.
237+
TECS_controller.set_throttle_min(0.01f*aparm.takeoff_throttle_min);
238+
}
239+
}
240+
calc_throttle();
241+
}
242+
243+
/* get the pitch min used during takeoff. This matches the mission pitch until near the end where it allows it to levels off
223244
*/
224245
int16_t Plane::get_takeoff_pitch_min_cd(void)
225246
{

0 commit comments

Comments
 (0)