comparison python/moving.py @ 244:5027c174ab90

moved indicators to new file, added ExtrapolatedTrajectory class to extrapolation file
author Nicolas Saunier <nicolas.saunier@polymtl.ca>
date Tue, 17 Jul 2012 00:15:42 -0400
parents e0988a8ace0c
children bd8ab323c198
comparison
equal deleted inserted replaced
243:e0988a8ace0c 244:5027c174ab90
208 208
209 @staticmethod 209 @staticmethod
210 def plotAll(points, color='r'): 210 def plotAll(points, color='r'):
211 from matplotlib.pyplot import scatter 211 from matplotlib.pyplot import scatter
212 scatter([p.x for p in points],[p.y for p in points], c=color) 212 scatter([p.x for p in points],[p.y for p in points], c=color)
213
214 @staticmethod
215 def predictPosition(nTimeSteps, initialPosition, initialVelocity, initialAcceleration = Point(0,0)):
216 '''Predicts the position in nTimeSteps at constant speed/acceleration'''
217 return initalPosition+velocity.multiply(nTimeSteps) + initialAcceleration.multiply(nTimeSteps**2)
213 218
214 class FlowVector: 219 class FlowVector:
215 '''Class to represent 4-D flow vectors, 220 '''Class to represent 4-D flow vectors,
216 ie a position and a velocity''' 221 ie a position and a velocity'''
217 def __init__(self, position, velocity): 222 def __init__(self, position, velocity):
506 at which the object passes from one side of the segment to the other 511 at which the object passes from one side of the segment to the other
507 empty list if there is no crossing''' 512 empty list if there is no crossing'''
508 indices = self.positions.getIntersections(p1, p2) 513 indices = self.positions.getIntersections(p1, p2)
509 return [t+self.getFirstInstant() for t in indices] 514 return [t+self.getFirstInstant() for t in indices]
510 515
511 def predictPosition(self, instant, deltaT, externalAcceleration = Point(0,0)): 516 def predictPosition(self, instant, nTimeSteps, externalAcceleration = Point(0,0)):
512 '''Predicts the position of object at instant+deltaT, 517 '''Predicts the position of object at instant+deltaT,
513 at constant speed''' 518 at constant speed'''
514 return self.getPositionAtInstant(instant) + self.getVelocityAtInstant(instant).multiply(deltaT) + externalAcceleration.multiply(deltaT**2) 519 return Point.predictPosition(nTimeSteps, self.getPositionAtInstant(instant), self.getVelocityAtInstant(instant), externalAcceleration)
515 520
516 @staticmethod 521 @staticmethod
517 def collisionCourseDotProduct(movingObject1, movingObject2, instant): 522 def collisionCourseDotProduct(movingObject1, movingObject2, instant):
518 'A positive result indicates that the road users are getting closer' 523 'A positive result indicates that the road users are getting closer'
519 deltap = movingObject1.getPositionAtInstant(instant)-movingObject2.getPositionAtInstant(instant) 524 deltap = movingObject1.getPositionAtInstant(instant)-movingObject2.getPositionAtInstant(instant)
533 figure() 538 figure()
534 for obj in objects: 539 for obj in objects:
535 obj.draw(colors.get(obj.userType)) 540 obj.draw(colors.get(obj.userType))
536 axis('equal') 541 axis('equal')
537 542
538
539 # need for a class representing the indicators, their units, how to print them in graphs...
540 class TemporalIndicator:
541 '''Class for temporal indicators
542 i.e. indicators that take a value at specific instants
543
544 values should be
545 * a dict, for the values at specific time instants
546 * or a list with a time interval object if continuous measurements
547
548 it should have more information like name, unit'''
549
550 def __init__(self, name, values, timeInterval=None):
551 self.name = name
552 self.isCosine = name.find('Cosine')
553 self.values = values
554 self.timeInterval = timeInterval
555 if timeInterval:
556 assert len(values) == timeInterval.length()
557
558 def empty(self):
559 return len(self.values) == 0
560
561 def __getitem__(self, i):
562 if self.timeInterval:
563 if self.timeInterval.contains(i):
564 return self.values[i-self.timeInterval.first]
565 else:
566 if i in self.values.keys():
567 return self.values[i]
568 return None # default
569
570 def __iter__(self):
571 self.iterInstantNum = 0 # index in the interval or keys of the dict
572 return self
573
574 def next(self):
575 if self.iterInstantNum >= len(self.values):#(self.timeInterval and self.iterInstantNum>=self.timeInterval.length())\
576 # or (self.iterInstantNum >= self.values)
577 raise StopIteration
578 else:
579 self.iterInstantNum += 1
580 if self.timeInterval:
581 return self.values[self.iterInstantNum-1]
582 else:
583 return self.values.values()[self.iterInstantNum-1]
584
585 def getTimeInterval(self):
586 if not self.timeInterval and type(self.values)==dict:
587 instants = self.values.keys()
588 if instants:
589 self.timeInterval = TimeInterval(instants[0], instants[-1])
590 else:
591 self.timeInterval = TimeInterval()
592 return self.timeInterval
593
594 def getValues(self):
595 if self.timeInterval:
596 return self.values
597 else:
598 return self.values.values()
599
600 def getAngleValues(self):
601 '''if the indicator is a function of an angle,
602 transform it to an angle (eg cos)
603 (no transformation otherwise)'''
604 from numpy import arccos
605 values = self.getValues()
606 if self.isCosine >= 0:
607 return [arccos(c) for c in values]
608 else:
609 return values
610
611 class SeverityIndicator(TemporalIndicator):
612 '''Class for severity indicators
613 field mostSevereIsMax is True
614 if the most severe value taken by the indicator is the maximum'''
615
616 def __init__(self, name, values, timeInterval=None, mostSevereIsMax=True, ignoredValue = None):
617 TemporalIndicator.__init__(self, name, values, timeInterval)
618 self.mostSevereIsMax = mostSevereIsMax
619 self.ignoredValue = ignoredValue
620
621 def getMostSevereValue(self, minNInstants=1):
622 from matplotlib.mlab import find
623 from numpy.core.multiarray import array
624 from numpy.core.fromnumeric import mean
625 values = array(self.values.values())
626 if self.ignoredValue:
627 indices = find(values != self.ignoredValue)
628 else:
629 indices = range(len(values))
630 if len(indices) >= minNInstants:
631 values = sorted(values[indices], reverse = self.mostSevereIsMax) # inverted if most severe is max -> take the first values
632 return mean(values[:minNInstants])
633 else:
634 return None
635
636 # functions to aggregate discretized maps of indicators
637 # TODO add values in the cells between the positions (similar to discretizing vector graphics to bitmap)
638
639 def indicatorMap(indicatorValues, trajectory, squareSize):
640 '''Returns a dictionary
641 with keys for the indices of the cells (squares)
642 in which the trajectory positions are located
643 at which the indicator values are attached
644
645 ex: speeds and trajectory'''
646
647 from numpy import floor, mean
648 assert len(indicatorValues) == trajectory.length()
649 indicatorMap = {}
650 for k in xrange(trajectory.length()):
651 p = trajectory[k]
652 i = floor(p.x/squareSize)
653 j = floor(p.y/squareSize)
654 if indicatorMap.has_key((i,j)):
655 indicatorMap[(i,j)].append(indicatorValues[k])
656 else:
657 indicatorMap[(i,j)] = [indicatorValues[k]]
658 for k in indicatorMap.keys():
659 indicatorMap[k] = mean(indicatorMap[k])
660 return indicatorMap
661
662 def indicatorMapFromPolygon(value, polygon, squareSize):
663 '''Fills an indicator map with the value within the polygon
664 (array of Nx2 coordinates of the polygon vertices)'''
665 import matplotlib.nxutils as nx
666 from numpy.core.multiarray import array, arange
667 from numpy import floor
668
669 points = []
670 for x in arange(min(polygon[:,0])+squareSize/2, max(polygon[:,0]), squareSize):
671 for y in arange(min(polygon[:,1])+squareSize/2, max(polygon[:,1]), squareSize):
672 points.append([x,y])
673 inside = nx.points_inside_poly(array(points), polygon)
674 indicatorMap = {}
675 for i in xrange(len(inside)):
676 if inside[i]:
677 indicatorMap[(floor(points[i][0]/squareSize), floor(points[i][1]/squareSize))] = 0
678 return indicatorMap
679
680 def indicatorMapFromAxis(value, limits, squareSize):
681 '''axis = [xmin, xmax, ymin, ymax] '''
682 from numpy.core.multiarray import arange
683 from numpy import floor
684 indicatorMap = {}
685 for x in arange(limits[0], limits[1], squareSize):
686 for y in arange(limits[2], limits[3], squareSize):
687 indicatorMap[(floor(x/squareSize), floor(y/squareSize))] = value
688 return indicatorMap
689
690 def combineIndicatorMaps(maps, squareSize, combinationFunction):
691 '''Puts many indicator maps together
692 (averaging the values in each cell
693 if more than one maps has a value)'''
694 #from numpy import mean
695 indicatorMap = {}
696 for m in maps:
697 for k,v in m.iteritems():
698 if indicatorMap.has_key(k):
699 indicatorMap[k].append(v)
700 else:
701 indicatorMap[k] = [v]
702 for k in indicatorMap.keys():
703 indicatorMap[k] = combinationFunction(indicatorMap[k])
704 return indicatorMap
705 543
706 if __name__ == "__main__": 544 if __name__ == "__main__":
707 import doctest 545 import doctest
708 import unittest 546 import unittest
709 suite = doctest.DocFileSuite('tests/moving.txt') 547 suite = doctest.DocFileSuite('tests/moving.txt')