Hey everyone,
I’m currently working through a great tutorial series on youtube for ROS2. Unfortunately, I ran into a bit of an issue with a race condition in a launch file. The controller managers were timing out before Gazebo was able to launch.
Controller manager not available
The author offers a suggestion to try using OnProcessExit
to work around this but unfortunately it did not work for me. The comments on the video seem to suggest that a few others also hit this problem.
I did a bit of Googling and found an alternative way to add a delay on startup using TimerAction. Using the following code as a replacement for the original launch actions seems to work:
import os
from ament_index_python.packages import get_package_share_directory
from launch import LaunchDescription
from launch.actions import IncludeLaunchDescription
from launch.actions import TimerAction
from launch.launch_description_sources import PythonLaunchDescriptionSource
from launch.actions import RegisterEventHandler
from launch.event_handlers import OnProcessExit
from launch_ros.actions import Node
def generate_launch_description():
# Include the robot_state_publisher launch file, provided by our own package. Force sim time to be enabled
# !!! MAKE SURE YOU SET THE PACKAGE NAME CORRECTLY !!!
package_name='my_bot' #<--- CHANGE ME
rsp = IncludeLaunchDescription(
PythonLaunchDescriptionSource([os.path.join(
get_package_share_directory(package_name),'launch','rsp.launch.py'
)]), launch_arguments={'use_sim_time': 'true'}.items()
)
# Include the Gazebo launch file, provided by the gazebo_ros package
gazebo = IncludeLaunchDescription(
PythonLaunchDescriptionSource([os.path.join(
get_package_share_directory('gazebo_ros'), 'launch', 'gazebo.launch.py')]),
)
# Run the spawner node from the gazebo_ros package. The entity name doesn't really matter if you only have a single robot.
spawn_entity = Node(package='gazebo_ros', executable='spawn_entity.py',
arguments=['-topic', 'robot_description',
'-entity', 'my_bot'],
output='screen')
# This helps to address race conditions on startup for the
# controller managers. Note that we are exporting delayed_controller_manager_spawner
# instead of just diff_drive_spawner.
delayed_controller_manager_spawner = TimerAction(
period=10.0,
actions=[
Node(
package="controller_manager",
executable="spawner.py",
arguments=["diff_cont"],
),
Node(
package="controller_manager",
executable="spawner.py",
arguments=["joint_broad"],
)
],
)
# Launch them all!
return LaunchDescription([
rsp,
gazebo,
spawn_entity,
delayed_controller_manager_spawner,
])
This Github link has a good example of how to do this for another similar project: https://github.com/ros2/launch_ros/blob/b84b72748e22d8fd648151d96478d19305c96c82/launch_testing_ros/test/examples/check_node_launch_test.py#L36-L45.
Leave a Reply