(!) Please ask about problems and questions regarding this tutorial on answers.ros.org. Don't forget to include in your question the link to this page, the versions of your OS & ROS, and also add appropriate tags.

ServiceState (ROS)

Description: This tutorial shows how to represent the execution of a service as a SMACH state.

Tutorial Level: BEGINNER

Next Tutorial: Monitor State

   1 from smach_ros import ServiceState

You could simply call any service from a generic state, but SMACH has specific support to call services, saving you a lot of code! SMACH provides a state class that acts as a proxy to a ROS service. The instantiation of the state takes a service name, service type, and some policy for generating a service request. The possible outcomes of the service state are 'succeeded', 'preempted' and 'aborted'.

/!\ The service state is almost identical to the simple action state. Just replace 'goal' with 'request', and 'result' with 'response'.

Request

Empty request message

   1 sm = StateMachine(['succeeded','aborted','preempted'])
   2 with sm:
   3     smach.StateMachine.add('TRIGGER_GRIPPER',
   4                            ServiceState('service_name',
   5                                         GripperSrv),
   6                            transitions={'succeeded':'APPROACH_PLUG'})

Fixed request message

   1 sm = StateMachine(['succeeded','aborted','preempted'])
   2 with sm:
   3     smach.StateMachine.add('TRIGGER_GRIPPER',
   4                            ServiceState('service_name',
   5                                         GripperSrv,
   6                                         request = GripperSrv(9.0)),
   7                            transitions={'succeeded':'APPROACH_PLUG'})

/!\ You may need to use the actual request type instead of the service type: ie. request = GripperSrvRequest(9.0) instead of GripperSrv.

Request from user data

   1 sm = StateMachine(['succeeded','aborted','preempted'])
   2 with sm:
   3     smach.StateMachine.add('TRIGGER_GRIPPER',
   4                            ServiceState('service_name',
   5                                         GripperSrv,
   6                                         request_slots = ['max_effort',
   7                                                          'position']),
   8                            transitions={'succeeded':'APPROACH_PLUG'})

Request callback

   1 sm = StateMachine(['succeeded','aborted','preempted'])
   2 with sm:
   3 
   4     @smach.cb_interface(input_keys=['gripper_input'])
   5     def gripper_request_cb(userdata, request):
   6        gripper_request = GripperSrv().Request
   7        gripper_request.position.x = 2.0
   8        gripper_request.max_effort = userdata.gripper_input
   9        return gripper_request
  10 
  11     smach.StateMachine.add('TRIGGER_GRIPPER',
  12                            ServiceState('service_name',
  13                                         GripperSrv,
  14                                         request_cb = gripper_request_cb,
  15                                         input_keys = ['gripper_input']),
  16                            transitions={'succeeded':'APPROACH_PLUG'})

For more advanced callback usage, see @smach.cb_interface decorator.

Response

Response to user data

Response callback

This works similarly to the SimpleActionState result callback, except instead of receiving both the result status and result data, the second argument to the callback is simply the service response message.

For more advanced callback usage, see @smach.cb_interface decorator.

Wiki: smach/Tutorials/ServiceState (last edited 2012-04-28 09:38:00 by MartinGuenther)