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;
145 const bool succeeded = (code == StopCalibrationSuccess) || (code == StopCalibrationSuccessShowLog);
152 case StopCalibrationSuccess:
153 (void) _orientationCalAreaHelpText->setProperty(
"text", tr(
"Calibration complete"));
157 case StopCalibrationSuccessShowLog:
160 case StopCalibrationCancelled:
176void APMSensorsComponentController::_mavCommandResult(
int vehicleId,
int component,
int command,
int result,
int failureCode)
178 Q_UNUSED(component); Q_UNUSED(failureCode);
185 case MAV_CMD_DO_CANCEL_MAG_CAL:
186 if (_magCalCancelBeforeStartPending) {
189 _magCalCancelBeforeStartPending =
false;
193 case MAV_CMD_DO_START_MAG_CAL:
194 if (result == MAV_RESULT_ACCEPTED) {
195 _magCalStartAccepted =
true;
197 _appendStatusLog(tr(
"Failed to start compass calibration"));
198 _stopCalibration(StopCalibrationFailed);
201 case MAV_CMD_FIXED_MAG_CAL_YAW:
202 if (result == MAV_RESULT_ACCEPTED) {
203 _appendStatusLog(tr(
"Successfully completed"));
204 _stopCalibration(StopCalibrationSuccessShowLog);
206 _appendStatusLog(tr(
"Failed"));
207 _stopCalibration(StopCalibrationFailed);
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;
226 _startLogCalibration();
227 uint8_t compassBits = 0;
230 compassBits |= 1 << 0;
231 qCDebug(APMSensorsComponentControllerLog) <<
"Performing onboard compass cal for compass 1";
233 _rgCompassCalComplete[0] =
true;
234 _rgCompassCalSucceeded[0] =
true;
235 _rgCompassCalFitness[0] = 0;
239 compassBits |= 1 << 1;
240 qCDebug(APMSensorsComponentControllerLog) <<
"Performing onboard compass cal for compass 2";
242 _rgCompassCalComplete[1] =
true;
243 _rgCompassCalSucceeded[1] =
true;
244 _rgCompassCalFitness[1] = 0;
248 compassBits |= 1 << 2;
249 qCDebug(APMSensorsComponentControllerLog) <<
"Performing onboard compass cal for compass 3";
251 _rgCompassCalComplete[2] =
true;
252 _rgCompassCalSucceeded[2] =
true;
253 _rgCompassCalFitness[2] = 0;
258 _restoreCompassCalFitness =
true;
259 _previousCompassCalFitness = compassCalFitness->
rawValue().toFloat();
262 _appendStatusLog(tr(
"Rotate the vehicle randomly around all axes until the progress bar fills all the way to the right."));
268 _magCalCompassBits = compassBits;
269 _magCalCancelBeforeStartPending =
true;
273void APMSensorsComponentController::_sendStartMagCal()
277 MAV_CMD_DO_START_MAG_CAL,
290 _startLogCalibration();
298 if (doSimpleAccelCal) {
299 _startLogCalibration();
305 _startVisualCalibration();
306 _cancelButton->setEnabled(
false);
307 (void) _orientationCalAreaHelpText->setProperty(
"text", tr(
"Hold still in the current orientation and press Next when ready"));
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;
324 _orientationCalDownSideVisible =
false;
325 _orientationCalUpsideDownSideVisible =
false;
326 _orientationCalLeftSideVisible =
false;
327 _orientationCalRightSideVisible =
false;
328 _orientationCalTailDownSideVisible =
false;
329 _orientationCalNoseDownSideVisible =
false;
332 _orientationCalDownSideVisible =
true;
333 _orientationCalUpsideDownSideVisible =
true;
334 _orientationCalLeftSideVisible =
true;
335 _orientationCalRightSideVisible =
true;
336 _orientationCalTailDownSideVisible =
true;
337 _orientationCalNoseDownSideVisible =
true;
342 _updateAndEmitShowOrientationCalArea(
true);
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"));
362 _startLogCalibration();
363 _appendStatusLog(tr(
"Hold the vehicle in its level flight position."));
371 _startLogCalibration();
372 _appendStatusLog(tr(
"Requesting pressure calibration..."));
380 _startLogCalibration();
381 _appendStatusLog(tr(
"Requesting gyro calibration..."));
385void APMSensorsComponentController::_handleTextMessage(
int sysid,
int componentid,
int severity,
const QString &text,
const QString &description)
387 Q_UNUSED(componentid); Q_UNUSED(severity); Q_UNUSED(description);
393 const QString originalMessageText = text;
394 const QString messageText = text.toLower();
396 const QStringList hidePrefixList = { QStringLiteral(
"prearm:"), QStringLiteral(
"ekf"), QStringLiteral(
"arm"), QStringLiteral(
"initialising") };
397 for (
const QString &hidePrefix : hidePrefixList) {
398 if (messageText.startsWith(hidePrefix)) {
403 _appendStatusLog(originalMessageText);
404 qCDebug(APMSensorsComponentControllerLog) << originalMessageText << severity;
407void APMSensorsComponentController::_refreshParams()
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_*"),
417void APMSensorsComponentController::_updateAndEmitShowOrientationCalArea(
bool show)
419 _showOrientationCalArea = show;
423void APMSensorsComponentController::_hideAllCalAreas()
425 _updateAndEmitShowOrientationCalArea(
false);
430 _cancelButton->setEnabled(
false);
434 _magCalCancelBeforeStartPending =
false;
436 _stopCalibration(StopCalibrationCancelled);
438 _waitingForCancel =
true;
452 (void) mavlink_msg_command_ack_pack_chan(
455 sharedLink->mavlinkChannel(),
468 _stopCalibration(StopCalibrationSuccess);
493void APMSensorsComponentController::_handleCommandAck(
const mavlink_message_t &message)
497 mavlink_msg_command_ack_decode(&message, &commandAck);
499 if (commandAck.command == MAV_CMD_PREFLIGHT_CALIBRATION) {
500 switch (commandAck.result) {
501 case MAV_RESULT_IN_PROGRESS:
502 _appendStatusLog(tr(
"In progress"));
504 case MAV_RESULT_ACCEPTED:
505 _appendStatusLog(tr(
"Successfully completed"));
506 _stopCalibration(StopCalibrationSuccessShowLog);
509 _appendStatusLog(tr(
"Failed"));
510 _stopCalibration(StopCalibrationFailed);
517void APMSensorsComponentController::_handleMagCalProgress(
const mavlink_message_t &message)
523 mavlink_mag_cal_progress_t magCalProgress{};
524 mavlink_msg_mag_cal_progress_decode(&message, &magCalProgress);
526 qCDebug(APMSensorsComponentControllerVerboseLog) <<
"id:mask:pct"
527 << magCalProgress.compass_id
528 << magCalProgress.cal_mask
529 << magCalProgress.completion_pct;
532 int compassCalCount = 0;
533 for (
int i = 0; i < 3; i++) {
534 if (magCalProgress.cal_mask & (1 << i)) {
539 if ((magCalProgress.compass_id < 3) && (compassCalCount != 0)) {
541 _rgCompassCalProgress[magCalProgress.compass_id] = magCalProgress.completion_pct / compassCalCount;
545 (void) _progressBar->setProperty(
"value",
static_cast<float>(_rgCompassCalProgress[0] + _rgCompassCalProgress[1] + _rgCompassCalProgress[2]) / 100.0);
549void APMSensorsComponentController::_handleMagCalReport(
const mavlink_message_t &message)
555 mavlink_mag_cal_report_t magCalReport{};
556 mavlink_msg_mag_cal_report_decode(&message, &magCalReport);
558 qCDebug(APMSensorsComponentControllerVerboseLog) <<
"id:mask:status:fitness"
559 << magCalReport.compass_id << magCalReport.cal_mask << magCalReport.cal_status << magCalReport.fitness;
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));
566 _appendStatusLog(tr(
"Compass %1 calibration below quality threshold").arg(magCalReport.compass_id));
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;
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]);
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);
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);
594 }
else if (additionalCompassCompleted) {
595 _appendStatusLog(tr(
"Continue rotating..."));
599bool APMSensorsComponentController::_handleCmdLongAccelcalVehiclePos(
const mavlink_command_long_t &commandLong)
601 bool updateImages =
false;
603 switch (
static_cast<ACCELCAL_VEHICLE_POS
>(
static_cast<int>(commandLong.param1))) {
604 case ACCELCAL_VEHICLE_POS_LEVEL:
605 if (!_orientationCalDownSideInProgress) {
607 _orientationCalDownSideInProgress =
true;
608 _nextButton->setEnabled(
true);
611 case ACCELCAL_VEHICLE_POS_LEFT:
612 if (!_orientationCalLeftSideInProgress) {
614 _orientationCalDownSideDone =
true;
615 _orientationCalDownSideInProgress =
false;
616 _orientationCalLeftSideInProgress =
true;
617 (void) _progressBar->setProperty(
"value",
static_cast<qreal
>(17 / 100.0));
620 case ACCELCAL_VEHICLE_POS_RIGHT:
621 if (!_orientationCalRightSideInProgress) {
623 _orientationCalLeftSideDone =
true;
624 _orientationCalLeftSideInProgress =
false;
625 _orientationCalRightSideInProgress =
true;
626 (void) _progressBar->setProperty(
"value",
static_cast<qreal
>(34 / 100.0));
629 case ACCELCAL_VEHICLE_POS_NOSEDOWN:
630 if (!_orientationCalNoseDownSideInProgress) {
632 _orientationCalRightSideDone =
true;
633 _orientationCalRightSideInProgress =
false;
634 _orientationCalNoseDownSideInProgress =
true;
635 (void) _progressBar->setProperty(
"value",
static_cast<qreal
>(51 / 100.0));
638 case ACCELCAL_VEHICLE_POS_NOSEUP:
639 if (!_orientationCalTailDownSideInProgress) {
641 _orientationCalNoseDownSideDone =
true;
642 _orientationCalNoseDownSideInProgress =
false;
643 _orientationCalTailDownSideInProgress =
true;
644 (void) _progressBar->setProperty(
"value",
static_cast<qreal
>(68 / 100.0));
647 case ACCELCAL_VEHICLE_POS_BACK:
648 if (!_orientationCalUpsideDownSideInProgress) {
650 _orientationCalTailDownSideDone =
true;
651 _orientationCalTailDownSideInProgress =
false;
652 _orientationCalUpsideDownSideInProgress =
true;
653 (void) _progressBar->setProperty(
"value",
static_cast<qreal
>(85 / 100.0));
656 case ACCELCAL_VEHICLE_POS_SUCCESS:
657 _stopCalibration(StopCalibrationSuccess);
659 case ACCELCAL_VEHICLE_POS_FAILED:
660 _stopCalibration(StopCalibrationFailed);
662 case ACCELCAL_VEHICLE_POS_ENUM_END:
670void APMSensorsComponentController::_handleCommandLong(
const mavlink_message_t &message)
672 bool updateImages =
false;
675 mavlink_msg_command_long_decode(&message, &commandLong);
677 if (commandLong.command == MAV_CMD_ACCELCAL_VEHICLE_POS) {
678 updateImages = _handleCmdLongAccelcalVehiclePos(commandLong);
696 switch (message.msgid) {
697 case MAVLINK_MSG_ID_COMMAND_ACK:
698 _handleCommandAck(message);
700 case MAVLINK_MSG_ID_MAG_CAL_PROGRESS:
701 _handleMagCalProgress(message);
703 case MAVLINK_MSG_ID_MAG_CAL_REPORT:
704 _handleMagCalReport(message);
706 case MAVLINK_MSG_ID_COMMAND_LONG:
707 _handleCommandLong(message);
712void APMSensorsComponentController::_restorePreviousCompassCalFitness()
714 if (_restoreCompassCalFitness) {
715 _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()
void setRebootRequired()
Latches rebootRequired until the vehicle reboots.
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.