ros-controls / ros2_control

Generic and simple controls framework for ROS 2
https://control.ros.org
Apache License 2.0
433 stars 272 forks source link

gazebo plugin not found by controller manager #1554

Closed MannavaVivek closed 1 month ago

MannavaVivek commented 1 month ago

I am trying to connect my robot arm to Gazebo but when i set the ros2_control hardware plugin to Gazebo as

        <ros2_control name="${name}" type="system">
            <hardware>
                <plugin>gazebo_ros2_control/GazeboSystem</plugin>
            </hardware>

I get the following error:

[ros2_control_node-1] [INFO] [1716894885.022383172] [controller_manager]: Received robot description file.
[ros2_control_node-1] [INFO] [1716894885.022679968] [resource_manager]: Loading hardware 'MyCobotControlInterface'
[ros2_control_node-1] [ERROR] [1716894885.022794553] [controller_manager]: The published robot description file (urdf) seems not to be genuine. The following error was caught: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

But the plugin are located in the same include directory as the two that are found here.

christophfroehlich commented 1 month ago

What do you want to achieve? Loading gazebo_ros2_control together with a custom 'MyCobotControlInterface' is not supported afaik.

MannavaVivek commented 1 month ago

Here is the xacro file that I am calling:

    <xacro:include filename="$(find mycobot_description)/arms/gen3/${dof}dof/urdf/mycobot.ros2_control.xacro" />
    <xacro:mycobot_ros2_control
      name="${prefix}MyCobotControlInterface" prefix="${prefix}"
      use_fake_hardware="${use_fake_hardware}"
      fake_sensor_commands="${fake_sensor_commands}"
      sim_gazebo="${sim_gazebo}"
      sim_ignition="${sim_ignition}"
      tf_prefix=""
      initial_positions="${initial_positions}"
      gripper_max_velocity="${gripper_max_velocity}"
      gripper_max_force="${gripper_max_force}"
      gripper_joint_name="${gripper_joint_name}"/>

and this in turn calls

<?xml version="1.0"?>
<robot xmlns:xacro="http://www.ros.org/wiki/xacro">

  <xacro:macro name="mycobot_ros2_control" params="
    name
    prefix
    use_fake_hardware:=false
    fake_sensor_commands:=false
    sim_gazebo:=false
    sim_ignition:=false
    tf_prefix
    initial_positions:=${dict(joint_1=0.0,joint_2=0.0,joint_3=0.0,joint_4=0.0,joint_5=0.0,joint_6=0.0,joint_7=0.0)}
    gripper_joint_name
    gripper_max_velocity:=100.0
    gripper_max_force:=100.0">

    <ros2_control name="${name}" type="system">
      <hardware>
        <xacro:if value="${sim_gazebo}">
          <plugin>gazebo_ros2_control/GazeboSystem</plugin>
        </xacro:if>
        <xacro:if value="${sim_ignition}">
          <plugin>ign_ros2_control/IgnitionSystem</plugin>
        </xacro:if>
        <xacro:if value="${use_fake_hardware}">
          <plugin>mock_components/GenericSystem</plugin>
          <param name="fake_sensor_commands">${fake_sensor_commands}</param>
          <param name="state_following_offset">0.0</param>
        </xacro:if>
      </hardware>
      <joint name="${prefix}joint_1">
        <command_interface name="position">
          <param name="min">{-2*pi}</param>
          <param name="max">{2*pi}</param>
        </command_interface>
        <state_interface name="position">
          <param name="initial_value">${initial_positions['joint_1']}</param>
        </state_interface>
        <state_interface name="velocity"/>
        <state_interface name="effort"/>
      </joint>
      <joint name="${prefix}joint_2">
        <command_interface name="position">
          <param name="min">-2.41</param>
          <param name="max">2.41</param>
        </command_interface>
        <state_interface name="position">
          <param name="initial_value">${initial_positions['joint_2']}</param>
        </state_interface>
        <state_interface name="velocity"/>
        <state_interface name="effort"/>
      </joint>
      <joint name="${prefix}joint_3">
        <command_interface name="position">
          <param name="min">{-2*pi}</param>
          <param name="max">{2*pi}</param>
        </command_interface>
        <state_interface name="position">
          <param name="initial_value">${initial_positions['joint_3']}</param>
        </state_interface>
        <state_interface name="velocity"/>
        <state_interface name="effort"/>
      </joint>
      <joint name="${prefix}joint_4">
        <command_interface name="position">
          <param name="min">-2.66</param>
          <param name="max">2.66</param>
        </command_interface>
        <state_interface name="position">
          <param name="initial_value">${initial_positions['joint_4']}</param>
        </state_interface>
        <state_interface name="velocity"/>
        <state_interface name="effort"/>
      </joint>
      <joint name="${prefix}joint_5">
        <command_interface name="position">
          <param name="min">{-2*pi}</param>
          <param name="max">{2*pi}</param>
        </command_interface>
        <state_interface name="position">
          <param name="initial_value">${initial_positions['joint_5']}</param>
        </state_interface>
        <state_interface name="velocity"/>
        <state_interface name="effort"/>
      </joint>
      <joint name="${prefix}joint_6">
        <command_interface name="position">
          <param name="min">-2.23</param>
          <param name="max">2.23</param>
        </command_interface>
        <state_interface name="position">
          <param name="initial_value">${initial_positions['joint_6']}</param>
        </state_interface>
        <state_interface name="velocity"/>
        <state_interface name="effort"/>
      </joint>
      <joint name="${prefix}joint_7">
        <command_interface name="position">
          <param name="min">{-2*pi}</param>
          <param name="max">{2*pi}</param>
        </command_interface>
        <state_interface name="position">
          <param name="initial_value">${initial_positions['joint_7']}</param>
        </state_interface>
        <state_interface name="velocity"/>
        <state_interface name="effort"/>
      </joint>
    </ros2_control>
  </xacro:macro>

