1
$\begingroup$

I have seen two posts with talking about this issue but none of them have been answered.

class gazebo_ros2_control/GazeboSystem with base class type hardware_interface::SystemInterface does not exist and ROS2/Gazebo/ros2_control: Class gazebo_ros2_control/GazeboSystem does not exist

I am trying to create a controller using gazebo_ros2_control. I am using ROS2 Humble, Gazebo 11 and Ubuntu 22.04.

The error I am getting is as follows "According to the loaded plugin descriptions the class gazebo_ros2_control/GazeboSystem with base class type hardware_interface::SystemInterface does not exist. Declared types are fake_components/GenericSystem mock_components/GenericSystem test_hardware_components/TestSystemCommandModes test_hardware_components/TestTwoJointSystem test_system"

I have ros2_control installed and it is the correct branch for my ROS2 distro. I can run the ros2_control_demos successfully.

Here is the ROS2 control portion of my xacro file

    <ros2_control name="GazeboSystem" type="system">
      <hardware>
        <plugin>gazebo_ros2_control/GazeboSystem</plugin>
      </hardware>
      <joint name="pitch_mass_joint">
        <command_interface name="position">
          <param name="min">${pitch_mass_limit_lower}</param>
      <param name="max">${pitch_mass_limit_upper}</param>
        </command_interface>
        <state_interface name="position"/>
        <state_interface name="velocity"/>
        <state_interface name="effort"/>
      </joint>

      <joint name="port_aileron_joint">
        <command_interface name="position">
          <param name="min">${aileron_limit_lower}</param>
      <param name="max">${aileron_limit_upper}</param>
        </command_interface>
        <state_interface name="position"/>
        <state_interface name="velocity"/>
        <state_interface name="effort"/>
      </joint>

      <joint name="port_flap_joint">
        <command_interface name="position">
          <param name="min">${flap_limit_lower}</param>
      <param name="max">${flap_limit_upper}</param>
        </command_interface>
        <state_interface name="position"/>
        <state_interface name="velocity"/>
        <state_interface name="effort"/>
      </joint>

      <joint name="stbd_aileron_joint">
        <command_interface name="position">
          <param name="min">${aileron_limit_lower}</param>
      <param name="max">${aileron_limit_upper}</param>
        </command_interface>
        <state_interface name="position"/>
        <state_interface name="velocity"/>
        <state_interface name="effort"/>
      </joint>

      <joint name="stbd_flap_joint">
        <command_interface name="position">
          <param name="min">${flap_limit_lower}</param>
      <param name="max">${flap_limit_upper}</param>
        </command_interface>
        <state_interface name="position"/>
        <state_interface name="velocity"/>
        <state_interface name="effort"/>
      </joint>
    </ros2_control>

   <gazebo>
       <plugin filename="libgazebo_ros2_control.so" name="gazebo_ros2_control" >
          <parameters>$(find zray_bringup)/config/controller_configuration.yaml</parameters>
       </plugin>
   </gazebo>

Here is my config file

gazebo_ros2_control:
  ros__parameters:
    hardware_interface: gazebo_ros2_control/GazeboSystem
    robot_description: robot_description
    
controller_manager:
  ros__parameters:
    update_rate: 100 #Hz

    joint_trajectory_controller:
      type: joint_trajectory_controller/JointTrajectoryController

    joint_state_broadcaster:
      type: joint_state_broadcaster/JointStateBroadcaster

joint_trajectory_controller:
  ros__parameters:
    joints:
      - pitch_mass_joint
      - port_aileron_joint
      - port_flap_joint
      - stbd_aileron_joint
      - stbd_flap_joint
    interface_name: position
    command_interfaces:
      - position
    state_interfaces:
      - position
      - velocity

and here is my launch file

import os
from ament_index_python.packages import get_package_share_directory
from launch import LaunchDescription
from launch.actions import DeclareLaunchArgument, ExecuteProcess
from launch.substitutions import LaunchConfiguration
from launch_ros.actions import Node

import xacro

