Skip to content

PowerService/Power msgs (ADC values) #265

Merged
Apehaenger merged 16 commits into
v2from
feat/sabo
Feb 5, 2026
Merged

PowerService/Power msgs (ADC values) #265
Apehaenger merged 16 commits into
v2from
feat/sabo

Conversation

@Apehaenger
Copy link
Copy Markdown
Collaborator

@Apehaenger Apehaenger commented Feb 4, 2026

This PR is related to xtech/fw-openmower-v2#35 and is based on (includes) https://github.com/ClemensElflein/open_mower_ros/tree/feat/input-context-and-high-level-service.

Summary by CodeRabbit

  • Refactor
    • Power data message restructured with expanded voltage sensor support
    • Enhanced docking and behavior systems with multi-source sensor reading capability
    • Improved input button handling with context-aware command routing

ClemensElflein and others added 14 commits December 9, 2025 00:36
Fixed docker tags for CI build
- add high-level status subscriber to determine current mower state context
- implement highLevelStatusReceived callback to update current_context_ based on state_name
- replace hardcoded "area_recording" context with dynamic current_context_ in OnInputEventChanged
- add default "idle" context initialization and corresponding play button action mapping
- change remote user from 'dev' to 'openmower' for consistency
- add initializeCommand to generate .env file with user id, group id, and username
- update base Docker image from 'osrf/ros:noetic-desktop-full' to 'ros:noetic-ros-base' for arm64 compatibility
- add environment variables for recordings path, params path, and ROS home directory
- update volume mounts to use host directories for workspace, ros data, recordings, and params
- add new test_run.bash script for launching open_mower with debug mode and hardware platform settings
- Implements HighLevelServiceInterface with inputs: State ID, State Name, Sub State Name, Gps Quality, Current Area, Current Path, Current Path Index.
- Subscribes to mower_logic/current_state and sends data to firmware via Send... methods.
- Integrates into mower_comms_v2 (CMakeLists.txt, mower_comms.cpp).
- Output Action is logged (TODO: implement action handling).
- simplify status conversion by removing redundant bounds check
- rely on direct static cast as enum values are identical
- update all behavior logic (Docking, Idle, PerimeterDocking, Undocking, safety checks) to prefer ADC voltage readings over charger readings
- update PowerServiceInterface method names to reflect new field names (e.g., `OnChargeVoltageCHGChanged`)
- update simulation service to use new method names (`SendBatteryVoltageCHG`, `SendChargeVoltageCHG`)
- update monitoring module to use new field names for sensor data
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Feb 4, 2026

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

  • 🔍 Trigger a full review
✨ Finishing touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feat/sabo

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/mower_logic/src/mower_logic/mower_logic.cpp (1)

490-524: ⚠️ Potential issue | 🟠 Major

Guard against invalid/zero ADC readings when selecting last_battery_v.

ROS float32 fields default to 0.0, not NaN. When battery_voltage_adc is unpublished, std::isnan(0.0f) returns false, forcing last_battery_v to 0.0. This yields battery_percent = (0 - 23.5) / (28.5 - 23.5) ≈ -4.7, clamped to 0.0, which then triggers false docking since the critical voltage check (0 < 22.5V) becomes true. Additionally, if both ADC and CHG default to 0.0, the clamping logic never corrects the invalid value.

Switch to std::isfinite(v) && v > 1.0f to filter out both zero and uninitialized values, implement a fallback chain to battery_voltage_bms, and handle the "no valid voltage" case explicitly. <cmath> and <limits> are required but likely already available transitively.