</robot>

And since sim_gazebo is set to true, it tries to load the plugin, from where comes the error.

christophfroehlich commented 1 month ago

Does it work if you enable mock_components/GenericSystem instead?

christophfroehlich commented 1 month ago

And which operating system + ROS distro are you using (humble, because you still have a fake_component..)? Which version of gazebo_ros2_control have you installed? ros2 pkg xml gazebo_ros2_control -t version

MannavaVivek commented 1 month ago

I can use mock_components/GenericSystem and run a controller_manager node myself, to control the robot in RViz, but the gazebo simulation just stays limp. I have been trying add the controllers so the robot replicates the motion in Gazebo as well.

As for the system details, I am Ros 2 Humble via the robostack binaries, and the gazebo_ros2_control version is 0.4.6

christophfroehlich commented 1 month ago

Can you check if you can run the gazebo_ros2_control_demos? There you also see the minimum to get a it running: Exactly, the gazebo plugin creates the controller_manager itself.

MannavaVivek commented 1 month ago

Okay I managed to resolve it, but not entire sure how.

I am now spawning gazebo as

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

whereas before I spawned them as

    start_gazebo_server_cmd = ExecuteProcess(
        condition=IfCondition(use_simulator),
        cmd=[
            'gzserver',
            '-s',
            'libgazebo_ros_init.so',
            '-s',
            'libgazebo_ros_factory.so',
            'myworld.world',
        ],
        # cwd=[launch_dir],
        output='screen',
    )

    start_gazebo_client_cmd = ExecuteProcess(
        condition=IfCondition(PythonExpression([use_simulator, ' and not ', headless])),
        cmd=['gzclient'],
        # cwd=[launch_dir],
        output='screen',
    )

and somehow this seemed to do the trick.

Ishansehgal commented 1 month ago

I'm experiencing the same problem. After the update, it has stopped working, even though it was functioning before. I've also tried the gazebo_ros2_control demos. Below, I've attached the log for reference.

