Skip to content

Commit cd0ead7

Browse files
julianoesHTRamsey
authored andcommitted
Vehicle: use terrain altitude for ROI
PX4 expects ROI commands to have altitude in AMSL. Therefore, it makes sense to look up the altitude from terrain, and fallback to home altitude otherwise. This commit doesn't change the logic for ArduPilot where ROI altitude is set to 0 relative to the home altitude.
1 parent df94a3a commit cd0ead7

File tree

2 files changed

+67
-14
lines changed

2 files changed

+67
-14
lines changed

src/Vehicle/Vehicle.cc

Lines changed: 61 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -2099,29 +2099,78 @@ void Vehicle::guidedModeROI(const QGeoCoordinate& centerCoord)
20992099
if (!centerCoord.isValid()) {
21002100
return;
21012101
}
2102-
// Sanity check Ardupilot. Max altitude processed is 83000
2103-
if (apmFirmware()) {
2104-
if ((centerCoord.altitude() >= 83000) || (centerCoord.altitude() <= -83000 )) {
2102+
if (!roiModeSupported()) {
2103+
qgcApp()->showAppMessage(QStringLiteral("ROI mode not supported by Vehicle."));
2104+
return;
2105+
}
2106+
2107+
if (px4Firmware()) {
2108+
// PX4 ignores the coordinate frame in COMMAND_INT and treats the altitude as AMSL.
2109+
// The map click provides no altitude, so we query terrain to get a proper AMSL altitude.
2110+
if (_roiTerrainAtCoordinateQuery) {
2111+
disconnect(_roiTerrainAtCoordinateQuery, &TerrainAtCoordinateQuery::terrainDataReceived, this, &Vehicle::_roiTerrainReceived);
2112+
_roiTerrainAtCoordinateQuery = nullptr;
2113+
}
2114+
2115+
_roiCoordinate = centerCoord;
2116+
2117+
_roiTerrainAtCoordinateQuery = new TerrainAtCoordinateQuery(true /* autoDelete */);
2118+
connect(_roiTerrainAtCoordinateQuery, &TerrainAtCoordinateQuery::terrainDataReceived, this, &Vehicle::_roiTerrainReceived);
2119+
QList<QGeoCoordinate> rgCoord;
2120+
rgCoord.append(centerCoord);
2121+
_roiTerrainAtCoordinateQuery->requestData(rgCoord);
2122+
} else {
2123+
// ArduPilot handles MAV_FRAME_GLOBAL_RELATIVE_ALT correctly, so altitude 0 relative to
2124+
// home is a reasonable default for a map click with no altitude info.
2125+
// Sanity check Ardupilot. Max altitude processed is 83000
2126+
if ((centerCoord.altitude() >= 83000) || (centerCoord.altitude() <= -83000)) {
21052127
return;
21062128
}
2129+
_sendROICommand(centerCoord, MAV_FRAME_GLOBAL_RELATIVE_ALT, static_cast<float>(centerCoord.altitude()));
21072130
}
2108-
if (!roiModeSupported()) {
2109-
qgcApp()->showAppMessage(QStringLiteral("ROI mode not supported by Vehicle."));
2131+
2132+
// This is picked by qml to display coordinate over map
2133+
emit roiCoordChanged(centerCoord);
2134+
}
2135+
2136+
void Vehicle::_roiTerrainReceived(bool success, QList<double> heights)
2137+
{
2138+
_roiTerrainAtCoordinateQuery = nullptr;
2139+
2140+
if (!_roiCoordinate.isValid()) {
21102141
return;
21112142
}
2143+
2144+
float roiAltitude;
2145+
if (success) {
2146+
roiAltitude = static_cast<float>(heights[0]);
2147+
} else {
2148+
qCDebug(VehicleLog) << "_roiTerrainReceived: terrain query failed, falling back to home altitude";
2149+
roiAltitude = static_cast<float>(_homePosition.altitude());
2150+
}
2151+
2152+
qCDebug(VehicleLog) << "guidedModeROI: lat" << _roiCoordinate.latitude() << "lon" << _roiCoordinate.longitude() << "terrainAltAMSL" << roiAltitude << "success" << success;
2153+
2154+
_sendROICommand(_roiCoordinate, MAV_FRAME_GLOBAL, roiAltitude);
2155+
2156+
_roiCoordinate = QGeoCoordinate();
2157+
}
2158+
2159+
void Vehicle::_sendROICommand(const QGeoCoordinate& coord, MAV_FRAME frame, float altitude)
2160+
{
21122161
if (capabilityBits() & MAV_PROTOCOL_CAPABILITY_COMMAND_INT) {
21132162
sendMavCommandInt(
21142163
defaultComponentId(),
21152164
MAV_CMD_DO_SET_ROI_LOCATION,
2116-
apmFirmware() ? MAV_FRAME_GLOBAL_RELATIVE_ALT : MAV_FRAME_GLOBAL,
2165+
frame,
21172166
true, // show error if fails
21182167
static_cast<float>(qQNaN()), // Empty
21192168
static_cast<float>(qQNaN()), // Empty
21202169
static_cast<float>(qQNaN()), // Empty
21212170
static_cast<float>(qQNaN()), // Empty
2122-
centerCoord.latitude(),
2123-
centerCoord.longitude(),
2124-
static_cast<float>(centerCoord.altitude()));
2171+
coord.latitude(),
2172+
coord.longitude(),
2173+
altitude);
21252174
} else {
21262175
sendMavCommand(
21272176
defaultComponentId(),
@@ -2131,12 +2180,10 @@ void Vehicle::guidedModeROI(const QGeoCoordinate& centerCoord)
21312180
static_cast<float>(qQNaN()), // Empty
21322181
static_cast<float>(qQNaN()), // Empty
21332182
static_cast<float>(qQNaN()), // Empty
2134-
static_cast<float>(centerCoord.latitude()),
2135-
static_cast<float>(centerCoord.longitude()),
2136-
static_cast<float>(centerCoord.altitude()));
2183+
static_cast<float>(coord.latitude()),
2184+
static_cast<float>(coord.longitude()),
2185+
altitude);
21372186
}
2138-
// This is picked by qml to display coordinate over map
2139-
emit roiCoordChanged(centerCoord);
21402187
}
21412188