🛠️ Suggested guard for invalid voltage readings
-  // Prefer ADC because it's assumed to be more accurate
-  const float last_battery_v =
-      !std::isnan(last_power.battery_voltage_adc) ? last_power.battery_voltage_adc : last_power.battery_voltage_chg;
-
-  double battery_percent = (last_battery_v - last_power_config.battery_empty_voltage) /
-                           (last_power_config.battery_full_voltage - last_power_config.battery_empty_voltage);
+  // Prefer ADC because it's assumed to be more accurate
+  const auto is_valid_v = [](float v) { return std::isfinite(v) && v > 1.0f; };
+  const float last_battery_v =
+      is_valid_v(last_power.battery_voltage_adc) ? last_power.battery_voltage_adc
+    : is_valid_v(last_power.battery_voltage_chg) ? last_power.battery_voltage_chg
+    : is_valid_v(last_power.battery_voltage_bms) ? last_power.battery_voltage_bms
+    : std::numeric_limits<float>::quiet_NaN();
+
+  double battery_percent = 0.0;
+  if (std::isfinite(last_battery_v)) {
+    battery_percent = (last_battery_v - last_power_config.battery_empty_voltage) /
+                      (last_power_config.battery_full_voltage - last_power_config.battery_empty_voltage);
+  } else {
+    ROS_WARN_STREAM_THROTTLE(5, "Battery voltage unavailable; battery_percent set to 0.");
+  }

This pattern also appears in IdleBehavior.cpp and DockingBehavior.cpp.

🤖 Fix all issues with AI agents
In `@src/mower_logic/src/mower_logic/behaviors/IdleBehavior.cpp`:
- Around line 87-92: The code uses std::isnan in IdleBehavior.cpp (variables
last_battery_v and last_charge_v) but does not include <cmath>, causing
build/portability issues; add `#include` <cmath> at the top of IdleBehavior.cpp
and likewise add the same include to the other files that use std::isnan
(mower_logic.cpp and DockingBehavior.cpp) so the calls to std::isnan compile
reliably across toolchains and standards modes.
🧹 Nitpick comments (2)
src/mower_comms_v2/src/HighLevelServiceInterface.cpp (1)

45-49: Follow up on the TODO for action handling.

There’s a TODO for action routing; happy to help implement or file a follow-up issue if needed.

src/mower_comms_v2/src/HighLevelServiceInterface.h (1)

27-41: Keep a NodeHandle member to make subscriber lifetime explicit.

The local ros::NodeHandle nh; is destroyed after the constructor. In roscpp, subscriptions created from a NodeHandle can be dropped if no handle remains, so it’s safer to store one as a member (or accept one from the caller).

♻️ Suggested adjustment
 class HighLevelServiceInterface : public HighLevelServiceInterfaceBase {
  public:
   HighLevelServiceInterface(uint16_t service_id, const xbot::serviceif::Context& ctx)
-      : HighLevelServiceInterfaceBase(service_id, ctx) {
-    ros::NodeHandle nh;
-    high_level_status_sub_ =
-        nh.subscribe("mower_logic/current_state", 1, &HighLevelServiceInterface::highLevelStatusReceived, this);
-  }
+      : HighLevelServiceInterfaceBase(service_id, ctx), nh_() {
+    high_level_status_sub_ =
+        nh_.subscribe("mower_logic/current_state", 1, &HighLevelServiceInterface::highLevelStatusReceived, this);
+  }
@@
  private:
   void highLevelStatusReceived(const mower_msgs::HighLevelStatus::ConstPtr& msg);
+  ros::NodeHandle nh_;
   ros::Subscriber high_level_status_sub_;
 };

Comment thread src/mower_logic/src/mower_logic/behaviors/IdleBehavior.cpp Outdated
…e fallback logic

- add new utils.h with `IsValidReading` and `GetFirstValid` helper functions
- replace manual NaN checks with `GetFirstValid` for voltage readings in DockingBehavior, IdleBehavior, and mower_logic
- update battery percent calculation to use std::max/min for clamping
- improve sensor selection comment to reflect new fallback chain (ADC -> BMS -> CHG)
- update services submodule to latest commit (69784e2)
@Apehaenger Apehaenger merged commit 14964ae into v2 Feb 5, 2026
1 check passed
@Apehaenger Apehaenger deleted the feat/sabo branch February 5, 2026 12:49
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants