0
$\begingroup$

Rosanswers logo

Hi, I am beginning to learn ROS and have encountered a strange issue. I have created 2 packages called, my_first_cpp_pkg and urdf_example, which contain xacro xmls of their own for URDF creation. I am getting to know the functionality of the launch file for ease.

I have an xacro file called example_urdf.robot.xacro in the package urdf_example, which if I try to run via command line to create the robot_description topic

ros2 run robot_state_publisher robot_state_publisher --ros-args -p robot_description:="$(xacro ros_articubot_tutorial/urdf_example/description/example_robot.urdf.xacro)"

throws the following error:-

[rcutils|error_handling.c:65] an error string (message, file name, or formatted message) will be truncated
[ERROR] [1659504478.236363109] [rcl]: Failed to parse global arguments
terminate called after throwing an instance of 'rclcpp::exceptions::RCLInvalidROSArgsError'

      what():  failed to initialize rcl: Couldn't parse parameter override rule: '-p robot_description:=<?xml version="1.0" ?
<!-- =================================================================================== -->
<!-- |    This document was autogenerated by xacro from ros_articubot_tutorial/urdf_example/description/example_robot.urdf.xacro | -->
<!-- |    EDITING THIS FILE BY HAND IS NOT RECOMMENDED                                 | -->
<!-- =================================================================================== -->
<robot name="robot">
  <!-- This is an example of a URDF. -->
  <!-- As we move through the file, new things to note will be pointed out. -->
  <!-- It's not meant an example of GOOD design, but an example of some of the various features of URDF/xacro. -->
  <!-- Thi, at /tmp/binarydeb/ros-foxy-rcl-1.1.13/src/rcl/arguments.c:325

However, if I run via a launch file, it works properly-

import os
from ament_index_python.packages import get_package_share_directory
from launch import LaunchDescription
from launch_ros.actions import Node
import xacro


def generate_launch_description():

# Specify the name of the package and path to xacro file within the package
pkg_name = 'urdf_example'
file_subpath = 'description/example_robot.urdf.xacro'

# Use xacro to process the file
xacro_file = os.path.join(get_package_share_directory(pkg_name),file_subpath)
robot_description_raw = xacro.process_file(xacro_file).toxml()

# Configure the node
node_robot_state_publisher = Node(
    package='robot_state_publisher',
    executable='robot_state_publisher',
    output='screen',
    parameters=[{'robot_description': robot_description_raw}] # add other parameters here if required
)


# Run the node
return LaunchDescription([
    node_robot_state_publisher
])

I wanted to see if it's the issue while processing of xacro file, so I manually parsed it and it works. Then I wanted to test if it's the issue with the command, then I tested the same robot_state_publisher command but gave the path of urdf of the package my_first_cpp_pkg/urdf_path and it works.

So, if it's neither an issue with xml parsing nor an issue with command, then I am not able to identify what is the additional information provided by launch file which makes it work without throwing any error?


Originally posted by manish.nayak on ROS Answers with karma: 3 on 2022-08-03

Post score: 0

$\endgroup$

2 Answers 2

0
$\begingroup$

Rosanswers logo

This issue thread seems to be connected to this problem (but it is already solved, implemented and merged...):

and

I think this can hint us the place of the error:

terminate called after throwing an instance of 'rclcpp::exceptions::RCLInvalidROSArgsError'

      what():  failed to initialize rcl: Couldn't parse parameter override rule: '-p robot_description:=<?xml version="1.0" ?

Why isn't it a string, but just a file-as-it-is?

In your launchfile you have two steps there:

robot_description_raw = xacro.process_file(xacro_file).toxml()

  1. process file, then

  2. convert it to XML

Maybe that is the difference?

Overall, in the terminal I would use only the path to the URDF file, like here:

ros2 run robot_state_publisher robot_state_publisher urdf/my_robot.urdf

And lauchfiles otherwise, for URDF / XACRO URDF, e.g. from the next section of ROS Industrial.


I found your example there: https://articulatedrobotics.xyz/ready-for-ros-7-urdf/ and use check_urdf (from sudo apt install liburdfdom-tools) to check it and got these errors:

$ check_urdf Desktop/example_robot.urdf.xacro 
Warning: link 'slider_link' material 'blue' undefined.
         at line 84 in /build/urdfdom-VnCcob/urdfdom-1.0.4+ds/urdf_parser/src/model.cpp
