Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 import rospy
00018 import rocon_python_comms
00019 import concert_service_utilities
00020 import concert_scheduler_requests
00021 import unique_id
00022 import scheduler_msgs.msg as scheduler_msgs
00023 import concert_msgs.msg as concert_msgs
00024 import rocon_std_msgs.msg as rocon_std_msgs
00025 import rocon_uri
00026
00027
00028
00029
00030
00031
00032 class TurtlePond:
00033 '''
00034 Requets handling for getting its mittens on some turtle_stroll'ing
00035 turtles.
00036 '''
00037 __slots__ = [
00038 'service_name',
00039 'service_description',
00040 'service_priority',
00041 'service_id',
00042 'requester',
00043 'pending_requests',
00044 'allocated_requests'
00045 ]
00046
00047 def __init__(self):
00048
00049
00050
00051 (self.service_name, self.service_description, self.service_priority, self.service_id) = concert_service_utilities.get_service_info()
00052
00053
00054
00055
00056 self.requester = self.setup_requester(self.service_id)
00057 self.pending_requests = []
00058 self.allocated_requests = []
00059
00060 turtles = rospy.get_param("turtles", default=[{'x_vel':1.0,'z_vel':0.4,'square_scale':1.0}])
00061
00062 rospy.loginfo("TurtlePond : requesting %s turtles" % len(turtles))
00063 for turtle in turtles:
00064 x_vel = turtle['x_vel']
00065 z_vel = turtle['z_vel']
00066 scale = turtle['square_scale']
00067 self.request_turtle(x_vel, z_vel, scale)
00068
00069 def setup_requester(self, uuid):
00070 try:
00071 scheduler_requests_topic_name = concert_service_utilities.find_scheduler_requests_topic()
00072
00073 except rocon_python_comms.NotFoundException as e:
00074 rospy.logerr("TurtlePond : %s" % (str(e)))
00075 return
00076 frequency = concert_scheduler_requests.common.HEARTBEAT_HZ
00077 return concert_scheduler_requests.Requester(self.requester_feedback, uuid, 0, scheduler_requests_topic_name, frequency)
00078
00079 def request_turtle(self, x_vel=0.1, z_vel=0.1, scale=1.0):
00080 '''
00081 Request a turtle.
00082 '''
00083 resource = scheduler_msgs.Resource()
00084 resource.id = unique_id.toMsg(unique_id.fromRandom())
00085 resource.rapp = 'turtle_concert/turtle_stroll'
00086 resource.uri = 'rocon:/'
00087 resource_request_id = self.requester.new_request([resource], priority=self.service_priority)
00088 resource.parameters = [rocon_std_msgs.KeyValue('turtle_x_vel', str(x_vel)), rocon_std_msgs.KeyValue('turtle_z_vel', str(z_vel)), rocon_std_msgs.KeyValue('square_scale', str(scale))]
00089
00090 self.pending_requests.append(resource_request_id)
00091 self.requester.send_requests()
00092
00093
00094
00095 def requester_feedback(self, request_set):
00096 '''
00097 Keep an eye on our pending requests and see if they get allocated here.
00098 Once they do, kick them out of the pending requests list so _ros_capture_teleop_callback
00099 can process and reply to the interaction.
00100
00101 @param request_set : the modified requests
00102 @type dic { uuid.UUID : scheduler_msgs.ResourceRequest }
00103 '''
00104 cancelled_requests = 0
00105 for request_id, request in request_set.requests.iteritems():
00106 if request_id in self.pending_requests:
00107 if request.msg.status == scheduler_msgs.Request.GRANTED:
00108 self.pending_requests.remove(request_id)
00109 self.allocated_requests.append(request_id)
00110 elif request.msg.status == scheduler_msgs.Request.GRANTED:
00111 completely_unallocated = True
00112 for resource in request.msg.resources:
00113 if rocon_uri.parse(resource.uri).name.string != concert_msgs.Strings.SCHEDULER_UNALLOCATED_RESOURCE:
00114 completely_unallocated = False
00115 if completely_unallocated:
00116 cancelled_requests += 1
00117 request.cancel()
00118
00119 for unused_i in range(0, cancelled_requests):
00120 self.request_turtle()
00121
00122 def cancel_all_requests(self):
00123 '''
00124 Exactly as it says! Used typically when shutting down or when
00125 it's lost more allocated resources than the minimum required (in which case it
00126 cancels everything and starts reissuing new requests).
00127 '''
00128 self.requester.cancel_all()
00129 self.requester.send_requests()
00130
00131
00132
00133
00134
00135 if __name__ == '__main__':
00136
00137 rospy.init_node('turtle_pond')
00138
00139 turtle_pond = TurtlePond()
00140 rospy.spin()
00141 if not rospy.is_shutdown():
00142 turtle_pond.cancel_all_requests()