27 _wireProgressTracking();
28 _wireTimeoutHandling();
30 setInitialState(_stateAutopilotVersion);
43void InitialConnectStateMachine::_createStates()
47 QStringLiteral(
"RequestAutopilotVersion"),
49 MAVLINK_MSG_ID_AUTOPILOT_VERSION,
51 _handleAutopilotVersionSuccess(message);
54 MAV_COMP_ID_AUTOPILOT1,
55 _timeoutAutopilotVersion
58 return _shouldSkipAutopilotVersionRequest();
61 _handleAutopilotVersionFailure();
66 QStringLiteral(
"RequestStandardModes"),
74 QStringLiteral(
"RequestCompInfo"),
82 QStringLiteral(
"RequestParameters"),
90 QStringLiteral(
"RequestMission"),
92 [
this]() {
return _shouldSkipForLinkType() || !_hasPrimaryLink(); },
95 qCDebug(InitialConnectStateMachineLog) <<
"Skipping mission load";
102 QStringLiteral(
"RequestGeoFence"),
105 return _shouldSkipForLinkType() || !_hasPrimaryLink() ||
106 !vehicle()->_geoFenceManager->supported();
110 qCDebug(InitialConnectStateMachineLog) <<
"Skipping geofence load";
117 QStringLiteral(
"RequestRallyPoints"),
120 return _shouldSkipForLinkType() || !_hasPrimaryLink() ||
121 !vehicle()->_rallyPointManager->supported();
125 qCDebug(InitialConnectStateMachineLog) <<
"Skipping rally points load";
127 vehicle()->_initialPlanRequestComplete =
true;
128 emit vehicle()->initialPlanRequestCompleteChanged(
true);
137 QStringLiteral(
"SignalComplete"),
149 _stateFinal =
new QGCFinalState(QStringLiteral(
"Final"),
this);
152void InitialConnectStateMachine::_wireTransitions()
174void InitialConnectStateMachine::_wireProgressTracking()
179 {_stateAutopilotVersion, 1},
180 {_stateStandardModes, 1},
182 {_stateParameters, 5},
185 {_stateRallyPoints, 1},
190void InitialConnectStateMachine::_onSubProgressUpdate(
double progressValue)
192 setSubProgress(
static_cast<float>(progressValue));
199void InitialConnectStateMachine::_wireTimeoutHandling()
205 [
this]() { _requestStandardModes(_stateStandardModes); }, _maxRetries);
208 [
this]() { _requestCompInfo(_stateCompInfo); }, _maxRetries);
211 [
this]() { _requestParameters(_stateParameters); }, _maxRetries);
214 [
this]() { _requestMission(_stateMission); }, _maxRetries);
217 [
this]() { _requestGeoFence(_stateGeoFence); }, _maxRetries);
220 [
this]() { _requestRallyPoints(_stateRallyPoints); }, _maxRetries);
227bool InitialConnectStateMachine::_shouldSkipAutopilotVersionRequest()
const
231 qCDebug(InitialConnectStateMachineLog) <<
"Skipping AUTOPILOT_VERSION: no primary link";
234 if (sharedLink->linkConfiguration()->isHighLatency() || sharedLink->isLogReplay()) {
235 qCDebug(InitialConnectStateMachineLog) <<
"Skipping AUTOPILOT_VERSION: high latency or log replay";
241bool InitialConnectStateMachine::_shouldSkipForLinkType()
const
247 return sharedLink->linkConfiguration()->isHighLatency() || sharedLink->isLogReplay();
250bool InitialConnectStateMachine::_hasPrimaryLink()
const
253 return sharedLink !=
nullptr;
260void InitialConnectStateMachine::_handleAutopilotVersionSuccess(
const mavlink_message_t& message)
262 qCDebug(InitialConnectStateMachineLog) <<
"AUTOPILOT_VERSION received";
264 mavlink_autopilot_version_t autopilotVersion;
265 mavlink_msg_autopilot_version_decode(&message, &autopilotVersion);
267 vehicle()->_uid = (quint64)autopilotVersion.uid;
268 vehicle()->_firmwareBoardVendorId = autopilotVersion.vendor_id;
269 vehicle()->_firmwareBoardProductId = autopilotVersion.product_id;
270 emit vehicle()->vehicleUIDChanged();
272 if (autopilotVersion.flight_sw_version != 0) {
273 int majorVersion, minorVersion, patchVersion;
274 FIRMWARE_VERSION_TYPE versionType;
276 majorVersion = (autopilotVersion.flight_sw_version >> (8*3)) & 0xFF;
277 minorVersion = (autopilotVersion.flight_sw_version >> (8*2)) & 0xFF;
278 patchVersion = (autopilotVersion.flight_sw_version >> (8*1)) & 0xFF;
279 versionType = (FIRMWARE_VERSION_TYPE)((autopilotVersion.flight_sw_version >> (8*0)) & 0xFF);
280 vehicle()->setFirmwareVersion(majorVersion, minorVersion, patchVersion, versionType);
283 if (vehicle()->px4Firmware()) {
285 int majorVersion, minorVersion, patchVersion;
286 majorVersion = autopilotVersion.flight_custom_version[2];
287 minorVersion = autopilotVersion.flight_custom_version[1];
288 patchVersion = autopilotVersion.flight_custom_version[0];
289 vehicle()->setFirmwareCustomVersion(majorVersion, minorVersion, patchVersion);
292 vehicle()->_gitHash =
"";
293 for (
int i = 7; i >= 0; i--) {
294 vehicle()->_gitHash.append(QString(
"%1").arg(autopilotVersion.flight_custom_version[i], 2, 16, QChar(
'0')));
299 strncpy(nullStr, (
char*)autopilotVersion.flight_custom_version, 8);
301 vehicle()->_gitHash = nullStr;
304 if (QGCCorePlugin::instance()->options()->checkFirmwareVersion() && !vehicle()->_checkLatestStableFWDone) {
305 vehicle()->_checkLatestStableFWDone =
true;
306 vehicle()->_firmwarePlugin->checkIfIsLatestStable(vehicle());
308 emit vehicle()->gitHashChanged(vehicle()->_gitHash);
310 vehicle()->_setCapabilities(autopilotVersion.capabilities);
313void InitialConnectStateMachine::_handleAutopilotVersionFailure()
315 qCDebug(InitialConnectStateMachineLog) <<
"AUTOPILOT_VERSION request failed, setting assumed capabilities";
317 uint64_t assumedCapabilities = MAV_PROTOCOL_CAPABILITY_MAVLINK2;
318 if (vehicle()->px4Firmware() || vehicle()->apmFirmware()) {
320 assumedCapabilities |= MAV_PROTOCOL_CAPABILITY_MISSION_INT | MAV_PROTOCOL_CAPABILITY_COMMAND_INT |
321 MAV_PROTOCOL_CAPABILITY_MISSION_FENCE | MAV_PROTOCOL_CAPABILITY_MISSION_RALLY;
323 vehicle()->_setCapabilities(assumedCapabilities);
328 qCDebug(InitialConnectStateMachineLog) <<
"_stateRequestStandardModes";
331 vehicle()->_standardModes->request();
336 qCDebug(InitialConnectStateMachineLog) <<
"_stateRequestCompInfo";
339 this, &InitialConnectStateMachine::_onSubProgressUpdate, Qt::UniqueConnection);
344 this, &InitialConnectStateMachine::_onSubProgressUpdate);
347 vehicle()->_componentInformationManager->requestAllComponentInformation(
348 [](
void* requestAllCompleteFnData) {
350 if (self->_stateCompInfo) {
360 qCDebug(InitialConnectStateMachineLog) <<
"_stateRequestParameters";
363 this, &InitialConnectStateMachine::_onSubProgressUpdate, Qt::UniqueConnection);
366 [
this](
bool parametersReady) {
367 _onParametersReady(parametersReady);
373 this, &InitialConnectStateMachine::_onSubProgressUpdate);
376 vehicle()->_parameterManager->refreshAllParameters();
379void InitialConnectStateMachine::_onParametersReady(
bool parametersReady)
381 qCDebug(InitialConnectStateMachineLog) <<
"_onParametersReady" << parametersReady;
385 this, &InitialConnectStateMachine::_onSubProgressUpdate);
387 if (parametersReady) {
389 vehicle()->_sendQGCTimeToVehicle();
390 vehicle()->_sendQGCTimeToVehicle();
393 vehicle()->_setupAutoDisarmSignalling();
397 if (_stateParameters) {
405 qCDebug(InitialConnectStateMachineLog) <<
"_stateRequestMission";
408 this, &InitialConnectStateMachine::_onSubProgressUpdate, Qt::UniqueConnection);
415 this, &InitialConnectStateMachine::_onSubProgressUpdate);
418 vehicle()->_missionManager->loadFromVehicle();
423 qCDebug(InitialConnectStateMachineLog) <<
"_stateRequestGeoFence";
426 this, &InitialConnectStateMachine::_onSubProgressUpdate, Qt::UniqueConnection);
433 this, &InitialConnectStateMachine::_onSubProgressUpdate);
436 vehicle()->_geoFenceManager->loadFromVehicle();
441 qCDebug(InitialConnectStateMachineLog) <<
"_stateRequestRallyPoints";
444 this, &InitialConnectStateMachine::_onSubProgressUpdate, Qt::UniqueConnection);
449 vehicle()->_initialPlanRequestComplete =
true;
450 emit vehicle()->initialPlanRequestCompleteChanged(
true);
452 if (_stateRallyPoints) {
460 this, &InitialConnectStateMachine::_onSubProgressUpdate);
463 vehicle()->_rallyPointManager->loadFromVehicle();
466void InitialConnectStateMachine::_signalComplete()
468 qCDebug(InitialConnectStateMachineLog) <<
"Signalling initialConnectComplete";
469 connect(
this, &QStateMachine::finished, vehicle(), [
this]() {
470 emit vehicle()->initialConnectComplete();
471 }, Qt::SingleShotConnection);
std::shared_ptr< LinkInterface > SharedLinkInterfacePtr
struct __mavlink_message mavlink_message_t
#define QGC_LOGGING_CATEGORY(name, categoryStr)
void connectToCompletion(typename QtPrivate::FunctionPointer< Func >::Object *sender, Func signal)
void complete()
Call this to signal that the async operation has completed successfully.
~InitialConnectStateMachine() override
void parametersReadyChanged(bool parametersReady)
void loadProgressChanged(float value)
void newMissionItemsAvailable(bool removeAllRequested)
void progressPctChanged(double progressPercentPct)
void setOnExit(ExitCallback callback)
Set a callback to be invoked when the state is exited.
Final state for a QGCStateMachine with logging support.
QGroundControl specific state machine with enhanced error handling.
void start()
Start the state machine with debug logging.
@ EmitError
Emit error() after retries exhausted.
void setSkipPredicate(SkipPredicate predicate)
void setFailureHandler(FailureHandler handler)
Set handler called when all retries fail.
void connectToCompletion(typename QtPrivate::FunctionPointer< Func >::Object *sender, Func signal)
void skipped()
Emitted when skip predicate returns true and the state is skipped.
void complete()
Call this to signal that the async operation has completed successfully.