From 7318a5b1aee1e6dece5e252cc3fe34c57586373b Mon Sep 17 00:00:00 2001 From: Tom Lonergan Date: Sun, 28 May 2023 20:19:56 +0100 Subject: [PATCH 01/10] encoder structure --- lib/sensors/wheel_encoder.cpp | 5 +++++ lib/sensors/wheel_encoder.hpp | 24 ++++++++++++++++++++++++ 2 files changed, 29 insertions(+) create mode 100644 lib/sensors/wheel_encoder.cpp create mode 100644 lib/sensors/wheel_encoder.hpp diff --git a/lib/sensors/wheel_encoder.cpp b/lib/sensors/wheel_encoder.cpp new file mode 100644 index 00000000..2067a220 --- /dev/null +++ b/lib/sensors/wheel_encoder.cpp @@ -0,0 +1,5 @@ +#include "wheel_encoder.hpp" + +namespace hyped::sensors { + +} // namespace hyped::sensors \ No newline at end of file diff --git a/lib/sensors/wheel_encoder.hpp b/lib/sensors/wheel_encoder.hpp new file mode 100644 index 00000000..9194614c --- /dev/null +++ b/lib/sensors/wheel_encoder.hpp @@ -0,0 +1,24 @@ +#include + +#include +#include +#include + +namespace hyped::sensors { +class WheelEncoder { + public: + std::optional create(core::ILogger &logger, std::shared_ptr adc); + + std::uint64_t getCount(); + + void updateCount(); + + private: + WheelEncoder(core::ILogger &logger, std::shared_ptr adc); + + private: + core::ILogger &logger_; + std::shared_ptr adc_; + const std::uint64_t count_; +}; +} // namespace hyped::sensors \ No newline at end of file From 9de728f5225082cd1c09d4bd2665174034285aa0 Mon Sep 17 00:00:00 2001 From: Tom Lonergan Date: Sun, 28 May 2023 20:27:06 +0100 Subject: [PATCH 02/10] implement wheel encoder --- lib/sensors/wheel_encoder.cpp | 24 ++++++++++++++++++++++++ lib/sensors/wheel_encoder.hpp | 7 +++---- 2 files changed, 27 insertions(+), 4 deletions(-) diff --git a/lib/sensors/wheel_encoder.cpp b/lib/sensors/wheel_encoder.cpp index 2067a220..1ff0a312 100644 --- a/lib/sensors/wheel_encoder.cpp +++ b/lib/sensors/wheel_encoder.cpp @@ -2,4 +2,28 @@ namespace hyped::sensors { +WheelEncoder::WheelEncoder(core::ILogger &logger, std::shared_ptr adc) + : logger_(logger), + adc_(adc), + count_(0) +{ +} + +std::uint64_t WheelEncoder::getCount() +{ + return count_; +} + +core::Result WheelEncoder::updateCount() +{ + const auto optional_voltage = adc_->readValue(); + if (!optional_voltage) { + logger_.log(core::LogLevel::kFatal, "Failed to read wheel encoder value from ADC"); + return core::Result::kFailure; + } + const core::Float voltage = *optional_voltage; + if (voltage > kVoltageThreshold) { count_++; } + return core::Result::kSuccess; +} + } // namespace hyped::sensors \ No newline at end of file diff --git a/lib/sensors/wheel_encoder.hpp b/lib/sensors/wheel_encoder.hpp index 9194614c..d747b3b0 100644 --- a/lib/sensors/wheel_encoder.hpp +++ b/lib/sensors/wheel_encoder.hpp @@ -7,18 +7,17 @@ namespace hyped::sensors { class WheelEncoder { public: - std::optional create(core::ILogger &logger, std::shared_ptr adc); - std::uint64_t getCount(); - void updateCount(); + core::Result updateCount(); private: WheelEncoder(core::ILogger &logger, std::shared_ptr adc); private: + static constexpr core::Float kVoltageThreshold = 1.7; core::ILogger &logger_; std::shared_ptr adc_; - const std::uint64_t count_; + std::uint64_t count_; }; } // namespace hyped::sensors \ No newline at end of file From 00f8235e1e3f49ec17966255a3380bcacf894e25 Mon Sep 17 00:00:00 2001 From: Tom Lonergan Date: Sun, 28 May 2023 20:38:20 +0100 Subject: [PATCH 03/10] make constructor public --- lib/sensors/wheel_encoder.hpp | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/lib/sensors/wheel_encoder.hpp b/lib/sensors/wheel_encoder.hpp index d747b3b0..27335933 100644 --- a/lib/sensors/wheel_encoder.hpp +++ b/lib/sensors/wheel_encoder.hpp @@ -7,13 +7,10 @@ namespace hyped::sensors { class WheelEncoder { public: + WheelEncoder(core::ILogger &logger, std::shared_ptr adc); std::uint64_t getCount(); - core::Result updateCount(); - private: - WheelEncoder(core::ILogger &logger, std::shared_ptr adc); - private: static constexpr core::Float kVoltageThreshold = 1.7; core::ILogger &logger_; From 8114a744e423797c7505b3126ec5fe05b6b21122 Mon Sep 17 00:00:00 2001 From: Tom Lonergan Date: Sun, 28 May 2023 20:45:41 +0100 Subject: [PATCH 04/10] fix logic --- lib/sensors/wheel_encoder.cpp | 10 ++++++++-- lib/sensors/wheel_encoder.hpp | 2 ++ 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/lib/sensors/wheel_encoder.cpp b/lib/sensors/wheel_encoder.cpp index 1ff0a312..b81d31f3 100644 --- a/lib/sensors/wheel_encoder.cpp +++ b/lib/sensors/wheel_encoder.cpp @@ -5,7 +5,8 @@ namespace hyped::sensors { WheelEncoder::WheelEncoder(core::ILogger &logger, std::shared_ptr adc) : logger_(logger), adc_(adc), - count_(0) + count_(0), + previous_voltage_(0) { } @@ -22,8 +23,13 @@ core::Result WheelEncoder::updateCount() return core::Result::kFailure; } const core::Float voltage = *optional_voltage; - if (voltage > kVoltageThreshold) { count_++; } + if (voltage > kVoltageThreshold && previous_voltage_ < kVoltageThreshold) { count_++; } return core::Result::kSuccess; } +void WheelEncoder::resetCount() +{ + count_ = 0; +} + } // namespace hyped::sensors \ No newline at end of file diff --git a/lib/sensors/wheel_encoder.hpp b/lib/sensors/wheel_encoder.hpp index 27335933..cd06d536 100644 --- a/lib/sensors/wheel_encoder.hpp +++ b/lib/sensors/wheel_encoder.hpp @@ -10,11 +10,13 @@ class WheelEncoder { WheelEncoder(core::ILogger &logger, std::shared_ptr adc); std::uint64_t getCount(); core::Result updateCount(); + void resetCount(); private: static constexpr core::Float kVoltageThreshold = 1.7; core::ILogger &logger_; std::shared_ptr adc_; std::uint64_t count_; + core::Float previous_voltage_; }; } // namespace hyped::sensors \ No newline at end of file From d8fb7119f9e7dafcc214a729e884f8b99767ae54 Mon Sep 17 00:00:00 2001 From: Tom Lonergan Date: Sun, 28 May 2023 20:46:29 +0100 Subject: [PATCH 05/10] store previous voltage --- lib/sensors/wheel_encoder.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/sensors/wheel_encoder.cpp b/lib/sensors/wheel_encoder.cpp index b81d31f3..38c57dd0 100644 --- a/lib/sensors/wheel_encoder.cpp +++ b/lib/sensors/wheel_encoder.cpp @@ -24,6 +24,7 @@ core::Result WheelEncoder::updateCount() } const core::Float voltage = *optional_voltage; if (voltage > kVoltageThreshold && previous_voltage_ < kVoltageThreshold) { count_++; } + previous_voltage_ = voltage; return core::Result::kSuccess; } From 4ca3cac1bce4daae4fbac66a2576bbcf5b428137 Mon Sep 17 00:00:00 2001 From: Tom Lonergan Date: Sun, 28 May 2023 20:47:29 +0100 Subject: [PATCH 06/10] add encoder to config file --- config/template.json | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/config/template.json b/config/template.json index aa53ee37..5296bd8d 100644 --- a/config/template.json +++ b/config/template.json @@ -33,6 +33,10 @@ "enabled": false, "bus": 2, "device_address": 56 + }, + "wheel_encoders": { + "enabled": false, + "pin": 0 } } } From cc85041316a28c50f188b06c5a28f8a93a109979 Mon Sep 17 00:00:00 2001 From: Tom Lonergan Date: Sun, 28 May 2023 20:49:32 +0100 Subject: [PATCH 07/10] wheel encoder repl commands --- lib/debug/repl.cpp | 79 ++++++++++++++++++++++++++++++++++++++++++++++ lib/debug/repl.hpp | 2 ++ 2 files changed, 81 insertions(+) diff --git a/lib/debug/repl.cpp b/lib/debug/repl.cpp index 78dcb80a..500c1f41 100644 --- a/lib/debug/repl.cpp +++ b/lib/debug/repl.cpp @@ -235,6 +235,26 @@ std::optional> Repl::fromFile(const std::string &path) const auto bus = temperature["bus"].GetUint(); repl->addTemperatureCommands(bus, device_address); } + if (!sensors.HasMember("wheel_encoders")) { + logger_.log(core::LogLevel::kFatal, + "Missing required field 'sensors.wheel_encoders' in configuration file"); + return std::nullopt; + } + const auto wheel_encoders = sensors["wheel_encoders"].GetObject(); + if (!wheel_encoders.HasMember("enabled")) { + logger_.log(core::LogLevel::kFatal, + "Missing required field 'sensors.wheel_encoders.enabled' in configuration file"); + return std::nullopt; + } + if (wheel_encoders["enabled"].GetBool()) { + if (!wheel_encoders.HasMember("pin")) { + logger_.log(core::LogLevel::kFatal, + "Missing required field 'sensors.wheel_encoders.pin' in configuration file"); + return std::nullopt; + } + const auto pin = wheel_encoders["pin"].GetUint(); + repl->addWheelEncoderCommands(pin); + } return repl; } @@ -609,4 +629,63 @@ void Repl::addTemperatureCommands(const std::uint8_t bus, const std::uint8_t dev addCommand(temperature_read_command); } +void Repl::addWheelEncoderCommands(const std::uint8_t pin) +{ + const auto optional_adc = io::HardwareAdc::create(logger_, pin); + if (!optional_adc) { + logger_.log(core::LogLevel::kFatal, "Failed to create ADC instance on pin %d", pin); + return; + } + const auto adc = std::move(*optional_adc); + const auto wheel_encoder = std::make_shared(logger_, adc); + { + Command wheel_encoder_read_count_command; + std::stringstream identifier; + identifier << "wheel encoder count"; + wheel_encoder_read_count_command.name = identifier.str(); + std::stringstream description; + description << "Read count wheel encoder"; + wheel_encoder_read_count_command.description = description.str(); + wheel_encoder_read_count_command.handler = [this, wheel_encoder]() { + const auto count = wheel_encoder->getCount(); + logger_.log(core::LogLevel::kInfo, "Wheel encoder value: %d", count); + }; + addCommand(wheel_encoder_read_count_command); + } + { + Command wheel_encoder_reset_count_command; + std::stringstream identifier; + identifier << "wheel encoder reset"; + wheel_encoder_reset_count_command.name = identifier.str(); + std::stringstream description; + description << "Reset wheel encoder count"; + wheel_encoder_reset_count_command.description = description.str(); + wheel_encoder_reset_count_command.handler = [this, wheel_encoder]() { + wheel_encoder->resetCount(); + logger_.log(core::LogLevel::kInfo, "Wheel encoder count reset"); + }; + addCommand(wheel_encoder_reset_count_command); + } + { + Command wheel_encoder_run_command; + std::stringstream identifier; + identifier << "wheel encoder run"; + wheel_encoder_run_command.name = identifier.str(); + std::stringstream description; + description << "Run wheel encoder"; + wheel_encoder_run_command.description = description.str(); + wheel_encoder_run_command.handler = [this, wheel_encoder]() { + std::uint64_t previous_wheel_encoder_count_ = 0; + while (1) { + wheel_encoder->updateCount(); + const auto count = wheel_encoder->getCount(); + if (count != previous_wheel_encoder_count_) { + logger_.log(core::LogLevel::kInfo, "Wheel encoder value: %d", count); + previous_wheel_encoder_count_ = count; + } + } + }; + } +} + } // namespace hyped::debug diff --git a/lib/debug/repl.hpp b/lib/debug/repl.hpp index 46485f59..5805e3a7 100644 --- a/lib/debug/repl.hpp +++ b/lib/debug/repl.hpp @@ -17,6 +17,7 @@ #include #include #include +#include namespace hyped::debug { @@ -46,6 +47,7 @@ class Repl { void addAccelerometerCommands(const std::uint8_t bus, const std::uint8_t device_address); void addTemperatureCommands(const std::uint8_t bus, const std::uint8_t device_address); void addUartCommands(const std::uint8_t bus); + void addWheelEncoderCommands(const std::uint8_t pin); core::ILogger &logger_; std::map command_map_; From 27ff71a7b8170cb91b758a0df8c2942c23eb4483 Mon Sep 17 00:00:00 2001 From: Tom Lonergan Date: Sun, 28 May 2023 21:01:35 +0100 Subject: [PATCH 08/10] pragma --- lib/sensors/wheel_encoder.hpp | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/sensors/wheel_encoder.hpp b/lib/sensors/wheel_encoder.hpp index cd06d536..e822d23c 100644 --- a/lib/sensors/wheel_encoder.hpp +++ b/lib/sensors/wheel_encoder.hpp @@ -1,3 +1,4 @@ +#pragma once #include #include From 7ccc2372323367bfff0f6fd2e7a71bd449210a1c Mon Sep 17 00:00:00 2001 From: Tom Lonergan Date: Sun, 28 May 2023 21:04:24 +0100 Subject: [PATCH 09/10] fix includes --- lib/sensors/wheel_encoder.hpp | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/sensors/wheel_encoder.hpp b/lib/sensors/wheel_encoder.hpp index e822d23c..188b54a6 100644 --- a/lib/sensors/wheel_encoder.hpp +++ b/lib/sensors/wheel_encoder.hpp @@ -1,4 +1,5 @@ #pragma once +#include #include #include From 924ac3f83fd1b3b8d94480efef50db9618b840d2 Mon Sep 17 00:00:00 2001 From: Tom Lonergan Date: Mon, 29 May 2023 16:58:22 +0100 Subject: [PATCH 10/10] fix repl print --- lib/debug/repl.cpp | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/lib/debug/repl.cpp b/lib/debug/repl.cpp index b27442cc..13653a0e 100644 --- a/lib/debug/repl.cpp +++ b/lib/debug/repl.cpp @@ -947,14 +947,19 @@ void Repl::addWheelEncoderCommands(const std::uint8_t pin) wheel_encoder_run_command.handler = [this, wheel_encoder]() { std::uint64_t previous_wheel_encoder_count_ = 0; while (1) { - wheel_encoder->updateCount(); - const auto count = wheel_encoder->getCount(); + const auto result = wheel_encoder->updateCount(); + if (result == core::Result::kFailure) { + logger_.log(core::LogLevel::kFatal, "Failed to update wheel encoder count"); + break; + } + const std::uint64_t count = wheel_encoder->getCount(); if (count != previous_wheel_encoder_count_) { - logger_.log(core::LogLevel::kInfo, "Wheel encoder value: %d", count); + logger_.log(core::LogLevel::kInfo, "Wheel encoder value: %jd", count); previous_wheel_encoder_count_ = count; } } }; + addCommand(wheel_encoder_run_command); } }