Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011 import roslib
00012 roslib.load_manifest('rocon_gateway')
00013 from gateway_msgs.msg import Rule, RemoteRule, ConnectionType
00014 import copy
00015 import re
00016
00017
00018 import utils
00019 import interactive_interface
00020
00021
00022
00023
00024
00025
00026 class FlippedInterface(interactive_interface.InteractiveInterface):
00027 '''
00028 The flipped interface is the set of rules
00029 (pubs/subs/services/actions) and rules controlling flips
00030 to other gateways.
00031 '''
00032 def __init__(self, firewall, default_rule_blacklist, default_rules, all_targets):
00033 '''
00034 Initialises the flipped interface.
00035
00036 @param firewall : flag to prevent this gateway from accepting flips
00037 @type Bool
00038 @param default_rule_blacklist : used when in flip all mode
00039 @type dictionary of gateway
00040 @param default_rules : static rules to flip on startup
00041 @type gateway_msgs.msg.RemoteRule[]
00042 @param all_targets : static flip all targets to flip to on startup
00043 @type string[]
00044
00045 '''
00046 interactive_interface.InteractiveInterface.__init__(self, default_rule_blacklist, default_rules, all_targets)
00047
00048 self.firewall = firewall
00049
00050
00051 self.flipped = self.active
00052 self.flip_all = self.add_all
00053 self.unflip_all = self.remove_all
00054
00055
00056
00057
00058
00059 def update(self, connections, gateways,unique_name):
00060 '''
00061 Computes a new flipped interface and returns two dictionaries -
00062 removed and newly added flips so the watcher thread can take
00063 appropriate action (inform the remote gateways).
00064
00065 This is run in the watcher thread (warning: take care - other
00066 additions come from ros service calls in different threads!)
00067
00068 @param connections : list of all the system state connections from the local master
00069 @type connection type keyed dictionary of utils.Connection lists.
00070
00071 @param gateways : gateways that are available (registered on the hub)
00072 @type string
00073
00074 @return new_flips, old_flips
00075 @rtype pair of connection type keyed dictionary of gateway_msgs.msg.Rule lists.
00076 '''
00077
00078
00079 flipped = utils.createEmptyConnectionTypeDictionary()
00080 new_flips = utils.createEmptyConnectionTypeDictionary()
00081 removed_flips = utils.createEmptyConnectionTypeDictionary()
00082 diff = lambda l1,l2: [x for x in l1 if x not in l2]
00083 self._lock.acquire()
00084
00085 for connection_type in utils.connection_types:
00086 self.flipped[connection_type] = [flip for flip in self.flipped[connection_type] if flip.gateway in gateways]
00087
00088 for connection_type in connections:
00089 for connection in connections[connection_type]:
00090 flipped[connection_type].extend(self._generate_flips(connection.rule.type, connection.rule.name, connection.rule.node, gateways,unique_name))
00091 new_flips[connection_type] = diff(flipped[connection_type],self.flipped[connection_type])
00092 removed_flips[connection_type] = diff(self.flipped[connection_type],flipped[connection_type])
00093 self.flipped = copy.deepcopy(flipped)
00094 self._lock.release()
00095 return new_flips, removed_flips
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120 def _generate_flips(self, type, name, node, gateways,unique_name):
00121 '''
00122 Checks if a local rule (obtained from master.getSystemState)
00123 is a suitable association with any of the rules or patterns. This can
00124 return multiple matches, since the same local rule
00125 properties can be multiply flipped to different remote gateways.
00126
00127 Used in the update() call above that is run in the watcher thread.
00128 Note, don't need to lock here as the update() function takes care of it.
00129
00130 @param type : rule type
00131 @type str : string constant from gateway_msgs.msg.Rule
00132
00133 @param name : fully qualified topic, service or action name
00134 @type str
00135
00136 @param node : ros node name (coming from master.getSystemState)
00137 @type str
00138
00139 @param gateways : gateways that are available (registered on the hub)
00140 @type string
00141
00142 @return all the flip rules that match this local rule
00143 @return list of RemoteRule objects updated with node names from self.watchlist
00144 '''
00145 matched_flip_rules = []
00146 for flip_rule in self.watchlist[type]:
00147
00148 matched_gateways = []
00149 for gateway in gateways:
00150 if re.match(flip_rule.gateway, gateway):
00151 matched_gateways.append(gateway)
00152 if not matched_gateways:
00153 continue
00154
00155
00156 rule_name = flip_rule.rule.name
00157 matched = self.is_matched(flip_rule,rule_name,name,node)
00158
00159 if not matched:
00160 rule_name = '/' + unique_name + '/' + flip_rule.rule.name
00161 matched = self.is_matched(flip_rule,rule_name,name,node)
00162
00163 if not matched:
00164 rule_name = '/' + flip_rule.rule.name
00165 matched = self.is_matched(flip_rule,rule_name,name,node)
00166
00167 if matched:
00168 for gateway in matched_gateways:
00169 matched_flip = copy.deepcopy(flip_rule)
00170 matched_flip.gateway = gateway
00171 matched_flip.rule.name = name
00172 matched_flip.rule.node = node
00173 matched_flip_rules.append(matched_flip)
00174 return matched_flip_rules
00175
00176
00177
00178
00179
00180 def get_flipped_connections(self):
00181 '''
00182 Gets the flipped connections list for GatewayInfo consumption.
00183
00184 @return the list of flip rules that are activated and have been flipped.
00185 @rtype RemoteRule[]
00186 '''
00187 flipped_connections = []
00188 for connection_type in utils.connection_types:
00189 flipped_connections.extend(copy.deepcopy(self.flipped[connection_type]))
00190 return flipped_connections
00191
00192
00193 if __name__ == "__main__":
00194
00195 gateways = ['dude','dudette']
00196 dudes = ['fred', 'dude']
00197 dudes[:] = [x for x in dudes if x in gateways]
00198 print dudes