예제 #1
0
 def test_move(self):
     position = (42, 2)
     obstacle = Obstacle(position=position, width=2, length=10)
     after = obstacle.move()
     self.assertEqual(position, after)
     self.assertEqual(position, obstacle.position)
     self.assertEqual(2, obstacle.width)
     self.assertEqual(10, obstacle.length)
예제 #2
0
 def test_tryAvoidObstacle(self, mocked_shuffled):
     mocked_shuffled.side_effect = lambda xs: xs
     # No obstacles on the road.
     road = Mock(lane_width=1)
     road.getNextVehicle.return_value = -1, None
     car = ConventionalCar(position=(42, 1), velocity=5, road=road)
     self.assertFalse(car._tryAvoidObstacle())
     # Not an obstacle on the road in front.
     road = Mock(lane_width=1)
     road.getNextVehicle.return_value = 44, Mock()
     car = ConventionalCar(position=(42, 1), velocity=5, road=road)
     self.assertFalse(car._tryAvoidObstacle())
     # Obstacle is far away.
     road = Mock(lane_width=1)
     road.getNextVehicle.return_value = 120, Obstacle(position=(120, 2),
                                                      length=1,
                                                      width=1)
     car = ConventionalCar(position=(42, 1), velocity=5, road=road)
     self.assertFalse(car._tryAvoidObstacle())
     # Lanes not changed.
     road = Mock(lane_width=1)
     road.getNextVehicle.return_value = 44, Obstacle(position=(44, 2),
                                                     length=1,
                                                     width=1)
     car = ConventionalCar(position=(42, 1), velocity=5, road=road)
     car._canAvoid = Mock(return_value=False)
     car._avoid = Mock()
     self.assertFalse(car._tryAvoidObstacle())
     car._avoid.assert_not_called()
     self.assertEqual(car.position, (42, 1))
     # Change to the first available lane.
     road = Mock(lane_width=1)
     road.getNextVehicle.return_value = 44, Obstacle(position=(44, 2),
                                                     length=1,
                                                     width=1)
     car = ConventionalCar(position=(42, 1), velocity=5, road=road)
     car._canAvoid = Mock(return_value=True)
     car._avoid = Mock()
     self.assertTrue(car._tryAvoidObstacle())
     car._avoid.assert_called_once()
     self.assertEqual(car.position, (42, 0))
     # Change to the second available lane.
     road = Mock(lane_width=1)
     road.getNextVehicle.return_value = 44, Obstacle(position=(44, 2),
                                                     length=1,
                                                     width=1)
     car = ConventionalCar(position=(42, 1), velocity=5, road=road)
     car._avoid = Mock()
     car._canAvoid = Mock(side_effect=[False, True])
     self.assertTrue(car._tryAvoidObstacle())
     car._avoid.assert_called_once()
     self.assertEqual(car.position, (42, 2))
예제 #3
0
    def _tryChangeEmergency(self) -> bool:
        '''
        Try changing the lane to create an emergency corridor.
        :return: if vehicle performed an emergency action.
        '''
        emergency = self._getEmergency()
        changeValue = self.road.lane_width // 2
        # If there is no emergency or already avoiding the emergency, continue.
        if emergency is None:
            if self.road.isSingleLane(self):
                return False
            else:
                _, absoluteLane = self.road.getAbsolutePosition(self.position)
                change = changeValue if absoluteLane == -1 else -changeValue
                # When coming back always get priority.
                return self._tryAvoidWithChange(Obstacle((-1, -1), 0, 0),
                                                change)

        # If already creating emergency corridor don't move.
        if not self.road.isSingleLane(self):
            return True
        # Decelerate slowly, cannot switch lanes when the speed is too high.
        self.velocity = max(1, self.velocity - 1)
        if self.velocity > 2:
            return True
        # Destination lane depends on the road position.
        _, absoluteLane = self.road.getAbsolutePosition(self.position)
        change = -changeValue if absoluteLane == 0 else changeValue
        self._tryAvoidWithChange(emergency, change)
        return True
예제 #4
0
def addObstacle(road: Road, obstacle: ObstacleValue) -> None:
    lane, begin, end = obstacle
    if not inBounds(lane, 0, road.lanes_count):
        raise ValueError(f'invalid obstacle, lane {lane} is not on the road')
    if not inBounds(begin, 0, road.length) or not inBounds(
            end, 0, road.length):
        raise ValueError(
            f'invalid obstacle, position {(begin, end)} is not on the road')

    length = end - begin + 1
    width = road.lane_width
    position = road.getRelativePosition(position=(end, lane))
    obstacle = Obstacle(position=position, width=width, length=length)
    road.addVehicle(obstacle)
