36 #include "firmwareiapobj.h"
40 #define OBJECT_RETRIEVE_TIMEOUT 20000
42 #define IAP_OBJECT_RETRIES 3
44 #ifdef TELEMETRYMONITOR_DEBUG
45 #define TELEMETRYMONITOR_QXTLOG_DEBUG(...) qDebug() << __VA_ARGS__
46 #else // TELEMETRYMONITOR_DEBUG
47 #define TELEMETRYMONITOR_QXTLOG_DEBUG(...)
48 #endif // TELEMETRYMONITOR_DEBUG
69 if (leftD && (!rightD)) {
72 }
else if ((!leftD) && (rightD)) {
97 : connectionStatus(CON_DISCONNECTED)
100 , queue(decltype(queue)(queueCompare))
101 , requestsInFlight(0)
103 this->connectionTimer =
new QTime();
105 gcsStatsObj = GCSTelemetryStats::GetInstance(objMngr);
106 flightStatsObj = FlightTelemetryStats::GetInstance(objMngr);
112 statsTimer =
new QTimer(
this);
113 objectRetrieveTimeout =
new QTimer(
this);
114 objectRetrieveTimeout->setSingleShot(
true);
116 connect(objectRetrieveTimeout, &QTimer::timeout,
this,
117 &TelemetryMonitor::objectRetrieveTimeoutCB);
118 statsTimer->start(STATS_CONNECT_PERIOD_MS);
132 GCSTelemetryStats::DataFields gcsStats = gcsStatsObj->getData();
133 gcsStats.Status = GCSTelemetryStats::STATUS_DISCONNECTED;
144 gcsStatsObj->setData(gcsStats);
150 void TelemetryMonitor::startRetrievingObjects()
152 TELEMETRYMONITOR_QXTLOG_DEBUG(
153 QString(
"%0 connectionStatus changed to CON_RETRIEVING_OBJECT").arg(Q_FUNC_INFO));
154 connectionStatus = CON_RETRIEVING_OBJECTS;
157 queue = decltype(queue)(queueCompare);
159 objectRetrieveTimeout->start(OBJECT_RETRIEVE_TIMEOUT);
168 TELEMETRYMONITOR_QXTLOG_DEBUG(
170 tr(
"Starting to retrieve objects from the autopilot (%1 objects)"))
172 retrieveNextObject();
178 void TelemetryMonitor::retrieveNextObject()
181 if (queue.empty() && requestsInFlight == 0) {
182 TELEMETRYMONITOR_QXTLOG_DEBUG(QString(
"%0 Object retrieval completed").arg(Q_FUNC_INFO));
183 TELEMETRYMONITOR_QXTLOG_DEBUG(
184 QString(
"%0 connectionStatus set to CON_CONNECTED_MANAGED( %1 )")
186 .arg(connectionStatus));
187 connectionStatus = CON_CONNECTED_MANAGED;
189 objectRetrieveTimeout->stop();
193 objectRetrieveTimeout->stop();
194 objectRetrieveTimeout->start(OBJECT_RETRIEVE_TIMEOUT);
196 while (requestsInFlight < MAX_REQUESTS_IN_FLIGHT) {
214 TELEMETRYMONITOR_QXTLOG_DEBUG(QString(
"%0 %1 not present on hardware, skipping")
227 TELEMETRYMONITOR_QXTLOG_DEBUG(QString(
"%0 %1 not present on hardware, skipping associated meta obj")
236 TELEMETRYMONITOR_QXTLOG_DEBUG(QString(
"%0 requesting %1 from board INSTID:%2")
255 TELEMETRYMONITOR_QXTLOG_DEBUG(QString(
"%0 received %1 OBJID:%2 result:%3")
282 while (idx > instId) {
284 qInfo() << QString(
"Got nak instID %1 removing %2").arg(instId).arg(idx);
295 }
else if (success) {
306 if (instObj == NULL) {
307 instdObj = dobj->
clone(new_idx);
313 queue.push(instdObj);
319 obj->disconnect(
this);
322 GCSTelemetryStats::DataFields gcsStats = gcsStatsObj->getData();
323 if (gcsStats.Status == GCSTelemetryStats::STATUS_CONNECTED) {
324 connectionStatus = CON_RETRIEVING_OBJECTS;
326 retrieveNextObject();
329 QString(
"%0 connection lost while retrieving objects, stopped object retrievel")
332 queue = decltype(queue)(queueCompare);
334 objectRetrieveTimeout->stop();
335 connectionStatus = CON_DISCONNECTED;
347 GCSTelemetryStats::DataFields gcsStats = gcsStatsObj->getData();
348 FlightTelemetryStats::DataFields flightStats = flightStatsObj->getData();
349 if (gcsStats.Status != GCSTelemetryStats::STATUS_CONNECTED
350 || flightStats.Status != FlightTelemetryStats::STATUS_CONNECTED) {
355 void TelemetryMonitor::objectRetrieveTimeoutCB()
358 QString(
"%0 reached timeout for object retrieval, clearing queue")
362 queue = decltype(queue)(queueCompare);
365 void TelemetryMonitor::newInstanceSlot(
UAVObject *obj)
379 GCSTelemetryStats::DataFields gcsStats = gcsStatsObj->getData();
380 FlightTelemetryStats::DataFields flightStats = flightStatsObj->getData();
384 gcsStats.RxDataRate = (float)telStats.
rxBytes / ((
float)statsTimer->interval() / 1000.0);
385 gcsStats.TxDataRate = (float)telStats.
txBytes / ((
float)statsTimer->interval() / 1000.0);
386 gcsStats.RxFailures += telStats.
rxErrors;
387 gcsStats.TxFailures += telStats.
txErrors;
388 gcsStats.TxRetries += telStats.
txRetries;
391 bool connectionTimeout;
393 connectionTimer->start();
395 if (connectionTimer->elapsed() > CONNECTION_TIMEOUT_MS) {
396 connectionTimeout =
true;
398 connectionTimeout =
false;
402 int oldStatus = gcsStats.Status;
403 if (gcsStats.Status == GCSTelemetryStats::STATUS_DISCONNECTED) {
405 gcsStats.Status = GCSTelemetryStats::STATUS_HANDSHAKEREQ;
406 }
else if (gcsStats.Status == GCSTelemetryStats::STATUS_HANDSHAKEREQ) {
408 if (flightStats.Status == FlightTelemetryStats::STATUS_HANDSHAKEACK) {
409 gcsStats.Status = GCSTelemetryStats::STATUS_CONNECTED;
411 }
else if (gcsStats.Status == GCSTelemetryStats::STATUS_CONNECTED) {
413 if (flightStats.Status == FlightTelemetryStats::STATUS_DISCONNECTED || connectionTimeout) {
414 gcsStats.Status = GCSTelemetryStats::STATUS_DISCONNECTED;
418 emit
telemetryUpdated((
double)gcsStats.TxDataRate, (
double)gcsStats.RxDataRate);
421 gcsStatsObj->setData(gcsStats);
424 if (gcsStats.Status != GCSTelemetryStats::STATUS_CONNECTED
425 || flightStats.Status != FlightTelemetryStats::STATUS_CONNECTED) {
426 gcsStatsObj->updated();
430 if (gcsStats.Status == GCSTelemetryStats::STATUS_CONNECTED && gcsStats.Status != oldStatus) {
431 statsTimer->setInterval(STATS_UPDATE_PERIOD_MS);
432 qDebug() <<
"Connection with the autopilot established";
433 connectionStatus = CON_INITIALIZING;
434 startRetrievingObjects();
435 }
else if (gcsStats.Status == GCSTelemetryStats::STATUS_DISCONNECTED && gcsStats.Status != oldStatus) {
436 statsTimer->setInterval(STATS_CONNECT_PERIOD_MS);
437 connectionStatus = CON_DISCONNECTED;
void transactionCompleted(UAVObject *obj, bool success, bool nacked)
TelemetryMonitor(UAVObjectManager *objMngr, Telemetry *tel)
QMap< quint32, UAVObject * > ObjectMap
bool registerObject(UAVDataObject *obj)
UAVObject * getParentObject()
void newInstance(UAVObject *obj)
void flightStatsUpdated(UAVObject *obj)
virtual ConnectionManager * connectionManager() const =0
void objectUpdated(UAVObject *obj)
Signal sent whenever any field of the object is updated.
void telemetryDisconnected()
void transactionCompleted(UAVObject *obj, bool success)
transactionCompleted. Triggered by a call to emitTransactionCompleted - done in telemetry.cpp whenever a transaction finishes.
static ICore * instance()
void telemetryUpdated(double txRate, double rxRate)
bool getIsPresentOnHardware() const
void processStatsUpdates()
QHash< quint32, QMap< quint32, UAVObject * > > getObjects()
void resetIsPresentOnHardware()
void telemetryUpdated(double txRate, double rxRate)
void telemetryConnected()
virtual UAVDataObject * clone(quint32 instID=0)=0
bool getPresenceKnown() const
UAVObject * getObject(const QString &name, quint32 instId=0)
TelemetryStats getStats()
bool unRegisterObject(UAVDataObject *obj)
unregisters an object instance and all instances bigger than the one passed as argument from the mana...
void setIsPresentOnHardware(bool value=true)
qint32 getNumInstances(const QString &name)