changeset 887:e2452abba0e7

added option to compute PET in safety analysis script, and save in database
author Nicolas Saunier <nicolas.saunier@polymtl.ca>
date Wed, 22 Mar 2017 10:44:24 -0400
parents d2eb8c93f7de
children 40994bb43148
files python/events.py python/moving.py python/tests/moving.txt scripts/safety-analysis.py
diffstat 4 files changed, 31 insertions(+), 17 deletions(-) [+]
line wrap: on
line diff
--- a/python/events.py	Tue Mar 21 17:51:38 2017 -0400
+++ b/python/events.py	Wed Mar 22 10:44:24 2017 -0400
@@ -165,9 +165,15 @@
         self.roadUser1.plotOnWorldImage(nPixelsPerUnitDistance, options, withOrigin, timeStep, **kwargs)
         self.roadUser2.plotOnWorldImage(nPixelsPerUnitDistance, options, withOrigin, timeStep, **kwargs)
 
-    def play(self, videoFilename, homography = None, undistort = False, intrinsicCameraMatrix = None, distortionCoefficients = None, undistortedImageMultiplication = 1.):
+    def play(self, videoFilename, homography = None, undistort = False, intrinsicCameraMatrix = None, distortionCoefficients = None, undistortedImageMultiplication = 1., allUserInstants = False):
         if self.roadUser1 is not None and self.roadUser2 is not None:
-            cvutils.displayTrajectories(videoFilename, [self.roadUser1, self.roadUser2], homography = homography, firstFrameNum = self.getFirstInstant(), lastFrameNumArg = self.getLastInstant(), undistort = undistort, intrinsicCameraMatrix = intrinsicCameraMatrix, distortionCoefficients = distortionCoefficients, undistortedImageMultiplication = undistortedImageMultiplication)
+            if allUserInstants:
+                firstFrameNum = min(self.roadUser1.getFirstInstant(), self.roadUser2.getFirstInstant())
+                lastFrameNum = max(self.roadUser1.getLastInstant(), self.roadUser2.getLastInstant())
+            else:
+                firstFrameNum = self.getFirstInstant()
+                lastFrameNum = self.getLastInstant()
+            cvutils.displayTrajectories(videoFilename, [self.roadUser1, self.roadUser2], homography = homography, firstFrameNum = firstFrameNum, lastFrameNumArg = lastFrameNum, undistort = undistort, intrinsicCameraMatrix = intrinsicCameraMatrix, distortionCoefficients = distortionCoefficients, undistortedImageMultiplication = undistortedImageMultiplication)
         else:
             print('Please set the interaction road user attributes roadUser1 and roadUser1 through the method setRoadUsers')
 
@@ -237,10 +243,9 @@
         # TODO add probability of collision, and probability of successful evasive action
 
     def computePET(self, collisionDistanceThreshold):
-        # TODO add crossing zone
-        pet =  moving.MovingObject.computePET(self.roadUser1, self.roadUser2, collisionDistanceThreshold)
-        if pet is not None: # TODO get crossing zone and time
-            self.addIndicator(indicators.SeverityIndicator(Interaction.indicatorNames[10], {0: pet}, mostSevereIsMax = False))
+        pet, t1, t2=  moving.MovingObject.computePET(self.roadUser1, self.roadUser2, collisionDistanceThreshold)
+        if pet is not None:
+            self.addIndicator(indicators.SeverityIndicator(Interaction.indicatorNames[10], {min(t1, t2): pet}, mostSevereIsMax = False))
 
     def setCollision(self, collision):
         '''indicates if it is a collision: argument should be boolean'''
--- a/python/moving.py	Tue Mar 21 17:51:38 2017 -0400
+++ b/python/moving.py	Wed Mar 22 10:44:24 2017 -0400
@@ -5,7 +5,7 @@
 from base import VideoFilenameAddable
 
 from math import sqrt, atan2, cos, sin
