Frames
ModiaMath.Frames
— Module.module ModiaMath.Frames
This module contains functions for frames that is coordinate systems in 3D. The orientation of a frame is described either with a 3x3 rotation matrix or with a quaternion vector and its origin is described with a Vector3D:
const
ModiaMath.RotationMatrix
= SMatrix{3,3,Float64,9}`: Type of a Rotation matrix to rotate from a frame 1 into a frame 2.const
ModiaMath.Quaternion
= SVector{4,Float64}`: Type of a Quaternion vector to rotate from a frame 1 into a frame 2.const
ModiaMath.Vector3D
= SVector{3,Float64}`: Type of a vector in 3D space (e.g. position vector of the origin of a frame).
The following constants are defined
const
ModiaMath.NullRotation
: RotationMatrix with no rotation from a frame 1 into a frame 2.const
ModiaMath.NullQuaternion
: Quaternion vector with no rotation from a frame 1 into a frame 2.const
ModiaMath.ZeroVector3D
: Vector3D with only zero elements.
If an angle is given as an argument to one of the functions below, it might be a number (interpreted as having unit rad
) or a number with a unit (for example: using Unitful; angle = 90u"°"
).
Constructors for a RotationMatrix R
The following functions return a ModiaMath.RotationMatrix
R
to rotate a frame 1 into a frame 2.
Function | Description |
---|---|
ModiaMath.rot1 (angle) | Rotate around angle along x-axis |
ModiaMath.rot2 (angle) | Rotate around angle along y-axis |
ModiaMath.rot3 (angle) | Rotate around angle along z-axis |
ModiaMath.rot123 (angle1, angle2, angle3) | Rotate around angles along x,y,z-axes |
ModiaMath.rot_e (e, angle) | Rotate around angle along unit vector e |
ModiaMath.rot_nxy (nx, ny) | nx /ny are in x/y-direction of frame 2 |
ModiaMath.from_q (q) | Return R from Quaternion q |
Constructors for a Quaternion q
The following functions return a ModiaMath.Quaternion
q
to rotate a frame 1 into a frame 2. Since q
and -q
define the same rotation the constructor functions have a keyword argument q_guess::Quaternion = NullQuaternion
. From the two possible solutions q
the one is returned that is closer to q_guess
.
Function | Description |
---|---|
ModiaMath.qrot1 (angle) | Rotate around angle along x-axis |
ModiaMath.qrot2 (angle) | Rotate around angle along y-axis |
ModiaMath.qrot3 (angle) | Rotate around angle along z-axis |
ModiaMath.qrot123 (angle1, angle2, angle3) | Rotate around angles along x,y,z-axes |
ModiaMath.qrot_e (e, angle) | Rotate around angle along unit vector e |
ModiaMath.qrot_nxy (nx, ny) | nx /ny are in x/y-direction of frame 2 |
ModiaMath.from_R (R) | Return q from RotationMatrix R |
Operations on Frames
The following functions provide operations on frames. The orientation of a frame is defined with argument Rq
meaning it can be either a ModiaMath.RotationMatrix
R
or a ModiaMath.Quaternion
q
(to rotate a frame 1 into a frame 2).
Function | Description |
---|---|
ModiaMath.resolve1 (Rq, v2) | Transform vector v from frame 2 to frame 1 |
ModiaMath.resolve2 (Rq, v1) | Transform vector v from frame 1 to frame 2 |
ModiaMath.absoluteRotation (Rq01, Rq12) | Return rotation 0->2 from rot. 0->1 and 1->2 |
ModiaMath.relativeRotation (Rq01, Rq02) | Return rotation 1->2 from rot. 0->1 and 0->2 |
ModiaMath.inverseRotation (Rq01) | Return rotation 1->0 from rot, 0->1 |
ModiaMath.planarRotationAngle (e,v1,v2) | Return angle of planar rotation along e |
ModiaMath.eAxis (axis) | Return unit vector e in direction of axis |
ModiaMath.skew (v) | Return skew-symmetric matrix of vector v |
Interpolation of Frames
Given a set of frames by a vector r
of position vectors to their origins and and an optional vector q
of Quaternions of their absolute orientations, then the following functions interpolate linearly in these frames:
Function | Description |
---|---|
ModiaMath.Path (r,q) | Return path defined by a vector of frames |
ModiaMath.t_pathEnd (path) | Return path parameter t_end of last frame |
ModiaMath.interpolate (path,t) | Return (rt,qt) of Path at path parameter t |
ModiaMath.interpolate_r (path,t) | Return rt of Path at path parameter t |
Examples
using ModiaMath
using Unitful
# R1,R2,R3 are the same RotationMatrices
R1 = ModiaMath.rot1(pi/2)
R2 = ModiaMath.rot1(90u"°")
R3 = ModiaMath.rot_e([1,0,0], pi/2)
Main developer
Martin Otter, DLR - Institute of System Dynamics and Control
The functions of this module are mostly a mapping of some of the functions of the Modelica Standard Library from Modelica (Modelica.Mechanics.MultiBody.Frames) to Julia (taking advantage of Julia features such as multiple dispatch and unit package Unitful).
ModiaMath.Frames.NullQuaternion
— Constant.const ModiaMath.NullQuaternion = Quaternion(0,0,0,1)
Constant Quaternion vector of a null rotation (= no rotation from frame 1 to frame 2)
ModiaMath.Frames.NullRotation
— Constant.Constant RotationMatrix that defines no rotation from frame 1 to frame 2.
ModiaMath.Frames.ZeroVector3D
— Constant.const ModiaMath.ZeroVector3D = Vector3D(0.0, 0.0, 0.0)
Constant of a Vector3D where all elements are zero
ModiaMath.Frames.Path
— Type.path = ModiaMath.Path(r::Vector{Vector3D},
q::Vector{Quaternion} = Quaternion[];
v = ones(length(r)))
Return an instance of a new Path object. The Path object consists of n frames defined by the position vectors of their origins (r[i]
for frame i
) and optionally of their absolute rotation quaternions (q[i]
for frame i
) describing the rotation from the world frame to the respective frame.
A path parameter t
is defined in the following way on these frames:
t[1] = 0.0
.t[i] = t[i-1] + pathLength_i/(v[i]+v[i-1])/2
if the origins of framesi-1
andi
do not coincide.t[i] = t[i-1] + pathAngle_i/(v[i]+v[i-1])/2
if the origins of framesi-1
andi
do coincide.
Hereby pathLength_i
is the distance between the origins of frames i-1
and i
in [m] and pathAngle_i
is the planar rotation angle between frames i-1
and i
in [rad].
If v[i]
is the desired velocity or angular velocity at frame i
, then path parameter t
is approximately the time to move along the path. The time instant t_end
of the last frame can be inquired with ModiaMath.t_pathEnd(path)
. For example, if a simulation shall be performed in such a way that the simulation should start with the first frame and end at stopTime
at the last frame, then the path parameter should be selected as t = time*t_end/stopTime
.
Given the actual path parameter, typically 0 <= t <= t_end
(if t
is outside of this interval, the frame at t
is determined by extrapolation through the first two or the last two frames), the corresponding frame is determined by linear interpolation in the following way:
(rt, qt) = interpolate( path,t)
rt = interpolate_r(path,t)
where rt
is the position vector to the origin of the frame at path parameter t
and qt
is the absolute quaternion of the frame at path parameter t
.
Example
import ModiaMath
using Unitful
r = [ ModiaMath.Vector3D(1,0,0),
ModiaMath.Vector3D(0,1,0),
ModiaMath.Vector3D(0,0,1) ]
q = [ ModiaMath.NullQuaternion,
ModiaMath.qrot1(45u"°"),
ModiaMath.qrot2(60u"°")]
path = ModiaMath.Path(r,q)
t_end = ModiaMath.t_pathEnd(path)
dt = 0.1
stopTime = 2.0
time = 0.0
while time <= stopTime
(rt, qt) = ModiaMath.interpolate(path, time*t_end/stopTime)
time += dt
end
ModiaMath.Frames.Quaternion
— Type.const ModiaMath.Quaternion = SVector{4,Float64}
Describes the rotation from a frame 1 into a frame 2 with a quaternion vector. If e
is the (normalized) axis of rotation to rotate frame 1 into frame 2 (either resolved in frame 1 or frame 2) and angle
is the rotation angle for this rotation then the quaternion vector q::ModiaMath.Quaternions
is defined as:
q = [e*sin(angle/2),
cos(angle/2]
ModiaMath.Frames.RotationMatrix
— Type.const ModiaMath.RotationMatrix = SMatrix{3,3,Float64,9}
Describes the rotation from a frame 1 into a frame 2. An instance R
of RotationMatrix
has the following interpretation:
R::RotationMatrix = [ex ey ez]
where ex
, ey
, ez
are unit vectors in the direction of the x-axis, y-axis, and z-axis of frame 1, resolved in frame 2, respectively (for example ex=[1.0, 0.0, 0.0]) Therefore, if v1
is vector v
resolved in frame 1 and v2
is vector v
resolved in frame 2, the following relationship holds:
v2 = R*v1
v1 = R'*v2
ModiaMath.Frames.Vector3D
— Type.const ModiaMath.Vector3D = SVector{3,Float64}
Type of a vector in 3D space (e.g. position vector of the origin of a frame)
ModiaMath.Frames.absoluteRotation
— Method. R2 = ModiaMath.absoluteRotation(R1, R_rel)
q2 = ModiaMath.absoluteRotation(q1, q_rel)
Return ModiaMath.RotationMatrix
R2
or ModiaMath.Quaternion
q2
defining the rotation from frame 0 to frame 2 from RotationMatrix R1
or Quaternion q1
that define the rotation from frame 0 to frame 1 and the relative RotationMatrix R_rel
or the relative Quaternion q_rel
that define the rotation from frame 1 to frame 2.
ModiaMath.Frames.assertQuaternion
— Method.ModiaMath.assertQuaternion(q::AbstractVector)
Assert that vector q
has the properties of a Quaternion
vector (has 4 elements, norm(q) = 1
)
ModiaMath.Frames.assertRotationMatrix
— Method.ModiaMath.assertRotationMatrix(R::AbstractMatrix)
Assert that matrix R has the properties of a rotation matrix (is 3x3 and R'*R - eye(3) = zeros(3,3))
ModiaMath.Frames.eAxis
— Method.e = eAxis(axis::Int)
Return unit vector e
in direction of axis axis
(axis
= 1,2,3 or -1,-2-,3).
Example
import ModiaMath
e1 = ModiMath.eAxis(1) # e1 = Vector3D(1.0, 0.0, 0.0)
e2 = ModiMath.eAxis(-2) # d2 = Vector3D(0.0, -1.0, 0.0)
ModiaMath.Frames.from_R
— Method.q = ModiaMath.from_R(R::ModiaMath.RotationMatrix;
q_guess = NullQuaternion)
Return Quaternion q
from RotationMatrix R
.
From the two possible solutions q
the one is returned that is closer to q_guess
(note, q
and -q
define the same rotation).
ModiaMath.Frames.from_q
— Method.R = ModiaMath.from_q(q::ModiaMath.Quaternion)
Return RotationMatrix R
from Quaternion q
.
ModiaMath.Frames.interpolate
— Method.(rt, qt) = ModiaMath.interpolate(path, t)
Return position rt
and Quaternion qt
of path::
ModiaMath.Path
at path parameter t::Number
.
ModiaMath.Frames.interpolate_r
— Method.rt = ModiaMath.interpolate_r(path, t)
Return position r
of path::
ModiaMath.Path
at path parameter t::Number
.
ModiaMath.Frames.inverseRotation
— Method. R_inv = ModiaMath.inverseRotation(R)
q_inv = ModiaMath.inverseRotation(q)
Return inverse ModiaMath.RotationMatrix
R_inv
or inverse ModiaMath.Quaternion
q_inv
defining the rotation from frame 1 to frame 0 from RotationMatrix R
or Quaternion q
that define the rotation from frame 0 to frame 1.
ModiaMath.Frames.planarRotationAngle
— Method.angle = planarRotationAngle(e, v1, v2; angle_guess = 0.0)
Return angle
of a planar rotation, given the normalized axis of rotation to rotate frame 1 around e
into frame 2 (norm(e) == 1 required), and the representations of a vector in frame 1 (v1
) and frame 2 (v2
). Hereby, it is required that v1
is not parallel to e
. The returned angle is in the range -pi <= angle - angle_guess <= pi
(from the infinite many solutions, the one is returned that is closest to angle_guess
).
Example
import ModiaMath
using Unitful
angle1 = 45u"°"
e = normalize([1.0, 1.0, 1.0])
R = ModiaMath.rot_e(e, angle1)
v1 = [1.0, 2.0, 3.0]
v2 = ModiaMath.resolve2(R, v1)
angle2 = planarRotationAngle(e, v1, v2)
isapprox(angle1, angle2)
ModiaMath.Frames.qrot1
— Method.q = ModiaMath.qrot1(angle; q_guess = NullQuaternion)
Return Quaternion q
that rotates with angle angle
along the x-axis of frame 1.
From the two possible solutions q
the one is returned that is closer to q_guess
(note, q
and -q
define the same rotation).
ModiaMath.Frames.qrot123
— Method.q = ModiaMath.qrot123(angle1, angle2, angle3)
Return Quaternion q
by rotating with angle1 along the x-axis of frame 1, then with angle2 along the y-axis of this frame and then with angle3 along the z-axis of this frame.
From the two possible solutions q
the one is returned that is closer to q_guess
(note, q
and -q
define the same rotation).
ModiaMath.Frames.qrot2
— Method.q = ModiaMath.qrot2(angle; q_guess = NullQuaternion)
Return Quaternion q
that rotates with angle angle
along the y-axis of frame 1.
From the two possible solutions q
the one is returned that is closer to q_guess
(note, q
and -q
define the same rotation).
ModiaMath.Frames.qrot3
— Method.q = ModiaMath.qrot3(angle; q_guess = NullQuaternion)
Return Quaternion q
that rotates with angle angle
along the z-axis of frame 1.
From the two possible solutions q
the one is returned that is closer to q_guess
(note, q
and -q
define the same rotation).
ModiaMath.Frames.qrot_e
— Method.q = ModiaMath.qrot_e(e, angle; q_guess = NullQuaternion)
Return Quaternion q
that rotates with angle angle
along unit axis e
. This function assumes that norm(e) == 1
.
From the two possible solutions q
the one is returned that is closer to q_guess
(note, q
and -q
define the same rotation).
ModiaMath.Frames.qrot_nxy
— Method.q = ModiaMath.qrot_nxy(nx, ny)
It is assumed that the two input vectors nx
and ny
are resolved in frame 1 and are directed along the x and y axis of frame 2. The function returns the Quaternion q
to rotate from frame 1 to frame 2.
The function is robust in the sense that it returns always a Quaternion q
, even if ny
is not orthogonal to nx
or if one or both vectors have zero length. This is performed in the following way: If nx
and ny
are not orthogonal to each other, first a unit vector ey
is determined that is orthogonal to nx
and is lying in the plane spanned by nx
and ny
. If nx
and ny
are parallel or nearly parallel to each other or ny
is a vector with zero or nearly zero length, a vector ey
is selected arbitrarily such that ex
and ey
are orthogonal to each other. If both nx
and ny
are vectors with zero or nearly zero length, an arbitrary Quaternion q
is returned.
Example
using Unitful
import ModiaMath
q1 = ModiaMath.qrot1(90u"°")
q2 = ModiaMath.qrot_nxy([1 , 0, 0], [0 , 0, 1 ])
q3 = ModiaMath.qrot_nxy([0.9, 0, 0], [1.1, 0, 1.1])
isapprox(q1,q2) # returns true
isapprox(q1,q3) # returns true
ModiaMath.Frames.relativeRotation
— Method. R_rel = ModiaMath.relativeRotation(R1, R2)
q_rel = ModiaMath.relativeRotation(q1, q2)
Return relative ModiaMath.RotationMatrix
R_rel
or relative ModiaMath.Quaternion
q_rel
defining the rotation from frame 1 to frame 2 from absolute RotationMatrix R1
or absolute Quaternion q1
that define the rotation from frame 0 to frame 1 and the absolute RotationMatrix R2
or the absolute Quaternion q2
that define the rotation from frame 0 to frame 2.
ModiaMath.Frames.resolve1
— Method.v1 = ModiaMath.resolve1([R|q], v2)
Transform vector v2 (v resolved in frame 2) to vector v1 (v resolved in frame 1) given either ModiaMath.RotationMatrix
R
or ModiaMath.Quaternion
q
(to rotate a frame 1 into a frame 2).
ModiaMath.Frames.resolve2
— Method.v2 = ModiaMath.resolve2([R|q], v1)
Transform vector v1 (v resolved in frame 1) to vector v2 (v resolved in frame 2) given either ModiaMath.RotationMatrix
R
or ModiaMath.Quaternion
q
(to rotate a frame 1 into a frame 2).
ModiaMath.Frames.rot1
— Method.R = ModiaMath.rot1(angle)
Return RotationMatrix R that rotates with angle angle
along the x-axis of frame 1.
ModiaMath.Frames.rot123
— Method.R = ModiaMath.rot123(angle1, angle2, angle3)
Return RotationMatrix R by rotating with angle1 along the x-axis of frame 1, then with angle2 along the y-axis of this frame and then with angle3 along the z-axis of this frame.
ModiaMath.Frames.rot2
— Method.R = ModiaMath.rot2(angle)
Return RotationMatrix R that rotates with angle angle
in [radian] along the y-axis of frame 1.
ModiaMath.Frames.rot3
— Method.R = ModiaMath.rot3(angle)
Return RotationMatrix R that rotates with angle angle
in [radian] along the z-axis of frame 1.
ModiaMath.Frames.rot_e
— Method.R = ModiaMath.rot_e(e, angle)
Return RotationMatrix that rotates around angle angle
along unit axis e
. This function assumes that norm(e) == 1
.
ModiaMath.Frames.rot_nxy
— Method.R = ModiaMath.rot_nxy(nx, ny)
It is assumed that the two input vectors nx
and ny
are resolved in frame 1 and are directed along the x and y axis of frame 2. The function returns the RotationMatrix R to rotate from frame 1 to frame 2.
The function is robust in the sense that it returns always a RotationMatrix R, even if ny
is not orthogonal to nx
or if one or both vectors have zero length. This is performed in the following way: If nx
and ny
are not orthogonal to each other, first a unit vector ey
is determined that is orthogonal to nx
and is lying in the plane spanned by nx
and ny
. If nx
and ny
are parallel or nearly parallel to each other or ny
is a vector with zero or nearly zero length, a vector ey
is selected arbitrarily such that ex
and ey
are orthogonal to each other. If both nx
and ny
are vectors with zero or nearly zero length, an arbitrary rotation matrix is returned.
Example
using Unitful
import ModiaMath
R1 = ModiaMath.rot1(90u"°")
R2 = ModiaMath.rot_nxy([1 , 0, 0], [0 , 0, 1 ])
R3 = ModiaMath.rot_nxy([0.9, 0, 0], [1.1, 0, 1.1])
isapprox(R1,R2) # returns true
isapprox(R1,R3) # returns true
ModiaMath.Frames.skew
— Method.M = ModiaMath.skew(e::AbstractVector)
Return the skew symmetric matrix M::SMatrix{3,3,Float64,9}
of vector e
(length(e) = 3
)
ModiaMath.Frames.t_pathEnd
— Method.t_end = ModiaMath.t_pathEnd(path::[`ModiaMath.Path`](@ref))
Return the final path parameter t
of the last frame in path (path parameter of first frame = 0.0).