ros-controls / ros_control

Generic and simple controls framework for ROS
http://wiki.ros.org/ros_control
BSD 3-Clause "New" or "Revised" License
487 stars 307 forks source link

Calling switch_controller service from python requires controller being loaded #511

Open rhaschke opened 1 year ago

rhaschke commented 1 year ago

When switching controllers from the cmdline via rosservice call /controller_manager/switch_controller ... it works out of the box. However doing the same from python code always failed silently (response was ok=True, but controller wasn't started as confirmed via rqt controller_manager plugin). Experimenting a little bit, I noticed that I need to load the controller in advance when switching programmatically. However calling the service from cmdline and from python should be the same, shouldn't it?

This works:

#!/usr/bin/env python3
import rospy
from controller_manager_msgs.srv import SwitchController, LoadController

def call(ns, cls, **kwargs):
    rospy.wait_for_service(ns)
    service = rospy.ServiceProxy(ns, cls)
    response = service(**kwargs)
    print(response.ok)
    if not response.ok:
        print(response)

try:
    # When calling the switch_controller service here, I need to ensure that the controller is loaded.
    # When calling the service via cmdline (rosservice call /controller_manager/switch_controller ...) it works without loading!?
    call("/controller_manager/load_controller", LoadController,
         name="position_joint_trajectory_controller")

    call("/controller_manager/switch_controller", SwitchController,
         start_controllers=["position_joint_trajectory_controller"],
         stop_controllers=["effort_joint_trajectory_controller"],
         strictness=1, start_asap=False, timeout=0.0)

except rospy.ServiceException as e:
    print("Service call failed: %s" % e)
ZZWang21 commented 1 year ago

I am planning to do this recently, will try this code. Thanks.

A small question: is it possible to write python code controlling rqt to switch controllers?

rhaschke commented 1 year ago

Is it possible to write python code controlling rqt to switch controllers

I don't think so. However, if you switch controllers, rqt's controller_manager plugin should reflect the new state of the controllers.