33import json
44import logging
55
6- from roslibpy .core import Message , MessageEncoder , ServiceResponse
6+ from roslibpy .core import (
7+ ActionFeedback ,
8+ ActionGoalStatus ,
9+ ActionResult ,
10+ Message ,
11+ MessageEncoder ,
12+ ServiceResponse ,
13+ )
714
815LOGGER = logging .getLogger ("roslibpy" )
916
@@ -22,19 +29,23 @@ def __init__(self, *args, **kwargs):
2229 super (RosBridgeProtocol , self ).__init__ (* args , ** kwargs )
2330 self .factory = None
2431 self ._pending_service_requests = {}
32+ self ._pending_action_requests = {}
2533 self ._message_handlers = {
2634 "publish" : self ._handle_publish ,
2735 "service_response" : self ._handle_service_response ,
2836 "call_service" : self ._handle_service_request ,
37+ "send_action_goal" : self ._handle_action_request , # TODO: action server
38+ "cancel_action_goal" : self ._handle_action_cancel , # TODO: action server
39+ "action_feedback" : self ._handle_action_feedback ,
40+ "action_result" : self ._handle_action_result ,
41+ "status" : None , # TODO: add handlers for op: status
2942 }
30- # TODO: add handlers for op: status
3143
3244 def on_message (self , payload ):
3345 message = Message (json .loads (payload .decode ("utf8" )))
3446 handler = self ._message_handlers .get (message ["op" ], None )
3547 if not handler :
3648 raise RosBridgeException ('No handler registered for operation "%s"' % message ["op" ])
37-
3849 handler (message )
3950
4051 def send_ros_message (self , message ):
@@ -106,3 +117,59 @@ def _handle_service_request(self, message):
106117 raise ValueError ("Expected service name missing in service request" )
107118
108119 self .factory .emit (message ["service" ], message )
120+
121+ def send_ros_action_goal (self , message , resultback , feedback , errback ):
122+ """Initiate a ROS action request by sending a goal through the ROS Bridge.
123+
124+ Args:
125+ message (:class:`.Message`): ROS Bridge Message containing the action request.
126+ callback: Callback invoked on receiving result.
127+ feedback: Callback invoked when receiving feedback from action server.
128+ errback: Callback invoked on error.
129+ """
130+ request_id = message ["id" ]
131+ self ._pending_action_requests [request_id ] = (resultback , feedback , errback )
132+
133+ json_message = json .dumps (dict (message ), cls = MessageEncoder ).encode ("utf8" )
134+ LOGGER .debug ("Sending ROS action goal request: %s" , json_message )
135+
136+ self .send_message (json_message )
137+
138+ def _handle_action_request (self , message ):
139+ if "action" not in message :
140+ raise ValueError ("Expected action name missing in action request" )
141+ raise RosBridgeException ('Action server capabilities not yet implemented' )
142+
143+ def _handle_action_cancel (self , message ):
144+ if "action" not in message :
145+ raise ValueError ("Expected action name missing in action request" )
146+ raise RosBridgeException ('Action server capabilities not yet implemented' )
147+
148+ def _handle_action_feedback (self , message ):
149+ if "action" not in message :
150+ raise ValueError ("Expected action name missing in action feedback" )
151+
152+ request_id = message ["id" ]
153+ _ , feedback , _ = self ._pending_action_requests .get (request_id , None )
154+ feedback (ActionFeedback (message ["values" ]))
155+
156+ def _handle_action_result (self , message ):
157+ request_id = message ["id" ]
158+ action_handlers = self ._pending_action_requests .get (request_id , None )
159+
160+ if not action_handlers :
161+ raise RosBridgeException ('No handler registered for action request ID: "%s"' % request_id )
162+
163+ resultback , _ , errback = action_handlers
164+ del self ._pending_action_requests [request_id ]
165+
166+ LOGGER .debug ("Received Action result with status: %s" , message ["status" ])
167+
168+ results = {"status" : ActionGoalStatus (message ["status" ]).name , "values" : message ["values" ]}
169+
170+ if "result" in message and message ["result" ] is False :
171+ if errback :
172+ errback (results )
173+ else :
174+ if resultback :
175+ resultback (ActionResult (results ))
0 commit comments