nsaunier/traffic-intelligence
work in progress on categorization
Commit ebb18043616e · Nicolas Saunier · 2024-05-28 17:16 -0400
Comments
No comments yet.
Diff
diff --git a/trafficintelligence/events.py b/trafficintelligence/events.py
--- a/trafficintelligence/events.py
+++ b/trafficintelligence/events.py
@@ -53,7 +53,8 @@
categories = {'headon': 0,
'rearend': 1,
'side': 2,
- 'parallel': 3}
+ 'parallel': 3,
+ 'stationary': 4}
indicatorNames = ['Collision Course Dot Product',
'Collision Course Angle',
@@ -108,7 +109,6 @@
else:
self.roadUserNumbers = None
self.indicators = {}
- self.interactionInterval = None
# list for collison points and crossing zones
self.collisionPoints = None
self.crossingZones = None
@@ -202,7 +202,6 @@
velocityAngles = {}
distances = {}
speedDifferentials = {}
- interactionInstants = []
for instant in self.timeInterval:
deltap = self.roadUser1.getPositionAtInstant(instant)-self.roadUser2.getPositionAtInstant(instant)
v1 = self.roadUser1.getVelocityAtInstant(instant)
@@ -215,15 +214,9 @@
collisionCourseDotProducts[instant] = moving.Point.dot(deltap, deltav)
distances[instant] = deltap.norm2()
speedDifferentials[instant] = deltav.norm2()
- if collisionCourseDotProducts[instant] > 0:
- interactionInstants.append(instant)
if distances[instant] != 0 and speedDifferentials[instant] != 0:
collisionCourseAngles[instant] = np.arccos(max(-1, min(1, collisionCourseDotProducts[instant]/(distances[instant]*speedDifferentials[instant])))) # avoid values slightly higher than 1.0
- if len(interactionInstants) >= 2:
- self.interactionInterval = moving.TimeInterval(interactionInstants[0], interactionInstants[-1])
- else:
- self.interactionInterval = moving.TimeInterval()
self.addIndicator(indicators.SeverityIndicator(Interaction.indicatorNames[0], collisionCourseDotProducts))
self.addIndicator(indicators.SeverityIndicator(Interaction.indicatorNames[1], collisionCourseAngles))
self.addIndicator(indicators.SeverityIndicator(Interaction.indicatorNames[2], distances, mostSevereIsMax = False))
@@ -237,7 +230,7 @@
minDistances[instant] = moving.MovingObject.minDistance(self.roadUser1, self.roadUser2, instant)
self.addIndicator(indicators.SeverityIndicator(Interaction.indicatorNames[3], minDistances, mostSevereIsMax = False))
- def categorize(self, velocityAngleTolerance, parallelAngleTolerance, headonCollisionCourseAngleTolerance = None):
+ def categorize(self, velocityAngleTolerance, parallelAngleTolerance, headonCollisionCourseAngleTolerance = None, speedThreshold = 0.):
'''Computes the interaction category by instant
all 3 angle arguments in radian
velocityAngleTolerance: indicates the angle threshold for rear and head on (180-velocityAngleTolerance), as well as the maximum collision course angle for head on (if headonCollisionCourseAngleTolerance is None)
@@ -248,6 +241,7 @@
parallelAngleToleranceCosine = np.cos(parallelAngleTolerance)
if headonCollisionCourseAngleTolerance is None:
headonCollisionCourseAngleTolerance = velocityAngleTolerance
+ speedThreshold2 = speedThreshold**2
self.categories = {}
collisionCourseDotProducts = self.getIndicator(Interaction.indicatorNames[0])
@@ -255,17 +249,27 @@
distances = self.getIndicator(Interaction.indicatorNames[2])
velocityAngles = self.getIndicator(Interaction.indicatorNames[4])
for instant in self.timeInterval:
- if velocityAngles[instant] < velocityAngleTolerance: # parallel or rear end
- midVelocity = self.roadUser1.getVelocityAtInstant(instant) + self.roadUser2.getVelocityAtInstant(instant)
- deltap = self.roadUser1.getPositionAtInstant(instant)-self.roadUser2.getPositionAtInstant(instant)
- if abs(moving.Point.dot(midVelocity, deltap)/(midVelocity.norm2()*distances[instant])) < parallelAngleToleranceCosine:
- self.categories[instant] = Interaction.categories["parallel"]
- else:
- self.categories[instant] = Interaction.categories["rearend"]
- elif velocityAngles[instant] > np.pi - velocityAngleTolerance and collisionCourseAngles[instant] < headonCollisionCourseAngleTolerance: # head on
- self.categories[instant] = Interaction.categories["headon"]
- elif collisionCourseDotProducts[instant] > 0:
- self.categories[instant] = Interaction.categories["side"]
+ if instant in velocityAngles:
+ if velocityAngles[instant] < velocityAngleTolerance: # parallel or rear end
+ midVelocity = self.roadUser1.getVelocityAtInstant(instant) + self.roadUser2.getVelocityAtInstant(instant)
+ deltap = self.roadUser1.getPositionAtInstant(instant)-self.roadUser2.getPositionAtInstant(instant)
+ if abs(moving.Point.dot(midVelocity, deltap)/(midVelocity.norm2()*distances[instant])) < parallelAngleToleranceCosine:
+ self.categories[instant] = Interaction.categories["parallel"]
+ else:
+ self.categories[instant] = Interaction.categories["rearend"]
+ elif velocityAngles[instant] > np.pi - velocityAngleTolerance and collisionCourseAngles[instant] < headonCollisionCourseAngleTolerance: # head on
+ self.categories[instant] = Interaction.categories["headon"]
+ elif collisionCourseDotProducts[instant] > 0:
+ self.categories[instant] = Interaction.categories["side"]
+ # true stationary is when object does not move for the whole period of the interaction, otherwise get last (or next) velocity vector for user orientation
+ # if instant not in self.categories: # if it's none of the other categories (could be with almost stationary vehicle) and only one speed is 0
+ # stationaryUser1 = self.roadUser1.getVelocityAtInstant(instant).norm2Squared() <= speedThreshold2
+ # stationaryUser2 = self.roadUser2.getVelocityAtInstant(instant).norm2Squared() <= speedThreshold2
+ # if stationaryUser1 != stationaryUser2 and collisionCourseDotProducts[instant] > 0: # only one is not moving
+ # self.categories[instant] = Interaction.categories["stationary"]
+ # leaving is not a good interaction category (issue in Etienne's 2022 paper): means we are past the situation in which users are approaching
+ # could try to predict what happened before, but it's not observed
+
def computeCrossingsCollisions(self, predictionParameters, collisionDistanceThreshold, timeHorizon, computeCZ = False, debug = False, timeInterval = None):
'''Computes all crossing and collision points at each common instant for two road users. '''