What are the industry best practices for the URDF / SDF mismatch?
This problem is well known and clearly defined. I have seen the following solutions:
- Tutorial: Using a URDF in Gazebo
- sdformat_urdf package to transform SDF to URDF XML, with a lot of limitations
- A lengthy discussion on the robot state publisher github issues
The sdformat_urdf package would have been nice, except that it does not support universal joints. So that makes me ask two questions:
- What are the industry best practices for the issue where your SDF must have elements that are not supported in both formats? Do professional teams write their own state publishers in such a case?
- What can I use in place of a universal join that may be a good substitute. I'll clarify my use case below
I am building a hobby project of an autonomous electric go-kart by taking the chassis and steering system from an old riding lawn mower; pictured below.
I would like to use ROS packages wherever possible. Already I now have to create my own controller based on the ros2-controller package to support Ackermann Steering, which is not support in the ros2 version of the package.
The ros2-control manager subscribes to the /robot_description
, and similarly the join_state_publisher
which is useful for both ro2 control and localization.
I would also like to simulate my robot in gazebo11
so that I can iterate over the controller and perception stack faster.
It seems the only way to do this properly is to have two version of the description: one for the physical runtime, and one for simulation?
Optionally, is it possible to use a different type of joint? I see in the gazebo ackermann prius car example, it uses several universal joints. Can I use another type of joint and still be able to simulate the robot to test out the controller?
I can't say anything about industry best practices, but something which I've always done is consider Gazebo "virtual HW". So the
.sdf
is a description of my virtual HW. It's analogous, but not identical to my.urdf
, which is the bare-minimum description of my kinematic structure of my robot (and some related properties), which is used by various ROS nodes to control or interact with it.A good example are "parallel kinematics" or "closed-loop kinematics". SDF supports this, URDF doesn't. But in all cases I've worked with such kinematic configurations, the consumers of my URDF didn't need to know anything about that. Either because the underlying controller already took care of the closed-loop, or because of some other non-ROS part of my robots.
Another example would be things like suspensions and steering arrangements.
If you use the
.urdf
for what it's intended, I ...(more)For Ackermann specifically, most controllers I've seen just need two joints: a steering joint and a joint for the throttle. They mostly don't care about all the other parts of your model.
Whether that's the case for you I can't say, but I wanted to give a different perspective on the "why do I need two different descriptions of my robot?" question.
Edit: and to clarify: I'm not trying to gold-plate the situation.it's certainly true there are limitations in URDF.
it's an interesting perspective, I just refused to believe that it's OK to have two different descriptions of your robot for two scenarios, in which one of them is suppose to test and iterate faster over your robot. I guess I have to accept that I need two different definitions...
you don't have to do anything.
I posted my comment as, well, a comment for a reason. It's just a comment. Not an actual answer.
yes but I have not seen or learned of any clear way of doing this. I have been thinking about it over night. I think I may put a few parameters in a YAML file, like base width, wheel radius, etc, then use some python code to auto generate both URDF and SDF in their respective launch files. This way I am not always copy pasting values around.
Or maybe a single
.xacro
file that has these values that I can import into different base templates. But it's clear that trying to make an individual URDF that is published by robot_state_publisher and it consumable everywhere, including Gazebo, just isn't possible...Regarding the latest comment. IMHO, one should always use
.xacro
files, even urdf is straightforward. It just gives you much more flexibility.Regarding Ackerman controller. Yes you are right, it is not ported yet, but it should work very well with ros2_control after porting.