diff --git a/qgroundcontrol.qrc b/qgroundcontrol.qrc
index bf22c447445..de282e5fe87 100644
--- a/qgroundcontrol.qrc
+++ b/qgroundcontrol.qrc
@@ -406,6 +406,7 @@
src/Vehicle/FactGroups/SetpointFact.json
src/Vehicle/FactGroups/LocalPositionFact.json
src/Vehicle/FactGroups/LocalPositionFact.json
+ src/Vehicle/FactGroups/RPMFact.json
src/Vehicle/FactGroups/SubmarineFact.json
src/Vehicle/FactGroups/TemperatureFact.json
src/Vehicle/FactGroups/TerrainFactGroup.json
diff --git a/src/Vehicle/FactGroups/CMakeLists.txt b/src/Vehicle/FactGroups/CMakeLists.txt
index dfcf902457e..4c8ecb9625f 100644
--- a/src/Vehicle/FactGroups/CMakeLists.txt
+++ b/src/Vehicle/FactGroups/CMakeLists.txt
@@ -27,6 +27,8 @@ qt_add_library(VehicleFactGroups STATIC
VehicleLocalPositionFactGroup.h
VehicleLocalPositionSetpointFactGroup.cc
VehicleLocalPositionSetpointFactGroup.h
+ VehicleRPMFactGroup.cc
+ VehicleRPMFactGroup.h
VehicleSetpointFactGroup.cc
VehicleSetpointFactGroup.h
VehicleTemperatureFactGroup.cc
diff --git a/src/Vehicle/FactGroups/RPMFact.json b/src/Vehicle/FactGroups/RPMFact.json
new file mode 100644
index 00000000000..ae5aeab6a35
--- /dev/null
+++ b/src/Vehicle/FactGroups/RPMFact.json
@@ -0,0 +1,35 @@
+{
+ "version": 1,
+ "fileType": "FactMetaData",
+ "QGC.MetaData.Facts":
+ [
+ {
+ "name": "rpm1",
+ "shortDesc": "RPM 1",
+ "type": "double",
+ "decimalPlaces": 2,
+ "units": "rpm"
+ },
+ {
+ "name": "rpm2",
+ "shortDesc": "RPM 2",
+ "type": "double",
+ "decimalPlaces": 2,
+ "units": "rpm"
+ },
+ {
+ "name": "rpm3",
+ "shortDesc": "RPM 3",
+ "type": "double",
+ "decimalPlaces": 2,
+ "units": "rpm"
+ },
+ {
+ "name": "rpm4",
+ "shortDesc": "RPM 4",
+ "type": "double",
+ "decimalPlaces": 2,
+ "units": "rpm"
+ }
+ ]
+}
\ No newline at end of file
diff --git a/src/Vehicle/FactGroups/VehicleRPMFactGroup.cc b/src/Vehicle/FactGroups/VehicleRPMFactGroup.cc
new file mode 100644
index 00000000000..67f6c6ac435
--- /dev/null
+++ b/src/Vehicle/FactGroups/VehicleRPMFactGroup.cc
@@ -0,0 +1,61 @@
+/****************************************************************************
+ *
+ * (c) 2009-2023 QGROUNDCONTROL PROJECT
+ *
+ * QGroundControl is licensed according to the terms in the file
+ * COPYING.md in the root of the source code directory.
+ *
+ ****************************************************************************/
+
+#include "VehicleSetpointFactGroup.h"
+#include "Vehicle.h"
+
+const char* VehicleRPMFactGroup::_rpm1FactName = "rpm1";
+const char* VehicleRPMFactGroup::_rpm2FactName = "rpm2";
+const char* VehicleRPMFactGroup::_rpm3FactName = "rpm3";
+const char* VehicleRPMFactGroup::_rpm4FactName = "rpm4";
+
+VehicleRPMFactGroup::VehicleRPMFactGroup(QObject* parent)
+ : FactGroup(1000, ":/json/Vehicle/RPMFact.json", parent)
+ , _rpm1Fact(0, _rpm1FactName, FactMetaData::valueTypeDouble)
+ , _rpm2Fact(0, _rpm2FactName, FactMetaData::valueTypeDouble)
+ , _rpm3Fact(0, _rpm3FactName, FactMetaData::valueTypeDouble)
+ , _rpm4Fact(0, _rpm4FactName, FactMetaData::valueTypeDouble)
+{
+ _addFact(&_rpm1Fact, _rpm1FactName);
+ _addFact(&_rpm2Fact, _rpm2FactName);
+ _addFact(&_rpm3Fact, _rpm3FactName);
+ _addFact(&_rpm4Fact, _rpm4FactName);
+
+ // Start out as not available "--.--"
+ _rpm1Fact.setRawValue(qQNaN());
+ _rpm2Fact.setRawValue(qQNaN());
+ _rpm3Fact.setRawValue(qQNaN());
+ _rpm4Fact.setRawValue(qQNaN());
+}
+
+void VehicleRPMFactGroup::handleMessage(Vehicle* /* vehicle */, mavlink_message_t& message)
+{
+ if (message.msgid == MAVLINK_MSG_ID_RAW_RPM) {
+ mavlink_raw_rpm_t raw_rpm;
+ mavlink_msg_raw_rpm_decode(&message, &raw_rpm);
+ switch (raw_rpm.index) {
+ case 0:
+ rpm1()->setRawValue(raw_rpm.frequency);
+ break;
+ case 1:
+ rpm2()->setRawValue(raw_rpm.frequency);
+ break;
+ case 2:
+ rpm3()->setRawValue(raw_rpm.frequency);
+ break;
+ case 3:
+ rpm4()->setRawValue(raw_rpm.frequency);
+ break;
+ default:
+ break;
+
+ }
+ _setTelemetryAvailable(true);
+ }
+}
diff --git a/src/Vehicle/FactGroups/VehicleRPMFactGroup.h b/src/Vehicle/FactGroups/VehicleRPMFactGroup.h
new file mode 100644
index 00000000000..be1bd2998ec
--- /dev/null
+++ b/src/Vehicle/FactGroups/VehicleRPMFactGroup.h
@@ -0,0 +1,45 @@
+/****************************************************************************
+ *
+ * (c) 2009-2023 QGROUNDCONTROL PROJECT
+ *
+ * QGroundControl is licensed according to the terms in the file
+ * COPYING.md in the root of the source code directory.
+ *
+ ****************************************************************************/
+
+#pragma once
+
+#include "FactGroup.h"
+#include "QGCMAVLink.h"
+
+class VehicleRPMFactGroup : public FactGroup
+{
+ Q_OBJECT
+
+public:
+ VehicleRPMFactGroup(QObject* parent = nullptr);
+
+ Q_PROPERTY(Fact* rpm1 READ rpm1 CONSTANT)
+ Q_PROPERTY(Fact* rpm2 READ rpm2 CONSTANT)
+ Q_PROPERTY(Fact* rpm3 READ rpm3 CONSTANT)
+ Q_PROPERTY(Fact* rpm4 READ rpm4 CONSTANT)
+
+ Fact* rpm1 () { return &_rpm1Fact; }
+ Fact* rpm2 () { return &_rpm2Fact; }
+ Fact* rpm3 () { return &_rpm3Fact; }
+ Fact* rpm4 () { return &_rpm4Fact; }
+
+ // Overrides from FactGroup
+ void handleMessage(Vehicle* vehicle, mavlink_message_t& message) override;
+
+ static const char* _rpm1FactName;
+ static const char* _rpm2FactName;
+ static const char* _rpm3FactName;
+ static const char* _rpm4FactName;
+
+private:
+ Fact _rpm1Fact;
+ Fact _rpm2Fact;
+ Fact _rpm3Fact;
+ Fact _rpm4Fact;
+};
diff --git a/src/Vehicle/Vehicle.cc b/src/Vehicle/Vehicle.cc
index 376ab0eaba0..22493407f0d 100644
--- a/src/Vehicle/Vehicle.cc
+++ b/src/Vehicle/Vehicle.cc
@@ -108,6 +108,7 @@ Vehicle::Vehicle(LinkInterface* link,
, _hygrometerFactGroup (this)
, _generatorFactGroup (this)
, _efiFactGroup (this)
+ , _rpmFactGroup (this)
, _terrainFactGroup (this)
, _terrainProtocolHandler (new TerrainProtocolHandler(this, &_terrainFactGroup, this))
{
@@ -330,6 +331,7 @@ void Vehicle::_commonInit()
_addFactGroup(&_hygrometerFactGroup, _hygrometerFactGroupName);
_addFactGroup(&_generatorFactGroup, _generatorFactGroupName);
_addFactGroup(&_efiFactGroup, _efiFactGroupName);
+ _addFactGroup(&_rpmFactGroup, _rpmFactGroupName);
_addFactGroup(&_terrainFactGroup, _terrainFactGroupName);
// Add firmware-specific fact groups, if provided
diff --git a/src/Vehicle/Vehicle.h b/src/Vehicle/Vehicle.h
index c0a13a2bdde..b8d52ac2e03 100644
--- a/src/Vehicle/Vehicle.h
+++ b/src/Vehicle/Vehicle.h
@@ -39,6 +39,7 @@
#include "VehicleHygrometerFactGroup.h"
#include "VehicleLocalPositionFactGroup.h"
#include "VehicleLocalPositionSetpointFactGroup.h"
+#include "VehicleRPMFactGroup.h"
#include "VehicleSetpointFactGroup.h"
#include "VehicleTemperatureFactGroup.h"
#include "VehicleVibrationFactGroup.h"
@@ -601,6 +602,7 @@ class Vehicle : public VehicleFactGroup
FactGroup* hygrometerFactGroup () { return &_hygrometerFactGroup; }
FactGroup* generatorFactGroup () { return &_generatorFactGroup; }
FactGroup* efiFactGroup () { return &_efiFactGroup; }
+ FactGroup* rpmFactGroup () { return &_rpmFactGroup; }
QmlObjectListModel* batteries () { return &_batteryFactGroupListModel; }
MissionManager* missionManager () { return _missionManager; }
@@ -1229,6 +1231,7 @@ private slots:
const QString _hygrometerFactGroupName = QStringLiteral("hygrometer");
const QString _generatorFactGroupName = QStringLiteral("generator");
const QString _efiFactGroupName = QStringLiteral("efi");
+ const QString _rpmFactGroupName = QStringLiteral("rpm");
VehicleFactGroup* _vehicleFactGroup;
VehicleGPSFactGroup _gpsFactGroup;
@@ -1246,6 +1249,7 @@ private slots:
VehicleHygrometerFactGroup _hygrometerFactGroup;
VehicleGeneratorFactGroup _generatorFactGroup;
VehicleEFIFactGroup _efiFactGroup;
+ VehicleRPMFactGroup _rpmFactGroup;
TerrainFactGroup _terrainFactGroup;
QmlObjectListModel _batteryFactGroupListModel;