mirror of
https://gitee.com/mirrors_PX4/PX4-Autopilot.git
synced 2026-11-02 01:31:36 +08:00
rtl: implemented RTL based on cone shape
- user defines a cone half angle which defines the RTL altitude behavior - if vehicle is outside the cone it will climb until it intersects the cone and then return at this altitude. - if vehicle is inside the cone or above the predefined return altitude (RTL_RETURN_ALT) then it will return at the current altitude Signed-off-by: RomanBapst <bapstroman@gmail.com>
This commit is contained in:
committed by
Mathieu Bresciani
parent
f7a460427b
commit
81ee40eac8
@@ -67,6 +67,9 @@ RTL::rtl_type() const
|
|||||||
void
|
void
|
||||||
RTL::on_activation()
|
RTL::on_activation()
|
||||||
{
|
{
|
||||||
|
|
||||||
|
_rtl_alt = calculate_return_alt_from_cone_half_angle((float)_param_rtl_cone_half_angle_deg.get());
|
||||||
|
|
||||||
if (_navigator->get_land_detected()->landed) {
|
if (_navigator->get_land_detected()->landed) {
|
||||||
// For safety reasons don't go into RTL if landed.
|
// For safety reasons don't go into RTL if landed.
|
||||||
_rtl_state = RTL_STATE_LANDED;
|
_rtl_state = RTL_STATE_LANDED;
|
||||||
@@ -133,14 +136,6 @@ RTL::set_rtl_item()
|
|||||||
// Check if we are pretty close to home already.
|
// Check if we are pretty close to home already.
|
||||||
const float home_dist = get_distance_to_next_waypoint(home.lat, home.lon, gpos.lat, gpos.lon);
|
const float home_dist = get_distance_to_next_waypoint(home.lat, home.lon, gpos.lat, gpos.lon);
|
||||||
|
|
||||||
// Compute the return altitude.
|
|
||||||
float return_alt = math::max(home.alt + _param_rtl_return_alt.get(), gpos.alt);
|
|
||||||
|
|
||||||
// We are close to home, limit climb to min.
|
|
||||||
if (home_dist < _param_rtl_min_dist.get()) {
|
|
||||||
return_alt = home.alt + _param_rtl_descend_alt.get();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Compute the loiter altitude.
|
// Compute the loiter altitude.
|
||||||
const float loiter_altitude = math::min(home.alt + _param_rtl_descend_alt.get(), gpos.alt);
|
const float loiter_altitude = math::min(home.alt + _param_rtl_descend_alt.get(), gpos.alt);
|
||||||
|
|
||||||
@@ -150,7 +145,7 @@ RTL::set_rtl_item()
|
|||||||
_mission_item.nav_cmd = NAV_CMD_WAYPOINT;
|
_mission_item.nav_cmd = NAV_CMD_WAYPOINT;
|
||||||
_mission_item.lat = gpos.lat;
|
_mission_item.lat = gpos.lat;
|
||||||
_mission_item.lon = gpos.lon;
|
_mission_item.lon = gpos.lon;
|
||||||
_mission_item.altitude = return_alt;
|
_mission_item.altitude = _rtl_alt;
|
||||||
_mission_item.altitude_is_relative = false;
|
_mission_item.altitude_is_relative = false;
|
||||||
_mission_item.yaw = _navigator->get_local_position()->yaw;
|
_mission_item.yaw = _navigator->get_local_position()->yaw;
|
||||||
_mission_item.acceptance_radius = _navigator->get_acceptance_radius();
|
_mission_item.acceptance_radius = _navigator->get_acceptance_radius();
|
||||||
@@ -159,7 +154,7 @@ RTL::set_rtl_item()
|
|||||||
_mission_item.origin = ORIGIN_ONBOARD;
|
_mission_item.origin = ORIGIN_ONBOARD;
|
||||||
|
|
||||||
mavlink_and_console_log_info(_navigator->get_mavlink_log_pub(), "RTL: climb to %d m (%d m above home)",
|
mavlink_and_console_log_info(_navigator->get_mavlink_log_pub(), "RTL: climb to %d m (%d m above home)",
|
||||||
(int)ceilf(return_alt), (int)ceilf(return_alt - _navigator->get_home_position()->alt));
|
(int)ceilf(_rtl_alt), (int)ceilf(_rtl_alt - _navigator->get_home_position()->alt));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -169,7 +164,7 @@ RTL::set_rtl_item()
|
|||||||
_mission_item.nav_cmd = NAV_CMD_WAYPOINT;
|
_mission_item.nav_cmd = NAV_CMD_WAYPOINT;
|
||||||
_mission_item.lat = home.lat;
|
_mission_item.lat = home.lat;
|
||||||
_mission_item.lon = home.lon;
|
_mission_item.lon = home.lon;
|
||||||
_mission_item.altitude = return_alt;
|
_mission_item.altitude = _rtl_alt;
|
||||||
_mission_item.altitude_is_relative = false;
|
_mission_item.altitude_is_relative = false;
|
||||||
|
|
||||||
// Use home yaw if close to home.
|
// Use home yaw if close to home.
|
||||||
@@ -353,3 +348,45 @@ RTL::advance_rtl()
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
float RTL::calculate_return_alt_from_cone_half_angle(float cone_half_angle_deg)
|
||||||
|
{
|
||||||
|
const home_position_s &home = *_navigator->get_home_position();
|
||||||
|
const vehicle_global_position_s &gpos = *_navigator->get_global_position();
|
||||||
|
|
||||||
|
float rtl_altitude;
|
||||||
|
|
||||||
|
if (gpos.alt > home.alt + _param_rtl_return_alt.get() || cone_half_angle_deg >= 90.0f) {
|
||||||
|
rtl_altitude = gpos.alt;
|
||||||
|
|
||||||
|
} else if (cone_half_angle_deg <= 0) {
|
||||||
|
rtl_altitude = home.alt + _param_rtl_return_alt.get();
|
||||||
|
|
||||||
|
} else {
|
||||||
|
// horizontal distance to home position
|
||||||
|
const float home_dist = get_distance_to_next_waypoint(home.lat, home.lon, gpos.lat, gpos.lon);
|
||||||
|
|
||||||
|
// constrain cone half angle to meaningful values. All other cases are already handled above.
|
||||||
|
const float cone_half_angle_rad = math::radians(math::constrain(cone_half_angle_deg, 1.0f, 89.0f));
|
||||||
|
|
||||||
|
// minimum height above home position required
|
||||||
|
float height_above_home_min = home_dist / tanf(cone_half_angle_rad);
|
||||||
|
|
||||||
|
// minimum altitude we need in order to be within the user defined cone
|
||||||
|
const float altitude_min = math::constrain(height_above_home_min + home.alt, home.alt,
|
||||||
|
home.alt + _param_rtl_return_alt.get());
|
||||||
|
|
||||||
|
if (gpos.alt < altitude_min) {
|
||||||
|
rtl_altitude = altitude_min;
|
||||||
|
|
||||||
|
} else {
|
||||||
|
rtl_altitude = gpos.alt;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// always demand altitude which is higher or equal the RTL descend altitude
|
||||||
|
rtl_altitude = math::max(rtl_altitude, home.alt + _param_rtl_descend_alt.get());
|
||||||
|
|
||||||
|
return rtl_altitude;
|
||||||
|
}
|
||||||
|
|||||||
@@ -80,6 +80,9 @@ private:
|
|||||||
*/
|
*/
|
||||||
void advance_rtl();
|
void advance_rtl();
|
||||||
|
|
||||||
|
|
||||||
|
float calculate_return_alt_from_cone_half_angle(float cone_half_angle_deg);
|
||||||
|
|
||||||
enum RTLState {
|
enum RTLState {
|
||||||
RTL_STATE_NONE = 0,
|
RTL_STATE_NONE = 0,
|
||||||
RTL_STATE_CLIMB,
|
RTL_STATE_CLIMB,
|
||||||
@@ -91,6 +94,7 @@ private:
|
|||||||
RTL_STATE_LANDED,
|
RTL_STATE_LANDED,
|
||||||
} _rtl_state{RTL_STATE_NONE};
|
} _rtl_state{RTL_STATE_NONE};
|
||||||
|
|
||||||
|
float _rtl_alt; // AMSL altitude at which the vehicle should return to the home position
|
||||||
bool _rtl_alt_min{false};
|
bool _rtl_alt_min{false};
|
||||||
|
|
||||||
DEFINE_PARAMETERS(
|
DEFINE_PARAMETERS(
|
||||||
@@ -98,6 +102,7 @@ private:
|
|||||||
(ParamFloat<px4::params::RTL_DESCEND_ALT>) _param_rtl_descend_alt,
|
(ParamFloat<px4::params::RTL_DESCEND_ALT>) _param_rtl_descend_alt,
|
||||||
(ParamFloat<px4::params::RTL_LAND_DELAY>) _param_rtl_land_delay,
|
(ParamFloat<px4::params::RTL_LAND_DELAY>) _param_rtl_land_delay,
|
||||||
(ParamFloat<px4::params::RTL_MIN_DIST>) _param_rtl_min_dist,
|
(ParamFloat<px4::params::RTL_MIN_DIST>) _param_rtl_min_dist,
|
||||||
(ParamInt<px4::params::RTL_TYPE>) _param_rtl_type
|
(ParamInt<px4::params::RTL_TYPE>) _param_rtl_type,
|
||||||
|
(ParamInt<px4::params::RTL_CONE_ANG>) _param_rtl_cone_half_angle_deg
|
||||||
)
|
)
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -116,3 +116,16 @@ PARAM_DEFINE_FLOAT(RTL_MIN_DIST, 5.0f);
|
|||||||
* @group Return Mode
|
* @group Return Mode
|
||||||
*/
|
*/
|
||||||
PARAM_DEFINE_INT32(RTL_TYPE, 0);
|
PARAM_DEFINE_INT32(RTL_TYPE, 0);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Half-angle of the RTL cone.
|
||||||
|
*
|
||||||
|
* Defines the half-angle of the cone which defines the vehicle RTL behavior.
|
||||||
|
*
|
||||||
|
* @unit degrees
|
||||||
|
* @min 0
|
||||||
|
* @max 90
|
||||||
|
* @increment 1
|
||||||
|
* @group Return Mode
|
||||||
|
*/
|
||||||
|
PARAM_DEFINE_INT32(RTL_CONE_ANG, 30);
|
||||||
|
|||||||
Reference in New Issue
Block a user