Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
41 commits
Select commit Hold shift + click to select a range
b6251dc
add load controller test to ipa320 broadcaster
YaraShahin Jan 2, 2026
cb9a005
delete ipa320 broadcaster
YaraShahin Jan 2, 2026
39fc8d4
Add battery_state_broadcaster
YaraShahin Sep 4, 2025
90ddaf1
Update battery_state_broadcaster/doc/userdoc.rst
YaraShahin Sep 30, 2025
ea3b8dd
edit maintainers and author order
YaraShahin Sep 30, 2025
0c00322
Update battery_state_broadcaster/package.xml
YaraShahin Sep 30, 2025
2f73c89
edit package dependencies
YaraShahin Sep 30, 2025
fa8a3f5
Update battery_state_broadcaster/src/battery_state_broadcaster.cpp
YaraShahin Sep 30, 2025
1afe2c8
Update battery_state_broadcaster/include/battery_state_broadcaster/ba…
YaraShahin Sep 30, 2025
d8ef0f2
fix interface types
YaraShahin Oct 1, 2025
bdb7db7
move protected members to private context
YaraShahin Oct 1, 2025
818f667
Update battery_state_broadcaster/src/battery_state_broadcaster.cpp
YaraShahin Oct 1, 2025
9a2556f
remove bool from get optional
YaraShahin Oct 1, 2025
2ed2664
add compatibility for ipa320 broadcaster
YaraShahin Oct 2, 2025
7c0d072
fix compatibility errors
YaraShahin Oct 2, 2025
24b8eff
add migration guide for ip320 users
YaraShahin Oct 2, 2025
2d0a3d9
update doxygen broadcaster header
YaraShahin Oct 7, 2025
e421711
remove license from yaml
YaraShahin Oct 24, 2025
5b80ea3
update build files with best practices
YaraShahin Oct 24, 2025
216b56f
change message type to sensor messages
YaraShahin Oct 24, 2025
4e57e57
rename msg to BatteryStateArray
YaraShahin Nov 12, 2025
3deb574
revert to control msgs
YaraShahin Dec 29, 2025
7e21e58
update realtime APIs
YaraShahin Dec 29, 2025
7c91749
update LoanedStateInterface API
YaraShahin Dec 29, 2025
0faa194
resolve all warnings
YaraShahin Jan 3, 2026
0813038
Update battery_state_broadcaster/package.xml
YaraShahin Jan 3, 2026
9bd0dba
remove license from xml file
YaraShahin Jan 3, 2026
1660c0c
add changelog
YaraShahin Feb 27, 2026
7999138
add shim header
YaraShahin Feb 27, 2026
3c6d20e
add msg link to enum param descriptions
YaraShahin Feb 27, 2026
afee55e
mark params as deprecated
YaraShahin Feb 27, 2026
6832b1c
add to release notes
YaraShahin Feb 27, 2026
f323e2a
Merge branch 'feature/battery_state_broadcaster' into add-battery-sta…
christophfroehlich Jun 6, 2026
5c09642
add friend functions and private var exposure
YaraShahin Jun 7, 2026
f7fad1e
renamed state joints to batteries across all files
YaraShahin Jun 7, 2026
32e2bdf
rename example and test batteries
YaraShahin Jun 7, 2026
78fbb29
rename remaining left and right occurances in test source code
YaraShahin Jun 7, 2026
6a7a583
Update battery_state_broadcaster/CHANGELOG.rst
YaraShahin Jun 7, 2026
d132add
Update battery_state_broadcaster/package.xml
YaraShahin Jun 7, 2026
6e32c30
fix wrong comment
YaraShahin Jun 7, 2026
1784106
remove mispositioned comments
YaraShahin Jun 7, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 6 additions & 2 deletions battery_state_broadcaster/CHANGELOG.rst
Comment thread
christophfroehlich marked this conversation as resolved.
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,19 @@
Changelog for package battery_state_broadcaster
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^


The entries below refer to the standalone `ipa320/ros_battery_monitoring <https://github.com/ipa320/ros_battery_monitoring>`_ package,
from which this broadcaster originates.

1.1.0 (2025-09-26)
------------------
* address deprecations in ros2_control for kilted
* Don't make a temporary copy of semantic component (https://github.com/ipa320/ros_battery_monitoring/pull/9)
* Don't make a temporary copy of semantic component (`#9 <https://github.com/ipa320/ros_battery_monitoring/pull/9>`_)
* Contributors: Christoph Froehlich, Jonas Otto

