I'm trying to make an environment for a simulation with a robotic arm (github repo of the 3 packages). Ubuntu 20 with ros foxy. This repo when running

ros2 launch learm_ros2 follower.launch.py
ros2 launch learm_ros2 run.launch.py

Allows you to visualise the robotic arm in rviz and move it (only if the real one is connected,) moving as well the real robotic arm. I wanted to start adding the robot into gazebo to proceed with simulations, seeing that one of the packages is called moveit_config

I modified run.launch.py in order to open gazebo, an empty world with a model (a table from the gazebo library), and I spawn the robot on top. The first thing I noticed is that the urdf being used is in the other package, description package, and has a xacro file as well. Which for the follower script and rviz, worked fine. But for gazebo, I need intertial and collision values, which are not in this urdf but happen to be in the urdf that is in main package

 urdf = os.path.join(

And the structure:

robot name is: LeArm
---------- Successfully Parsed XML ---------------
root Link: base_link has 1 child(ren)
    child(1):  shoulder_link
        child(1):  humerus_link
            child(1):  forearm_link
                child(1):  wrist_link
                    child(1):  hand_link
                        child(1):  grip_left_link
                            child(1):  finger_left_link
                        child(2):  grip_right_link
                            child(1):  finger_right_link
                        child(3):  tendon_left_link
                        child(4):  tendon_right_link

This is my modified run.launch.py

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

def generate_launch_description():
    gui = LaunchConfiguration('gui', default='true')
    rviz_config = os.path.join(

    urdf = os.path.join(

    with open(urdf, 'r') as infp:
        robot_desc = infp.read()
    gazebo_world_path = os.path.join(
        'worlds', 'table_world.world')  
    return LaunchDescription([
            cmd=['gazebo', '--verbose', gazebo_world_path, '-s', 'libgazebo_ros_factory.so', '-u'],
            package='gazebo_ros', executable='spawn_entity.py',
            arguments=['-entity', 'robot_name', '-topic', 'robot_description', '-z', '1.04'],  
            package='joint_state_publisher' + '_gui' if gui else '',
            executable='joint_state_publisher' + '_gui' if gui else '',
            parameters=[{'robot_description': robot_desc}],
            package='joint_state_publisher', executable='joint_state_publisher',
            parameters=[{'robot_description': robot_desc}],
            parameters=[{'robot_description': robot_desc}],
            parameters=[{'robot_description': robot_desc}],
            arguments=['-d', rviz_config]),
        # Node(
        #     package='gazebo_ros',
        #     executable='gazebo',
        #     name='gazebo',
        #     output='screen',
        #     arguments=['-e', '-s', 'libgazebo_ros_controller_manager.so']),

robot starting the simulation robot falls on itself

I added more mass to the base so it would not flip as well. This is what the log gives me. I can already see a warning on deleting a connection right after creation, and the gazebo_ros2_control errors of yaml configuration files.

ros2 launch learm_ros2 run.launch.py 
/opt/ros/foxy/bin/ros2:6: DeprecationWarning: pkg_resources is deprecated as an API. See https://setuptools.pypa.io/en/latest/pkg_resources.html
  from pkg_resources import load_entry_point
[INFO] [launch]: All log files can be found below /home/mk/.ros/log/2024-04-04-23-40-36-177870-mk-5490
[INFO] [launch]: Default logging verbosity is set to INFO
[INFO] [gazebo-1]: process started with pid [5492]
[INFO] [spawn_entity.py-2]: process started with pid [5494]
[INFO] [joint_state_publisher_gui-3]: process started with pid [5496]
[INFO] [joint_state_publisher-4]: process started with pid [5498]
[INFO] [robot_state_publisher-5]: process started with pid [5500]
[INFO] [rviz2-6]: process started with pid [5511]
[robot_state_publisher-5] Parsing robot urdf xml string.
[robot_state_publisher-5] The root link base_link has an inertia specified in the URDF, but KDL does not support a root link with an inertia.  As a workaround, you can add an extra dummy link to your URDF.
[robot_state_publisher-5] Link shoulder_link had 1 children
[robot_state_publisher-5] Link humerus_link had 1 children
[robot_state_publisher-5] Link forearm_link had 1 children
[robot_state_publisher-5] Link wrist_link had 1 children
[robot_state_publisher-5] Link hand_link had 4 children
[robot_state_publisher-5] Link grip_left_link had 1 children
[robot_state_publisher-5] Link finger_left_link had 0 children
[robot_state_publisher-5] Link grip_right_link had 1 children
[robot_state_publisher-5] Link finger_right_link had 0 children
[robot_state_publisher-5] Link tendon_left_link had 0 children
[robot_state_publisher-5] Link tendon_right_link had 0 children
[robot_state_publisher-5] [INFO] [1712266836.456161261] [robot_state_publisher]: got segment base_link
[robot_state_publisher-5] [INFO] [1712266836.456240671] [robot_state_publisher]: got segment finger_left_link
[robot_state_publisher-5] [INFO] [1712266836.456249049] [robot_state_publisher]: got segment finger_right_link
[robot_state_publisher-5] [INFO] [1712266836.456253881] [robot_state_publisher]: got segment forearm_link
[robot_state_publisher-5] [INFO] [1712266836.456258395] [robot_state_publisher]: got segment grip_left_link
[robot_state_publisher-5] [INFO] [1712266836.456262773] [robot_state_publisher]: got segment grip_right_link
[robot_state_publisher-5] [INFO] [1712266836.456267075] [robot_state_publisher]: got segment hand_link
[robot_state_publisher-5] [INFO] [1712266836.456271369] [robot_state_publisher]: got segment humerus_link
[robot_state_publisher-5] [INFO] [1712266836.456275698] [robot_state_publisher]: got segment shoulder_link
[robot_state_publisher-5] [INFO] [1712266836.456280086] [robot_state_publisher]: got segment tendon_left_link
[robot_state_publisher-5] [INFO] [1712266836.456284457] [robot_state_publisher]: got segment tendon_right_link
[robot_state_publisher-5] [INFO] [1712266836.456288771] [robot_state_publisher]: got segment wrist_link
[gazebo-1] Gazebo multi-robot simulator, version 11.11.0
[gazebo-1] Copyright (C) 2012 Open Source Robotics Foundation.
[gazebo-1] Released under the Apache 2 License.
[gazebo-1] http://gazebosim.org
[spawn_entity.py-2] [INFO] [1712266836.811201907] [spawn_entity]: Spawn Entity started
[spawn_entity.py-2] [INFO] [1712266836.812114364] [spawn_entity]: Loading entity published on topic robot_description
[spawn_entity.py-2] [INFO] [1712266836.815611701] [spawn_entity]: Waiting for entity xml on robot_description
[spawn_entity.py-2] [INFO] [1712266836.828088416] [spawn_entity]: Waiting for service /spawn_entity, timeout = 30
[spawn_entity.py-2] [INFO] [1712266836.828809548] [spawn_entity]: Waiting for service /spawn_entity
[rviz2-6] [INFO] [1712266836.836382659] [rviz2]: Stereo is NOT SUPPORTED
[rviz2-6] [INFO] [1712266836.836553267] [rviz2]: OpenGl version: 4.3 (GLSL 4.3)
[gazebo-1] Gazebo multi-robot simulator, version 11.11.0
[gazebo-1] Copyright (C) 2012 Open Source Robotics Foundation.
[gazebo-1] Released under the Apache 2 License.
[gazebo-1] http://gazebosim.org
[rviz2-6] [INFO] [1712266836.858854278] [rviz2]: Stereo is NOT SUPPORTED
[joint_state_publisher-4] [INFO] [1712266836.863734987] [joint_state_publisher]: Waiting for robot_description to be published on the robot_description topic...
[rviz2-6] Parsing robot urdf xml string.
[joint_state_publisher_gui-3] [INFO] [1712266836.996659300] [joint_state_publisher]: Centering
[gazebo-1] [INFO] [1712266837.412595584] [gazebo_ros_node]: ROS was initialized without arguments.
[spawn_entity.py-2] [INFO] [1712266837.833437326] [spawn_entity]: Calling service /spawn_entity
[spawn_entity.py-2] [INFO] [1712266838.127301269] [spawn_entity]: Spawn status: SpawnEntity: Successfully spawned entity [robot_name]
[INFO] [spawn_entity.py-2]: process has finished cleanly [pid 5494]
[gazebo-1] [Msg] Waiting for master.
[gazebo-1] [Msg] Connected to gazebo master @
[gazebo-1] [Msg] Publicized address:
[gazebo-1] [Wrn] [Event.cc:61] Warning: Deleting a connection right after creation. Make sure to save the ConnectionPtr from a Connect call
[gazebo-1] [INFO] [1712266838.773043703] [gazebo_ros2_control]: Loading gazebo_ros2_control plugin
[gazebo-1] [INFO] [1712266838.774871093] [gazebo_ros_control]: Starting gazebo_ros2_control plugin in namespace: /
[gazebo-1] [INFO] [1712266838.775045657] [gazebo_ros_control]: Starting gazebo_ros2_control plugin in ros 2 node: gazebo_ros_control
[gazebo-1] [ERROR] [1712266838.775078276] [gazebo_ros_control]: No parameter file provided. Configuration might be wrong
[gazebo-1] [ERROR] [1712266838.775138756] [gazebo_ros_control]: failed to parse input yaml file(s)

I searched on the learm_moveit_mode1.launch.py as it has a supposed environment to test the arm in gazebo as I understood it, and it configures yaml files. But this is confusing as well, as there are several yaml files for the robotic arm.


ls learm_ros2_description/config/
controllers.yaml       joint_limits.yaml  learm_servo.yaml    ros_controllers.yaml
fake_controllers.yaml  kinematics.yaml    ompl_planning.yaml


ls learm_ros2_moveit_config/config/
cartesian_limits.yaml  gazebo_controllers.yaml  sensors_3d.yaml                 stomp_planning.yaml
chomp_planning.yaml    LeArm.srdf               simple_moveit_controllers.yaml

I think I am either missing something quite basic in configuration or something with ros_controllers as a user in this site mentioned in a previous question.

This for example is ros_controllers.launch

<?xml version="1.0"?>

  <!-- Load joint controller configurations from YAML file to parameter server -->
  <rosparam file="$(find learm_ros2_moveit_config)/config/ros_controllers.yaml" command="load"/>

  <!-- Load the controllers -->
  <node name="controller_spawner" pkg="controller_manager" type="spawner" respawn="false"
    output="screen" args="arm_controller "/>


I do not understand why the robot seems to not update the joint_states publisher and acts strange, moving on its own (with the effects of gravity).


Taking @christoph-froehlich's advice, updating the system to Ubuntu 22 and ros2 humble did not change anything but it's always good to have it. Works the same. I think that the urdf needs the appropriate ros2-control tags with the existent joints. I will keep this updated.


2 Answers 2


Foxy is EOL, please use a still supported ROS distribution.

There were several fixes to gazebo_ros2_control regarding sagging robots.

By having a look on your console output: Why are you using joint_state_publisher_gui and gazebo at the same time? Both will publish on /joint_states if configured so.

  • $\begingroup$ Thank you very much! I will try with a supported ROS2 distro and update this! Sorry for the joint_state_publisher_gui, at some point I removed it and it didn't change any behavior so I kept it. $\endgroup$
    – M.K
    Apr 5 at 9:06

It was a bit confusing at first so I will summarise how I fixed it:

  1. Create a ros2_control.xacro file that will be included in the urdf.xacro. Add the proper ros2-control tags with each joint necessary, and the gazebo-ros2-control. I tried with just the .urdf, but it was not working.
  2. Include it in the urdf.xacro. Use that for the robot_description. Remember, you will not use the .urdf, but the new .urdf.xacro

<xacro:include filename = "ros2_control.xacro" />

  1. PROPERLY define the yaml file, with the proper structure and ros__params.

        update_rate: 30
        use_sim_time: true
          type: joint_state_controller/JointStateController
          publish_rate: 50`
  2. ros2_control is now able to connect to the joints, the console will show you so. It can also be checked with roscontrol list_hardware_interfaces


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.