If I understand correctly, once you calibrate your cell, those settings remain valid during operation, and hopefully for a 'long' time, whatever long means. Furthermore, I assume that you don't need to dynamically reload the URDF with the system up and running.
If the above assumptions hold, a pattern that could work rather well is the following:
- Have all parameters that are subject to calibration (xacro, yaml, etc.) in a separate package (or packages). Let's call it
my_cell_calibration
. - The default version of
my_cell_calibration
contains nominal values, and is what you use in simulation. - Once you perform a calibration for a specific setup (sensor, robot, cell), you create a new version of
my_cell_calibration
and overlay it for your setup, so it gets picked up instead of the default with nominal values.
In this way, you don't need to touch the original URDF or other config files upon a calibration run. Just overlay and restart the relevant components.
Update after comments. On dynamically changing frames
If you want to dynamically change the frame associated to a joint or link, I would suggest extending the robot_state_publisher
node. This node currently takes as inputs a URDF and a joint_states
topic. You could add an additional, optional configuration that specifies which frames are subject to change dynamically. These frames would default to the value specified in the respective <origin>
, but the node would create subscribers for updating those values.
The configuration could look something like:
dynamic_frames:
- foo_joint
- foo_link
- bar_joint
which would create these subscribers of type geometry_msgs/PoseStamped
:
robot_state_publisher/dynamic_frames/foo_joint
robot_state_publisher/dynamic_frames/foo_link
robot_state_publisher/dynamic_frames/bar_joint
Naming and namespacing can vary, but you get the idea.
The output of robot_state_publisher
would still be a set of tf frames, but ones that take into account the dynamic variations of otherwise static URDF frames.
Update 2. Further comments
The upside of this approach is that the tf frames will be up to date with calibration updates. The downside is that exiting code that parses the URDF, like the kdl_parser
, for instance, would not be aware of the updated frames.
Also, if your calibration routine also calibrates joint zeros, you would need to feed updated offsets to the entity that publishes the joint_states
topic.
There was some work on a python library for reading, calibrating and writing URDFs. It should still be part of the calibration stack.
In the past I've usually manually done the "reloading" of the urdf by restarting the entire robot. Automatically reloading the URDF while running would be neat, but also could be tricky. You would need to make sure that every ROS node is designed to watch for and use a modified robot description.