ros2_control "Error configuring controller" and controller state "finalized"
Hello community,
I want to implement a differential drive controller on a simulated diff drive robot using ros2_control.
After I spawn my robot I run the launch file that starts the controllers (ros2 launch diffbot_sim diffbot_controllers.launch.py
) and I get the following error log (cut short for brevity):
[ros2-1] Sucessfully loaded controller joint_state_broadcaster into state active
...
[ros2-3] Error configuring controller
[ERROR] [ros2-3]: process has died [pid 7817, exit code 1, cmd 'ros2 control load_controller --set-state start diff_drive_controller'].
And the output of ros2 control list_controllers
is:
joint_state_broadcaster[joint_state_broadcaster/JointStateBroadcaster] active
diff_drive_controller[diff_drive_controller/DiffDriveController] finalized
The error log is pointing me to an error in the configuration file. Left and right wheel names seem to be ok. How do I debug this? Could you point me in the right direction? Thank you for any help you can offer.
Regards, Roberto
launch file:
import os
from ament_index_python.packages import get_package_share_directory
from launch import LaunchDescription
from launch.substitutions import Command, FindExecutable, PathJoinSubstitution
from launch.actions import ExecuteProcess, IncludeLaunchDescription, RegisterEventHandler
from launch.event_handlers import OnProcessExit
from launch.launch_description_sources import PythonLaunchDescriptionSource
from launch_ros.actions import Node
from launch_ros.substitutions import FindPackageShare
def generate_launch_description():
load_joint_state_controller = ExecuteProcess(
cmd=['ros2', 'control', 'load_controller', '--set-state', 'start',
'joint_state_broadcaster'],
output='screen'
)
load_diff_drive_controller = ExecuteProcess(
cmd=['ros2', 'control', 'load_controller', '--set-state', 'start',
'diff_drive_controller'],
output='screen'
)
return LaunchDescription([
load_joint_state_controller,
RegisterEventHandler(
event_handler=OnProcessExit(
target_action=load_joint_state_controller,
on_exit=[load_diff_drive_controller],
)
),
])
.yaml config file
controller_manager:
ros__parameters:
update_rate: 50 # Hz
joint_state_broadcaster:
type: joint_state_broadcaster/JointStateBroadcaster
diff_drive_controller:
type: diff_drive_controller/DiffDriveController
diffbot_base_controller:
ros__parameters:
left_wheel_names: ["left_wheel_joint"]
right_wheel_names: ["right_wheel_joint"]
wheel_separation: 0.10
#wheels_per_side: 1 # actually 2, but both are controlled by 1 signal
wheel_radius: 0.015
wheel_separation_multiplier: 1.0
left_wheel_radius_multiplier: 1.0
right_wheel_radius_multiplier: 1.0
publish_rate: 50.0
odom_frame_id: odom
base_frame_id: base_link
pose_covariance_diagonal : [0.001, 0.001, 0.001, 0.001, 0.001, 0.01]
twist_covariance_diagonal: [0.001, 0.001, 0.001, 0.001, 0.001, 0.01]
open_loop: true
enable_odom_tf: true
cmd_vel_timeout: 0.5
#publish_limited_velocity: true
use_stamped_vel: false
#velocity_rolling_window_size: 10
# Velocity and acceleration limits
# Whenever a min_* is unspecified, default to -max_*
linear.x.has_velocity_limits: true
linear.x.has_acceleration_limits: true
linear.x.has_jerk_limits: false
linear.x.max_velocity: 1.0
linear.x.min_velocity: -1.0
linear.x.max_acceleration: 1.0
linear.x.max_jerk: 0.0
linear.x.min_jerk: 0.0
angular.z.has_velocity_limits: true
angular.z.has_acceleration_limits: true
angular.z.has_jerk_limits: false
angular.z.max_velocity: 1.0
angular.z.min_velocity: -1.0
angular.z.max_acceleration: 1.0
angular.z.min_acceleration: -1.0
angular.z.max_jerk: 0.0
angular.z.min_jerk: 0.0
ros2_control XML tags:
<ros2_control name="diff_drive" type="system">
<hardware>
<plugin>gazebo_ros2_control/GazeboSystem</plugin>
</hardware>
<joint name="left_wheel_joint">
<command_interface name="velocity">
<param name="min">-1</param>
<param name="max">1</param>
</command_interface>
<state_interface name="position"/>
<state_interface name="velocity"/>
<state_interface name="effort"/>
</joint>
<joint name="right_wheel_joint">
<command_interface name="velocity">
<param name="min">-1</param>
<param name="max">1</param>
</command_interface>
<state_interface name="position"/>
<state_interface name="velocity"/>
<state_interface name="effort"/>
</joint>
</ros2_control>