Modified Rodrigues Parameters
The Modified Rodrigues Parameters (MRP) are defined by the following immutable structure:
struct MRP{T}
q1::T
q2::T
q3::T
endThe MRP is a 3-element parameterization of a rotation related to quaternions by a stereographic projection. Compared with CRP, it moves the singularity to $360^\circ$ and therefore remains finite at $180^\circ$.
If a rotation is represented by the Euler angle $\phi$ and the unitary Euler vector $\mathbf{e}$, then the corresponding MRP $\mathbf{m}$ is defined by:
\[\mathbf{m} = \mathbf{e} \tan\left(\frac{\phi}{4}\right)\ .\]
Hence, the MRP remains finite for $\phi = \pi$ rad ($180^\circ$), and becomes singular only for $\phi = 2\pi$ rad ($360^\circ$).
Initialization
The constructors for this structure are:
MRP(q1::T1, q2::T2, q3::T3) where {T1,T2,T3}
MRP(v::AbstractVector)in which a MRP with components q1, q2, and q3 will be created. Notice that the type of the returned structure will be selected according to the input types.
julia> MRP(0.1, 0.2, 0.3)MRP{Float64}: X : + 0.1 Y : + 0.2 Z : + 0.3julia> MRP([0.1, 0.2, 0.3])MRP{Float64}: X : + 0.1 Y : + 0.2 Z : + 0.3julia> MRP(1, 2, 3.0f0)MRP{Float32}: X : + 1.0 Y : + 2.0 Z : + 3.0
It is also possible to create the identity rotation using I, zero, and one:
julia> MRP(I)MRP{Bool}: X : + false Y : + false Z : + falsejulia> zero(MRP)MRP{Float64}: X : + 0.0 Y : + 0.0 Z : + 0.0julia> one(MRP)MRP{Float64}: X : + 0.0 Y : + 0.0 Z : + 0.0
Individual elements of the MRP can be accessed by:
m.q1
m.q2
m.q3or using linear indexing:
m[1]
m[2]
m[3]Operations
Sum, subtraction, and scalar multiplication
julia> m1 = MRP(0.1, 0.2, 0.3)MRP{Float64}: X : + 0.1 Y : + 0.2 Z : + 0.3julia> m2 = MRP(0.2, -0.1, 0.1)MRP{Float64}: X : + 0.2 Y : - 0.1 Z : + 0.1julia> m1 + m2MRP{Float64}: X : + 0.3 Y : + 0.1 Z : + 0.4julia> m1 - m2MRP{Float64}: X : - 0.1 Y : + 0.3 Z : + 0.2julia> 2m1MRP{Float64}: X : + 0.2 Y : + 0.4 Z : + 0.6julia> m1 / 2MRP{Float64}: X : + 0.05 Y : + 0.1 Z : + 0.15
Multiplication (rotation composition)
The multiplication of two MRPs is defined here as the composition of the rotations. Let $\mathbf{m}_1$ and $\mathbf{m}_2$ be two MRPs (instances of the structure MRP). Thus, the operation:
\[\mathbf{m}_{2,1} = \mathbf{m}_2 \cdot \mathbf{m}_1\]
will return a new MRP $\mathbf{m}_{2,1}$ that represents the composed rotation of $\mathbf{m}_1$ followed by $\mathbf{m}_2$.
MRP has a shadow-set representation. Depending on the rotation, the result can be represented by different MRP vectors that describe the same attitude. If desired, use shadow_rotation(m) to switch to the shadow set.
julia> m1 = angle_to_mrp(0.1, 0.2, 0.3, :ZYX)MRP{Float64}: X : + 0.0723888 Y : + 0.0534553 Z : + 0.0172793julia> m2 = angle_to_mrp(-0.2, 0.1, -0.1, :XYZ)MRP{Float64}: X : - 0.0512328 Y : + 0.0224287 Z : - 0.0274314julia> m2 * m1MRP{Float64}: X : + 0.0174925 Y : + 0.0772258 Z : - 0.00125679
Inversion
The inverse rotation is obtained using inv:
julia> m = angle_to_mrp(0.2, -0.1, 0.3, :ZYX)MRP{Float64}: X : + 0.077422 Y : - 0.0172923 Z : + 0.0534956julia> inv(m)MRP{Float64}: X : - 0.077422 Y : + 0.0172923 Z : - 0.0534956
Shadow rotation
The MRP admits a shadow set representation that corresponds to the same rotation and is useful when the norm grows too large.
julia> m = MRP(0.8, 0.2, -0.1)MRP{Float64}: X : + 0.8 Y : + 0.2 Z : - 0.1julia> shadow_rotation(m)MRP{Float64}: X : - 1.15942 Y : - 0.289855 Z : + 0.144928
Functions
Useful helper functions include:
julia> m = MRP(0.1, 0.2, 0.3)MRP{Float64}: X : + 0.1 Y : + 0.2 Z : + 0.3julia> norm(m)0.37416573867739417julia> vect(m)3-element StaticArraysCore.SVector{3, Float64} with indices SOneTo(3): 0.1 0.2 0.3julia> copy(m)MRP{Float64}: X : + 0.1 Y : + 0.2 Z : + 0.3
Kinematics
The time-derivative of a MRP can be computed using:
function dmrp(m::MRP, wba_b::AbstractVector)julia> m = MRP(0.0, 0.0, 0.0)MRP{Float64}: X : + 0.0 Y : + 0.0 Z : + 0.0julia> wba_b = [0.01, 0.02, -0.03]3-element Vector{Float64}: 0.01 0.02 -0.03julia> dmrp(m, wba_b)MRP{Float64}: X : + 0.0025 Y : + 0.005 Z : - 0.0075