mirror of
https://github.com/ArduPilot/ardupilot
synced 2025-02-07 00:13:59 -04:00
Copter: mavlink initiated takeoff in alt-hold modes
adds PILOT_TKOFF_ALT for target altitude above home in cm for pilot initiated takeoff
This commit is contained in:
parent
b10cf0f38a
commit
73d961cebc
@ -374,6 +374,13 @@ static struct {
|
||||
uint32_t last_edge_time_ms; // system time that switch position was last changed
|
||||
} control_switch_state;
|
||||
|
||||
static struct {
|
||||
bool running;
|
||||
float speed;
|
||||
uint32_t start_ms;
|
||||
uint32_t time_ms;
|
||||
} takeoff_state;
|
||||
|
||||
static RCMapper rcmap;
|
||||
|
||||
// board specific config
|
||||
|
@ -1044,22 +1044,22 @@ void GCS_MAVLINK::handleMessage(mavlink_message_t* msg)
|
||||
|
||||
switch(packet.command) {
|
||||
|
||||
case MAV_CMD_NAV_TAKEOFF:
|
||||
case MAV_CMD_NAV_TAKEOFF: {
|
||||
// param4 : yaw angle (not supported)
|
||||
// param5 : latitude (not supported)
|
||||
// param6 : longitude (not supported)
|
||||
// param7 : altitude [metres]
|
||||
if (motors.armed() && control_mode == GUIDED) {
|
||||
set_auto_armed(true);
|
||||
float takeoff_alt = packet.param7 * 100; // Convert m to cm
|
||||
takeoff_alt = max(takeoff_alt,current_loc.alt);
|
||||
takeoff_alt = max(takeoff_alt,100.0f);
|
||||
guided_takeoff_start(takeoff_alt);
|
||||
|
||||
float takeoff_alt = packet.param7 * 100; // Convert m to cm
|
||||
|
||||
if(do_user_takeoff(takeoff_alt, !packet.param3)) {
|
||||
result = MAV_RESULT_ACCEPTED;
|
||||
} else {
|
||||
result = MAV_RESULT_FAILED;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
case MAV_CMD_NAV_LOITER_UNLIM:
|
||||
if (set_mode(LOITER)) {
|
||||
|
@ -130,6 +130,7 @@ public:
|
||||
k_param_cli_enabled,
|
||||
k_param_throttle_filt,
|
||||
k_param_throttle_behavior,
|
||||
k_param_pilot_takeoff_alt, // 64
|
||||
|
||||
// 65: AP_Limits Library
|
||||
k_param_limits = 65, // deprecated - remove
|
||||
@ -345,6 +346,7 @@ public:
|
||||
AP_Float throttle_filt;
|
||||
AP_Int16 throttle_behavior;
|
||||
AP_Int16 takeoff_trigger_dz;
|
||||
AP_Float pilot_takeoff_alt;
|
||||
|
||||
AP_Int16 rtl_altitude;
|
||||
AP_Float sonar_gain;
|
||||
|
@ -71,6 +71,15 @@ const AP_Param::Info var_info[] PROGMEM = {
|
||||
// @Increment: .5
|
||||
GSCALAR(throttle_filt, "PILOT_THR_FILT", 0),
|
||||
|
||||
// @Param: PILOT_TKOFF_ALT
|
||||
// @DisplayName: Pilot takeoff altitude
|
||||
// @Description: Altitude that altitude control modes will climb to when a takeoff is triggered with the throttle stick.
|
||||
// @User: Standard
|
||||
// @Units: Centimeters
|
||||
// @Range: 0.0 1000.0
|
||||
// @Increment: 10
|
||||
GSCALAR(pilot_takeoff_alt, "PILOT_TKOFF_ALT", 0.0f),
|
||||
|
||||
// @Param: PILOT_TKOFF_DZ
|
||||
// @DisplayName: Takeoff trigger deadzone
|
||||
// @Description: Offset from mid stick at which takeoff is triggered
|
||||
|
@ -23,7 +23,7 @@ static void althold_run()
|
||||
{
|
||||
float target_roll, target_pitch;
|
||||
float target_yaw_rate;
|
||||
int16_t target_climb_rate;
|
||||
float target_climb_rate;
|
||||
|
||||
// if not auto armed set throttle to zero and exit immediately
|
||||
if(!ap.auto_armed) {
|
||||
@ -44,9 +44,14 @@ static void althold_run()
|
||||
|
||||
// get pilot desired climb rate
|
||||
target_climb_rate = get_pilot_desired_climb_rate(g.rc_3.control_in);
|
||||
target_climb_rate = constrain_float(target_climb_rate, -g.pilot_velocity_z_max-tkoff_get_speed(), g.pilot_velocity_z_max-tkoff_get_speed());
|
||||
|
||||
// check for take-off
|
||||
if (ap.land_complete && (takeoff_state.running || g.rc_3.control_in > get_takeoff_trigger_throttle())) {
|
||||
if (!takeoff_state.running) {
|
||||
tkoff_timer_start(constrain_float(g.pilot_takeoff_alt,0.0f,1000.0f));
|
||||
}
|
||||
|
||||
// check for pilot requested take-off
|
||||
if (ap.land_complete && target_climb_rate > 0) {
|
||||
// indicate we are taking off
|
||||
set_land_complete(false);
|
||||
// clear i term when we're taking off
|
||||
@ -70,6 +75,7 @@ static void althold_run()
|
||||
|
||||
// call position controller
|
||||
pos_control.set_alt_target_from_climb_rate(target_climb_rate, G_Dt);
|
||||
tkoff_increment_alt_target(G_Dt);
|
||||
pos_control.update_z_controller();
|
||||
}
|
||||
}
|
||||
|
@ -53,9 +53,14 @@ static void loiter_run()
|
||||
|
||||
// get pilot desired climb rate
|
||||
target_climb_rate = get_pilot_desired_climb_rate(g.rc_3.control_in);
|
||||
target_climb_rate = constrain_float(target_climb_rate, -g.pilot_velocity_z_max-tkoff_get_speed(), g.pilot_velocity_z_max-tkoff_get_speed());
|
||||
|
||||
// check for take-off
|
||||
if (ap.land_complete && (takeoff_state.running || g.rc_3.control_in > get_takeoff_trigger_throttle())) {
|
||||
if (!takeoff_state.running) {
|
||||
tkoff_timer_start(constrain_float(g.pilot_takeoff_alt,0.0f,1000.0f));
|
||||
}
|
||||
|
||||
// check for pilot requested take-off
|
||||
if (ap.land_complete && target_climb_rate > 0) {
|
||||
// indicate we are taking off
|
||||
set_land_complete(false);
|
||||
// clear i term when we're taking off
|
||||
@ -94,6 +99,7 @@ static void loiter_run()
|
||||
|
||||
// update altitude target and call position controller
|
||||
pos_control.set_alt_target_from_climb_rate(target_climb_rate, G_Dt);
|
||||
tkoff_increment_alt_target(G_Dt);
|
||||
pos_control.update_z_controller();
|
||||
}
|
||||
}
|
||||
|
@ -171,9 +171,14 @@ static void poshold_run()
|
||||
|
||||
// get pilot desired climb rate (for alt-hold mode and take-off)
|
||||
target_climb_rate = get_pilot_desired_climb_rate(g.rc_3.control_in);
|
||||
target_climb_rate = constrain_float(target_climb_rate, -g.pilot_velocity_z_max-tkoff_get_speed(), g.pilot_velocity_z_max-tkoff_get_speed());
|
||||
|
||||
// check for take-off
|
||||
if (ap.land_complete && (takeoff_state.running || g.rc_3.control_in > get_takeoff_trigger_throttle())) {
|
||||
if (!takeoff_state.running) {
|
||||
tkoff_timer_start(constrain_float(g.pilot_takeoff_alt,0.0f,1000.0f));
|
||||
}
|
||||
|
||||
// check for pilot requested take-off
|
||||
if (ap.land_complete && target_climb_rate > 0) {
|
||||
// indicate we are taking off
|
||||
set_land_complete(false);
|
||||
// clear i term when we're taking off
|
||||
@ -521,6 +526,7 @@ static void poshold_run()
|
||||
}
|
||||
// update altitude target and call position controller
|
||||
pos_control.set_alt_target_from_climb_rate(target_climb_rate, G_Dt);
|
||||
tkoff_increment_alt_target(G_Dt);
|
||||
pos_control.update_z_controller();
|
||||
}
|
||||
}
|
||||
|
@ -64,9 +64,14 @@ static void sport_run()
|
||||
|
||||
// get pilot desired climb rate
|
||||
target_climb_rate = get_pilot_desired_climb_rate(g.rc_3.control_in);
|
||||
target_climb_rate = constrain_float(target_climb_rate, -g.pilot_velocity_z_max-tkoff_get_speed(), g.pilot_velocity_z_max-tkoff_get_speed());
|
||||
|
||||
// check for take-off
|
||||
if (ap.land_complete && (takeoff_state.running || g.rc_3.control_in > get_takeoff_trigger_throttle())) {
|
||||
if (!takeoff_state.running) {
|
||||
tkoff_timer_start(constrain_float(g.pilot_takeoff_alt,0.0f,1000.0f));
|
||||
}
|
||||
|
||||
// check for pilot requested take-off
|
||||
if (ap.land_complete && target_climb_rate > 0) {
|
||||
// indicate we are taking off
|
||||
set_land_complete(false);
|
||||
// clear i term when we're taking off
|
||||
@ -91,6 +96,7 @@ static void sport_run()
|
||||
|
||||
// call position controller
|
||||
pos_control.set_alt_target_from_climb_rate(target_climb_rate, G_Dt);
|
||||
tkoff_increment_alt_target(G_Dt);
|
||||
pos_control.update_z_controller();
|
||||
}
|
||||
}
|
||||
|
@ -402,4 +402,7 @@ enum FlipState {
|
||||
#define MAVLINK_SET_POS_TYPE_MASK_YAW_IGNORE (1<<10)
|
||||
#define MAVLINK_SET_POS_TYPE_MASK_YAW_RATE_IGNORE (1<<11)
|
||||
|
||||
// for PILOT_THR_BHV parameter
|
||||
#define THR_BEHAVE_FEEDBACK_FROM_MID_STICK (1<<0)
|
||||
|
||||
#endif // _DEFINES_H
|
||||
|
@ -129,6 +129,8 @@ static bool set_mode(uint8_t mode)
|
||||
// called at 100hz or more
|
||||
static void update_flight_mode()
|
||||
{
|
||||
tkoff_timer_update();
|
||||
|
||||
#if AP_AHRS_NAVEKF_AVAILABLE
|
||||
// Update EKF speed limit - used to limit speed when we are using optical flow
|
||||
ahrs.getEkfControlLimits(ekfGndSpdLimit, ekfNavVelGainScaler);
|
||||
|
@ -646,7 +646,7 @@ static bool arm_checks(bool display_failure, bool arming_from_gcs)
|
||||
// check throttle is not too high - skips checks if arming from GCS in Guided
|
||||
if (!(arming_from_gcs && control_mode == GUIDED)) {
|
||||
// above top of deadband is too always high
|
||||
if (g.rc_3.control_in > (g.rc_3.get_control_mid() + g.throttle_deadzone)) {
|
||||
if (g.rc_3.control_in > get_takeoff_trigger_throttle()) {
|
||||
if (display_failure) {
|
||||
gcs_send_text_P(SEVERITY_HIGH,PSTR("Arm: Throttle too high"));
|
||||
}
|
||||
|
74
ArduCopter/takeoff.pde
Normal file
74
ArduCopter/takeoff.pde
Normal file
@ -0,0 +1,74 @@
|
||||
// -*- tab-width: 4; Mode: C++; c-basic-offset: 4; indent-tabs-mode: nil -*-
|
||||
|
||||
|
||||
bool current_mode_has_user_takeoff(bool with_navigation)
|
||||
{
|
||||
switch (control_mode) {
|
||||
case GUIDED:
|
||||
case LOITER:
|
||||
case POSHOLD:
|
||||
return true;
|
||||
case ALT_HOLD:
|
||||
case SPORT:
|
||||
return !with_navigation;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
static bool do_user_takeoff(float takeoff_alt_cm, bool must_navigate)
|
||||
{
|
||||
if (motors.armed() && ap.land_complete && current_mode_has_user_takeoff(must_navigate) && takeoff_alt_cm > current_loc.alt) {
|
||||
switch(control_mode) {
|
||||
case GUIDED:
|
||||
set_auto_armed(true);
|
||||
guided_takeoff_start(takeoff_alt_cm);
|
||||
return true;
|
||||
case LOITER:
|
||||
case POSHOLD:
|
||||
case ALT_HOLD:
|
||||
case SPORT:
|
||||
set_auto_armed(true);
|
||||
tkoff_timer_start(pv_alt_above_origin(takeoff_alt_cm)-pos_control.get_pos_target().z);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static void tkoff_timer_start(float alt)
|
||||
{
|
||||
float speed = min(wp_nav.get_speed_up(), max(g.pilot_velocity_z_max*2.0f/3.0f, g.pilot_velocity_z_max-50.0f));
|
||||
|
||||
if (takeoff_state.running || speed <= 0.0f || alt <= 0.0f) {
|
||||
return;
|
||||
}
|
||||
|
||||
takeoff_state.running = true;
|
||||
takeoff_state.speed = speed;
|
||||
takeoff_state.start_ms = millis();
|
||||
takeoff_state.time_ms = (alt/takeoff_state.speed) * 1.0e3f;
|
||||
}
|
||||
|
||||
static void tkoff_timer_update()
|
||||
{
|
||||
if (millis()-takeoff_state.start_ms >= takeoff_state.time_ms) {
|
||||
takeoff_state.running = false;
|
||||
}
|
||||
}
|
||||
|
||||
static void tkoff_increment_alt_target(float dt)
|
||||
{
|
||||
if (takeoff_state.running) {
|
||||
Vector3f pos_target = pos_control.get_pos_target();
|
||||
pos_target.z += takeoff_state.speed*dt;
|
||||
pos_control.set_pos_target(pos_target);
|
||||
}
|
||||
}
|
||||
|
||||
static float tkoff_get_speed()
|
||||
{
|
||||
return takeoff_state.running?takeoff_state.speed:0.0f;
|
||||
}
|
Loading…
Reference in New Issue
Block a user