예제 #5
0
 def test_canAvoidObstacle(self):
     # No space on a nearby lane.
     car = Car(position=(0, 0), velocity=1, road=Mock())
     car._isChangePossible = Mock(return_value=False)
     self.assertFalse(car._canAvoid(obstacle=Mock(), destination=(0, 1)))
     # No nearby vehicles on the destination lane.
     car = Car(position=(0, 0), velocity=1, road=Mock())
     car._isChangePossible = Mock(return_value=True)
     car._isChangeSafe = Mock(return_value=True)
     self.assertTrue(car._canAvoid(obstacle=Mock(), destination=(0, 1)))
     # Vehicle on the destination lane is a car willing to zip.
     road = Mock()
     other = Car(position=(0, 1), velocity=1, road=road)
     road.getPreviousVehicle.return_value = 0, other
     car = Car(position=(1, 0), velocity=1, road=road)
     car._isChangePossible = Mock(return_value=True)
     car._isChangeSafe = Mock(return_value=False)
     obstacle = Mock()
     self.assertNotIn(obstacle, other.zipped)
     self.assertTrue(car._canAvoid(obstacle=obstacle, destination=(1, 1)))
     # Vehicle on the destination lane is a static obstacle.
     road = Mock()
     other = Obstacle(position=(0, 1), length=1, width=1)
     road.getPreviousVehicle.return_value = 0, other
     car = Car(position=(1, 0), velocity=1, road=road)
     car._isChangePossible = Mock(return_value=True)
     car._isChangeSafe = Mock(return_value=False)
     self.assertTrue(car._canAvoid(obstacle=obstacle, destination=(1, 1)))
     # Vehicle on the destination lane is a car not willing to zip.
     road = Mock()
     other = Car(position=(0, 1), velocity=1, road=road)
     road.getPreviousVehicle.return_value = 0, other
     car = Car(position=(1, 0), velocity=1, road=road)
     car._isChangePossible = Mock(return_value=True)
     car._isChangeSafe = Mock(return_value=False)
     obstacle = Mock()
     other.zipped = {obstacle}
     self.assertFalse(car._canAvoid(obstacle=obstacle, destination=(1, 1)))
예제 #6
0
 def getVehicle(self, position: Position) -> Obstacle:
     return Obstacle(position=position, width=1, length=1)
예제 #7
0
    def test_tryAvoidObstacle(self):
        # No obstacles on the road.
        road = Mock(lane_width=1)
        road.getNextVehicle.return_value = -1, None
        car = AutonomousCar(position=(42, 1), velocity=5, road=road)
        self.assertFalse(car._tryAvoidObstacle())
        # Not an obstacle on the road in front.
        road = Mock(lane_width=1)
        road.getNextVehicle.return_value = 44, Mock()
        car = AutonomousCar(position=(42, 1), velocity=5, road=road)
        self.assertFalse(car._tryAvoidObstacle())
        # Obstacle is far away.
        road = Mock(lane_width=1)
        road.getNextVehicle.return_value = 120, Obstacle(position=(120, 2),
                                                         length=1,
                                                         width=1)
        car = AutonomousCar(position=(42, 1), velocity=5, road=road)
        self.assertFalse(car._tryAvoidObstacle())

        def mock_getMaxSpeed(prev: int, next: int,
                             other: int) -> typing.Callable[[Position], int]:
            def f(position: Position) -> int:
                if position == (0, 0):
                    return prev
                if position == (0, 2):
                    return next
                return other

            return f

        road = Mock(lane_width=1)
        road.getNextVehicle.return_value = 5, Obstacle(position=(5, 1),
                                                       length=1,
                                                       width=1)
        # Unable to change lanes.
        car = AutonomousCar(position=(0, 1), velocity=5, road=road)
        car._canAvoid = Mock(return_value=False)
        car._avoid = Mock()
        car._getMaxSpeed = Mock(side_effect=mock_getMaxSpeed(5, 4, 3))
        self.assertFalse(car._tryAvoidObstacle())
        car._avoid.assert_not_called()
        self.assertEqual(car.position, (0, 1))
        # Previous lane is the fastest.
        car = AutonomousCar(position=(0, 1), velocity=5, road=road)
        car._canAvoid = Mock(return_value=True)
        car._avoid = Mock()
        car._getMaxSpeed = Mock(side_effect=mock_getMaxSpeed(5, 4, 3))
        self.assertTrue(car._tryAvoidObstacle())
        car._avoid.assert_called_once()
        self.assertEqual(car.position, (0, 0))
        # Next lane is the fastest.
        car = AutonomousCar(position=(0, 1), velocity=5, road=road)
        car._canAvoid = Mock(return_value=True)
        car._avoid = Mock()
        car._getMaxSpeed = Mock(side_effect=mock_getMaxSpeed(4, 5, 3))
        self.assertTrue(car._tryAvoidObstacle())
        car._avoid.assert_called_once()
        self.assertEqual(car.position, (0, 2))
        # Current lane is the fastest.
        car = AutonomousCar(position=(0, 1), velocity=5, road=road)
        car._canAvoid = Mock(return_value=True)
        car._avoid = Mock()
        car._getMaxSpeed = Mock(side_effect=mock_getMaxSpeed(4, 3, 5))
        self.assertFalse(car._tryAvoidObstacle())
        car._avoid.assert_not_called()
        self.assertEqual(car.position, (0, 1))
        # Best lane is the same speed as current.
        car = AutonomousCar(position=(0, 1), velocity=5, road=road)
        car._canAvoid = Mock(return_value=True)
        car._avoid = Mock()
        car._getMaxSpeed = Mock(side_effect=mock_getMaxSpeed(5, 4, 5))
        self.assertFalse(car._tryAvoidObstacle())
        car._avoid.assert_not_called()
        self.assertEqual(car.position, (0, 1))