.urdf  →  ros2_control

ros2_control configuration, generated from your URDF

The joint list, the command and state interfaces, the limits on each command — all of it is already in your description, and all of it is normally retyped by hand into two files. Open the model and take the configuration instead.

What comes out

Open your robot in the viewer and choose Export → ros2_control · configuration. You get a zip with three files and a README that says what had to be assumed:

What is derived, and what is not

Everything above comes out of the file you opened. Joint names, their order, their limits — read, not guessed. That is the part where a human transcribing twelve joints into two files gets one of them wrong, and where the mistake shows up much later as a robot that moves almost correctly.

What cannot be derived is the hardware. The plugin that talks to real motors is a driver somebody wrote for your machine, and no description names it. The generated block therefore loads mock_components/GenericSystem — the loopback that pretends every command was executed perfectly. It runs today, without a driver, and it is marked in the file as the one line to replace.

Two other things are said out loud rather than papered over: a joint with no declared limits gets a command interface without bounds, and a mimic joint gets no controller at all, because it is driven by the joint it follows.

The order of the joints is not cosmetic

A trajectory message is a list of positions matched to a list of names. Publish one against a different order and the robot moves the right amounts on the wrong joints. There is no error and no warning — the message is well formed, the controller accepts it, and the machine does something else.

The generated YAML keeps the order the joints appear in the description, and says so in a comment. The motion tool exports its JointTrajectory in that same order, for the same reason.

Before you launch it

A configuration generated from a description inherits whatever the description got wrong. Worth two minutes first: the viewer checks the model as it loads — joints with a zero effort limit, limits that leave no valid position, a joint that is movable but locked by equal bounds. Every one of those produces a controller that starts and then behaves strangely.

And if the movement matters more than the wiring, the motion tool will tell you whether the motors in that same description can perform what you plan to command — before the controller exists.

Common questions

What is ros2_control, in one paragraph?

The layer between a robot description and a robot that moves. A URDF says what the machine is; ros2_control says which joints have motors, what each motor accepts and reports, which controller claims which joint, and how fast the loop runs. None of that is in the description, which is why every robot needs it written once.

What can be generated from a URDF, and what cannot?

The joint list, their command and state interfaces, and the position limits on each command can all be read straight out of the description — that is most of the typing and all of the transcription errors. What cannot be derived is your hardware: the plugin that talks to real motors is a driver somebody wrote for your machine, and no description names it.

Why does the generated file use mock_components/GenericSystem?

Because it runs today. The mock hardware loops every command back as if it had been executed perfectly, so the controller manager starts, the controllers claim their joints and you can publish a trajectory before any driver exists. It is one line, and it is commented as the one line to replace.

Why is joint order in the YAML not alphabetical?

Because a trajectory is a list of numbers matched to that list of names. Publish one against a different order and the robot moves the right amounts on the wrong joints — no error, no warning, just a machine doing something else. The generated order is the order the joints appear in the description.

Does it handle mimic joints?

By leaving them out, and saying so. A mimic joint is driven by the joint it follows; giving it a controller means two things commanding one joint, which fails in ways that look like a tuning problem for a long time before anyone suspects the configuration.

What about a joint with no limits?

Its command interface is written without min and max, and the README says how many joints that happened to. Inventing bounds would be inventing the machine's range, and a controller that silently clamps to a number nobody chose is worse than one that accepts anything.

Is this a replacement for reading the documentation?

No. It is the transcription — the part where a human copies twelve joint names into two files and gets one of them wrong. What the controllers do, how to tune them and which one suits your robot is what the ros2_control documentation is for.