diff --git a/CMakeLists.txt b/CMakeLists.txt
index 84737575b1a91baa0a711824384de9fd8ce91912..c5847472d2f17a6458b387ae135a5563fe0b20f4 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -77,6 +77,7 @@ add_executable(groundstation
     src/shared/Modules/OrientationVisualizer/OrientationVisualizer.cpp
     src/shared/Modules/MainStateViewer/MainStateViewer.cpp
     src/shared/Modules/PayloadStateViewer/PayloadStateViewer.cpp
+    src/shared/Modules/RigStateViewer/RigStateViewer.cpp
     src/shared/Modules/Tabs/TabsModule.cpp
     src/shared/Modules/Test/TestModule.cpp
     src/shared/Modules/TimerController/TimerControllerModule.cpp
diff --git a/SkywardHub.pro b/SkywardHub.pro
index 04ba882c70d8c0a2526e1ffa1a74789c2c31a652..97a8c79b4df4e46bfc718c5424d863d5bc98c1b2 100644
--- a/SkywardHub.pro
+++ b/SkywardHub.pro
@@ -24,6 +24,7 @@ SOURCES += \
     src/shared/Modules/OrientationVisualizer/OrientationVisualizer.cpp \
     src/shared/Modules/MainStateViewer/MainStateViewer.cpp \
     src/shared/Modules/PayloadStateViewer/PayloadStateViewer.cpp \
+    src/shared/Modules/RigStateViewer/RigStateViewer.cpp \
     src/shared/Modules/FileStream/FileStreamModule.cpp \
     src/shared/Modules/Graph/Graph.cpp \
     src/shared/Modules/Test/TestModule.cpp \
@@ -77,6 +78,8 @@ HEADERS += \
     src/shared/Modules/MainStateViewer/MainStateViewer.h \
     src/shared/Modules/PayloadStateViewer/PayloadStatesList.h \
     src/shared/Modules/PayloadStateViewer/PayloadStateViewer.h \
+    src/shared/Modules/RigStateViewer/RigStatesList.h \
+    src/shared/Modules/RigStateViewer/RigStateViewer.h \
     src/shared/Modules/FileStream/FileStreamModule.h \
     src/shared/Modules/Graph/Graph.h \
     src/shared/Modules/Test/TestModule.h \
diff --git a/libs/mavlink-skyward-lib b/libs/mavlink-skyward-lib
index 05993b2739364c7d4cb510ad6840a62cca6c69cd..b4c2b98d38a0d15049b7fc9afcfb615aea2403a1 160000
--- a/libs/mavlink-skyward-lib
+++ b/libs/mavlink-skyward-lib
@@ -1 +1 @@
-Subproject commit 05993b2739364c7d4cb510ad6840a62cca6c69cd
+Subproject commit b4c2b98d38a0d15049b7fc9afcfb615aea2403a1
diff --git a/src/shared/Modules/CommandPad/MessagesList.h b/src/shared/Modules/CommandPad/MessagesList.h
index c8f583a4c3e26c0db2fa64729d98eecc9600e9f7..8ef3d2bbfd534d55328876a59fb58526635c8194 100644
--- a/src/shared/Modules/CommandPad/MessagesList.h
+++ b/src/shared/Modules/CommandPad/MessagesList.h
@@ -62,7 +62,8 @@ static const QMap<QString, int> systemTmList{
     {"MAV_STATS_ID", MAV_STATS_ID},
     {"MAV_SENSORS_STATE_ID", MAV_SENSORS_STATE_ID},
     {"MAV_GSE_ID", MAV_GSE_ID},
-    {"MAV_MOTOR_ID", MAV_MOTOR_ID}};
+    {"MAV_MOTOR_ID", MAV_MOTOR_ID},
+    {"MAV_REGISTRY_ID", MAV_REGISTRY_ID}};
 
 static const QMap<QString, int> sensorsList{
     {"MAV_GPS_ID", MAV_GPS_ID},
@@ -110,7 +111,11 @@ static const QMap<QString, int> commandsList{
     {"MAV_CMD_ENTER_TEST_MODE", MAV_CMD_ENTER_TEST_MODE},
     {"MAV_CMD_EXIT_TEST_MODE", MAV_CMD_EXIT_TEST_MODE},
     {"MAV_CMD_START_RECORDING", MAV_CMD_START_RECORDING},
-    {"MAV_CMD_STOP_RECORDING", MAV_CMD_STOP_RECORDING}};
+    {"MAV_CMD_STOP_RECORDING", MAV_CMD_STOP_RECORDING},
+    {"MAV_CMD_OPEN_NITROGEN", MAV_CMD_OPEN_NITROGEN},
+    {"MAV_CMD_REGISTRY_LOAD", MAV_CMD_REGISTRY_LOAD},
+    {"MAV_CMD_REGISTRY_SAVE", MAV_CMD_REGISTRY_SAVE},
+    {"MAV_CMD_REGISTRY_CLEAR", MAV_CMD_REGISTRY_CLEAR}};
 
 const QMap<QString, int> servosList{
     {"AIR_BRAKES_SERVO", AIR_BRAKES_SERVO},
diff --git a/src/shared/Modules/Mavlink/MavlinkVersionHeader.h b/src/shared/Modules/Mavlink/MavlinkVersionHeader.h
index 421e1ba43a919d0875a8bc4926c257b78272bbb2..69e6e2a675f4538b3547d71e01ff62fd65510fa5 100644
--- a/src/shared/Modules/Mavlink/MavlinkVersionHeader.h
+++ b/src/shared/Modules/Mavlink/MavlinkVersionHeader.h
@@ -23,7 +23,7 @@
 #if __GNUC__ >= 9
 #pragma GCC diagnostic ignored "-Waddress-of-packed-member"
 #endif
-#include <mavlink_lib/gemini/mavlink.h>
+#include <mavlink_lib/lyra/mavlink.h>
 #pragma GCC diagnostic pop
 
 // static __attribute__((unused)) uint8_t validSysid = 171;
diff --git a/src/shared/Modules/ModuleInfo.h b/src/shared/Modules/ModuleInfo.h
index 08362667df617f1cb72ac8e2710f41e394932826..588ad4bb36ffec5efc7888c9c357514a34529351 100644
--- a/src/shared/Modules/ModuleInfo.h
+++ b/src/shared/Modules/ModuleInfo.h
@@ -32,6 +32,7 @@ enum ModuleId
     INCOMING_MESSAGES_VIEWER,
     MAIN_STATE_VIEWER,
     PAYLOAD_STATE_VIEWER,
+    RIG_STATE_VIEWER,
     ORIENTATION_VISUALIZER,
     VALVES_VIEWER,
 
diff --git a/src/shared/Modules/ModulesList.cpp b/src/shared/Modules/ModulesList.cpp
index 1c6928438b48ccd0fc301f1cc6196db25a440432..e6f3edea9689bb602ab4b45095b802218bee0453 100644
--- a/src/shared/Modules/ModulesList.cpp
+++ b/src/shared/Modules/ModulesList.cpp
@@ -32,6 +32,7 @@
 #include <Modules/OrientationVisualizer/OrientationVisualizer.h>
 #include <Modules/OutgoingMessagesViewer/OutgoingMessagesViewerModule.h>
 #include <Modules/PayloadStateViewer/PayloadStateViewer.h>
+#include <Modules/RigStateViewer/RigStateViewer.h>
 #include <Modules/Splitter/Splitter.h>
 #include <Modules/Tabs/TabsModule.h>
 #include <Modules/Test/TestModule.h>
@@ -94,6 +95,13 @@ ModulesList::ModulesList()
             []() { return new PayloadStateViewerModule(); });
         modulesInfo.append(payloadStateViewer);
 
