QGroundControl
Ground Control Station for MAVLink Drones
Loading...
Searching...
No Matches
APMSensorsComponentController.cc
Go to the documentation of this file.
4#include "MAVLinkLib.h"
5#include "MAVLinkProtocol.h"
6#include "ParameterManager.h"
7#include "AppMessages.h"
9#include "Vehicle.h"
10#include "VehicleLinkManager.h"
11
12#include <QtCore/QVariant>
13
14QGC_LOGGING_CATEGORY(APMSensorsComponentControllerLog, "AutoPilotPlugins.APMSensorsComponentController")
15QGC_LOGGING_CATEGORY(APMSensorsComponentControllerVerboseLog, "AutoPilotPlugins.APMSensorsComponentController:verbose")
16
18 : FactPanelController(parent)
19{
20 APMAutoPilotPlugin *const apmPlugin = qobject_cast<APMAutoPilotPlugin*>(_vehicle->autopilotPlugin());
21
22 // Find the sensors component
23 for (const QVariant &varVehicleComponent : apmPlugin->vehicleComponents()) {
24 _sensorsComponent = qobject_cast<APMSensorsComponent*>(varVehicleComponent.value<VehicleComponent*>());
25 if (_sensorsComponent) {
26 break;
27 }
28 }
29
30 if (_sensorsComponent) {
32 } else {
33 qCWarning(APMSensorsComponentControllerLog) << "Sensors component is missing";
34 }
35
36}
37
39{
40 _restorePreviousCompassCalFitness();
41}
42
43void APMSensorsComponentController::_appendStatusLog(const QString &text)
44{
45 Q_ASSERT(_statusLog);
46
47 const QString varText = text;
48 (void) QMetaObject::invokeMethod(_statusLog, "append", varText);
49}
50
51void APMSensorsComponentController::_startLogCalibration()
52{
53 _hideAllCalAreas();
54
55 (void) connect(_vehicle, &Vehicle::textMessageReceived, this, &APMSensorsComponentController::_handleTextMessage);
56
57 emit setAllCalButtonsEnabled(false);
58 if ((_calTypeInProgress == QGCMAVLink::CalibrationAccel) || (_calTypeInProgress == QGCMAVLink::CalibrationAPMCompassMot)) {
59 _nextButton->setEnabled(true);
60 }
61 _cancelButton->setEnabled(_calTypeInProgress == QGCMAVLink::CalibrationMag);
62
63 (void) connect(MAVLinkProtocol::instance(), &MAVLinkProtocol::messageReceived, this, &APMSensorsComponentController::_mavlinkMessageReceived);
65}
66
67void APMSensorsComponentController::_startVisualCalibration()
68{
69 emit setAllCalButtonsEnabled(false);
70 _cancelButton->setEnabled(true);
71 _nextButton->setEnabled(false);
72
73 _resetInternalState();
74
75 (void) _progressBar->setProperty("value", 0);
76
77 (void) connect(MAVLinkProtocol::instance(), &MAVLinkProtocol::messageReceived, this, &APMSensorsComponentController::_mavlinkMessageReceived);
79}
80
81void APMSensorsComponentController::_resetInternalState()
82{
83 _orientationCalDownSideDone = true;
84 _orientationCalUpsideDownSideDone = true;
85 _orientationCalLeftSideDone = true;
86 _orientationCalRightSideDone = true;
87 _orientationCalTailDownSideDone = true;
88 _orientationCalNoseDownSideDone = true;
89 _orientationCalDownSideInProgress = false;
90 _orientationCalUpsideDownSideInProgress = false;
91 _orientationCalLeftSideInProgress = false;
92 _orientationCalRightSideInProgress = false;
93 _orientationCalNoseDownSideInProgress = false;
94 _orientationCalTailDownSideInProgress = false;
95 _orientationCalDownSideRotate = false;
96 _orientationCalUpsideDownSideRotate = false;
97 _orientationCalLeftSideRotate = false;
98 _orientationCalRightSideRotate = false;
99 _orientationCalNoseDownSideRotate = false;
100 _orientationCalTailDownSideRotate = false;
101
105}
106
107void APMSensorsComponentController::_stopCalibration(APMSensorsComponentController::StopCalibrationCode code)
108{
109 // Clear mag cal sequencing state first so a reentrant CANCEL ack can't trigger a new START
110 _magCalStartAccepted = false;
111 _magCalCancelBeforeStartPending = false;
112
113 (void) disconnect(MAVLinkProtocol::instance(), &MAVLinkProtocol::messageReceived, this, &APMSensorsComponentController::_mavlinkMessageReceived);
115
116 (void) disconnect(_vehicle, &Vehicle::textMessageReceived, this, &APMSensorsComponentController::_handleTextMessage);
117
118 emit setAllCalButtonsEnabled(true);
119 _nextButton->setEnabled(false);
120 _cancelButton->setEnabled(false);
121
122 if (_calTypeInProgress == QGCMAVLink::CalibrationMag) {
123 _restorePreviousCompassCalFitness();
124 if (code == StopCalibrationFailed) {
125 // ArduPilot keeps streaming the failed MAG_CAL_REPORT until cancelled
126 _vehicle->sendMavCommand(_vehicle->defaultComponentId(), MAV_CMD_DO_CANCEL_MAG_CAL, false /* showError */);
127 }
128 }
129
130 if (code == StopCalibrationSuccess) {
131 _resetInternalState();
132 (void) _progressBar->setProperty("value", 1);
133 if (parameterExists(ParameterManager::defaultComponentId, QStringLiteral("COMPASS_LEARN"))) {
134 getParameterFact(ParameterManager::defaultComponentId, QStringLiteral("COMPASS_LEARN"))->setRawValue(0);
135 }
136 } else {
137 (void) _progressBar->setProperty("value", 0);
138 }
139
140 _waitingForCancel = false;
142
143 _refreshParams();
144
145 const bool succeeded = (code == StopCalibrationSuccess) || (code == StopCalibrationSuccessShowLog);
146 if (succeeded &&
147 ((_calTypeInProgress == QGCMAVLink::CalibrationMag) || (_calTypeInProgress == QGCMAVLink::CalibrationAccel))) {
149 }
150
151 switch (code) {
152 case StopCalibrationSuccess:
153 (void) _orientationCalAreaHelpText->setProperty("text", tr("Calibration complete"));
154 emit resetStatusTextArea();
155 emit calibrationComplete(_calTypeInProgress);
156 break;
157 case StopCalibrationSuccessShowLog:
158 emit calibrationComplete(_calTypeInProgress);
159 break;
160 case StopCalibrationCancelled:
161 emit resetStatusTextArea();
162 _hideAllCalAreas();
163 break;
164 default:
165 // Assume failed
166 _hideAllCalAreas();
167 QGC::showAppMessage(tr("Calibration failed. Calibration log will be displayed."));
168 break;
169 }
170
171 (void) disconnect(_vehicle, &Vehicle::mavCommandResult, this, &APMSensorsComponentController::_mavCommandResult);
172 _calTypeInProgress = QGCMAVLink::CalibrationNone;
174}
175
176void APMSensorsComponentController::_mavCommandResult(int vehicleId, int component, int command, int result, int failureCode)
177{
178 Q_UNUSED(component); Q_UNUSED(failureCode);
179
180 if (_vehicle->id() != vehicleId) {
181 return;
182 }
183
184 switch (command) {
185 case MAV_CMD_DO_CANCEL_MAG_CAL:
186 if (_magCalCancelBeforeStartPending) {
187 // Pre-start flush of stale cal state is complete (result doesn't matter - older
188 // firmwares reject CANCEL when no cal is running). Safe to start the new cal now.
189 _magCalCancelBeforeStartPending = false;
190 _sendStartMagCal();
191 }
192 break;
193 case MAV_CMD_DO_START_MAG_CAL:
194 if (result == MAV_RESULT_ACCEPTED) {
195 _magCalStartAccepted = true;
196 } else {
197 _appendStatusLog(tr("Failed to start compass calibration"));
198 _stopCalibration(StopCalibrationFailed);
199 }
200 break;
201 case MAV_CMD_FIXED_MAG_CAL_YAW:
202 if (result == MAV_RESULT_ACCEPTED) {
203 _appendStatusLog(tr("Successfully completed"));
204 _stopCalibration(StopCalibrationSuccessShowLog);
205 } else {
206 _appendStatusLog(tr("Failed"));
207 _stopCalibration(StopCalibrationFailed);
208 }
209 break;
210 default:
211 break;
212 }
213}
214
216{
217 _calTypeInProgress = QGCMAVLink::CalibrationMag;
218 _magCalStartAccepted = false;
219 _rgCompassCalProgress[0] = 0;
220 _rgCompassCalProgress[1] = 0;
221 _rgCompassCalProgress[2] = 0;
222 _rgCompassCalComplete[0] = false;
223 _rgCompassCalComplete[1] = false;
224 _rgCompassCalComplete[2] = false;
225
226 _startLogCalibration();
227 uint8_t compassBits = 0;
228 if ((getParameterFact(ParameterManager::defaultComponentId, QStringLiteral("COMPASS_DEV_ID"))->rawValue().toInt() > 0) &&
229 getParameterFact(ParameterManager::defaultComponentId, QStringLiteral("COMPASS_USE"))->rawValue().toBool()) {
230 compassBits |= 1 << 0;
231 qCDebug(APMSensorsComponentControllerLog) << "Performing onboard compass cal for compass 1";
232 } else {
233 _rgCompassCalComplete[0] = true;
234 _rgCompassCalSucceeded[0] = true;
235 _rgCompassCalFitness[0] = 0;
236 }
237 if ((getParameterFact(ParameterManager::defaultComponentId, QStringLiteral("COMPASS_DEV_ID2"))->rawValue().toInt() > 0) &&
238 getParameterFact(ParameterManager::defaultComponentId, QStringLiteral("COMPASS_USE2"))->rawValue().toBool()) {
239 compassBits |= 1 << 1;
240 qCDebug(APMSensorsComponentControllerLog) << "Performing onboard compass cal for compass 2";
241 } else {
242 _rgCompassCalComplete[1] = true;
243 _rgCompassCalSucceeded[1] = true;
244 _rgCompassCalFitness[1] = 0;
245 }
246 if ((getParameterFact(ParameterManager::defaultComponentId, QStringLiteral("COMPASS_DEV_ID3"))->rawValue().toInt() > 0) &&
247 getParameterFact(ParameterManager::defaultComponentId, QStringLiteral("COMPASS_USE3"))->rawValue().toBool()) {
248 compassBits |= 1 << 2;
249 qCDebug(APMSensorsComponentControllerLog) << "Performing onboard compass cal for compass 3";
250 } else {
251 _rgCompassCalComplete[2] = true;
252 _rgCompassCalSucceeded[2] = true;
253 _rgCompassCalFitness[2] = 0;
254 }
255
256 // We bump up the fitness value so calibration will always succeed
257 const Fact *const compassCalFitness = getParameterFact(ParameterManager::defaultComponentId, _compassCalFitnessParam);
258 _restoreCompassCalFitness = true;
259 _previousCompassCalFitness = compassCalFitness->rawValue().toFloat();
260 getParameterFact(ParameterManager::defaultComponentId, _compassCalFitnessParam)->setRawValue(100.0);
261
262 _appendStatusLog(tr("Rotate the vehicle randomly around all axes until the progress bar fills all the way to the right."));
263 (void) connect(_vehicle, &Vehicle::mavCommandResult, this, &APMSensorsComponentController::_mavCommandResult, Qt::UniqueConnection);
264
265 // A previously failed cal keeps streaming MAG_CAL_REPORT until cancelled. Flush that stale
266 // state before starting so it can't instantly complete the new calibration. START is sent
267 // from the CANCEL ack handler (_mavCommandResult) so the two commands can't race.
268 _magCalCompassBits = compassBits;
269 _magCalCancelBeforeStartPending = true;
270 _vehicle->sendMavCommand(_vehicle->defaultComponentId(), MAV_CMD_DO_CANCEL_MAG_CAL, false /* showError */);
271}
272
273void APMSensorsComponentController::_sendStartMagCal()
274{
277 MAV_CMD_DO_START_MAG_CAL,
278 true, // showError
279 _magCalCompassBits, // which compass(es) to calibrate
280 0, // no retry on failure
281 1, // save values after complete
282 0, // no delayed start
283 0 // no auto-reboot
284 );
285}
286
288{
289 _calTypeInProgress = QGCMAVLink::CalibrationMag;
290 _startLogCalibration();
291 (void) connect(_vehicle, &Vehicle::mavCommandResult, this, &APMSensorsComponentController::_mavCommandResult, Qt::UniqueConnection);
292 _vehicle->sendMavCommand(_vehicle->defaultComponentId(), MAV_CMD_FIXED_MAG_CAL_YAW, true /* showError */, 0 /* north*/, mask, lat, lon);
293}
294
296{
297 _calTypeInProgress = QGCMAVLink::CalibrationAccel;
298 if (doSimpleAccelCal) {
299 _startLogCalibration();
300 _calTypeInProgress = QGCMAVLink::CalibrationAPMAccelSimple;
301 _vehicle->startCalibration(_calTypeInProgress);
302 return;
303 }
305 _startVisualCalibration();
306 _cancelButton->setEnabled(false);
307 (void) _orientationCalAreaHelpText->setProperty("text", tr("Hold still in the current orientation and press Next when ready"));
308
309 // Reset all progress indication
310 _orientationCalDownSideDone = false;
311 _orientationCalUpsideDownSideDone = false;
312 _orientationCalLeftSideDone = false;
313 _orientationCalRightSideDone = false;
314 _orientationCalTailDownSideDone = false;
315 _orientationCalNoseDownSideDone = false;
316 _orientationCalDownSideInProgress = false;
317 _orientationCalUpsideDownSideInProgress = false;
318 _orientationCalLeftSideInProgress = false;
319 _orientationCalRightSideInProgress = false;
320 _orientationCalNoseDownSideInProgress = false;
321 _orientationCalTailDownSideInProgress = false;
322
323 // Reset all visibility
324 _orientationCalDownSideVisible = false;
325 _orientationCalUpsideDownSideVisible = false;
326 _orientationCalLeftSideVisible = false;
327 _orientationCalRightSideVisible = false;
328 _orientationCalTailDownSideVisible = false;
329 _orientationCalNoseDownSideVisible = false;
330
331 _calTypeInProgress = QGCMAVLink::CalibrationAccel;
332 _orientationCalDownSideVisible = true;
333 _orientationCalUpsideDownSideVisible = true;
334 _orientationCalLeftSideVisible = true;
335 _orientationCalRightSideVisible = true;
336 _orientationCalTailDownSideVisible = true;
337 _orientationCalNoseDownSideVisible = true;
338
342 _updateAndEmitShowOrientationCalArea(true);
343
344 _vehicle->startCalibration(_calTypeInProgress);
345}
346
348{
349 _calTypeInProgress = QGCMAVLink::CalibrationAPMCompassMot;
351 _startLogCalibration();
352 _appendStatusLog(tr("Raise the throttle slowly to between 50% ~ 75% (the props will spin!) for 5 ~ 10 seconds."));
353 _appendStatusLog(tr("Quickly bring the throttle back down to zero"));
354 _appendStatusLog(tr("Press the Next button to complete the calibration"));
355 _vehicle->startCalibration(_calTypeInProgress);
356}
357
359{
360 _calTypeInProgress = QGCMAVLink::CalibrationLevel;
362 _startLogCalibration();
363 _appendStatusLog(tr("Hold the vehicle in its level flight position."));
364 _vehicle->startCalibration(_calTypeInProgress);
365}
366
368{
371 _startLogCalibration();
372 _appendStatusLog(tr("Requesting pressure calibration..."));
373 _vehicle->startCalibration(_calTypeInProgress);
374}
375
377{
378 _calTypeInProgress = QGCMAVLink::CalibrationGyro;
380 _startLogCalibration();
381 _appendStatusLog(tr("Requesting gyro calibration..."));
382 _vehicle->startCalibration(_calTypeInProgress);
383}
384
385void APMSensorsComponentController::_handleTextMessage(int sysid, int componentid, int severity, const QString &text, const QString &description)
386{
387 Q_UNUSED(componentid); Q_UNUSED(severity); Q_UNUSED(description);
388
389 if (sysid != _vehicle->id()) {
390 return;
391 }
392
393 const QString originalMessageText = text;
394 const QString messageText = text.toLower();
395
396 const QStringList hidePrefixList = { QStringLiteral("prearm:"), QStringLiteral("ekf"), QStringLiteral("arm"), QStringLiteral("initialising") };
397 for (const QString &hidePrefix : hidePrefixList) {
398 if (messageText.startsWith(hidePrefix)) {
399 return;
400 }
401 }
402
403 _appendStatusLog(originalMessageText);
404 qCDebug(APMSensorsComponentControllerLog) << originalMessageText << severity;
405}
406
407void APMSensorsComponentController::_refreshParams()
408{
410 QStringLiteral("COMPASS_OFS_X"), QStringLiteral("COMPASS_OFS_Y"), QStringLiteral("COMPASS_OFS_Z"),
411 QStringLiteral("INS_ACCOFFS_X"), QStringLiteral("INS_ACCOFFS_Y"), QStringLiteral("INS_ACCOFFS_Z"),
412 QStringLiteral("COMPASS_*"),
413 QStringLiteral("INS_*"),
414 }, false /* notifyFailure */);
415}
416
417void APMSensorsComponentController::_updateAndEmitShowOrientationCalArea(bool show)
418{
419 _showOrientationCalArea = show;
421}
422
423void APMSensorsComponentController::_hideAllCalAreas()
424{
425 _updateAndEmitShowOrientationCalArea(false);
426}
427
429{
430 _cancelButton->setEnabled(false);
431
432 if (_calTypeInProgress == QGCMAVLink::CalibrationMag) {
433 // Clear pending start first so a reentrant CANCEL ack can't trigger a new START
434 _magCalCancelBeforeStartPending = false;
435 _vehicle->sendMavCommand(_vehicle->defaultComponentId(), MAV_CMD_DO_CANCEL_MAG_CAL, true /* showError */);
436 _stopCalibration(StopCalibrationCancelled);
437 } else {
438 _waitingForCancel = true;
440 // The firmware doesn't always allow us to cancel calibration. The best we can do is wait
441 // for it to timeout.
442 _vehicle->stopCalibration(true /* showError */);
443 }
444}
445
447{
449 if (sharedLink) {
450 mavlink_message_t msg{};
451
452 (void) mavlink_msg_command_ack_pack_chan(
455 sharedLink->mavlinkChannel(),
456 &msg,
457 0, // command
458 1, // result
459 0, // progress
460 0, // result_param2
461 0, // target_system
462 0 // target_component
463 );
464
465 (void) _vehicle->sendMessageOnLinkThreadSafe(sharedLink.get(), msg);
466
467 if (_calTypeInProgress == QGCMAVLink::CalibrationAPMCompassMot) {
468 _stopCalibration(StopCalibrationSuccess);
469 }
470 }
471}
472
474{
475 return _sensorsComponent->compassSetupNeeded();
476}
477
479{
480 return _sensorsComponent->accelSetupNeeded();
481}
482
484{
485 const SharedLinkInterfacePtr sharedLink = _vehicle->vehicleLinkManager()->primaryLink().lock();
486 if (!sharedLink) {
487 return false;
488 }
489
490 return (sharedLink->linkConfiguration()->type() == LinkConfiguration::TypeUdp);
491}
492
493void APMSensorsComponentController::_handleCommandAck(const mavlink_message_t &message)
494{
495 if ((_calTypeInProgress == QGCMAVLink::CalibrationLevel) || (_calTypeInProgress == QGCMAVLink::CalibrationGyro) || (_calTypeInProgress == QGCMAVLink::CalibrationAPMPressureAirspeed) || (_calTypeInProgress == QGCMAVLink::CalibrationAPMAccelSimple)) {
496 mavlink_command_ack_t commandAck{};
497 mavlink_msg_command_ack_decode(&message, &commandAck);
498
499 if (commandAck.command == MAV_CMD_PREFLIGHT_CALIBRATION) {
500 switch (commandAck.result) {
501 case MAV_RESULT_IN_PROGRESS:
502 _appendStatusLog(tr("In progress"));
503 break;
504 case MAV_RESULT_ACCEPTED:
505 _appendStatusLog(tr("Successfully completed"));
506 _stopCalibration(StopCalibrationSuccessShowLog);
507 break;
508 default:
509 _appendStatusLog(tr("Failed"));
510 _stopCalibration(StopCalibrationFailed);
511 break;
512 }
513 }
514 }
515}
516
517void APMSensorsComponentController::_handleMagCalProgress(const mavlink_message_t &message)
518{
519 if ((_calTypeInProgress != QGCMAVLink::CalibrationMag) || !_magCalStartAccepted) {
520 return;
521 }
522
523 mavlink_mag_cal_progress_t magCalProgress{};
524 mavlink_msg_mag_cal_progress_decode(&message, &magCalProgress);
525
526 qCDebug(APMSensorsComponentControllerVerboseLog) << "id:mask:pct"
527 << magCalProgress.compass_id
528 << magCalProgress.cal_mask
529 << magCalProgress.completion_pct;
530
531 // How many compasses are we calibrating?
532 int compassCalCount = 0;
533 for (int i = 0; i < 3; i++) {
534 if (magCalProgress.cal_mask & (1 << i)) {
535 compassCalCount++;
536 }
537 }
538
539 if ((magCalProgress.compass_id < 3) && (compassCalCount != 0)) {
540 // Each compass gets a portion of the overall progress
541 _rgCompassCalProgress[magCalProgress.compass_id] = magCalProgress.completion_pct / compassCalCount;
542 }
543
544 if (_progressBar) {
545 (void) _progressBar->setProperty("value", static_cast<float>(_rgCompassCalProgress[0] + _rgCompassCalProgress[1] + _rgCompassCalProgress[2]) / 100.0);
546 }
547}
548
549void APMSensorsComponentController::_handleMagCalReport(const mavlink_message_t &message)
550{
551 if ((_calTypeInProgress != QGCMAVLink::CalibrationMag) || !_magCalStartAccepted) {
552 return;
553 }
554
555 mavlink_mag_cal_report_t magCalReport{};
556 mavlink_msg_mag_cal_report_decode(&message, &magCalReport);
557
558 qCDebug(APMSensorsComponentControllerVerboseLog) << "id:mask:status:fitness"
559 << magCalReport.compass_id << magCalReport.cal_mask << magCalReport.cal_status << magCalReport.fitness;
560
561 bool additionalCompassCompleted = false;
562 if ((magCalReport.compass_id < 3) && !_rgCompassCalComplete[magCalReport.compass_id]) {
563 if (magCalReport.cal_status == MAG_CAL_SUCCESS) {
564 _appendStatusLog(tr("Compass %1 calibration complete").arg(magCalReport.compass_id));
565 } else {
566 _appendStatusLog(tr("Compass %1 calibration below quality threshold").arg(magCalReport.compass_id));
567 }
568 _rgCompassCalComplete[magCalReport.compass_id] = true;
569 _rgCompassCalSucceeded[magCalReport.compass_id] = (magCalReport.cal_status == MAG_CAL_SUCCESS);
570 _rgCompassCalFitness[magCalReport.compass_id] = magCalReport.fitness;
571 additionalCompassCompleted = true;
572 }
573
574 if (_rgCompassCalComplete[0] && _rgCompassCalComplete[1] &&_rgCompassCalComplete[2]) {
575 for (int i = 0; i < 3; i++) {
576 qCDebug(APMSensorsComponentControllerLog) << QString("Onboard compass call report #%1: succeed:fitness %2:%3").arg(i).arg(_rgCompassCalSucceeded[i]).arg(_rgCompassCalFitness[i]);
577 }
578 emit compass1CalFitnessChanged(_rgCompassCalFitness[0]);
579 emit compass2CalFitnessChanged(_rgCompassCalFitness[1]);
580 emit compass3CalFitnessChanged(_rgCompassCalFitness[2]);
581 emit compass1CalSucceededChanged(_rgCompassCalSucceeded[0]);
582 emit compass2CalSucceededChanged(_rgCompassCalSucceeded[1]);
583 emit compass3CalSucceededChanged(_rgCompassCalSucceeded[2]);
584 if (_rgCompassCalSucceeded[0] && _rgCompassCalSucceeded[1] && _rgCompassCalSucceeded[2]) {
585 _appendStatusLog(tr("All compasses calibrated successfully"));
586 _appendStatusLog(tr("YOU MUST REBOOT YOUR VEHICLE NOW FOR NEW SETTINGS TO TAKE AFFECT"));
587 _stopCalibration(StopCalibrationSuccessShowLog);
588 } else {
589 _appendStatusLog(tr("Compass calibration failed"));
590 _appendStatusLog(tr("YOU MUST REBOOT YOUR VEHICLE NOW AND RETRY COMPASS CALIBRATION PRIOR TO FLIGHT"));
592 _stopCalibration(StopCalibrationFailed);
593 }
594 } else if (additionalCompassCompleted) {
595 _appendStatusLog(tr("Continue rotating..."));
596 }
597}
598
599bool APMSensorsComponentController::_handleCmdLongAccelcalVehiclePos(const mavlink_command_long_t &commandLong)
600{
601 bool updateImages = false;
602
603 switch (static_cast<ACCELCAL_VEHICLE_POS>(static_cast<int>(commandLong.param1))) {
604 case ACCELCAL_VEHICLE_POS_LEVEL:
605 if (!_orientationCalDownSideInProgress) {
606 updateImages = true;
607 _orientationCalDownSideInProgress = true;
608 _nextButton->setEnabled(true);
609 }
610 break;
611 case ACCELCAL_VEHICLE_POS_LEFT:
612 if (!_orientationCalLeftSideInProgress) {
613 updateImages = true;
614 _orientationCalDownSideDone = true;
615 _orientationCalDownSideInProgress = false;
616 _orientationCalLeftSideInProgress = true;
617 (void) _progressBar->setProperty("value", static_cast<qreal>(17 / 100.0));
618 }
619 break;
620 case ACCELCAL_VEHICLE_POS_RIGHT:
621 if (!_orientationCalRightSideInProgress) {
622 updateImages = true;
623 _orientationCalLeftSideDone = true;
624 _orientationCalLeftSideInProgress = false;
625 _orientationCalRightSideInProgress = true;
626 (void) _progressBar->setProperty("value", static_cast<qreal>(34 / 100.0));
627 }
628 break;
629 case ACCELCAL_VEHICLE_POS_NOSEDOWN:
630 if (!_orientationCalNoseDownSideInProgress) {
631 updateImages = true;
632 _orientationCalRightSideDone = true;
633 _orientationCalRightSideInProgress = false;
634 _orientationCalNoseDownSideInProgress = true;
635 (void) _progressBar->setProperty("value", static_cast<qreal>(51 / 100.0));
636 }
637 break;
638 case ACCELCAL_VEHICLE_POS_NOSEUP:
639 if (!_orientationCalTailDownSideInProgress) {
640 updateImages = true;
641 _orientationCalNoseDownSideDone = true;
642 _orientationCalNoseDownSideInProgress = false;
643 _orientationCalTailDownSideInProgress = true;
644 (void) _progressBar->setProperty("value", static_cast<qreal>(68 / 100.0));
645 }
646 break;
647 case ACCELCAL_VEHICLE_POS_BACK:
648 if (!_orientationCalUpsideDownSideInProgress) {
649 updateImages = true;
650 _orientationCalTailDownSideDone = true;
651 _orientationCalTailDownSideInProgress = false;
652 _orientationCalUpsideDownSideInProgress = true;
653 (void) _progressBar->setProperty("value", static_cast<qreal>(85 / 100.0));
654 }
655 break;
656 case ACCELCAL_VEHICLE_POS_SUCCESS:
657 _stopCalibration(StopCalibrationSuccess);
658 break;
659 case ACCELCAL_VEHICLE_POS_FAILED:
660 _stopCalibration(StopCalibrationFailed);
661 break;
662 case ACCELCAL_VEHICLE_POS_ENUM_END:
663 default:
664 break;
665 }
666
667 return updateImages;
668}
669
670void APMSensorsComponentController::_handleCommandLong(const mavlink_message_t &message)
671{
672 bool updateImages = false;
673 mavlink_command_long_t commandLong{};
674
675 mavlink_msg_command_long_decode(&message, &commandLong);
676
677 if (commandLong.command == MAV_CMD_ACCELCAL_VEHICLE_POS) {
678 updateImages = _handleCmdLongAccelcalVehiclePos(commandLong);
679 }
680
681 if (updateImages) {
685 }
686}
687
688void APMSensorsComponentController::_mavlinkMessageReceived(LinkInterface *link, const mavlink_message_t &message)
689{
690 Q_UNUSED(link);
691
692 if (message.sysid != _vehicle->id()) {
693 return;
694 }
695
696 switch (message.msgid) {
697 case MAVLINK_MSG_ID_COMMAND_ACK:
698 _handleCommandAck(message);
699 break;
700 case MAVLINK_MSG_ID_MAG_CAL_PROGRESS:
701 _handleMagCalProgress(message);
702 break;
703 case MAVLINK_MSG_ID_MAG_CAL_REPORT:
704 _handleMagCalReport(message);
705 break;
706 case MAVLINK_MSG_ID_COMMAND_LONG:
707 _handleCommandLong(message);
708 break;
709 }
710}
711
712void APMSensorsComponentController::_restorePreviousCompassCalFitness()
713{
714 if (_restoreCompassCalFitness) {
715 _restoreCompassCalFitness = false;
716 getParameterFact(ParameterManager::defaultComponentId, _compassCalFitnessParam)->setRawValue(_previousCompassCalFitness);
717 }
718}
std::shared_ptr< LinkInterface > SharedLinkInterfacePtr
struct __mavlink_message mavlink_message_t
#define QGC_LOGGING_CATEGORY(name, categoryStr)
struct __mavlink_command_ack_t mavlink_command_ack_t
struct __mavlink_command_long_t mavlink_command_long_t
This is the AutoPilotPlugin implementation for the MAV_AUTOPILOT_ARDUPILOT type.
const QVariantList & vehicleComponents() override
Sensors Component MVC Controller for SensorsComponent.qml.
Q_INVOKABLE void calibrateCompassNorth(float lat, float lon, int mask)
void compass3CalFitnessChanged(double compass3CalFitness)
void compass1CalFitnessChanged(double compass1CalFitness)
void compass2CalFitnessChanged(double compass2CalFitness)
Q_INVOKABLE void calibrateAccel(bool doSimpleAccelCal)
void compass2CalSucceededChanged(bool compass2CalSucceeded)
void setAllCalButtonsEnabled(bool enabled)
void compass3CalSucceededChanged(bool compass3CalSucceeded)
void compass1CalSucceededChanged(bool compass1CalSucceeded)
void calibrationComplete(QGCMAVLink::CalibrationType calType)
Used for handling missing Facts from C++ code.
Q_INVOKABLE Fact * getParameterFact(int componentId, const QString &name, bool reportMissing=true) const
Q_INVOKABLE bool parameterExists(int componentId, const QString &name) const
A Fact is used to hold a single value within the system.
Definition Fact.h:15
void setRawValue(const QVariant &value)
Definition Fact.cc:135
QVariant rawValue() const
Definition Fact.h:87
The link interface defines the interface for all links used to communicate with the ground station ap...
static int getComponentId()
void messageReceived(LinkInterface *link, const mavlink_message_t &message)
static MAVLinkProtocol * instance()
int getSystemId() const
void bulkRefresh(int componentId, const QStringList &names, bool notifyFailure=true)
static constexpr int defaultComponentId
A vehicle component is an object which abstracts the physical portion of a vehicle into a set of conf...
void setupCompleteChanged()
WeakLinkInterfacePtr primaryLink() const
void setCommunicationLostEnabled(bool communicationLostEnabled)
void sendMavCommand(int compId, MAV_CMD command, bool showError, float param1=0.0f, float param2=0.0f, float param3=0.0f, float param4=0.0f, float param5=0.0f, float param6=0.0f, float param7=0.0f)
Definition Vehicle.cc:2173
void textMessageReceived(int sysid, int componentid, int severity, QString text, QString description)
VehicleLinkManager * vehicleLinkManager()
Definition Vehicle.h:597
void setRebootRequired()
Latches rebootRequired until the vehicle reboots.
Definition Vehicle.cc:2355
int id() const
Definition Vehicle.h:443
bool sendMessageOnLinkThreadSafe(LinkInterface *link, mavlink_message_t message)
Definition Vehicle.cc:1401
int defaultComponentId() const
Definition Vehicle.h:700
ParameterManager * parameterManager()
Definition Vehicle.h:595
void startCalibration(QGCMAVLink::CalibrationType calType)
Definition Vehicle.cc:2408
void stopCalibration(bool showError)
Definition Vehicle.cc:2488
void mavCommandResult(int vehicleId, int targetComponent, int command, int ackResult, int failureCode)
void showAppMessage(const QString &message, const QString &title)
Modal application message. Queued if the UI isn't ready yet.
Definition AppMessages.cc:9