-from numpy import median, array, zeros, hypot, NaN, std, floor, float32
+from numpy import median, array, zeros, hypot, NaN, std, floor, float32, argwhere
 from matplotlib.pyplot import plot, text
 from scipy.stats import scoreatpercentile
 from scipy.spatial.distance import cdist
@@ -1426,19 +1426,25 @@
     def computePET(obj1, obj2, collisionDistanceThreshold):
         '''Post-encroachment time based on distance threshold
 
-        Returns the smallest time difference when the object positions are within collisionDistanceThreshold'''
+        Returns the smallest time difference when the object positions are within collisionDistanceThreshold
+        and the instants at which each object is passing through its corresponding position'''
         positions1 = [p.astuple() for p in obj1.getPositions()]
         positions2 = [p.astuple() for p in obj2.getPositions()]
-        pets = zeros((int(obj1.length()), int(obj2.length())))
+        n1 = len(positions1)
+        n2 = len(positions2)
+        pets = zeros((n1, n2))
         for i,t1 in enumerate(obj1.getTimeInterval()):
             for j,t2 in enumerate(obj2.getTimeInterval()):
                 pets[i,j] = abs(t1-t2)
         distances = cdist(positions1, positions2, metric = 'euclidean')
-        if distances.min() <= collisionDistanceThreshold:
-            #idx = distances.argmin()
-            return pets[distances <= collisionDistanceThreshold].min()
+        smallDistances = (distances <= collisionDistanceThreshold)
+        if smallDistances.any():
+            smallPets = pets[smallDistances]
+            petIdx = smallPets.argmin()
+            distanceIndices = argwhere(smallDistances)[petIdx]
+            return smallPets[petIdx], obj1.getFirstInstant()+distanceIndices[0], obj2.getFirstInstant()+distanceIndices[1]
         else:
-            return None
+            return None, None, None
 
     def predictPosition(self, instant, nTimeSteps, externalAcceleration = Point(0,0)):
         '''Predicts the position of object at instant+deltaT, 
--- a/python/tests/moving.txt	Tue Mar 21 17:51:38 2017 -0400
+++ b/python/tests/moving.txt	Wed Mar 22 10:44:24 2017 -0400
@@ -174,10 +174,13 @@
 >>> o1 = MovingObject.generate(Point(-5.,0.), Point(1.,0.), TimeInterval(0,10))
 >>> o2 = MovingObject.generate(Point(0.,-5.), Point(0.,1.), TimeInterval(0,10))
 >>> MovingObject.computePET(o1, o2, 0.1)
-0.0
+(0.0, 5, 5)
 >>> o2 = MovingObject.generate(Point(0.,-5.), Point(0.,1.), TimeInterval(5,15))
 >>> MovingObject.computePET(o1, o2, 0.1)
-5.0
+(5.0, 5, 10)
+>>> o2 = MovingObject.generate(Point(0.,-5.), Point(0.,1.), TimeInterval(15,30))
+>>> MovingObject.computePET(o1, o2, 0.1)
+(15.0, 5, 20)
 
 >>> t = CurvilinearTrajectory(S = [1., 2., 3., 5.], Y = [0.5, 0.5, 0.6, 0.7], lanes = ['1']*4)
 >>> t.differentiate() # doctest:+ELLIPSIS
--- a/scripts/safety-analysis.py	Tue Mar 21 17:51:38 2017 -0400
+++ b/scripts/safety-analysis.py	Wed Mar 22 10:44:24 2017 -0400
@@ -68,8 +68,8 @@
     inter.computeCrossingsCollisions(predictionParameters, params.collisionDistance, params.predictionTimeHorizon, params.crossingZones, nProcesses = args.nProcesses)
 
 if args.computePET:
-    for inter in Interactions:
-        inter.computePET()
+    for inter in interactions:
+        inter.computePET(params.collisionDistance)
     
 storage.saveIndicators(params.databaseFilename, interactions)