Final Assignment  1.0
Research Track part 1 - Assignment 2 - RobEng A.A. 2020/2021
reach_random_pos_service.py
Go to the documentation of this file.
1 #! /usr/bin/env python
2 
3 
32 
33 
34 
35 import rospy
36 from final_assignment.srv import switch_service, switch_serviceRequest, switch_serviceResponse
37 from final_assignment.srv import check_position, check_positionRequest, check_positionResponse
38 from final_assignment.srv import get_point, get_pointRequest, get_pointResponse
39 from final_assignment.srv import reach_random_pos_status, reach_random_pos_statusRequest, reach_random_pos_statusResponse
40 from move_base_msgs.msg import MoveBaseActionGoal
41 from geometry_msgs.msg import Point
42 
43 
44 
45 # --------------------------------- DATA
46 
47 
48 node_name = "reach_random_pos_service"
49 
50 
51 
52 name_reach_random_pos_status = "/reach_random_pos_status"
53 
54 
55 
56 name_reach_random_pos_switch = "/reach_random_pos_switch"
57 
58 
59 
60 name_check_position = "/check_position"
61 
62 
63 
64 name_get_point = "/get_point"
65 
66 
67 
68 name_move_base = "/move_base/goal"
69 
70 
71 topic_move_base = None
72 
73 
74 
75 service_active = False
76 
77 
78 is_moving = False
79 
80 
81 signal_last_pos = False
82 
83 
84 
85 actual_position = Point( )
86 
87 
88 target_position = None
89 
90 
91 
92 last_response_check_pos = check_positionResponse( )
93 
94 
95 
96 min_distance_from_the_target = 0.5
97 
98 
99 cycle_time = rospy.Duration( 0, 500 )
100 
101 
102 
103 
104 # --------------------------------- FUNCTIONS
105 
106 
113  global is_moving, min_distance_from_the_target, target_position, last_response_check_pos, actual_position
114  global srv_check_position
115 
116  if is_moving:
117  # require an update
118  req = check_positionRequest( )
119 
120  req.check_only = False
121  req.tol = min_distance_from_the_target
122  req.target = target_position
123 
124  res = srv_check_position( req )
125 
126  # store the last message
127  last_response_check_pos = res
128 
129  # store the last position
130  actual_position = res.actual_position
131 
132 
133 
134 
141  global is_moving, signal_last_pos, target_position
142 
143  is_moving = False
144  signal_last_pos = False
145  target_position = None
146 
147  pass
148 
149 
150 
151 
155  global name_get_point, srv_get_point
156  global name_move_base, srv_move_base
157  global target_position
158 
159  # ge the new target
160  target_position = ( srv_get_point( ) ).position
161 
162  # send it to move_base
163  msg = MoveBaseActionGoal( )
164  msg.goal.target_pose.header.frame_id = 'map'
165  msg.goal.target_pose.pose.position.x = target_position.x
166  msg.goal.target_pose.pose.position.y = target_position.y
167  msg.goal.target_pose.pose.orientation.w = 1.0
168 
169  topic_move_base.publish(msg)
170 
171 
172 
173 # --------------------------------- SERVICES
174 
175 
176 srv_check_position = None
177 
178 
179 srv_get_point = None
180 
181 
182 
197  global service_active, signal_last_pos, is_moving
198 
199  response = switch_serviceResponse()
200 
201  if data.val:
202  # i want to turn on the service
203  if service_active:
204  # turn off any last pos signals
205  signal_last_pos = False
206  else:
207  # activate the service
208  service_active = True
209 
210  # in any case, return this:
211  response.success = True
212  response.in_progress = False
213 
214  else:
215  # i want to turn off the service
216  if service_active:
217  if is_moving:
218  # signal last pos
219  signal_last_pos = True
220 
221  # request in progress
222  response.in_progress = True
223  response.success = False
224  else:
225  # clear the status and turn off
226  # already done from the while cycle
227  response.success = True
228  response.in_progress = False
229  else:
230  # you're trying to turn off an already turned off service
231  # the server was turned off
232  response.success = True
233  response.in_progress = False
234 
235  return response
236 
237 
238 
239 
241  global service_active, actual_position, target_position, last_response_check_pos, signal_last_pos
242 
243  msg = reach_random_pos_statusResponse( )
244 
245  msg.is_active = service_active
246 
247  if target_position is not None:
248  msg.target = target_position
249  else:
250  msg.target = Point()
251 
252  msg.distance = last_response_check_pos.distance
253  msg.actual_position = actual_position
254  msg.last_pos_signal = signal_last_pos
255 
256  return msg
257 
258 
259 
260 # --------------------------------- WORKING CYCLE
261 
262 
273 def main():
274  global service_active, cycle_time, target_position, is_moving
275  global name_get_point, srv_get_point
276  global last_response_check_pos, signal_last_pos
277 
278 
279  while not rospy.is_shutdown( ):
280 
281  # update the current position
283 
284  if not service_active:
285  # do nothing
286  rospy.sleep( cycle_time )
287  continue
288 
289  if not is_moving:
290  if signal_last_pos:
291  # last pos signal received
292  # target reached
293  # clear the node and deactivate it
294  clear_status( )
295 
296  service_active = False
297  else:
298  # need for a new target
300 
301  # the robot starts to move
302  is_moving = True
303 
304  else:
305  # check the progress towards the target
306  if last_response_check_pos.reached:
307  # stop the movement
308  is_moving = False
309  else:
310  # do nothing
311  pass
312 
313  rospy.sleep( cycle_time )
314 
315 
316 
317 # --------------------------------- NODE
318 
319 
321  rospy.loginfo( " [%s] is OFFLINE", node_name )
322 
323 
324 
325 
326 if __name__ == "__main__":
327  rospy.init_node( node_name )
328  rospy.on_shutdown( cbk_on_shutdown )
329 
330  # require the server 'reach_random_pos_status'
331  rospy.loginfo( " [%s] advertising service %s ...", node_name, name_reach_random_pos_status )
332  rospy.Service( name_reach_random_pos_status, reach_random_pos_status, srv_reach_random_pos_status )
333  rospy.loginfo( " [%s] service %s ... OK", node_name, name_reach_random_pos_status )
334 
335  # service 'check_position'
336  rospy.loginfo( " [%s] getting service %s ...", node_name, name_check_position )
337  rospy.wait_for_service( name_check_position )
338  srv_check_position = rospy.ServiceProxy( name_check_position, check_position )
339  rospy.loginfo( " [%s] service %s ... OK", node_name, name_check_position )
340 
341  # service 'get_point'
342  rospy.loginfo( " [%s] getting service %s ...", node_name, name_get_point )
343  rospy.wait_for_service( name_get_point )
344  srv_get_point = rospy.ServiceProxy( name_get_point, get_point )
345  rospy.loginfo( " [%s] service %s ... OK", node_name, name_get_point )
346 
347  # require the topic 'move_base/goal'
348  rospy.loginfo( " [%s] topic (out) %s ...", node_name, name_move_base )
349  topic_move_base = rospy.Publisher( name_move_base, MoveBaseActionGoal, queue_size=1 )
350  rospy.loginfo( " [%s] topic (out) %s ... OK", node_name, name_move_base )
351 
352  # service 'reach_random_pos_switch'
353  rospy.loginfo( " [%s] getting service %s ...", node_name, name_reach_random_pos_switch )
354  rospy.Service( name_reach_random_pos_switch, switch_service, srv_reach_random_pos_switch )
355  rospy.loginfo( " [%s] service %s ... OK", node_name, name_reach_random_pos_switch )
356 
357  try:
358  rospy.loginfo( " [%s] is ONLINE", node_name )
359  main()
360  except rospy.ROSException:
361  rospy.loginfo( " [%s] Raised an Exception ... ", node_name )
def cbk_on_shutdown()
This is called on the shutdown of the node.
def srv_reach_random_pos_status(data)
return the status of the service.
def clear_status()
clear the status of the node.
def main()
The algorithm of the node.
srv_get_point
call-point of the service 'get_point'
def update_current_position()
Update the informations about the position from check_position service.
def new_target_to_move_base()
ask a new randomly-choosen target to the server points_manager, then send to MoveBase the target to r...
def srv_reach_random_pos_switch(data)
Turn on and off the service.
srv_check_position
call-point of the service 'check_position'