Skip to content

[RFC] set initial controller state via configuration - #3489

Open
christianrauch wants to merge 1 commit into
ros-controls:masterfrom
christianrauch:set_init_state
Open

[RFC] set initial controller state via configuration#3489
christianrauch wants to merge 1 commit into
ros-controls:masterfrom
christianrauch:set_init_state

Conversation

@christianrauch

@christianrauch christianrauch commented Jul 20, 2026

Copy link
Copy Markdown
Contributor

Description

This is a proposal to add a new parameter initial_state, next to type, that allows the controller manager to set controller states (unconfigured, inactive, active) right after initialisation. The advantage of this is that you can start load, configure, or start controllers immediately, without requiring an external service call.

Example:

Using the configuration

controller_manager:
  ros__parameters:
    update_rate: 100

    joint_state_broadcaster:
      type: joint_state_broadcaster/JointStateBroadcaster
      initial_state: active

with:

def generate_launch_description():
    return LaunchDescription([
        Node(
            package="robot_state_publisher",
            executable="robot_state_publisher",
            parameters=[{"robot_description": URDF}],
        ),

        Node(
            package="controller_manager",
            executable="ros2_control_node",
            parameters=["controllers.yaml"],
        ),
    ])

starts the controller manager and the controllers almost instantly:

$ ros2 control list_controllers 
joint_state_broadcaster joint_state_broadcaster/JointStateBroadcaster  active

Fixes # (issue)

Is this user-facing behavior change?

Yes.

Did you use Generative AI?

No.

Additional Information

Controller configuration is not yet implemented. The user-facing change is only the addition of initial_state. Configuration parameters would be provided in the same way they are now.

TODOs

To send us a pull request, please:

  • Fork the repository.
  • Modify the source; please focus on the specific change you are contributing. If you also reformat all the code, it will be hard for us to focus on your change.
  • Ensure local tests pass. (colcon test and pre-commit run (requires you to install pre-commit by pip3 install pre-commit)
  • Commit to your fork using clear commit messages.
  • Send a pull request, answering any default questions in the pull request interface.
  • Pay attention to any automated CI failures reported in the pull request, and stay involved in the conversation.

@saikishor saikishor left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure if we should go down this road, at the end someone should load the controller and all and then you can always activate them as a group

@christianrauch

Copy link
Copy Markdown
Contributor Author

I'm not sure if we should go down this road, at the end someone should load the controller and all and then you can always activate them as a group

Yes. In this case, this "someone" would be the controller manager itself. The controller manager is already activating the hardware via the resource manager. So activating the controllers would be the next logical step.

@saikishor

Copy link
Copy Markdown
Member

I'm not sure if we should go down this road, at the end someone should load the controller and all and then you can always activate them as a group

Yes. In this case, this "someone" would be the controller manager itself. The controller manager is already activating the hardware via the resource manager. So activating the controllers would be the next logical step.

We are settling them up because without that there are no interfaces up and moreover, the hardware interfaces are limited and predefined in the URDF, but that's not the. Ade with the controllers, they are dynamic and you can load them at any point of time.

@christianrauch

Copy link
Copy Markdown
Contributor Author

I'm not sure if we should go down this road, at the end someone should load the controller and all and then you can always activate them as a group

Yes. In this case, this "someone" would be the controller manager itself. The controller manager is already activating the hardware via the resource manager. So activating the controllers would be the next logical step.

We are settling them up because without that there are no interfaces up and moreover, the hardware interfaces are limited and predefined in the URDF, but that's not the. Ade with the controllers, they are dynamic and you can load them at any point of time.

You can still continue to use the services to set the states. This PR is not touching that functionality. It only adds the option for the controller manager to set the states at initialisation without a separate service call.

If hardware components are predefined in the URDF and started automatically, and controllers are predefined in the controller manager configuration, why shouldn't there be an option to load, configure, or activate them as well? IMHO, it is very useful to have broadcasters or sensor processing/filtering nodes, that are permanently active, to start right at the beginning. In the same way that we currently do not have to use hardware_spawner.py (unless explicitly desired), this way, we also do not have to use the spawner.py. This safes you a lot of startup time and memory consumption on resource-constrained devices.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Needs discussion

Development

Successfully merging this pull request may close these issues.

3 participants