Closed peetCreative closed 2 years ago
Sure you can. Have you tried using a namespace?
<?xml version="1.0"?>
<launch>
<include file="$(find gazebo_ros)/launch/empty_world.launch"/>
<group ns="franka_control">
<include file="$(find franka_gazebo)/launch/panda.launch">
<arg name="gazebo" value="false" />
<!-- all other your args you want to set here -->
</include>
</group>
</launch>
Then you should see every topic, service & action within that namespace similar to the real robot:
$ rosservice list /franka_control | grep -E "set_(EE|K|load)"
/franka_control/set_EE_frame
/franka_control/set_K_frame
/franka_control/set_load
Does this help you?
Hey, thanks for the quick help, it actually changes the name. However this seems to break some things in the panda.launch file. I will try to find a way..
What exactly breaks?
However gazebo is not working and the controller as well, there is no obvious errormessages in the log, but I guess some services and topics are now on the wrong namespace.
Best hint is: Controller Spawner couldn't find the expected controller_manager ROS interface.
So the controller_manager does not find the services controller_manager/load_controller, unload_controller, ...
because they are now under /franka_control
I also pushed your suggestion to my previous branch so you could checkout here.
I think, we need to put the name into the urdf. But maybe also have a look, how the setups with two robots solve this problem. Because there you want the services advertise for each robot.
It's a general thing also on how does naming works in the ROS world.
So should these services live in:
/<robot_arm_name>/franka_control/set_load
or rather directly in /<robot_arm_name>/set_load
In contrast the examples here with two arms are that there is one controller and one combined_ros_control node.
However what if I want to have two seperate ros_control_node nodes running and two times the same controller on them. How's the naming than, and best would consistent between simulation and the real robot.
Yes you are on a good track I think. The problem with the namespace is that the model spawner must find the spawn_urdf_model
service of Gazebo and the controller spawner must find the controller_manager/load_controller
service of the controller manager. Unfortunately for your use case both nodes are started from the same panda.launch
file, which works fine if everything is top-level.
So I think you have two options:
/gazebo
) and pass the namespace of the robot into the model spawner:
diff --git a/franka_gazebo/launch/panda.launch b/franka_gazebo/launch/panda.launch
index a15c27e..69ba397 100644
--- a/franka_gazebo/launch/panda.launch
+++ b/franka_gazebo/launch/panda.launch
@@ -57,7 +57,7 @@
<node name="$(arg arm_id)_model_spawner"
pkg="gazebo_ros"
type="spawn_model"
- args="-param robot_description -urdf -model $(arg arm_id) $(arg unpause)
+ args="-param robot_description -urdf -model $(arg arm_id) $(arg unpause) -robot_namespace /franka_control
$(arg initial_joint_positions)
"/>
2. or move Gazebo into the robot's namespace and remap the gazebo namespace of the model spawner:
```diff
diff --git a/franka_gazebo/launch/panda.launch b/franka_gazebo/launch/panda.launch
index a15c27e..e5fa512 100644
--- a/franka_gazebo/launch/panda.launch
+++ b/franka_gazebo/launch/panda.launch
@@ -57,7 +57,7 @@
<node name="$(arg arm_id)_model_spawner"
pkg="gazebo_ros"
type="spawn_model"
- args="-param robot_description -urdf -model $(arg arm_id) $(arg unpause)
+ args="-param robot_description -urdf -model $(arg arm_id) $(arg unpause) -gazebo_namespace /franka_control/gazebo
$(arg initial_joint_positions)
"/>
Please try if this helps your use case as intermediate solution. Of course hardcoding the namespace into the panda.launch
is not a resilient solution, so we have to discuss a bit internally about how to make this proper. Maybe a(nother) arg to panda.launch
?
Let me know if any of this helps you in the process
Note for solution 1. you would probably want <arg name="gazebo" value="true" />
and for 2. <arg name="gazebo" value="false" />
(and the empty_world.launch
outside of the <group>
) in your outer launch file
That definitly helps.
For perspective: From what I think, and know about ROS and nameing it would be good to have a scheme, which is interchangeable between simulation and "reality". So as a proposal for a naming scheme for a single robot arm.
/<arm_id>/franka_control
/<arm_id>/controller_manager
/<arm_id>/controller_spawner
/<arm_id>/joint_state_publisher
/<arm_id>/robot_state_publisher
/<arm_id>/<controller_name>
However for that we would need to tinker also around with the examples in franka_example_controllers. I'm about to commit a proposal. But didn't got it quite right jet.
Also I often find in launch files $(arg arm_id)_more_naming
. I'm not a big expert with ROS, but I thought this is supposed to be solved using namespaces. So $(arg arm_id)/more_naming
or probably put the corresponding node to the corresponding namespace.
Hi @peetCreative,
you definitely have a point regarding our naming and namespaces in general. However this is a relatively breaking change for users which we have to discuss internally. Your original problem how to match simulation & real robot naming is solved, right? Can we close this issue then?
For reference, the service names were adjusted within franka_gazebo
so they better match now with franka_control
. See 54ab726ba2eea4 for details
Hello, I want to call some services provided by franka_control e.g.
set_EE_frame
For demonstration I exended the cartesian_impedance_example_controller here. So I want to run the controller in the simulation as well as on the robot.However running on the robot (
roslaunch franka_example_controllers cartesian_impedance_example_controller.launch ...
), the node franka_control provides the service of course to/franka_control/set_EE_frame
. Running the gazebo simulation (roslaunch franka_gazebo panda.launch ...
), franka_hw_sim provides the service on/set_EE_frame
.So the standard way to face this issue in ROS is to use the
remap
-tag in the roslaunch file to redirect the services. However I did not find a way for to pass this tocontroller_manager/spawner
.My workaround currently is to define a param called operation_type I read from the controller, and depending on it I call either the one or the other service name. I think, that's a bad solution as the controller should not care about it is simulated or not. This is connected to #241, where it is also recomended to call either the one or the other.