turtle_pond.py
Go to the documentation of this file.
00001 #!/usr/bin/env python
00002 #
00003 # License: BSD
00004 #   https://raw.github.com/robotics-in-concert/concert_services/license/LICENSE
00005 #
00006 ##############################################################################
00007 # About
00008 ##############################################################################
00009 
00010 # Simple script to request a pre-configured number of strolling turtles.
00011 # This could also be done with link graphs, but chatter concert does that.
00012 
00013 ##############################################################################
00014 # Imports
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 # Classes
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',   # [uuid.UUID] list of request id's pending feedback from the scheduler
00044         'allocated_requests'  # [uuid.UUID] moved here from pending requests once granted
00045     ]
00046 
00047     def __init__(self):
00048         ####################
00049         # Discovery
00050         ####################
00051         (self.service_name, self.service_description, self.service_priority, self.service_id) = concert_service_utilities.get_service_info()
00052 
00053         ####################
00054         # Setup
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             #rospy.loginfo("Service : found scheduler [%s][%s]" % (topic_name))
00073         except rocon_python_comms.NotFoundException as e:
00074             rospy.logerr("TurtlePond : %s" % (str(e)))
00075             return  # raise an exception here?
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             # Need to add logic here for when the request gets released
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 # Launch point
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()


turtle_concert
Author(s): Daniel Stonier , Jihoon Lee
autogenerated on Fri Feb 12 2016 02:51:42