in robogym/envs/dactyl/common/cube_manipulator.py [0:0]
def snap_rotate_face_with_threshold(self, axis, side, angle, threshold=0.1):
"""
Rotate face of a cube in a "snapping" fashion, correcting the cube along the way.
Underlying assumption: cube is already in a "snapped", physically-aligned state
Threshold is threshold in radians which decides maximum angle we want to snap over.
If the angle required to move the face to be snapped is larger than that, the cube
will remain locked and won't rotate.
"""
qpos = self.sim.data.qpos
drivers = rotation.normalize_angles(
qpos[[self.joints_qpos_map[x] for x in self.drivers]]
)
perpendicular_axes = sorted({0, 1, 2} - {axis})
transaction = []
abort = False
for other_axis in perpendicular_axes:
for other_side in range(2):
other_driver_idx = other_axis * 2 + other_side
other_angle = drivers[other_driver_idx]
other_angle_aligned = rotation.round_to_straight_angles(other_angle)
other_angle_diff = rotation.normalize_angles(
other_angle_aligned - other_angle
)
if (
np.abs(other_angle_diff) < np.abs(angle)
and np.abs(other_angle_diff) < threshold
):
transaction.append((other_axis, other_side, other_angle_diff))
else:
abort = True
if not abort:
# Snap other faces
for other_axis, other_side, angle_diff in transaction:
self.rotate_face(other_axis, other_side, angle_diff)
# rotate the actual face
self.rotate_face(axis, side, angle)