def generate_launch_description():

    use_sim_time = LaunchConfiguration('use_sim_time', default='false')

    urdf_file_name = 'zray.urdf.xacro'
    urdf = os.path.join(
        get_package_share_directory('zray'),
        urdf_file_name)
    #with open(urdf, 'r') as infp:
    #    robot_desc = infp.read()

    robot_description_config = xacro.process_file(urdf)
    robot_desc = robot_description_config.toxml()

    controller_config_file_name = 'controller_configuration.yaml'
    controller_config = os.path.join(
        get_package_share_directory('zray_bringup'), 'config',
        controller_config_file_name)
        
    
    load_joint_state_controller = ExecuteProcess(
        cmd=['ros2', 'control', 'load_controller', '--set-state', 'active', 'joint_state_broadcaster'],
        output='screen'
    )
    
    load_joint_trajectory_controller = ExecuteProcess(
        cmd=['ros2', 'control', 'load_controller', '--set-state', 'active', 'joint_trajectory_controller'],
        output='screen'
    )
    
    return LaunchDescription([
        DeclareLaunchArgument(
            'use_sim_time',
            default_value='false',
            description='Use simulation (Gazebo) clock if true'),
        Node(
            package='robot_state_publisher',
            executable='robot_state_publisher',
            name='robot_state_publisher',
            output='screen',
            parameters=[{'use_sim_time': use_sim_time, 'robot_description': robot_desc}],
            arguments=[robot_desc]),
        Node(
            package='zray',
            executable='state_publisher',
            name='state_publisher',
            output='screen'),

        Node(
            package='controller_manager',
            executable='ros2_control_node',
            parameters=[{'robot_description': robot_desc}, controller_config],
            output='screen'),
            
        load_joint_state_controller, load_joint_trajectory_controller,                

    ])

I have noticed something else which my be pointing to the same underlying issue. I have been following tutorials on ros2_control pipeline in Gazebo from the Construct. https://youtu.be/xBhYHOSxMOk?si=JpdWSoqeRTptElVd&t=2566

When I set the state of the joint_state_broadcaster to 'start'

cmd=['ros2','control','load_controller','--set-state','start','joint_state_broadcaster'], ...

I get "ros2 control load_controller: error: argument --set-state: invalid choice: 'start' (choose from 'configured', 'inactive', 'active')"

It seem to work fine for everyone else, so it appears like I have some versioning issue. Why would I not have 'start' to chose from? I have tried everything I can think of to find it with no luck.

I appreciate any help or insight as I am truly stuck. For completeness I am attaching the full ROS info log incase that is of any help.

Thanks

Gideon

