Mercurial Hosting > traffic-intelligence
comparison python/events.py @ 708:a37c565f4b68
merged dev
author | Nicolas Saunier <nicolas.saunier@polymtl.ca> |
---|---|
date | Wed, 22 Jul 2015 14:17:44 -0400 |
parents | e395bffe1412 |
children | 4e89341edd29 |
comparison
equal
deleted
inserted
replaced
707:7efa36b9bcfd | 708:a37c565f4b68 |
---|---|
4 | 4 |
5 import moving, prediction, indicators, utils, cvutils | 5 import moving, prediction, indicators, utils, cvutils |
6 from base import VideoFilenameAddable | 6 from base import VideoFilenameAddable |
7 | 7 |
8 import numpy as np | 8 import numpy as np |
9 from numpy import arccos | |
10 | 9 |
11 import multiprocessing | 10 import multiprocessing |
12 import itertools | 11 import itertools |
13 | 12 |
14 | 13 |
88 '', | 87 '', |
89 's', | 88 's', |
90 '', | 89 '', |
91 ''] | 90 ''] |
92 | 91 |
92 timeIndicators = ['Time to Collision', 'predicted Post Encroachment Time'] | |
93 | |
93 def __init__(self, num = None, timeInterval = None, roaduserNum1 = None, roaduserNum2 = None, roadUser1 = None, roadUser2 = None, categoryNum = None): | 94 def __init__(self, num = None, timeInterval = None, roaduserNum1 = None, roaduserNum2 = None, roadUser1 = None, roadUser2 = None, categoryNum = None): |
94 moving.STObject.__init__(self, num, timeInterval) | 95 moving.STObject.__init__(self, num, timeInterval) |
95 if timeInterval is None and roadUser1 is not None and roadUser2 is not None: | 96 if timeInterval is None and roadUser1 is not None and roadUser2 is not None: |
96 self.timeInterval = roadUser1.commonTimeInterval(roadUser2) | 97 self.timeInterval = roadUser1.commonTimeInterval(roadUser2) |
97 self.roadUser1 = roadUser1 | 98 self.roadUser1 = roadUser1 |
111 | 112 |
112 def getRoadUserNumbers(self): | 113 def getRoadUserNumbers(self): |
113 return self.roadUserNumbers | 114 return self.roadUserNumbers |
114 | 115 |
115 def setRoadUsers(self, objects): | 116 def setRoadUsers(self, objects): |
116 nums = list(self.getRoadUserNumbers()) | 117 nums = sorted(list(self.getRoadUserNumbers())) |
117 if objects[nums[0]].getNum() == nums[0]: | 118 if nums[0]<len(objects) and objects[nums[0]].getNum() == nums[0]: |
118 self.roadUser1 = objects[nums[0]] | 119 self.roadUser1 = objects[nums[0]] |
119 if objects[nums[1]].getNum() == nums[1]: | 120 if nums[1]<len(objects) and objects[nums[1]].getNum() == nums[1]: |
120 self.roadUser2 = objects[nums[1]] | 121 self.roadUser2 = objects[nums[1]] |
121 | 122 |
122 i = 0 | 123 if self.roadUser1 is None or self.roadUser2 is None: |
123 while i < len(objects) and self.roadUser2 is None: | 124 self.roadUser1 = None |
124 if objects[i].getNum() in nums: | 125 self.roadUser2 = None |
125 if self.roadUser1 is None: | 126 i = 0 |
126 self.roadUser1 = objects[i] | 127 while i < len(objects) and self.roadUser2 is None: |
127 else: | 128 if objects[i].getNum() in nums: |
128 self.roadUser2 = objects[i] | 129 if self.roadUser1 is None: |
129 i += 1 | 130 self.roadUser1 = objects[i] |
131 else: | |
132 self.roadUser2 = objects[i] | |
133 i += 1 | |
130 | 134 |
131 def getIndicator(self, indicatorName): | 135 def getIndicator(self, indicatorName): |
132 return self.indicators.get(indicatorName, None) | 136 return self.indicators.get(indicatorName, None) |
133 | 137 |
134 def addIndicator(self, indicator): | 138 def addIndicator(self, indicator): |
175 for instant in self.timeInterval: | 179 for instant in self.timeInterval: |
176 deltap = self.roadUser1.getPositionAtInstant(instant)-self.roadUser2.getPositionAtInstant(instant) | 180 deltap = self.roadUser1.getPositionAtInstant(instant)-self.roadUser2.getPositionAtInstant(instant) |
177 v1 = self.roadUser1.getVelocityAtInstant(instant) | 181 v1 = self.roadUser1.getVelocityAtInstant(instant) |
178 v2 = self.roadUser2.getVelocityAtInstant(instant) | 182 v2 = self.roadUser2.getVelocityAtInstant(instant) |
179 deltav = v2-v1 | 183 deltav = v2-v1 |
180 velocityAngles[instant] = arccos(moving.Point.dot(v1, v2)/(v1.norm2()*v2.norm2())) | 184 velocityAngles[instant] = np.arccos(moving.Point.dot(v1, v2)/(v1.norm2()*v2.norm2())) |
181 collisionCourseDotProducts[instant] = moving.Point.dot(deltap, deltav) | 185 collisionCourseDotProducts[instant] = moving.Point.dot(deltap, deltav) |
182 distances[instant] = deltap.norm2() | 186 distances[instant] = deltap.norm2() |
183 speedDifferentials[instant] = deltav.norm2() | 187 speedDifferentials[instant] = deltav.norm2() |
184 if collisionCourseDotProducts[instant] > 0: | 188 if collisionCourseDotProducts[instant] > 0: |
185 interactionInstants.append(instant) | 189 interactionInstants.append(instant) |
186 if distances[instant] != 0 and speedDifferentials[instant] != 0: | 190 if distances[instant] != 0 and speedDifferentials[instant] != 0: |
187 collisionCourseAngles[instant] = arccos(collisionCourseDotProducts[instant]/(distances[instant]*speedDifferentials[instant])) | 191 collisionCourseAngles[instant] = np.arccos(collisionCourseDotProducts[instant]/(distances[instant]*speedDifferentials[instant])) |
188 | 192 |
189 if len(interactionInstants) >= 2: | 193 if len(interactionInstants) >= 2: |
190 self.interactionInterval = moving.TimeInterval(interactionInstants[0], interactionInstants[-1]) | 194 self.interactionInterval = moving.TimeInterval(interactionInstants[0], interactionInstants[-1]) |
191 else: | 195 else: |
192 self.interactionInterval = moving.TimeInterval() | 196 self.interactionInterval = moving.TimeInterval() |
193 self.addIndicator(indicators.SeverityIndicator(Interaction.indicatorNames[0], collisionCourseDotProducts)) | 197 self.addIndicator(indicators.SeverityIndicator(Interaction.indicatorNames[0], collisionCourseDotProducts)) |
194 self.addIndicator(indicators.SeverityIndicator(Interaction.indicatorNames[1], collisionCourseAngles)) | 198 self.addIndicator(indicators.SeverityIndicator(Interaction.indicatorNames[1], collisionCourseAngles)) |
195 self.addIndicator(indicators.SeverityIndicator(Interaction.indicatorNames[2], distances)) | 199 self.addIndicator(indicators.SeverityIndicator(Interaction.indicatorNames[2], distances, mostSevereIsMax = False)) |
196 self.addIndicator(indicators.SeverityIndicator(Interaction.indicatorNames[4], velocityAngles)) | 200 self.addIndicator(indicators.SeverityIndicator(Interaction.indicatorNames[4], velocityAngles)) |
197 self.addIndicator(indicators.SeverityIndicator(Interaction.indicatorNames[5], speedDifferentials)) | 201 self.addIndicator(indicators.SeverityIndicator(Interaction.indicatorNames[5], speedDifferentials)) |
198 | 202 |
199 # if we have features, compute other indicators | 203 # if we have features, compute other indicators |
200 if self.roadUser1.hasFeatures() and self.roadUser2.hasFeatures(): | 204 if self.roadUser1.hasFeatures() and self.roadUser2.hasFeatures(): |
201 minDistance={} | 205 minDistances={} |
202 for instant in self.timeInterval: | 206 for instant in self.timeInterval: |
203 minDistance[instant] = moving.MovingObject.minDistance(self.roadUser1, self.roadUser2, instant) | 207 minDistances[instant] = moving.MovingObject.minDistance(self.roadUser1, self.roadUser2, instant) |
204 self.addIndicator(indicators.SeverityIndicator(Interaction.indicatorNames[3], minDistance)) | 208 self.addIndicator(indicators.SeverityIndicator(Interaction.indicatorNames[3], minDistances, mostSevereIsMax = False)) |
205 | 209 |
206 def computeCrossingsCollisions(self, predictionParameters, collisionDistanceThreshold, timeHorizon, computeCZ = False, debug = False, timeInterval = None, nProcesses = 1, usePrototypes=False, route1= (-1,-1), route2=(-1,-1), prototypes={}, secondStepPrototypes={}, nMatching={}, objects=[], noiseEntryNums=[], noiseExitNums=[], minSimilarity=0.1, mostMatched=None, useDestination=True, useSpeedPrototype=True, acceptPartialLength=30, step=1): | 210 def computeCrossingsCollisions(self, predictionParameters, collisionDistanceThreshold, timeHorizon, computeCZ = False, debug = False, timeInterval = None, nProcesses = 1, usePrototypes=False, route1= (-1,-1), route2=(-1,-1), prototypes={}, secondStepPrototypes={}, nMatching={}, objects=[], noiseEntryNums=[], noiseExitNums=[], minSimilarity=0.1, mostMatched=None, useDestination=True, useSpeedPrototype=True, acceptPartialLength=30, step=1): |
207 '''Computes all crossing and collision points at each common instant for two road users. ''' | 211 '''Computes all crossing and collision points at each common instant for two road users. ''' |
208 TTCs = {} | 212 TTCs = {} |
209 if usePrototypes: | 213 if usePrototypes: |
215 else: | 219 else: |
216 commonTimeInterval = self.timeInterval | 220 commonTimeInterval = self.timeInterval |
217 self.collisionPoints, crossingZones = predictionParameters.computeCrossingsCollisions(self.roadUser1, self.roadUser2, collisionDistanceThreshold, timeHorizon, computeCZ, debug, commonTimeInterval, nProcesses,usePrototypes,route1,route2,prototypes,secondStepPrototypes,nMatching,objects,noiseEntryNums,noiseExitNums,minSimilarity,mostMatched,useDestination,useSpeedPrototype,acceptPartialLength, step) | 221 self.collisionPoints, crossingZones = predictionParameters.computeCrossingsCollisions(self.roadUser1, self.roadUser2, collisionDistanceThreshold, timeHorizon, computeCZ, debug, commonTimeInterval, nProcesses,usePrototypes,route1,route2,prototypes,secondStepPrototypes,nMatching,objects,noiseEntryNums,noiseExitNums,minSimilarity,mostMatched,useDestination,useSpeedPrototype,acceptPartialLength, step) |
218 for i, cp in self.collisionPoints.iteritems(): | 222 for i, cp in self.collisionPoints.iteritems(): |
219 TTCs[i] = prediction.SafetyPoint.computeExpectedIndicator(cp) | 223 TTCs[i] = prediction.SafetyPoint.computeExpectedIndicator(cp) |
220 self.addIndicator(indicators.SeverityIndicator(Interaction.indicatorNames[7], TTCs, mostSevereIsMax=False)) | 224 if len(TTCs) > 0: |
225 self.addIndicator(indicators.SeverityIndicator(Interaction.indicatorNames[7], TTCs, mostSevereIsMax=False)) | |
221 | 226 |
222 # crossing zones and pPET | 227 # crossing zones and pPET |
223 if computeCZ: | 228 if computeCZ: |
224 self.crossingZones[predictionParameters.name] = crossingZones | 229 self.crossingZones = crossingZones |
225 pPETs = {} | 230 pPETs = {} |
226 for i, cz in self.crossingZones.iteritems(): | 231 for i, cz in self.crossingZones.iteritems(): |
227 pPETs[i] = prediction.SafetyPoint.computeExpectedIndicator(cz) | 232 pPETs[i] = prediction.SafetyPoint.computeExpectedIndicator(cz) |
228 self.addIndicator(indicators.SeverityIndicator(Interaction.indicatorNames[9], pPETs, mostSevereIsMax=False)) | 233 self.addIndicator(indicators.SeverityIndicator(Interaction.indicatorNames[9], pPETs, mostSevereIsMax=False)) |
229 # TODO add probability of collision, and probability of successful evasive action | 234 # TODO add probability of collision, and probability of successful evasive action |
240 if hasattr(self, 'collision'): | 245 if hasattr(self, 'collision'): |
241 return self.collision | 246 return self.collision |
242 else: | 247 else: |
243 return None | 248 return None |
244 | 249 |
245 def getCrossingZones(self, predictionMethodName): | 250 def getCollisionPoints(self): |
246 if self.crossingZones is not None: | 251 return self.collisionPoints |
247 return self.crossingZones[predictionMethodName] | 252 |
248 else: | 253 def getCrossingZones(self): |
249 return None | 254 return self.crossingZones |
250 | |
251 def getCollisionPoints(self, predictionMethodName): | |
252 if self.collisionPoints is not None: | |
253 return self.collisionPoints[predictionMethodName] | |
254 else: | |
255 return None | |
256 | |
257 | 255 |
258 def createInteractions(objects, _others = None): | 256 def createInteractions(objects, _others = None): |
259 '''Create all interactions of two co-existing road users''' | 257 '''Create all interactions of two co-existing road users''' |
260 if _others is not None: | 258 if _others is not None: |
261 others = _others | 259 others = _others |
280 if i<len(interactions): | 278 if i<len(interactions): |
281 return interactions[i] | 279 return interactions[i] |
282 else: | 280 else: |
283 return None | 281 return None |
284 | 282 |
285 def aggregateSafetyPoints(interactions, predictionMethodName = None, pointType = 'collision'): | 283 def aggregateSafetyPoints(interactions, pointType = 'collision'): |
286 '''Put all collision points or crossing zones in a list for display''' | 284 '''Put all collision points or crossing zones in a list for display''' |
287 if predictionMethodName is None and len(interactions)>0: | |
288 predictionMethodName = interactions[0].collisionPoints.keys()[0] | |
289 | |
290 allPoints = [] | 285 allPoints = [] |
291 if pointType == 'collision': | 286 if pointType == 'collision': |
292 for i in interactions: | 287 for i in interactions: |
293 for points in i.collisionPoints[predictionMethodName].values(): | 288 for points in i.collisionPoints.values(): |
294 allPoints += points | 289 allPoints += points |
295 elif pointType == 'crossing': | 290 elif pointType == 'crossing': |
296 for i in interactions: | 291 for i in interactions: |
297 for points in i.crossingZones[predictionMethodName].values(): | 292 for points in i.crossingZones.values(): |
298 allPoints += points | 293 allPoints += points |
299 else: | 294 else: |
300 print('unknown type of point '+pointType) | 295 print('unknown type of point: '+pointType) |
301 return allPoints | 296 return allPoints |
302 | 297 |
303 def prototypeCluster(interactions, similarityMatrix, alignmentMatrix, indicatorName, minSimilarity): | 298 def prototypeCluster(interactions, similarityMatrix, alignmentMatrix, indicatorName, minSimilarity): |
304 '''Finds exemplar indicator time series for all interactions | 299 '''Finds exemplar indicator time series for all interactions |
305 Returns the prototype indices (in the interaction list) and the label of each indicator (interaction) | 300 Returns the prototype indices (in the interaction list) and the label of each indicator (interaction) |
341 if any interaction indicator time series is different enough (<minSimilarity), | 336 if any interaction indicator time series is different enough (<minSimilarity), |
342 it will become a new prototype. | 337 it will become a new prototype. |
343 Non-prototype interactions will be assigned to an existing prototype if all indicators are similar enough''' | 338 Non-prototype interactions will be assigned to an existing prototype if all indicators are similar enough''' |
344 pass | 339 pass |
345 | 340 |
346 # TODO: | |
347 #http://stackoverflow.com/questions/3288595/multiprocessing-using-pool-map-on-a-function-defined-in-a-class | |
348 #http://www.rueckstiess.net/research/snippets/show/ca1d7d90 | |
349 def calculateIndicatorPipe(pairs, predParam, timeHorizon=75,collisionDistanceThreshold=1.8): | |
350 collisionPoints, crossingZones = prediction.computeCrossingsCollisions(pairs.roadUser1, pairs.roadUser2, predParam, collisionDistanceThreshold, timeHorizon) | |
351 #print pairs.num | |
352 # Ignore empty collision points | |
353 empty = 1 | |
354 for i in collisionPoints: | |
355 if(collisionPoints[i] != []): | |
356 empty = 0 | |
357 if(empty == 1): | |
358 pairs.hasCP = 0 | |
359 else: | |
360 pairs.hasCP = 1 | |
361 pairs.CP = collisionPoints | |
362 | |
363 # Ignore empty crossing zones | |
364 empty = 1 | |
365 for i in crossingZones: | |
366 if(crossingZones[i] != []): | |
367 empty = 0 | |
368 if(empty == 1): | |
369 pairs.hasCZ = 0 | |
370 else: | |
371 pairs.hasCZ = 1 | |
372 pairs.CZ = crossingZones | |
373 return pairs | |
374 | |
375 def calculateIndicatorPipe_star(a_b): | |
376 """Convert `f([1,2])` to `f(1,2)` call.""" | |
377 return calculateIndicatorPipe(*a_b) | |
378 | |
379 class VehPairs(): | |
380 '''Create a veh-pairs object from objects list''' | |
381 def __init__(self,objects): | |
382 self.pairs = createInteractions(objects) | |
383 self.interactionCount = 0 | |
384 self.CPcount = 0 | |
385 self.CZcount = 0 | |
386 | |
387 # Process indicator calculation with support for multi-threading | |
388 def calculateIndicators(self,predParam,threads=1,timeHorizon=75,collisionDistanceThreshold=1.8): | |
389 if(threads > 1): | |
390 pool = multiprocessing.Pool(threads) | |
391 self.pairs = pool.map(calculateIndicatorPipe_star, itertools.izip(self.pairs, itertools.repeat(predParam))) | |
392 pool.close() | |
393 else: | |
394 #prog = Tools.ProgressBar(0, len(self.pairs), 77) #Removed in traffic-intelligenc port | |
395 for j in xrange(len(self.pairs)): | |
396 #prog.updateAmount(j) #Removed in traffic-intelligenc port | |
397 collisionPoints, crossingZones = prediction.computeCrossingsCollisions(self.pairs[j].roadUser1, self.pairs[j].roadUser2, predParam, collisionDistanceThreshold, timeHorizon) | |
398 | |
399 # Ignore empty collision points | |
400 empty = 1 | |
401 for i in collisionPoints: | |
402 if(collisionPoints[i] != []): | |
403 empty = 0 | |
404 if(empty == 1): | |
405 self.pairs[j].hasCP = 0 | |
406 else: | |
407 self.pairs[j].hasCP = 1 | |
408 self.pairs[j].CP = collisionPoints | |
409 | |
410 # Ignore empty crossing zones | |
411 empty = 1 | |
412 for i in crossingZones: | |
413 if(crossingZones[i] != []): | |
414 empty = 0 | |
415 if(empty == 1): | |
416 self.pairs[j].hasCZ = 0 | |
417 else: | |
418 self.pairs[j].hasCZ = 1 | |
419 self.pairs[j].CZ = crossingZones | |
420 | |
421 for j in self.pairs: | |
422 self.interactionCount = self.interactionCount + len(j.CP) | |
423 self.CPcount = len(self.getCPlist()) | |
424 self.Czcount = len(self.getCZlist()) | |
425 | |
426 | |
427 def getPairsWCP(self): | |
428 lists = [] | |
429 for j in self.pairs: | |
430 if(j.hasCP): | |
431 lists.append(j.num) | |
432 return lists | |
433 | |
434 def getPairsWCZ(self): | |
435 lists = [] | |
436 for j in self.pairs: | |
437 if(j.hasCZ): | |
438 lists.append(j.num) | |
439 return lists | |
440 | |
441 def getCPlist(self,indicatorThreshold=float('Inf')): | |
442 lists = [] | |
443 for j in self.pairs: | |
444 if(j.hasCP): | |
445 for k in j.CP: | |
446 if(j.CP[k] != [] and j.CP[k][0].indicator < indicatorThreshold): | |
447 lists.append([k,j.CP[k][0]]) | |
448 return lists | |
449 | |
450 def getCZlist(self,indicatorThreshold=float('Inf')): | |
451 lists = [] | |
452 for j in self.pairs: | |
453 if(j.hasCZ): | |
454 for k in j.CZ: | |
455 if(j.CZ[k] != [] and j.CZ[k][0].indicator < indicatorThreshold): | |
456 lists.append([k,j.CZ[k][0]]) | |
457 return lists | |
458 | |
459 def genIndicatorHistogram(self, CPlist=False, bins=range(0,100,1)): | |
460 if(not CPlist): | |
461 CPlist = self.getCPlist() | |
462 if(not CPlist): | |
463 return False | |
464 TTC_list = [] | |
465 for i in CPlist: | |
466 TTC_list.append(i[1].indicator) | |
467 histo = np.histogram(TTC_list,bins=bins) | |
468 histo += (histo[0].astype(float)/np.sum(histo[0]),) | |
469 return histo | |
470 | 341 |
471 class Crossing(moving.STObject): | 342 class Crossing(moving.STObject): |
472 '''Class for the event of a street crossing | 343 '''Class for the event of a street crossing |
473 | 344 |
474 TODO: detecter passage sur la chaussee | 345 TODO: detecter passage sur la chaussee |