Skip to content

Commit

Permalink
Plane: fixed terrain RTL with rally points
Browse files Browse the repository at this point in the history
this fixes a bug where if the terrain database cache does not have the
tile for the location of a rally point then RTL to the rally point
with TERRAIN_FOLLOW=1 will not track terrain

The underlying issue is that Location::loc.change_alt_frame() will
return false if the location is not in the terrain memory cache. We
can't just extrapolate as the rally point could be in a totally
different terrain area to the current location. So instead we set it
as terrain_following_pending and fix it as soon as the terrain cache
is filled.

fixes ArduPilot#25157
  • Loading branch information
tridge committed Oct 3, 2023
1 parent 802813f commit 6a9d77f
Show file tree
Hide file tree
Showing 4 changed files with 25 additions and 4 deletions.
5 changes: 4 additions & 1 deletion ArduPlane/Plane.h
Original file line number Diff line number Diff line change
Expand Up @@ -735,6 +735,9 @@ class Plane : public AP_Vehicle {
// are we trying to follow terrain?
bool terrain_following;

// are we waiting to load terrain data to init terrain following
bool terrain_following_pending;

// target altitude above terrain in cm, valid if terrain_following
// is set
int32_t terrain_alt_cm;
Expand Down Expand Up @@ -855,7 +858,7 @@ class Plane : public AP_Vehicle {
void reset_offset_altitude(void);
void set_offset_altitude_location(const Location &start_loc, const Location &destination_loc);
bool above_location_current(const Location &loc);
void setup_terrain_target_alt(Location &loc) const;
void setup_terrain_target_alt(Location &loc);
int32_t adjusted_altitude_cm(void);
int32_t adjusted_relative_altitude_cm(void);
float mission_alt_offset(void);
Expand Down
14 changes: 12 additions & 2 deletions ArduPlane/altitude.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -212,6 +212,12 @@ void Plane::set_target_altitude_location(const Location &loc)
target_altitude.amsl_cm += home.alt;
}
#if AP_TERRAIN_AVAILABLE
if (target_altitude.terrain_following_pending) {
/* we didn't get terrain data to init when we started on this
target, retry
*/
setup_terrain_target_alt(next_WP_loc);
}
/*
if this location has the terrain_alt flag set and we know the
terrain altitude of our current location then treat it as a
Expand Down Expand Up @@ -469,12 +475,16 @@ bool Plane::above_location_current(const Location &loc)
modify a destination to be setup for terrain following if
TERRAIN_FOLLOW is enabled
*/
void Plane::setup_terrain_target_alt(Location &loc) const
void Plane::setup_terrain_target_alt(Location &loc)
{
#if AP_TERRAIN_AVAILABLE
if (terrain_enabled_in_current_mode()) {
loc.change_alt_frame(Location::AltFrame::ABOVE_TERRAIN);
if (!loc.change_alt_frame(Location::AltFrame::ABOVE_TERRAIN)) {
target_altitude.terrain_following_pending = true;
return;
}
}
target_altitude.terrain_following_pending = false;
#endif
}

Expand Down
6 changes: 5 additions & 1 deletion ArduPlane/commands_logic.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,11 @@ bool Plane::start_command(const AP_Mission::Mission_Command& cmd)
// default to non-VTOL loiter
auto_state.vtol_loiter = false;

// log when new commands start
#if AP_TERRAIN_AVAILABLE
plane.target_altitude.terrain_following_pending = false;
#endif

// log when new commands start
if (should_log(MASK_LOG_CMD)) {
logger.Write_Mission_Cmd(mission, cmd);
}
Expand Down
4 changes: 4 additions & 0 deletions ArduPlane/mode.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,10 @@ bool Mode::enter()
quadplane.mode_enter();
#endif

#if AP_TERRAIN_AVAILABLE
plane.target_altitude.terrain_following_pending = false;
#endif

bool enter_result = _enter();

if (enter_result) {
Expand Down

0 comments on commit 6a9d77f

Please sign in to comment.