Package rocon_gateway :: Module pulled_interface
[frames] | no frames]

Source Code for Module rocon_gateway.pulled_interface

  1  #!/usr/bin/env python 
  2  # 
  3  # License: BSD 
  4  #   https://raw.github.com/robotics-in-concert/rocon_multimaster/hydro-devel/rocon_gateway/LICENSE 
  5  # 
  6   
  7  ############################################################################## 
  8  # Imports 
  9  ############################################################################## 
 10   
 11  import copy 
 12  import re 
 13  import rocon_utilities 
 14  # Local imports 
 15  import utils 
 16  import interactive_interface 
 17   
 18  ############################################################################## 
 19  # Pulled Interface 
 20  ############################################################################## 
 21   
 22   
23 -class PulledInterface(interactive_interface.InteractiveInterface):
24 ''' 25 The pulled interface is the set of rules 26 (pubs/subs/services/actions) and rules controlling pulls from 27 other gateways. 28 '''
29 - def __init__(self, default_rule_blacklist, default_rules, all_targets):
30 ''' 31 Initialises the pulled interface. 32 33 @param default_rule_blacklist : used when in flip all mode 34 @type dictionary of gateway 35 @param default_rules : static rules to pull on startup 36 @type gateway_msgs.msg.RemoteRule[] 37 @param all_targets : static pull all targets to pull to on startup 38 @type string[] 39 ''' 40 interactive_interface.InteractiveInterface.__init__(self, default_rule_blacklist, default_rules, all_targets) 41 42 # Function aliases 43 self.pulled = self.active 44 self.pull_all = self.add_all 45 self.unpull_all = self.remove_all
46
47 - def update(self, remote_connections, unique_name):
48 ''' 49 Computes a new pulled interface from the incoming connections list 50 and returns two dictionaries - 51 removed and newly added pulls so the watcher thread can take 52 appropriate action ((un)registrations). 53 54 This is run in the watcher thread (warning: take care - other 55 additions come from ros service calls in different threads!) 56 57 @param remote_gateway_hub_index : full gateway-hub database index to parse 58 @type gateway hash names keyed into a dic with a list of their hubs 59 ''' 60 # SLOW, EASY METHOD 61 # Totally regenerate a new pulled interface, compare with old 62 pulled = utils.create_empty_connection_type_dictionary() 63 new_pulls = utils.create_empty_connection_type_dictionary() 64 removed_pulls = utils.create_empty_connection_type_dictionary() 65 diff = lambda l1,l2: [x for x in l1 if x not in l2] # diff of lists 66 self._lock.acquire() 67 # Totally regenerate a new pulled interface, compare with old 68 for remote_gateway in remote_connections.keys(): 69 connections = remote_connections[remote_gateway] 70 for connection_type in connections: 71 for connection in connections[connection_type]: 72 pulled[connection_type].extend(self._generate_pulls(connection.rule.type, connection.rule.name, connection.rule.node, remote_gateway, unique_name)) 73 for connection_type in utils.connection_types: 74 new_pulls[connection_type] = diff(pulled[connection_type], self.pulled[connection_type]) 75 removed_pulls[connection_type] = diff(self.pulled[connection_type], pulled[connection_type]) 76 self.pulled = copy.deepcopy(pulled) 77 self._lock.release() 78 return new_pulls, removed_pulls
79 80 # OPTIMISED METHOD 81 # Keep old rule state and old flip rules/patterns around 82 # 83 # 1 - If flip rules/patterns disappeared [diff(old_rules,new_rules)] 84 # Check if the current flips are still valid 85 # If not all are, remove and unflip them 86 # 87 # 2 - If rules disappeared [diff(old_conns,new_conns)] 88 # If matching any in pulled, remove and unflip 89 # 90 # 3 - If flip rules/patterns appeared [diff(new_rules,old_rules)] 91 # parse all conns, if match found, flip 92 # 93 # 4 - If rules appeared [diff(new_conns,old_conns)] 94 # check for matches, if found, flou 95 # 96 # diff = lambda l1,l2: [x for x in l1 if x not in l2] # diff of lists 97 98 ########################################################################## 99 # Utility Methods 100 ########################################################################## 101
102 - def _generate_pulls(self, connection_type, name, node, gateway, unique_name):
103 ''' 104 Checks if a local rule (obtained from master.get_system_state) 105 is a suitable association with any of the rules or patterns. This can 106 return multiple matches, since the same local rule 107 properties can be multiply pulled to different remote gateways. 108 109 Used in the update() call above that is run in the watcher thread. 110 111 Note, don't need to lock here as the update() function takes care of it. 112 113 @param connection_type : rule type 114 @type str : string constant from gateway_msgs.Rule 115 116 @param name : fully qualified topic, service or action name 117 @type str 118 119 @param node : ros node name (coming from master.get_system_state) 120 @type str 121 122 @param gateway : remote gateway hash name. 123 @type str 124 125 @return all the pull rules that match this local rule 126 @return list of RemoteRule objects updated with node names from self.watchlist 127 ''' 128 matched_pull_rules = [] 129 for rule in self.watchlist[connection_type]: 130 # check for regular expression or perfect match 131 gateway_match_result = re.match(rule.gateway, gateway) 132 matched = False 133 if gateway_match_result and gateway_match_result.group() == gateway: 134 matched = True 135 elif rule.gateway == rocon_utilities.gateway_basename(gateway): 136 matched = True 137 if not matched: 138 continue 139 140 # Check names 141 rule_name = rule.rule.name 142 matched = self.is_matched(rule, rule_name, name, node) 143 if not matched: 144 rule_name = '/' + unique_name + '/' + rule.rule.name 145 matched = self.is_matched(rule, rule_name, name, node) 146 147 if not matched: 148 rule_name = '/' + rule.rule.name 149 matched = self.is_matched(rule, rule_name, name, node) 150 151 if matched: 152 matched_pull = copy.deepcopy(rule) 153 matched_pull.gateway = gateway # just in case we used a regex or matched basename 154 matched_pull.rule.name = name # just in case we used a regex 155 matched_pull.rule.node = node # just in case we used a regex 156 matched_pull_rules.append(matched_pull) 157 return matched_pull_rules
158 159 ########################################################################## 160 # Pulled Interface Specific Methods 161 ########################################################################## 162
164 ''' 165 Collects all gateways that it should watch for (i.e. those 166 currently handled by existing registrations). 167 168 @return set of gateway string ids 169 @rtype set of string 170 ''' 171 gateways = [] 172 for connection_type in utils.connection_types: 173 for registration in self.registrations[connection_type]: 174 if registration.remote_gateway not in gateways: 175 gateways.append(registration.remote_gateway) 176 return gateways
177