diff --git a/simulation/VirtualLedBoard/.gitignore b/simulation/VirtualLedBoard/.gitignore new file mode 100644 index 0000000..fab7372 --- /dev/null +++ b/simulation/VirtualLedBoard/.gitignore @@ -0,0 +1,73 @@ +# This file is used to ignore files which are generated +# ---------------------------------------------------------------------------- + +*~ +*.autosave +*.a +*.core +*.moc +*.o +*.obj +*.orig +*.rej +*.so +*.so.* +*_pch.h.cpp +*_resource.rc +*.qm +.#* +*.*# +core +!core/ +tags +.DS_Store +.directory +*.debug +Makefile* +*.prl +*.app +moc_*.cpp +ui_*.h +qrc_*.cpp +Thumbs.db +*.res +*.rc +/.qmake.cache +/.qmake.stash + +# qtcreator generated files +*.pro.user* + +# xemacs temporary files +*.flc + +# Vim temporary files +.*.swp + +# Visual Studio generated files +*.ib_pdb_index +*.idb +*.ilk +*.pdb +*.sln +*.suo +*.vcproj +*vcproj.*.*.user +*.ncb +*.sdf +*.opensdf +*.vcxproj +*vcxproj.* + +# MinGW generated files +*.Debug +*.Release + +# Python byte code +*.pyc + +# Binaries +# -------- +*.dll +*.exe + diff --git a/simulation/VirtualLedBoard/VirtualLedBoard.pro b/simulation/VirtualLedBoard/VirtualLedBoard.pro new file mode 100644 index 0000000..208ce2e --- /dev/null +++ b/simulation/VirtualLedBoard/VirtualLedBoard.pro @@ -0,0 +1,31 @@ +QT += core gui +QT += network + +greaterThan(QT_MAJOR_VERSION, 4): QT += widgets + +CONFIG += c++11 + +# You can make your code fail to compile if it uses deprecated APIs. +# In order to do so, uncomment the following line. +#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 + +SOURCES += \ + main.cpp \ + mainwindow.cpp \ + udpserver.cpp + +HEADERS += \ + mainwindow.h \ + settings.h \ + udpserver.h + +FORMS += \ + mainwindow.ui + +TRANSLATIONS += \ + VirtualLedBoard_en_150.ts + +# Default rules for deployment. +qnx: target.path = /tmp/$${TARGET}/bin +else: unix:!android: target.path = /opt/$${TARGET}/bin +!isEmpty(target.path): INSTALLS += target diff --git a/simulation/VirtualLedBoard/VirtualLedBoard_en_150.ts b/simulation/VirtualLedBoard/VirtualLedBoard_en_150.ts new file mode 100644 index 0000000..eb9feca --- /dev/null +++ b/simulation/VirtualLedBoard/VirtualLedBoard_en_150.ts @@ -0,0 +1,3 @@ + + + diff --git a/simulation/VirtualLedBoard/main.cpp b/simulation/VirtualLedBoard/main.cpp new file mode 100644 index 0000000..fd3e533 --- /dev/null +++ b/simulation/VirtualLedBoard/main.cpp @@ -0,0 +1,11 @@ +#include "mainwindow.h" + +#include + +int main(int argc, char *argv[]) +{ + QApplication a(argc, argv); + MainWindow w; + w.show(); + return a.exec(); +} diff --git a/simulation/VirtualLedBoard/mainwindow.cpp b/simulation/VirtualLedBoard/mainwindow.cpp new file mode 100644 index 0000000..b99fbab --- /dev/null +++ b/simulation/VirtualLedBoard/mainwindow.cpp @@ -0,0 +1,53 @@ +#include "mainwindow.h" +#include "ui_mainwindow.h" + +#include +#include +#include +#include + +MainWindow::MainWindow(QWidget *parent) + : QMainWindow(parent) + , ui(new Ui::MainWindow) +{ + ui->setupUi(this); + this->mOffscreenPanel = new QImage(DEFAULT_WIDTH + LED_DISTANCE, DEFAULT_HEIGHT + LED_DISTANCE, QImage::Format_RGB32); + this->drawImage(this->mOffscreenPanel); + this->server = new UdpLedServer (NULL, this); +} + +MainWindow::~MainWindow() +{ + delete ui; +} + +void MainWindow::drawImage(QImage *target) { + this->mScene=new QGraphicsScene() ; + QGraphicsView *graphicsView = new QGraphicsView(); + graphicsView->setRenderHints(QPainter::Antialiasing | QPainter::SmoothPixmapTransform); + graphicsView->setScene(this->mScene); + graphicsView->show(); + this->ui->ledPanel->addWidget(graphicsView); +} + + +void MainWindow::setLED(uint8_t x, uint8_t y) { + /* draw inital screen */ + QPainter painter(this->mOffscreenPanel); + painter.setRenderHint(QPainter::Antialiasing, true); + painter.setPen(QPen(COLOR_FOREGROUND, 1)); + painter.setBrush(COLOR_FOREGROUND); + painter.drawEllipse(LED_DIAMETER/2 + (x* LED_DISTANCE), LED_DIAMETER/2 + (y * LED_DISTANCE), LED_DIAMETER, LED_DIAMETER); +} + +void MainWindow::updatePanel(void) { + + QGraphicsPixmapItem* item = new QGraphicsPixmapItem(QPixmap::fromImage(*(this->mOffscreenPanel))); + this->mScene->clear(); + mScene->addItem(item); + this->renderPanel(); +} + +void MainWindow::renderPanel(void) { + this->mOffscreenPanel->fill(COLOR_BACKGROUND); +} diff --git a/simulation/VirtualLedBoard/mainwindow.h b/simulation/VirtualLedBoard/mainwindow.h new file mode 100644 index 0000000..d32b5f4 --- /dev/null +++ b/simulation/VirtualLedBoard/mainwindow.h @@ -0,0 +1,41 @@ +#ifndef MAINWINDOW_H +#define MAINWINDOW_H + +#include +#include +#include +#include "udpserver.h" + +#include "settings.h" + +#define COLOR_BACKGROUND Qt::black +#define COLOR_FOREGROUND QColor(255, 127, 0, 255) + +QT_BEGIN_NAMESPACE +namespace Ui { class MainWindow; } +QT_END_NAMESPACE + +/* dummy */ +class UdpLedServer; + +class MainWindow : public QMainWindow +{ + Q_OBJECT + +public: + MainWindow(QWidget *parent = nullptr); + ~MainWindow(); + +public slots: + void setLED(uint8_t x, uint8_t y); + void updatePanel(void); + +private: + Ui::MainWindow *ui; + UdpLedServer *server = nullptr; + QImage *mOffscreenPanel = nullptr; + QGraphicsScene* mScene = nullptr; + void drawImage(QImage *image); + void renderPanel(void); +}; +#endif // MAINWINDOW_H diff --git a/simulation/VirtualLedBoard/mainwindow.ui b/simulation/VirtualLedBoard/mainwindow.ui new file mode 100644 index 0000000..a181b2b --- /dev/null +++ b/simulation/VirtualLedBoard/mainwindow.ui @@ -0,0 +1,48 @@ + + + MainWindow + + + + 0 + 0 + 800 + 600 + + + + MainWindow + + + + + 0 + 0 + + + + + + 10 + 0 + 781 + 441 + + + + + + + + 0 + 0 + 800 + 22 + + + + + + + + diff --git a/simulation/VirtualLedBoard/settings.h b/simulation/VirtualLedBoard/settings.h new file mode 100644 index 0000000..c1b23ef --- /dev/null +++ b/simulation/VirtualLedBoard/settings.h @@ -0,0 +1,14 @@ + +#define PACKET_LENGTH 801 +#define PACKET_INDEX_BRIGHTNESS 0 +#define PACKET_INDEX_PANEL0 1 + +#define MAXIMUM_PANELSIZE 5 +#define PANEL_WIDTH 32 +#define PANEL_HEIGHT 40 + +#define LED_DIAMETER 8 +#define LED_DISTANCE (LED_DIAMETER + 3) + +#define DEFAULT_WIDTH (LED_DISTANCE * MAXIMUM_PANELSIZE * PANEL_WIDTH) +#define DEFAULT_HEIGHT (LED_DISTANCE * PANEL_HEIGHT) diff --git a/simulation/VirtualLedBoard/udpserver.cpp b/simulation/VirtualLedBoard/udpserver.cpp new file mode 100644 index 0000000..0acdf06 --- /dev/null +++ b/simulation/VirtualLedBoard/udpserver.cpp @@ -0,0 +1,74 @@ +#include "udpserver.h" +#include "settings.h" +#include +#include +#include "mainwindow.h" + +#define UDP_IMAGE_PORT 4242 + +UdpLedServer::UdpLedServer (QObject *parent, MainWindow *window) + : QObject(parent) +{ + initSocket(); + connect(this, + &UdpLedServer::changeLEDstate, + window, + &MainWindow::setLED); + connect(this, + &UdpLedServer::updatePanelContent, + window, + &MainWindow::updatePanel); + + + for(int x=0; x < (PANEL_WIDTH * MAXIMUM_PANELSIZE); x++) { + for(int y=0; y < PANEL_HEIGHT; y++) { + changeLEDstate(x, y); + } + } + updatePanelContent(); + +} + +void UdpLedServer ::initSocket() +{ + this->mUdpSocket = new QUdpSocket(this); + this->mUdpSocket->bind(QHostAddress::LocalHost, UDP_IMAGE_PORT); + + connect(this->mUdpSocket, &QUdpSocket::readyRead, + this, &UdpLedServer ::readPendingDatagrams); +} + + +void UdpLedServer ::readPendingDatagrams() +{ + while (this->mUdpSocket->hasPendingDatagrams()) { + QNetworkDatagram datagram = this->mUdpSocket->receiveDatagram(); + processTheDatagram(datagram); + } +} + +void UdpLedServer::processTheDatagram(QNetworkDatagram datagram) { + if (datagram.isValid() && datagram.data().length() == PACKET_LENGTH) { + uint8_t brightness = datagram.data().at(PACKET_INDEX_BRIGHTNESS); + int currentIndex = PACKET_INDEX_PANEL0; + + uint16_t mask = 1; + for(int y=0; y < PANEL_HEIGHT; y++) { + for(int x=0; x < (PANEL_WIDTH * MAXIMUM_PANELSIZE); x++) { + if (datagram.data().at(currentIndex) & mask) { + this->changeLEDstate(x, y); + qDebug() << x << "x" << y << " set"; + } + mask = (mask << 1); + if (mask >= 256) { + mask = 1; + currentIndex++; + } + } + } + this->updatePanelContent(); + + qDebug() << "Received datagram:" << brightness; + + } +} diff --git a/simulation/VirtualLedBoard/udpserver.h b/simulation/VirtualLedBoard/udpserver.h new file mode 100644 index 0000000..023370b --- /dev/null +++ b/simulation/VirtualLedBoard/udpserver.h @@ -0,0 +1,29 @@ +#ifndef UDPSERVER_H +#define UDPSERVER_H + +#include +#include +#include "mainwindow.h" + +class MainWindow; + +class UdpLedServer : public QObject +{ + Q_OBJECT + +public: + /*UdpLedServer (QObject *parent = nullptr); */ + UdpLedServer (QObject *parent = nullptr, MainWindow *window = nullptr); + +private: + void initSocket(); + void readPendingDatagrams(); + QUdpSocket *mUdpSocket; + void processTheDatagram(QNetworkDatagram datagram); + +signals: + void changeLEDstate(uint8_t x, uint8_t y); + void updatePanelContent(void); +}; + +#endif // UDPSERVER_H