12#include <QtCore/QString>
20 , versionNotified(false)
27 const QString manualFlightModeName = tr(
"Manual");
28 const QString acroFlightModeName = tr(
"Acro");
29 const QString stabilizedFlightModeName = tr(
"Stabilized");
30 const QString rattitudeFlightModeName = tr(
"Rattitude");
31 const QString altCtlFlightModeName = tr(
"Altitude");
32 const QString posCtlFlightModeName = tr(
"Position");
33 const QString offboardFlightModeName = tr(
"Offboard");
34 const QString readyFlightModeName = tr(
"Ready");
35 const QString takeoffFlightModeName = tr(
"Takeoff");
36 const QString holdFlightModeName = tr(
"Hold");
37 const QString missionFlightModeName = tr(
"Mission");
38 const QString rtlFlightModeName = tr(
"Return");
39 const QString landingFlightModeName = tr(
"Land");
40 const QString preclandFlightModeName = tr(
"Precision Land");
41 const QString followMeFlightModeName = tr(
"Follow Me");
42 const QString simpleFlightModeName = tr(
"Simple");
43 const QString orbitFlightModeName = tr(
"Orbit");
44 const QString slowFlightModeName = tr(
"Position Slow");
45 const QString altitudeCruiseFlightModeName = tr(
"Altitude Cruise");
46 const QString terminationFlightModeName = tr(
"Termination");
47 const QString vtolTakeoffFlightModeName = tr(
"VTOL Takeoff");
48 const QString guidedCourseFlightModeName = tr(
"Guided Course");
115 QStringList flightModesList;
119 bool fw = (vehicle->
fixedWing() && mode.fixedWing);
120 bool mc = (vehicle->
multiRotor() && mode.multiRotor);
124 if (fw || mc || other) {
125 flightModesList += mode.mode_name;
130 return flightModesList;
137 if (base_mode & MAV_MODE_FLAG_CUSTOM_MODE_ENABLED) {
138 return _modeEnumToString.value(custom_mode, tr(
"Unknown %1:%2").arg(base_mode).arg(custom_mode));
152 if(
flightMode.compare(mode.mode_name, Qt::CaseInsensitive) == 0){
153 *base_mode = MAV_MODE_FLAG_CUSTOM_MODE_ENABLED;
154 *custom_mode = mode.custom_mode;
161 qCWarning(PX4FirmwarePluginLog) <<
"Unknown flight Mode" <<
flightMode;
180 return (capabilities & available) == capabilities;
197 QList<MAV_CMD> supportedCommands = {
198 MAV_CMD_NAV_WAYPOINT,
199 MAV_CMD_NAV_LOITER_UNLIM, MAV_CMD_NAV_LOITER_TIME,
200 MAV_CMD_NAV_RETURN_TO_LAUNCH,
202 MAV_CMD_DO_DIGICAM_CONTROL,
203 MAV_CMD_DO_SET_CAM_TRIGG_DIST,
204 MAV_CMD_DO_SET_SERVO,
205 MAV_CMD_DO_SET_ACTUATOR,
206 MAV_CMD_DO_CHANGE_SPEED,
208 MAV_CMD_DO_LAND_START,
209 MAV_CMD_DO_SET_ROI_LOCATION, MAV_CMD_DO_SET_ROI_WPNEXT_OFFSET, MAV_CMD_DO_SET_ROI_NONE,
210 MAV_CMD_DO_MOUNT_CONFIGURE,
211 MAV_CMD_DO_MOUNT_CONTROL,
212 MAV_CMD_SET_CAMERA_MODE,
213 MAV_CMD_IMAGE_START_CAPTURE, MAV_CMD_IMAGE_STOP_CAPTURE, MAV_CMD_VIDEO_START_CAPTURE, MAV_CMD_VIDEO_STOP_CAPTURE,
215 MAV_CMD_CONDITION_YAW,
216 MAV_CMD_NAV_LOITER_TO_ALT,
220 QList<MAV_CMD> vtolCommands = {
221 MAV_CMD_DO_VTOL_TRANSITION, MAV_CMD_NAV_VTOL_TAKEOFF, MAV_CMD_NAV_VTOL_LAND,
224 QList<MAV_CMD> flightCommands = {
225 MAV_CMD_NAV_LAND, MAV_CMD_NAV_TAKEOFF,
229 supportedCommands += vtolCommands;
230 supportedCommands += flightCommands;
233 supportedCommands += vtolCommands;
234 supportedCommands += flightCommands;
236 supportedCommands += flightCommands;
240 supportedCommands.append(MAV_CMD_CONDITION_GATE);
243 return supportedCommands;
248 switch (vehicleClass) {
250 return QStringLiteral(
":/json/PX4-MavCmdInfoCommon.json");
252 return QStringLiteral(
":/json/PX4-MavCmdInfoFixedWing.json");
254 return QStringLiteral(
":/json/PX4-MavCmdInfoMultiRotor.json");
256 return QStringLiteral(
":/json/PX4-MavCmdInfoVTOL.json");
258 return QStringLiteral(
":/json/PX4-MavCmdInfoSub.json");
260 return QStringLiteral(
":/json/PX4-MavCmdInfoRover.json");
262 qCWarning(PX4FirmwarePluginLog) <<
"PX4FirmwarePlugin::missionCommandOverrides called with bad VehicleClass_t:" << vehicleClass;
275 MAV_CMD_DO_REPOSITION,
278 MAV_DO_REPOSITION_FLAGS_CHANGE_MODE,
297void PX4FirmwarePlugin::_mavCommandResult(
int vehicleId,
int component,
int command,
int result,
int failureCode)
299 Q_UNUSED(vehicleId); Q_UNUSED(component); Q_UNUSED(failureCode);
301 auto* vehicle = qobject_cast<Vehicle*>(sender());
303 qCWarning(PX4FirmwarePluginLog) <<
"Dynamic cast failed!";
307 if (command == MAV_CMD_NAV_TAKEOFF && result == MAV_RESULT_ACCEPTED) {
312 if (!vehicle->armed()) {
313 vehicle->setArmedShowError(
true);
321 if (qIsNaN(vehicleAltitudeAMSL)) {
326 double takeoffAltAMSL = takeoffAltRel + vehicleAltitudeAMSL;
337 static_cast<float>(takeoffAltAMSL));
342 QString speedParam(
"MPC_XY_VEL_MAX");
353 QString airspeedMax(
"FW_AIRSPD_MAX");
364 QString airspeedMin(
"FW_AIRSPD_MIN");
388 Q_UNUSED(forwardFlightLoiterRadius)
395 if (vehicle->
capabilityBits() & MAV_PROTOCOL_CAPABILITY_COMMAND_INT) {
397 MAV_CMD_DO_REPOSITION,
401 MAV_DO_REPOSITION_FLAGS_CHANGE_MODE,
404 gotoCoord.latitude(),
405 gotoCoord.longitude(),
409 MAV_CMD_DO_REPOSITION,
412 MAV_DO_REPOSITION_FLAGS_CHANGE_MODE,
415 static_cast<float>(gotoCoord.latitude()),
416 static_cast<float>(gotoCoord.longitude()),
431 if (ack.result != MAV_RESULT_ACCEPTED) {
432 switch (failureCode) {
434 qCDebug(PX4FirmwarePluginLog) << QStringLiteral(
"MAV_CMD_DO_REPOSITION error(%1)").arg(ack.result);
437 qCDebug(PX4FirmwarePluginLog) <<
"MAV_CMD_DO_REPOSITION no response from vehicle";
440 qCDebug(PX4FirmwarePluginLog) <<
"Internal Error: MAV_CMD_DO_REPOSITION could not be sent due to duplicate command";
453 if (pauseSucceeded) {
456 MAV_CMD_DO_REPOSITION,
459 MAV_DO_REPOSITION_FLAGS_CHANGE_MODE,
461 qQNaN(), qQNaN(), qQNaN(),
482 double newAltRel = currentAltRel + altitudeChange;
485 resultData->
plugin =
this;
497 MAV_CMD_DO_REPOSITION,
499 MAV_DO_REPOSITION_FLAGS_CHANGE_MODE,
501 qQNaN(), qQNaN(), qQNaN(), qQNaN());
512 MAV_CMD_DO_CHANGE_SPEED,
515 static_cast<float>(groundspeed),
526 MAV_CMD_DO_CHANGE_SPEED,
529 static_cast<float>(airspeed_equiv),
542 const float radians = qDegreesToRadians(vehicle->
coordinate().azimuthTo(headingCoord));
546 MAV_CMD_DO_REPOSITION,
549 MAV_DO_REPOSITION_FLAGS_CHANGE_MODE,
643 if (message->compid == MAV_COMP_ID_UDP_BRIDGE) {
647 switch (message->msgid) {
648 case MAVLINK_MSG_ID_AUTOPILOT_VERSION:
649 _handleAutopilotVersion(vehicle, message);
661 if (!instanceData->versionNotified) {
662 bool notifyUser =
false;
663 int supportedMajorVersion = 1;
664 int supportedMinorVersion = 4;
665 int supportedPatchVersion = 1;
667 mavlink_autopilot_version_t version;
668 mavlink_msg_autopilot_version_decode(message, &version);
670 if (version.flight_sw_version != 0) {
671 int majorVersion, minorVersion, patchVersion;
673 majorVersion = (version.flight_sw_version >> (8*3)) & 0xFF;
674 minorVersion = (version.flight_sw_version >> (8*2)) & 0xFF;
675 patchVersion = (version.flight_sw_version >> (8*1)) & 0xFF;
677 if (majorVersion < supportedMajorVersion) {
679 }
else if (majorVersion == supportedMajorVersion) {
680 if (minorVersion < supportedMinorVersion) {
682 }
else if (minorVersion == supportedMinorVersion) {
683 notifyUser = patchVersion < supportedPatchVersion;
691 instanceData->versionNotified =
true;
692 QGC::showAppMessage(tr(
"QGroundControl supports PX4 Pro firmware Version %1.%2.%3 and above. You are using a version prior to that which will lead to unpredictable results. Please upgrade your firmware.").arg(supportedMajorVersion).arg(supportedMinorVersion).arg(supportedPatchVersion));
706QString PX4FirmwarePlugin::_getLatestVersionFileUrl(
Vehicle* vehicle)
const
709 return QStringLiteral(
"https://api.github.com/repos/PX4/Firmware/releases");
712QString PX4FirmwarePlugin::_versionRegex()
const
714 return QStringLiteral(
"v([0-9,\\.]*) Stable");
719 return ((vehicle->
vehicleType() == MAV_TYPE_GROUND_ROVER) || (vehicle->
vehicleType() == MAV_TYPE_SUBMARINE));
724 static const char* HOOBS_HI =
"LND_FLIGHT_T_HI";
725 static const char* HOOBS_LO =
"LND_FLIGHT_T_LO";
726 uint64_t hobbsTimeSeconds = 0;
732 hobbsTimeSeconds = ((uint64_t)factHi->
rawValue().toUInt() << 32 | (uint64_t)factLo->
rawValue().toUInt()) / 1000000;
733 qCDebug(PX4FirmwarePluginLog) <<
"Hobbs Meter raw PX4:" <<
"(" << factHi->
rawValue().toUInt() << factLo->
rawValue().toUInt() <<
")";
736 int hours = hobbsTimeSeconds / 3600;
737 int minutes = (hobbsTimeSeconds % 3600) / 60;
738 int seconds = hobbsTimeSeconds % 60;
739 QString timeStr = QString::asprintf(
"%04d:%02d:%02d", hours, minutes, seconds);
740 qCDebug(PX4FirmwarePluginLog) <<
"Hobbs Meter string:" << timeStr;
755 for(
auto &mode: modeList){
778 mode.multiRotor =
true;
784 mode.multiRotor =
false;
795 mode.fixedWing =
false;
814 mode.fixedWing =
true;
823 if (indicatorName ==
"Battery") {
824 return QVariant::fromValue(QUrl::fromUserInput(
"qrc:/qml/QGroundControl/FirmwarePlugin/PX4/PX4BatteryIndicator.qml"));
825 }
else if (indicatorName ==
"FlightMode") {
826 return QVariant::fromValue(QUrl::fromUserInput(
"qrc:/qml/QGroundControl/FirmwarePlugin/PX4/PX4FlightModeIndicator.qml"));
827 }
else if (indicatorName ==
"MainStatus") {
828 return QVariant::fromValue(QUrl::fromUserInput(
"qrc:/qml/QGroundControl/FirmwarePlugin/PX4/PX4MainStatusIndicator.qml"));
QList< FirmwareFlightMode > FlightModeList
static void _pauseVehicleThenChangeAltResultHandler(void *resultHandlerData, int, const mavlink_command_ack_t &ack, Vehicle::MavCmdResultFailureCode_t failureCode)
struct __mavlink_message mavlink_message_t
#define QGC_LOGGING_CATEGORY(name, categoryStr)
struct __mavlink_command_ack_t mavlink_command_ack_t
The AutoPilotPlugin class is an abstract base class which represents the methods and objects which ar...
A Fact is used to hold a single value within the system.
QVariant rawValue() const
void _setModeEnumToModeStringMapping(FlightModeCustomModeMap enumToString)
FlightModeList _flightModeList
virtual double minimumEquivalentAirspeed(Vehicle *) const
FirmwareCapabilities
Set of optional capabilites which firmware may support.
@ ChangeHeadingCapability
Vehicle supports changing heading at current location.
@ GuidedTakeoffCapability
Vehicle supports guided takeoff.
@ TakeoffVehicleCapability
Vehicle supports taking off.
@ GuidedModeCapability
Vehicle supports guided mode commands.
@ OrbitModeCapability
Vehicle supports orbit mode.
@ SetFlightModeCapability
FirmwarePlugin::setFlightMode method is supported.
@ ROIModeCapability
Vehicle supports ROI (both in Fly guided mode and from Plan creation)
@ PauseVehicleCapability
Vehicle supports pausing at current location.
virtual double maximumEquivalentAirspeed(Vehicle *) const
bool _setFlightModeAndValidate(Vehicle *vehicle, const QString &flightMode) const
void _updateFlightModeList(FlightModeList &flightModeList)
bool _armVehicleAndValidate(Vehicle *vehicle) const
FlightModeCustomModeMap _modeEnumToString
virtual double maximumHorizontalSpeedMultirotorMetersSecond(Vehicle *) const
void initializeVehicle(Vehicle *vehicle) override
Called when Vehicle is first created to perform any firmware specific setup.
bool isCapable(const Vehicle *vehicle, FirmwareCapabilities capabilities) const override
bool adjustIncomingMavlinkMessage(Vehicle *vehicle, mavlink_message_t *message) override
void setGuidedMode(Vehicle *vehicle, bool guidedMode) const override
Set guided flight mode.
QString gotoFlightMode(void) const override
Returns the flight mode which the vehicle will be in if it is performing a goto location.
QList< MAV_CMD > supportedMissionCommands(QGCMAVLink::VehicleClass_t vehicleClass) const override
List of supported mission commands. Empty list for all commands supported.
bool guidedModeGotoLocation(Vehicle *vehicle, const QGeoCoordinate &gotoCoord, double forwardFlightLoiterRadius) const override
QString flightMode(uint8_t base_mode, uint32_t custom_mode) const override
QString takeOffFlightMode(void) const override
Returns the flight mode for TakeOff.
QString pauseFlightMode(void) const override
Returns The flight mode which indicates the vehicle is paused.
virtual ~PX4FirmwarePlugin()
bool sendHomePositionToVehicle(void) const override
bool setFlightMode(const QString &flightMode, uint8_t *base_mode, uint32_t *custom_mode) const override
void startMission(Vehicle *vehicle) const override
Command the vehicle to start the mission.
void updateAvailableFlightModes(FlightModeList &modeList) override
Update Available flight modes received from vehicle.
ParameterMetaData * _createParameterMetaData() final
QString takeControlFlightMode(void) const override
Returns the flight mode to use when the operator wants to take back control from autonomouse flight.
bool fixedWingAirSpeedLimitsAvailable(Vehicle *vehicle) const override
QString missionFlightMode(void) const override
Returns the flight mode for running missions.
void pauseVehicle(Vehicle *vehicle) const override
QString landFlightMode(void) const override
Returns the flight mode for Land.
QString rtlFlightMode(void) const override
Returns the flight mode for RTL.
void guidedModeRTL(Vehicle *vehicle, bool smartRTL) const override
Command vehicle to return to launch.
void guidedModeChangeHeading(Vehicle *vehicle, const QGeoCoordinate &headingCoord) const override
Command vehicle to rotate towards specified location.
uint32_t highLatencyCustomModeTo32Bits(uint16_t hlCustomMode) const override
Convert from HIGH_LATENCY2.custom_mode value to correct 32 bit value.
void startTakeoff(Vehicle *vehicle) const override
Command the vehicle to start a takeoff.
double maximumHorizontalSpeedMultirotorMetersSecond(Vehicle *vehicle) const override
QStringList flightModes(Vehicle *vehicle) const override
QString getHobbsMeter(Vehicle *vehicle) const override
gets hobbs meter from autopilot. This should be reimplmeented for each firmware
bool isGuidedMode(const Vehicle *vehicle) const override
Returns whether the vehicle is in guided mode or not.
void guidedModeTakeoff(Vehicle *vehicle, double takeoffAltRel) const override
Command vehicle to takeoff from current location to the specified height.
QVariant expandedToolbarIndicatorSource(const Vehicle *vehicle, const QString &indicatorName) const override
double minimumEquivalentAirspeed(Vehicle *vehicle) const override
QString followFlightMode(void) const override
Returns the flight mode which the vehicle will be for follow me.
void guidedModeChangeEquivalentAirspeedMetersSecond(Vehicle *vehicle, double airspeed_equiv) const override
bool supportsNegativeThrust(Vehicle *vehicle) const override
bool mulirotorSpeedLimitsAvailable(Vehicle *vehicle) const override
QString missionCommandOverrides(QGCMAVLink::VehicleClass_t vehicleClass) const override
double maximumEquivalentAirspeed(Vehicle *vehicle) const override
void guidedModeChangeAltitude(Vehicle *vehicle, double altitudeRel, bool pauseVehicle) override
QString stabilizedFlightMode(void) const override
Returns the flight mode for Stabilized.
void _changeAltAfterPause(void *resultHandlerData, bool pauseSucceeded)
AutoPilotPlugin * autopilotPlugin(Vehicle *vehicle) const override
bool hasGripper(const Vehicle *vehicle) const override
void guidedModeChangeGroundSpeedMetersSecond(Vehicle *vehicle, double groundspeed) const override
void guidedModeLand(Vehicle *vehicle) const override
Command vehicle to land at current location.
bool parameterExists(int componentId, const QString ¶mName) const
Fact * getParameter(int componentId, const QString ¶mName)
static constexpr int defaultComponentId
static constexpr const VehicleClass_t VehicleClassSub
static constexpr const VehicleClass_t VehicleClassFixedWing
static constexpr const VehicleClass_t VehicleClassMultiRotor
static constexpr const VehicleClass_t VehicleClassRoverBoat
static constexpr const VehicleClass_t VehicleClassVTOL
static SettingsManager * instance()
Fact * altitudeRelative()
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)
QString flightMode() const
QGeoCoordinate homePosition()
void setFirmwarePluginInstanceData(FirmwarePluginInstanceData *firmwarePluginInstanceData)
uint64_t capabilityBits() const
MAV_TYPE vehicleType() const
void sendMavCommandInt(int compId, MAV_CMD command, MAV_FRAME frame, bool showError, float param1, float param2, float param3, float param4, double param5, double param6, float param7)
int defaultComponentId() const
ParameterManager * parameterManager()
QGeoCoordinate coordinate()
void mavCommandResult(int vehicleId, int targetComponent, int command, int ackResult, int failureCode)
class FirmwarePluginInstanceData * firmwarePluginInstanceData()
void sendMavCommandWithHandler(const MavCmdAckHandlerInfo_t *ackHandlerInfo, int compId, MAV_CMD command, 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)
Sends the command and calls the callback with the result.
void showAppMessage(const QString &message, const QString &title)
Modal application message. Queued if the UI isn't ready yet.
PX4FirmwarePlugin * plugin
static constexpr VehicleClass_t VehicleClassGeneric
Callback info bundle for sendMavCommandWithHandler.
MavCmdResultHandler resultHandler
nullptr for no handler
MavCmdResultFailureCode_t
@ MavCmdResultFailureDuplicateCommand
Unable to send command since duplicate is already being waited on for response.
@ MavCmdResultCommandResultOnly
commandResult specifies full success/fail info
@ MavCmdResultFailureNoResponseToCommand
No response from vehicle to command.