31 _wireProgressTracking();
33 setInitialState(_stateAutopilotVersion);
46void InitialConnectStateMachine::_createStates()
50 QStringLiteral(
"RequestAutopilotVersion"),
52 MAVLINK_MSG_ID_AUTOPILOT_VERSION,
54 _handleAutopilotVersionSuccess(message);
56 _autopilotVersionMaxRetries,
57 MAV_COMP_ID_AUTOPILOT1
60 return _shouldSkipAutopilotVersionRequest();
63 _handleAutopilotVersionFailure();
70 QStringLiteral(
"RequestStandardModes"),
79 QStringLiteral(
"RequestCompInfo"),
89 QStringLiteral(
"RequestParameters"),
this,
91 if (_shouldSkipForArmed()) {
96 _lastSkipReason = QStringLiteral(
"(vehicle is armed)");
103 qCDebug(InitialConnectStateMachineLog) <<
"Skipping parameter download" << _lastSkipReason;
110 QStringLiteral(
"RequestMission"),
112 [
this]() {
return _shouldSkipForPlanLoad(); },
115 qCDebug(InitialConnectStateMachineLog) <<
"Skipping mission load" << _lastSkipReason;
122 QStringLiteral(
"RequestGeoFence"),
125 if (_shouldSkipForPlanLoad()) {
128 if (!
vehicle()->_geoFenceManager->supported()) {
129 _lastSkipReason = QStringLiteral(
"(not supported by vehicle)");
136 qCDebug(InitialConnectStateMachineLog) <<
"Skipping geofence load" << _lastSkipReason;
143 QStringLiteral(
"RequestRallyPoints"),
146 if (_shouldSkipForPlanLoad()) {
149 if (!
vehicle()->_rallyPointManager->supported()) {
150 _lastSkipReason = QStringLiteral(
"(not supported by vehicle)");
157 qCDebug(InitialConnectStateMachineLog) <<
"Skipping rally points load" << _lastSkipReason;
159 vehicle()->_initialPlanRequestComplete =
true;
168 QStringLiteral(
"SignalComplete"),
180 _stateFinal =
new QGCFinalState(QStringLiteral(
"Final"),
this);
183void InitialConnectStateMachine::_wireTransitions()
208void InitialConnectStateMachine::_wireProgressTracking()
213 {_stateAutopilotVersion, 1},
214 {_stateStandardModes, 1},
216 {_stateParameters, 5},
219 {_stateRallyPoints, 1},
224void InitialConnectStateMachine::_onSubProgressUpdate(
double progressValue)
233bool InitialConnectStateMachine::_shouldSkipAutopilotVersionRequest()
const
237 qCDebug(InitialConnectStateMachineLog) <<
"Skipping AUTOPILOT_VERSION: no primary link";
240 if (sharedLink->linkConfiguration()->isHighLatency() || sharedLink->isLogReplay()) {
241 qCDebug(InitialConnectStateMachineLog) <<
"Skipping AUTOPILOT_VERSION: high latency or log replay";
247bool InitialConnectStateMachine::_shouldSkipForArmed()
const
255bool InitialConnectStateMachine::_shouldSkipForLinkType()
const
261 return sharedLink->linkConfiguration()->isHighLatency() || sharedLink->isLogReplay();
264bool InitialConnectStateMachine::_hasPrimaryLink()
const
267 return sharedLink !=
nullptr;
270bool InitialConnectStateMachine::_shouldSkipForPlanLoad()
272 if (_shouldSkipForArmed()) {
273 _lastSkipReason = QStringLiteral(
"(vehicle is armed)");
276 if (!_hasPrimaryLink()) {
277 _lastSkipReason = QStringLiteral(
"(no primary link)");
280 if (_shouldSkipForLinkType()) {
281 _lastSkipReason = QStringLiteral(
"(high latency or log replay link)");
291void InitialConnectStateMachine::_handleAutopilotVersionSuccess(
const mavlink_message_t& message)
293 qCDebug(InitialConnectStateMachineLog) <<
"AUTOPILOT_VERSION received";
295 mavlink_autopilot_version_t autopilotVersion;
296 mavlink_msg_autopilot_version_decode(&message, &autopilotVersion);
298 vehicle()->_uid = (quint64)autopilotVersion.uid;
299 vehicle()->_firmwareBoardVendorId = autopilotVersion.vendor_id;
300 vehicle()->_firmwareBoardProductId = autopilotVersion.product_id;
303 if (autopilotVersion.flight_sw_version != 0) {
304 int majorVersion, minorVersion, patchVersion;
305 FIRMWARE_VERSION_TYPE versionType;
307 majorVersion = (autopilotVersion.flight_sw_version >> (8*3)) & 0xFF;
308 minorVersion = (autopilotVersion.flight_sw_version >> (8*2)) & 0xFF;
309 patchVersion = (autopilotVersion.flight_sw_version >> (8*1)) & 0xFF;
310 versionType = (FIRMWARE_VERSION_TYPE)((autopilotVersion.flight_sw_version >> (8*0)) & 0xFF);
314 if (
vehicle()->px4Firmware()) {
316 int majorVersion, minorVersion, patchVersion;
317 majorVersion = autopilotVersion.flight_custom_version[2];
318 minorVersion = autopilotVersion.flight_custom_version[1];
319 patchVersion = autopilotVersion.flight_custom_version[0];
324 for (
int i = 7; i >= 0; i--) {
325 vehicle()->_gitHash.append(QString(
"%1").arg(autopilotVersion.flight_custom_version[i], 2, 16, QChar(
'0')));
330 strncpy(nullStr, (
char*)autopilotVersion.flight_custom_version, 8);
336 vehicle()->_checkLatestStableFWDone =
true;
341 vehicle()->_setCapabilities(autopilotVersion.capabilities);
344void InitialConnectStateMachine::_handleAutopilotVersionFailure()
346 qCDebug(InitialConnectStateMachineLog) <<
"AUTOPILOT_VERSION request failed, setting assumed capabilities";
348 uint64_t assumedCapabilities = MAV_PROTOCOL_CAPABILITY_MAVLINK2;
351 assumedCapabilities |= MAV_PROTOCOL_CAPABILITY_MISSION_INT | MAV_PROTOCOL_CAPABILITY_COMMAND_INT |
352 MAV_PROTOCOL_CAPABILITY_MISSION_FENCE | MAV_PROTOCOL_CAPABILITY_MISSION_RALLY;
354 vehicle()->_setCapabilities(assumedCapabilities);
359 qCDebug(InitialConnectStateMachineLog) <<
"_stateRequestStandardModes";
367 qCDebug(InitialConnectStateMachineLog) <<
"_stateRequestCompInfo";
370 this, &InitialConnectStateMachine::_onSubProgressUpdate, Qt::UniqueConnection);
375 this, &InitialConnectStateMachine::_onSubProgressUpdate);
384 qCDebug(InitialConnectStateMachineLog) <<
"_stateRequestParameters";
386 const bool cacheOnly = _shouldSkipForArmed();
387 QMetaObject::Connection cacheFailedConn;
392 qCDebug(InitialConnectStateMachineLog)
393 <<
"Parameter cache check failed while armed, advancing without parameters";
400 this, &InitialConnectStateMachine::_onSubProgressUpdate, Qt::UniqueConnection);
405 qCDebug(InitialConnectStateMachineLog) <<
"Initial parameter request failed, advancing without parameters";
410 [
this](
bool parametersReady) {
411 _onParametersReady(parametersReady);
415 state->
setOnExit([
this, cacheFailedConn, requestFailedConn]() {
417 this, &InitialConnectStateMachine::_onSubProgressUpdate);
418 disconnect(requestFailedConn);
419 if (cacheFailedConn) {
420 disconnect(cacheFailedConn);
431void InitialConnectStateMachine::_onParametersReady(
bool parametersReady)
433 qCDebug(InitialConnectStateMachineLog) <<
"_onParametersReady" << parametersReady;
437 this, &InitialConnectStateMachine::_onSubProgressUpdate);
439 if (parametersReady) {
441 vehicle()->_sendQGCTimeToVehicle();
442 vehicle()->_sendQGCTimeToVehicle();
445 vehicle()->_setupAutoDisarmSignalling();
449 if (_stateParameters) {
457 qCDebug(InitialConnectStateMachineLog) <<
"_stateRequestMission";
460 this, &InitialConnectStateMachine::_onSubProgressUpdate, Qt::UniqueConnection);
467 this, &InitialConnectStateMachine::_onSubProgressUpdate);
475 qCDebug(InitialConnectStateMachineLog) <<
"_stateRequestGeoFence";
478 this, &InitialConnectStateMachine::_onSubProgressUpdate, Qt::UniqueConnection);
485 this, &InitialConnectStateMachine::_onSubProgressUpdate);
493 qCDebug(InitialConnectStateMachineLog) <<
"_stateRequestRallyPoints";
496 this, &InitialConnectStateMachine::_onSubProgressUpdate, Qt::UniqueConnection);
501 vehicle()->_initialPlanRequestComplete =
true;
504 if (_stateRallyPoints) {
512 this, &InitialConnectStateMachine::_onSubProgressUpdate);
518void InitialConnectStateMachine::_signalComplete()
520 qCDebug(InitialConnectStateMachineLog) <<
"Signalling initialConnectComplete";
521 connect(
this, &QStateMachine::finished,
vehicle(), [
this]() {
523 }, Qt::SingleShotConnection);
std::shared_ptr< LinkInterface > SharedLinkInterfacePtr
struct __mavlink_message mavlink_message_t
#define QGC_LOGGING_CATEGORY(name, categoryStr)
Calls a function when entered and waits for an external trigger to advance.
void connectToCompletion(typename QtPrivate::FunctionPointer< Func >::Object *sender, Func signal)
void complete()
Call this to signal that the async operation has completed successfully.
virtual void checkIfIsLatestStable(Vehicle *vehicle) const
Used to check if running firmware is latest stable version.
State machine for initial vehicle connection sequence.
~InitialConnectStateMachine() override
void setParameterDownloadSkipped(bool skipped)
void initialParametersRequestFailed()
Vehicle never responded to PARAM_REQUEST_LIST, all retries exhausted.
void parametersReadyChanged(bool parametersReady)
void tryHashCheckCacheLoad()
void refreshAllParameters(uint8_t componentID)
Re-request the full set of parameters from the autopilot.
void loadProgressChanged(float value)
void cacheCheckOnlyFailed()
void newMissionItemsAvailable(bool removeAllRequested)
void loadFromVehicle(void)
void progressPctChanged(double progressPercentPct)
void setOnExit(ExitCallback callback)
Set a callback to be invoked when the state is exited.
static QGCCorePlugin * instance()
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.
void setSubProgress(float subProgress)
Vehicle * vehicle() const
void setProgressWeights(const QList< QPair< QAbstractState *, int > > &stateWeights)
void resetProgress()
Reset progress tracking (call when restarting the machine)
A state that retries an action and chooses behavior when retries are exhausted.
@ EmitError
Emit error() after retries exhausted.
Requests a MAVLink message with built-in retry logic.
void setSkipPredicate(SkipPredicate predicate)
void setFailureHandler(FailureHandler handler)
Set handler called when all retries fail.
static SettingsManager * instance()
Combines skip condition checking with async operation setup in a single state.
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.
WeakLinkInterfacePtr primaryLink() const
MissionManager * _missionManager
void initialConnectComplete()
void initialPlanRequestCompleteChanged(bool initialPlanRequestComplete)
VehicleLinkManager * vehicleLinkManager()
void setFirmwareCustomVersion(int majorVersion, int minorVersion, int patchVersion)
GeoFenceManager * _geoFenceManager
void gitHashChanged(QString hash)
void setFirmwareVersion(int majorVersion, int minorVersion, int patchVersion, FIRMWARE_VERSION_TYPE versionType=FIRMWARE_VERSION_TYPE_OFFICIAL)
RallyPointManager * _rallyPointManager
StandardModes * _standardModes