How to run ROS2 visualize_franka.sh with external /joint_state input
The visualize_franka.sh
script from the franka_description uses the joint state publisher GUI which has a graphical interface that constantly publishes joint states:
While this is a great tool for interactively setting the joint positions, since it’s constantly publishing joint states, it blocks every other software from publishing joint states to the same topic. While you can publish joint states to the same topic, the GUI will just overwrite your joint state with its own.
Modifying franka_description
to accept external joint states
To work around this, we need to modify the launch/visualize_franka.launch.py
to not start the joint state publisher GUI. The robot state publisher will subscribe to /joint_states
anyway, so you can just inject your own joint states into that topic.
The simple way to do it is to clone my fork, which has the modification already done and is based on my jazzy
port of franka_description
:
git clone -b external_joint_state https://github.com/ulikoehler/franka_description.git
You can also modify launch/visualize_franka.launch.py
yourself: Just delete the Node()
call that starts the joint state publisher GUI. The following diff shows you which lines to delete (the lines prefixed by -
).
robot_state_publisher_spawner_opaque_function,
- Node(
- package="joint_state_publisher_gui",
- executable="joint_state_publisher_gui",
- name="joint_state_publisher_gui",
- ),
Node(
package="rviz2",
executable="rviz2",
Running the modified script
Run visualize_franka.sh
as usual:
./scripts/visualize_franka.sh arm_id:=fr3
Note that it will look weird at first, since rviz2 won’t know any default joint states. This is normal and expected:
Which exact joint states does the robot_state_publisher
expect?
First, I recorded the /joint_states
topic using
ros2 topic echo /joint_states > joint_states.txt
Based on the output:
---
header:
stamp:
sec: 1736718274
nanosec: 6300566
frame_id: ''
name:
- fr3_joint1
- fr3_joint2
- fr3_joint3
- fr3_joint4
- fr3_joint5
- fr3_joint6
- fr3_joint7
- fr3_finger_joint1
- fr3_finger_joint2
position:
- -2.7437
- 0.8697321200000001
- 0.8121960000000001
- -2.2966916299999998
- -0.6359528999999999
- 2.9597191999999994
- 0.32752674000000015
- 0.038372
- 0.038372
velocity: []
effort: []
you can see that in our case, it expects 8
entries in the name
field, and 8
entries in the position
field. The velocity
and effort
fields are empty.
Publishing your own joint states
Now we can use the script from our post ROS2 Python script to publish custom joint states to publish our own joint states to the /joint_states
topic.
By running the script from that post:
./publish_custom_joint_states.py
we can see that the robot moves according to the sinusoidal joint states we’re publishing: