9#include <QtCore/QTimer>
16 , _terrainFactGroup(terrainFactGroup)
17 , _terrainDataSendTimer(new QTimer(this))
21 _terrainDataSendTimer->setSingleShot(
false);
22 _terrainDataSendTimer->setInterval(1000.0/12.0);
23 (void) connect(_terrainDataSendTimer, &QTimer::timeout,
this, &TerrainProtocolHandler::_sendNextTerrainData);
33 switch (message.msgid) {
34 case MAVLINK_MSG_ID_TERRAIN_REQUEST:
35 _handleTerrainRequest(message);
37 case MAVLINK_MSG_ID_TERRAIN_REPORT:
38 _handleTerrainReport(message);
45void TerrainProtocolHandler::_handleTerrainRequest(
const mavlink_message_t &message)
47 _terrainRequestActive =
true;
48 mavlink_msg_terrain_request_decode(&message, &_currentTerrainRequest);
49 _sendNextTerrainData();
52void TerrainProtocolHandler::_handleTerrainReport(
const mavlink_message_t &message)
54 mavlink_terrain_report_t terrainReport;
55 mavlink_msg_terrain_report_decode(&message, &terrainReport);
60 if (TerrainProtocolHandlerLog().isDebugEnabled()) {
62 QList<double> altitudes;
63 QList<QGeoCoordinate> coordinates;
64 QGeoCoordinate coord(
static_cast<double>(terrainReport.lat) / 1e7,
static_cast<double>(terrainReport.lon) / 1e7);
65 (void) coordinates.append(coord);
67 const QString vehicleAlt = terrainReport.spacing ? QStringLiteral(
"%1").arg(terrainReport.terrain_height) : QStringLiteral(
"n/a");
70 qgcAlt = QStringLiteral(
"Error");
71 }
else if (altAvailable && !altitudes.isEmpty()) {
72 qgcAlt = QStringLiteral(
"%1").arg(altitudes[0]);
74 qgcAlt = QStringLiteral(
"N/A");
76 qCDebug(TerrainProtocolHandlerLog) <<
"TERRAIN_REPORT" << coord << QStringLiteral(
"Vehicle(%1) QGC(%2)").arg(vehicleAlt).arg(qgcAlt);
80void TerrainProtocolHandler::_sendNextTerrainData()
82 if (!_terrainRequestActive) {
86 QGeoCoordinate terrainRequestCoordSWCorner(
static_cast<double>(_currentTerrainRequest.lat) / 1e7,
static_cast<double>(_currentTerrainRequest.lon) / 1e7);
87 const int spacingBetweenGrids = _currentTerrainRequest.grid_spacing * 4;
93 bool bitFound =
false;
94 for (
int rowIndex=0; rowIndex<7; rowIndex++) {
95 for (
int colIndex=0; colIndex<8; colIndex++) {
96 const uint8_t gridBit = (rowIndex * 8) + colIndex;
97 const uint64_t checkBit = 1ull << gridBit;
98 if (_currentTerrainRequest.mask & checkBit) {
100 QGeoCoordinate swCorner = terrainRequestCoordSWCorner.atDistanceAndAzimuth(spacingBetweenGrids * colIndex, 90);
101 swCorner = swCorner.atDistanceAndAzimuth(spacingBetweenGrids * rowIndex, 0);
102 _sendTerrainData(swCorner, gridBit);
115 _terrainDataSendTimer->start();
117 _terrainRequestActive =
false;
121void TerrainProtocolHandler::_sendTerrainData(
const QGeoCoordinate &swCorner, uint8_t gridBit)
123 QList<QGeoCoordinate> coordinates;
124 for (
int rowIndex=0; rowIndex<4; rowIndex++) {
125 for (
int colIndex=0; colIndex<4; colIndex++) {
127 QGeoCoordinate coord = swCorner.atDistanceAndAzimuth(_currentTerrainRequest.grid_spacing * colIndex, 90);
128 coord = coord.atDistanceAndAzimuth(_currentTerrainRequest.grid_spacing * rowIndex, 0);
129 coordinates.append(coord);
135 QList<double> altitudes;
141 qCWarning(TerrainProtocolHandlerLog) << Q_FUNC_INFO <<
"TerrainAtCoordinateQuery::getAltitudesForCoordinates failed";
146 const uint64_t removeBit = ~(1ull << gridBit);
147 _currentTerrainRequest.mask &= removeBit;
149 int16_t terrainData[16];
150 for (
const double& altitude : altitudes) {
151 terrainData[altIndex++] =
static_cast<int16_t
>(altitude);
157 (void) mavlink_msg_terrain_data_pack_chan(
160 sharedLink->mavlinkChannel(),
162 _currentTerrainRequest.lat,
163 _currentTerrainRequest.lon,
164 _currentTerrainRequest.grid_spacing,
std::shared_ptr< LinkInterface > SharedLinkInterfacePtr
struct __mavlink_message mavlink_message_t
#define QGC_LOGGING_CATEGORY(name, categoryStr)
void setRawValue(const QVariant &value)
static int getComponentId()
static MAVLinkProtocol * instance()
static bool getAltitudesForCoordinates(const QList< QGeoCoordinate > &coordinates, QList< double > &altitudes, bool &error)
bool mavlinkMessageReceived(const mavlink_message_t &message)
~TerrainProtocolHandler()
WeakLinkInterfacePtr primaryLink() const
VehicleLinkManager * vehicleLinkManager()
bool sendMessageOnLinkThreadSafe(LinkInterface *link, mavlink_message_t message)