-
Notifications
You must be signed in to change notification settings - Fork 23
Synching #580
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Synching #580
Changes from all commits
4d9a7ec
2d65174
e16c745
e4a496a
e329de3
8e92378
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -4,6 +4,7 @@ | |||||||||
| #include <cmath> | ||||||||||
| #include <functional> | ||||||||||
|
|
||||||||||
| #include "esp_timer.h" | ||||||||||
| #include "base_peripheral.hpp" | ||||||||||
| #include "task.hpp" | ||||||||||
|
|
||||||||||
|
|
@@ -40,9 +41,9 @@ class As5600 : public BasePeripheral<> { | |||||||||
| typedef std::function<float(float raw)> velocity_filter_fn; | ||||||||||
|
|
||||||||||
| static constexpr int COUNTS_PER_REVOLUTION = | ||||||||||
| 16384; ///< Int number of counts per revolution for the magnetic encoder. | ||||||||||
| 4096; ///< Int number of counts per revolution for the magnetic encoder (12-bit). | ||||||||||
| static constexpr float COUNTS_PER_REVOLUTION_F = | ||||||||||
| 16384.0f; ///< Float number of counts per revolution for the magnetic encoder. | ||||||||||
| 4096.0f; ///< Float number of counts per revolution for the magnetic encoder (12-bit). | ||||||||||
| static constexpr float COUNTS_TO_RADIANS = | ||||||||||
| 2.0f * (float)(M_PI) / | ||||||||||
| COUNTS_PER_REVOLUTION_F; ///< Conversion factor to convert from count value to radians. | ||||||||||
|
|
@@ -162,32 +163,43 @@ class As5600 : public BasePeripheral<> { | |||||||||
| int read_count(std::error_code &ec) { | ||||||||||
| logger_.info("read_count"); | ||||||||||
| std::lock_guard<std::recursive_mutex> lock(base_mutex_); | ||||||||||
| // read the angle count registers | ||||||||||
| // read the angle count registers (12-bit value: 0-4095) | ||||||||||
| uint8_t angle_h = read_u8_from_register((uint8_t)Registers::ANGLE_H, ec); | ||||||||||
| if (ec) { | ||||||||||
| return 0; | ||||||||||
| } | ||||||||||
| uint8_t angle_l = read_u8_from_register((uint8_t)Registers::ANGLE_L, ec) >> 2; | ||||||||||
| uint8_t angle_l = read_u8_from_register((uint8_t)Registers::ANGLE_L, ec); | ||||||||||
| if (ec) { | ||||||||||
| return 0; | ||||||||||
| } | ||||||||||
| return (int)((angle_h << 6) | angle_l); | ||||||||||
| // Combine the high byte (bits 11-4) and low byte (bits 3-0) | ||||||||||
| // ANGLE_H contains bits [11:8] in the lower nibble | ||||||||||
| // ANGLE_L contains bits [7:0] | ||||||||||
| return (int)(((angle_h & 0x0F) << 8) | angle_l); | ||||||||||
| } | ||||||||||
|
|
||||||||||
| void update(std::error_code &ec) { | ||||||||||
| logger_.info("update"); | ||||||||||
| std::lock_guard<std::recursive_mutex> lock(base_mutex_); | ||||||||||
| // update velocity (filtering it) (use member variable instead of static) | ||||||||||
| uint64_t now_us = esp_timer_get_time(); | ||||||||||
| uint64_t dt = now_us - prev_time_us_; | ||||||||||
| float seconds = dt / 1e6f; | ||||||||||
| prev_time_us_ = now_us; | ||||||||||
|
|
||||||||||
| if (seconds == 0.0f) { | ||||||||||
| seconds = update_period_.count(); | ||||||||||
| } | ||||||||||
|
Comment on lines
+190
to
+192
|
||||||||||
| // update raw count | ||||||||||
| auto count = read_count(ec); | ||||||||||
| if (ec) { | ||||||||||
| return; | ||||||||||
| } | ||||||||||
| count_.store(count); | ||||||||||
| static int prev_count = count_; | ||||||||||
| // compute diff | ||||||||||
| int diff = count_ - prev_count; | ||||||||||
| // compute diff (use member variable instead of static to support multiple instances) | ||||||||||
| int diff = count_ - prev_count_; | ||||||||||
| // update prev_count | ||||||||||
| prev_count = count_; | ||||||||||
| prev_count_ = count_; | ||||||||||
|
||||||||||
| // check for zero crossing | ||||||||||
| if (diff > COUNTS_PER_REVOLUTION / 2) { | ||||||||||
| // we crossed zero going clockwise (1 -> 359) | ||||||||||
|
|
@@ -199,12 +211,7 @@ class As5600 : public BasePeripheral<> { | |||||||||
| // update accumulator | ||||||||||
| accumulator_ += diff; | ||||||||||
| logger_.debug("CDA: {}, {}, {}", count_, diff, accumulator_); | ||||||||||
| // update velocity (filtering it) | ||||||||||
| static auto prev_time = std::chrono::high_resolution_clock::now(); | ||||||||||
| auto now = std::chrono::high_resolution_clock::now(); | ||||||||||
| float elapsed = std::chrono::duration<float>(now - prev_time).count(); | ||||||||||
| prev_time = now; | ||||||||||
| float seconds = elapsed ? elapsed : update_period_.count(); | ||||||||||
|
|
||||||||||
| float raw_velocity = (float)(diff) / COUNTS_PER_REVOLUTION_F / seconds * SECONDS_PER_MINUTE; | ||||||||||
| velocity_rpm_ = velocity_filter_ ? velocity_filter_(raw_velocity) : raw_velocity; | ||||||||||
| static float max_velocity = 0.5f / update_period_.count() * SECONDS_PER_MINUTE; | ||||||||||
|
||||||||||
| static float max_velocity = 0.5f / update_period_.count() * SECONDS_PER_MINUTE; | |
| float max_velocity = 0.5f / update_period_.count() * SECONDS_PER_MINUTE; |
Copilot
AI
Dec 22, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The member variables prev_count_ and prev_time_us_ are accessed without mutex protection, but they're modified inside the update() method which is protected by base_mutex_. If update() can be called from multiple threads or if these variables are accessed from other methods, this could lead to race conditions. Consider using std::atomic for these variables or ensuring all accesses are protected by the mutex.
| int prev_count_{0}; | |
| uint64_t prev_time_us_{0}; | |
| std::atomic<int> prev_count_{0}; | |
| std::atomic<uint64_t> prev_time_us_{0}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Consider initializing prev_time_us_ to the current time in the init() method before starting the task. This would prevent the first update() call from calculating an incorrect dt value based on the initial value of 0, which would result in a very large time delta.