~$ ros2 launch gazebo_ros2_control_demos gripper_mimic_joint_example_effort.launch.py 
[INFO] [launch]: All log files can be found below /home/techturners/.ros/log/2024-06-07-11-18-14-836133-team1381-45265
[INFO] [launch]: Default logging verbosity is set to INFO
[INFO] [gzserver-1]: process started with pid [45267]
[INFO] [gzclient-2]: process started with pid [45269]
[INFO] [robot_state_publisher-3]: process started with pid [45271]
[INFO] [spawn_entity.py-4]: process started with pid [45273]
[robot_state_publisher-3] [INFO] [1717739295.713308971] [robot_state_publisher]: got segment base
[robot_state_publisher-3] [INFO] [1717739295.713431601] [robot_state_publisher]: got segment finger_left
[robot_state_publisher-3] [INFO] [1717739295.713438484] [robot_state_publisher]: got segment finger_right
[robot_state_publisher-3] [INFO] [1717739295.713443043] [robot_state_publisher]: got segment world
[spawn_entity.py-4] [INFO] [1717739296.037380683] [spawn_entity]: Spawn Entity started
[spawn_entity.py-4] [INFO] [1717739296.037798237] [spawn_entity]: Loading entity published on topic robot_description
[spawn_entity.py-4] /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-4]   warnings.warn(
[spawn_entity.py-4] [INFO] [1717739296.040010035] [spawn_entity]: Waiting for entity xml on robot_description
[spawn_entity.py-4] [INFO] [1717739296.051454938] [spawn_entity]: Waiting for service /spawn_entity, timeout = 30
[spawn_entity.py-4] [INFO] [1717739296.051866450] [spawn_entity]: Waiting for service /spawn_entity
[spawn_entity.py-4] [INFO] [1717739297.056777083] [spawn_entity]: Calling service /spawn_entity
[spawn_entity.py-4] [INFO] [1717739297.269601522] [spawn_entity]: Spawn status: SpawnEntity: Successfully spawned entity [gripper]
[gzserver-1] [INFO] [1717739297.289676661] [gazebo_ros2_control]: Loading gazebo_ros2_control plugin
[gzserver-1] [INFO] [1717739297.292821599] [gazebo_ros2_control]: Starting gazebo_ros2_control plugin in namespace: /
[gzserver-1] [INFO] [1717739297.293022486] [gazebo_ros2_control]: Starting gazebo_ros2_control plugin in ros 2 node: gazebo_ros2_control
[gzserver-1] [INFO] [1717739297.293619235] [gazebo_ros2_control]: Loading parameter files /home/techturners/second_ws/install/gazebo_ros2_control_demos/share/gazebo_ros2_control_demos/config/gripper_controller_effort.yaml
[gzserver-1] [INFO] [1717739297.293761071] [gazebo_ros2_control]: after remapping 
[gzserver-1] [INFO] [1717739297.297095094] [gazebo_ros2_control]: connected to service!! robot_state_publisher
[gzserver-1] [INFO] [1717739297.299172009] [gazebo_ros2_control]: Received urdf from param server, parsing...
[gzserver-1] [WARN] [1717739297.311104868] [gazebo_ros2_control]: The position_proportional_gain parameter was not defined, defaulting to: 0.1
[gzserver-1] [INFO] [1717739297.311690225] [gazebo_ros2_control]: Loading joint: right_finger_joint
[gzserver-1] [INFO] [1717739297.311848011] [gazebo_ros2_control]:   State:
[gzserver-1] [INFO] [1717739297.311878829] [gazebo_ros2_control]:        position
[gzserver-1] [INFO] [1717739297.312130020] [gazebo_ros2_control]:            found initial value: 0.150000
[gzserver-1] [INFO] [1717739297.312147483] [gazebo_ros2_control]:        velocity
[gzserver-1] [INFO] [1717739297.312244715] [gazebo_ros2_control]:        effort
[gzserver-1] [INFO] [1717739297.312282787] [gazebo_ros2_control]:   Command:
[gzserver-1] [INFO] [1717739297.312356585] [gazebo_ros2_control]:        effort
[gzserver-1] [INFO] [1717739297.312632062] [gazebo_ros2_control]: Loading joint: left_finger_joint
[gzserver-1] [INFO] [1717739297.312644685] [gazebo_ros2_control]:   State:
[gzserver-1] [INFO] [1717739297.312650406] [gazebo_ros2_control]:        position
[gzserver-1] [INFO] [1717739297.312656968] [gazebo_ros2_control]:        velocity
[gzserver-1] [INFO] [1717739297.312664733] [gazebo_ros2_control]:        effort
[gzserver-1] [INFO] [1717739297.312670604] [gazebo_ros2_control]:   Command:
[gzserver-1] [INFO] [1717739297.312955398] [resource_manager]: Initialize hardware 'GazeboSystem' 
[gzserver-1] [INFO] [1717739297.313750850] [resource_manager]: Successful initialization of hardware 'GazeboSystem'
[gzserver-1] [INFO] [1717739297.313943792] [resource_manager]: 'configure' hardware 'GazeboSystem' 
[gzserver-1] [INFO] [1717739297.313954822] [resource_manager]: Successful 'configure' of hardware 'GazeboSystem'
[gzserver-1] [INFO] [1717739297.313959992] [resource_manager]: 'activate' hardware 'GazeboSystem' 
[gzserver-1] [INFO] [1717739297.313964741] [resource_manager]: Successful 'activate' of hardware 'GazeboSystem'
[gzserver-1] [INFO] [1717739297.314379278] [gazebo_ros2_control]: Loading controller_manager ..
[gzserver-1] [INFO] [1717739297.324397306] [controller_manager]: Subscribing to '~/robot_description' topic for robot description file.
[gzserver-1] [INFO] [1717739297.325628275] [gazebo_ros2_control]: Loading controller_manager's next
[gzserver-1] [WARN] [1717739297.325785209] [gazebo_ros2_control]:  Desired controller update period (0.01 s) is slower than the gazebo simulation period (0.001 s).
[gzserver-1] [INFO] [1717739297.326867919] [gazebo_ros2_control]: Loaded gazebo_ros2_control.
[INFO] [spawn_entity.py-4]: process has finished cleanly [pid 45273]
[INFO] [ros2-5]: process started with pid [45424]
[ros2-5] Could not contact service /controller_manager/load_controller
[ERROR] [ros2-5]: process has died [pid 45424, exit code 1, cmd 'ros2 control load_controller --set-state active joint_state_broadcaster'].
[INFO] [ros2-6]: process started with pid [45606]
[ros2-6] Could not contact service /controller_manager/load_controller
[ERROR] [ros2-6]: process has died [pid 45606, exit code 1, cmd 'ros2 control load_controller --set-state active gripper_controller'].
christophfroehlich commented 1 month ago

I'm experiencing the same problem. After the update, it has stopped working, even though it was functioning before. I've also tried the gazebo_ros2_control demos. Below, I've attached the log for reference.

did the demos work or not?