3 Use this class to perform indoor positioning with the metraTec IPS system. The position of a receiver is evaluated by 4 the received messages of RF beacons placed in the environment. Requires a YAML file with the configuration of zones. 7 Initialize the class by passing the directory of the config file. Then collect any number of beacon pings and use the 8 get_zone() function to return the current zone. Passing a list of pings instead of a single ping leads to averaging 9 over all the passed messages. 13 from beacon
import Beacon
18 """Use the metraTec IPS system to perform positioning of a receiver depending on placement of RF beacons.""" 21 Initialize class object by passing the directory to a YAML config file containing zone information. 22 :param config_dir: String: directory of the YAML config file containing the definitions of zones 32 Return a list of EIDs of all beacons that are configured in the config file 33 :return: [String]: EIDs of all beacons that are defined 45 Return beacon object with the specified EID. 46 :param eid: String: EID of the beacon object that should be fetched from the initialized zones 47 :return: Beacon/None: beacon object with the specified EID 59 Read the YAML config files of zones, parse the data and create zone/beacon objects. The created zone objects 60 are appended to the classes list of zones for later use. 61 :param yml_dir: String: directory of the YAML config file containing the definitions of zones 64 with open(yml_dir,
'r') as stream: 65 yml = yaml.load(stream) 68 for i
in range(len(yml)):
74 for j
in range(0, len(zone[
'polygon']), 3):
75 poly.append([zone[
'polygon'][j], zone[
'polygon'][j+1], zone[
'polygon'][j+2]])
78 for k
in range(len(zone)-4):
81 beacons.append(Beacon(beacon[
'EID'], beacon[
'position'], zone[
'frame_id']))
85 self.zones.append(Zone(zone[
'name'], zone[
'frame_id'], zone[
'threshold'], poly, beacons))
89 Take average RSSI value for each beacon ping contained in the passed list of beacon pings. Then return the 90 zone which the beacon with the highest value belongs to. 91 :param pings: List of Strings: beacon pings collected over time to average [BCN <EID> <RSSI>, ...] 92 :return: Zone/None: zone object of beacons with highest signal strength 98 for key, value
in sorted(means.items(), key=
lambda (k, v): v, reverse=
True):
102 if value < z.threshold:
106 print(
'Current zone: {}. RSSI: {}'.format(z.name, value))
109 print(
'None of the received beacon pings match a beacon from the configuration file. Returning \'None\'')
115 Compute the mean of RSSI values of a list of collected beacon pings. 116 Sort the passed list of pings by their unique EID and allocate their measured RSSI values. Then compute and 117 return the mean RSSI value of all received messages for each individual beacon. 118 :param pings: List of Strings: beacon pings collected over time to average [BCN <EID> <RSSI>, ...] 119 :return: Dict: key-value-pairs of EID and computed mean of RSSI values {<EID>: <AVERAGE_RSSI>, ...} 122 ordered_values = dict()
131 if len(split) != 3
or split[0] !=
'BCN' or len(split[1]) != 16
or len(split[2]) != 4:
132 print(
'Encountered invalid beacon ping: {}'.format(p))
135 if split[1]
in ordered_values:
136 ordered_values[split[1]].append(int(split[2]))
139 ordered_values[split[1]] = [int(split[2])]
141 for o
in ordered_values:
142 ordered_values[o] = sum(ordered_values[o]) / len(ordered_values[o])
144 return ordered_values
147 if __name__ ==
'__main__':
148 """Testing the class and its methods.""" 150 pos =
Positioning(
'/home/metratec/catkin_ws/src/indoor_positioning/config/zones.yml')
152 dummy_pings = [
'BCN 0123456789ABCDEF -060',
'BCN 0123456789ABCDEF -070',
'BCN 0123456789ABCDFF -070',
153 'BCN 0123456789ABCDFF -090',
'BCN 0123456789ABCFFF -070',
'BCN 0123456789ABCFFF -050',
154 'BCN 0123456789ABFFFF -070',
'BCN 0123456789ABFFFF -060',
'BCN 0123456789ABFFFF -090']
157 zone = pos.get_zone(dummy_pings)
def get_beacon(self, eid)
def get_zone(self, pings)
def parse_config(self, yml_dir)
def __init__(self, config_dir)
def get_defined_beacons(self)