[INFO] [robot_state_publisher-1]: process started with pid [103499]
[INFO] [state_publisher-2]: process started with pid [103501]
[INFO] [ros2_control_node-3]: process started with pid [103503]
[INFO] [ros2-4]: process started with pid [103505]
[INFO] [ros2-5]: process started with pid [103507]
[INFO] [spawn_entity.py-6]: process started with pid [103509]
[robot_state_publisher-1] [INFO] [1706740525.742803775] [robot_state_publisher]: got segment base_link
[robot_state_publisher-1] [INFO] [1706740525.742904027] [robot_state_publisher]: got segment dummy_link
[robot_state_publisher-1] [INFO] [1706740525.742919349] [robot_state_publisher]: got segment pitch_mass_link
[robot_state_publisher-1] [INFO] [1706740525.742928839] [robot_state_publisher]: got segment port_aileron_link
[robot_state_publisher-1] [INFO] [1706740525.742936937] [robot_state_publisher]: got segment port_flap_link
[robot_state_publisher-1] [INFO] [1706740525.742944622] [robot_state_publisher]: got segment stbd_aileron_link
[robot_state_publisher-1] [INFO] [1706740525.742951954] [robot_state_publisher]: got segment stbd_flap_link
[ros2_control_node-3] [INFO] [1706740525.746934847] [resource_manager]: Loading hardware 'GazeboSystem' 
[ros2_control_node-3] terminate called after throwing an instance of 'pluginlib::LibraryLoadException'
[ros2_control_node-3]   what():  According to the loaded plugin descriptions the class gazebo_ros2_control/GazeboSystem with base class type hardware_interface::SystemInterface does not exist. Declared types are  fake_components/GenericSystem mock_components/GenericSystem test_hardware_components/TestSystemCommandModes test_hardware_components/TestTwoJointSystem test_system
[ros2_control_node-3] Stack trace (most recent call last):
[ros2_control_node-3] #16   Object "", at 0xffffffffffffffff, in 
[ros2_control_node-3] #15   Object "/opt/ros/humble/lib/controller_manager/ros2_control_node", at 0x56420a88ed84, in 
[ros2_control_node-3] #14   Source "../csu/libc-start.c", line 392, in __libc_start_main_impl [0x7f2d8fc29e3f]
[ros2_control_node-3] #13   Source "../sysdeps/nptl/libc_start_call_main.h", line 58, in __libc_start_call_main [0x7f2d8fc29d8f]
[ros2_control_node-3] #12   Object "/opt/ros/humble/lib/controller_manager/ros2_control_node", at 0x56420a88e89e, in 
[ros2_control_node-3] #11   Object "/opt/ros/humble/lib/libcontroller_manager.so", at 0x7f2d90635661, in controller_manager::ControllerManager::ControllerManager(std::shared_ptr<rclcpp::Executor>, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, rclcpp::NodeOptions const&)
[ros2_control_node-3] #10   Object "/opt/ros/humble/lib/libcontroller_manager.so", at 0x7f2d90634747, in controller_manager::ControllerManager::init_resource_manager(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)
[ros2_control_node-3] #9    Object "/opt/ros/humble/lib/libhardware_interface.so", at 0x7f2d902d1d7f, in hardware_interface::ResourceManager::load_urdf(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, bool)
[ros2_control_node-3] #8    Object "/opt/ros/humble/lib/libhardware_interface.so", at 0x7f2d902d040e, in 
[ros2_control_node-3] #7    Object "/opt/ros/humble/lib/libhardware_interface.so", at 0x7f2d902af6b0, in 
[ros2_control_node-3] #6    Object "/usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.30", at 0x7f2d900ae4d7, in __cxa_throw
[ros2_control_node-3] #5    Object "/usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.30", at 0x7f2d900ae276, in std::terminate()
[ros2_control_node-3] #4    Object "/usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.30", at 0x7f2d900ae20b, in 
[ros2_control_node-3] #3    Object "/usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.30", at 0x7f2d900a2b9d, in 
[ros2_control_node-3] #2    Source "./stdlib/abort.c", line 79, in abort [0x7f2d8fc287f2]
[ros2_control_node-3] #1    Source "../sysdeps/posix/raise.c", line 26, in raise [0x7f2d8fc42475]
[ros2_control_node-3] #0  | Source "./nptl/pthread_kill.c", line 89, in __pthread_kill_internal
[ros2_control_node-3]     | Source "./nptl/pthread_kill.c", line 78, in __pthread_kill_implementation
[ros2_control_node-3]       Source "./nptl/pthread_kill.c", line 44, in __pthread_kill [0x7f2d8fc969fc]
[ros2_control_node-3] Aborted (Signal sent by tkill() 103503 1000)
[state_publisher-2] [INFO] [1706740526.045458968] [state_publisher]: state_publisher started
[spawn_entity.py-6] [INFO] [1706740526.062908834] [spawn_entity]: Spawn Entity started
[spawn_entity.py-6] [INFO] [1706740526.063390831] [spawn_entity]: Loading entity published on topic /robot_description
[spawn_entity.py-6] /opt/ros/humble/local/lib/python3.10/dist-packages/rclpy/qos.py:307: UserWarning: DurabilityPolicy.RMW_QOS_POLICY_DURABILITY_TRANSIENT_LOCAL is deprecated. Use DurabilityPolicy.TRANSIENT_LOCAL instead.
[spawn_entity.py-6]   warnings.warn(
[spawn_entity.py-6] [INFO] [1706740526.065729092] [spawn_entity]: Waiting for entity xml on /robot_description
[spawn_entity.py-6] [INFO] [1706740526.076636921] [spawn_entity]: Waiting for service /spawn_entity, timeout = 30
[spawn_entity.py-6] [INFO] [1706740526.076959611] [spawn_entity]: Waiting for service /spawn_entity
[spawn_entity.py-6] [INFO] [1706740526.080424535] [spawn_entity]: Calling service /spawn_entity
[spawn_entity.py-6] [INFO] [1706740526.282578617] [spawn_entity]: Spawn status: SpawnEntity: Successfully spawned entity [zray-62706]
[INFO] [spawn_entity.py-6]: process has finished cleanly [pid 103509]
[ros2-4] Sucessfully loaded controller joint_state_broadcaster into state active
[INFO] [ros2-4]: process has finished cleanly [pid 103505]
[ERROR] [ros2_control_node-3]: process has died [pid 103503, exit code -6, cmd '/opt/ros/humble/lib/controller_manager/ros2_control_node --ros-args --params-file /tmp/launch_params_76vi2_zj --params-file /home/gideon/zray_ws/src/zray_bringup/config/controller_configuration.yaml'].
[ros2-5] Sucessfully loaded controller joint_trajectory_controller into state active
[INFO] [ros2-5]: process has finished cleanly [pid 103507]

$\endgroup$

1 Answer 1

0
$\begingroup$

Btw: Both questions have been answered.

Why do you use a ros2_control_node? (see the answers in the questions you mentioned).

$\endgroup$
2
  • $\begingroup$ There are two answers on the first link, one is actually a question asking if ros2 control demos are working, and the other said "Thanks for help and your answers. I almost solve the problems." So I figured out there was more to sort out. I appreciate you pointing out the ros2_control_node not needing to be there. Removing it has cleared up the issue. I saw it in a tutorial. Is that only used when launching a real robot? Thanks $\endgroup$
    – Gideon
    Feb 5 at 18:15
  • $\begingroup$ The ros2_control_node is a wrapper around the controller_manager. The gazebo_ros2_control directly creates an instance of the controller manager class, hence, there is no need for an additional ros2_control_node. $\endgroup$ Feb 5 at 19:00

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.