Robotics StackExchange | Archived questions

Error when running launch file with joint_trajectory_controller

Hi everyone,

im quite new to ros2. I'm using humble and im#m trying to get my launch file to work. Here's my code:

import os

from ament_index_python.packages import get_package_share_directory

import launch 
from launch import LaunchDescription
import launch.actions 
import launch_ros
from launch.actions import IncludeLaunchDescription
from launch.launch_description_sources import PythonLaunchDescriptionSource


from launch_ros.actions import Node

def generate_launch_description():

    package_name='gripper'
gripper = IncludeLaunchDescription(
    PythonLaunchDescriptionSource([os.path.join(
        get_package_share_directory(package_name), 'launch', 'gripper_controller.launch.py'
        )]), launch_arguments={'use_sim_time': 'true'}.items()
)

gazebo = IncludeLaunchDescription(
    PythonLaunchDescriptionSource([os.path.join(
        get_package_share_directory('gazebo_ros'), 'launch', 'gazebo.launch.py'
    )]),
)

rviz2 = Node(
      package='rviz2', executable='rviz2', name="rviz2", output='screen',
    )

spawn_entity = Node(package='gazebo_ros', executable='spawn_entity.py',
                    arguments=['-topic', 'robot_description',
                               '-entity', 'gripper'],
                    output='screen'
)


gripper_pkg_path=get_package_share_directory('gripper')

joint_state_broadcaster_spawner = launch_ros.actions.Node(
    package='joint_state_publisher',
    executable='joint_state_publisher',
    name='joint_state_publisher',
    output='screen'
)

joint_trajectory_controller = launch_ros.actions.Node(
    package='joint_trajectory_controller',
    executable='joint_trajectory_controller',
    name='joint_trajectory_controller',
    output='screen',
    parameters=[os.path.join(gripper_pkg_path, 'config', 'config.yaml')]
)

controller_manager = launch_ros.actions.Node(
    package='controller_manager',
    executable='ros2_control_node',
    parameters=[os.path.join(gripper_pkg_path, 'config', 'config.yaml')],
    output='screen'
)

return LaunchDescription([
    gripper,
    gazebo,
    # rvis2,
    spawn_entity,
    joint_state_broadcaster_spawner,
    joint_trajectory_controller,
    controller_manager
])

And here is the included launch file:

import os

from ament_index_python.packages import get_package_share_directory

from launch import LaunchDescription
from launch.substitutions import LaunchConfiguration
from launch.actions import DeclareLaunchArgument
from launch_ros.actions import Node

import xacro


def generate_launch_description():

    # Check if we're told to use sim time
    use_sim_time = LaunchConfiguration('use_sim_time')

    # Process the URDF file
    pkg_path = os.path.join(get_package_share_directory('gripper'))
    xacro_file = os.path.join(pkg_path,'description','gripper.xacro')
    robot_description_config = xacro.process_file(xacro_file)

    # Create a robot_state_publisher node
    params = {'robot_description': robot_description_config.toxml(), 'use_sim_time': use_sim_time}
    node_robot_state_publisher = Node(
        package='robot_state_publisher',
        executable='robot_state_publisher',
        output='screen',
        parameters=[params]
    )


    # Launch!
    return LaunchDescription([
        DeclareLaunchArgument(
            'use_sim_time',
            default_value='false',
            description='Use sim time if true'),

        node_robot_state_publisher
    ])

And here's the output i receive when running the first launchfile:

[INFO] [launch]: Default logging verbosity is set to INFO
[ERROR] [launch]: Caught exception in launch (see debug for traceback): package 'joint_trajectory_controller' found at '/opt/ros/humble', but libexec directory '/opt/ros/humble/lib/joint_trajectory_controller' does not exist

did anyone have a similar issue or knows what's going on here?

Asked by Icon45 on 2023-05-25 02:42:04 UTC

Comments

Answers

The ros2_control controller named joint_trajectory_controller is not a standalone executable. It's a plugin that's dynamically loaded into the ROS 2 control controller manager. It's C++ code for controlling the robot, but like all of the ROS 2 control controllers, it gets exported as a pluginlib plugin, see here.

To load the controllers, you need to use the spawner executable from the controller_manager package to start joint_trajectory_controller and other ros2_control controllers. See, for example here in the Universal Robots ROS 2 driver.

I wrote a minimal ros2_control controller example here that provides a basic example. The controller is loaded (or "spawned") in the launch file here:

dz_spawner_node = launch_ros.actions.Node(
    package="controller_manager",
    executable="spawner",
    arguments=["dz_controller", "--controller-manager", "/controller_manager"]
)

This loads the controller plugin named dz_controller into the controller manager node named /controller_manager.

This controller named dz_controller is defined in the configuration YAML file here. The package and plugin type for the controller named dz_controller are declared there (a dz_minimal_controller/DzMinimalController) and the joints and interfaces are configured.

Anything provided by https://github.com/ros-controls/ros2_controllers will need to be loaded with the spawner executable like this. Note the possible difference in the name of the controller from the YAML file and the package that provides it. Frequently the package and controller name are the same, but not always, and you'll need to pass whatever you configured in the controller config YAML file to the spawner.

Asked by danzimmerman on 2023-05-26 06:45:03 UTC

Comments

Hi @danzimmerman,

thank you for your answer. I updated my code and unfortunately get a new error. I created a new question for that: https://answers.ros.org/question/415865/error-with-te-controller-manager/

Asked by Icon45 on 2023-05-26 10:33:09 UTC