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,6 +32,8 @@ def main(args): | ||
32 | #### Distances #### | 32 | #### Distances #### |
33 | print ("\ndistances : " + str(testSample.distances)) | 33 | print ("\ndistances : " + str(testSample.distances)) |
34 | 34 | ||
35 | + KNeighbors(dz,) | ||
36 | + | ||
35 | #### Barycenter #### | 37 | #### Barycenter #### |
36 | a = resolve_barycenter(neighborsCells, testSample.distances) | 38 | a = resolve_barycenter(neighborsCells, testSample.distances) |
37 | print(a.toString()) | 39 | print(a.toString()) |
@@ -40,6 +42,7 @@ def main(args): | @@ -40,6 +42,7 @@ def main(args): | ||
40 | MM = MarkovModel(Tf) | 42 | MM = MarkovModel(Tf) |
41 | 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]) | 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 | MM.printValues() | 46 | MM.printValues() |
44 | print("\r\nPERCENTAGES : \r\n") | 47 | print("\r\nPERCENTAGES : \r\n") |
45 | MM.printPercentages() | 48 | MM.printPercentages() |
structure.py
@@ -4,6 +4,12 @@ from math import floor | @@ -4,6 +4,12 @@ from math import floor | ||
4 | class RSSVector(): | 4 | class RSSVector(): |
5 | distances = [] | 5 | distances = [] |
6 | def __init__(self, n1, n2, n3, n4): | 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 | self.n1 = n1 | 13 | self.n1 = n1 |
8 | self.n2 = n2 | 14 | self.n2 = n2 |
9 | self.n3 = n3 | 15 | self.n3 = n3 |
@@ -46,6 +52,10 @@ class Location(): | @@ -46,6 +52,10 @@ class Location(): | ||
46 | return "(" + str(self.x) + " ; " + str(self.y) + " ; " + str(self.z) + ")" | 52 | return "(" + str(self.x) + " ; " + str(self.y) + " ; " + str(self.z) + ")" |
47 | 53 | ||
48 | def getPositionInArray(self, arraySize=3): | 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 | temp = Location(self.x, self.y) | 59 | temp = Location(self.x, self.y) |
50 | temp /= 2 | 60 | temp /= 2 |
51 | temp -= Location(1,1) | 61 | temp -= Location(1,1) |
@@ -53,6 +63,11 @@ class Location(): | @@ -53,6 +63,11 @@ class Location(): | ||
53 | 63 | ||
54 | @staticmethod | 64 | @staticmethod |
55 | def fromID(id, arraySize=3): | 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 | id -= 1 | 71 | id -= 1 |
57 | y=id % 3 | 72 | y=id % 3 |
58 | x=floor((id - y) / 3) | 73 | x=floor((id - y) / 3) |
@@ -64,16 +79,27 @@ class Location(): | @@ -64,16 +79,27 @@ class Location(): | ||
64 | 79 | ||
65 | class Cell(): | 80 | class Cell(): |
66 | def __init__(self, v_, loc): | 81 | def __init__(self, v_, loc): |
82 | + ''' | ||
83 | + :param v_: RSSI vector of the fingerprint | ||
84 | + :param loc: Location of the fingerprint | ||
85 | + ''' | ||
67 | self.v = v_ | 86 | self.v = v_ |
68 | self.location = loc | 87 | self.location = loc |
69 | 88 | ||
70 | class MarkovValue(): | 89 | class MarkovValue(): |
71 | def __init__(self, nb=0, percentage=0.0): | 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 | self.nb = nb | 95 | self.nb = nb |
73 | self.percentage = percentage # Probability of Markov model (100% <=> 1.0) | 96 | self.percentage = percentage # Probability of Markov model (100% <=> 1.0) |
74 | 97 | ||
75 | class MarkovModel(): | 98 | class MarkovModel(): |
76 | def __init__(self,cells): | 99 | def __init__(self,cells): |
100 | + ''' | ||
101 | + :param cells: an array containing all the cells of the model | ||
102 | + ''' | ||
77 | self.MarkovValues = [] #table of the coefficients of the Markov Model | 103 | self.MarkovValues = [] #table of the coefficients of the Markov Model |
78 | self.cells = cells | 104 | self.cells = cells |
79 | self.previousCell = 0 | 105 | self.previousCell = 0 |
@@ -84,20 +110,36 @@ class MarkovModel(): | @@ -84,20 +110,36 @@ class MarkovModel(): | ||
84 | self.MarkovValues[10][0].nb = 1 #initial position sigma increment | 110 | self.MarkovValues[10][0].nb = 1 #initial position sigma increment |
85 | 111 | ||
86 | def moveToCellID(self, nextCell): | 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 | self.MarkovValues[nextCell][self.previousCell].nb += 1 | 117 | self.MarkovValues[nextCell][self.previousCell].nb += 1 |
88 | self.MarkovValues[10][nextCell].nb += 1 | 118 | self.MarkovValues[10][nextCell].nb += 1 |
89 | self.refreshPercentage(self.previousCell) | 119 | self.refreshPercentage(self.previousCell) |
90 | self.previousCell = nextCell | 120 | self.previousCell = nextCell |
91 | 121 | ||
92 | def moveToCell(self, nextCell): | 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 | self.moveToCellID(nextCell.location.getPositionInArray()+1) | 127 | self.moveToCellID(nextCell.location.getPositionInArray()+1) |
94 | 128 | ||
95 | def refreshPercentage(self, col): | 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 | if self.MarkovValues[10][col].nb: | 135 | if self.MarkovValues[10][col].nb: |
97 | for k in range(0,10): | 136 | for k in range(0,10): |
98 | self.MarkovValues[k][col].percentage = self.MarkovValues[k][col].nb / self.MarkovValues[10][col].nb | 137 | self.MarkovValues[k][col].percentage = self.MarkovValues[k][col].nb / self.MarkovValues[10][col].nb |
99 | 138 | ||
100 | def printValues(self): | 139 | def printValues(self): |
140 | + ''' | ||
141 | + Prints the counters of the Markov Model in a human-readable table form | ||
142 | + ''' | ||
101 | print("\t? \t1 \t2 \t3\t4 \t5 \t6 \t7 \t8 \t9") | 143 | print("\t? \t1 \t2 \t3\t4 \t5 \t6 \t7 \t8 \t9") |
102 | print("---------------------------------------------------------------------------------", end='') | 144 | print("---------------------------------------------------------------------------------", end='') |
103 | 145 | ||
@@ -108,17 +150,23 @@ class MarkovModel(): | @@ -108,17 +150,23 @@ class MarkovModel(): | ||
108 | 150 | ||
109 | print(i, end='\t') | 151 | print(i, end='\t') |
110 | for k in range (0,10): | 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 | print(self.MarkovValues[i][k].nb, end='\t') | 157 | print(self.MarkovValues[i][k].nb, end='\t') |
158 | + print("\033[1;37;40m", end='') | ||
112 | print("") | 159 | print("") |
113 | 160 | ||
114 | def printPercentages(self): | 161 | def printPercentages(self): |
162 | + ''' | ||
163 | + Prints the percentages of the Markov Model in a human-readable table form | ||
164 | + ''' | ||
115 | print("\t? \t1 \t2 \t3\t4 \t5 \t6 \t7 \t8 \t9") | 165 | print("\t? \t1 \t2 \t3\t4 \t5 \t6 \t7 \t8 \t9") |
116 | print("---------------------------------------------------------------------------------", end='') | 166 | print("---------------------------------------------------------------------------------", end='') |
117 | 167 | ||
118 | for i in range (1, 10): | 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 | for k in range (0,10): | 170 | for k in range (0,10): |
123 | if not self.MarkovValues[i][k].percentage: | 171 | if not self.MarkovValues[i][k].percentage: |
124 | print("\033[0;31;40m", end='') | 172 | print("\033[0;31;40m", end='') |
@@ -129,9 +177,21 @@ class MarkovModel(): | @@ -129,9 +177,21 @@ class MarkovModel(): | ||
129 | print("") | 177 | print("") |
130 | 178 | ||
131 | def getMostLikely(self): | 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 | return self.getMostLikelyFromCell(self.previousCell) | 185 | return self.getMostLikelyFromCell(self.previousCell) |
133 | 186 | ||
134 | def getMostLikelyFromCell(self, currentCell): | 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 | max=0 | 195 | max=0 |
136 | max_id=0 | 196 | max_id=0 |
137 | for k in range(1,10): | 197 | for k in range(1,10): |
@@ -141,19 +201,33 @@ class MarkovModel(): | @@ -141,19 +201,33 @@ class MarkovModel(): | ||
141 | return max_id | 201 | return max_id |
142 | 202 | ||
143 | def path(self, locationIDs): | 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 | for loc in locationIDs: | 208 | for loc in locationIDs: |
145 | self.moveToCellID(loc) | 209 | self.moveToCellID(loc) |
146 | 210 | ||
147 | 211 | ||
148 | def newCell(n1, n2, n3, n4, l1, l2): | 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 | return Cell(RSSVector(n1,n2,n3,n4), Location(l1,l2)) | 223 | return Cell(RSSVector(n1,n2,n3,n4), Location(l1,l2)) |
150 | 224 | ||
151 | def KNeighbors(fingerprints, sample): | 225 | def KNeighbors(fingerprints, sample): |
152 | ''' | 226 | ''' |
153 | Returns the 4 closest cells to the given sample and fills sample distance data | 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 | distances, neighbours = [], [] | 232 | distances, neighbours = [], [] |
159 | for row in fingerprints: | 233 | for row in fingerprints: |
@@ -174,9 +248,9 @@ def KNeighbors(fingerprints, sample): | @@ -174,9 +248,9 @@ def KNeighbors(fingerprints, sample): | ||
174 | def resolve_barycenter(nC, d): | 248 | def resolve_barycenter(nC, d): |
175 | ''' | 249 | ''' |
176 | Returns the weighted barycenter of the 4 neighbouring cells | 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 | return None if len(nC) != 4 or len(d) != 4 else \ | 255 | return None if len(nC) != 4 or len(d) != 4 else \ |
182 | 1 / (1+d[0]/d[1]+d[0]/d[2]+d[0]/d[3])*nC[0].location \ | 256 | 1 / (1+d[0]/d[1]+d[0]/d[2]+d[0]/d[3])*nC[0].location \ |