## For instruction on writing tutorials ## http://www.ros.org/wiki/WritingTutorials #################################### ##FILL ME IN #################################### ## for a custom note with links: ## note = ## for the canned note of "This tutorial assumes that you have completed the previous tutorials:" just add the links ## note.0= ## descriptive title for the tutorial ## title = ServiceState (ROS) ## multi-line description to be displayed in search ## description = This tutorial shows how to represent the execution of a service as a SMACH state. ## the next tutorial description (optional) ## next = ## links to next tutorial (optional) ## next.0.link= [[smach/Tutorials/MonitorState|Monitor State]] ## next.1.link= ## what level user is this tutorial for ## level= BeginnerCategory ## keywords = #################################### <<IncludeCSTemplate(TutorialCSHeaderTemplate)>> <<TableOfContents(4)>> {{{#!python from smach_ros import ServiceState }}} You could simply call any service from a [[smach/Tutorials/Generic State|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 [[Services|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 === {{{#!python sm = StateMachine(['succeeded','aborted','preempted']) with sm: smach.StateMachine.add('TRIGGER_GRIPPER', ServiceState('service_name', GripperSrv), transitions={'succeeded':'APPROACH_PLUG'}) }}} === Fixed request message === {{{#!python sm = StateMachine(['succeeded','aborted','preempted']) with sm: smach.StateMachine.add('TRIGGER_GRIPPER', ServiceState('service_name', GripperSrv, request = GripperSrv(9.0)), 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 === {{{#!python sm = StateMachine(['succeeded','aborted','preempted']) with sm: smach.StateMachine.add('TRIGGER_GRIPPER', ServiceState('service_name', GripperSrv, request_slots = ['max_effort', 'position']), transitions={'succeeded':'APPROACH_PLUG'}) }}} === Request callback === {{{#!python sm = StateMachine(['succeeded','aborted','preempted']) with sm: @smach.cb_interface(input_keys=['gripper_input']) def gripper_request_cb(userdata, request): gripper_request = GripperSrv().Request gripper_request.position.x = 2.0 gripper_request.max_effort = userdata.gripper_input return gripper_request smach.StateMachine.add('TRIGGER_GRIPPER', ServiceState('service_name', GripperSrv, request_cb = gripper_request_cb, input_keys = ['gripper_input']), transitions={'succeeded':'APPROACH_PLUG'}) }}} For more advanced callback usage, see [[http://www.ros.org/doc/api/smach/html/python/smach.util.CBInterface-class.html|@smach.cb_interface]] decorator. == Response == === Response to user data === === Response callback === This works similarly to the SimpleActionState [[smach/Tutorials/SimpleActionState#Result_callback|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 [[http://www.ros.org/doc/api/smach/html/python/smach.util.CBInterface-class.html|@smach.cb_interface]] decorator. ## AUTOGENERATED DO NOT DELETE ## TutorialCategory ## FILL IN THE STACK TUTORIAL CATEGORY HERE ## SMACHROSStatesCategory, SMACHStatesCategory