From a0b678de9d74bad87b4c98c41db208f2a535ab53 Mon Sep 17 00:00:00 2001 From: Peter Poetzi Date: Sun, 17 Jul 2022 19:30:29 +0200 Subject: [PATCH] measurement mode partially implemented --- main/CMakeLists.txt | 2 + main/accessors/settingsaccessors.h | 3 + main/displays/measurementdisplay.cpp | 149 +++++++++++++++++++++++++++ main/displays/measurementdisplay.h | 42 ++++++++ main/displays/menus/mainmenu.cpp | 4 + main/newsettings.h | 8 ++ 6 files changed, 208 insertions(+) create mode 100644 main/displays/measurementdisplay.cpp create mode 100644 main/displays/measurementdisplay.h diff --git a/main/CMakeLists.txt b/main/CMakeLists.txt index 5227b44..9f52924 100644 --- a/main/CMakeLists.txt +++ b/main/CMakeLists.txt @@ -75,6 +75,7 @@ set(headers displays/buttoncalibratedisplay.h displays/calibratevoltagedisplay.h displays/confiscationdisplay.h + displays/measurementdisplay.h displays/gameoflifedisplay.h displays/gametrakcalibratedisplay.h displays/joystickdebugdisplay.h @@ -328,6 +329,7 @@ set(sources displays/buttoncalibratedisplay.cpp displays/calibratevoltagedisplay.cpp displays/confiscationdisplay.cpp + displays/measurementdisplay.cpp displays/gameoflifedisplay.cpp displays/gametrakcalibratedisplay.cpp displays/joystickdebugdisplay.cpp diff --git a/main/accessors/settingsaccessors.h b/main/accessors/settingsaccessors.h index 6170d8e..26d267b 100644 --- a/main/accessors/settingsaccessors.h +++ b/main/accessors/settingsaccessors.h @@ -218,6 +218,9 @@ template struct LockscreenPinDigitAccessor : public NewSettingsAccessor { ConfigWrapper &getConfig() const override { return configs.lockscreen.pin[index]; } }; struct LockscreenKeepLockedAccessor : public NewSettingsAccessor { ConfigWrapper &getConfig() const override { return configs.lockscreen.keepLockedAfterReboot; } }; +// MeasurementMode +struct MeasurementIntervalAccessor : public NewSettingsAccessor { ConfigWrapper &getConfig() const override { return configs.measurementMode.measurementInterval; } }; + // Handbremse struct HandbremsEnabledAccessor : public NewSettingsAccessor { ConfigWrapper &getConfig() const override { return configs.handbremse.enable; } }; struct HandbremsModeAccessor : public NewSettingsAccessor { ConfigWrapper &getConfig() const override { return configs.handbremse.mode; } }; diff --git a/main/displays/measurementdisplay.cpp b/main/displays/measurementdisplay.cpp new file mode 100644 index 0000000..75abcd1 --- /dev/null +++ b/main/displays/measurementdisplay.cpp @@ -0,0 +1,149 @@ +#include "measurementdisplay.h" + +// system includes +#include + +// 3rdparty lib includes +#include +#include +#include +#include +#include +#include +#include +#include + +// local includes +#include "displays/bobbychangevaluedisplay.h" +#include "globals.h" +#include "newsettings.h" +#include "drivingstatistics.h" +#include "accessors/settingsaccessors.h" +#include "bobbycheckbox.h" + +using namespace espgui; + +namespace { + constexpr char TEXT_INTERVAL[] = "Set interval"; + constexpr char TEXT_INTERVAL_KMH[] = "km/h Measurement Interval"; + constexpr char TEXT_CLEARRESULTS[] = "Start Measurement"; + constexpr char TEXT_ACCELERATION[] = "Show Acceleration"; + constexpr char TEXT_BACK[] = "Back"; + + bool showAcceleration; + struct ShowAccelerationAccessor : espgui::RefAccessor { bool &getRef() const override { return showAcceleration; } }; + + + class ClearMeasurementsAction : public virtual espgui::ActionInterface { + public: + void triggered() override { + //TODO: call clearMeasurements() + } + }; + + + + class MeasurementDisplayItem : public MenuItem { + public: + MeasurementDisplayItem(const MeasurementDisplay::Result result) : m_result{result} {} + + void triggered() override; + + std::string text() const override; + + private: + MeasurementDisplay::Result m_result; + }; + + void MeasurementDisplayItem::triggered() + { + //pushScreen(m_result); + } + + std::string MeasurementDisplayItem::text() const + { + if(showAcceleration){ + return fmt::format("{}: {}ms {:.2f}m/s² ", m_result.speed, m_result.time.count(), + m_result.speed / (m_result.time.count() * 1e-3)); + }else{ + return fmt::format("{}: {}ms {:.2f}m ", m_result.speed, m_result.time.count(), m_result.distance); + } + } + + constexpr const size_t extraItemsAtBeginning = 3; + + using MeasurementIntervalChangeScreen = espgui::makeComponent< + BobbyChangeValueDisplay, + espgui::StaticText, + MeasurementIntervalAccessor, + espgui::ConfirmActionInterface, + espgui::BackActionInterface + >; +} // namespace + + +MeasurementDisplay::MeasurementDisplay() { + clearMeasurements(); + constructMenuItem, PushScreenAction>>(); + constructMenuItem, ClearMeasurementsAction>>(); + constructMenuItem, BobbyCheckbox, ShowAccelerationAccessor>>(); + constructMenuItem, PopScreenAction, StaticMenuItemIcon<&icons::back>>>(); + +} + +std::string MeasurementDisplay::text() const { + return "Measurement Mode"; +} + +void MeasurementDisplay::back() { + popScreen(); +} + +void MeasurementDisplay::start() { + Base::start(); +} + +void MeasurementDisplay::update() { + if (distance_at_line && !distance_at_start) { + if (drivingStatistics.meters_driven > *distance_at_line + 0.3) { + //start measurement + distance_at_start = drivingStatistics.meters_driven; + m_start_time = espchrono::millis_clock::now(); + } + } + + //remove excess menu items + if(menuItemCount() - extraItemsAtBeginning - 1 > m_results.size()) { + auto backButton = takeLastMenuItem(); + while(menuItemCount() - extraItemsAtBeginning - 1 > m_results.size()) { + takeLastMenuItem(); + } + emplaceMenuItem(std::move(backButton)); + } + + //take measurement and add menu items + while (distance_at_start && avgSpeedKmh + configs.measurementMode.measurementInterval.value() > m_max_speed) { + m_max_speed += configs.measurementMode.measurementInterval.value(); + + Result result = { + .time = std::chrono::floor(espchrono::millis_clock::now() - *m_start_time), + .distance = drivingStatistics.meters_driven - *distance_at_start, + .speed = m_max_speed + }; + m_results.push_back(result); + + auto backButton = takeLastMenuItem(); + constructMenuItem(result); + emplaceMenuItem(std::move(backButton)); + } + + Base::update(); +} + +void MeasurementDisplay::clearMeasurements() { + distance_at_line = drivingStatistics.meters_driven; + distance_at_start = std::nullopt; + m_max_speed = 0; + m_start_time = std::nullopt; +} + diff --git a/main/displays/measurementdisplay.h b/main/displays/measurementdisplay.h new file mode 100644 index 0000000..7677ae8 --- /dev/null +++ b/main/displays/measurementdisplay.h @@ -0,0 +1,42 @@ +#pragma once + +// 3rdparty lib includes +#include +#include +#include +#include + +// local includes +#include "bobbydisplaywithtitle.h" +#include "modes/ignoreinputmode.h" +#include "bobbymenudisplay.h" + +class MeasurementDisplay : public BobbyMenuDisplay +{ + using Base = BobbyMenuDisplay; + +public: + MeasurementDisplay(); + + std::string text() const override; + + void back() override; + void start() override; + void update() override; + + + void clearMeasurements(); + + struct Result { + std::chrono::milliseconds time; + float distance; + float speed; + }; + std::vector m_results; + + std::optional distance_at_line; // measurement should start af 0.30m from starting line https://en.wikipedia.org/wiki/Rollout_(drag_racing) + std::optional distance_at_start; + + std::optional m_start_time; + float m_max_speed; +}; diff --git a/main/displays/menus/mainmenu.cpp b/main/displays/menus/mainmenu.cpp index 58b1e3d..e5a061d 100644 --- a/main/displays/menus/mainmenu.cpp +++ b/main/displays/menus/mainmenu.cpp @@ -27,6 +27,7 @@ #include "displays/poweroffdisplay.h" #include "displays/menus/statisticsmenu.h" #include "displays/confiscationdisplay.h" +#include "displays/measurementdisplay.h" #include "actions/rebootaction.h" #include "displays/menus/debugmenu.h" #include "icons/battery.h" @@ -47,6 +48,7 @@ #include "icons/greenpass.h" #include "icons/time.h" #include "displays/statusdisplay.h" +#include "displays/measurementdisplay.h" namespace { constexpr char TAG[] = "BOBBY"; @@ -75,6 +77,7 @@ constexpr char TEXT_DEBUG[] = "Debug"; constexpr char TEXT_BATTERY[] = "Battery"; constexpr char TEXT_BATTERYDEBUG[] = "Bat Debug Menu"; constexpr char TEXT_CONFISCATIONMODE[] = "Confiscation Mode"; +constexpr char TEXT_MEASUREMENT[] = "Measurement Mode"; constexpr char TEXT_TOGGLECLOUDDEBUG[] = "Cloud Debug"; constexpr char TEXT_MANAGEPROFILESMENU[] = "Manage Profiles"; @@ -118,6 +121,7 @@ MainMenu::MainMenu() if (SHOWITEM) { constructMenuItem,PushScreenAction, StaticMenuItemIcon<&bobbyicons::presets>>>(); } if (SHOWITEM) { constructMenuItem, PushScreenAction>>(); } constructMenuItem, PushScreenAction, StaticMenuItemIcon<&bobbyicons::poweroff>>>(); + constructMenuItem, PushScreenAction>>(); constructMenuItem, PushScreenAction>>(); constructMenuItem, RebootAction, StaticMenuItemIcon<&bobbyicons::reboot>>>(); //#ifdef MAINMENU_PLUGIN diff --git a/main/newsettings.h b/main/newsettings.h index 7b1186d..d584f58 100644 --- a/main/newsettings.h +++ b/main/newsettings.h @@ -450,6 +450,12 @@ public: ConfigWrapperLegacy totalCentimeters {0, DoReset, {}, "totalCentimeter" }; } savedStatistics; + struct { + ConfigWrapperLegacy measurementInterval{1, DoReset, {}, "measurementiv" }; + } measurementMode; + + + struct { ConfigWrapperLegacy mode {HandbremseMode::MOSFETS_OFF, DoReset, {}, "handBremsM" }; ConfigWrapperLegacy triggerTimeout {10, DoReset, {}, "handBremsT" }; @@ -781,6 +787,8 @@ public: \ x(savedStatistics.totalCentimeters) \ \ + x(measurementMode.measurementInterval) \ + \ x(handbremse.mode) \ x(handbremse.triggerTimeout) \ x(handbremse.automatic) \