Mercurial Hosting > traffic-intelligence
comparison python/events.py @ 614:5e09583275a4
Merged Nicolas/trafficintelligence into default
author | Mohamed Gomaa <eng.m.gom3a@gmail.com> |
---|---|
date | Fri, 05 Dec 2014 12:13:53 -0500 |
parents | 07b1bd0785cd |
children | 84690dfe5560 |
comparison
equal
deleted
inserted
replaced
598:11f96bd08552 | 614:5e09583275a4 |
---|---|
6 from numpy import arccos | 6 from numpy import arccos |
7 | 7 |
8 import multiprocessing | 8 import multiprocessing |
9 import itertools | 9 import itertools |
10 | 10 |
11 import moving | 11 import moving, prediction, indicators, utils |
12 import prediction | |
13 import indicators | |
14 | 12 |
15 __metaclass__ = type | 13 __metaclass__ = type |
16 | 14 |
17 class Interaction(moving.STObject): | 15 class Interaction(moving.STObject): |
18 '''Class for an interaction between two road users | 16 '''Class for an interaction between two road users |
20 | 18 |
21 link to the moving objects | 19 link to the moving objects |
22 contains the indicators in a dictionary with the names as keys | 20 contains the indicators in a dictionary with the names as keys |
23 ''' | 21 ''' |
24 | 22 |
25 categories = {'headon': 0, | 23 categories = {'Head On': 0, |
26 'rearend': 1, | 24 'rearend': 1, |
27 'side': 2, | 25 'side': 2, |
28 'parallel': 3} | 26 'parallel': 3} |
29 | 27 |
30 def __init__(self, num = None, timeInterval = None, roaduserNum1 = None, roaduserNum2 = None, movingObject1 = None, movingObject2 = None, categoryNum = None): | 28 indicatorNames = ['Collision Course Dot Product', |
29 'Collision Course Angle', | |
30 'Distance', | |
31 'Minimum Distance', | |
32 'Velocity Angle', | |
33 'Speed Differential', | |
34 'Collision Probability', | |
35 'Time to Collision', | |
36 'Probability of Successful Evasive Action', | |
37 'predicted Post Encroachment Time'] | |
38 | |
39 indicatorNameToIndices = utils.inverseEnumeration(indicatorNames) | |
40 | |
41 indicatorShortNames = ['CCDP', | |
42 'CCA', | |
43 'Dist', | |
44 'MinDist', | |
45 'VA', | |
46 'SD', | |
47 'PoC', | |
48 'TTC', | |
49 'P(SEA)', | |
50 'pPET'] | |
51 | |
52 indicatorUnits = ['', | |
53 'rad', | |
54 'm', | |
55 'm', | |
56 'rad', | |
57 'm/s', | |
58 '', | |
59 's', | |
60 '', | |
61 ''] | |
62 | |
63 def __init__(self, num = None, timeInterval = None, roaduserNum1 = None, roaduserNum2 = None, roadUser1 = None, roadUser2 = None, categoryNum = None): | |
31 moving.STObject.__init__(self, num, timeInterval) | 64 moving.STObject.__init__(self, num, timeInterval) |
32 self.roaduserNumbers = set([roaduserNum1, roaduserNum2]) | 65 if timeInterval == None and roadUser1 != None and roadUser2 != None: |
33 self.movingObject1 = movingObject1 | 66 self.timeInterval = roadUser1.commonTimeInterval(roadUser2) |
34 self.movingObject2 = movingObject2 | 67 self.roadUser1 = roadUser1 |
68 self.roadUser2 = roadUser2 | |
69 if roaduserNum1 != None and roaduserNum2 != None: | |
70 self.roadUserNumbers = set([roaduserNum1, roaduserNum2]) | |
71 elif roadUser1 != None and roadUser2 != None: | |
72 self.roadUserNumbers = set(roadUser1.getNum(), roadUser2.getNum()) | |
73 else: | |
74 self.roadUserNumbers = None | |
35 self.categoryNum = categoryNum | 75 self.categoryNum = categoryNum |
36 self.indicators = {} | 76 self.indicators = {} |
77 self.interactionInterval = None | |
78 | |
79 def getRoadUserNumbers(self): | |
80 return self.roadUserNumbers | |
37 | 81 |
38 def getIndicator(self, indicatorName): | 82 def getIndicator(self, indicatorName): |
39 return self.indicators[indicatorName] | 83 return self.indicators.get(indicatorName, None) |
40 | 84 |
41 def addIndicator(self, indicator): | 85 def addIndicator(self, indicator): |
42 self.indicators[indicator.name] = indicator | 86 if indicator: |
87 self.indicators[indicator.name] = indicator | |
43 | 88 |
44 def computeIndicators(self): | 89 def computeIndicators(self): |
45 '''Computes the collision course cosine only if the cosine is positive''' | 90 '''Computes the collision course cosine only if the cosine is positive''' |
46 collisionCourseDotProducts = {}#[0]*int(self.timeInterval.length()) | 91 collisionCourseDotProducts = {}#[0]*int(self.timeInterval.length()) |
47 collisionCourseCosines = {} | 92 collisionCourseAngles = {} |
93 velocityAngles = {} | |
48 distances = {}#[0]*int(self.timeInterval.length()) | 94 distances = {}#[0]*int(self.timeInterval.length()) |
49 speedDifferentials = {} | 95 speedDifferentials = {} |
96 interactionInstants = [] | |
50 for instant in self.timeInterval: | 97 for instant in self.timeInterval: |
51 deltap = self.movingObject1.getPositionAtInstant(instant)-self.movingObject2.getPositionAtInstant(instant) | 98 deltap = self.roadUser1.getPositionAtInstant(instant)-self.roadUser2.getPositionAtInstant(instant) |
52 deltav = self.movingObject2.getVelocityAtInstant(instant)-self.movingObject1.getVelocityAtInstant(instant) | 99 v1 = self.roadUser1.getVelocityAtInstant(instant) |
100 v2 = self.roadUser2.getVelocityAtInstant(instant) | |
101 deltav = v2-v1 | |
102 velocityAngles[instant] = arccos(moving.Point.dot(v1, v2)/(v1.norm2()*v2.norm2())) | |
53 collisionCourseDotProducts[instant] = moving.Point.dot(deltap, deltav) | 103 collisionCourseDotProducts[instant] = moving.Point.dot(deltap, deltav) |
54 distances[instant] = deltap.norm2() # todo compute closest feature distance, if features | 104 distances[instant] = deltap.norm2() |
55 speedDifferentials[instant] = deltav.norm2() | 105 speedDifferentials[instant] = deltav.norm2() |
56 if collisionCourseDotProducts[instant] > 0: | 106 if collisionCourseDotProducts[instant] > 0: |
57 collisionCourseCosines[instant] = arccos(collisionCourseDotProducts[instant]/(distances[instant]*speedDifferentials[instant])) | 107 interactionInstants.append(instant) |
58 | 108 collisionCourseAngles[instant] = arccos(collisionCourseDotProducts[instant]/(distances[instant]*speedDifferentials[instant])) |
59 # todo shorten the time intervals based on the interaction definition | 109 |
60 self.addIndicator(indicators.SeverityIndicator('Collision Course Dot Product', collisionCourseDotProducts)) | 110 if len(interactionInstants) >= 2: |
61 self.addIndicator(indicators.SeverityIndicator('Distance', distances)) | 111 self.interactionInterval = moving.TimeInterval(interactionInstants[0], interactionInstants[-1]) |
62 self.addIndicator(indicators.SeverityIndicator('Speed Differential', speedDifferentials)) | 112 else: |
63 self.addIndicator(indicators.SeverityIndicator('Collision Course Cosine', collisionCourseCosines)) | 113 self.interactionInterval = moving.TimeInterval() |
64 | 114 self.addIndicator(indicators.SeverityIndicator(Interaction.indicatorNames[0], collisionCourseDotProducts)) |
65 # todo test for interaction instants and interval, compute indicators | 115 self.addIndicator(indicators.SeverityIndicator(Interaction.indicatorNames[1], collisionCourseAngles)) |
116 self.addIndicator(indicators.SeverityIndicator(Interaction.indicatorNames[2], distances)) | |
117 self.addIndicator(indicators.SeverityIndicator(Interaction.indicatorNames[4], velocityAngles)) | |
118 self.addIndicator(indicators.SeverityIndicator(Interaction.indicatorNames[5], speedDifferentials)) | |
119 | |
120 # if we have features, compute other indicators | |
121 if len(self.roadUser1.features) != 0 and len(self.roadUser2.features) != 0: | |
122 minDistance={} | |
123 for instant in self.timeInterval: | |
124 minDistance[instant] = moving.MovingObject.minDistance(self.roadUser1, self.roadUser2, instant) | |
125 self.addIndicator(indicators.SeverityIndicator(Interaction.indicatorNames[3], minDistance)) | |
126 | |
127 def computeCrossingsCollisions(self, predictionParameters, collisionDistanceThreshold, timeHorizon, computeCZ = False, debug = False, timeInterval = None, nProcesses = 1): | |
128 '''Computes all crossing and collision points at each common instant for two road users. ''' | |
129 self.collisionPoints={} | |
130 self.crossingZones={} | |
131 TTCs = {} | |
132 | |
133 if timeInterval: | |
134 commonTimeInterval = timeInterval | |
135 else: | |
136 commonTimeInterval = self.timeInterval | |
137 self.collisionPoints, self.crossingZones = prediction.computeCrossingsCollisions(predictionParameters, self.roadUser1, self.roadUser2, collisionDistanceThreshold, timeHorizon, computeCZ, debug, commonTimeInterval, nProcesses) | |
138 for i, cp in self.collisionPoints.iteritems(): | |
139 TTCs[i] = prediction.SafetyPoint.computeExpectedIndicator(cp) | |
140 # add probability of collision, and probability of successful evasive action | |
141 self.addIndicator(indicators.SeverityIndicator(Interaction.indicatorNames[7], TTCs)) | |
142 | |
143 if computeCZ: | |
144 pPETs = {} | |
145 for i in list(commonTimeInterval)[:-1]: | |
146 if len(self.crossingZones[i]) > 0: | |
147 pPETs[i] = prediction.SafetyPoint.computeExpectedIndicator(self.crossingZones[i]) | |
148 self.addIndicator(indicators.SeverityIndicator(Interaction.indicatorNames[9], pPETs)) | |
66 | 149 |
67 def addVideoFilename(self,videoFilename): | 150 def addVideoFilename(self,videoFilename): |
68 self.videoFilename= videoFilename | 151 self.videoFilename= videoFilename |
69 | 152 |
70 def addInteractionType(self,interactionType): | 153 def addInteractionType(self,interactionType): |
71 ''' interaction types: conflict or collision if they are known''' | 154 ''' interaction types: conflict or collision if they are known''' |
72 self.interactionType= interactionType | 155 self.interactionType= interactionType |
73 | 156 |
74 def createInteractions(objects): | 157 def createInteractions(objects, _others = None): |
75 '''Create all interactions of two co-existing road users | 158 '''Create all interactions of two co-existing road users''' |
76 | 159 if _others != None: |
77 todo add test to compute categories?''' | 160 others = _others |
161 | |
78 interactions = [] | 162 interactions = [] |
79 num = 0 | 163 num = 0 |
80 for i in xrange(len(objects)): | 164 for i in xrange(len(objects)): |
81 for j in xrange(i): | 165 if _others == None: |
82 commonTimeInterval = objects[i].commonTimeInterval(objects[j]) | 166 others = objects[:i] |
167 for j in xrange(len(others)): | |
168 commonTimeInterval = objects[i].commonTimeInterval(others[j]) | |
83 if not commonTimeInterval.empty(): | 169 if not commonTimeInterval.empty(): |
84 interactions.append(Interaction(num, commonTimeInterval, objects[i].num, objects[j].num, objects[i], objects[j])) | 170 interactions.append(Interaction(num, commonTimeInterval, objects[i].num, others[j].num, objects[i], others[j])) |
85 num += 1 | 171 num += 1 |
86 return interactions | 172 return interactions |
87 | 173 |
174 def prototypeCluster(interactions, similarityMatrix, alignmentMatrix, indicatorName, minSimilarity): | |
175 '''Finds exemplar indicator time series for all interactions | |
176 Returns the prototype indices (in the interaction list) and the label of each indicator (interaction) | |
177 | |
178 if an indicator profile (time series) is different enough (<minSimilarity), | |
179 it will become a new prototype. | |
180 Non-prototype interactions will be assigned to an existing prototype''' | |
181 | |
182 # sort indicators based on length | |
183 indices = range(similarityMatrix.shape[0]) | |
184 def compare(i, j): | |
185 if len(interactions[i].getIndicator(indicatorName)) > len(interactions[j].getIndicator(indicatorName)): | |
186 return -1 | |
187 elif len(interactions[i].getIndicator(indicatorName)) == len(interactions[j].getIndicator(indicatorName)): | |
188 return 0 | |
189 else: | |
190 return 1 | |
191 indices.sort(compare) | |
192 # go through all indicators | |
193 prototypeIndices = [indices[0]] | |
194 for i in indices[1:]: | |
195 if similarityMatrix[i][prototypeIndices].max() < minSimilarity: | |
196 prototypeIndices.append(i) | |
197 | |
198 # assignment | |
199 labels = [-1]*similarityMatrix.shape[0] | |
200 indices = [i for i in range(similarityMatrix.shape[0]) if i not in prototypeIndices] | |
201 for i in prototypeIndices: | |
202 labels[i] = i | |
203 for i in indices: | |
204 prototypeIndex = similarityMatrix[i][prototypeIndices].argmax() | |
205 labels[i] = prototypeIndices[prototypeIndex] | |
206 | |
207 return prototypeIndices, labels | |
208 | |
209 def prototypeMultivariateCluster(interactions, similarityMatrics, indicatorNames, minSimilarities, minClusterSize): | |
210 '''Finds exmaple indicator time series (several indicators) for all interactions | |
211 | |
212 if any interaction indicator time series is different enough (<minSimilarity), | |
213 it will become a new prototype. | |
214 Non-prototype interactions will be assigned to an existing prototype if all indicators are similar enough''' | |
215 pass | |
88 | 216 |
89 # TODO: | 217 # TODO: |
90 #http://stackoverflow.com/questions/3288595/multiprocessing-using-pool-map-on-a-function-defined-in-a-class | 218 #http://stackoverflow.com/questions/3288595/multiprocessing-using-pool-map-on-a-function-defined-in-a-class |
91 #http://www.rueckstiess.net/research/snippets/show/ca1d7d90 | 219 #http://www.rueckstiess.net/research/snippets/show/ca1d7d90 |
92 def calculateIndicatorPipe(pairs, predParam, timeHorizon=75,collisionDistanceThreshold=1.8): | 220 def calculateIndicatorPipe(pairs, predParam, timeHorizon=75,collisionDistanceThreshold=1.8): |
93 collisionPoints, crossingZones = prediction.computeCrossingsCollisions(pairs.movingObject1, pairs.movingObject2, predParam, collisionDistanceThreshold, timeHorizon) | 221 collisionPoints, crossingZones = prediction.computeCrossingsCollisions(pairs.roadUser1, pairs.roadUser2, predParam, collisionDistanceThreshold, timeHorizon) |
94 #print pairs.num | 222 #print pairs.num |
95 # Ignore empty collision points | 223 # Ignore empty collision points |
96 empty = 1 | 224 empty = 1 |
97 for i in collisionPoints: | 225 for i in collisionPoints: |
98 if(collisionPoints[i] != []): | 226 if(collisionPoints[i] != []): |
135 pool.close() | 263 pool.close() |
136 else: | 264 else: |
137 #prog = Tools.ProgressBar(0, len(self.pairs), 77) #Removed in traffic-intelligenc port | 265 #prog = Tools.ProgressBar(0, len(self.pairs), 77) #Removed in traffic-intelligenc port |
138 for j in xrange(len(self.pairs)): | 266 for j in xrange(len(self.pairs)): |
139 #prog.updateAmount(j) #Removed in traffic-intelligenc port | 267 #prog.updateAmount(j) #Removed in traffic-intelligenc port |
140 collisionPoints, crossingZones = prediction.computeCrossingsCollisions(self.pairs[j].movingObject1, self.pairs[j].movingObject2, predParam, collisionDistanceThreshold, timeHorizon) | 268 collisionPoints, crossingZones = prediction.computeCrossingsCollisions(self.pairs[j].roadUser1, self.pairs[j].roadUser2, predParam, collisionDistanceThreshold, timeHorizon) |
141 | 269 |
142 # Ignore empty collision points | 270 # Ignore empty collision points |
143 empty = 1 | 271 empty = 1 |
144 for i in collisionPoints: | 272 for i in collisionPoints: |
145 if(collisionPoints[i] != []): | 273 if(collisionPoints[i] != []): |
179 for j in self.pairs: | 307 for j in self.pairs: |
180 if(j.hasCZ): | 308 if(j.hasCZ): |
181 lists.append(j.num) | 309 lists.append(j.num) |
182 return lists | 310 return lists |
183 | 311 |
184 def getCPlist(self,indicatorThreshold=99999): | 312 def getCPlist(self,indicatorThreshold=float('Inf')): |
185 lists = [] | 313 lists = [] |
186 for j in self.pairs: | 314 for j in self.pairs: |
187 if(j.hasCP): | 315 if(j.hasCP): |
188 for k in j.CP: | 316 for k in j.CP: |
189 if(j.CP[k] != [] and j.CP[k][0].indicator < indicatorThreshold): | 317 if(j.CP[k] != [] and j.CP[k][0].indicator < indicatorThreshold): |
190 lists.append([k,j.CP[k][0]]) | 318 lists.append([k,j.CP[k][0]]) |
191 return lists | 319 return lists |
192 | 320 |
193 def getCZlist(self,indicatorThreshold=99999): | 321 def getCZlist(self,indicatorThreshold=float('Inf')): |
194 lists = [] | 322 lists = [] |
195 for j in self.pairs: | 323 for j in self.pairs: |
196 if(j.hasCZ): | 324 if(j.hasCZ): |
197 for k in j.CZ: | 325 for k in j.CZ: |
198 if(j.CZ[k] != [] and j.CZ[k][0].indicator < indicatorThreshold): | 326 if(j.CZ[k] != [] and j.CZ[k][0].indicator < indicatorThreshold): |
227 | 355 |
228 | 356 |
229 if __name__ == "__main__": | 357 if __name__ == "__main__": |
230 import doctest | 358 import doctest |
231 import unittest | 359 import unittest |
232 #suite = doctest.DocFileSuite('tests/moving.txt') | 360 suite = doctest.DocFileSuite('tests/events.txt') |
233 suite = doctest.DocTestSuite() | 361 #suite = doctest.DocTestSuite() |
234 unittest.TextTestRunner().run(suite) | 362 unittest.TextTestRunner().run(suite) |
235 | 363 |