In this simple example, we show a more sophisticated BT interacting with several components. The robot acts as a museum guide
The robot has the following task: The robot has to visit a list of poses on the map, At each pose, it tells a description of the point of interest at the pose (like a museum guide). Whenever the robot's battery is below 10% of its capacity, it goes to a charging station until the battery is fully charged
Let's consider the BT below:
Where we assume that the poses charging_station
is present in the Blackboard. In this example, we add it from the bt executable.
Let's first analyze the architecture of this use case:
Leaf nodes:
-
The BT Condition IsBatteryLevelAbove {
reference_value
} that reads the battery value from a topic and compares it with the reference value -
The BT Action GoTo {
pose
} that sends the pose to a navigation stack via ROS Actions -
The BT Action Wait returns only the status of BT::Running
-
The BT Condition BatterIsNotCharging checks if the status of the battery is POWER_SUPPLY_STATUS_NOT_CHARING, reading from the topic
/battery_state
-
The BT Condition IsAt{
pose
}, {linear_threshold
} , {angular_threshold
} checks if the current pose of the robot is close topose
, within the related thresholds. -
The BT Action WriteCurrentPOIOnBB takes the current POI from a tour scheduler component and writes it on the blackboard.
-
The BT Action SayText reads a std::string with the description of the POI from the blackboard and sends it to a talker component.
-
The BT Action UpdateScheduler sends a request to a tour scheduler component to update the current poi.
-
Components:
- Nav2 as navigation stack.
- FakeBatteryReader to simulate a battery reading. In publishes the BatteryState message on the topic
/fake_battery_reader/battery_state
with the battery value. It also provides the servicecharge_battery
to charge the battery. - SimpleTourScheduler a simple tour scheduler that takes a set of POIs from a config file and schedules them in sequence.
- FakeTalker to simulate the speech synthesis capability of the robot. It prints on the console the text received.
-
Interfaces:
-
we interface the GoTo action in the BT with the Nav2 via the NavigateToPose.action
-
we interface the IsBatteryLevelAbove with the battery reader component via the BatteryState message.
-
we interface the BT Actions WriteCurrentPOIOnBB and UpdateScheduler with SimpleTourScheduler via the services: GetCurrentPOI and UpdatePOI
-
we interface the BT Actions Say via the services: SayText
Warning In this BT we trust the success conditions of Nav2 Action for the BT Actions Goto. In general, it is better to follow the design principle Improving Readability using Explicit Success Conditions from Chapter 3.1 of the book Behavior Trees in Robotics and AI
Let's run this BT and play with the battery value.
We first run the simulation environment:
ros2 launch bt_uc_sim simple_simulation_launch.py
Note If the simulation is too heavy for your computer, run the command above with the option
headless:=True
(i.e.,ros2 launch bt_uc_sim simple_simulation_launch.py headless:=True
. That will not launch the Gazebo Client.
We then run all the components (the launch file runs the custom-made FakeBatteryReader, Nav2, SimpleTourScheduler, and FakeTalker ).
ros2 launch tour_components all_components_launch.py
A new terminal with the output of the component fake_talker should.
At this point windows should appear as below:
And finally, run the BT
ros2 run tour_bts run_bts
The robot should happily roam between four poses. At Each pose it provides the description of the related POI (check the terminal of the fake_talker). Whenever the battery goes below 10% the robot goes to the another pose (the charging station) and wait for manual recharge.
Note It you are running it from WSL, you must install
gnome-terminal
to let the terminal of fake_talker pop up. If you are eager to let the robot go to the charging station, open RQt
rqt
and call the service fake_battery_reader/set_battery_level
with a value of 0.1
(or a lower one).
Once it reaches the charging station should stay there until we charge the battery. We do that by calling the service fake_battery_reader/charge_battery
. The robot will leave the charging station when the battery is full.
Check the battery level still with RQt:
Note If you have ZeroMQ installed you can visualize the BT while it runs via Groot