+        ModuleInfo rigStateViewer(ModuleId::RIG_STATE_VIEWER,
+                                  "Rig State Viewer",
+                                  ModuleCategory::DATA_VISUALIZATION);
+        rigStateViewer.setFactoryMethod([]()
+                                        { return new RigStateViewerModule(); });
+        modulesInfo.append(rigStateViewer);
+
         ModuleInfo orientationVisualizer(ModuleId::ORIENTATION_VISUALIZER,
                                          "Orientation Visualizer",
                                          ModuleCategory::DATA_VISUALIZATION);
diff --git a/src/shared/Modules/RigStateViewer/RigStateViewer.cpp b/src/shared/Modules/RigStateViewer/RigStateViewer.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..c1161e11db963e6398a1ebfcbcb20946cc72bd02
--- /dev/null
+++ b/src/shared/Modules/RigStateViewer/RigStateViewer.cpp
@@ -0,0 +1,144 @@
+/*
+ * This file is part of Skyward Hub.
+ *
+ * Skyward Hub is free software: you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License as published by the Free Software
+ * Foundation, either version 3 of the License, or (at your option) any later
+ * version.
+ *
+ * Skyward Hub is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * Skyward Hub. If not, see <https://www.gnu.org/licenses/>.
+ *
+ */
+
+#include "RigStateViewer.h"
+
+#include <Components/FilterSelector/FilterSelector.h>
+#include <Core/MessageBroker/MessageBroker.h>
+
+#include <QAction>
+
+RigStateViewerModule::RigStateViewerModule()
+    : Module(ModuleId::RIG_STATE_VIEWER)
+{
+    setupUi();
+    customContextMenuActionSetup();
+}
+
+RigStateViewerModule::~RigStateViewerModule()
+{
+    MessageBroker::getInstance().unsubscribe(filter, this);
+}
+
+XmlObject RigStateViewerModule::toXmlObject()
+{
+    XmlObject obj = Module::toXmlObject();
+
+    obj.addAttribute("filter", filter.toString());
+
+    return obj;
+}
+
+void RigStateViewerModule::fromXmlObject(const XmlObject& xmlObject)
+{
+    auto filter = Filter::fromString(xmlObject.getAttribute("filter"));
+    setFilter(filter);
+}
+
+void RigStateViewerModule::setupUi()
+{
+    outerLayout = new QHBoxLayout;
+    outerLayout->setContentsMargins(0, 0, 0, 0);
+    outerLayout->setSpacing(0);
+
+    for (auto labelText : RigStatesList::statesLabels)
+    {
+        QLabel* label = new QLabel;
+        label->setText(labelText);
+        label->setAlignment(Qt::AlignCenter);
+        label->setContentsMargins(4, 4, 4, 4);
+        outerLayout->addWidget(label);
+    }
+
+    setLayout(outerLayout);
+}
+
+void RigStateViewerModule::customContextMenuActionSetup()
+{
+    QAction* action = new QAction("Choose topic and field");
+    connect(action, &QAction::triggered, this,
+            &RigStateViewerModule::onConfigureClicked);
+
+    customContextMenuActions.append(action);
+}
+
+void RigStateViewerModule::onConfigureClicked()
+{
+    FilterSelector::selectFilter(
+        filter, [this](const Filter& newFilter) { setFilter(newFilter); });
+}
+
+void RigStateViewerModule::setFilter(const Filter& newFilter)
+{
+    MessageBroker::getInstance().unsubscribe(filter, this);
+    MessageBroker::getInstance().subscribe(
+        newFilter, this,
+        [this](const Message& message, const Filter& filter)
+        { onMsgReceived(message); });
+    filter = newFilter;
+}
+
+void RigStateViewerModule::onMsgReceived(const Message& msg)
+{
+    Field field = msg.getField("gmm_state");
+
+    RigStatesList::State state =
+        static_cast<RigStatesList::State>(field.getUnsignedInteger());
+
+    // Skip invalid and macro states
+    if (state == RigStatesList::State::INVALID ||
+        state == RigStatesList::State::IDLE ||
+        state == RigStatesList::State::FIRING)
+        return;
+
+    if (state != currentState)
+    {
+        currentState = static_cast<RigStatesList::State>(state);
+
+        QString baseStyle =
+            "border-bottom-width:1px;border-left-width:1px;border-top-width:"
+            "1px;border-radius:0;";
+        QString currentStateStyle =
+            "background-color:yellow; color:black;" + baseStyle;
+        QString completedStyle = "background-color:green;" + baseStyle;
+        QString errorStyle     = "background-color:red;" + baseStyle;
+
+        int index  = RigStatesList::statesIndexes[currentState];
+        auto label = outerLayout->itemAt(index)->widget();
+
+        if (currentState == RigStatesList::State::INIT_ERR)
+            label->setStyleSheet(errorStyle);
+        else
+            label->setStyleSheet(currentStateStyle);
+
+        // Set as completed every state before the current
+        for (int i = index - 1; i >= 0; i--)
+            outerLayout->itemAt(i)->widget()->setStyleSheet(completedStyle);
+
+        // Reset every state after the current
+        for (int i = index + 1; i < RigStatesList::statesLabels.count(); i++)
+            outerLayout->itemAt(i)->widget()->setStyleSheet(baseStyle);
+
+        auto tmp = outerLayout->itemAt(RigStatesList::statesLabels.count() - 1)
+                       ->widget()
+                       ->styleSheet();
+        outerLayout->itemAt(RigStatesList::statesLabels.count() - 1)
+            ->widget()
+            ->setStyleSheet(tmp + "border-right-width:1px;");
+    }
+}
diff --git a/src/shared/Modules/RigStateViewer/RigStateViewer.h b/src/shared/Modules/RigStateViewer/RigStateViewer.h
new file mode 100644
index 0000000000000000000000000000000000000000..5259d77e89fcfc7f0c710c84366e61c7cb32fb54
--- /dev/null
+++ b/src/shared/Modules/RigStateViewer/RigStateViewer.h
@@ -0,0 +1,53 @@
+/*
+ * This file is part of Skyward Hub.
+ *
+ * Skyward Hub is free software: you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License as published by the Free Software
+ * Foundation, either version 3 of the License, or (at your option) any later
+ * version.
+ *
+ * Skyward Hub is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * Skyward Hub. If not, see <https://www.gnu.org/licenses/>.
+ *
+ */
+
+#pragma once
+
+#include <Core/Message/Filter.h>
+#include <Core/Message/Message.h>
+#include <Core/XmlObject.h>
+#include <Modules/Module.h>
+
+#include <QLabel>
+#include <QWidget>
+
+#include "RigStatesList.h"
+
+class RigStateViewerModule : public Module
+{
+    Q_OBJECT
+
+public:
+    RigStateViewerModule();
+    ~RigStateViewerModule();
+
+    XmlObject toXmlObject() override;
+    void fromXmlObject(const XmlObject& xmlObject) override;
+
+private:
+    void setupUi();
+    void customContextMenuActionSetup();
+    void onConfigureClicked();
+    void setFilter(const Filter& filter);
+    void onMsgReceived(const Message& msg);
+
+    QHBoxLayout* outerLayout;
+
+    Filter filter;
+    RigStatesList::State currentState;
+};
diff --git a/src/shared/Modules/RigStateViewer/RigStatesList.h b/src/shared/Modules/RigStateViewer/RigStatesList.h
new file mode 100644
index 0000000000000000000000000000000000000000..7e496bf22658ef273c1a170cd9232a8ad49ba3e1
--- /dev/null
+++ b/src/shared/Modules/RigStateViewer/RigStatesList.h
@@ -0,0 +1,53 @@
+/*
+ * This file is part of Skyward Hub.
+ *
+ * Skyward Hub is free software: you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License as published by the Free Software
+ * Foundation, either version 3 of the License, or (at your option) any later
+ * version.
+ *
+ * Skyward Hub is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * Skyward Hub. If not, see <https://www.gnu.org/licenses/>.
+ *
+ */
+
+#pragma once
+
+#include <QList>
+#include <QMap>
+#include <QString>
+
+namespace RigStatesList
+{
+
+// Rockets states
+enum class State : int
+{
+    IDLE = 0,
+    INIT,
+    INIT_ERR,
+    DISARMED,
+    ARMED,
+    FIRING,
+    IGNITING,
+    OXIDIZER,
+    COOLING,
+    INVALID,
+};
+
+// Groundstation labels
+static const QList<QString> statesLabels{"INIT",     "DISARMED", "ARMED",
+                                         "IGNITING", "OXIDIZER", "COOLING"};
+
+// Map from rocket states to groundstation labels
+static const QMap<State, int> statesIndexes{
+    {State::IDLE, -1},    {State::INIT, 0},   {State::INIT_ERR, 0},
+    {State::DISARMED, 1}, {State::ARMED, 2},  {State::IGNITING, 3},
+    {State::OXIDIZER, 4}, {State::COOLING, 5}};
+
+}  // namespace RigStatesList
\ No newline at end of file
diff --git a/src/shared/Modules/ValvesViewer/ValvesList.h b/src/shared/Modules/ValvesViewer/ValvesList.h
index 16fe15efa5b171177872a611b563822cd316ce9e..be0077cbbbb8f8b74153bd676cef1b2f24baf2c0 100644
--- a/src/shared/Modules/ValvesViewer/ValvesList.h
+++ b/src/shared/Modules/ValvesViewer/ValvesList.h
@@ -32,14 +32,12 @@ enum class Valve : int
     RELEASE,
     VENTING,
     MAIN,
