Ejemplo n.º 1
0
    def goal_reachable(self, goal_state, current_state):
        """ Check if goal is in reach from current state."""
        relative_goal = self.relative_goal(goal_state, current_state)
        face_rotation_angles = relative_goal["cube_face_angle"]
        goal_type = goal_state["goal_type"]
        eps = 1e-6

        rounded_rotation_angles = rotation.round_to_straight_angles(
            np.abs(rotation.normalize_angles(face_rotation_angles)))

        rotated_faces = list(np.where(rounded_rotation_angles > eps)[0])

        if goal_type == "rotation":
            # When doing face rotation, three conditions should met:
            # 1. Goal face should face up
            # 2. Rounded rotation angle for goal face should be at most 90 degree.
            # 3. Rounded rotation angle for other faces should be 0.
            goal_face_idx = self._get_goal_action().face_idx
            face_up = cube_utils.face_up(self.mujoco_simulation.sim,
                                         self.face_geom_names)

            return (goal_face_idx == face_up and
                    rounded_rotation_angles[goal_face_idx] < np.pi / 2 + eps
                    and rotated_faces in ([], [goal_face_idx]))
        elif goal_type == "flip":
            # When doing flipping, rounded rotation angles should be 0.
            return len(rotated_faces) == 0
        else:
            raise ValueError('unknown goal_type "{}"'.format(goal_type))
Ejemplo n.º 2
0
    def next_goal(self, random_state, current_state):
        """ Generate a new goal from current cube goal state """
        cube_pos = current_state["cube_pos"]
        cube_quat = current_state["cube_quat"]
        cube_face = current_state["cube_face_angle"]

        # Success threshold parameters
        face_threshold = self.face_threshold()
        rot_threshold = self.success_threshold["cube_quat"]

        rounded_current_face = rotation.round_to_straight_angles(cube_face)

        # Face aligned - are faces in the current cube aligned within the threshold
        current_face_diff = rotation.normalize_angles(cube_face -
                                                      rounded_current_face)
        face_aligned = np.linalg.norm(current_face_diff,
                                      axis=-1) < face_threshold

        # Z aligned - is there a cube face looking up within the rotation threshold
        z_aligned = rotation.rot_xyz_aligned(cube_quat, rot_threshold)

        axis_nr, axis_sign = cube_utils.up_axis_with_sign(cube_quat)

        cube_aligned = face_aligned and z_aligned

        # Check if current state already meets goal state.
        if cube_aligned and self._is_goal_met(cube_face, face_threshold):
            # Step forward in goal sequence to get next goal.
            self._step_goal()

        goal_action = self._get_goal_action()

        if cube_aligned:
            # Choose index from the geoms that is highest on the z axis
            face_to_shift = cube_utils.face_up(self.mujoco_simulation.sim,
                                               self.face_geom_names)

            # Rotate face if the face to rotate for next goal is facing up.
            rotate_face = face_to_shift == goal_action.face_idx
        else:
            rotate_face = False

        if rotate_face:
            self.mujoco_simulation.target_model.rotate_face(
                face_to_shift // 2, face_to_shift % 2, goal_action.face_angle)

            goal_quat = cube_utils.align_quat_up(cube_quat)
            goal_face = self.goal_face_state
        else:  # need to flip cube

            # Rotate cube so that goal face is on the top. We currently apply
            # a deterministic transformation here that would get the goal face to the top,
            # which is _not_ the minimal possible orientation change, which may be
            # worth addressing in the future.
            goal_quat = self.goal_quat_for_face[goal_action.face_idx]

            # No need to rotate face, just align them.
            goal_face = rounded_current_face

        goal_quat = rotation.quat_normalize(goal_quat)

        return {
            "cube_pos": cube_pos,
            "cube_quat": goal_quat,
            "cube_face_angle": goal_face,
            "goal_type": "rotation" if rotate_face else "flip",
            "axis_nr": axis_nr,
            "axis_sign": axis_sign,
        }