def from_pycuber()

in robogym/envs/dactyl/common/cube_manipulator.py [0:0]


    def from_pycuber(self, cube: pycuber.Cube):
        """
        Set cubelet positions based on the pycuber cube state

        Image copied from rubik_utils.py

                        Z(+) Up (Yellow)                     Faces:
                        |                                    +X: Right (Orange)
                        |          / Y(+) Back (Blue)        -X: Left (Red)
                    _____________ /                          +Y: Back (Blue)
                   /            /|                           -Y: Front (Green)
                  /            / |                           +Z: Up (Yellow)
                 /            /  |                           -Z: Down (White)
                /____________/   |
                |            |   |____ X(+) Right (Orange)
       Left     |            |   /
       (Red)    |   Front    |  /
                |  (Green)   | /
                |____________|/
                         Down (White)
        """
        # First, we zero out the cubelet positions to reset all of the cube state
        self.sim.data.qpos[self.joints_qpos_idx] = 0.0

        for cubelet in cube.children:
            if isinstance(cubelet, pycuber.cube.Corner):

                mtx = np.zeros((3, 3))

                for element in cubelet.location:
                    # Example: Corner(B: [r], U: [y], L: [g])
                    # Original location: red, yellow, green: -X, +Z, -Y
                    # Current location back, up, left: +Y, +Z, -X
                    # Mapping: -X -> +Y, +Z -> +Z, -Y -> -X
                    axis, sign = PYCUBER_COLOR_AXES_DESCRIPTIONS[
                        cubelet[element].colour
                    ]
                    vector = PYCUBER_LOCATION_AXES[element]

                    mtx[:, axis] = sign * vector

                euler_angles = rotation.mat2euler(mtx)

                original_location: np.array = sum(
                    PYCUBER_COLOR_AXES[x.colour] for x in cubelet.children
                )
                idx = (
                    (original_location[0] + 1) * 9
                    + (original_location[1] + 1) * 3
                    + original_location[2]
                    + 1
                )

                # Set the euler angles
                self.sim.data.qpos[
                    self.cubelet_meta_info[idx]["euler_qpos"]
                ] = euler_angles
            elif isinstance(cubelet, pycuber.cube.Edge):
                # Example:
                # Edge(R: [o], B: [g])
                # original location: orange-green +X, -Y, (1, -1, 0)
                # current location: right-back, +X, +Y (1, 1, 0)
                original_location = sum(
                    PYCUBER_COLOR_AXES[x.colour] for x in cubelet.children
                )

                mtx = np.zeros((3, 3))

                axes = {0, 1, 2}

                for element in cubelet.location:
                    axis, sign = PYCUBER_COLOR_AXES_DESCRIPTIONS[
                        cubelet[element].colour
                    ]
                    vector = PYCUBER_LOCATION_AXES[element]

                    mtx[:, axis] = sign * vector
                    axes.remove(axis)

                remaining_axis = axes.pop()

                # Antisymmetric tensor
                if remaining_axis == 0:
                    mtx[:, 0] = np.cross(mtx[:, 1], mtx[:, 2])
                elif remaining_axis == 1:
                    mtx[:, 1] = -np.cross(mtx[:, 0], mtx[:, 2])
                elif remaining_axis == 2:
                    mtx[:, 2] = np.cross(mtx[:, 0], mtx[:, 1])

                euler_angles = rotation.mat2euler(mtx)

                idx = (
                    (original_location[0] + 1) * 9
                    + (original_location[1] + 1) * 3
                    + original_location[2]
                    + 1
                )

                # Set the euler angles
                self.sim.data.qpos[
                    self.cubelet_meta_info[idx]["euler_qpos"]
                ] = euler_angles