diff --git a/.vscode/c_cpp_properties.json b/.vscode/c_cpp_properties.json
index 7c8dbf1e9859f75dcf7efa4518385241ad909715..5180384afd2347367d6bd8c42f6f9ed1f65586ab 100644
--- a/.vscode/c_cpp_properties.json
+++ b/.vscode/c_cpp_properties.json
@@ -4,6 +4,7 @@
             "name": "Linux",
             "includePath": [
                 "${workspaceFolder}/src/shared",
+                "${workspaceFolder}/libs/mavlink-skyward-lib",
                 "~/Qt/5.15.2/**"
             ],
             "defines": [],
diff --git a/.vscode/settings.json b/.vscode/settings.json
index 614e17417bd882dba390244064b21ddb8acbde3b..5be4d54fdf82e48698263bda9572fe43c4490d3f 100644
--- a/.vscode/settings.json
+++ b/.vscode/settings.json
@@ -1,5 +1,6 @@
 {
     "files.associations": {
+        ".clang-format": "bibtex",
         "ratio": "cpp",
         "sstream": "cpp",
         "filesystem": "cpp",
@@ -111,7 +112,9 @@
         "qthread": "cpp",
         "qtopengl": "cpp",
         "forward_list": "cpp",
-        "cfenv": "cpp"
+        "cfenv": "cpp",
+        "qaspectengine": "cpp",
+        "qorbitcameracontroller": "cpp"
     },
     "editor.defaultFormatter": "ms-vscode.cpptools",
     "[xml]": {
diff --git a/CMakeLists.txt b/CMakeLists.txt
index cb0d44cca0b7815810b5c0a9f4c67aa9fe1e5ae0..078a34d5fad97e7a82f0d962990545dfb84e1b49 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -31,9 +31,12 @@ set(CMAKE_AUTOMOC ON)
 set(CMAKE_AUTORCC ON)
 set(CMAKE_AUTOUIC ON)
 
-find_package(Qt5 COMPONENTS Widgets REQUIRED)
-find_package(Qt5 COMPONENTS SerialPort REQUIRED)
-find_package(Qt5 COMPONENTS PrintSupport REQUIRED)
+find_package(Qt5 REQUIRED COMPONENTS 
+    Widgets
+    SerialPort
+    PrintSupport
+    3DCore 3DExtras 3DRender 3DInput
+)
 
 add_executable(groundstation
     src/shared/Components/ContextMenuSeparator/contextmenuseparator.cpp
@@ -81,6 +84,7 @@ add_executable(groundstation
     src/shared/Modules/SkywardHub/prefabviewelement.cpp
     src/shared/Modules/SkywardHub/skywardhubmodule.cpp
     src/shared/Modules/Splitter/Splitter.cpp
+    src/shared/Modules/OrientationVisualizer/OrientationVisualizer.cpp
     src/shared/Modules/StateViewer/StateViewer.cpp
     src/shared/Modules/Tabs/tabsmodule.cpp
     src/shared/Modules/Test/testmodule.cpp
@@ -98,6 +102,10 @@ target_link_libraries(groundstation PUBLIC
     Qt5::Widgets
     Qt5::SerialPort
     Qt5::PrintSupport
+    Qt5::3DCore
+    Qt5::3DExtras
+    Qt5::3DRender
+    Qt5::3DInput
     Mavlink::Mavlink
 )
 if(APPLE)
diff --git a/SkywardHub.pro b/SkywardHub.pro
index 44076ea2f5bdb1df904e6db516bb0b87fecce815..55b1d3efc2a279f21631f21ac245a2d913b20689 100644
--- a/SkywardHub.pro
+++ b/SkywardHub.pro
@@ -1,4 +1,4 @@
-QT       += core gui
+QT       += core gui 3dcore 3drender 3dinput 3dlogic 3dextras 3danimation
 
 greaterThan(QT_MAJOR_VERSION, 4): QT += widgets printsupport serialport
 
diff --git a/sbs b/sbs
index 28adeff9d71bc231e65195ce07ccd0d8a82cbbc2..9dd12b16276d64491fc4baaf81fdb7df4bfa4c3b 100755
--- a/sbs
+++ b/sbs
@@ -322,7 +322,7 @@ EOF
 }
 
 CMAKE_FILENAME="CMakeCache.txt"
-CMAKE_PREFIX_PATH="/Users/alberton/Qt/5.15.2/clang_64/lib/cmake/"
+CMAKE_PREFIX_PATH="~/Qt/5.15.2/gcc_64/lib/cmake/"
 DEBUG_FILENAME=".sbsdebug"
 VERBOSE_FILENAME=".sbsverbose"
 BUILD_DIRNAME="build"
diff --git a/src/shared/Modules/OrientationVisualizer/OrientationVisualizer.cpp b/src/shared/Modules/OrientationVisualizer/OrientationVisualizer.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..956209a46fcd1e8d221004cd16e224ccb8dc374b
--- /dev/null
+++ b/src/shared/Modules/OrientationVisualizer/OrientationVisualizer.cpp
@@ -0,0 +1,184 @@
+#include "OrientationVisualizer.h"
+
+#include <Qt3DRender/qpointlight.h>
+
+#include <QSizePolicy>
+#include <Qt3DCore/QAspectEngine>
+#include <Qt3DCore/QEntity>
+#include <Qt3DExtras/QConeMesh>
+#include <Qt3DExtras/QFirstPersonCameraController>
+#include <Qt3DExtras/QForwardRenderer>
+#include <Qt3DExtras/QOrbitCameraController>
+#include <Qt3DExtras/QPhongMaterial>
+#include <Qt3DExtras/QSphereMesh>
+#include <Qt3DExtras/QTorusMesh>
+#include <Qt3DExtras/Qt3DWindow>
+#include <Qt3DInput/QInputAspect>
+#include <Qt3DRender/QCamera>
+#include <Qt3DRender/QCameraLens>
+#include <Qt3DRender/QGeometryRenderer>
+#include <Qt3DRender/QRenderAspect>
+
+OrientationVisualizer::OrientationVisualizer(QWidget *parent)
+    : DefaultModule(parent)
+{
+
+    setupUi();
+    defaultContextMenuSetup();
+
+    updateOrientation(0, 0, 0, 1);
+
+    getCore()->getModuleMessagesBroker()->subscribe(
+        {"Mav/PAYLOAD_FLIGHT_TM"}, this,
+        [this](const ModuleMessage &msg)
+        {
+            updateOrientation(msg.getField("nas_qx").getDouble(0.0),
+                              msg.getField("nas_qy").getDouble(0.0),
+                              msg.getField("nas_qz").getDouble(0.0),
+                              msg.getField("nas_qw").getDouble(0.0));
+        });
+}
+
+QWidget *OrientationVisualizer::toWidget() { return this; }
+
+XmlObject OrientationVisualizer::toXmlObject()
+{
+    XmlObject obj(getName(ModuleId::ORIENTATION_VISUALIZER));
+    return obj;
+}
+
+void OrientationVisualizer::fromXmlObject(const XmlObject &xmlObject) {}
+
+void OrientationVisualizer::setupUi()
+{
+    Qt3DExtras::Qt3DWindow *view = new Qt3DExtras::Qt3DWindow;
+    QWidget *windowContainer     = QWidget::createWindowContainer(view);
+
+    Qt3DCore::QEntity *rootEntity   = new Qt3DCore::QEntity;
+    Qt3DCore::QEntity *rocketEntity = new Qt3DCore::QEntity(rootEntity);
+
+    Qt3DExtras::QConeMesh *rocketMesh = new Qt3DExtras::QConeMesh();
+    rocketMesh->setBottomRadius(10);
+    rocketMesh->setBottomRadius(3);
+    rocketMesh->setLength(20);
+    rocketMesh->setRings(100);
+    rocketMesh->setSlices(20);
+
+    Qt3DExtras::QPhongMaterial *rocketMaterial =
+        new Qt3DExtras::QPhongMaterial();
+    rocketMaterial->setDiffuse(QColor(QRgb(0x15628c)));
+
+    rocketTransform = new Qt3DCore::QTransform();
+
+    rocketEntity->addComponent(rocketMesh);
+    rocketEntity->addComponent(rocketMaterial);
+    rocketEntity->addComponent(rocketTransform);
+
+    // Spheres
+
+    Qt3DExtras::QSphereMesh *sphereMesh = new Qt3DExtras::QSphereMesh;
+    sphereMesh->setRadius(3);
+    sphereMesh->setGenerateTangents(true);
+
+    // Qt3DCore::QEntity *sphereEntity1 = new Qt3DCore::QEntity(rootEntity);
+    // Qt3DCore::QTransform *sphereTransform1 = new Qt3DCore::QTransform;
+    // sphereTransform1->setTranslation(QVector3D(0.0f, 0.0f, 5.0f));
+    // Qt3DExtras::QPhongMaterial *sphereMaterial1 = new
+    // Qt3DExtras::QPhongMaterial();
+    // sphereMaterial1->setDiffuse(QColor(QRgb(0xff0000)));
+    // sphereEntity1->addComponent(sphereMesh);
+    // sphereEntity1->addComponent(sphereTransform1);
+    // sphereEntity1->addComponent(sphereMaterial1);
+
+    // Qt3DCore::QEntity *sphereEntity2 = new Qt3DCore::QEntity(rootEntity);
+    // Qt3DCore::QTransform *sphereTransform2 = new Qt3DCore::QTransform;
+    // sphereTransform2->setTranslation(QVector3D(0.0f, 5.0f, 0.0f));
+    // Qt3DExtras::QPhongMaterial *sphereMaterial2 = new
+    // Qt3DExtras::QPhongMaterial();
+    // sphereMaterial2->setDiffuse(QColor(QRgb(0x00ff00)));
+    // sphereEntity2->addComponent(sphereMesh);
+    // sphereEntity2->addComponent(sphereTransform2);
+    // sphereEntity2->addComponent(sphereMaterial2);
+
+    // Qt3DCore::QEntity *sphereEntity3 = new Qt3DCore::QEntity(rootEntity);
+    // Qt3DCore::QTransform *sphereTransform3 = new Qt3DCore::QTransform;
+    // sphereTransform3->setTranslation(QVector3D(5.0f, 0.0f, 0.0f));
+    // Qt3DExtras::QPhongMaterial *sphereMaterial3 = new
+    // Qt3DExtras::QPhongMaterial();
+    // sphereMaterial3->setDiffuse(QColor(QRgb(0x0000ff)));
+    // sphereEntity3->addComponent(sphereMesh);
+    // sphereEntity3->addComponent(sphereTransform3);
+    // sphereEntity3->addComponent(sphereMaterial3);
+
+    // Camera
+    Qt3DRender::QCamera *camera = view->camera();
+    camera->lens()->setPerspectiveProjection(45.0f, 16.0f / 9.0f, 0.1f,
+                                             1000.0f);
+    camera->setPosition(QVector3D(30.0f, 30.0f, 30.0f));
+    camera->setViewCenter(QVector3D(0, 0, 0));
+    camera->setUpVector(QVector3D(-1, -1, 1));
+
+    // Light
+    Qt3DCore::QEntity *lightEntity = new Qt3DCore::QEntity(rootEntity);
+    Qt3DRender::QPointLight *light = new Qt3DRender::QPointLight(lightEntity);
+    light->setColor("white");
+    light->setIntensity(1);
+    lightEntity->addComponent(light);
+    Qt3DCore::QTransform *lightTransform =
+        new Qt3DCore::QTransform(lightEntity);
+    lightTransform->setTranslation(camera->position());
+    lightEntity->addComponent(lightTransform);
+
+    // For camera controls
+    // Qt3DExtras::QFirstPersonCameraController *camController = new
+    // Qt3DExtras::QFirstPersonCameraController(rootEntity);
+    // camController->setLinearSpeed( 50.0f );
+    // camController->setLookSpeed( 180.0f );
+    // camController->setCamera(camera);
+
+    view->setRootEntity(rootEntity);
+
+    // Visualizer of roll/pitch/yaw
+    QHBoxLayout *lower = new QHBoxLayout();
+
+    yawLabel = new QLabel(this);
+    yawLabel->setText("Y: 0.00");
+    yawLabel->setAlignment(Qt::AlignCenter);
+    pitchLabel = new QLabel(this);
+    pitchLabel->setText("P: 0.00");
+    pitchLabel->setAlignment(Qt::AlignCenter);
+    rollLabel = new QLabel(this);
+    rollLabel->setText("R: 0.00");
+    rollLabel->setAlignment(Qt::AlignCenter);
+    this->setStyleSheet("QLabel {font-weight: bold;}");
+
+    lower->addWidget(yawLabel);
+    lower->addWidget(pitchLabel);
+    lower->addWidget(rollLabel);
+
+    QVBoxLayout *container = new QVBoxLayout(this);
+    container->addWidget(windowContainer);
+    container->addLayout(lower);
+
+    container->setStretch(0, 1);
+    container->setStretch(1, 0);
+}
+
+void OrientationVisualizer::updateOrientation(double qx, double qy, double qz,
+                                              double qw)
+{
+    float yaw, pitch, roll;
+
+    QQuaternion quaternion(QVector4D(qx, qy, qz, qw));
+    quaternion.getEulerAngles(&pitch, &yaw, &roll);
+
+    yawLabel->setText(QString::asprintf("Y: %.2lf", yaw));
+    pitchLabel->setText(QString::asprintf("P: %.2lf", pitch));
+    rollLabel->setText(QString::asprintf("R: %.2lf", roll));
+
+    QQuaternion displayQuaternion = QQuaternion::fromRotationMatrix(
+        quaternion.toRotationMatrix() *
+        QQuaternion::fromEulerAngles(90, 0, 0).toRotationMatrix());
+
+    rocketTransform->setRotation(displayQuaternion);
+}
diff --git a/src/shared/Modules/OrientationVisualizer/OrientationVisualizer.h b/src/shared/Modules/OrientationVisualizer/OrientationVisualizer.h
new file mode 100644
index 0000000000000000000000000000000000000000..a14d7657eec8ba6b973c54dbd17b653df70f522b
--- /dev/null
+++ b/src/shared/Modules/OrientationVisualizer/OrientationVisualizer.h
@@ -0,0 +1,26 @@
+#pragma once
+
+#include <Modules/DefaultModule/defaultmodule.h>
+
+#include <Qt3DCore/QTransform>
+
+class OrientationVisualizer : public DefaultModule
+{
+    Q_OBJECT
+
+public:
+    explicit OrientationVisualizer(QWidget* parent = nullptr);
+
+    QWidget* toWidget() override;
+
+    XmlObject toXmlObject() override;
+    void fromXmlObject(const XmlObject& xmlObject) override;
+
+private:
+    QLabel *rollLabel, *pitchLabel, *yawLabel;
+
+    Qt3DCore::QTransform* rocketTransform;
+
+    void updateOrientation(double qx, double qy, double qz, double qw);
+    void setupUi();
+};
diff --git a/src/shared/Modules/ValuesConverterViewer/valuesconverterviewermodule.h b/src/shared/Modules/ValuesConverterViewer/valuesconverterviewermodule.h
index 873b9d6affe2e685f77cff73beda63f4bdfd1f80..53a8543efbfe4032a39b28b7c6b4492927432bf9 100644
--- a/src/shared/Modules/ValuesConverterViewer/valuesconverterviewermodule.h
+++ b/src/shared/Modules/ValuesConverterViewer/valuesconverterviewermodule.h
@@ -17,7 +17,6 @@ class ValuesConverterViewerModule;
 
 class ValuesConverterViewerModule : public DefaultModule
 {
-
     Q_OBJECT
 
 public:
diff --git a/src/shared/Modules/moduleinfo.h b/src/shared/Modules/moduleinfo.h
index 4ebac8d7720f7ab043dc9bb684e4bab41f8d09fb..76b29257c2137a49ef10e4ac090e90f89676385e 100644
--- a/src/shared/Modules/moduleinfo.h
+++ b/src/shared/Modules/moduleinfo.h
@@ -18,6 +18,7 @@ enum ModuleId
     INCOMINGMESSAGESVIEWER,
     MAVLINK,
     FILESTREAM,
+    ORIENTATION_VISUALIZER,
     STATEVIEWER,
     VALUESCONVERTERVIEWER,
     MAVLINK_RCK_TESTING,
diff --git a/src/shared/Modules/moduleslist.cpp b/src/shared/Modules/moduleslist.cpp
index 44d461829fd098465e41ccbe80315cd6a030e585..6076b53a7742c4607d992999981f24191e243ef8 100644
--- a/src/shared/Modules/moduleslist.cpp
+++ b/src/shared/Modules/moduleslist.cpp
@@ -9,6 +9,7 @@
 #include <Modules/IncomingMessagesViewer/incomingmessagesviewermodule.h>
 #include <Modules/Mavlink/mavlinkmodule.h>
 #include <Modules/Mavlink/mavlinkrocketmsgtestingmodule.h>
+#include <Modules/OrientationVisualizer/OrientationVisualizer.h>
 #include <Modules/OutgoingMessagesViewer/outgoingmessagesviewermodule.h>
 #include <Modules/SkywardHub/skywardhubmodule.h>
 #include <Modules/Splitter/Splitter.h>
@@ -113,14 +114,23 @@ void ModulesList::createModuleList()
     stateViewer.addModuleSourceFiles("Modules/StateViewer/");
     addModuleInfo(stateViewer);
 
-    ModuleInfo valuesconverterviewer(ModuleId::VALUESCONVERTERVIEWER,
+    ModuleInfo valuesConverterViewer(ModuleId::VALUESCONVERTERVIEWER,
                                      "ValuesConverterViewer",
                                      ModuleCategory::UTILITY);
-    valuesconverterviewer.setFactory(
+    valuesConverterViewer.setFactory(
         []() { return new ValuesConverterViewerModule(); });
-    valuesconverterviewer.addModuleSourceFiles(
+    valuesConverterViewer.addModuleSourceFiles(
         "Modules/ValuesConverterViewer/");
-    addModuleInfo(valuesconverterviewer);
+    addModuleInfo(valuesConverterViewer);
+
+    ModuleInfo orientationVisualizer(ModuleId::ORIENTATION_VISUALIZER,
+                                     "OrientationVisualizer",
+                                     ModuleCategory::UTILITY);
+    orientationVisualizer.setFactory([]()
+                                     { return new OrientationVisualizer(); });
+    orientationVisualizer.addModuleSourceFiles(
+        "Modules/OrientationVisualizer/");
+    addModuleInfo(orientationVisualizer);
 
     ModuleInfo timerController(ModuleId::TIMER_CONTROLLER, "TimerController",
                                ModuleCategory::UTILITY);