ros_comm
ros_comm copied to clipboard
remapping parameter names in roslaunch is inconsistent
Remapping can be used for parameter names, but is inconsistent when namespaces are involved.
Here is a minimal example:
❯ roscat foo foo.py
#!/usr/bin/env python
import rospy
rospy.init_node("foo")
print("myparam: ", rospy.get_param("myparam"))
TLDR: See the last two examples for the failure cases.
this works:
<?xml version="1.0"?>
<launch>
<param name="bar" value="123"/>
<node ns="foo" name="foo" pkg="foo" type="foo.py" required="true" output="screen">
<remap from="myparam" to="/bar" />
</node>
</launch>
so does that:
<?xml version="1.0"?>
<launch>
<param name="bar" value="123"/>
<group ns="foo">
<remap from="myparam" to="/bar" />
<node name="foo" pkg="foo" type="foo.py" required="true" output="screen"/>
</group>
</launch>
This fails (as expected, though there might be use-cases for it):
<?xml version="1.0"?>
<launch>
<param name="bar" value="123"/>
<group ns="foo">
<remap from="myparam" to="/bar" />
</group>
<node ns="foo" name="foo" pkg="foo" type="foo.py" required="true" output="screen"/>
</launch>
Crucially, this fails but I would expect it to work:
<?xml version="1.0"?>
<launch>
<param name="bar" value="123"/>
<remap from="foo/myparam" to="/bar" />
<node ns="foo" name="foo" pkg="foo" type="foo.py" required="true" output="screen"/>
</launch>
However, and that's the unintuitive part, the following succeeds:
<?xml version="1.0"?>
<launch>
<param name="bar" value="123"/>
<remap from="myparam" to="/bar" />
<node ns="foo" name="foo" pkg="foo" type="foo.py" required="true" output="screen"/>
</launch>
May be related to https://github.com/ros/ros_comm/issues/2175 which is concerned with remapping topics. The bug most likely affects any remapping including remapping of parameters.
This is not a bug as remappig essentially gets passed ddown to nodes arguments and it only considers ros names declared in the node's code. And the declared name in the node is "myparam" and not "foo/myparam" hence it is not matched for remapping at all.
The same behaviour happens with topics. Ig this behaviour is by design, tho it could have been better.
This is not a bug as remappig essentially gets passed down to nodes arguments and it only considers ros names declared in the node's code. And the declared name in the node is "myparam" and not "foo/myparam" hence it is not matched for remapping at all.
Arguing for language semantics with implementation details is never a good idea. :)
I do not have an implementation because I just noticed and reported this as inconsistent with expectations and then worked around it, but here are my current thoughts on this. It is quite possible to rewrite the node's remapping arguments to account for the respective values of ROS_NAMESPACE
in scope of the remap, but it's not implemented.
- I would expect a remap on
foo/xyz
to trigger for a node in (sub)namespacefoo/
that uses the namexyz
. This could be implemented with an additional filter that strips any additional namespace of a node for which remap args are generated from the source names of the remap (if such a prefix matches in the name). - I would expect a parameter remap on
xyz
to succeed only for a node in some subnamespace when the node usessearchParam
and ends up looking at a parameterxyz
in the parent namespace where the remap is defined. This might be possible by resolving the absolute name of the parameter and pass that one as the remap source argument.
remap targets are a different debate, but they might also need some more thoughts.
That being said, I believe it is no good idea to break the current behavior after so many years, so I would mostly like to see the prefix matching supported to get the remap to work that I mentioned in my first post.. Not saying anyone will bother :shrug:
I am not sure if you got me, the language semantics here are not implementation defined because this behaviour is explicitly mentioned in the documentation and hence this should be expected by anyone who uses this feature. I agree that it could have been better.
Also for your first use case there can be conflict in the following case, lets say you have a node namespace foo and also have a topic as below, nh.subscribe("foo/xyz", 1, &callback); then it would never be possible to remap the topic which in this case would be /foo/foo/xyz to /foo/new_name
I am not sure if you got me,
I believe we just take different stances on this edge-case. There are advantages to either definition, though we both seem to agree that the current behavior is "not ideal". :)
the language semantics here are not implementation defined because this behaviour is explicitly mentioned in the documentation and hence this should be expected by anyone who uses this feature. I agree that it could have been better.
Please point me to the documentation that describes the expected behavior for <remap>
statements in roslaunch files when the subsequent affected node definitions add additional namespaces. I cannot find it. I only found this documentation explaining how the command line arguments are to be interpreted with namespaces. And that seems well defined.
But from my perspective this documentation only describes the case where the remap directive is in the same namespace as the node definition. By the nature of command line arguments they can never be "in a different namespace". But in roslaunch xml that is perfectly possible and can affect the interpretation. So either
- you bluntly ignore the namespace difference and just append the remap command line arguments without modification (that's what happens, and it's the simplest)
- or you prohibit differences in namespace between remaps and affected node definitions (the strictest, but it breaks a lot of launch files that do not even rely on it just because some node in scope of an unrelated remap uses a namespace)
- or you define something for how the difference in namespaces is to affect the remapping.
I'm not saying I thought all of this through, but I do not see how the current behavior can be claimed to be consistent or intuitive (and I don't see documentation for it).
Also for your first use case there can be conflict in the following case, lets say you have a node namespace foo and also have a topic as below, nh.subscribe("foo/xyz", 1, &callback); then it would never be possible to remap the topic which in this case would be /foo/foo/xyz to /foo/new_name
I don't see why not?
<launch>
<remap from="foo/foo/xyz" to="foo/new_name" />
<node name="foo" pkg="foo" type="foo" ns="foo" />
</launch>
as well as
<launch>
<node name="foo" pkg="foo" type="foo" ns="foo">
<remap from="foo/xyz" to "new_name" />
</node>
</launch>
both appear to have clear semantics to me that could be implemented consistently with the definition of command line remappings and some prefix matching.
Assuming roslaunch fully resolves remap targets in that context, you could even do
<launch>
<remap from="foo/xyz" to="xyz" />
<node ns="foo" .../>
</launch>
and thus remap a name xyz
into the parent namespace without using /
in the beginning. That's impossible at the moment, but it would be necessary to allow the whole launch file to be included in an additional namespace from higher up.
And then there is this curiosity with the current interpretation:
<launch>
<remap from="foo" to="/bar" />
<node name="foo" pkg="test_remaps" type="foo.py" output="screen" ns="a" />
<node name="foo" pkg="test_remaps" type="foo.py" output="screen" ns="b" />
<node name="foo" pkg="test_remaps" type="foo.py" output="screen" ns="c" />
</launch>
Usually one statement should do one thing (and you can argue that the remap still only does one thing, but in my world you'd be wrong ;)), but the remap directive here remaps three distinct names/topics to one target name/topic. It's even worse when the target is no absolute name (no /
prefix), because that remaps three topics to three different topics...