From e0d4e05eb677233710e29e56863f47f7f07b7887 Mon Sep 17 00:00:00 2001 From: Jeremy Date: Sat, 23 Sep 2023 22:48:09 -0400 Subject: [PATCH] Add CAN logs --- UOSM-Dashboard/Core/Modules/CANCallbacks.c | 36 +++++++------ UOSM-Dashboard/Core/Src/main.c | 2 +- .../Core/UI/Data/DataAggregatorWrapper.cpp | 4 ++ .../Core/UI/Data/DataAggregatorWrapper.h | 13 +++++ UOSM-Dashboard/Core/UI/HomeView.hpp | 4 +- UOSM-Dashboard/Core/UI/StatsView.hpp | 4 +- UOSM-Dashboard/Core/UI/application.cpp | 20 ++++--- .../UOSM-Core/Inc/ApplicationTypes.h | 5 ++ .../UOSM-Core/Utils/CANLogEntry.hpp | 6 +-- UOSM-Dashboard/UOSM-Core/Utils/DataQueue.hpp | 53 +++++++++++++++++++ 10 files changed, 116 insertions(+), 31 deletions(-) diff --git a/UOSM-Dashboard/Core/Modules/CANCallbacks.c b/UOSM-Dashboard/Core/Modules/CANCallbacks.c index 8ae3466..9633ff5 100644 --- a/UOSM-Dashboard/Core/Modules/CANCallbacks.c +++ b/UOSM-Dashboard/Core/Modules/CANCallbacks.c @@ -28,20 +28,10 @@ void MotorRPMDataCallback(iCommsMessage_t* msg) { velocity_t rpm = readMsg(msg); DebugPrint("CAN rpm received: %d", rpm); SetMotorRPM(aggregatorWrapper, rpm * -1); -} - -void VoltageDataCallback(iCommsMessage_t* msg) { - if (!CAN_Enabled()) { - return; - } - - uint32_t voltage = readMsg(msg); - DebugPrint("CAN voltage received: %d", voltage); - SetBatteryVoltage(aggregatorWrapper, voltage); + LogCanMessage(aggregatorWrapper, MOTOR_RPM_DATA_ID, rpm, CAN_DECIMAL); } void ThrottleDataCallback(iCommsMessage_t* msg) { -// DebugPrint("ThrottleDataCallback not implemented! %d", msg->standardMessageID); if (!CAN_Enabled()) { return; } @@ -49,20 +39,36 @@ void ThrottleDataCallback(iCommsMessage_t* msg) { percentage_t throttle = readMsg(msg); DebugPrint("CAN throttle received: %d", throttle); SetThrottlePosition(aggregatorWrapper, throttle); + LogCanMessage(aggregatorWrapper, THROTTLE_DATA_ID, throttle, CAN_DECIMAL); } void ErrorDataCallback(iCommsMessage_t* msg) { - DebugPrint("ErrorDataCallback not implemented! %d", msg->standardMessageID); + if (msg->dataLength == CANMessageLookUpTable[ERROR_DATA_ID].numberOfBytes) { + ErrorCode code = msg->data[1]; + flag_status_t status = msg->data[0]; + LogCanMessagePairValue(aggregatorWrapper, ERROR_DATA_ID, code, status, CAN_DECIMAL); + } else { + DebugPrint("Received corrupted error CAN message."); + } } void SpeedDataCallback(iCommsMessage_t* msg) { - DebugPrint("SpeedDataCallback not implemented! %d", msg->standardMessageID); + speed_t speed = readMsg(msg); + LogCanMessage(aggregatorWrapper, SPEED_DATA_ID, speed, CAN_DECIMAL); } void EventDataCallback(iCommsMessage_t* msg) { - DebugPrint("EventDataCallback not implemented! %d", msg->standardMessageID); + if (msg->dataLength == CANMessageLookUpTable[EVENT_DATA_ID].numberOfBytes) { + EventCode code = (EventCode) msg->data[1]; + flag_status_t status = (flag_status_t) msg->data[0]; + LogCanMessagePairValue(aggregatorWrapper, EVENT_DATA_ID, code, status, CAN_DECIMAL); + } else { + DebugPrint("Received corrupted event CAN message."); + } } void CurrentVoltageDataCallback(iCommsMessage_t* msg) { - DebugPrint("CurrentVoltageDataCallback not implemented! %d", msg->standardMessageID); + uint16_pair_t pair = readMsgPairUInt16Bit(msg); + SetBatteryVoltage(aggregatorWrapper, pair.b); + LogCanMessagePairValue(aggregatorWrapper, CURRENT_VOLTAGE_DATA_ID, pair.a, pair.b, CAN_DECIMAL); } diff --git a/UOSM-Dashboard/Core/Src/main.c b/UOSM-Dashboard/Core/Src/main.c index 1612361..6eebcac 100644 --- a/UOSM-Dashboard/Core/Src/main.c +++ b/UOSM-Dashboard/Core/Src/main.c @@ -145,7 +145,7 @@ int main(void) { tft_init(); touchpad_init(); - DataAggregatorWrapper* wrapper = DataAggregator_Create(10, 10, 10, 10); + DataAggregatorWrapper* wrapper = DataAggregator_Create(10, 10, 10, 10, 10, 10); CAN_SetAggregator(wrapper); Application_Create(wrapper); diff --git a/UOSM-Dashboard/Core/UI/Data/DataAggregatorWrapper.cpp b/UOSM-Dashboard/Core/UI/Data/DataAggregatorWrapper.cpp index 2166f8c..7f32e09 100644 --- a/UOSM-Dashboard/Core/UI/Data/DataAggregatorWrapper.cpp +++ b/UOSM-Dashboard/Core/UI/Data/DataAggregatorWrapper.cpp @@ -33,6 +33,10 @@ void LogCanMessage(DataAggregatorWrapper* wrapper, ICommsMessageLookUpIndex type wrapper->aggregator.canLogEntries.add(new CANLogEntry(type, value, style)); } +void LogCanMessagePairValue(DataAggregatorWrapper* wrapper, ICommsMessageLookUpIndex type, uint32_t a, uint32_t b, CANLogEntryFormat style) { + wrapper->aggregator.canLogEntries.add(new CANLogEntry(type, a, b, style)); +} + DataAggregator& DataAggregator_GetReference(DataAggregatorWrapper* wrapper) { return wrapper->aggregator; } \ No newline at end of file diff --git a/UOSM-Dashboard/Core/UI/Data/DataAggregatorWrapper.h b/UOSM-Dashboard/Core/UI/Data/DataAggregatorWrapper.h index 2d8ff03..4470b5c 100644 --- a/UOSM-Dashboard/Core/UI/Data/DataAggregatorWrapper.h +++ b/UOSM-Dashboard/Core/UI/Data/DataAggregatorWrapper.h @@ -7,6 +7,7 @@ #include "ApplicationTypes.h" #include "DataAggregatorWrapperType.h" +#include "CANMessageLookUpModule.h" #ifdef __cplusplus extern "C" { @@ -46,6 +47,18 @@ void SetLapTime(DataAggregatorWrapper* wrapper, ms_t time); */ void SetThrottlePosition(DataAggregatorWrapper* wrapper, percentage_t throttle); +/** @ingroup core-modules + * Log a new can message in the data aggregator object from a given wrapper. + * @param wrapper The pointer to the wrapper that contains the data aggregator object. + * @param type The type of CAN message + * @param value The value to log + * @param style How to display the value in the logs + */ +void LogCanMessage(DataAggregatorWrapper* wrapper, ICommsMessageLookUpIndex type, uint32_t value, CANLogEntryFormat style); + +void LogCanMessagePairValue(DataAggregatorWrapper* wrapper, ICommsMessageLookUpIndex type, uint32_t a, uint32_t b, CANLogEntryFormat style); + + #ifdef __cplusplus } #endif diff --git a/UOSM-Dashboard/Core/UI/HomeView.hpp b/UOSM-Dashboard/Core/UI/HomeView.hpp index b399e3e..164bb3b 100644 --- a/UOSM-Dashboard/Core/UI/HomeView.hpp +++ b/UOSM-Dashboard/Core/UI/HomeView.hpp @@ -9,7 +9,7 @@ /** @ingroup core-ui * A class that represents a view that displays the home screen of the dashboard. - * It inherits from the View class and uses the \ref HomeViewModel class to get the data for the view elements. + * It inherits from the View class. */ class HomeView : public View { private: @@ -44,7 +44,7 @@ class HomeView : public View { public: /** Constructs a home view with a given parent and a home view model. * @param parent The parent object of the container, or NULL if the container is a screen. - * @param viewModel The reference to the home view model that provides the data for the view elements. + * @param aggregator The reference to the data aggregator to use as source of truth for this view. */ HomeView(lv_obj_t* parent, DataAggregator& aggregator); }; diff --git a/UOSM-Dashboard/Core/UI/StatsView.hpp b/UOSM-Dashboard/Core/UI/StatsView.hpp index ff3a5b9..1e83d36 100644 --- a/UOSM-Dashboard/Core/UI/StatsView.hpp +++ b/UOSM-Dashboard/Core/UI/StatsView.hpp @@ -10,7 +10,7 @@ /** @ingroup core-ui * A class that represents a view that displays the statistics of the dashboard, such as the motor RPM over time. - * It inherits from the View class and uses the StatsViewModel class to get the data for the view elements. + * It inherits from the View class. */ class StatsView : public View { private: @@ -31,7 +31,7 @@ class StatsView : public View { public: /** Constructs a stats view with a given parent and a stats view model. * @param parent The parent object of the container, or NULL if the container is a screen. - * @param viewModel The reference to the stats view model that provides the data for the view elements. + * @param aggregator The reference to the data aggregator to use as source of truth for this view. */ StatsView(lv_obj_t* parent, DataAggregator& aggregator); }; diff --git a/UOSM-Dashboard/Core/UI/application.cpp b/UOSM-Dashboard/Core/UI/application.cpp index 637ecf6..56f234d 100644 --- a/UOSM-Dashboard/Core/UI/application.cpp +++ b/UOSM-Dashboard/Core/UI/application.cpp @@ -13,17 +13,14 @@ #include "HomeView.hpp" #include "StatsView.hpp" - -static void Application_Fetch_Data(lv_timer_t*); +#include "LogView.hpp" static HomeView* homeView; - static StatsView* statsView; - -static lv_timer_t* dataTimer; +static LogView* logView; static uint8_t screenIndex = 0; -static uint8_t nScreens = 2; +static uint8_t nScreens = 3; void swipe_event_callback(lv_event_t* event) { if (event->code == LV_EVENT_GESTURE) { @@ -53,6 +50,9 @@ void swipe_event_callback(lv_event_t* event) { case 1: lv_scr_load_anim(statsView->getContainer(), animDirection, 300, 0, false); break; + case 2: + lv_scr_load_anim(logView->getContainer(), animDirection, 300, 0, false); + break; default: break; } @@ -69,6 +69,10 @@ void Application_Create(DataAggregatorWrapper* aggregatorWrapper) { DataAggregator& aggregator = DataAggregator_GetReference(aggregatorWrapper); + aggregator.canLogEntries.add(new CANLogEntry(THROTTLE_DATA_ID, 200, CAN_DECIMAL)); + aggregator.canLogEntries.add(new CANLogEntry(THROTTLE_DATA_ID, 200, CAN_DECIMAL)); + aggregator.canLogEntries.add(new CANLogEntry(MOTOR_RPM_DATA_ID, 200, CAN_DECIMAL)); + // Create an object with no parent. (This will act as the screen). homeView = new HomeView(nullptr, aggregator); lv_obj_set_size(homeView->getContainer(), SCREEN_WIDTH, SCREEN_HEIGHT); @@ -76,8 +80,12 @@ void Application_Create(DataAggregatorWrapper* aggregatorWrapper) { statsView = new StatsView(nullptr, aggregator); lv_obj_set_size(statsView->getContainer(), SCREEN_WIDTH, SCREEN_HEIGHT); + logView = new LogView(nullptr, aggregator); + lv_obj_set_size(logView->getContainer(), SCREEN_WIDTH, SCREEN_HEIGHT); + lv_scr_load(homeView->getContainer()); lv_obj_add_event_cb(homeView->getContainer(), swipe_event_callback, LV_EVENT_GESTURE, nullptr); lv_obj_add_event_cb(statsView->getContainer(), swipe_event_callback, LV_EVENT_GESTURE, nullptr); + lv_obj_add_event_cb(logView->getContainer(), swipe_event_callback, LV_EVENT_GESTURE, nullptr); } \ No newline at end of file diff --git a/UOSM-Dashboard/UOSM-Core/Inc/ApplicationTypes.h b/UOSM-Dashboard/UOSM-Core/Inc/ApplicationTypes.h index 205c83b..07181cc 100644 --- a/UOSM-Dashboard/UOSM-Core/Inc/ApplicationTypes.h +++ b/UOSM-Dashboard/UOSM-Core/Inc/ApplicationTypes.h @@ -32,6 +32,11 @@ typedef enum { RESULT_OK } result_t; +typedef enum { + CAN_DECIMAL, + CAN_HEX +} CANLogEntryFormat; + typedef enum { MOTOR_LOW_SPEED, MOTOR_HIGH_SPEED diff --git a/UOSM-Dashboard/UOSM-Core/Utils/CANLogEntry.hpp b/UOSM-Dashboard/UOSM-Core/Utils/CANLogEntry.hpp index ce4ee51..5e9ebd7 100644 --- a/UOSM-Dashboard/UOSM-Core/Utils/CANLogEntry.hpp +++ b/UOSM-Dashboard/UOSM-Core/Utils/CANLogEntry.hpp @@ -7,11 +7,7 @@ #include "Identifiable.hpp" #include "CANMessageLookUpModule.h" - -enum CANLogEntryFormat { - CAN_DECIMAL, - CAN_HEX -}; +#include "ApplicationTypes.h" /** * @class CANLogEntry diff --git a/UOSM-Dashboard/UOSM-Core/Utils/DataQueue.hpp b/UOSM-Dashboard/UOSM-Core/Utils/DataQueue.hpp index 30b4f1d..26018a9 100644 --- a/UOSM-Dashboard/UOSM-Core/Utils/DataQueue.hpp +++ b/UOSM-Dashboard/UOSM-Core/Utils/DataQueue.hpp @@ -9,6 +9,39 @@ #include +template +class DataQueue; + +template +class DataQueueIterator { +private: + const DataQueue& dataQueue; + uint8_t currentIndex; + +public: + DataQueueIterator(const DataQueue& dataQueue, uint8_t index): dataQueue(dataQueue), currentIndex(index) {} + + bool operator!=(const DataQueueIterator& other) const { + return currentIndex != other.currentIndex; + } + + DataQueueIterator& operator++() { + currentIndex++; + return *this; + } + + const T& operator*() { + if (currentIndex >= dataQueue.getNumberOfElements()) { + throw std::out_of_range("Iterator is out of range."); + } + return dataQueue.getValues()[currentIndex]; + } + + uint8_t getCurrentIndex() const { + return currentIndex; + } +}; + /** @ingroup core-ui-utils * A class that aggregates the data to display on a bar chart. * It can store any type T, but the values will be cast to lv_coord_t when displayed in a bar chart. @@ -93,6 +126,16 @@ class DataQueue { uint8_t i = head - 1; values[i] = value; } + + using iterator = DataQueueIterator; + + iterator begin() const { + return iterator(*this, 0); + } + + iterator end() const { + return iterator(*this, getNumberOfElements()); + } }; template @@ -180,6 +223,16 @@ class DataQueue { delete values[i]; values[i] = value; } + + using iterator = DataQueueIterator; + + iterator begin() const { + return iterator(*this, 0); + } + + iterator end() const { + return iterator(*this, getNumberOfElements()); + } }; #endif //UOSM_CORE_DATAQUEUE_HPP