Mercurial Hosting > traffic-intelligence
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') |