changeset 1222:69b531c7a061

added methods to reset trajectories and change object coordinates (including features)
author Nicolas Saunier <nicolas.saunier@polymtl.ca>
date Tue, 20 Jun 2023 15:42:19 -0400
parents 5a207c838323
children 051cf5bddc1f
files trafficintelligence/moving.py trafficintelligence/tests/moving.txt trafficintelligence/utils.py
diffstat 3 files changed, 41 insertions(+), 1 deletions(-) [+]
line wrap: on
line diff
--- a/trafficintelligence/moving.py	Mon Jun 19 22:37:45 2023 -0400
+++ b/trafficintelligence/moving.py	Tue Jun 20 15:42:19 2023 -0400
@@ -873,6 +873,11 @@
     def setPosition(self, i, p):
         self.setPositionXY(i, p.x, p.y)
 
+    def reset(self, x, y):
+        for i in range(self.__len__()):
+            self.positions[0][i] = x
+            self.positions[1][i] = y
+
     def addPositionXY(self, x, y):
         self.positions[0].append(x)
         self.positions[1].append(y)
@@ -884,6 +889,9 @@
         self.positions[0].append(self.positions[0][-1])
         self.positions[1].append(self.positions[1][-1])
 
+    def agg(self, aggFunc = mean):
+        return Point.agg(self, aggFunc)
+
     @staticmethod
     def _plot(positions, options = '', withOrigin = False, lastCoordinate = None, timeStep = 1, objNum = None, **kwargs):
         if lastCoordinate is None:
@@ -952,6 +960,11 @@
         return Trajectory([[alpha*x for x in self.getXCoordinates()],
                            [alpha*y for y in self.getYCoordinates()]])
 
+    def filterMovingWindow(self, halfWidth, mode = 'valid'):
+        '''Returns a new Trajectory obtained after the smoothing of the input by a moving average'''
+        return Trajectory([utils.filterMovingWindow(self.positions[0], halfWidth, mode),
+                           utils.filterMovingWindow(self.positions[1], halfWidth, mode)])
+
     def differentiate(self, doubleLastPosition = False):
         diff = Trajectory()
         for i in range(1, self.length()):
@@ -1765,6 +1778,17 @@
     def getYCoordinates(self):
         return self.positions.getYCoordinates()
 
+    def setStationary(self):
+        '''Resets the position to the mean of existing positions and sets speeds to 0
+        And does the same to the features
+        TODO: other options (provide x, y, what to do with features?)'''
+        meanPosition = self.positions.agg(mean)
+        self.positions.reset(meanPosition.x, meanPosition.y)
+        self.velocities.reset(0,0)
+        if self.hasFeatures():
+            for f in self.getFeatures():
+                f.setStationary()
+        
     def plot(self, options = '', withOrigin = False, timeStep = 1, withFeatures = False, withIds = False, **kwargs):
         if withIds:
             objNum = self.getNum()
--- a/trafficintelligence/tests/moving.txt	Mon Jun 19 22:37:45 2023 -0400
+++ b/trafficintelligence/tests/moving.txt	Tue Jun 20 15:42:19 2023 -0400
@@ -219,6 +219,22 @@
 >>> Point.timeToCollision(p1, p2, v1, v2, 1.)
 4.0
 
+>>> t = Trajectory.generate(Point(0.1,-1.), Point(1.,0.), 22)
+>>> t[0].x == 0.1
+True
+>>> x = 1.
+>>> t.reset(x, x)
+>>> t[0].x == x
+True
+>>> t[10].y == x
+True
+>>> o1 = MovingObject.generate(1, Point(-5.,0.), Point(1.,0.), TimeInterval(0,10))
+>>> o1.getVelocityAt(1).x == 1.
+True
+>>> o1.setStationary()
+>>> o1.getVelocityAt(1).x == 0
+True
+
 >>> objects = storage.loadTrajectoriesFromSqlite('../samples/laurier.sqlite', 'object')
 >>> len(objects)
 5
--- a/trafficintelligence/utils.py	Mon Jun 19 22:37:45 2023 -0400
+++ b/trafficintelligence/utils.py	Tue Jun 20 15:42:19 2023 -0400
@@ -432,7 +432,7 @@
     return smoothed
 
 def filterMovingWindow(inputSignal, halfWidth, mode = 'valid'):
-    '''Returns an array obtained after the smoothing of the input by a moving average
+    '''Returns an array obtained after the smoothing of the 1-D input by a moving average
     The size of the output depends on the mode: 'full', 'same', 'valid'
     See https://numpy.org/doc/stable/reference/generated/numpy.convolve.html.'''
     width = min(len(inputSignal), int(halfWidth*2+1))