-
-
Notifications
You must be signed in to change notification settings - Fork 104
Description
This came up when calling xacro from python. Not sure if this is an actual problem or expected behavior. I've lost a couple of days on this so at the very least maybe this can serve as a warning to the next person
Problem (?)
When passing argument values that contain single quote characters to xacro, the single quotes are interpreted as string literal delimiters within conditional expressions rather than as part of the value itself. Double quotes are not. This leads to (in my opinion) surprising and inconsistent behavior.
Steps to reproduce
example_problem.xacro
<?xml version="1.0" ?>
<robot name="example_problem" xmlns:xacro="http://www.ros.org/wiki/xacro">
<xacro:arg name="example_arg" default="" />
<xacro:property name="example_arg" value="$(arg example_arg)" />
<xacro:if value="${example_arg == ''}">
<link name="example_link"/>
</xacro:if>
</robot>Example calls to xacro
# Empty string: if conditional evaluates to true - resulting URDF contains example_link
xacro example_problem.xacro example_arg:=
# Literal single quotes: also matches empty string - resulting URDF contains example_link
xacro example_problem.xacro example_arg:="''"
# Literal double quotes: does not match empty string - resulting URDF does not contain example_link
xacro example_problem.xacro example_arg:='""'
This is particularly confusing when calling xacro from Python, where quote characters naturally end up in argument values:
# User intends to pass an empty string, but actually passes literal ""
subprocess.run(['xacro', 'example_problem.xacro', 'example_arg:=""'])
# User intends to pass an empty string, but '' gets parsed as empty string
# (happens to work, but maybe for the wrong reason)
subprocess.run(["xacro", "example_problem.xacro", "example_arg:=''"])Is this behavior expected? Personally, I'd expect example_arg:="''" to be evaluated in the same way as example_arg:='""', but it feels like there might be some complexities here that I'm not fully aware of
EDIT: Perhaps a better example
example_problem_2.xacro
What if we're trying to match a single space in the conditional?
<?xml version="1.0" ?>
<robot name="example_problem" xmlns:xacro="http://www.ros.org/wiki/xacro">
<xacro:arg name="example_arg" default="" />
<xacro:property name="example_arg" value="$(arg example_arg)" />
<xacro:if value="${example_arg == ' '}">
<link name="example_link_space"/>
</xacro:if>
</robot>xacro example_problem_2.xacro example_arg:='" "'Results in:
<?xml version="1.0" ?>
...
<robot name="example_problem">
</robot>Whereas:
xacro example_problem_2.xacro example_arg:="' '"Results in:
<?xml version="1.0" ?>
...
<robot name="example_problem">
<link name="example_link_space"/>
</robot>Environment
xacro version: 1.14.20
ROS: Noetic
OS: Ubuntu 20.04