1.0.2 (2025-06-01)
------------------
* Replace ament_target_dependencies with target_link_libraries ([#6](https://github.com/ipa320/ros_battery_monitoring/issues/6))
* Replace ament_target_dependencies with target_link_libraries (`#6 <https://github.com/ipa320/ros_battery_monitoring/issues/6>`_)
* Contributors: Alejandro Hernandez Cordero, Jonas Otto

1.0.1 (2025-02-06)
Expand Down
75 changes: 53 additions & 22 deletions battery_state_broadcaster/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,54 +1,86 @@
cmake_minimum_required(VERSION 3.10)
project(battery_state_broadcaster)

if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang")
add_compile_options(-Wall -Wextra -Wpedantic)
endif()
find_package(ros2_control_cmake REQUIRED)
set_compiler_options()
export_windows_symbols()

set(THIS_PACKAGE_INCLUDE_DEPENDS
builtin_interfaces
controller_interface
hardware_interface
generate_parameter_library
pluginlib
rclcpp
rclcpp_lifecycle
realtime_tools
sensor_msgs
urdf
)

# find dependencies
find_package(ament_cmake REQUIRED)
find_package(controller_interface REQUIRED)
find_package(pluginlib REQUIRED)
find_package(realtime_tools REQUIRED)
find_package(sensor_msgs REQUIRED)
find_package(backward_ros REQUIRED)
foreach(Dependency IN ITEMS ${THIS_PACKAGE_INCLUDE_DEPENDS})
find_package(${Dependency} REQUIRED)
endforeach()
add_compile_definitions(RCPPUTILS_VERSION_MAJOR=${rcpputils_VERSION_MAJOR})
add_compile_definitions(RCPPUTILS_VERSION_MINOR=${rcpputils_VERSION_MINOR})

add_library(battery_state_broadcaster SHARED src/BatteryStateBroadcaster.cpp)
target_include_directories(battery_state_broadcaster PUBLIC
$<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}/include>
$<INSTALL_INTERFACE:include/battery_state_broadcaster>
generate_parameter_library(battery_state_broadcaster_parameters
src/battery_state_broadcaster.yaml
)
target_link_libraries(battery_state_broadcaster

add_library(
battery_state_broadcaster
SHARED
src/battery_state_broadcaster.cpp
)

target_compile_features(battery_state_broadcaster PUBLIC cxx_std_17)
target_include_directories(battery_state_broadcaster
PUBLIC
controller_interface::controller_interface
pluginlib::pluginlib
realtime_tools::realtime_tools
${sensor_msgs_TARGETS}
$<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}/include>
$<INSTALL_INTERFACE:include/battery_state_broadcaster>
)
target_link_libraries(battery_state_broadcaster PUBLIC
battery_state_broadcaster_parameters
controller_interface::controller_interface
hardware_interface::hardware_interface
pluginlib::pluginlib
rclcpp::rclcpp
rclcpp_lifecycle::rclcpp_lifecycle
realtime_tools::realtime_tools
${sensor_msgs_TARGETS}
${builtin_interfaces_TARGETS})

pluginlib_export_plugin_description_file(controller_interface battery_state_broadcaster.xml)

pluginlib_export_plugin_description_file(
controller_interface battery_state_broadcaster.xml)

if(BUILD_TESTING)
find_package(ament_cmake_gmock REQUIRED)
find_package(controller_manager REQUIRED)
find_package(hardware_interface REQUIRED)
find_package(rclcpp REQUIRED)
find_package(ros2_control_test_assets REQUIRED)

add_definitions(-DTEST_FILES_DIRECTORY="${CMAKE_CURRENT_SOURCE_DIR}/test")
ament_add_gmock(test_load_battery_state_broadcaster test/test_load_battery_state_broadcaster.cpp)
target_include_directories(test_load_battery_state_broadcaster PRIVATE include)
target_link_libraries(test_load_battery_state_broadcaster
battery_state_broadcaster
controller_manager::controller_manager
hardware_interface::hardware_interface
rclcpp::rclcpp
ros2_control_test_assets::ros2_control_test_assets
)

add_rostest_with_parameters_gmock(test_battery_state_broadcaster
test/test_battery_state_broadcaster.cpp
${CMAKE_CURRENT_SOURCE_DIR}/test/battery_state_broadcaster_params.yaml)
target_include_directories(test_battery_state_broadcaster PRIVATE include)
target_link_libraries(test_battery_state_broadcaster
battery_state_broadcaster
)
endif()

install(
Expand All @@ -57,15 +89,14 @@ install(
)
install(
TARGETS
battery_state_broadcaster
battery_state_broadcaster
battery_state_broadcaster_parameters
EXPORT export_battery_state_broadcaster
RUNTIME DESTINATION bin
ARCHIVE DESTINATION lib
LIBRARY DESTINATION lib
INCLUDES DESTINATION include
)

ament_export_targets(export_battery_state_broadcaster HAS_LIBRARY_TARGET)
ament_export_dependencies(${THIS_PACKAGE_INCLUDE_DEPENDS})

ament_package()
15 changes: 8 additions & 7 deletions battery_state_broadcaster/battery_state_broadcaster.xml
Comment thread
christophfroehlich marked this conversation as resolved.
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
<library path="battery_state_broadcaster">
<class name="battery_state_broadcaster/BatteryStateBroadcaster"
type="battery_state_broadcaster::BatteryStateBroadcaster" base_class_type="controller_interface::ControllerInterface">
<description>
This controller publishes the readings of a battery sensor as sensor_msgs/BatteryState message.
</description>
</class>
</library>
<class name="battery_state_broadcaster/BatteryStateBroadcaster"
type="battery_state_broadcaster::BatteryStateBroadcaster" base_class_type="controller_interface::ControllerInterface">
<description>
This controller publishes the individual battery state of each battery as sensor_msgs/BatteryState messages.
It also publishes the aggregated battery state of all batteries as a single control_msgs/BatteryStateArray message.
</description>
</class>
</library>
140 changes: 105 additions & 35 deletions battery_state_broadcaster/doc/userdoc.rst
Original file line number Diff line number Diff line change
Expand Up @@ -3,53 +3,123 @@
.. _battery_state_broadcaster_userdoc:

Battery State Broadcaster
--------------------------------
The *Battery State Broadcaster* publishes battery status information as ``sensor_msgs/msg/BatteryState`` messages.

It reads battery-related state interfaces from one or more batteries and exposes them in a standard ROS 2 message format. This allows easy integration with monitoring tools, logging systems, and higher-level decision-making nodes.

Interfaces
^^^^^^^^^^^

The broadcaster can read the following state interfaces from each configured battery:

- ``battery_voltage`` *(mandatory)* (double)
- ``battery_temperature`` *(optional)* (double)
- ``battery_current`` *(optional)* (double)
- ``battery_charge`` *(optional)* (double)
- ``battery_percentage`` *(optional)* (double)
- ``battery_power_supply_status`` *(optional)* (double)
- ``battery_power_supply_health`` *(optional)* (double)
- ``battery_present`` *(optional)* (bool)

Published Topics
^^^^^^^^^^^^^^^^^^

The broadcaster publishes two topics:

- ``~/raw_battery_states`` (``control_msgs/msg/BatteryStateArray``)
Publishes **per-battery state messages**, containing the raw values for each configured battery.

- ``~/battery_state`` (``sensor_msgs/msg/BatteryState``)
Publishes a **single aggregated battery message** representing the combined status across all batteries.

+-----------------------------+-------------------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------+
| Field | ``battery_state`` | ``raw_battery_states`` |
+=============================+=========================================================================+=================================================================================================================================================+
| ``header.frame_id`` | Empty | Battery name |
+-----------------------------+-------------------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------+
| ``voltage`` | Mean across all batteries | From battery's ``battery_voltage`` interface if enabled, otherwise nan |
+-----------------------------+-------------------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------+
| ``temperature`` | Mean across batteries reporting temperature | From battery's ``battery_temperature`` interface if enabled, otherwise nan. |
+-----------------------------+-------------------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------+
| ``current`` | Mean across batteries reporting current | From battery's ``battery_current`` interface if enabled, otherwise nan. |
+-----------------------------+-------------------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------+
| ``charge`` | Sum across all batteries | From battery's ``battery_charge`` interface if enabled, otherwise nan. |
+-----------------------------+-------------------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------+
| ``capacity`` | Sum across all batteries | From battery's ``capacity`` parameter if provided, otherwise nan. |
+-----------------------------+-------------------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------+
| ``design_capacity`` | Sum across all batteries | From battery's ``design_capacity`` parameter if provided, otherwise nan. |
+-----------------------------+-------------------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------+
| ``percentage`` | Mean across batteries reporting/calculating percentage | From battery's ``battery_percentage`` interface if enabled, otherwise calculated from battery's ``min_voltage`` and ``max_voltage`` parameters. |
+-----------------------------+-------------------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------+
| ``power_supply_status`` | Highest reported enum value | From battery's ``battery_power_supply_status`` interface if enabled, otherwise 0 (unknown). |
+-----------------------------+-------------------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------+
| ``power_supply_health`` | Highest reported enum value | From battery's ``battery_power_supply_health`` interface if enabled, otherwise 0 (unknown). |
+-----------------------------+-------------------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------+
| ``power_supply_technology`` | Reported as-is if same across all batteries, otherwise set to *Unknown* | From battery's ``power_supply_technology`` parameter if provided, otherwise 0 (unknown). |
+-----------------------------+-------------------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------+
| ``present`` | True | From battery's ``battery_present`` interface if enabled, otherwise true if battery's voltage values is valid. |
+-----------------------------+-------------------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------+
| ``cell_voltage`` | Empty | Empty |
+-----------------------------+-------------------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------+
| ``cell_temperature`` | Empty | Empty |
+-----------------------------+-------------------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------+
| ``location`` | All battery locations appended | From battery's ``location`` parameter if provided, otherwise empty. |
+-----------------------------+-------------------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------+
| ``serial_number`` | All battery serial numbers appended | From battery's ``serial_number`` parameter if provided, otherwise empty. |
+-----------------------------+-------------------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------+


Parameters
^^^^^^^^^^^
This controller uses the `generate_parameter_library <https://github.com/PickNikRobotics/generate_parameter_library>`_ to manage parameters.
The parameter `definition file <https://github.com/ros-controls/ros2_controllers/blob/{REPOS_FILE_BRANCH}/battery_state_broadcaster/src/battery_state_broadcaster_parameters.yaml>`_ contains the full list and descriptions.

List of parameters
=========================
This broadcaster publishes `sensor_msgs/BatteryState <https://github.com/ros2/common_interfaces/blob/rolling/sensor_msgs/msg/BatteryState.msg>`__ messages from appropriate state interfaces.
.. generate_parameter_library_details:: ../src/battery_state_broadcaster_parameters.yaml

Example Parameter File
=========================

Required State Interfaces
---------------------------------
This broadcaster requires the robot to have a sensor component which contains the battery state interfaces:
An example parameter file for this controller is available in the `test directory <https://github.com/ros-controls/ros2_controllers/blob/{REPOS_FILE_BRANCH}/battery_state_broadcaster/test/battery_state_broadcaster_params.yaml>`_:

.. code-block:: xml
.. literalinclude:: ../test/battery_state_broadcaster_params.yaml
:language: yaml

<ros2_control type="system">
Migration for ``ipa320/ros_battery_monitoring`` users
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

<!-- ... -->
If you were previously using the ``battery_state_broadcaster`` from the ``ipa320/ros_battery_monitoring package``, you can switch directly to this package. The configuration style using ``sensor_name`` is still supported for backward compatibility, but it may be removed in a future release.

<sensor name="battery_state">
<state_interface name="voltage" />
</sensor>
</ros2_control>
To adapt your setup to the new ``battery_state_broadcaster`` configuration:

Parameters
---------------------------------
To use this broadcaster, declare it in the controller manager and set its parameters:
1. Update your hardware interface name from ``voltage`` → ``battery_voltage``.

2. Convert your controller parameters from

.. code-block:: yaml
.. code-block:: yaml

controller_manager:
ros__parameters:
battery_state_broadcaster:
type: battery_state_broadcaster/BatteryStateBroadcaster
battery_state_broadcaster:
ros__parameters:
sensor_name: "battery_state"
design_capacity: 100.0
# https://github.com/ros2/common_interfaces/blob/rolling/sensor_msgs/msg/BatteryState.msg
power_supply_technology: 2

battery_state_broadcaster:
ros__parameters:
sensor_name: "battery_state"
design_capacity: 100.0
# https://github.com/ros2/common_interfaces/blob/rolling/sensor_msgs/msg/BatteryState.msg
power_supply_technology: 2
to:

And spawn it in the launch file:
.. code-block:: yaml

.. code-block:: python
battery_state_broadcaster:
ros__parameters:
batteries: ["battery_state"]
battery_state:
design_capacity: 100.0
power_supply_technology: 2

battery_state_broadcaster_spawner = Node(
package="controller_manager",
executable="spawner",
arguments=["battery_state_broadcaster"]
**Notes**:

Topics
---------------------------------
The battery state is published on ``~/battery_state``.
Since it's a plugin within the controller manager, add a remapping of the form ``("~/battery_state", "/my_battery_state")`` to the *controller manager*, not the spawner, to change the topic name.
- Parameters must provide **either** sensor_name **or** batteries.
- If both are empty → the broadcaster will fail to configure.
- If both are set → the broadcaster will throw an error.
Loading