3
3
import json
4
4
import logging
5
5
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
+ )
7
14
8
15
LOGGER = logging .getLogger ("roslibpy" )
9
16
@@ -22,19 +29,23 @@ def __init__(self, *args, **kwargs):
22
29
super (RosBridgeProtocol , self ).__init__ (* args , ** kwargs )
23
30
self .factory = None
24
31
self ._pending_service_requests = {}
32
+ self ._pending_action_requests = {}
25
33
self ._message_handlers = {
26
34
"publish" : self ._handle_publish ,
27
35
"service_response" : self ._handle_service_response ,
28
36
"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
29
42
}
30
- # TODO: add handlers for op: status
31
43
32
44
def on_message (self , payload ):
33
45
message = Message (json .loads (payload .decode ("utf8" )))
34
46
handler = self ._message_handlers .get (message ["op" ], None )
35
47
if not handler :
36
48
raise RosBridgeException ('No handler registered for operation "%s"' % message ["op" ])
37
-
38
49
handler (message )
39
50
40
51
def send_ros_message (self , message ):
@@ -106,3 +117,59 @@ def _handle_service_request(self, message):
106
117
raise ValueError ("Expected service name missing in service request" )
107
118
108
119
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