diff --git a/ArduCopter/landing_gear.cpp b/ArduCopter/landing_gear.cpp index 71594fab0e220..e5aae8b5825d9 100644 --- a/ArduCopter/landing_gear.cpp +++ b/ArduCopter/landing_gear.cpp @@ -12,12 +12,6 @@ void Copter::landinggear_update() // last status (deployed or retracted) used to check for changes, initialised to startup state of landing gear static bool last_deploy_status = landinggear.deployed(); - // if we are doing an automatic landing procedure, force the landing gear to deploy. - // To-Do: should we pause the auto-land procedure to give time for gear to come down? - if (flightmode->landing_gear_should_be_deployed()) { - landinggear.set_position(AP_LandingGear::LandingGear_Deploy); - } - // send event message to datalog if status has changed if (landinggear.deployed() != last_deploy_status) { if (landinggear.deployed()) { diff --git a/ArduCopter/mode.h b/ArduCopter/mode.h index 30412c9d61ea2..93c0395def278 100644 --- a/ArduCopter/mode.h +++ b/ArduCopter/mode.h @@ -66,7 +66,6 @@ class Mode { virtual bool is_taking_off() const; static void takeoff_stop() { takeoff.stop(); } - virtual bool landing_gear_should_be_deployed() const { return false; } virtual bool is_landing() const { return false; } // mode requires terrain to be present to be functional @@ -361,7 +360,6 @@ class ModeAuto : public Mode { void nav_guided_start(); bool is_landing() const override; - bool landing_gear_should_be_deployed() const override; bool is_taking_off() const override; @@ -870,7 +868,6 @@ class ModeLand : public Mode { bool is_autopilot() const override { return true; } bool is_landing() const override { return true; }; - bool landing_gear_should_be_deployed() const override { return true; }; void do_not_use_GPS(); @@ -1043,7 +1040,6 @@ class ModeRTL : public Mode { bool state_complete() { return _state_complete; } bool is_landing() const override; - bool landing_gear_should_be_deployed() const override; void restart_without_terrain(); diff --git a/ArduCopter/mode_auto.cpp b/ArduCopter/mode_auto.cpp index 38980ccf64253..1d015a733f679 100644 --- a/ArduCopter/mode_auto.cpp +++ b/ArduCopter/mode_auto.cpp @@ -234,6 +234,9 @@ void ModeAuto::land_start(const Vector3f& destination) // initialise yaw auto_yaw.set_mode(AUTO_YAW_HOLD); + + // optionally deploy landing gear + copter.landinggear.deploy_for_landing(); } // auto_circle_movetoedge_start - initialise waypoint controller to move to edge of a circle with it's center at the specified location @@ -358,19 +361,6 @@ bool ModeAuto::is_taking_off() const return ((_mode == Auto_TakeOff) && !wp_nav->reached_wp_destination()); } -bool ModeAuto::landing_gear_should_be_deployed() const -{ - switch(_mode) { - case Auto_Land: - return true; - case Auto_RTL: - return copter.mode_rtl.landing_gear_should_be_deployed(); - default: - return false; - } - return false; -} - // auto_payload_place_start - initialises controller to implement a placing void ModeAuto::payload_place_start() { @@ -1493,7 +1483,7 @@ bool ModeAuto::verify_takeoff() // retract the landing gear if (reached_wp_dest) { - copter.landinggear.set_position(AP_LandingGear::LandingGear_Retract); + copter.landinggear.retract_after_takeoff(); } return reached_wp_dest; diff --git a/ArduCopter/mode_guided.cpp b/ArduCopter/mode_guided.cpp index 05fc647e7bc8f..27aca8adf55e8 100644 --- a/ArduCopter/mode_guided.cpp +++ b/ArduCopter/mode_guided.cpp @@ -370,6 +370,10 @@ void ModeGuided::takeoff_run() { auto_takeoff_run(); if (wp_nav->reached_wp_destination()) { + // optionally retract landing gear + copter.landinggear.retract_after_takeoff(); + + // switch to position control mode but maintain current target const Vector3f& target = wp_nav->get_wp_destination(); set_destination(target); } diff --git a/ArduCopter/mode_land.cpp b/ArduCopter/mode_land.cpp index 491005f62c376..5c781b20eda69 100644 --- a/ArduCopter/mode_land.cpp +++ b/ArduCopter/mode_land.cpp @@ -37,6 +37,9 @@ bool ModeLand::init(bool ignore_checks) // initialise yaw auto_yaw.set_mode(AUTO_YAW_HOLD); + // optionally deploy landing gear + copter.landinggear.deploy_for_landing(); + return true; } diff --git a/ArduCopter/mode_rtl.cpp b/ArduCopter/mode_rtl.cpp index 21c34dae006dc..a8304477d7f23 100644 --- a/ArduCopter/mode_rtl.cpp +++ b/ArduCopter/mode_rtl.cpp @@ -274,6 +274,9 @@ void ModeRTL::descent_start() // initialise yaw auto_yaw.set_mode(AUTO_YAW_HOLD); + + // optionally deploy landing gear + copter.landinggear.deploy_for_landing(); } // rtl_descent_run - implements the final descent to the RTL_ALT @@ -357,6 +360,9 @@ void ModeRTL::land_start() // initialise yaw auto_yaw.set_mode(AUTO_YAW_HOLD); + + // optionally deploy landing gear + copter.landinggear.deploy_for_landing(); } bool ModeRTL::is_landing() const @@ -364,19 +370,6 @@ bool ModeRTL::is_landing() const return _state == RTL_Land; } -bool ModeRTL::landing_gear_should_be_deployed() const -{ - switch(_state) { - case RTL_LoiterAtHome: - case RTL_Land: - case RTL_FinalDescent: - return true; - default: - return false; - } - return false; -} - // rtl_returnhome_run - return home // called by rtl_run at 100hz or more void ModeRTL::land_run(bool disarm_on_land) diff --git a/libraries/AP_LandingGear/AP_LandingGear.cpp b/libraries/AP_LandingGear/AP_LandingGear.cpp index 5fa9b42a4b078..62c787989e66c 100644 --- a/libraries/AP_LandingGear/AP_LandingGear.cpp +++ b/libraries/AP_LandingGear/AP_LandingGear.cpp @@ -67,6 +67,14 @@ const AP_Param::GroupInfo AP_LandingGear::var_info[] = { // @User: Standard AP_GROUPINFO("RETRACT_ALT", 8, AP_LandingGear, _retract_alt, 0), + // @Param: OPTIONS + // @DisplayName: Landing gear auto retract/deploy options + // @Description: Options to retract or deploy landing gear in Auto or Guided mode + // @Values: 1:Retract after Takeoff, 2:Deploy during Land, 3:Retract after Takeoff AND deploy during Land + // @Bitmask: 0:Retract after Takeoff,1:Deploy during Land + // @User: Standard + AP_GROUPINFO("OPTIONS", 9, AP_LandingGear, _options, 3), + AP_GROUPEND }; @@ -272,3 +280,19 @@ bool AP_LandingGear::check_before_land(void) // If the landing gear was not used - return true, otherwise - check for deployed return (get_state() == LG_DEPLOYED); } + +// retract after takeoff if configured via the OPTIONS parameter +void AP_LandingGear::retract_after_takeoff() +{ + if (_options.get() & (uint16_t)Option::RETRACT_AFTER_TAKEOFF) { + retract(); + } +} + +// deploy for landing if configured via the OPTIONS parameter +void AP_LandingGear::deploy_for_landing() +{ + if (_options.get() & (uint16_t)Option::DEPLOY_DURING_LANDING) { + deploy(); + } +} diff --git a/libraries/AP_LandingGear/AP_LandingGear.h b/libraries/AP_LandingGear/AP_LandingGear.h index dea4a6da689ac..15c3274b1e089 100644 --- a/libraries/AP_LandingGear/AP_LandingGear.h +++ b/libraries/AP_LandingGear/AP_LandingGear.h @@ -85,6 +85,10 @@ class AP_LandingGear { bool check_before_land(void); + // retract after takeoff or deploy for landing depending on the OPTIONS parameter + void retract_after_takeoff(); + void deploy_for_landing(); + private: // Parameters AP_Int8 _startup_behaviour; // start-up behaviour (see LandingGearStartupBehaviour) @@ -95,6 +99,13 @@ class AP_LandingGear { AP_Int8 _pin_weight_on_wheels_polarity; AP_Int16 _deploy_alt; AP_Int16 _retract_alt; + AP_Int16 _options; + + // bitmask of options + enum class Option : uint16_t { + RETRACT_AFTER_TAKEOFF = (1U<<0), + DEPLOY_DURING_LANDING = (1U<<1) + }; // internal variables bool _deployed; // true if the landing gear has been deployed, initialized false