Mercurial > hg > nsaunier > 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') |
