def test_trackWaiting(self): road = Mock() vehicles: typing.List[Vehicle] = [] for x in range(10): vehicle = Mock() vehicle.position = (x, 0) vehicle.last_position = (x, 0) vehicles.append(vehicle) road.getAllActiveVehicles = lambda: vehicles tracker = Tracker(simulator=Mock(road=road)) # No vehicles matching the predicate. result = tracker._trackWaiting(lambda _: False) expected = AverageResult(value=0, count=0) self.assertEqual(result, expected, '{} != {}'.format(str(result), str(expected))) # All vehicles matching the predicate. result = tracker._trackWaiting(lambda _: True) expected = AverageResult(value=10, count=10) self.assertEqual(result, expected, '{} != {}'.format(str(result), str(expected))) # Some vehicles matching the predicate. def isEven(vehicle: Vehicle) -> bool: x, _ = vehicle.position return x % 2 == 0 result = tracker._trackWaiting(isEven) expected = AverageResult(value=5, count=5) self.assertEqual(result, expected, '{} != {}'.format(str(result), str(expected)))
def _drawStatistics(self, tracker: Tracker) -> None: rect = (0, self.height, self.width, self.STATS_SIZE) pygame.draw.rect(self.screen, CL_BACKGROUND, rect) font = pygame.font.Font(pygame.font.get_default_font(), self.SIZE) statistics = { 'steps': tracker.steps, 'velocity': tracker.getAverageVelocity(VehicleType.ANY), 'velocity_autonomous': tracker.getAverageVelocity(VehicleType.AUTONOMOUS), 'velocity_conventional': tracker.getAverageVelocity(VehicleType.CONVENTIONAL), 'velocity_emergency': tracker.getAverageVelocity(VehicleType.EMERGENCY) } text = font.render( 'Steps={steps} | Velocity={velocity:.2f} | ' 'Conventional Velocity={velocity_conventional:.2f} | ' 'Autonomous Velocity={velocity_autonomous:.2f} | ' 'Emergency Velocity={velocity_emergency:.2f}'.format( **withOptionalFormat(statistics)), True, (0, 0, 0)) rect = text.get_rect() rect.center = (self.width // 2, self.height + self.STATS_SIZE // 2) self.screen.blit(text, rect)
def test_trackThroughput(self): vehicles: typing.List[Vehicle] = [Mock(velocity=v) for v in range(10)] road = Mock(removed=vehicles) tracker = Tracker(simulator=Mock(road=road)) # No vehicles matching the predicate. result = tracker._trackThroughput(lambda _: False) self.assertEqual(result, 0) # All vehicles matching the predicate. result = tracker._trackThroughput(lambda _: True) self.assertEqual(result, 10) # Some vehicles matching the predicate. def isEven(vehicle): return vehicle.velocity % 2 == 0 result = tracker._trackThroughput(isEven) self.assertEqual(result, 5)
def test_trackDecelerations(self): road = Mock() vehicles: typing.List[Vehicle] = [] for velocity in range(10): vehicle = Mock(spec=Car) vehicle.velocity = velocity vehicle.path = [((0, 0), 12)] vehicles.append(vehicle) road.getAllActiveVehicles = lambda: vehicles tracker = Tracker(simulator=Mock(road=road)) # No vehicles matching the predicate. result = tracker._trackDecelerations(lambda _: False) expected = AverageResult(value=0, count=0) self.assertEqual(result, expected, '{} != {}'.format(str(result), str(expected))) # All vehicles matching the predicate. result = tracker._trackDecelerations(lambda _: True) expected = AverageResult(value=10, count=10) self.assertEqual(result, expected, '{} != {}'.format(str(result), str(expected))) # Some vehicles matching the predicate. def isEven(vehicle: Vehicle) -> bool: return vehicle.velocity % 2 == 0 result = tracker._trackDecelerations(isEven) expected = AverageResult(value=5, count=5) self.assertEqual(result, expected, '{} != {}'.format(str(result), str(expected))) # Test decelerations filter. road = Mock() vehicles: typing.List[Vehicle] = [] # Vehicles which decelerated quickly. for _ in range(10): vehicle = Mock(spec=Car) vehicle.velocity = 5 vehicle.path = [((0, 0), 10)] vehicles.append(vehicle) # Not cars, therefore should not be counted. for _ in range(10): vehicle = Mock(spec=Vehicle) vehicle.velocity = 5 vehicle.path = [((0, 0), 10)] vehicles.append(vehicle) # Vehicles which did not decelerate quickly. for _ in range(10): vehicle = Mock(spec=Car) vehicle.velocity = 9 vehicle.path = [((0, 0), 10)] vehicles.append(vehicle) road.getAllActiveVehicles = lambda: vehicles tracker = Tracker(simulator=Mock(road=road)) result = tracker._trackDecelerations(lambda _: True) expected = AverageResult(value=10, count=20) self.assertEqual(result, expected, '{} != {}'.format(str(result), str(expected)))
def test_trackVelocity(self): vehicles: typing.List[Vehicle] = [Mock(velocity=v) for v in range(10)] road = Mock() road.getAllActiveVehicles = lambda: vehicles tracker = Tracker(simulator=Mock(road=road)) # No vehicles matching the predicate. result = tracker._trackVelocity(lambda _: False) expected = AverageResult(value=0, count=0) self.assertEqual(result, expected, '{} != {}'.format(str(result), str(expected))) # All vehicles matching the predicate. result = tracker._trackVelocity(lambda _: True) expected = AverageResult(value=45, count=10) self.assertEqual(result, expected, '{} != {}'.format(str(result), str(expected))) # Some vehicles matching the predicate. def isEven(vehicle): return vehicle.velocity % 2 == 0 result = tracker._trackVelocity(isEven) expected = AverageResult(value=20, count=5) self.assertEqual(result, expected, '{} != {}'.format(str(result), str(expected)))
def test_trackPercentage(self): road = Mock() vehicles: typing.List[Vehicle] = [] for x in range(100): vehicles.append(Mock(position=(x, 0))) road.getAllActiveVehicles = lambda: vehicles tracker = Tracker(simulator=Mock(road=road)) def make_filter(xfilter: typing.Callable[[int], bool]) -> Filter: def f(vehicle: Vehicle) -> bool: x, _ = vehicle.position return xfilter(x) return f no_filter = make_filter(lambda _: True) x50_filter = make_filter(lambda x: x < 50) x25_filter = make_filter(lambda x: x < 25) # Check count working. result = tracker._trackPercentage(x50_filter, no_filter) expected = AverageResult(value=50, count=50) self.assertEqual(result, expected, '{} != {}'.format(str(result), str(expected))) # Check value working. result = tracker._trackPercentage(no_filter, x50_filter) expected = AverageResult(value=50, count=100) self.assertEqual(result, expected, '{} != {}'.format(str(result), str(expected))) # More potential count than values. result = tracker._trackPercentage(x50_filter, x25_filter) expected = AverageResult(value=25, count=50) self.assertEqual(result, expected, '{} != {}'.format(str(result), str(expected))) # More potential values than count. result = tracker._trackPercentage(x25_filter, x50_filter) expected = AverageResult(value=25, count=25) self.assertEqual(result, expected, '{} != {}'.format(str(result), str(expected)))
def run(self, speed: float = 100., refresh: int = 60, buffer: int = 1) -> None: # Initialize parameters. self.speed = speed self.passed = 0 self.running = True self.clock = pygame.time.Clock() # Initialize statistics. with Tracker(simulator=self.simulator, buffer_size=buffer) as tracker: while self.running: self._updateEvents() if self._updateTime(): self.simulator.step() self.screen.fill(CL_ROAD) self._drawVehicles(self.passed / self.speed) self._drawStatistics(tracker) pygame.display.flip() pygame.display.update() self.clock.tick(refresh) pygame.quit()
def run(self, steps: int, skip: int, statistics: Statistics, no_charts: bool, output: typing.Optional[str] = None, prefix: str = '') -> None: with Collector(simulator=self.simulator, statistics=statistics, skip=skip) as collector, \ Tracker(simulator=self.simulator, buffer_size=steps - skip) as tracker: def show_stats(_: typing.Any) -> str: return '{:.2f}|{:.2f}|{:.2f} (Average|Conventional|Autonomous)'.format( OptionalFormat(tracker.getAverageVelocity(VehicleType.ANY)), OptionalFormat(tracker.getAverageVelocity(VehicleType.CONVENTIONAL)), OptionalFormat(tracker.getAverageVelocity(VehicleType.AUTONOMOUS)) ) with click.progressbar(range(steps), steps, item_show_func=show_stats) as bar: for _ in bar: self.simulator.step() if statistics & Statistics.THROUGHPUT: click.secho('Generating throughput charts', fg='blue') throughput = HeatMap( data=collector.getThrougput(), title='Throughput', max_value=3) if output is not None: throughput.save(path=output, prefix=f'{prefix}_throughput', only_data=no_charts) else: throughput.show(only_data=no_charts) if statistics & Statistics.HEAT_MAP: click.secho('Generating traffic density charts', fg='blue') heat_map = HeatMap( data=collector.getHeatMap(), title='Traffic density', max_value=1) if output is not None: heat_map.save(path=output, prefix=f'{prefix}_traffic', only_data=no_charts) else: heat_map.show(only_data=no_charts) if statistics & Statistics.VELOCITY: click.secho('Generating speed charts', fg='blue') def mapper(x: AverageResult) -> float: return x.toZeroFloat() velocity = \ [list(map(mapper, lane)) for lane in collector.velocity] autonomous = \ [list(map(mapper, lane)) for lane in collector.velocity_autonomous] conventional = \ [list(map(mapper, lane)) for lane in collector.velocity_conventional] velocity = VelocityChart( car=velocity, autonomous=autonomous, conventional=conventional) if output is not None: velocity.save(path=output, prefix=f'{prefix}_speed', only_data=no_charts) else: velocity.show(only_data=no_charts) if statistics & Statistics.TRAVEL_TIME: click.secho('Generating travel time histogram', fg='blue') df = pd.DataFrame(columns=['x', 'y', 'type']) n = sum(collector.travel) na = sum(collector.travel_autonomous) nc = sum(collector.travel_conventional) for i in range(collector._travelLimit): df = df.append({'x': i, 'y': collector.travel[i] / n * 100, 'type': 'All'}, ignore_index=True) df = df.append({'x': i, 'y': collector.travel_autonomous[i] / na * 100, 'type': 'Autonomous'}, ignore_index=True) df = df.append({'x': i, 'y': collector.travel_conventional[i] / nc * 100, 'type': 'Conventional'}, ignore_index=True) travel = TravelHistogram(data=df) if output is not None: travel.save(path=output, prefix=prefix, only_data=no_charts) else: travel.show(only_data=no_charts) click.secho('Generating average statistics', fg='blue') data = tracker.getAverageData() if output is not None: data.to_csv(os.path.join(output, f'{prefix}_average.csv'), index=False) else: click.echo(data.to_csv(index=False))