Warning: link 'slider_link' material 'blue' undefined.
         at line 84 in /build/urdfdom-VnCcob/urdfdom-1.0.4+ds/urdf_parser/src/model.cpp
Error:   Unable to parse component [${arm_length/2}] to a double (while parsing a vector value)
         at line 102 in /build/urdfdom-VnCcob/urdfdom-1.0.4+ds/urdf_parser/src/pose.cpp
Error:   Could not parse visual element for Link [arm_link]
         at line 453 in /build/urdfdom-VnCcob/urdfdom-1.0.4+ds/urdf_parser/src/link.cpp
Error:   Unable to parse component [${pi/2}] to a double (while parsing a vector value)
         at line 114

But, after saving in the same folder these three files from there: https://github.com/joshnewans/urdf_example/tree/main/description I could use xacro to get normal URDF from XACROURDF, it was parsed correctly too

ljaniec@ljaniec-PC:~/Desktop$ xacro example_robot.urdf.xacro > test_robot.urdf
ljaniec@ljaniec-PC:~/Desktop$ check_urdf test_robot.urdf 
robot name is: robot
---------- Successfully Parsed XML ---------------
root Link: world has 1 child(ren)
    child(1):  base_link
        child(1):  slider_link
            child(1):  arm_link
                child(1):  camera_link
                    child(1):  camera_link_optical

The different behavior in the terminal is surprising for sure.


Originally posted by ljaniec with karma: 3064 on 2022-08-03

This answer was ACCEPTED on the original site

Post score: 1


Original comments

Comment by manish.nayak on 2022-08-03:
I see. It indeed seems like a very old issue which has been fixed and even I believe that step 2 which converts to XML does the trick. What I don't understand is that I have been following the tutorials where they do the same. Also, this is the command and output where the exact same input works, albeit for a different urdf:-

   ros2 run robot_state_publisher robot_state_publisher --ros-args -p robot_description:="$(xacro ros_articubot_tutorial/my_first_cpp_pkg/urdf/example_robot.urdf)" 
    Parsing robot urdf xml string.
    Link base had 1 children
    Link l3 had 1 children
    Link l2 had 1 children
    Link l1 had 1 children
    Link grip had 0 children
    Link camera had 0 children
    [INFO] [1659520565.730462926] [robot_state_publisher]: got segment base .....

Does the content of the URDF cause some difference?

Comment by manish.nayak on 2022-08-04:
The different behavior in the terminal is surprising for sure.

Exactly! But I guess I would stick with this approach for now, although the root cause is still not clear. Thanks.

Overall, in the terminal I would use only the path to the URDF file, like here:

ros2 run robot_state_publisher robot_state_publisher urdf/my_robot.urdf

And lauchfiles otherwise, for URDF / XACRO URDF, e.g. from the next section of ROS Industrial.
$\endgroup$
1
$\begingroup$

I had this exact issue (using ROS2 Humble on Ubuntu 22.04) and after much frustrated old school debugging (i.e. delete part of the code until it works and gradually add code again until it breaks), the issue turned out to be:

Colons in XML comments in the URDF can break the parsing.

But only when running from command line. Running from the launch file is fine, but using ... --ros-args -p robot_description:="$(xacro ~/ros2_ws/mybot/description/urdf/mybot.urdf.xacro)" would cause the error.

Also if I ran xacro ~/ros2_ws/mybot/description/urdf/mybot.urdf.xacro > mybot.xml and then launched as ros2 run robot_state_publisher robot_state_publisher --ros-args -p robot_description:="$( cat mybot.xml )".

This is an example of a comment that will break the parsing:

<!--  NOTE: The origin has been rotated PI radians around Z because the RPLidar has X pointing backwards and Y pointing right compared to conventional robot orientation (X forward, Y left, Z up). -->

Removing the colon will make it work:

<!--  NOTE The origin has been rotated PI radians around Z because the RPLidar has X pointing backwards and Y pointing right compared to conventional robot orientation (X forward, Y left, Z up). -->

Weird? You betcha...

So to fix your issue, look at all the XML comments in your URDF and see if any has a colon in it.

(As a further detail, URLs in XML comments acutally do work fine. With colon and all. So maybe it's some weird regex that expects a word followed by color to be a proper URL scheme?)

$\endgroup$

Your Answer

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