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