frankaemika/franka_ros

How to change nameing of services to switch between robot and simulation

Closed this issue · 11 comments

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 to controller_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.

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.
Screenshot_20220422_160721

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:

  1. Let Gazebo top-level (i.e. /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)
               "/>
  1. or move Gazebo into the robot's namespace and remap the gazebo namespace of the model spawner:
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 54ab726 for details