diff --git a/.gitmodules b/.gitmodules deleted file mode 100644 index 07ed0c7..0000000 --- a/.gitmodules +++ /dev/null @@ -1,3 +0,0 @@ -[submodule "MiddleWare/Libs"] - path = MiddleWare/Libs - url = git@github.com:SEAME-pt/Team02-Libs.git diff --git a/CMakeLists.txt b/CMakeLists.txt index 7c64b5c..0d191f7 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -16,15 +16,17 @@ set(CMAKE_AUTOMOC ON) set(CMAKE_AUTOUIC ON) set(CMAKE_AUTORCC ON) +include_directories(include) + # Add Resource File (QML and Other Resources) qt_add_resources(QT_RESOURCES ./ui/resources.qrc) # Define Executable Target -add_executable(InstrumentCluster +add_executable(InstrumentClusterApp ${QT_RESOURCES} ./src/main.cpp ./src/InstrumentCluster.cpp ./include/InstrumentCluster.hpp ) -target_link_libraries(InstrumentCluster zenohcxx::zenohc -lm -ldl Qt6::Core Qt6::DBus Qt6::Quick) +target_link_libraries(InstrumentClusterApp zenohcxx::zenohc -lm -ldl Qt6::Core Qt6::DBus Qt6::Quick) diff --git a/MiddleWare/CMakeLists.txt b/MiddleWare/CMakeLists.txt index c1de850..b7e4c90 100644 --- a/MiddleWare/CMakeLists.txt +++ b/MiddleWare/CMakeLists.txt @@ -10,8 +10,20 @@ set(zenohcxx_DIR "/usr/local/lib/cmake/zenohcxx") find_package(zenohc REQUIRED) find_package(zenohcxx REQUIRED) -add_executable(middleWare +# include(FetchContent) +# FetchContent_Declare( +# Libs +# GIT_REPOSITORY https://github.com/SEAME-pt/Team02-Libs +# GIT_TAG main +# ) +# FetchContent_MakeAvailable(Libs) + +# include_directories(${libs_SOURCE_DIR}/Communication/I2C/include) +# include_directories(${libs_SOURCE_DIR}/Communication/CAN/include) +# include_directories(${libs_SOURCE_DIR}/Peripherals/INA219/include) + +add_executable(MiddleWareApp ./src/main.cpp ) -target_link_libraries(middleWare PRIVATE zenohcxx::zenohc) +target_link_libraries(MiddleWareApp PRIVATE zenohcxx::zenohc) diff --git a/MiddleWare/Libs b/MiddleWare/Libs deleted file mode 160000 index 7f38a66..0000000 --- a/MiddleWare/Libs +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 7f38a66dbbf353c0a477578ca87646fb77df0599 diff --git a/MiddleWare/config/MiddleWareConfig.json b/MiddleWare/config/MiddleWareConfig.json new file mode 100644 index 0000000..6ec92e9 --- /dev/null +++ b/MiddleWare/config/MiddleWareConfig.json @@ -0,0 +1,17 @@ +{ + "mode": "peer", + "connect": { + "endpoints": ["tcp/127.0.0.1:7447"] + }, + "listen": { + "endpoints": ["tcp/127.0.0.1:7448"] + }, + "scouting": { + "multicast": { + "enabled": false + }, + "gossip": { + "enabled": false + } + } +} \ No newline at end of file diff --git a/MiddleWare/src/main.cpp b/MiddleWare/src/main.cpp index 740c371..5f1839a 100644 --- a/MiddleWare/src/main.cpp +++ b/MiddleWare/src/main.cpp @@ -39,13 +39,19 @@ int main(int argc, char** argv) std::cout << "CAN socket bound to can0 interface successfully." << std::endl; - Config config = Config::create_default(); - auto session = Session::open(std::move(config)); + auto config = Config::create_default(); + if (argc == 2) + { + config = Config::from_file(argv[1]); + } + 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")); + auto pubLights = session.declare_publisher(KeyExpr("seame/car/1/lights")); + auto pubGear = session.declare_publisher(KeyExpr("seame/car/1/gear")); while (1) { @@ -67,19 +73,49 @@ int main(int argc, char** argv) speed = wheelDiame * 3.14 * speed * 10 / 60; std::string speed_str = std::to_string(speed); - printf("Publishing speed: '%d'\n", 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); + double battery; + + memcpy(&battery, frame.data, sizeof(double)); + + float percentage = ((battery - 9.5f) / (12.6f - 9.5f)) * 100.0f; + battery = std::min(100.0f, std::max(0.0f, percentage)); std::string battery_str = std::to_string(battery); - printf("Publishing battery: '%d\n", battery); + // printf("Publishing battery: '%lf\n", battery); pubBattery.put(battery_str.c_str()); } + else if (frame.can_id == 0x03) + { + char lights; + + memcpy(&lights, frame.data, sizeof(char)); + + printf("Can received lights: "); + for (int i = 7; i >= 0; i--) + { + printf("%d", (lights >> i) & 0x01); + } + printf("\n"); + + // printf("Publishing lights: '%lf\n", lights[0]); + std::string light_str(1, lights); + pubLights.put(light_str); + } + else if (frame.can_id == 0x04) + { + char gear; + + memcpy(&gear, frame.data, sizeof(char)); + + // printf("Publishing gear: '%lf\n", gear[0]); + std::string gear_str(1, gear); + pubGear.put(std::to_string(gear_str)); + } usleep(10); } return 0; diff --git a/assets/icons/cloud.png b/assets/icons/cloud.png new file mode 100644 index 0000000..bf33132 Binary files /dev/null and b/assets/icons/cloud.png differ diff --git a/assets/icons/watch.png b/assets/icons/watch.png new file mode 100644 index 0000000..d10bfb5 Binary files /dev/null and b/assets/icons/watch.png differ diff --git a/assets/images/car.png b/assets/images/car.png new file mode 100644 index 0000000..8c7fa69 Binary files /dev/null and b/assets/images/car.png differ diff --git a/config/InstrumentClusterConfig.json b/config/InstrumentClusterConfig.json new file mode 100644 index 0000000..e63c57c --- /dev/null +++ b/config/InstrumentClusterConfig.json @@ -0,0 +1,17 @@ +{ + "mode": "peer", + "connect": { + "endpoints": [] + }, + "listen": { + "endpoints": ["tcp/127.0.0.1:7447"] + }, + "scouting": { + "multicast": { + "enabled": false + }, + "gossip": { + "enabled": false + } + } +} \ No newline at end of file diff --git a/include/InstrumentCluster.hpp b/include/InstrumentCluster.hpp index 9d8590e..89f23a3 100644 --- a/include/InstrumentCluster.hpp +++ b/include/InstrumentCluster.hpp @@ -7,90 +7,120 @@ using namespace zenoh; -class InstrumentCluster : public QObject +struct LightStatus { - Q_OBJECT - Q_PROPERTY(int speed READ getSpeed NOTIFY speedChanged) - Q_PROPERTY(int battery READ getBattery NOTIFY batteryChanged) - Q_PROPERTY( - bool rightBlinker READ getRightBlinker NOTIFY rightBlinkerChanged) - Q_PROPERTY(bool leftBlinker READ getLeftBlinker NOTIFY leftBlinkerChanged) - Q_PROPERTY(bool lowBeam READ getLowBeam NOTIFY lowBeamChanged) - Q_PROPERTY(bool highBeam READ getHighBeam NOTIFY highBeamChanged) - Q_PROPERTY( - bool frontFogLight READ getFrontFogLight NOTIFY frontFogLightChanged) - Q_PROPERTY( - bool readFogLight READ getRearFogLight NOTIFY rearFogLightChanged) - Q_PROPERTY(bool hazardLight READ getHazardLight NOTIFY hazardLightChanged) - Q_PROPERTY( - bool parkingLight READ getParkingLight NOTIFY parkingLightChanged) - Q_PROPERTY(GearPosition gear READ getGear NOTIFY gearChanged) + Q_GADGET + + Q_PROPERTY(bool rightBlinker MEMBER rightBlinker) + Q_PROPERTY(bool leftBlinker MEMBER leftBlinker) + Q_PROPERTY(bool lowBeam MEMBER lowBeam) + Q_PROPERTY(bool highBeam MEMBER highBeam) + Q_PROPERTY(bool frontFogLight MEMBER frontFogLight) + Q_PROPERTY(bool rearFogLight MEMBER rearFogLight) + Q_PROPERTY(bool hazardLight MEMBER hazardLight) + Q_PROPERTY(bool parkingLight MEMBER parkingLight) + + public: + bool rightBlinker{false}; + bool leftBlinker{false}; + bool lowBeam{false}; + bool highBeam{false}; + bool frontFogLight{false}; + bool rearFogLight{false}; + bool hazardLight{false}; + bool parkingLight{false}; + + bool operator!=(const LightStatus& lights) const + { + return rightBlinker != lights.rightBlinker || + leftBlinker != lights.leftBlinker || lowBeam != lights.lowBeam || + highBeam != lights.highBeam || + frontFogLight != lights.frontFogLight || + rearFogLight != lights.rearFogLight || + hazardLight != lights.hazardLight || + parkingLight != lights.parkingLight; + } +}; + +struct BatteryStatus +{ + Q_GADGET + + Q_PROPERTY(int percentage MEMBER percentage) + Q_PROPERTY(int autonomy MEMBER autonomy) + + public: + int percentage; + int autonomy; + + bool operator!=(const BatteryStatus& battery) const + { + return percentage != battery.percentage || autonomy != battery.autonomy; + } +}; + +struct GearPosition +{ + Q_GADGET + + Q_PROPERTY(bool park MEMBER park) + Q_PROPERTY(bool reverse MEMBER reverse) + Q_PROPERTY(bool neutral MEMBER neutral) + Q_PROPERTY(bool drive MEMBER drive) public: - enum class GearPosition + bool park{true}; + bool reverse{false}; + bool neutral{false}; + bool drive{false}; + + bool operator!=(const GearPosition& gear) const { - PARK, - REVERSE, - NEUTRAL, - DRIVE - }; + return park != gear.park || reverse != gear.reverse || + neutral != gear.neutral || drive != gear.drive; + } +}; - Q_ENUM(GearPosition) +class InstrumentCluster : public QObject +{ + Q_OBJECT + Q_PROPERTY(int speed READ getSpeed NOTIFY speedChanged) + Q_PROPERTY(BatteryStatus battery READ getBattery NOTIFY batteryChanged) + Q_PROPERTY(LightStatus lights READ getLights NOTIFY lightsChanged) + Q_PROPERTY(GearPosition gear READ getGear NOTIFY gearChanged) private: int m_speed; - int m_battery; - bool m_rightBlinker; - bool m_leftBlinker; - bool m_lowBeam; - bool m_highBeam; - bool m_frontFogLight; - bool m_rearFogLight; - bool m_hazardLight; - bool m_parkingLight; + BatteryStatus m_battery; + LightStatus m_lights; GearPosition m_gear; - Session& m_session; + Session m_session; + Subscriber m_subSpeed; + Subscriber m_subBattery; + Subscriber m_subLights; + Subscriber m_subGear; public: - explicit InstrumentCluster(Session& session, QObject* parent = nullptr); + explicit InstrumentCluster(QObject* parent = nullptr); + explicit InstrumentCluster(const std::string& configFile, + QObject* parent = nullptr); ~InstrumentCluster(); int getSpeed() const; - int getBattery() const; - bool getRightBlinker() const; - bool getLeftBlinker() const; - bool getLowBeam() const; - bool getHighBeam() const; - bool getFrontFogLight() const; - bool getRearFogLight() const; - bool getHazardLight() const; - bool getParkingLight() const; + BatteryStatus getBattery() const; + LightStatus getLights() const; GearPosition getGear() const; void setSpeed(int speed); - void setBattery(int battery); - void setRightBlinker(bool rightBlinker); - void setLeftBlinker(bool leftBlinker); - void setLowBeam(bool lowBeam); - void setHighBeam(bool highBeam); - void setFrontFogLight(bool frontFogLight); - void setRearFogLight(bool readFogLight); - void setHazardLight(bool hazardLight); - void setParkingLight(bool parkingLight); + void setBattery(BatteryStatus battery); + void setLights(LightStatus lights); void setGear(GearPosition gear); signals: void speedChanged(int speed); - void batteryChanged(int battery); - void rightBlinkerChanged(bool rightBlinker); - void leftBlinkerChanged(bool leftBlinker); - void lowBeamChanged(bool lowBeam); - void highBeamChanged(bool highBeam); - void frontFogLightChanged(bool frontFogLight); - void rearFogLightChanged(bool readFogLight); - void hazardLightChanged(bool hazardLight); - void parkingLightChanged(bool parkingLight); + void batteryChanged(BatteryStatus battery); + void lightsChanged(LightStatus lights); void gearChanged(GearPosition gear); }; diff --git a/src/InstrumentCluster.cpp b/src/InstrumentCluster.cpp index d8c0f11..c6911f9 100644 --- a/src/InstrumentCluster.cpp +++ b/src/InstrumentCluster.cpp @@ -1,10 +1,131 @@ -#include "../include/InstrumentCluster.hpp" - -InstrumentCluster::InstrumentCluster(Session& session, QObject* parent) - : QObject(parent), m_speed(0), m_battery(0), m_rightBlinker(false), - m_leftBlinker(false), m_lowBeam(false), m_highBeam(false), - m_frontFogLight(false), m_rearFogLight(false), m_hazardLight(false), - m_parkingLight(false), m_gear(GearPosition::PARK), m_session(session) +#include "InstrumentCluster.hpp" + +InstrumentCluster::InstrumentCluster(QObject* parent) + : QObject(parent), + m_session(Session::open(std::move(Config::create_default()))), + m_subSpeed(m_session.declare_subscriber( + "seame/car/1/speedSensor", + [this](const Sample& sample) + { + int speed = std::stoi(sample.get_payload().as_string()); + std::cout << "Sub speed" << std::endl; + this->setSpeed(speed); + }, + closures::none)), + m_subBattery(m_session.declare_subscriber( + "seame/car/1/batterySensor", + [this](const Sample& sample) + { + int batteryPercentage = + std::stoi(sample.get_payload().as_string()); + BatteryStatus battery; + battery.percentage = batteryPercentage; + std::cout << "Sub battery" << std::endl; + this->setBattery(battery); + }, + closures::none)), + m_subLights(m_session.declare_subscriber( + "seame/car/1/lights", + [this](const Sample& sample) + { + uint8_t data = + static_cast(sample.get_payload().as_string()[0]); + + LightStatus lights; + lights.rightBlinker = (data & (1 << 0)) != 0; + lights.leftBlinker = (data & (1 << 1)) != 0; + lights.lowBeam = (data & (1 << 2)) != 0; + lights.highBeam = (data & (1 << 3)) != 0; + lights.frontFogLight = (data & (1 << 4)) != 0; + lights.rearFogLight = (data & (1 << 5)) != 0; + lights.hazardLight = (data & (1 << 6)) != 0; + lights.parkingLight = (data & (1 << 7)) != 0; + std::cout << "Sub lights" << std::endl; + this->setLights(lights); + }, + closures::none)), + m_subGear(m_session.declare_subscriber( + "seame/car/1/gear", + [this](const Sample& sample) + { + uint8_t data = + static_cast(sample.get_payload().as_string()[0]); + + GearPosition gear; + gear.park = (data & (1 << 0)) != 0; + gear.reverse = (data & (1 << 1)) != 0; + gear.neutral = (data & (1 << 2)) != 0; + gear.drive = (data & (1 << 3)) != 0; + std::cout << "Sub gear" << std::endl; + this->setGear(gear); + }, + closures::none)), + m_speed(0) +{ +} + +InstrumentCluster::InstrumentCluster(const std::string& configFile, + QObject* parent) + : QObject(parent), + m_session(Session::open(std::move(Config::from_file(configFile)))), + m_subSpeed(m_session.declare_subscriber( + "seame/car/1/speedSensor", + [this](const Sample& sample) + { + int speed = std::stoi(sample.get_payload().as_string()); + std::cout << "Sub speed" << std::endl; + this->setSpeed(speed); + }, + closures::none)), + m_subBattery(m_session.declare_subscriber( + "seame/car/1/batterySensor", + [this](const Sample& sample) + { + int batteryPercentage = + std::stoi(sample.get_payload().as_string()); + BatteryStatus battery; + battery.percentage = batteryPercentage; + std::cout << "Sub battery" << std::endl; + this->setBattery(battery); + }, + closures::none)), + m_subLights(m_session.declare_subscriber( + "seame/car/1/lights", + [this](const Sample& sample) + { + uint8_t data = + static_cast(sample.get_payload().as_string()[0]); + + LightStatus lights; + lights.rightBlinker = (data & (1 << 0)) != 0; + lights.leftBlinker = (data & (1 << 1)) != 0; + lights.lowBeam = (data & (1 << 2)) != 0; + lights.highBeam = (data & (1 << 3)) != 0; + lights.frontFogLight = (data & (1 << 4)) != 0; + lights.rearFogLight = (data & (1 << 5)) != 0; + lights.hazardLight = (data & (1 << 6)) != 0; + lights.parkingLight = (data & (1 << 7)) != 0; + std::cout << "Sub lights" << std::endl; + this->setLights(lights); + }, + closures::none)), + m_subGear(m_session.declare_subscriber( + "seame/car/1/gear", + [this](const Sample& sample) + { + uint8_t data = + static_cast(sample.get_payload().as_string()[0]); + + GearPosition gear; + gear.park = (data & (1 << 0)) != 0; + gear.reverse = (data & (1 << 1)) != 0; + gear.neutral = (data & (1 << 2)) != 0; + gear.drive = (data & (1 << 3)) != 0; + std::cout << "Sub gear" << std::endl; + this->setGear(gear); + }, + closures::none)), + m_speed(0) { } @@ -18,52 +139,17 @@ int InstrumentCluster::getSpeed() const return m_speed; } -int InstrumentCluster::getBattery() const +BatteryStatus InstrumentCluster::getBattery() const { return m_battery; } -bool InstrumentCluster::getRightBlinker() const -{ - return m_rightBlinker; -} - -bool InstrumentCluster::getLeftBlinker() const +LightStatus InstrumentCluster::getLights() const { - return m_leftBlinker; + return m_lights; } -bool InstrumentCluster::getLowBeam() const -{ - return m_lowBeam; -} - -bool InstrumentCluster::getHighBeam() const -{ - return m_highBeam; -} - -bool InstrumentCluster::getFrontFogLight() const -{ - return m_frontFogLight; -} - -bool InstrumentCluster::getRearFogLight() const -{ - return m_rearFogLight; -} - -bool InstrumentCluster::getHazardLight() const -{ - return m_hazardLight; -} - -bool InstrumentCluster::getParkingLight() const -{ - return m_parkingLight; -} - -InstrumentCluster::GearPosition InstrumentCluster::getGear() const +GearPosition InstrumentCluster::getGear() const { return m_gear; } @@ -77,7 +163,7 @@ void InstrumentCluster::setSpeed(int speed) } } -void InstrumentCluster::setBattery(int battery) +void InstrumentCluster::setBattery(BatteryStatus battery) { if (m_battery != battery) { @@ -86,75 +172,12 @@ void InstrumentCluster::setBattery(int battery) } } -void InstrumentCluster::setRightBlinker(bool rightBlinker) -{ - if (m_rightBlinker != rightBlinker) - { - m_rightBlinker = rightBlinker; - emit rightBlinkerChanged(m_rightBlinker); - } -} - -void InstrumentCluster::setLeftBlinker(bool leftBlinker) -{ - if (m_leftBlinker != leftBlinker) - { - m_leftBlinker = leftBlinker; - emit leftBlinkerChanged(m_leftBlinker); - } -} - -void InstrumentCluster::setLowBeam(bool lowBeam) -{ - if (m_lowBeam != lowBeam) - { - m_lowBeam = lowBeam; - emit lowBeamChanged(m_lowBeam); - } -} - -void InstrumentCluster::setHighBeam(bool highBeam) -{ - if (m_highBeam != highBeam) - { - m_highBeam = highBeam; - emit highBeamChanged(m_highBeam); - } -} - -void InstrumentCluster::setFrontFogLight(bool frontFogLight) -{ - if (m_frontFogLight != frontFogLight) - { - m_frontFogLight = frontFogLight; - emit frontFogLightChanged(m_frontFogLight); - } -} - -void InstrumentCluster::setRearFogLight(bool rearFogLight) -{ - if (m_rearFogLight != rearFogLight) - { - m_rearFogLight = rearFogLight; - emit rearFogLightChanged(m_rearFogLight); - } -} - -void InstrumentCluster::setHazardLight(bool hazardLight) -{ - if (m_hazardLight != hazardLight) - { - m_hazardLight = hazardLight; - emit hazardLightChanged(m_hazardLight); - } -} - -void InstrumentCluster::setParkingLight(bool parkingLight) +void InstrumentCluster::setLights(LightStatus lights) { - if (m_parkingLight != parkingLight) + if (m_lights != lights) { - m_parkingLight = parkingLight; - emit parkingLightChanged(m_parkingLight); + m_lights = lights; + emit lightsChanged(m_lights); } } diff --git a/src/main.cpp b/src/main.cpp index ffbc34f..6cbd359 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,19 +1,26 @@ #include #include #include -#include "../include/InstrumentCluster.hpp" +#include "InstrumentCluster.hpp" + +using namespace zenoh; int main(int argc, char* argv[]) { QGuiApplication app(argc, argv); QQmlApplicationEngine engine; - Config config = Config::create_default(); - auto session = Session::open(std::move(config)); - - InstrumentCluster instrumentCluster(session); + InstrumentCluster* instrumentCluster; + if (argc == 2) + { + instrumentCluster = new InstrumentCluster(argv[1]); + } + else + { + instrumentCluster = new InstrumentCluster(); + } engine.rootContext()->setContextProperty("instrumentCluster", - &instrumentCluster); + instrumentCluster); const QUrl url(QStringLiteral("qrc:/Main.qml")); QObject::connect( @@ -26,117 +33,7 @@ int main(int argc, char* argv[]) Qt::QueuedConnection); engine.load(url); - auto speed_handler = [&instrumentCluster](const Sample& sample) - { - int speed = std::stoi(sample.get_payload().as_string()); - std::cout << "Sub speed: " << speed << std::endl; - instrumentCluster.setSpeed(speed); - }; - - auto battery_handler = [&instrumentCluster](const Sample& sample) - { - int battery = std::stoi(sample.get_payload().as_string()); - std::cout << "Sub battery: " << battery << std::endl; - instrumentCluster.setBattery(battery); - }; - - auto rightBlinker_handler = [&instrumentCluster](const Sample& sample) - { - int rightBlinker = std::stoi(sample.get_payload().as_string()); - std::cout << "Sub rightBlinker: " << rightBlinker << std::endl; - instrumentCluster.setRightBlinker(rightBlinker); - }; - - auto leftBlinker_handler = [&instrumentCluster](const Sample& sample) - { - int leftBlinker = std::stoi(sample.get_payload().as_string()); - std::cout << "Sub leftBlinker: " << leftBlinker << std::endl; - instrumentCluster.setLeftBlinker(leftBlinker); - }; - - auto lowBeam_handler = [&instrumentCluster](const Sample& sample) - { - int lowBeam = std::stoi(sample.get_payload().as_string()); - std::cout << "Sub lowBeam: " << lowBeam << std::endl; - instrumentCluster.setLowBeam(lowBeam); - }; - - auto highBeam_handler = [&instrumentCluster](const Sample& sample) - { - int highBeam = std::stoi(sample.get_payload().as_string()); - std::cout << "Sub highBeam: " << highBeam << std::endl; - instrumentCluster.setHighBeam(highBeam); - }; - - auto frontFogLight_handler = [&instrumentCluster](const Sample& sample) - { - int frontFogLight = std::stoi(sample.get_payload().as_string()); - std::cout << "Sub frontFogLight: " << frontFogLight << std::endl; - instrumentCluster.setFrontFogLight(frontFogLight); - }; - - auto rearFogLight_handler = [&instrumentCluster](const Sample& sample) - { - int rearFogLight = std::stoi(sample.get_payload().as_string()); - std::cout << "Sub rearFogLight: " << rearFogLight << std::endl; - instrumentCluster.setRearFogLight(rearFogLight); - }; - - auto hazardLight_handler = [&instrumentCluster](const Sample& sample) - { - int hazardLight = std::stoi(sample.get_payload().as_string()); - std::cout << "Sub frontFogLight: " << hazardLight << std::endl; - instrumentCluster.setHazardLight(hazardLight); - }; - - auto parkingLight_handler = [&instrumentCluster](const Sample& sample) - { - int parkingLight = std::stoi(sample.get_payload().as_string()); - std::cout << "Sub parkingLight: " << parkingLight << std::endl; - instrumentCluster.setParkingLight(parkingLight); - }; - - auto gear_handler = [&instrumentCluster](const Sample& sample) - { - int gear = std::stoi(sample.get_payload().as_string()); - std::cout << "Sub gear: " << gear << std::endl; - instrumentCluster.setGear(InstrumentCluster::GearPosition::PARK); - }; - - 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); - - auto subRightBlinker = session.declare_subscriber( - "seame/car/1/rightBlinker", rightBlinker_handler, closures::none); - - auto subLeftBlinker = session.declare_subscriber( - "seame/car/1/leftBlinker", leftBlinker_handler, closures::none); - - auto subLowBeam = session.declare_subscriber( - "seame/car/1/lowBeam", lowBeam_handler, closures::none); - - auto subHighBeam = session.declare_subscriber( - "seame/car/1/highBeam", highBeam_handler, closures::none); - - auto subFrontFogLight = session.declare_subscriber( - "seame/car/1/frontFogLight", frontFogLight_handler, closures::none); - - auto subRearFogLight = session.declare_subscriber( - "seame/car/1/rearFogLight", rearFogLight_handler, closures::none); - - auto subHazardLight = session.declare_subscriber( - "seame/car/1/hazardLight", hazardLight_handler, closures::none); - - auto subParkingLight = session.declare_subscriber( - "seame/car/1/parkingLight", parkingLight_handler, closures::none); - - auto subGear = session.declare_subscriber("seame/car/1/gear", gear_handler, - closures::none); - - std::cout << "Subs created!" << std::endl; - - return app.exec(); + int result = app.exec(); + delete instrumentCluster; + return result; } diff --git a/ui/CircularProgressBar.qml b/ui/CircularProgressBar.qml new file mode 100644 index 0000000..f3446ab --- /dev/null +++ b/ui/CircularProgressBar.qml @@ -0,0 +1,67 @@ +import QtQuick 2.9 + +Item { + id: root + + property int size: 150 + property int lineWidth: 5 + property real value: 0 + + property color primaryColor: "#29b6f6" + property color secondaryColor: "#e0e0e0" + + property int animationDuration: 1000 + + width: size + height: size + + onValueChanged: { + canvas.degree = value * 360; + } + + Canvas { + id: canvas + + property real degree: 0 + + anchors.fill: parent + antialiasing: true + + onDegreeChanged: { + requestPaint(); + } + + onPaint: { + var ctx = getContext("2d"); + + var x = root.width/2; + var y = root.height/2; + + var radius = root.size/2 - root.lineWidth + var startAngle = (Math.PI/180) * 270; + var fullAngle = (Math.PI/180) * (270 + 360); + var progressAngle = (Math.PI/180) * (270 + degree); + + ctx.reset() + + ctx.lineCap = 'round'; + ctx.lineWidth = root.lineWidth; + + ctx.beginPath(); + ctx.arc(x, y, radius, startAngle, fullAngle); + ctx.strokeStyle = root.secondaryColor; + ctx.stroke(); + + ctx.beginPath(); + ctx.arc(x, y, radius, startAngle, progressAngle); + ctx.strokeStyle = root.primaryColor; + ctx.stroke(); + } + + Behavior on degree { + NumberAnimation { + duration: root.animationDuration + } + } + } +} \ No newline at end of file diff --git a/ui/FootbarInfo.qml b/ui/FootbarInfo.qml index 66ea725..c6cc028 100644 --- a/ui/FootbarInfo.qml +++ b/ui/FootbarInfo.qml @@ -5,74 +5,26 @@ Row { height: 50 spacing: 30 padding: 10 - Column { + Column { Row { + spacing: 5 - anchors.verticalCenterOffset: -10 Image { - id: batteryLevel - // source: { - // if (canBusHandler.battery >= 80) { - // "qrc:/assets/icons/battery-5.png" - // } else if (canBusHandler.battery >= 60) { - // "qrc:/assets/icons/battery-4.png" - // } else if (canBusHandler.battery >= 40) { - // "qrc:/assets/icons/battery-3.png" - // } else if (canBusHandler.battery >= 20) { - // "qrc:/assets/icons/battery-2.png" - // } else { - // "qrc:/assets/icons/battery-1.png" - // } - // } - width: 80 + id: cloudIcon + source: "qrc:/assets/icons/cloud.png" + width: app.iconWidth - 5 + height: app.iconHeight - 5 visible: true fillMode: Image.PreserveAspectFit - source: "qrc:/assets/icons/battery-5.png" - // Adjust this value to move the image up or down } - } - // Row { - // spacing: 5 - - // Text { - // font.family: "Open Sans" - // //text: canBusHandler.battery - // text: "100" - // font.pixelSize: app.letterSize - // color: "white" - // } - // Text { - // font.family: "Open Sans" - // text: "%" - // font.pixelSize: app.letterSize - // color: "gray" - // } - // } - } - - Column { - - Row { - spacing: 5 - Text { - font.family: "Open Sans" - text: "256" - font.pixelSize: app.letterSize - color: "white" - } - Text { - font.family: "Open Sans" - text: "mi" - font.pixelSize: app.letterSize - color: "gray" + + Rectangle { + width: 7 // Adjust the width to set the desired space + height: 1 + color: "transparent" } - } - } - Column { - Row { - spacing: 5 Text { font.family: "Open Sans" text: "22°" diff --git a/ui/GearShiftInfo.qml b/ui/GearShiftInfo.qml index ef5bbce..c00bfa4 100644 --- a/ui/GearShiftInfo.qml +++ b/ui/GearShiftInfo.qml @@ -1,29 +1,35 @@ import QtQuick 2.15 +// import com.example.gearPosition 1.0 + +Row { + spacing: 20 -Column { - spacing: 10 Text { font.family: "Open Sans" text: "P" - font.pixelSize: app.letterSize - color: "gray" + font.pixelSize: instrumentCluster.gear.park ? app.letterSizeLoaded : app.letterSize + color: instrumentCluster.gear.park ? "blue" : "white" + y: instrumentCluster.gear.park ? gearOffset : 0 } Text { font.family: "Open Sans" text: "R" - font.pixelSize: app.letterSize - color: "gray" + font.pixelSize: instrumentCluster.gear.reverse ? app.letterSizeLoaded : app.letterSize + color: instrumentCluster.gear.reverse ? "blue" : "white" + y: instrumentCluster.gear.reverse ? gearOffset : 0 } Text { font.family: "Open Sans" text: "N" - font.pixelSize: app.letterSize - color: "gray" + font.pixelSize: instrumentCluster.gear.neutral ? app.letterSizeLoaded : app.letterSize + color: instrumentCluster.gear.neutral ? "blue" : "white" + y: instrumentCluster.gear.neutral ? gearOffset : 0 } Text { font.family: "Open Sans" text: "D" - font.pixelSize: app.letterSize - color: "blue" + font.pixelSize: instrumentCluster.gear.drive ? app.letterSizeLoaded : app.letterSize + color: instrumentCluster.gear.drive ? "blue" : "white" + y: instrumentCluster.gear.drive ? gearOffset : 0 } } \ No newline at end of file diff --git a/ui/LightInfo.qml b/ui/LightInfo.qml index 0994884..2cf13e1 100644 --- a/ui/LightInfo.qml +++ b/ui/LightInfo.qml @@ -1,46 +1,81 @@ import QtQuick 2.15 Row { - spacing: 10 - padding: 10 + spacing: 20 - Image { - id: lowBeamSignal - source: "qrc:/assets/icons/low_beam_on.png" + Rectangle { width: app.iconWidth height: app.iconHeight - visible: true + color: "transparent" // Keeps the placeholder invisible + Image { + id: lowBeamSignal + anchors.centerIn: parent + width: parent.width + height: parent.height + source: "qrc:/assets/icons/low_beam_on.png" + // visible: instrumentCluster.lights.lowBeam + visible: true + + } } - Image { - id: highBeamSignal - source: "qrc:/assets/icons/high_beam_on.png" + Rectangle { width: app.iconWidth height: app.iconHeight - visible: true + color: "transparent" + Image { + id: highBeamSignal + anchors.centerIn: parent + width: parent.width + height: parent.height + source: "qrc:/assets/icons/high_beam_on.png" + // visible: instrumentCluster.lights.highBeam + visible: true + } } - Image { - id: frontFogSignal - source: "qrc:/assets/icons/front_fog_on.png" + Rectangle { width: app.iconWidth height: app.iconHeight - visible: true + color: "transparent" + Image { + id: frontFogSignal + anchors.centerIn: parent + width: parent.width + height: parent.height + source: "qrc:/assets/icons/front_fog_on.png" + // visible: instrumentCluster.lights.frontFogLight + visible: true + } } - Image { - id: parkingLightsSignal - source: "qrc:/assets/icons/parking_lights_on.png" + Rectangle { width: app.iconWidth height: app.iconHeight - visible: true + color: "transparent" + Image { + id: parkingLightsSignal + anchors.centerIn: parent + width: parent.width + height: parent.height + source: "qrc:/assets/icons/parking_lights_on.png" + // visible: instrumentCluster.lights.parkingLight + visible: true + } } - Image { - id: backFogSignal - source: "qrc:/assets/icons/back_fog_on.png" + Rectangle { width: app.iconWidth height: app.iconHeight - visible: true + color: "transparent" + Image { + id: backFogSignal + anchors.centerIn: parent + width: parent.width + height: parent.height + source: "qrc:/assets/icons/back_fog_on.png" + // visible: instrumentCluster.lights.rearFogLight + visible: true + } } } diff --git a/ui/Main.qml b/ui/Main.qml index 37c78f3..dafbfb4 100644 --- a/ui/Main.qml +++ b/ui/Main.qml @@ -1,18 +1,21 @@ import QtQuick 2.15 -import QtQuick.Controls 2.15 +import QtQuick.Window 2.2 +import QtQuick.Controls 2.4 ApplicationWindow { id: app visible: true width: Screen.width height: Screen.height - // flags: Qt.FramelessWindowHint + flags: Qt.Window | Qt.FramelessWindowHint | Qt.WindowStaysOnTopHint + visibility: Window.FullScreen // Add this line property int letterSize: 25 + property int letterSizeLoaded: 35 + property int gearOffset: -5 property int iconWidth: 40 property int iconHeight: 40 property bool carClusterVisible: true - property bool showSplash: true font.family: "Roboto" @@ -24,113 +27,157 @@ ApplicationWindow { anchors.fill: parent visible: app.carClusterVisible - // Background Gradient - Canvas { - anchors.fill: parent - onPaint: { - var ctx = getContext("2d"); - ctx.fillStyle = "#000000"; - ctx.fillRect(0, 0, width, height); + gradient: Gradient { + GradientStop { position: 0.0; color: "#000000" } + GradientStop { position: 0.5; color: "#153441" } // Turquoise color + GradientStop { position: 1.0; color: "#000000" } + } + Rectangle { + anchors.verticalCenter: parent.verticalCenter + anchors.horizontalCenter: parent.horizontalCenter + width: 420 + height: 420 + color: "transparent" + Image { + id: car + anchors.centerIn: parent + width: parent.width + height: parent.height + source: "qrc:/assets/images/car.png" + visible: true + fillMode: Image.PreserveAspectFit } } - Row { anchors.verticalCenter: parent.verticalCenter anchors.left: parent.left - anchors.leftMargin: 100 + anchors.leftMargin: 120 spacing: 10 - TurnSignals { - isLeft: true - isBlinking: true - } + TurnSignalLeft {} SpeedDisplay {} - TurnSignals { - isLeft: false - isBlinking: false + TurnSignalRight {} + } + + Row { + + anchors.right: parent.right + anchors.rightMargin: 105 + anchors.verticalCenter: parent.verticalCenter + spacing: 15 + CircularProgressBar { + id: batteryPercentage + lineWidth: 10 + value: 0.1 + size: 150 + secondaryColor: "#ffffff" + primaryColor: "#1b43c7" + + Text { + text: parseInt(batteryPercentage.value * 100) + "%" + anchors.centerIn: parent + font.pixelSize: 25 + color: "#ffffff" + } + } + + CircularProgressBar { + id: batteryAutonomy + lineWidth: 10 + value: 0.2 + size: 120 + secondaryColor: "#ffffff" + primaryColor: "#1ba5c7" + + Text { + text: parseInt(batteryAutonomy.value * 100) + "km" + anchors.centerIn: parent + font.pixelSize: 15 + color: "#ffffff" + } } + } GearShiftInfo { - anchors.verticalCenter: parent.verticalCenter - anchors.left: parent.left - anchors.leftMargin: 20 + anchors.bottom: parent.bottom + anchors.horizontalCenter: parent.horizontalCenter + anchors.bottomMargin: 15 } LightInfo { anchors.top: parent.top - anchors.topMargin: 30 - anchors.left: parent.left - anchors.leftMargin: 70 + anchors.horizontalCenter: parent.horizontalCenter + anchors.topMargin: 15 } FootbarInfo { - anchors.bottom: parent.bottom - anchors.bottomMargin: 60 + anchors.top: parent.top + anchors.topMargin: 10 anchors.left: parent.left - anchors.leftMargin: 70 + anchors.leftMargin: 30 } TimeInfo { - anchors.bottom: parent.bottom - anchors.bottomMargin: 60 + anchors.top: parent.top + anchors.topMargin: 10 anchors.right: parent.right - anchors.rightMargin: 70 + anchors.rightMargin: 30 } } - // Logo Screen - Rectangle { - id: splashScreen - visible: app.showSplash - anchors.fill: parent - color: "black" - - // O retângulo sempre fica visível, mas apenas o logo tem a opacidade animada - Image { - id: logo - source: "qrc:/assets/icons/seame-logo.png" // Substitua pelo logo do carro - anchors.centerIn: parent - width: parent.width * 0.5 - height: parent.width * 0.5 - fillMode: Image.PreserveAspectFit - opacity: 1.0 // Começa visível - - SequentialAnimation { - running: true - loops: 1 - - // Transição para mostrar o logo - PropertyAnimation { - target: logo - property: "opacity" - from: 0.0 - to: 1.0 - duration: 3000 // 3 segundos - } - - PauseAnimation { duration: 1000 } // Aguarda 1 segundo com o logo visível - - // Transição para esconder o logo - PropertyAnimation { - target: logo - property: "opacity" - from: 1.0 - to: 0.0 - duration: 2000 // 2 segundos - } - - PauseAnimation { duration: 1000 } // Aguarda 2 segundos com a tela preta - - ScriptAction { - script: { - app.showSplash = false; // Oculta a splash screen - app.carClusterVisible = true; // Mostra o cluster - } - } - } - } - } + // // Logo Screen + // Rectangle { + // id: splashScreen + // visible: app.showSplash + // anchors.fill: parent + // color: "black" + + // // O retângulo sempre fica visível, mas apenas o logo tem a opacidade animada + // Image { + // id: logo + // source: "qrc:/assets/icons/seame-logo.png" // Substitua pelo logo do carro + // anchors.centerIn: parent + // width: parent.width * 0.5 + // height: parent.width * 0.5 + // fillMode: Image.PreserveAspectFit + // opacity: 1.0 // Começa visível + + // SequentialAnimation { + // running: true + // loops: 1 + + // // Transição para mostrar o logo + // PropertyAnimation { + // target: logo + // property: "opacity" + // from: 0.0 + // to: 1.0 + // duration: 3000 // 3 segundos + // } + + // PauseAnimation { duration: 1000 } // Aguarda 1 segundo com o logo visível + + // // Transição para esconder o logo + // PropertyAnimation { + // target: logo + // property: "opacity" + // from: 1.0 + // to: 0.0 + // duration: 2000 // 2 segundos + // } + + // PauseAnimation { duration: 1000 } // Aguarda 2 segundos com a tela preta + + // ScriptAction { + // script: { + // app.showSplash = false; // Oculta a splash screen + // app.carClusterVisible = true; // Mostra o cluster + // } + // } + // } + // } + // } } \ No newline at end of file diff --git a/ui/SpeedDisplay.qml b/ui/SpeedDisplay.qml index b7f1e3a..1f0cf1b 100644 --- a/ui/SpeedDisplay.qml +++ b/ui/SpeedDisplay.qml @@ -1,7 +1,8 @@ import QtQuick 2.15 + Column { - spacing: 5 + spacing: 3 Text { font.family: "Open Sans" diff --git a/ui/TimeInfo.qml b/ui/TimeInfo.qml index af12b9b..06a95b7 100644 --- a/ui/TimeInfo.qml +++ b/ui/TimeInfo.qml @@ -2,8 +2,21 @@ import QtQuick 2.15 Row { spacing: 5 + Image { + id: clockIcon + source: "qrc:/assets/icons/watch.png" + width: app.iconWidth - 5 + height: app.iconHeight - 5 + visible: true + fillMode: Image.PreserveAspectFit + } + + Rectangle { + width: 7 // Adjust the width to set the desired space + height: 1 + color: "transparent" + } - // Hora Text { font.family: "Open Sans" id: timeDisplay @@ -13,7 +26,6 @@ Row { opacity: 0.0 } - // AM/PM Text { font.family: "Open Sans" id: amPmDisplay @@ -37,7 +49,6 @@ Row { } } - // Funções encapsuladas em um QtObject QtObject { id: timeHelper diff --git a/ui/TurnSignalLeft.qml b/ui/TurnSignalLeft.qml new file mode 100644 index 0000000..4ff9157 --- /dev/null +++ b/ui/TurnSignalLeft.qml @@ -0,0 +1,34 @@ +import QtQuick 2.15 + + +Row { + id: root + spacing: 10 + + Rectangle { + width: 70 + height: 70 + color: "transparent" + Image { + anchors.verticalCenter: parent.verticalCenter + id: turnSignal + source: "qrc:/assets/icons/turn_left_on.png" + width: 70 + height: 70 + opacity: 0.0 + visible: instrumentCluster.lights.leftBlinker + + Timer { + id: blinkTimer + interval: 500 + running: instrumentCluster.lights.leftBlinker + repeat: true + onTriggered: { + // Toggle opacity when blinking + turnSignal.opacity = turnSignal.opacity === 1.0 ? 0.0 : 1.0; + } + } + } + } +} + diff --git a/ui/TurnSignalRight.qml b/ui/TurnSignalRight.qml new file mode 100644 index 0000000..a2592fd --- /dev/null +++ b/ui/TurnSignalRight.qml @@ -0,0 +1,32 @@ +import QtQuick 2.15 + +Row { + id: root + spacing: 10 + + Rectangle { + width: 70 + height: 70 + color: "transparent" + Image { + anchors.verticalCenter: parent.verticalCenter + id: turnSignal + source: "qrc:/assets/icons/turn_right_on.png" + width: 70 + height: 70 + opacity: 0.0 + visible: instrumentCluster.lights.rightBlinker + + Timer { + id: blinkTimer + interval: 500 + running: instrumentCluster.lights.rightBlinker + repeat: true + onTriggered: { + // Toggle opacity when blinking + turnSignal.opacity = turnSignal.opacity === 1.0 ? 0.0 : 1.0; + } + } + } + } +} diff --git a/ui/TurnSignals.qml b/ui/TurnSignals.qml deleted file mode 100644 index 3d33a4e..0000000 --- a/ui/TurnSignals.qml +++ /dev/null @@ -1,32 +0,0 @@ -import QtQuick 2.15 - -Row { - id: root - spacing: 10 - - property bool isLeft: true - property bool isBlinking: false - - Image { - anchors.verticalCenter: parent.verticalCenter - id: turnSignal - source: isLeft ? "qrc:/assets/icons/turn_left_on.png" : "qrc:/assets/icons/turn_right_on.png" - width: 70 - height: 70 - opacity: 0.0 - - Timer { - id: blinkTimer - interval: 500 - running: root.isBlinking - repeat: true - onTriggered: { - if (turnSignal.isBlinking) { - turnSignal.opacity = turnSignal.opacity === 1.0 ? 0.0 : 1.0; - } else { - turnSignal.opacity = 0.0; - } - } - } - } -} diff --git a/ui/resources.qrc b/ui/resources.qrc index 27ab5eb..e89189b 100644 --- a/ui/resources.qrc +++ b/ui/resources.qrc @@ -1,13 +1,14 @@ Main.qml - TurnSignals.qml + TurnSignalLeft.qml + TurnSignalRight.qml SpeedDisplay.qml LightInfo.qml FootbarInfo.qml GearShiftInfo.qml TimeInfo.qml - + CircularProgressBar.qml @@ -25,5 +26,10 @@ ../assets/icons/battery-3.png ../assets/icons/battery-4.png ../assets/icons/battery-5.png + ../assets/icons/cloud.png + ../assets/icons/watch.png + + + ../assets/images/car.png \ No newline at end of file