Commit dd28d2a3 authored by acfloria's avatar acfloria

Fix QTimer issue and send command on high latency link change

parent f4b03729
...@@ -191,8 +191,6 @@ Vehicle::Vehicle(LinkInterface* link, ...@@ -191,8 +191,6 @@ Vehicle::Vehicle(LinkInterface* link,
, _clockFactGroup(this) , _clockFactGroup(this)
, _distanceSensorFactGroup(this) , _distanceSensorFactGroup(this)
{ {
_addLink(link);
connect(_joystickManager, &JoystickManager::activeJoystickChanged, this, &Vehicle::_loadSettings); connect(_joystickManager, &JoystickManager::activeJoystickChanged, this, &Vehicle::_loadSettings);
connect(qgcApp()->toolbox()->multiVehicleManager(), &MultiVehicleManager::activeVehicleAvailableChanged, this, &Vehicle::_loadSettings); connect(qgcApp()->toolbox()->multiVehicleManager(), &MultiVehicleManager::activeVehicleAvailableChanged, this, &Vehicle::_loadSettings);
...@@ -200,6 +198,8 @@ Vehicle::Vehicle(LinkInterface* link, ...@@ -200,6 +198,8 @@ Vehicle::Vehicle(LinkInterface* link,
connect(_mavlink, &MAVLinkProtocol::messageReceived, this, &Vehicle::_mavlinkMessageReceived); connect(_mavlink, &MAVLinkProtocol::messageReceived, this, &Vehicle::_mavlinkMessageReceived);
_addLink(link);
connect(this, &Vehicle::_sendMessageOnLinkOnThread, this, &Vehicle::_sendMessageOnLink, Qt::QueuedConnection); connect(this, &Vehicle::_sendMessageOnLinkOnThread, this, &Vehicle::_sendMessageOnLink, Qt::QueuedConnection);
connect(this, &Vehicle::flightModeChanged, this, &Vehicle::_handleFlightModeChanged); connect(this, &Vehicle::flightModeChanged, this, &Vehicle::_handleFlightModeChanged);
connect(this, &Vehicle::armedChanged, this, &Vehicle::_announceArmedChanged); connect(this, &Vehicle::armedChanged, this, &Vehicle::_announceArmedChanged);
...@@ -1609,8 +1609,12 @@ void Vehicle::_addLink(LinkInterface* link) ...@@ -1609,8 +1609,12 @@ void Vehicle::_addLink(LinkInterface* link)
if (!_containsLink(link)) { if (!_containsLink(link)) {
qCDebug(VehicleLog) << "_addLink:" << QString("%1").arg((ulong)link, 0, 16); qCDebug(VehicleLog) << "_addLink:" << QString("%1").arg((ulong)link, 0, 16);
_links += link; _links += link;
_updatePriorityLink(true); if (_links.count() <= 1) {
_updateHighLatencyLink(); _updatePriorityLink(true, false);
} else {
_updatePriorityLink(true, true);
}
connect(_toolbox->linkManager(), &LinkManager::linkInactive, this, &Vehicle::_linkInactiveOrDeleted); connect(_toolbox->linkManager(), &LinkManager::linkInactive, this, &Vehicle::_linkInactiveOrDeleted);
connect(_toolbox->linkManager(), &LinkManager::linkDeleted, this, &Vehicle::_linkInactiveOrDeleted); connect(_toolbox->linkManager(), &LinkManager::linkDeleted, this, &Vehicle::_linkInactiveOrDeleted);
connect(link, &LinkInterface::highLatencyChanged, this, &Vehicle::_updateHighLatencyLink); connect(link, &LinkInterface::highLatencyChanged, this, &Vehicle::_updateHighLatencyLink);
...@@ -1623,7 +1627,7 @@ void Vehicle::_linkInactiveOrDeleted(LinkInterface* link) ...@@ -1623,7 +1627,7 @@ void Vehicle::_linkInactiveOrDeleted(LinkInterface* link)
qCDebug(VehicleLog) << "_linkInactiveOrDeleted linkCount" << _links.count(); qCDebug(VehicleLog) << "_linkInactiveOrDeleted linkCount" << _links.count();
_links.removeOne(link); _links.removeOne(link);
_updatePriorityLink(true); _updatePriorityLink(true, true);
if (_links.count() == 0 && !_allLinksInactiveSent) { if (_links.count() == 0 && !_allLinksInactiveSent) {
qCDebug(VehicleLog) << "All links inactive"; qCDebug(VehicleLog) << "All links inactive";
...@@ -1669,7 +1673,7 @@ void Vehicle::_sendMessageOnLink(LinkInterface* link, mavlink_message_t message) ...@@ -1669,7 +1673,7 @@ void Vehicle::_sendMessageOnLink(LinkInterface* link, mavlink_message_t message)
emit messagesSentChanged(); emit messagesSentChanged();
} }
void Vehicle::_updatePriorityLink(bool updateActive) void Vehicle::_updatePriorityLink(bool updateActive, bool sendCommand)
{ {
emit linkNamesChanged(); emit linkNamesChanged();
LinkInterface* newPriorityLink = NULL; LinkInterface* newPriorityLink = NULL;
...@@ -1751,7 +1755,9 @@ void Vehicle::_updatePriorityLink(bool updateActive) ...@@ -1751,7 +1755,9 @@ void Vehicle::_updatePriorityLink(bool updateActive)
qgcApp()->showMessage((tr("switch to %2 as priority link")).arg(newPriorityLink->getName())); qgcApp()->showMessage((tr("switch to %2 as priority link")).arg(newPriorityLink->getName()));
} }
_priorityLink = _toolbox->linkManager()->sharedLinkInterfacePointerForLink(newPriorityLink); _priorityLink = _toolbox->linkManager()->sharedLinkInterfacePointerForLink(newPriorityLink);
_updateHighLatencyLink();
_updateHighLatencyLink(sendCommand);
emit priorityLinkNameChanged(_priorityLink->getName()); emit priorityLinkNameChanged(_priorityLink->getName());
if (updateActive) { if (updateActive) {
_linkActiveChanged(_priorityLink.data(), _priorityLink->active()); _linkActiveChanged(_priorityLink.data(), _priorityLink->active());
...@@ -2131,7 +2137,7 @@ void Vehicle::setPriorityLinkByName(const QString& priorityLinkName) ...@@ -2131,7 +2137,7 @@ void Vehicle::setPriorityLinkByName(const QString& priorityLinkName)
if (newPriorityLink) { if (newPriorityLink) {
_priorityLink = _toolbox->linkManager()->sharedLinkInterfacePointerForLink(newPriorityLink); _priorityLink = _toolbox->linkManager()->sharedLinkInterfacePointerForLink(newPriorityLink);
_updateHighLatencyLink(); _updateHighLatencyLink(true);
emit priorityLinkNameChanged(_priorityLink->getName()); emit priorityLinkNameChanged(_priorityLink->getName());
_linkActiveChanged(_priorityLink.data(), _priorityLink->active()); _linkActiveChanged(_priorityLink.data(), _priorityLink->active());
} }
...@@ -2443,19 +2449,24 @@ void Vehicle::_linkActiveChanged(LinkInterface *link, bool active) ...@@ -2443,19 +2449,24 @@ void Vehicle::_linkActiveChanged(LinkInterface *link, bool active)
if (active && _connectionLost) { if (active && _connectionLost) {
// communication to priority link regained // communication to priority link regained
_connectionLost = false; _connectionLost = false;
emit connectionLostChanged(false);
qgcApp()->showMessage((tr("communication to priority link %2 regained")).arg(link->getName())); qgcApp()->showMessage((tr("communication to priority link %2 regained")).arg(link->getName()));
// Re-negotiate protocol version for the link if (_priorityLink->highLatency()) {
sendMavCommand(MAV_COMP_ID_ALL, // Don't know default component id yet. _setMaxProtoVersion(100);
MAV_CMD_REQUEST_PROTOCOL_VERSION, } else {
false, // No error shown if fails // Re-negotiate protocol version for the link
1); // Request protocol version sendMavCommand(MAV_COMP_ID_ALL, // Don't know default component id yet.
MAV_CMD_REQUEST_PROTOCOL_VERSION,
false, // No error shown if fails
1); // Request protocol version
}
} else if (!active && !_connectionLost) { } else if (!active && !_connectionLost) {
// communication to priority link lost // communication to priority link lost
qgcApp()->showMessage((tr("communication to priority link %2 lost")).arg(link->getName())); qgcApp()->showMessage((tr("communication to priority link %2 lost")).arg(link->getName()));
_updatePriorityLink(false); _updatePriorityLink(false, true);
if (link == _priorityLink) { if (link == _priorityLink) {
_say(QString(tr("%1 communication lost")).arg(_vehicleIdSpeech())); _say(QString(tr("%1 communication lost")).arg(_vehicleIdSpeech()));
...@@ -3354,12 +3365,26 @@ void Vehicle::_vehicleParamLoaded(bool ready) ...@@ -3354,12 +3365,26 @@ void Vehicle::_vehicleParamLoaded(bool ready)
} }
} }
void Vehicle::_updateHighLatencyLink(void) void Vehicle::_updateHighLatencyLink(bool sendCommand)
{ {
if (_priorityLink->highLatency() != _highLatencyLink) { if (_priorityLink->highLatency() != _highLatencyLink) {
_highLatencyLink = _priorityLink->highLatency(); _highLatencyLink = _priorityLink->highLatency();
_mavCommandAckTimer.setInterval(_highLatencyLink ? _mavCommandAckTimeoutMSecsHighLatency : _mavCommandAckTimeoutMSecs); _mavCommandAckTimer.setInterval(_highLatencyLink ? _mavCommandAckTimeoutMSecsHighLatency : _mavCommandAckTimeoutMSecs);
emit highLatencyLinkChanged(_highLatencyLink); emit highLatencyLinkChanged(_highLatencyLink);
if (sendCommand) {
if (_highLatencyLink) {
sendMavCommand(defaultComponentId(),
MAV_CMD_CONTROL_HIGH_LATENCY,
true,
1.0f); // request start transmitting over high latency telemetry
} else {
sendMavCommand(defaultComponentId(),
MAV_CMD_CONTROL_HIGH_LATENCY,
true,
0.0f); // request stop transmitting over high latency telemetry
}
}
} }
} }
......
...@@ -1032,7 +1032,7 @@ private slots: ...@@ -1032,7 +1032,7 @@ private slots:
void _offlineVehicleTypeSettingChanged(QVariant value); void _offlineVehicleTypeSettingChanged(QVariant value);
void _offlineCruiseSpeedSettingChanged(QVariant value); void _offlineCruiseSpeedSettingChanged(QVariant value);
void _offlineHoverSpeedSettingChanged(QVariant value); void _offlineHoverSpeedSettingChanged(QVariant value);
void _updateHighLatencyLink(void); void _updateHighLatencyLink(bool sendCommand = true);
void _handleTextMessage (int newCount); void _handleTextMessage (int newCount);
void _handletextMessageReceived (UASMessage* message); void _handletextMessageReceived (UASMessage* message);
...@@ -1106,7 +1106,7 @@ private: ...@@ -1106,7 +1106,7 @@ private:
void _handleMavlinkLoggingDataAcked(mavlink_message_t& message); void _handleMavlinkLoggingDataAcked(mavlink_message_t& message);
void _ackMavlinkLogData(uint16_t sequence); void _ackMavlinkLogData(uint16_t sequence);
void _sendNextQueuedMavCommand(void); void _sendNextQueuedMavCommand(void);
void _updatePriorityLink(bool updateActive); void _updatePriorityLink(bool updateActive, bool sendCommand);
void _commonInit(void); void _commonInit(void);
void _startPlanRequest(void); void _startPlanRequest(void);
void _setupAutoDisarmSignalling(void); void _setupAutoDisarmSignalling(void);
......
...@@ -28,6 +28,7 @@ LinkInterface::LinkInterface(SharedLinkConfigurationPointer& config) ...@@ -28,6 +28,7 @@ LinkInterface::LinkInterface(SharedLinkConfigurationPointer& config)
, _active (false) , _active (false)
, _enableRateCollection (false) , _enableRateCollection (false)
, _decodedFirstMavlinkPacket(false) , _decodedFirstMavlinkPacket(false)
, _bytesReceivedTimer(NULL)
{ {
_config->setLink(this); _config->setLink(this);
...@@ -43,14 +44,6 @@ LinkInterface::LinkInterface(SharedLinkConfigurationPointer& config) ...@@ -43,14 +44,6 @@ LinkInterface::LinkInterface(SharedLinkConfigurationPointer& config)
QObject::connect(this, &LinkInterface::_invokeWriteBytes, this, &LinkInterface::_writeBytes); QObject::connect(this, &LinkInterface::_invokeWriteBytes, this, &LinkInterface::_writeBytes);
qRegisterMetaType<LinkInterface*>("LinkInterface*"); qRegisterMetaType<LinkInterface*>("LinkInterface*");
// active Lost timer
_bytesReceivedTimer.setInterval(_bytesReceivedTimeoutMSecs);
_bytesReceivedTimer.setSingleShot(false);
_bytesReceivedTimer.start();
QObject::connect(&_bytesReceivedTimer, &QTimer::timeout, this, &LinkInterface::_bytesReceivedTimeout);
QObject::connect(this, &LinkInterface::bytesReceived, this, &LinkInterface::_bytesReceived);
} }
/// This function logs the send times and amounts of datas for input. Data is used for calculating /// This function logs the send times and amounts of datas for input. Data is used for calculating
...@@ -168,18 +161,6 @@ void LinkInterface::_setMavlinkChannel(uint8_t channel) ...@@ -168,18 +161,6 @@ void LinkInterface::_setMavlinkChannel(uint8_t channel)
_mavlinkChannel = channel; _mavlinkChannel = channel;
} }
void LinkInterface::_bytesReceived(LinkInterface* link, QByteArray bytes)
{
Q_UNUSED(bytes);
if (this == link) {
_bytesReceivedTimer.start();
if (!link->active()) {
link->setActive(true);
}
}
}
void LinkInterface::_bytesReceivedTimeout() void LinkInterface::_bytesReceivedTimeout()
{ {
...@@ -187,3 +168,23 @@ void LinkInterface::_bytesReceivedTimeout() ...@@ -187,3 +168,23 @@ void LinkInterface::_bytesReceivedTimeout()
setActive(false); setActive(false);
} }
} }
void LinkInterface::timerStart() {
if (_bytesReceivedTimer) {
_bytesReceivedTimer->start();
} else {
_bytesReceivedTimer = new QTimer();
_bytesReceivedTimer->setInterval(_bytesReceivedTimeoutMSecs);
_bytesReceivedTimer->setSingleShot(true);
_bytesReceivedTimer->start();
QObject::connect(_bytesReceivedTimer, &QTimer::timeout, this, &LinkInterface::_bytesReceivedTimeout);
}
}
void LinkInterface::timerStop() {
if (_bytesReceivedTimer) {
_bytesReceivedTimer->stop();
QObject::disconnect(_bytesReceivedTimer, &QTimer::timeout, this, &LinkInterface::_bytesReceivedTimeout);
delete _bytesReceivedTimer;
}
}
...@@ -37,7 +37,10 @@ class LinkInterface : public QThread ...@@ -37,7 +37,10 @@ class LinkInterface : public QThread
friend class LinkManager; friend class LinkManager;
public: public:
~LinkInterface() { _config->setLink(NULL); } ~LinkInterface() {
_config->setLink(NULL);
timerStop();
}
Q_PROPERTY(bool active READ active WRITE setActive NOTIFY activeChanged) Q_PROPERTY(bool active READ active WRITE setActive NOTIFY activeChanged)
...@@ -150,6 +153,9 @@ public slots: ...@@ -150,6 +153,9 @@ public slots:
private slots: private slots:
virtual void _writeBytes(const QByteArray) = 0; virtual void _writeBytes(const QByteArray) = 0;
void _bytesReceivedTimeout(void);
signals: signals:
void autoconnectChanged(bool autoconnect); void autoconnectChanged(bool autoconnect);
...@@ -250,13 +256,23 @@ private: ...@@ -250,13 +256,23 @@ private:
virtual void _disconnect(void) = 0; virtual void _disconnect(void) = 0;
void _bytesReceived(LinkInterface* link, QByteArray bytes);
void _bytesReceivedTimeout(void);
/// Sets the mavlink channel to use for this link /// Sets the mavlink channel to use for this link
void _setMavlinkChannel(uint8_t channel); void _setMavlinkChannel(uint8_t channel);
/**
* @brief timerStart
*
* Allocate the timer if it does not exist yet and start it.
*/
void timerStart();
/**
* @brief timerStop
*
* Stop and deallocate the timer if it exists.
*/
void timerStop();
bool _mavlinkChannelSet; ///< true: _mavlinkChannel has been set bool _mavlinkChannelSet; ///< true: _mavlinkChannel has been set
uint8_t _mavlinkChannel; ///< mavlink channel to use for this link, as used by mavlink_parse_char uint8_t _mavlinkChannel; ///< mavlink channel to use for this link, as used by mavlink_parse_char
...@@ -283,7 +299,7 @@ private: ...@@ -283,7 +299,7 @@ private:
bool _decodedFirstMavlinkPacket; ///< true: link has correctly decoded it's first mavlink packet bool _decodedFirstMavlinkPacket; ///< true: link has correctly decoded it's first mavlink packet
static const int _bytesReceivedTimeoutMSecs = 3500; // Signal connection lost after 3.5 seconds of no messages static const int _bytesReceivedTimeoutMSecs = 3500; // Signal connection lost after 3.5 seconds of no messages
QTimer _bytesReceivedTimer; QTimer* _bytesReceivedTimer;
}; };
typedef QSharedPointer<LinkInterface> SharedLinkInterfacePointer; typedef QSharedPointer<LinkInterface> SharedLinkInterfacePointer;
......
...@@ -195,6 +195,7 @@ void LinkManager::_addLink(LinkInterface* link) ...@@ -195,6 +195,7 @@ void LinkManager::_addLink(LinkInterface* link)
connect(link, &LinkInterface::communicationError, _app, &QGCApplication::criticalMessageBoxOnMainThread); connect(link, &LinkInterface::communicationError, _app, &QGCApplication::criticalMessageBoxOnMainThread);
connect(link, &LinkInterface::bytesReceived, _mavlinkProtocol, &MAVLinkProtocol::receiveBytes); connect(link, &LinkInterface::bytesReceived, _mavlinkProtocol, &MAVLinkProtocol::receiveBytes);
connect(link, &LinkInterface::bytesReceived, this, &LinkManager::_bytesReceived);
_mavlinkProtocol->resetMetadataForLink(link); _mavlinkProtocol->resetMetadataForLink(link);
_mavlinkProtocol->setVersion(_mavlinkProtocol->getCurrentVersion()); _mavlinkProtocol->setVersion(_mavlinkProtocol->getCurrentVersion());
...@@ -1003,3 +1004,13 @@ void LinkManager::_freeMavlinkChannel(int channel) ...@@ -1003,3 +1004,13 @@ void LinkManager::_freeMavlinkChannel(int channel)
{ {
_mavlinkChannelsUsedBitMask &= ~(1 << channel); _mavlinkChannelsUsedBitMask &= ~(1 << channel);
} }
void LinkManager::_bytesReceived(LinkInterface *link, QByteArray bytes) {
Q_UNUSED(bytes);
link->timerStart();
if (!link->active()) {
link->setActive(true);
}
}
...@@ -204,6 +204,8 @@ private: ...@@ -204,6 +204,8 @@ private:
SerialConfiguration* _autoconnectConfigurationsContainsPort(const QString& portName); SerialConfiguration* _autoconnectConfigurationsContainsPort(const QString& portName);
#endif #endif
void _bytesReceived(LinkInterface* link, QByteArray bytes);
bool _configUpdateSuspended; ///< true: stop updating configuration list bool _configUpdateSuspended; ///< true: stop updating configuration list
bool _configurationsLoaded; ///< true: Link configurations have been loaded bool _configurationsLoaded; ///< true: Link configurations have been loaded
bool _connectionsSuspended; ///< true: all new connections should not be allowed bool _connectionsSuspended; ///< true: all new connections should not be allowed
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment