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)
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))
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
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)
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)))
def getVehicle(self, position: Position) -> Obstacle: return Obstacle(position=position, width=1, length=1)
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))