Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Copter: land & payload place obey altitude frame when lat/lon specified #20982

Merged
merged 2 commits into from Jun 21, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
6 changes: 2 additions & 4 deletions ArduCopter/Copter.h
Expand Up @@ -255,10 +255,8 @@ class Copter : public AP_Vehicle {
uint32_t glitch_cleared_ms; // system time glitch cleared
} rangefinder_state, rangefinder_up_state;

/*
return rangefinder height interpolated using inertial altitude
*/
bool get_rangefinder_height_interpolated_cm(int32_t& ret);
// return rangefinder height interpolated using inertial altitude
bool get_rangefinder_height_interpolated_cm(int32_t& ret) const;

class SurfaceTracking {
public:
Expand Down
2 changes: 1 addition & 1 deletion ArduCopter/mode.h
Expand Up @@ -513,7 +513,7 @@ class ModeAuto : public Mode {

SubMode _mode = SubMode::TAKEOFF; // controls which auto controller is run

Location terrain_adjusted_location(const AP_Mission::Mission_Command& cmd) const;
bool shift_alt_to_current_alt(Location& target_loc) const;

void do_takeoff(const AP_Mission::Mission_Command& cmd);
void do_nav_wp(const AP_Mission::Mission_Command& cmd);
Expand Down
62 changes: 43 additions & 19 deletions ArduCopter/mode_auto.cpp
Expand Up @@ -1228,25 +1228,33 @@ void ModeAuto::payload_place_run_descend()
land_run_vertical_control();
}

// terrain_adjusted_location: returns a Location with lat/lon from cmd
// and altitude from our current altitude adjusted for location
Location ModeAuto::terrain_adjusted_location(const AP_Mission::Mission_Command& cmd) const
{
// convert to location class
Location target_loc(cmd.content.location);
// sets the target_loc's alt to the vehicle's current alt but does not change target_loc's frame
// in the case of terrain altitudes either the terrain database or the rangefinder may be used
// returns true on success, false on failure
bool ModeAuto::shift_alt_to_current_alt(Location& target_loc) const
{
// if terrain alt using rangefinder is being used then set alt to current rangefinder altitude
if ((target_loc.get_alt_frame() == Location::AltFrame::ABOVE_TERRAIN) &&
(wp_nav->get_terrain_source() == AC_WPNav::TerrainSource::TERRAIN_FROM_RANGEFINDER)) {
int32_t curr_rngfnd_alt_cm;
if (copter.get_rangefinder_height_interpolated_cm(curr_rngfnd_alt_cm)) {
// wp_nav is using rangefinder so use current rangefinder alt
target_loc.set_alt_cm(MAX(curr_rngfnd_alt_cm, 200), Location::AltFrame::ABOVE_TERRAIN);
return true;
}
return false;
}

// decide if we will use terrain following
int32_t curr_terr_alt_cm, target_terr_alt_cm;
if (copter.current_loc.get_alt_cm(Location::AltFrame::ABOVE_TERRAIN, curr_terr_alt_cm) &&
target_loc.get_alt_cm(Location::AltFrame::ABOVE_TERRAIN, target_terr_alt_cm)) {
curr_terr_alt_cm = MAX(curr_terr_alt_cm,200);
// if using terrain, set target altitude to current altitude above terrain
target_loc.set_alt_cm(curr_terr_alt_cm, Location::AltFrame::ABOVE_TERRAIN);
} else {
// set target altitude to current altitude above home
target_loc.set_alt_cm(copter.current_loc.alt, Location::AltFrame::ABOVE_HOME);
// take copy of current location and change frame to match target
Location currloc = copter.current_loc;
if (!currloc.change_alt_frame(target_loc.get_alt_frame())) {
// this could fail due missing terrain database alt
return false;
}
return target_loc;

// set target_loc's alt
target_loc.set_alt_cm(currloc.alt, currloc.get_alt_frame());
return true;
}

/********************************************************************************/
Expand Down Expand Up @@ -1398,7 +1406,15 @@ void ModeAuto::do_land(const AP_Mission::Mission_Command& cmd)
// set state to fly to location
state = State::FlyToLocation;

const Location target_loc = terrain_adjusted_location(cmd);
// convert cmd to location class
Location target_loc(cmd.content.location);
if (!shift_alt_to_current_alt(target_loc)) {
// this can only fail due to missing terrain database alt or rangefinder alt
// use current alt-above-home and report error
target_loc.set_alt_cm(copter.current_loc.alt, Location::AltFrame::ABOVE_HOME);
AP::logger().Write_Error(LogErrorSubsystem::TERRAIN, LogErrorCode::MISSING_TERRAIN_DATA);
gcs().send_text(MAV_SEVERITY_CRITICAL, "Land: no terrain data, using alt-above-home");
}

wp_start(target_loc);
} else {
Expand Down Expand Up @@ -1748,7 +1764,15 @@ void ModeAuto::do_payload_place(const AP_Mission::Mission_Command& cmd)
// set state to fly to location
nav_payload_place.state = PayloadPlaceStateType_FlyToLocation;

const Location target_loc = terrain_adjusted_location(cmd);
// convert cmd to location class
Location target_loc(cmd.content.location);
if (!shift_alt_to_current_alt(target_loc)) {
// this can only fail due to missing terrain database alt or rangefinder alt
// use current alt-above-home and report error
target_loc.set_alt_cm(copter.current_loc.alt, Location::AltFrame::ABOVE_HOME);
AP::logger().Write_Error(LogErrorSubsystem::TERRAIN, LogErrorCode::MISSING_TERRAIN_DATA);
gcs().send_text(MAV_SEVERITY_CRITICAL, "PayloadPlace: no terrain data, using alt-above-home");
}

wp_start(target_loc);
} else {
Expand Down
2 changes: 1 addition & 1 deletion ArduCopter/sensors.cpp
Expand Up @@ -135,7 +135,7 @@ bool Copter::rangefinder_up_ok() const
difference between the inertial height at that time and the current
inertial height to give us interpolation of height from rangefinder
*/
bool Copter::get_rangefinder_height_interpolated_cm(int32_t& ret)
bool Copter::get_rangefinder_height_interpolated_cm(int32_t& ret) const
{
if (!rangefinder_alt_ok()) {
return false;
Expand Down