projection
Rotation-manifold projection layers shared across RL frameworks.
Control modes and their action dimensions::
cmd_ctatt_euler → 4D [thrust, roll, pitch, yaw] cmd_ctatt_rotvec → 4D [thrust, rx, ry, rz] cmd_ctatt_quat → 5D [thrust, qx, qy, qz, qw] cmd_ctatt_rotmat → 10D [thrust, r00..r22]
Projection layers ensure the rotation component of the policy output lies on a valid SO(3) manifold. Available variants per rotation type:
============== ============================================================
Euler / rotvec EulerProjection (tanh clamp)
Quaternion QuatProjection (tanh + L2-normalize)
QuatPlusProjection (tanh + sigmoid w + L2-normalize)
QuatOffsetProjection (offset by identity quat)
Rotation RotmatProjection (tanh + SVD-orthogonalize)
matrix RotmatOffsetProjection (offset by identity matrix)
============== ============================================================
Classes:
| Name | Description |
|---|---|
EulerProjection |
Bounded projection for euler-angle or rotation-vector actions. |
QuatProjection |
L2-normalize the 4-D quaternion at indices [1:5]. |
QuatPlusProjection |
Quaternion projection with double-cover elimination. |
QuatOffsetProjection |
Quaternion projection centred at the identity rotation. |
RotmatProjection |
SVD-orthogonalize the 9-D rotation-matrix at indices [1:10]. |
RotmatOffsetProjection |
Rotation-matrix projection centred at the identity matrix. |
EulerProjection
Bases: Module
Bounded projection for euler-angle or rotation-vector actions.
Applies tanh to clamp all components to [-1, 1] so that
the environment action scaling (e.g. multiplying by
attitude_range) stays within the expected range. No geometric
constraint is needed beyond clipping.
References
so3_primer.rotations.modules.ddpg.activations — plain
nn.Tanh() used for euler / tangent quadrotor actors.
Methods:
| Name | Description |
|---|---|
forward |
Clamp x to |
forward
forward(x: Tensor) -> torch.Tensor
Clamp x to [-1, 1] via tanh.
QuatProjection
Bases: Module
L2-normalize the 4-D quaternion at indices [1:5].
Applies tanh to bound all components, then normalizes the
quaternion slice to unit length. The thrust channel (index 0) is
passed through unchanged.
This is the simplest quaternion projection — the double-cover
ambiguity (q and -q represent the same rotation) is left
for the policy to resolve.
References
so3_primer.rotations.modules.ddpg.activations.QuatQuadrotor
Methods:
| Name | Description |
|---|---|
forward |
Normalize quaternion slice of x. |
forward
forward(x: Tensor) -> torch.Tensor
Normalize quaternion slice of x.
QuatPlusProjection
Bases: Module
Quaternion projection with double-cover elimination.
The scalar component w is mapped through a sigmoid channel
(tanh → [0, 1]) so that the output quaternion always satisfies
w ≥ 0, breaking the q ≡ -q ambiguity. The vector
components (x, y, z) use standard tanh. This mirrors
so3_primer.rotations.modules.ddpg.activations.QuatPlusQuadrotor
and so3_primer.rotations.modules.ppo.std.QuatPlusQuadrotorActor.
Methods:
| Name | Description |
|---|---|
forward |
Match the primer quadrotor quat-plus head. |
forward
forward(x: Tensor) -> torch.Tensor
Match the primer quadrotor quat-plus head.
QuatOffsetProjection
QuatOffsetProjection()
Bases: Module
Quaternion projection centred at the identity rotation.
Adds the identity quaternion [0, 0, 0, 1] to the policy output,
clamps to [-1, 1], then L2-normalizes. This centres the action
distribution on zero-rotation so that a zero policy output commands
hover attitude.
References
so3_primer.rotations.modules.ddpg.activations.QuatQuadrotorOffset
Register the identity-quaternion offset buffer.
Methods:
| Name | Description |
|---|---|
forward |
Offset x by identity quaternion, then normalize. |
forward
forward(x: Tensor) -> torch.Tensor
Offset x by identity quaternion, then normalize.
RotmatProjection
Bases: Module
SVD-orthogonalize the 9-D rotation-matrix at indices [1:10].
Reshapes the matrix slice to (..., 3, 3), applies tanh to
bound elements, then computes the least-squares orthogonal
Procrustes projection via SVD. A determinant correction ensures
the result lies in SO(3) (det=+1) rather than O(3).
The thrust channel (index 0) is passed through unchanged.
References
so3_primer.rotations.modules.ddpg.activations.MatrixQuadrotor
Methods:
| Name | Description |
|---|---|
forward |
SVD-project the matrix slice of x onto SO(3). |
forward
forward(x: Tensor) -> torch.Tensor
SVD-project the matrix slice of x onto SO(3).
RotmatOffsetProjection
RotmatOffsetProjection()
Bases: Module
Rotation-matrix projection centred at the identity matrix.
Adds the flattened 3×3 identity to the policy output, clamps to
[-1, 1], then SVD-projects onto SO(3). A zero policy output
therefore commands hover attitude.
References
so3_primer.rotations.modules.ddpg.activations.MatrixQuadrotorOffset
Register the identity-matrix offset buffer.
Methods:
| Name | Description |
|---|---|
forward |
Offset x by identity matrix, then SVD-project. |
forward
forward(x: Tensor) -> torch.Tensor
Offset x by identity matrix, then SVD-project.