17#elif defined(Q_OS_ANDROID)
22#include <QtCore/QApplicationStatic>
23#include <QtCore/QTimer>
31 , _gcsHeartbeatTimer(new QTimer(this))
35 qCDebug(MultiVehicleManagerLog) <<
this;
37 (void) qRegisterMetaType<Vehicle::MavCmdResultFailureCode_t>(
"MavCmdResultFailureCode_t");
40MultiVehicleManager::~MultiVehicleManager()
42 qCDebug(MultiVehicleManagerLog) <<
this;
47 return _multiVehicleManagerInstance();
50void MultiVehicleManager::init()
60 _gcsHeartbeatTimer->setInterval(kGCSHeartbeatRateMSecs);
61 _gcsHeartbeatTimer->setSingleShot(
false);
62 (void) connect(_gcsHeartbeatTimer, &QTimer::timeout,
this, &MultiVehicleManager::_sendGCSHeartbeat);
63 _gcsHeartbeatTimer->start();
68void MultiVehicleManager::_vehicleHeartbeatInfo(
LinkInterface* link,
int vehicleId,
int componentId,
int vehicleFirmwareType,
int vehicleType)
70 if (componentId != MAV_COMP_ID_AUTOPILOT1) {
72 qCDebug(MultiVehicleManagerLog) <<
"Ignoring heartbeat from unknown component port:vehicleId:componentId:fwType:vehicleType"
76 << vehicleFirmwareType
81#ifndef QGC_NO_ARDUPILOT_DIALECT
85 if ((vehicleType == MAV_TYPE_GENERIC) && (vehicleFirmwareType == MAV_AUTOPILOT_ARDUPILOTMEGA)) {
86 vehicleType = MAV_TYPE_QUADROTOR;
90 switch (vehicleType) {
92 case MAV_TYPE_ONBOARD_CONTROLLER:
101 if ((_vehicles->
count() > 0) && !QGCCorePlugin::instance()->options()->multiVehicleEnabled()) {
105 if (_ignoreVehicleIds.contains(vehicleId) || getVehicleById(vehicleId) || (vehicleId == 0)) {
109 qCDebug(MultiVehicleManagerLog) <<
"Adding new vehicle link:vehicleId:componentId:vehicleFirmwareType:vehicleType "
113 << vehicleFirmwareType
117 qgcApp()->showAppMessage(tr(
"Warning: A vehicle is using the same system id as %1: %2").arg(QCoreApplication::applicationName()).arg(vehicleId));
120 Vehicle *
const vehicle =
new Vehicle(link, vehicleId, componentId, (MAV_AUTOPILOT)vehicleFirmwareType, (MAV_TYPE)vehicleType,
this);
124 _vehicles->
append(vehicle);
129 SettingsManager::instance()->firmwareUpgradeSettings()->
defaultFirmwareType()->setRawValue(vehicleFirmwareType);
133 if (_vehicles->
count() > 1) {
134 qgcApp()->showAppMessage(tr(
"Connected to Vehicle %1").arg(vehicleId));
136 setActiveVehicle(vehicle);
139#if defined(Q_OS_ANDROID) || defined(Q_OS_IOS)
140 if (_vehicles->
count() == 1) {
141 qCDebug(MultiVehicleManagerLog) <<
"keepScreenOn";
142 #if defined(Q_OS_ANDROID)
144 #elif defined(Q_OS_IOS)
145 MobileScreenMgr::setKeepScreenOn(
true);
151void MultiVehicleManager::_deleteVehiclePhase1(
Vehicle *vehicle)
153 qCDebug(MultiVehicleManagerLog) << Q_FUNC_INFO << vehicle;
156 for (
int i = 0; i < _vehicles->
count(); i++) {
157 if (_vehicles->
get(i) == vehicle) {
165 qCWarning(MultiVehicleManagerLog) <<
"Vehicle not found in map!";
169 deselectVehicle(vehicle->
id());
171 _setActiveVehicleAvailable(
false);
172 _setParameterReadyVehicleAvailable(
false);
175#if defined(Q_OS_ANDROID) || defined (Q_OS_IOS)
176 if (_vehicles->
count() == 0) {
177 qCDebug(MultiVehicleManagerLog) <<
"restoreScreenOn";
178 #if defined(Q_OS_ANDROID)
180 #elif defined(Q_OS_IOS)
181 MobileScreenMgr::setKeepScreenOn(
false);
192 QTimer::singleShot(20,
this, [
this, vehicle]() {
193 _deleteVehiclePhase2(vehicle);
197void MultiVehicleManager::_deleteVehiclePhase2(
Vehicle *vehicle)
199 qCDebug(MultiVehicleManagerLog) << Q_FUNC_INFO << vehicle;
204 Vehicle *newActiveVehicle =
nullptr;
205 if (_vehicles->
count() > 0) {
206 newActiveVehicle = qobject_cast<Vehicle*>(_vehicles->
get(0));
209 _setActiveVehicle(newActiveVehicle);
211 if (_activeVehicle) {
212 _setActiveVehicleAvailable(
true);
214 _setParameterReadyVehicleAvailable(
true);
218 vehicle->deleteLater();
221void MultiVehicleManager::setActiveVehicle(
Vehicle *vehicle)
223 qCDebug(MultiVehicleManagerLog) << Q_FUNC_INFO << vehicle;
225 if (vehicle != _activeVehicle) {
226 if (_activeVehicle) {
232 _setActiveVehicleAvailable(
false);
233 _setParameterReadyVehicleAvailable(
false);
236 QTimer::singleShot(20,
this, [
this, vehicle]() {
237 _setActiveVehiclePhase2(vehicle);
242void MultiVehicleManager::_setActiveVehiclePhase2(
Vehicle *vehicle)
244 qCDebug(MultiVehicleManagerLog) << Q_FUNC_INFO << vehicle;
246 _setActiveVehicle(vehicle);
248 if (_activeVehicle) {
249 _setActiveVehicleAvailable(
true);
252 _setParameterReadyVehicleAvailable(
true);
257void MultiVehicleManager::_vehicleParametersReadyChanged(
bool parametersReady)
259 ParameterManager *
const paramMgr = qobject_cast<ParameterManager*>(sender());
264 if (paramMgr->
vehicle() == _activeVehicle) {
265 _setParameterReadyVehicleAvailable(parametersReady);
269void MultiVehicleManager::_sendGCSHeartbeat()
271 if (!SettingsManager::instance()->mavlinkSettings()->sendGCSHeartbeat()->rawValue().toBool()) {
275 const QList<SharedLinkInterfacePtr> sharedLinks = LinkManager::instance()->links();
282 if (linkConfiguration->isHighLatency()) {
287 (void) mavlink_msg_heartbeat_pack_chan(
293 MAV_AUTOPILOT_INVALID,
294 MAV_MODE_MANUAL_ARMED,
299 uint8_t buffer[MAVLINK_MAX_PACKET_LEN];
300 const uint16_t len = mavlink_msg_to_send_buffer(buffer, &message);
305void MultiVehicleManager::selectVehicle(
int vehicleId)
307 if(!_vehicleSelected(vehicleId)) {
308 Vehicle *
const vehicle = getVehicleById(vehicleId);
309 _selectedVehicles->
append(vehicle);
314void MultiVehicleManager::deselectVehicle(
int vehicleId)
316 for (
int i = 0; i < _selectedVehicles->
count(); i++) {
317 Vehicle *
const vehicle = qobject_cast<Vehicle*>(_selectedVehicles->
get(i));
318 if (vehicle->
id() == vehicleId) {
325void MultiVehicleManager::deselectAllVehicles()
327 _selectedVehicles->
clear();
330bool MultiVehicleManager::_vehicleSelected(
int vehicleId)
332 for (
int i = 0; i < _selectedVehicles->
count(); i++) {
333 Vehicle *
const vehicle = qobject_cast<Vehicle*>(_selectedVehicles->
get(i));
334 if (vehicle->
id() == vehicleId) {
341Vehicle *MultiVehicleManager::getVehicleById(
int vehicleId)
const
343 for (
int i = 0; i < _vehicles->
count(); i++) {
344 Vehicle *
const vehicle = qobject_cast<Vehicle*>(_vehicles->
get(i));
345 if (vehicle->
id() == vehicleId) {
353void MultiVehicleManager::_setActiveVehicle(
Vehicle *vehicle)
355 if (vehicle != _activeVehicle) {
356 _activeVehicle = vehicle;
361void MultiVehicleManager::_setActiveVehicleAvailable(
bool activeVehicleAvailable)
363 if (activeVehicleAvailable != _activeVehicleAvailable) {
364 _activeVehicleAvailable = activeVehicleAvailable;
369void MultiVehicleManager::_setParameterReadyVehicleAvailable(
bool parametersReady)
371 if (parametersReady != _parameterReadyVehicleAvailable) {
372 _parameterReadyVehicleAvailable = parametersReady;
std::shared_ptr< LinkConfiguration > SharedLinkConfigurationPtr
std::shared_ptr< LinkInterface > SharedLinkInterfacePtr
Q_APPLICATION_STATIC(MultiVehicleManager, _multiVehicleManagerInstance)
struct __mavlink_message mavlink_message_t
#define QGC_LOGGING_CATEGORY(name, categoryStr)
Fact *defaultFirmwareType READ defaultFirmwareType CONSTANT Fact * defaultFirmwareType()
The link interface defines the interface for all links used to communicate with the ground station ap...
uint8_t mavlinkChannel() const
virtual bool isConnected() const =0
void writeBytesThreadSafe(const char *bytes, int length)
SharedLinkConfigurationPtr linkConfiguration()
static int getComponentId()
Get the component id of this application.
void vehicleHeartbeatInfo(LinkInterface *link, int vehicleId, int componentId, int vehicleFirmwareType, int vehicleType)
Heartbeat received on link.
static MAVLinkProtocol * instance()
int getSystemId() const
Get the system id of this application.
void activeVehicleAvailableChanged(bool activeVehicleAvailable)
void vehicleAdded(Vehicle *vehicle)
void vehicleRemoved(Vehicle *vehicle)
void parameterReadyVehicleAvailableChanged(bool parameterReadyVehicleAvailable)
void activeVehicleChanged(Vehicle *activeVehicle)
void parametersReadyChanged(bool parametersReady)
bool parametersReady() const
void append(QObject *object)
Caller maintains responsibility for object ownership and deletion.
QObject * removeAt(int index)
int count() const override final
void clear() override final
void allLinksRemoved(Vehicle *vehicle)
VehicleLinkManager * vehicleLinkManager()
static const MAV_AUTOPILOT MAV_AUTOPILOT_TRACK
static const MAV_TYPE MAV_TYPE_TRACK
ParameterManager * parameterManager()
void setKeepScreenOn(bool on)