+    NITROGEN,
+    TARS,
 };
 
 // Groundstation labels
-static const QList<QString> valvesLabels{
-    "FILLING",
-    "RELEASE",
-    "VENTING",
-    "MAIN",
-};
+static const QList<QString> valvesLabels{"FILLING", "RELEASE",  "VENTING",
+                                         "MAIN",    "NITROGEN", "TARS"};
 
 }  // namespace ValvesList
\ No newline at end of file
diff --git a/src/shared/Modules/ValvesViewer/ValvesViewer.cpp b/src/shared/Modules/ValvesViewer/ValvesViewer.cpp
index 7b68f3a62e82f5d44de0e1281f64f2695f78361c..4889eb8ca9eeb1945bc2347dcb6c5af56c77f5a9 100644
--- a/src/shared/Modules/ValvesViewer/ValvesViewer.cpp
+++ b/src/shared/Modules/ValvesViewer/ValvesViewer.cpp
@@ -101,7 +101,11 @@ void ValvesViewer::onMsgReceived(const Message& msg)
         {ValvesList::Valve::RELEASE,
          msg.getField("release_valve_state").getUnsignedInteger()},
         {ValvesList::Valve::VENTING,
-         msg.getField("venting_valve_state").getUnsignedInteger()}};
+         msg.getField("venting_valve_state").getUnsignedInteger()},
+        {ValvesList::Valve::NITROGEN,
+         msg.getField("nitrogen_valve_state").getUnsignedInteger()},
+        {ValvesList::Valve::TARS,
+         msg.getField("tars_state").getUnsignedInteger()}};
 
     // Define the "active" and the "not active" look
     QString baseStyle =