12#include <QtCore/QVariant>
14QGC_LOGGING_CATEGORY(APMSensorsComponentControllerLog,
"AutoPilotPlugins.APMSensorsComponentController")
20 APMAutoPilotPlugin *
const apmPlugin = qobject_cast<APMAutoPilotPlugin*>(_vehicle->autopilotPlugin());
24 _sensorsComponent = qobject_cast<APMSensorsComponent*>(varVehicleComponent.value<
VehicleComponent*>());
25 if (_sensorsComponent) {
30 if (_sensorsComponent) {
33 qCWarning(APMSensorsComponentControllerLog) <<
"Sensors component is missing";
40 _restorePreviousCompassCalFitness();
43void APMSensorsComponentController::_appendStatusLog(
const QString &text)
47 const QString varText = text;
48 (void) QMetaObject::invokeMethod(_statusLog,
"append", varText);
51void APMSensorsComponentController::_startLogCalibration()
59 _nextButton->setEnabled(
true);
67void APMSensorsComponentController::_startVisualCalibration()
70 _cancelButton->setEnabled(
true);
71 _nextButton->setEnabled(
false);
73 _resetInternalState();
75 (void) _progressBar->setProperty(
"value", 0);
81void APMSensorsComponentController::_resetInternalState()
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;
107void APMSensorsComponentController::_stopCalibration(APMSensorsComponentController::StopCalibrationCode code)
110 _magCalStartAccepted =
false;
111 _magCalCancelBeforeStartPending =
false;
119 _nextButton->setEnabled(
false);
120 _cancelButton->setEnabled(
false);
123 _restorePreviousCompassCalFitness();
124 if (code == StopCalibrationFailed) {
130 if (code == StopCalibrationSuccess) {
131 _resetInternalState();
132 (void) _progressBar->setProperty(
"value", 1);
137 (void) _progressBar->setProperty(
"value", 0);
140 _waitingForCancel =
false;
146 case StopCalibrationSuccess:
147 (void) _orientationCalAreaHelpText->setProperty(
"text", tr(
"Calibration complete"));
151 case StopCalibrationSuccessShowLog:
154 case StopCalibrationCancelled:
170void APMSensorsComponentController::_mavCommandResult(
int vehicleId,
int component,
int command,
int result,
int failureCode)
172 Q_UNUSED(component); Q_UNUSED(failureCode);
179 case MAV_CMD_DO_CANCEL_MAG_CAL:
180 if (_magCalCancelBeforeStartPending) {
183 _magCalCancelBeforeStartPending =
false;
187 case MAV_CMD_DO_START_MAG_CAL:
188 if (result == MAV_RESULT_ACCEPTED) {
189 _magCalStartAccepted =
true;
191 _appendStatusLog(tr(
"Failed to start compass calibration"));
192 _stopCalibration(StopCalibrationFailed);
195 case MAV_CMD_FIXED_MAG_CAL_YAW:
196 if (result == MAV_RESULT_ACCEPTED) {
197 _appendStatusLog(tr(
"Successfully completed"));
198 _stopCalibration(StopCalibrationSuccessShowLog);
200 _appendStatusLog(tr(
"Failed"));
201 _stopCalibration(StopCalibrationFailed);
212 _magCalStartAccepted =
false;
213 _rgCompassCalProgress[0] = 0;
214 _rgCompassCalProgress[1] = 0;
215 _rgCompassCalProgress[2] = 0;
216 _rgCompassCalComplete[0] =
false;
217 _rgCompassCalComplete[1] =
false;
218 _rgCompassCalComplete[2] =
false;
220 _startLogCalibration();
221 uint8_t compassBits = 0;
224 compassBits |= 1 << 0;
225 qCDebug(APMSensorsComponentControllerLog) <<
"Performing onboard compass cal for compass 1";
227 _rgCompassCalComplete[0] =
true;
228 _rgCompassCalSucceeded[0] =
true;
229 _rgCompassCalFitness[0] = 0;
233 compassBits |= 1 << 1;
234 qCDebug(APMSensorsComponentControllerLog) <<
"Performing onboard compass cal for compass 2";
236 _rgCompassCalComplete[1] =
true;
237 _rgCompassCalSucceeded[1] =
true;
238 _rgCompassCalFitness[1] = 0;
242 compassBits |= 1 << 2;
243 qCDebug(APMSensorsComponentControllerLog) <<
"Performing onboard compass cal for compass 3";
245 _rgCompassCalComplete[2] =
true;
246 _rgCompassCalSucceeded[2] =
true;
247 _rgCompassCalFitness[2] = 0;
252 _restoreCompassCalFitness =
true;
253 _previousCompassCalFitness = compassCalFitness->
rawValue().toFloat();
256 _appendStatusLog(tr(
"Rotate the vehicle randomly around all axes until the progress bar fills all the way to the right."));
262 _magCalCompassBits = compassBits;
263 _magCalCancelBeforeStartPending =
true;
267void APMSensorsComponentController::_sendStartMagCal()
271 MAV_CMD_DO_START_MAG_CAL,
284 _startLogCalibration();
292 if (doSimpleAccelCal) {
293 _startLogCalibration();
299 _startVisualCalibration();
300 _cancelButton->setEnabled(
false);
301 (void) _orientationCalAreaHelpText->setProperty(
"text", tr(
"Hold still in the current orientation and press Next when ready"));
304 _orientationCalDownSideDone =
false;
305 _orientationCalUpsideDownSideDone =
false;
306 _orientationCalLeftSideDone =
false;
307 _orientationCalRightSideDone =
false;
308 _orientationCalTailDownSideDone =
false;
309 _orientationCalNoseDownSideDone =
false;
310 _orientationCalDownSideInProgress =
false;
311 _orientationCalUpsideDownSideInProgress =
false;
312 _orientationCalLeftSideInProgress =
false;
313 _orientationCalRightSideInProgress =
false;
314 _orientationCalNoseDownSideInProgress =
false;
315 _orientationCalTailDownSideInProgress =
false;
318 _orientationCalDownSideVisible =
false;
319 _orientationCalUpsideDownSideVisible =
false;
320 _orientationCalLeftSideVisible =
false;
321 _orientationCalRightSideVisible =
false;
322 _orientationCalTailDownSideVisible =
false;
323 _orientationCalNoseDownSideVisible =
false;
326 _orientationCalDownSideVisible =
true;
327 _orientationCalUpsideDownSideVisible =
true;
328 _orientationCalLeftSideVisible =
true;
329 _orientationCalRightSideVisible =
true;
330 _orientationCalTailDownSideVisible =
true;
331 _orientationCalNoseDownSideVisible =
true;
336 _updateAndEmitShowOrientationCalArea(
true);
345 _startLogCalibration();
346 _appendStatusLog(tr(
"Raise the throttle slowly to between 50% ~ 75% (the props will spin!) for 5 ~ 10 seconds."));
347 _appendStatusLog(tr(
"Quickly bring the throttle back down to zero"));
348 _appendStatusLog(tr(
"Press the Next button to complete the calibration"));
356 _startLogCalibration();
357 _appendStatusLog(tr(
"Hold the vehicle in its level flight position."));
365 _startLogCalibration();
366 _appendStatusLog(tr(
"Requesting pressure calibration..."));
374 _startLogCalibration();
375 _appendStatusLog(tr(
"Requesting gyro calibration..."));
379void APMSensorsComponentController::_handleTextMessage(
int sysid,
int componentid,
int severity,
const QString &text,
const QString &description)
381 Q_UNUSED(componentid); Q_UNUSED(severity); Q_UNUSED(description);
387 const QString originalMessageText = text;
388 const QString messageText = text.toLower();
390 const QStringList hidePrefixList = { QStringLiteral(
"prearm:"), QStringLiteral(
"ekf"), QStringLiteral(
"arm"), QStringLiteral(
"initialising") };
391 for (
const QString &hidePrefix : hidePrefixList) {
392 if (messageText.startsWith(hidePrefix)) {
397 _appendStatusLog(originalMessageText);
398 qCDebug(APMSensorsComponentControllerLog) << originalMessageText << severity;
401void APMSensorsComponentController::_refreshParams()
404 QStringLiteral(
"COMPASS_OFS_X"), QStringLiteral(
"COMPASS_OFS_Y"), QStringLiteral(
"COMPASS_OFS_Z"),
405 QStringLiteral(
"INS_ACCOFFS_X"), QStringLiteral(
"INS_ACCOFFS_Y"), QStringLiteral(
"INS_ACCOFFS_Z"),
406 QStringLiteral(
"COMPASS_*"),
407 QStringLiteral(
"INS_*"),
411void APMSensorsComponentController::_updateAndEmitShowOrientationCalArea(
bool show)
413 _showOrientationCalArea = show;
417void APMSensorsComponentController::_hideAllCalAreas()
419 _updateAndEmitShowOrientationCalArea(
false);
424 _cancelButton->setEnabled(
false);
428 _magCalCancelBeforeStartPending =
false;
430 _stopCalibration(StopCalibrationCancelled);
432 _waitingForCancel =
true;
446 (void) mavlink_msg_command_ack_pack_chan(
449 sharedLink->mavlinkChannel(),
462 _stopCalibration(StopCalibrationSuccess);
487void APMSensorsComponentController::_handleCommandAck(
const mavlink_message_t &message)
491 mavlink_msg_command_ack_decode(&message, &commandAck);
493 if (commandAck.command == MAV_CMD_PREFLIGHT_CALIBRATION) {
494 switch (commandAck.result) {
495 case MAV_RESULT_IN_PROGRESS:
496 _appendStatusLog(tr(
"In progress"));
498 case MAV_RESULT_ACCEPTED:
499 _appendStatusLog(tr(
"Successfully completed"));
500 _stopCalibration(StopCalibrationSuccessShowLog);
503 _appendStatusLog(tr(
"Failed"));
504 _stopCalibration(StopCalibrationFailed);
511void APMSensorsComponentController::_handleMagCalProgress(
const mavlink_message_t &message)
517 mavlink_mag_cal_progress_t magCalProgress{};
518 mavlink_msg_mag_cal_progress_decode(&message, &magCalProgress);
520 qCDebug(APMSensorsComponentControllerVerboseLog) <<
"id:mask:pct"
521 << magCalProgress.compass_id
522 << magCalProgress.cal_mask
523 << magCalProgress.completion_pct;
526 int compassCalCount = 0;
527 for (
int i = 0; i < 3; i++) {
528 if (magCalProgress.cal_mask & (1 << i)) {
533 if ((magCalProgress.compass_id < 3) && (compassCalCount != 0)) {
535 _rgCompassCalProgress[magCalProgress.compass_id] = magCalProgress.completion_pct / compassCalCount;
539 (void) _progressBar->setProperty(
"value",
static_cast<float>(_rgCompassCalProgress[0] + _rgCompassCalProgress[1] + _rgCompassCalProgress[2]) / 100.0);
543void APMSensorsComponentController::_handleMagCalReport(
const mavlink_message_t &message)
549 mavlink_mag_cal_report_t magCalReport{};
550 mavlink_msg_mag_cal_report_decode(&message, &magCalReport);
552 qCDebug(APMSensorsComponentControllerVerboseLog) <<
"id:mask:status:fitness"
553 << magCalReport.compass_id << magCalReport.cal_mask << magCalReport.cal_status << magCalReport.fitness;
555 bool additionalCompassCompleted =
false;
556 if ((magCalReport.compass_id < 3) && !_rgCompassCalComplete[magCalReport.compass_id]) {
557 if (magCalReport.cal_status == MAG_CAL_SUCCESS) {
558 _appendStatusLog(tr(
"Compass %1 calibration complete").arg(magCalReport.compass_id));
560 _appendStatusLog(tr(
"Compass %1 calibration below quality threshold").arg(magCalReport.compass_id));
562 _rgCompassCalComplete[magCalReport.compass_id] =
true;
563 _rgCompassCalSucceeded[magCalReport.compass_id] = (magCalReport.cal_status == MAG_CAL_SUCCESS);
564 _rgCompassCalFitness[magCalReport.compass_id] = magCalReport.fitness;
565 additionalCompassCompleted =
true;
568 if (_rgCompassCalComplete[0] && _rgCompassCalComplete[1] &&_rgCompassCalComplete[2]) {
569 for (
int i = 0; i < 3; i++) {
570 qCDebug(APMSensorsComponentControllerLog) << QString(
"Onboard compass call report #%1: succeed:fitness %2:%3").arg(i).arg(_rgCompassCalSucceeded[i]).arg(_rgCompassCalFitness[i]);
578 if (_rgCompassCalSucceeded[0] && _rgCompassCalSucceeded[1] && _rgCompassCalSucceeded[2]) {
579 _appendStatusLog(tr(
"All compasses calibrated successfully"));
580 _appendStatusLog(tr(
"YOU MUST REBOOT YOUR VEHICLE NOW FOR NEW SETTINGS TO TAKE AFFECT"));
581 _stopCalibration(StopCalibrationSuccessShowLog);
583 _appendStatusLog(tr(
"Compass calibration failed"));
584 _appendStatusLog(tr(
"YOU MUST REBOOT YOUR VEHICLE NOW AND RETRY COMPASS CALIBRATION PRIOR TO FLIGHT"));
585 _stopCalibration(StopCalibrationFailed);
587 }
else if (additionalCompassCompleted) {
588 _appendStatusLog(tr(
"Continue rotating..."));
592bool APMSensorsComponentController::_handleCmdLongAccelcalVehiclePos(
const mavlink_command_long_t &commandLong)
594 bool updateImages =
false;
596 switch (
static_cast<ACCELCAL_VEHICLE_POS
>(
static_cast<int>(commandLong.param1))) {
597 case ACCELCAL_VEHICLE_POS_LEVEL:
598 if (!_orientationCalDownSideInProgress) {
600 _orientationCalDownSideInProgress =
true;
601 _nextButton->setEnabled(
true);
604 case ACCELCAL_VEHICLE_POS_LEFT:
605 if (!_orientationCalLeftSideInProgress) {
607 _orientationCalDownSideDone =
true;
608 _orientationCalDownSideInProgress =
false;
609 _orientationCalLeftSideInProgress =
true;
610 (void) _progressBar->setProperty(
"value",
static_cast<qreal
>(17 / 100.0));
613 case ACCELCAL_VEHICLE_POS_RIGHT:
614 if (!_orientationCalRightSideInProgress) {
616 _orientationCalLeftSideDone =
true;
617 _orientationCalLeftSideInProgress =
false;
618 _orientationCalRightSideInProgress =
true;
619 (void) _progressBar->setProperty(
"value",
static_cast<qreal
>(34 / 100.0));
622 case ACCELCAL_VEHICLE_POS_NOSEDOWN:
623 if (!_orientationCalNoseDownSideInProgress) {
625 _orientationCalRightSideDone =
true;
626 _orientationCalRightSideInProgress =
false;
627 _orientationCalNoseDownSideInProgress =
true;
628 (void) _progressBar->setProperty(
"value",
static_cast<qreal
>(51 / 100.0));
631 case ACCELCAL_VEHICLE_POS_NOSEUP:
632 if (!_orientationCalTailDownSideInProgress) {
634 _orientationCalNoseDownSideDone =
true;
635 _orientationCalNoseDownSideInProgress =
false;
636 _orientationCalTailDownSideInProgress =
true;
637 (void) _progressBar->setProperty(
"value",
static_cast<qreal
>(68 / 100.0));
640 case ACCELCAL_VEHICLE_POS_BACK:
641 if (!_orientationCalUpsideDownSideInProgress) {
643 _orientationCalTailDownSideDone =
true;
644 _orientationCalTailDownSideInProgress =
false;
645 _orientationCalUpsideDownSideInProgress =
true;
646 (void) _progressBar->setProperty(
"value",
static_cast<qreal
>(85 / 100.0));
649 case ACCELCAL_VEHICLE_POS_SUCCESS:
650 _stopCalibration(StopCalibrationSuccess);
652 case ACCELCAL_VEHICLE_POS_FAILED:
653 _stopCalibration(StopCalibrationFailed);
655 case ACCELCAL_VEHICLE_POS_ENUM_END:
663void APMSensorsComponentController::_handleCommandLong(
const mavlink_message_t &message)
665 bool updateImages =
false;
668 mavlink_msg_command_long_decode(&message, &commandLong);
670 if (commandLong.command == MAV_CMD_ACCELCAL_VEHICLE_POS) {
671 updateImages = _handleCmdLongAccelcalVehiclePos(commandLong);
689 switch (message.msgid) {
690 case MAVLINK_MSG_ID_COMMAND_ACK:
691 _handleCommandAck(message);
693 case MAVLINK_MSG_ID_MAG_CAL_PROGRESS:
694 _handleMagCalProgress(message);
696 case MAVLINK_MSG_ID_MAG_CAL_REPORT:
697 _handleMagCalReport(message);
699 case MAVLINK_MSG_ID_COMMAND_LONG:
700 _handleCommandLong(message);
705void APMSensorsComponentController::_restorePreviousCompassCalFitness()
707 if (_restoreCompassCalFitness) {
708 _restoreCompassCalFitness =
false;
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 waitingForCancelChanged()
void compass3CalFitnessChanged(double compass3CalFitness)
void compass1CalFitnessChanged(double compass1CalFitness)
Q_INVOKABLE void nextClicked()
void showOrientationCalAreaChanged()
void compass2CalFitnessChanged(double compass2CalFitness)
Q_INVOKABLE void calibrateAccel(bool doSimpleAccelCal)
void calibrationActiveChanged()
Q_INVOKABLE bool usingUDPLink() const
void compass2CalSucceededChanged(bool compass2CalSucceeded)
Q_INVOKABLE void cancelCalibration()
Q_INVOKABLE void calibrateMotorInterference()
~APMSensorsComponentController()
bool accelSetupNeeded() const
Q_INVOKABLE void calibrateCompass()
Q_INVOKABLE void levelHorizon()
void orientationCalSidesInProgressChanged()
void setAllCalButtonsEnabled(bool enabled)
void compass3CalSucceededChanged(bool compass3CalSucceeded)
void setupNeededChanged()
void compass1CalSucceededChanged(bool compass1CalSucceeded)
Q_INVOKABLE void calibrateGyro()
Q_INVOKABLE void calibratePressure()
void calibrationComplete(QGCMAVLink::CalibrationType calType)
void orientationCalSidesDoneChanged()
void resetStatusTextArea()
void orientationCalSidesRotateChanged()
bool compassSetupNeeded() const
void orientationCalSidesVisibleChanged()
bool accelSetupNeeded() const
bool compassSetupNeeded() const
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.
void setRawValue(const QVariant &value)
QVariant rawValue() const
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()
void bulkRefresh(int componentId, const QStringList &names, bool notifyFailure=true)
static constexpr int defaultComponentId
@ CalibrationAPMPressureAirspeed
@ CalibrationAPMAccelSimple
@ CalibrationAPMCompassMot
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)
void textMessageReceived(int sysid, int componentid, int severity, QString text, QString description)
VehicleLinkManager * vehicleLinkManager()
bool sendMessageOnLinkThreadSafe(LinkInterface *link, mavlink_message_t message)
int defaultComponentId() const
ParameterManager * parameterManager()
void startCalibration(QGCMAVLink::CalibrationType calType)
void stopCalibration(bool showError)
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.