Commit b9bbfd280caff432b97470ceee43a6c03aa34b6b
1 parent
67724b67
Add Documentation
Showing
2 changed files
with
86 additions
and
9 deletions
Show diff stats
main.py
... | ... | @@ -32,6 +32,8 @@ def main(args): |
32 | 32 | #### Distances #### |
33 | 33 | print ("\ndistances : " + str(testSample.distances)) |
34 | 34 | |
35 | + KNeighbors(dz,) | |
36 | + | |
35 | 37 | #### Barycenter #### |
36 | 38 | a = resolve_barycenter(neighborsCells, testSample.distances) |
37 | 39 | print(a.toString()) |
... | ... | @@ -40,6 +42,7 @@ def main(args): |
40 | 42 | MM = MarkovModel(Tf) |
41 | 43 | MM.path([8,7,8,7,8,7,8,5,8,2,9,8,1,9,8,9,5,4,3,2,3,2,4,5,4,5,6,6,7,6,9,5,9,3,2,4,3,5,3,4,3,3,5,6,7,6,7,6,5,4,3,4,3,4]) |
42 | 44 | |
45 | + print("\r\n") | |
43 | 46 | MM.printValues() |
44 | 47 | print("\r\nPERCENTAGES : \r\n") |
45 | 48 | MM.printPercentages() | ... | ... |
structure.py
... | ... | @@ -4,6 +4,12 @@ from math import floor |
4 | 4 | class RSSVector(): |
5 | 5 | distances = [] |
6 | 6 | def __init__(self, n1, n2, n3, n4): |
7 | + ''' | |
8 | + :param n1: AP1 RSSI | |
9 | + :param n2: AP2 RSSI | |
10 | + :param n3: AP3 RSSI | |
11 | + :param n4: AP4 RSSI | |
12 | + ''' | |
7 | 13 | self.n1 = n1 |
8 | 14 | self.n2 = n2 |
9 | 15 | self.n3 = n3 |
... | ... | @@ -46,6 +52,10 @@ class Location(): |
46 | 52 | return "(" + str(self.x) + " ; " + str(self.y) + " ; " + str(self.z) + ")" |
47 | 53 | |
48 | 54 | def getPositionInArray(self, arraySize=3): |
55 | + ''' | |
56 | + Returns the unique ID of a fingerprint given its location | |
57 | + :param arraySize: (Optional) dimension of the array | |
58 | + ''' | |
49 | 59 | temp = Location(self.x, self.y) |
50 | 60 | temp /= 2 |
51 | 61 | temp -= Location(1,1) |
... | ... | @@ -53,6 +63,11 @@ class Location(): |
53 | 63 | |
54 | 64 | @staticmethod |
55 | 65 | def fromID(id, arraySize=3): |
66 | + ''' | |
67 | + Returns the Location of a fingerprint of known ID | |
68 | + :param: ID to resolve | |
69 | + :param arraySize: (Optional) dimension of the array | |
70 | + ''' | |
56 | 71 | id -= 1 |
57 | 72 | y=id % 3 |
58 | 73 | x=floor((id - y) / 3) |
... | ... | @@ -64,16 +79,27 @@ class Location(): |
64 | 79 | |
65 | 80 | class Cell(): |
66 | 81 | def __init__(self, v_, loc): |
82 | + ''' | |
83 | + :param v_: RSSI vector of the fingerprint | |
84 | + :param loc: Location of the fingerprint | |
85 | + ''' | |
67 | 86 | self.v = v_ |
68 | 87 | self.location = loc |
69 | 88 | |
70 | 89 | class MarkovValue(): |
71 | 90 | def __init__(self, nb=0, percentage=0.0): |
91 | + ''' | |
92 | + :param nb: Counter of incoming/outgoing movements | |
93 | + :param percentage: probability of being the next movement [0.0 , 1.0] | |
94 | + ''' | |
72 | 95 | self.nb = nb |
73 | 96 | self.percentage = percentage # Probability of Markov model (100% <=> 1.0) |
74 | 97 | |
75 | 98 | class MarkovModel(): |
76 | 99 | def __init__(self,cells): |
100 | + ''' | |
101 | + :param cells: an array containing all the cells of the model | |
102 | + ''' | |
77 | 103 | self.MarkovValues = [] #table of the coefficients of the Markov Model |
78 | 104 | self.cells = cells |
79 | 105 | self.previousCell = 0 |
... | ... | @@ -84,20 +110,36 @@ class MarkovModel(): |
84 | 110 | self.MarkovValues[10][0].nb = 1 #initial position sigma increment |
85 | 111 | |
86 | 112 | def moveToCellID(self, nextCell): |
113 | + ''' | |
114 | + Registers a movement from the current cell to a specified location by its ID | |
115 | + :param nextCell: The ID of the new location | |
116 | + ''' | |
87 | 117 | self.MarkovValues[nextCell][self.previousCell].nb += 1 |
88 | 118 | self.MarkovValues[10][nextCell].nb += 1 |
89 | 119 | self.refreshPercentage(self.previousCell) |
90 | 120 | self.previousCell = nextCell |
91 | 121 | |
92 | 122 | def moveToCell(self, nextCell): |
123 | + ''' | |
124 | + Registers a movement from the current cell to another based on the Location of its fingerprint | |
125 | + :param nextCell: The location of the new cell | |
126 | + ''' | |
93 | 127 | self.moveToCellID(nextCell.location.getPositionInArray()+1) |
94 | 128 | |
95 | 129 | def refreshPercentage(self, col): |
130 | + ''' | |
131 | + Refreshes the probabilities of a column after a counter is changed | |
132 | + Needed after every change to the nb field | |
133 | + :param col: the # of the column to refresh | |
134 | + ''' | |
96 | 135 | if self.MarkovValues[10][col].nb: |
97 | 136 | for k in range(0,10): |
98 | 137 | self.MarkovValues[k][col].percentage = self.MarkovValues[k][col].nb / self.MarkovValues[10][col].nb |
99 | 138 | |
100 | 139 | def printValues(self): |
140 | + ''' | |
141 | + Prints the counters of the Markov Model in a human-readable table form | |
142 | + ''' | |
101 | 143 | print("\t? \t1 \t2 \t3\t4 \t5 \t6 \t7 \t8 \t9") |
102 | 144 | print("---------------------------------------------------------------------------------", end='') |
103 | 145 | |
... | ... | @@ -108,17 +150,23 @@ class MarkovModel(): |
108 | 150 | |
109 | 151 | print(i, end='\t') |
110 | 152 | for k in range (0,10): |
153 | + if not self.MarkovValues[i][k].nb: | |
154 | + print("\033[0;31;40m", end='') | |
155 | + else: | |
156 | + print("\033[1;36;40m", end='') | |
111 | 157 | print(self.MarkovValues[i][k].nb, end='\t') |
158 | + print("\033[1;37;40m", end='') | |
112 | 159 | print("") |
113 | 160 | |
114 | 161 | def printPercentages(self): |
162 | + ''' | |
163 | + Prints the percentages of the Markov Model in a human-readable table form | |
164 | + ''' | |
115 | 165 | print("\t? \t1 \t2 \t3\t4 \t5 \t6 \t7 \t8 \t9") |
116 | 166 | print("---------------------------------------------------------------------------------", end='') |
117 | 167 | |
118 | 168 | for i in range (1, 10): |
119 | - print("\r\n", end='') | |
120 | - | |
121 | - print(i, end='\t') | |
169 | + print("\r\n", i, end='\t') | |
122 | 170 | for k in range (0,10): |
123 | 171 | if not self.MarkovValues[i][k].percentage: |
124 | 172 | print("\033[0;31;40m", end='') |
... | ... | @@ -129,9 +177,21 @@ class MarkovModel(): |
129 | 177 | print("") |
130 | 178 | |
131 | 179 | def getMostLikely(self): |
180 | + ''' | |
181 | + Returns the ID of the most likely next location | |
182 | + Convert to coordinates using the Location.fromID() function | |
183 | + :return: ID of the most likely next location | |
184 | + ''' | |
132 | 185 | return self.getMostLikelyFromCell(self.previousCell) |
133 | 186 | |
134 | 187 | def getMostLikelyFromCell(self, currentCell): |
188 | + ''' | |
189 | + Returns the ID of the most likely next location with a given previous cell ID | |
190 | + Typically called by getMostLikely() function | |
191 | + Convert to coordinates using the Location.fromID() function | |
192 | + :param currentCell: ID of the last cell | |
193 | + :return: ID of the most likely next location | |
194 | + ''' | |
135 | 195 | max=0 |
136 | 196 | max_id=0 |
137 | 197 | for k in range(1,10): |
... | ... | @@ -141,19 +201,33 @@ class MarkovModel(): |
141 | 201 | return max_id |
142 | 202 | |
143 | 203 | def path(self, locationIDs): |
204 | + ''' | |
205 | + shorthand for defining multiple movements betweens cells | |
206 | + :param LocationIDs: Array containing the different cell IDs in order of movement | |
207 | + ''' | |
144 | 208 | for loc in locationIDs: |
145 | 209 | self.moveToCellID(loc) |
146 | 210 | |
147 | 211 | |
148 | 212 | def newCell(n1, n2, n3, n4, l1, l2): |
213 | + ''' | |
214 | + Shorthand for Cell creation | |
215 | + :param n1: AP1 RSSI | |
216 | + :param n2: AP2 RSSI | |
217 | + :param n3: AP3 RSSI | |
218 | + :param n4: AP4 RSSI | |
219 | + :param L1: x coordinate of the fingerprinting location | |
220 | + :param L2: y coordinate of the fingerprinting location | |
221 | + :return: Cell with given characteristics | |
222 | + ''' | |
149 | 223 | return Cell(RSSVector(n1,n2,n3,n4), Location(l1,l2)) |
150 | 224 | |
151 | 225 | def KNeighbors(fingerprints, sample): |
152 | 226 | ''' |
153 | 227 | Returns the 4 closest cells to the given sample and fills sample distance data |
154 | - :param Cell[3][3] fingerprints: 2D array of all the cells | |
155 | - :param RSSVector sample: Mobile terminal sample | |
156 | - :return Cell[4]: the 4 nearest cells | |
228 | + :param fingerprints: 2D array of all the cells | |
229 | + :param sample: Mobile terminal sample | |
230 | + :return: the 4 nearest cells | |
157 | 231 | ''' |
158 | 232 | distances, neighbours = [], [] |
159 | 233 | for row in fingerprints: |
... | ... | @@ -174,9 +248,9 @@ def KNeighbors(fingerprints, sample): |
174 | 248 | def resolve_barycenter(nC, d): |
175 | 249 | ''' |
176 | 250 | Returns the weighted barycenter of the 4 neighbouring cells |
177 | - :param Cell[4] nC: (neighborCells) Array containing the 4 closest cells | |
178 | - :param distance[4] d: distances of the sample of the mobile terminal | |
179 | - :return Location: Estimated location of the mobile terminal (return None if error) | |
251 | + :param nC: (neighborCells) Array containing the 4 closest cells | |
252 | + :param d: distances of the sample of the mobile terminal | |
253 | + :return: Estimated location of the mobile terminal (return None if error) | |
180 | 254 | ''' |
181 | 255 | return None if len(nC) != 4 or len(d) != 4 else \ |
182 | 256 | 1 / (1+d[0]/d[1]+d[0]/d[2]+d[0]/d[3])*nC[0].location \ | ... | ... |