def rotate(self, delta_angle, steps=10): """Rotate the player delta_angle degrees in horizontal plane.""" start = self.orientation target = np.array([start[0], start[1] + delta_angle, 0.0]) speed = self._rotation_speed(delta_angle, steps=steps) if np.abs(speed) < 1.: return actions = self._get_actions(_TURN_ACTION_NAME, speed) error_message = ('Failed to reach requested orientation. Start: {0}, ' 'target: {1}, current: {2}.') for _ in six.moves.range(steps): if self._env.is_running(): self._step(actions, 1) else: raise AssertionError( error_message.format(start[1], target[1], self.orientation[1])) if abs(math_utils.delta_angle_degrees( self.orientation[1], target[1])) >= _INTERNAL_ROTATION_TOLERANCE: if steps == 1: raise AssertionError( error_message.format(start[1], target[1], self.orientation[1])) else: self.rotate( math_utils.delta_angle_degrees(self.orientation[1], target[1]), steps=1)
def testLookAt(self): target_angles = np.random.uniform(360, size=(_TEST_TRIALS)) for target_angle in target_angles: self._controller.look_at_2d(target_angle) delta = math_utils.delta_angle_degrees(self._controller.orientation[1], target_angle) self.assertLess(abs(delta), game_controller.ROTATION_TOLERANCE)
def move_to(self, target_x, target_y, max_steps=2000): """Move the player to the target location.""" pos = self.position target = np.array([target_x, target_y, pos[2]]) direction = target - pos target_orientation = np.degrees(np.arctan2(direction[1], direction[0])) self.look_at_2d(target_orientation) for _ in xrange(max_steps): pos = self.position direction = target - pos distance = np.linalg.norm(direction) if distance < _SLOW_MOVE_DISTANCE: speed = np.linalg.norm(self.velocity) if speed > 0.0: self.stop() if distance < _INTERNAL_POSITION_TOLERANCE: break target_orientation = np.degrees(np.arctan2(direction[1], direction[0])) rotation_speed = self._rotation_speed( math_utils.delta_angle_degrees(self.orientation[1], target_orientation), steps=1) actions = self._get_empty_actions() self._set_action_value(actions, _TURN_ACTION_NAME, rotation_speed) self._set_action_value(actions, _MOVE_ACTION_NAME, 1) self._env.step(actions, 1) else: raise ('Failed to reach target in max steps.')
def move_to(self, target_x, target_y, max_steps=2000, max_speed=None): """Move the player to the target location.""" pos = self.position target = np.array([target_x, target_y, pos[2]]) if max_speed is None: max_speed = float('inf') direction = (target - pos)[:2] last_pos = np.array([float('inf'), float('inf'), float('inf')]) target_orientation = np.degrees(np.arctan2(direction[1], direction[0])) self.look_at_2d(target_orientation) blocked_frames_count = 0 for _ in six.moves.range(max_steps): move_action_value = 1 pos = self.position direction = (target - pos)[:2] distance = np.linalg.norm(direction) speed = np.linalg.norm(self.velocity[:2]) if distance < _SLOW_MOVE_DISTANCE: if speed > 0.0: self.stop() elif speed > max_speed: move_action_value = 0 if distance < _INTERNAL_POSITION_TOLERANCE: break if np.linalg.norm(last_pos - pos) < .1: blocked_frames_count += 1 if blocked_frames_count > 10: raise PathBlockedError( 'Failed to reach target. The path might be blocked.') else: blocked_frames_count = 0 last_pos = pos target_orientation = np.degrees(np.arctan2(direction[1], direction[0])) rotation_speed = self._rotation_speed( math_utils.delta_angle_degrees(self.orientation[1], target_orientation), steps=1) actions = self._get_empty_actions() self._set_action_value(actions, _TURN_ACTION_NAME, rotation_speed) self._set_action_value(actions, _MOVE_ACTION_NAME, move_action_value) self._step(actions, 1) else: raise AssertionError('Failed to reach target in max steps.')
def testStopping(self): for angle in [0.0, 90., 180., -90]: self._controller.look_at_2d(0.0) move_forward_action = self._controller._get_actions( game_controller._MOVE_ACTION_NAME, 1) for _ in six.moves.range(10): self._env.step(move_forward_action, 1) self._controller.look_at_2d(angle) num_steps_before_stopping = self._env.num_steps() self._controller.stop() num_steps_after_stopping = self._env.num_steps() self.assertLess(num_steps_after_stopping - num_steps_before_stopping, 15) delta = math_utils.delta_angle_degrees(self._controller.orientation[1], angle) self.assertLess(abs(delta), game_controller.ROTATION_TOLERANCE)
def look_at_2d(self, target_orientation, steps=10): """Rotate the player in horizontal plane towards the angle.""" delta_angle = math_utils.delta_angle_degrees(self.orientation[1], target_orientation) self.rotate(delta_angle, steps=steps)
def testDeltaAngleDegrees(self): self.assertAlmostEqual(math_utils.delta_angle_degrees(10., 20.), 10.) self.assertAlmostEqual(math_utils.delta_angle_degrees(20., 10.), -10.) self.assertAlmostEqual(math_utils.delta_angle_degrees(10., 350.), -20.) self.assertAlmostEqual(math_utils.delta_angle_degrees(350., 10.), 20.) self.assertAlmostEqual(math_utils.delta_angle_degrees(350., 10.), 20.) self.assertAlmostEqual(math_utils.delta_angle_degrees(10., 190.), -180.) self.assertAlmostEqual(math_utils.delta_angle_degrees(190., 10.), -180.) self.assertAlmostEqual(math_utils.delta_angle_degrees(10., 195.), -175.) self.assertAlmostEqual(math_utils.delta_angle_degrees(195., 10.), 175.) self.assertAlmostEqual(math_utils.delta_angle_degrees(-350., -10.), -20.) self.assertAlmostEqual(math_utils.delta_angle_degrees(-10., -350.), 20.)