diff --git a/CMakeLists.txt b/CMakeLists.txt index 4f428e0..2651e9c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,12 +1,16 @@ -cmake_minimum_required(VERSION 3.5) +cmake_minimum_required(VERSION 3.10) -project(HelloQt6 LANGUAGES CXX) +project(Cluster LANGUAGES CXX) message("CMAKE_SYSROOT " ${CMAKE_SYSROOT}) message("CMAKE_LIBRARY_ARCHITECTURE " ${CMAKE_LIBRARY_ARCHITECTURE}) -set(CMAKE_CXX_STANDARD 11) +set(CMAKE_CXX_STANDARD 17) set(CMAKE_CXX_STANDARD_REQUIRED ON) +set(zenohc_DIR "/usr/local/lib/cmake/zenohc") +set(zenohcxx_DIR "/usr/local/lib/cmake/zenohcxx") find_package(Qt6 COMPONENTS Core Quick DBus SerialBus REQUIRED) +find_package(zenohc REQUIRED) +find_package(zenohcxx REQUIRED) set(CMAKE_C_FLAGS "${CMAKE_CXX_FLAGS} -fPIC -Wl,-rpath-link, ${CMAKE_SYSROOT}/usr/lib/${CMAKE_LIBRARY_ARCHITECTURE} -L${CMAKE_SYSROOT}/usr/lib/${CMAKE_LIBRARY_ARCHITECTURE}") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fPIC -Wl,-rpath-link,${CMAKE_SYSROOT}/usr/lib/${CMAKE_LIBRARY_ARCHITECTURE} -L${CMAKE_SYSROOT}/usr/lib/${CMAKE_LIBRARY_ARCHITECTURE}") @@ -23,5 +27,10 @@ add_executable(speedometer ${QT_RESOURCES} ./include/CANBusHandler.hpp ) -target_link_libraries(speedometer -lm -ldl Qt6::Core Qt6::DBus Qt6::Quick Qt6::SerialBus) +target_link_libraries(speedometer zenohcxx::zenohc -lm -ldl Qt6::Core Qt6::DBus Qt6::Quick Qt6::SerialBus) +add_executable(zenoh + ./middelWare/src/main.cpp +) + +target_link_libraries(zenoh PRIVATE zenohcxx::zenohc) diff --git a/include/CANBusHandler.hpp b/include/CANBusHandler.hpp index 0fb3df9..041e97e 100644 --- a/include/CANBusHandler.hpp +++ b/include/CANBusHandler.hpp @@ -1,35 +1,35 @@ #ifndef CANBUSHANDLER_HPP #define CANBUSHANDLER_HPP -#include +#include +#include +#include "zenoh.hxx" + +using namespace zenoh; class CANBusHandler : public QObject { Q_OBJECT - Q_PROPERTY(int speed READ getSpeed WRITE setSpeed NOTIFY speedChanged) - Q_PROPERTY( - int battery READ getBattery WRITE setBattery NOTIFY batteryChanged) + Q_PROPERTY(int speed READ getSpeed NOTIFY speedChanged) + Q_PROPERTY(int battery READ getBattery NOTIFY batteryChanged) public: - explicit CANBusHandler(QObject* parent = nullptr); + explicit CANBusHandler(Session& session, QObject* parent = nullptr); ~CANBusHandler(); int getSpeed() const; - void setSpeed(int speed); int getBattery() const; + void setSpeed(int speed); void setBattery(int battery); signals: void speedChanged(int speed); void batteryChanged(int battery); - private slots: - void readFrames(); - private: - int canSocket; int m_speed; int m_battery; + Session& m_session; }; #endif // CANBUSHANDLER_HPP diff --git a/middelWare/src/main.cpp b/middelWare/src/main.cpp new file mode 100644 index 0000000..740c371 --- /dev/null +++ b/middelWare/src/main.cpp @@ -0,0 +1,86 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "zenoh.hxx" + +using namespace zenoh; + +int main(int argc, char** argv) +{ + struct ifreq ifr; + struct sockaddr_can addr; + + int canSocket = socket(PF_CAN, SOCK_RAW, CAN_RAW); + if (canSocket < 0) + { + std::cerr << "Cannot create CAN socket!" << std::endl; + exit(-1); + } + + strcpy(ifr.ifr_name, "can0"); + ioctl(canSocket, SIOCGIFINDEX, &ifr); + + addr.can_family = AF_CAN; + addr.can_ifindex = ifr.ifr_ifindex; + if (bind(canSocket, (struct sockaddr*)&addr, sizeof(addr)) < 0) + { + std::cerr << "Cannot bind CAN socket!" << std::endl; + close(canSocket); + exit(1); + } + + std::cout << "CAN socket bound to can0 interface successfully." + << std::endl; + + Config config = Config::create_default(); + auto session = Session::open(std::move(config)); + + auto pubSpeed = + session.declare_publisher(KeyExpr("seame/car/1/speedSensor")); + auto pubBattery = + session.declare_publisher(KeyExpr("seame/car/1/batterySensor")); + + while (1) + { + struct can_frame frame; + + int nbytes = read(canSocket, &frame, sizeof(struct can_frame)); + if (nbytes < 0) + { + std::cerr << "Error reading CAN frame!" << std::endl; + continue; + } + if (frame.can_id == 0x01) + { + int speed; + double wheelDiame = 0.067; + + memcpy(&speed, frame.data, sizeof(int)); + speed = ntohl(speed); + speed = wheelDiame * 3.14 * speed * 10 / 60; + std::string speed_str = std::to_string(speed); + + printf("Publishing speed: '%d'\n", speed); + pubSpeed.put(speed_str.c_str()); + } + else if (frame.can_id == 0x02) + { + int battery; + memcpy(&battery, frame.data, sizeof(int)); + battery = ntohl(battery); + std::string battery_str = std::to_string(battery); + + printf("Publishing battery: '%d\n", battery); + pubBattery.put(battery_str.c_str()); + } + usleep(10); + } + return 0; +} diff --git a/src/CANBusHandler.cpp b/src/CANBusHandler.cpp index 23fb595..362386a 100644 --- a/src/CANBusHandler.cpp +++ b/src/CANBusHandler.cpp @@ -1,53 +1,13 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include #include "../include/CANBusHandler.hpp" -CANBusHandler::CANBusHandler(QObject* parent) - : QObject(parent), canSocket(-1), m_speed(0), m_battery(0) +CANBusHandler::CANBusHandler(Session& session, QObject* parent) + : QObject(parent), m_speed(0), m_battery(0), m_session(session) { - struct ifreq ifr; - struct sockaddr_can addr; - - canSocket = socket(PF_CAN, SOCK_RAW, CAN_RAW); - if (canSocket < 0) - { - qWarning() << "Cannot create CAN socket!"; - return; - } - - strcpy(ifr.ifr_name, "can0"); - ioctl(canSocket, SIOCGIFINDEX, &ifr); - - addr.can_family = AF_CAN; - addr.can_ifindex = ifr.ifr_ifindex; - if (bind(canSocket, (struct sockaddr*)&addr, sizeof(addr)) < 0) - { - qWarning() << "Cannot bind CAN socket!"; - close(canSocket); - return; - } - - qDebug() << "CAN socket bound to can0 interface successfully."; - - // Set up a timer to periodically read frames - QTimer* timer = new QTimer(this); - connect(timer, &QTimer::timeout, this, [this]() { readFrames(); }); - timer->start(10); // Adjust the interval as needed } CANBusHandler::~CANBusHandler() { - if (canSocket >= 0) - { - close(canSocket); // Close the CAN socket - } + m_session.close(); } int CANBusHandler::getSpeed() const @@ -55,6 +15,11 @@ int CANBusHandler::getSpeed() const return m_speed; } +int CANBusHandler::getBattery() const +{ + return m_battery; +} + void CANBusHandler::setSpeed(int speed) { if (m_speed != speed) @@ -64,49 +29,11 @@ void CANBusHandler::setSpeed(int speed) } } -int CANBusHandler::getBattery() const -{ - return m_battery; -} - void CANBusHandler::setBattery(int battery) { if (m_battery != battery) - { - m_battery = battery; emit batteryChanged(m_battery); - } -} - -void CANBusHandler::readFrames() -{ - struct can_frame frame; - int nbytes = read(canSocket, &frame, sizeof(struct can_frame)); - - if (nbytes < 0) { - qWarning() << "Error reading CAN frame!"; - return; - } - - if (frame.can_id == 0x01) - { - int speed; - memcpy(&speed, frame.data, sizeof(int)); - - speed = ntohl(speed); - - // qDebug() << "Speed:" << speed; // Print the speed value - setSpeed(speed); - } - else if (frame.can_id == 0x02) - { - int battery; - memcpy(&battery, frame.data, sizeof(int)); - - battery = ntohl(battery); - - // qDebug() << "Battery:" << battery; // Print the speed value - setBattery(battery); + m_battery = battery; } } diff --git a/src/Main.qml b/src/Main.qml index e7f8c01..53f97fa 100644 --- a/src/Main.qml +++ b/src/Main.qml @@ -1,18 +1,11 @@ import QtQuick 2.15 import QtQuick.Controls 2.15 -import canbus 1.0 ApplicationWindow { visible: true width: Screen.width height: Screen.height - title: "Instrument Cluster with Smooth Transitions" - - CANBusHandler { - id: canBusHandler - onSpeedChanged: speedGauge.requestPaint() - onBatteryChanged: batteryGauge.requestPaint() - } + flags: Qt.FramelessWindowHint Rectangle { anchors.fill: parent @@ -60,56 +53,22 @@ ApplicationWindow { } } - // Left Speedometer Gauge - Canvas { - id: speedGauge - width: 300 - height: 300 + Text { + text: canBusHandler.speed + font.pixelSize: 50 + color: "white" anchors.verticalCenter: parent.verticalCenter anchors.left: parent.left - anchors.leftMargin: 20 - - onPaint: { - var ctx = getContext("2d"); - ctx.clearRect(0, 0, width, height); - - // Speed Value - ctx.font = "36px sans-serif"; - ctx.fillStyle = "white"; - ctx.textAlign = "center"; - ctx.fillText(canBusHandler.speed, width / 2, height / 2); - - // Label - ctx.font = "18px sans-serif"; - ctx.fillStyle = "lightgray"; - ctx.fillText("Speed", width / 2, height / 2 + 40); - } + anchors.leftMargin: 300 } - // Right Battery Status Gauge - Canvas { - id: batteryGauge - width: 300 - height: 300 + Text { + text: canBusHandler.battery + font.pixelSize: 50 + color: "white" anchors.verticalCenter: parent.verticalCenter anchors.right: parent.right - anchors.rightMargin: 20 - - onPaint: { - var ctx = getContext("2d"); - ctx.clearRect(0, 0, width, height); - - // Battery Value - ctx.font = "36px sans-serif"; - ctx.fillStyle = "white"; - ctx.textAlign = "center"; - ctx.fillText(canBusHandler.battery + " %", width / 2, height / 2); - - // Label - ctx.font = "18px sans-serif"; - ctx.fillStyle = "lightgray"; - ctx.fillText("Battery", width / 2, height / 2 + 40); - } + anchors.rightMargin: 300 } } } diff --git a/src/main.cpp b/src/main.cpp index 925258e..e17a8b1 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,22 +1,19 @@ #include #include -#include #include -#include #include "../include/CANBusHandler.hpp" int main(int argc, char* argv[]) { QGuiApplication app(argc, argv); - QQmlApplicationEngine engine; - qmlRegisterType("canbus", 1, 0, "CANBusHandler"); + Config config = Config::create_default(); + auto session = Session::open(std::move(config)); - CANBusHandler canBusHandler; + CANBusHandler canBusHandler(session); engine.rootContext()->setContextProperty("canBusHandler", &canBusHandler); - // Load QML file const QUrl url(QStringLiteral("qrc:/Main.qml")); QObject::connect( &engine, &QQmlApplicationEngine::objectCreated, &app, @@ -28,5 +25,25 @@ int main(int argc, char* argv[]) Qt::QueuedConnection); engine.load(url); + auto speed_handler = [&canBusHandler](const Sample& sample) + { + int speed = std::stoi(sample.get_payload().as_string()); + std::cout << "Sub speed: " << speed << std::endl; + canBusHandler.setSpeed(speed); + }; + + auto battery_handler = [&canBusHandler](const Sample& sample) + { + int battery = std::stoi(sample.get_payload().as_string()); + std::cout << "Sub battery: " << battery << std::endl; + canBusHandler.setBattery(battery); + }; + + auto subSpeed = session.declare_subscriber("seame/car/1/speedSensor", + speed_handler, closures::none); + auto subBattery = session.declare_subscriber( + "seame/car/1/batterySensor", battery_handler, closures::none); + std::cout << "Subs created!" << std::endl; + return app.exec(); }