diff --git a/CMakeLists.txt b/CMakeLists.txt index dc328c0cfd1743968caf820770e1d8298a78a9ce..64a4c4a4bde7bc9bcdddddf8ba69416bfde075d8 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -86,6 +86,7 @@ add_executable(groundstation src/shared/Modules/ValuesConverterViewer/ValuesViewerConfigPanel.cpp src/shared/Modules/ModuleInfo.cpp src/shared/Modules/ModulesList.cpp + src/shared/Modules/ValvesViewer/ValvesViewer.cpp src/entrypoints/groundstation/application.qrc src/entrypoints/groundstation/main.cpp ) diff --git a/SkywardHub.pro b/SkywardHub.pro index 479c81743a6f0a41859150636461780bfebdb5a6..ba8d17d250db489ab7a22b771b5bb0af64ef8008 100644 --- a/SkywardHub.pro +++ b/SkywardHub.pro @@ -48,6 +48,7 @@ SOURCES += \ src/shared/Modules/Mavlink/MavlinkReader.cpp \ src/shared/Modules/Mavlink/MavlinkCommandAdapter.cpp \ src/shared/Modules/Mavlink/MavlinkModule.cpp \ + src/shared/Modules/ValvesViewer/ValvesViewer.cpp \ src/shared/Core/EventHandler/EventHandler.cpp \ src/shared/Core/XmlObject.cpp \ src/shared/Core/QCustomPlot/QCustomPlot.cpp \ @@ -102,6 +103,8 @@ HEADERS += \ src/shared/Modules/Mavlink/MavlinkModule.h \ src/shared/Modules/Mavlink/MavlinkCommandAdapter.h \ src/shared/Modules/ModulesList.h \ + src/shared/Modules/ValvesViewer/ValvesViewer.h \ + src/shared/Modules/ValvesViewer/ValvesList.h \ src/shared/Core/EventHandler/EventHandler.h \ src/shared/Core/QCustomPlot/QCustomPlot.h \ src/shared/Core/MessageBroker/MessageBroker.h \ diff --git a/src/shared/Modules/ModuleInfo.h b/src/shared/Modules/ModuleInfo.h index f300c0acb3eaf602ea42e66a8537a593ef9265b8..7590775044e4ec6fa5d4df6f4556f6a1f76d68df 100644 --- a/src/shared/Modules/ModuleInfo.h +++ b/src/shared/Modules/ModuleInfo.h @@ -41,6 +41,7 @@ enum ModuleId MODULETEST, TABS, FILTER_SELECTOR, + VALVESVIEWER, }; enum ModuleCategory diff --git a/src/shared/Modules/ModulesList.cpp b/src/shared/Modules/ModulesList.cpp index d32058bd97cd0c686595a7f70135463fff2dc7a4..666fadd812c9e13d86d99dbd806118073d1c8dcc 100644 --- a/src/shared/Modules/ModulesList.cpp +++ b/src/shared/Modules/ModulesList.cpp @@ -35,6 +35,7 @@ #include <Modules/Test/TestModule.h> #include <Modules/TimerController/TimerControllerModule.h> #include <Modules/ValuesConverterViewer/ValuesConverterViewerModule.h> +#include <Modules/ValvesViewer/ValvesViewer.h> void ModulesList::createModuleList() { @@ -130,6 +131,12 @@ void ModulesList::createModuleList() ModuleInfo tabs(ModuleId::TABS, "Tabs", ModuleCategory::UTILITY); tabs.setFactory([]() { return new TabsModule(); }); addModuleInfo(tabs); + + ModuleInfo valvesViewer(ModuleId::VALVESVIEWER, "ValvesViewer", + ModuleCategory::DATAVISUAL); + valvesViewer.setFactory([]() { return new ValvesViewer(); }); + valvesViewer.addModuleSourceFiles("Modules/ValvesViewer/"); + addModuleInfo(valvesViewer); } // ____________________________________________________________________________________________ diff --git a/src/shared/Modules/ValvesViewer/ValvesList.h b/src/shared/Modules/ValvesViewer/ValvesList.h new file mode 100644 index 0000000000000000000000000000000000000000..16fe15efa5b171177872a611b563822cd316ce9e --- /dev/null +++ b/src/shared/Modules/ValvesViewer/ValvesList.h @@ -0,0 +1,45 @@ +/* + * 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 ValvesList +{ + +// Valves +enum class Valve : int +{ + FILLING = 0, + RELEASE, + VENTING, + MAIN, +}; + +// Groundstation labels +static const QList<QString> valvesLabels{ + "FILLING", + "RELEASE", + "VENTING", + "MAIN", +}; + +} // namespace ValvesList \ No newline at end of file diff --git a/src/shared/Modules/ValvesViewer/ValvesViewer.cpp b/src/shared/Modules/ValvesViewer/ValvesViewer.cpp new file mode 100644 index 0000000000000000000000000000000000000000..71169955cafc25b042e34414f97448a9fd6a6df2 --- /dev/null +++ b/src/shared/Modules/ValvesViewer/ValvesViewer.cpp @@ -0,0 +1,136 @@ +/* + * 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 "ValvesViewer.h" + +#include <Components/FilterSelector/FilterSelector.h> +#include <Core/MessageBroker/MessageBroker.h> + +ValvesViewer::ValvesViewer(QWidget* parent) : DefaultModule(parent) +{ + setupUi(); + defaultContextMenuSetup(); +} + +ValvesViewer::~ValvesViewer() +{ + getCore()->getMessageBroker()->unsubscribe(filter, this); +} + +QWidget* ValvesViewer::toWidget() { return this; } + +XmlObject ValvesViewer::toXmlObject() +{ + XmlObject obj(getName(ModuleId::VALVESVIEWER)); + + obj.addAttribute("filter", filter.toString()); + + return obj; +} + +void ValvesViewer::fromXmlObject(const XmlObject& xmlObject) +{ + if (xmlObject.getObjectName() == getName(ModuleId::VALVESVIEWER)) + { + auto filter = Filter::fromString(xmlObject.getAttribute("filter")); + setFilter(filter); + } +} + +void ValvesViewer::setupUi() +{ + outerLayout = new QHBoxLayout; + outerLayout->setContentsMargins(0, 0, 0, 0); + outerLayout->setSpacing(0); + + for (auto labelText : ValvesList::valvesLabels) + { + QLabel* label = new QLabel; + label->setText(labelText); + label->setAlignment(Qt::AlignCenter); + label->setContentsMargins(4, 4, 4, 4); + outerLayout->addWidget(label); + } + + setLayout(outerLayout); +} + +void ValvesViewer::addCustomActionsToMenu() +{ + QAction* action = new QAction("Choose topic and field"); + connect(action, &QAction::triggered, this, + &ValvesViewer::onConfigureClicked); + + addActionToMenu(action); +} + +void ValvesViewer::onConfigureClicked() +{ + FilterSelector::selectFilter( + filter, [this](const Filter& newFilter) { setFilter(newFilter); }); +} + +void ValvesViewer::setFilter(const Filter& newFilter) +{ + getCore()->getMessageBroker()->unsubscribe(filter, this); + getCore()->getMessageBroker()->subscribe( + newFilter, this, + [this](const Message& message, const Filter& filter) + { onMsgReceived(message); }); + filter = newFilter; +} + +void ValvesViewer::onMsgReceived(const Message& msg) +{ + // Couple the valves with their own state + QMap<ValvesList::Valve, uint64_t> map{ + {ValvesList::Valve::FILLING, + msg.getField("filling_valve_state").getUnsignedInteger()}, + {ValvesList::Valve::MAIN, + msg.getField("main_valve_state").getUnsignedInteger()}, + {ValvesList::Valve::RELEASE, + msg.getField("release_valve_state").getUnsignedInteger()}, + {ValvesList::Valve::VENTING, + msg.getField("venting_valve_state").getUnsignedInteger()}}; + + // Define the "active" and the "not active" look + QString baseStyle = + "border-bottom-width:1px;border-left-width:1px;border-top-width:" + "1px;border-radius:0;"; + QString completedStyle = "background-color:green;" + baseStyle; + QString errorStyle = "background-color:red;" + baseStyle; + + // Iterate over the valves to assign them the correct look + for (auto i = map.cbegin(), end = map.cend(); i != end; i++) + { + if (i.value() == 1) + { + // The valve is opened + auto label = + outerLayout->itemAt(static_cast<int>(i.key()))->widget(); + label->setStyleSheet(completedStyle); + } + else + { + // The valve is closed + auto label = + outerLayout->itemAt(static_cast<int>(i.key()))->widget(); + label->setStyleSheet(errorStyle); + } + } +} diff --git a/src/shared/Modules/ValvesViewer/ValvesViewer.h b/src/shared/Modules/ValvesViewer/ValvesViewer.h new file mode 100644 index 0000000000000000000000000000000000000000..89fa9e7a0860ce837f0c0ae03d013641fcae836f --- /dev/null +++ b/src/shared/Modules/ValvesViewer/ValvesViewer.h @@ -0,0 +1,54 @@ +/* + * 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 <Modules/DefaultModule/DefaultModule.h> + +#include <QLabel> +#include <QWidget> + +#include "ValvesList.h" + +class ValvesViewer : public DefaultModule +{ + Q_OBJECT + +public: + explicit ValvesViewer(QWidget* parent = nullptr); + ~ValvesViewer(); + + QWidget* toWidget() override; + + XmlObject toXmlObject() override; + void fromXmlObject(const XmlObject& xmlObject) override; + +private: + void setupUi(); + void addCustomActionsToMenu() override; + void onConfigureClicked(); + void setFilter(const Filter& filter); + void onMsgReceived(const Message& msg); + + QHBoxLayout* outerLayout; + + Filter filter; + ValvesList::Valve currentState; +};