21422189
void Vehicle::stopGuidedModeROI()

src/Vehicle/Vehicle.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -915,6 +915,8 @@ private slots:
915915
void _updateFlightTime ();
916916
void _gotProgressUpdate (float progressValue);
917917
void _doSetHomeTerrainReceived (bool success, QList<double> heights);
918+
void _roiTerrainReceived (bool success, QList<double> heights);
919+
void _sendROICommand (const QGeoCoordinate& coord, MAV_FRAME frame, float altitude);
918920
void _updateAltAboveTerrain ();
919921
void _altitudeAboveTerrainReceived (bool sucess, QList<double> heights);
920922

@@ -1254,6 +1256,10 @@ void _activeVehicleChanged (Vehicle* newActiveVehicle);
12541256
TerrainAtCoordinateQuery* _currentDoSetHomeTerrainAtCoordinateQuery = nullptr;
12551257
QGeoCoordinate _doSetHomeCoordinate;
12561258

1259+
// Terrain query members, used to get terrain altitude for guidedModeROI()
1260+
TerrainAtCoordinateQuery* _roiTerrainAtCoordinateQuery = nullptr;
1261+
QGeoCoordinate _roiCoordinate;
1262+
12571263
// Terrain query members, used to get altitude above terrain Fact
12581264
QElapsedTimer _altitudeAboveTerrQueryTimer;
12591265
TerrainAtCoordinateQuery* _altitudeAboveTerrTerrainAtCoordinateQuery = nullptr;

0 commit comments

Comments
 (0)