Skip to content
This repository was archived by the owner on Oct 6, 2025. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 13 additions & 4 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -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}")
Expand All @@ -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)
20 changes: 10 additions & 10 deletions include/CANBusHandler.hpp
Original file line number Diff line number Diff line change
@@ -1,35 +1,35 @@
#ifndef CANBUSHANDLER_HPP
#define CANBUSHANDLER_HPP

#include <QtCore/QObject>
#include <QObject>
#include <iostream>
#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
86 changes: 86 additions & 0 deletions middelWare/src/main.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
#include <stdio.h>
#include <iostream>
#include <string.h>
#include <sys/socket.h>
#include <linux/can.h>
#include <linux/can/raw.h>
#include <net/if.h>
#include <sys/ioctl.h>
#include <unistd.h>
#include <arpa/inet.h>
#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;
}
91 changes: 9 additions & 82 deletions src/CANBusHandler.cpp
Original file line number Diff line number Diff line change
@@ -1,60 +1,25 @@
#include <QtCore/QDebug>
#include <QtCore/QTimer>
#include <sys/socket.h>
#include <linux/can.h>
#include <linux/can/raw.h>
#include <net/if.h>
#include <sys/ioctl.h>
#include <unistd.h>
#include <arpa/inet.h>
#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
{
return m_speed;
}

int CANBusHandler::getBattery() const
{
return m_battery;
}

void CANBusHandler::setSpeed(int speed)
{
if (m_speed != speed)
Expand All @@ -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;
}
}
63 changes: 11 additions & 52 deletions src/Main.qml
Original file line number Diff line number Diff line change
@@ -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
Expand Down Expand Up @@ -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
}
}
}
Loading
Loading