How to Create a Battery State Publisher in ROS 2


In this tutorial, I will show you how to create a simulated battery state publisher in ROS 2. My goal is to publish a sensor_msgs/BatteryState message to a topic named /battery_status

Real-World Application

The application that we will develop in this tutorial can be used as a template for a number of real-world robotic applications…the most important being:

  • Autonomous docking at a charging station once the battery level gets below a certain threshold.


You can find the files for this post here on my Google Drive

In this implementation, I want the float32 percentage variable of the sensor_msgs/BatteryState message to start off as 1.0 and gradually decrease. 1.0 indicates a full battery at 100% charge. 

In a real-life application, we could have a condition plugin that listens to the /battery_status topic and returns SUCCESS when the battery percentage is lower than a specified value, and FAILURE otherwise.

Create the Battery State Publisher Node

Open a terminal window, and move to your package.

cd ~/dev_ws/src/two_wheeled_robot/scripts

Create a folder for battery state.

mkdir battery_state
cd battery_state

Open a new Python program called


Add this code.

#!/usr/bin/env python3 

Publish the battery state at a specific time interval
Publishing Topics:
/battery_status – sensor_msgs/BatteryState
Subscription Topics:
Author: Addison Sears-Collins
Date: November 10, 2021
import rclpy # Import the ROS client library for Python
from rclpy.node import Node # Enables the use of rclpy's Node class
from sensor_msgs.msg import BatteryState # Enable use of the sensor_msgs/BatteryState message type
class BatteryStatePublisher(Node):
  Create a BatteryStatePublisher class, which is a subclass of the Node class.
  The class publishes the battery state of an object at a specific time interval.
  def __init__(self):
    Class constructor to set up the node
    # Initiate the Node class's constructor and give it a name
    # Create publisher(s)  
    # This node publishes the state of the battery.
    # Maximum queue size of 10. 
    self.publisher_battery_state = self.create_publisher(BatteryState, '/battery_status', 10)
    # Time interval in seconds
    timer_period = 5.0 
    self.timer = self.create_timer(timer_period, self.get_battery_state)
    # Initialize battery level
    self.battery_voltage = 9.0 # Initialize the battery voltage level
    self.percent_charge_level = 1.0  # Initialize the percentage charge level
    self.decrement_factor = 0.99 # Used to reduce battery level each cycle
  def get_battery_state(self):
    Callback function.
    This function gets called at the specific time interval.
    We decrement the battery charge level to simulate a real-world battery.
    msg = BatteryState() # Create a message of this type 
    msg.voltage = self.battery_voltage 
    msg.percentage = self.percent_charge_level
    self.publisher_battery_state.publish(msg) # Publish BatteryState message 
    # Decrement the battery state 
    self.battery_voltage = self.battery_voltage * self.decrement_factor
    self.percent_charge_level = self.percent_charge_level * self.decrement_factor
def main(args=None):
  # Initialize the rclpy library
  # Create the node
  battery_state_pub = BatteryStatePublisher()
  # Spin the node so the callback function is called.
  # Publish any pending messages to the topics.
  # Destroy the node explicitly
  # (optional - otherwise it will be done automatically
  # when the garbage collector destroys the node object)
  # Shutdown the ROS client library for Python
if __name__ == '__main__':

Save the code, and close the file.

Change the access permissions on the file.

chmod +x

Open CMakeLists.txt.

cd ~/dev_ws/src/two_wheeled_robot
gedit CMakeLists.txt

Add the Python executables.


Build the Package

Now we build the package.

cd ~/dev_ws/
colcon build

Run the Node

Open a new terminal,  and run the node:

ros2 run two_wheeled_robot

Check out the current ROS topics.

ros2 topic list

Check the output on the /battery_status topic by opening a new terminal window and typing:

ros2 topic echo /battery_status

Here is the output:


That’s it! Keep building!