From 66d0c7d0a17f46d2bf53e9e6224c7f19b747c9ec Mon Sep 17 00:00:00 2001 From: "Documenter.jl" Date: Mon, 8 Apr 2024 14:50:59 +0000 Subject: [PATCH] build based on e4be8c5 --- dev/.documenter-siteinfo.json | 2 +- dev/2d_angle/index.html | 2 +- dev/2d_matrix/index.html | 2 +- dev/2d_rotation_generator/index.html | 18 +- dev/3d_angleaxis/index.html | 4 +- dev/3d_euler/index.html | 2 +- dev/3d_matrix/index.html | 2 +- dev/3d_quaternion/index.html | 2 +- dev/3d_rotation_generator/index.html | 20 +- dev/assets/documenter.js | 923 +++++++++++-------- dev/assets/themes/documenter-dark.css | 2 +- dev/functionreference/index.html | 74 +- dev/functions/index.html | 28 +- dev/general_dimensional_rotations/index.html | 48 +- dev/index.html | 2 +- dev/objects.inv | Bin 0 -> 1987 bytes dev/reference/index.html | 2 +- dev/rotation_generator_types/index.html | 2 +- dev/rotation_types/index.html | 2 +- dev/search_index.js | 2 +- dev/visualizing/index.html | 2 +- 21 files changed, 651 insertions(+), 490 deletions(-) create mode 100644 dev/objects.inv diff --git a/dev/.documenter-siteinfo.json b/dev/.documenter-siteinfo.json index e6a23dd..ac4f4e9 100644 --- a/dev/.documenter-siteinfo.json +++ b/dev/.documenter-siteinfo.json @@ -1 +1 @@ -{"documenter":{"julia_version":"1.10.0","generation_timestamp":"2024-02-06T12:02:32","documenter_version":"1.2.1"}} \ No newline at end of file +{"documenter":{"julia_version":"1.10.2","generation_timestamp":"2024-04-08T14:50:54","documenter_version":"1.3.0"}} \ No newline at end of file diff --git a/dev/2d_angle/index.html b/dev/2d_angle/index.html index a6e2a28..71a765c 100644 --- a/dev/2d_angle/index.html +++ b/dev/2d_angle/index.html @@ -12,4 +12,4 @@ 1: Float64 0.3623577544766736 2: Float64 0.9320390859672263 3: Float64 -0.9320390859672263 - 4: Float64 0.3623577544766736 + 4: Float64 0.3623577544766736 diff --git a/dev/2d_matrix/index.html b/dev/2d_matrix/index.html index 80b465f..f18d12c 100644 --- a/dev/2d_matrix/index.html +++ b/dev/2d_matrix/index.html @@ -5,4 +5,4 @@ 0.362358 -0.932039 0.932039 0.362358
julia> RotMatrix{2}(t) # construct from angle2×2 RotMatrix2{Float64} with indices SOneTo(2)×SOneTo(2): 0.362358 -0.932039 - 0.932039 0.362358 + 0.932039 0.362358 diff --git a/dev/2d_rotation_generator/index.html b/dev/2d_rotation_generator/index.html index e1333d1..c0f6675 100644 --- a/dev/2d_rotation_generator/index.html +++ b/dev/2d_rotation_generator/index.html @@ -1,16 +1,16 @@ 2D Rotation Generators · Rotations.jl

2D Rotation Generator

RotMatrixGenerator2

example

julia> m = rand(2,2)2×2 Matrix{Float64}:
- 0.509433  0.925772
- 0.24587   0.284683
julia> s = RotMatrixGenerator{2}(m - m')2×2 RotMatrixGenerator2{Float64} with indices SOneTo(2)×SOneTo(2): - 0.0 0.679902 - -0.679902 0.0
julia> exp(s)2×2 RotMatrix2{Float64} with indices SOneTo(2)×SOneTo(2): - 0.777634 0.628717 - -0.628717 0.777634
julia> log(exp(s))2×2 RotMatrixGenerator2{Float64} with indices SOneTo(2)×SOneTo(2): - 0.0 0.679902 - -0.679902 0.0

Angle2dGenerator

example

julia> s = Angle2dGenerator(0.42)2×2 Angle2dGenerator{Float64} with indices SOneTo(2)×SOneTo(2)(0.42):
+ 0.596184  0.637158
+ 0.879545  0.550411
julia> s = RotMatrixGenerator{2}(m - m')2×2 RotMatrixGenerator2{Float64} with indices SOneTo(2)×SOneTo(2): + 0.0 -0.242387 + 0.242387 0.0
julia> exp(s)2×2 RotMatrix2{Float64} with indices SOneTo(2)×SOneTo(2): + 0.970768 -0.24002 + 0.24002 0.970768
julia> log(exp(s))2×2 RotMatrixGenerator2{Float64} with indices SOneTo(2)×SOneTo(2): + 0.0 -0.242387 + 0.242387 0.0

Angle2dGenerator

example

julia> s = Angle2dGenerator(0.42)2×2 Angle2dGenerator{Float64} with indices SOneTo(2)×SOneTo(2)(0.42):
  0.0   -0.42
  0.42   0.0
julia> exp(s)2×2 Angle2d{Float64} with indices SOneTo(2)×SOneTo(2)(0.42): 0.913089 -0.40776 0.40776 0.913089
julia> log(exp(s))2×2 Angle2dGenerator{Float64} with indices SOneTo(2)×SOneTo(2)(0.42): 0.0 -0.42 - 0.42 0.0
julia> rotation_angle(exp(s))0.42
julia> rotation_angle(exp(2s))0.84
julia> rotation_angle(exp(2s)) / rotation_angle(exp(s))2.0
+ 0.42 0.0
julia> rotation_angle(exp(s))0.42
julia> rotation_angle(exp(2s))0.84
julia> rotation_angle(exp(2s)) / rotation_angle(exp(s))2.0 diff --git a/dev/3d_angleaxis/index.html b/dev/3d_angleaxis/index.html index 7275966..55416e4 100644 --- a/dev/3d_angleaxis/index.html +++ b/dev/3d_angleaxis/index.html @@ -43,7 +43,7 @@ R(\bm{v}) &= R_{\bm{n}} (\theta) & \left(\bm{n} = \frac{\bm{v}}{\|\bm{v}\|}, \theta = \|\bm{v}\| \right) \end{aligned}\]

Differentiation

If you're differentiating a Rodrigues Vector check the result is what you expect at theta = 0. The first derivative of the rotation should behave, but higher-order derivatives of it (as well as parameterization conversions) should be tested. The Stereographic Quaternion Projection (MRP) is the recommended three parameter format for differentiation.

example

julia> using Rotations, LinearAlgebra
-       # 1/3 (120°) rotation around the (1/√3, 1/√3, 1/√3) vector
julia> R = R = RotationVec(2π/3(√3), 2π/3(√3), 2π/3(√3)) + # 1/3 (120°) rotation around the (1/√3, 1/√3, 1/√3) vector
julia> R = RotationVec(2π/3(√3), 2π/3(√3), 2π/3(√3)) # This matrix swaps the xyz coordinates3×3 RotationVec{Float64} with indices SOneTo(3)×SOneTo(3)(1.2092, 1.2092, 1.2092): 1.11022e-16 -1.11022e-16 1.0 1.0 1.11022e-16 -1.11022e-16 @@ -57,4 +57,4 @@ # These matrices are approximately equal3×3 RotationVec{Float64} with indices SOneTo(3)×SOneTo(3)(3.6276, 3.6276, 3.6276): 1.0 1.4141e-16 -1.4141e-16 -1.4141e-16 1.0 1.4141e-16 - 1.4141e-16 -1.4141e-16 1.0
julia> R^3 ≈ I(3)true
julia> α, β, γ = 1.2, -0.8, 0.1;
julia> RotX(α) ≈ RotationVec(α,0,0) # These matrices are equaltrue
julia> RotY(β) ≈ RotationVec(0,β,0) # These matrices are equaltrue
julia> RotZ(γ) ≈ RotationVec(0,0,γ) # These matrices are equaltrue
+ 1.4141e-16 -1.4141e-16 1.0
julia> R^3 ≈ I(3)true
julia> α, β, γ = 1.2, -0.8, 0.1;
julia> RotX(α) ≈ RotationVec(α,0,0) # These matrices are equaltrue
julia> RotY(β) ≈ RotationVec(0,β,0) # These matrices are equaltrue
julia> RotZ(γ) ≈ RotationVec(0,0,γ) # These matrices are equaltrue diff --git a/dev/3d_euler/index.html b/dev/3d_euler/index.html index 2374b61..0cedc97 100644 --- a/dev/3d_euler/index.html +++ b/dev/3d_euler/index.html @@ -76,4 +76,4 @@ # These matrices are equal3×3 RotYXZ{Float64} with indices SOneTo(3)×SOneTo(3)(1.2, 4.7, -0.4): 0.696679 -0.71729 -0.0115467 0.00482437 -0.0114107 0.999923 - -0.717367 -0.696681 -0.00448913
julia> RotYXZ(α, β, γ) == RotY(α)*RotX(β)*RotZ(γ)true + -0.717367 -0.696681 -0.00448913
julia> RotYXZ(α, β, γ) == RotY(α)*RotX(β)*RotZ(γ)true diff --git a/dev/3d_matrix/index.html b/dev/3d_matrix/index.html index e875dad..1665b81 100644 --- a/dev/3d_matrix/index.html +++ b/dev/3d_matrix/index.html @@ -14,4 +14,4 @@ 0.0 0.0 1.0
julia> RotMatrix(m2) # Type parameter can be omitted.3×3 RotMatrix3{Float64} with indices SOneTo(3)×SOneTo(3): 0.362358 -0.932039 0.0 0.932039 0.362358 0.0 - 0.0 0.0 1.0 + 0.0 0.0 1.0 diff --git a/dev/3d_quaternion/index.html b/dev/3d_quaternion/index.html index fbe1ed0..51b7c3d 100644 --- a/dev/3d_quaternion/index.html +++ b/dev/3d_quaternion/index.html @@ -27,4 +27,4 @@ \right.\]

example

julia> one(MRP)  # identity rotation3×3 MRP{Float64} with indices SOneTo(3)×SOneTo(3)(0.0, 0.0, 0.0):
  1.0  0.0  0.0
  0.0  1.0  0.0
- 0.0  0.0  1.0
julia> α, β, γ = 1.2, -0.8, 0.1;
julia> RotX(α) ≈ MRP(sin(α/2)/(cos(α/2)-1),0,0) # These matrices are equaltrue
julia> RotY(β) ≈ MRP(0,sin(β/2)/(cos(β/2)-1),0) # These matrices are equaltrue
julia> RotZ(γ) ≈ MRP(0,0,sin(γ/2)/(cos(γ/2)-1)) # These matrices are equaltrue
+ 0.0 0.0 1.0
julia> α, β, γ = 1.2, -0.8, 0.1;
julia> RotX(α) ≈ MRP(sin(α/2)/(cos(α/2)-1),0,0) # These matrices are equaltrue
julia> RotY(β) ≈ MRP(0,sin(β/2)/(cos(β/2)-1),0) # These matrices are equaltrue
julia> RotZ(γ) ≈ MRP(0,0,sin(γ/2)/(cos(γ/2)-1)) # These matrices are equaltrue diff --git a/dev/3d_rotation_generator/index.html b/dev/3d_rotation_generator/index.html index 396c614..a98a926 100644 --- a/dev/3d_rotation_generator/index.html +++ b/dev/3d_rotation_generator/index.html @@ -1,14 +1,14 @@ 3D Rotation Generators · Rotations.jl

3D Rotation Generator

RotMatrixGenerator3

example

julia> m = rand(3,3)3×3 Matrix{Float64}:
- 0.900117  0.480563  0.406903
- 0.460993  0.636629  0.949096
- 0.930412  0.586648  0.166578
julia> s = RotMatrixGenerator{3}(m - m')3×3 RotMatrixGenerator3{Float64} with indices SOneTo(3)×SOneTo(3): - 0.0 0.0195693 -0.523508 - -0.0195693 0.0 0.362448 - 0.523508 -0.362448 0.0
julia> exp(s)3×3 RotMatrix3{Float64} with indices SOneTo(3)×SOneTo(3): - 0.867356 0.109979 -0.485384 - 0.0734346 0.936322 0.343378 - 0.49224 -0.333475 0.804049

RotationVecGenerator

example

julia> s = RotationVecGenerator(0.1,0.2,0.3)3×3 RotationVecGenerator{Float64} with indices SOneTo(3)×SOneTo(3)(0.1, 0.2, 0.3):
+ 0.838406  0.29884   0.447385
+ 0.930052  0.940084  0.993462
+ 0.920853  0.908114  0.372662
julia> s = RotMatrixGenerator{3}(m - m')3×3 RotMatrixGenerator3{Float64} with indices SOneTo(3)×SOneTo(3): + 0.0 -0.631212 -0.473468 + 0.631212 0.0 0.085348 + 0.473468 -0.085348 0.0
julia> exp(s)3×3 RotMatrix3{Float64} with indices SOneTo(3)×SOneTo(3): + 0.704701 -0.547836 -0.450857 + 0.586169 0.807571 -0.0650824 + 0.399753 -0.218415 0.89022

RotationVecGenerator

example

julia> s = RotationVecGenerator(0.1,0.2,0.3)3×3 RotationVecGenerator{Float64} with indices SOneTo(3)×SOneTo(3)(0.1, 0.2, 0.3):
   0.0  -0.3   0.2
   0.3   0.0  -0.1
  -0.2   0.1   0.0
julia> exp(s)3×3 RotationVec{Float64} with indices SOneTo(3)×SOneTo(3)(0.1, 0.2, 0.3): @@ -17,4 +17,4 @@ -0.18054 0.127335 0.97529
julia> log(exp(s))3×3 RotationVecGenerator{Float64} with indices SOneTo(3)×SOneTo(3)(0.1, 0.2, 0.3): 0.0 -0.3 0.2 0.3 0.0 -0.1 - -0.2 0.1 0.0
julia> rotation_angle(exp(s))0.37416573867739417
julia> rotation_angle(exp(2s))0.7483314773547883
julia> rotation_angle(exp(2s)) / rotation_angle(exp(s))2.0
+ -0.2 0.1 0.0
julia> rotation_angle(exp(s))0.37416573867739417
julia> rotation_angle(exp(2s))0.7483314773547883
julia> rotation_angle(exp(2s)) / rotation_angle(exp(s))2.0 diff --git a/dev/assets/documenter.js b/dev/assets/documenter.js index f531160..c6562b5 100644 --- a/dev/assets/documenter.js +++ b/dev/assets/documenter.js @@ -4,7 +4,6 @@ requirejs.config({ 'highlight-julia': 'https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.8.0/languages/julia.min', 'headroom': 'https://cdnjs.cloudflare.com/ajax/libs/headroom/0.12.0/headroom.min', 'jqueryui': 'https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.13.2/jquery-ui.min', - 'minisearch': 'https://cdn.jsdelivr.net/npm/minisearch@6.1.0/dist/umd/index.min', 'katex-auto-render': 'https://cdnjs.cloudflare.com/ajax/libs/KaTeX/0.16.8/contrib/auto-render.min', 'jquery': 'https://cdnjs.cloudflare.com/ajax/libs/jquery/3.7.0/jquery.min', 'headroom-jquery': 'https://cdnjs.cloudflare.com/ajax/libs/headroom/0.12.0/jQuery.headroom.min', @@ -103,9 +102,10 @@ $(document).on("click", ".docstring header", function () { }); }); -$(document).on("click", ".docs-article-toggle-button", function () { +$(document).on("click", ".docs-article-toggle-button", function (event) { let articleToggleTitle = "Expand docstring"; let navArticleToggleTitle = "Expand all docstrings"; + let animationSpeed = event.noToggleAnimation ? 0 : 400; debounce(() => { if (isExpanded) { @@ -116,7 +116,7 @@ $(document).on("click", ".docs-article-toggle-button", function () { isExpanded = false; - $(".docstring section").slideUp(); + $(".docstring section").slideUp(animationSpeed); } else { $(this).removeClass("fa-chevron-down").addClass("fa-chevron-up"); $(".docstring-article-toggle-button") @@ -127,7 +127,7 @@ $(document).on("click", ".docs-article-toggle-button", function () { articleToggleTitle = "Collapse docstring"; navArticleToggleTitle = "Collapse all docstrings"; - $(".docstring section").slideDown(); + $(".docstring section").slideDown(animationSpeed); } $(this).prop("title", navArticleToggleTitle); @@ -224,224 +224,465 @@ $(document).ready(function () { }) //////////////////////////////////////////////////////////////////////////////// -require(['jquery', 'minisearch'], function($, minisearch) { - -// In general, most search related things will have "search" as a prefix. -// To get an in-depth about the thought process you can refer: https://hetarth02.hashnode.dev/series/gsoc +require(['jquery'], function($) { -let results = []; -let timer = undefined; +$(document).ready(function () { + let meta = $("div[data-docstringscollapsed]").data(); -let data = documenterSearchIndex["docs"].map((x, key) => { - x["id"] = key; // minisearch requires a unique for each object - return x; + if (meta?.docstringscollapsed) { + $("#documenter-article-toggle-button").trigger({ + type: "click", + noToggleAnimation: true, + }); + } }); -// list below is the lunr 2.1.3 list minus the intersect with names(Base) -// (all, any, get, in, is, only, which) and (do, else, for, let, where, while, with) -// ideally we'd just filter the original list but it's not available as a variable -const stopWords = new Set([ - "a", - "able", - "about", - "across", - "after", - "almost", - "also", - "am", - "among", - "an", - "and", - "are", - "as", - "at", - "be", - "because", - "been", - "but", - "by", - "can", - "cannot", - "could", - "dear", - "did", - "does", - "either", - "ever", - "every", - "from", - "got", - "had", - "has", - "have", - "he", - "her", - "hers", - "him", - "his", - "how", - "however", - "i", - "if", - "into", - "it", - "its", - "just", - "least", - "like", - "likely", - "may", - "me", - "might", - "most", - "must", - "my", - "neither", - "no", - "nor", - "not", - "of", - "off", - "often", - "on", - "or", - "other", - "our", - "own", - "rather", - "said", - "say", - "says", - "she", - "should", - "since", - "so", - "some", - "than", - "that", - "the", - "their", - "them", - "then", - "there", - "these", - "they", - "this", - "tis", - "to", - "too", - "twas", - "us", - "wants", - "was", - "we", - "were", - "what", - "when", - "who", - "whom", - "why", - "will", - "would", - "yet", - "you", - "your", -]); - -let index = new minisearch({ - fields: ["title", "text"], // fields to index for full-text search - storeFields: ["location", "title", "text", "category", "page"], // fields to return with search results - processTerm: (term) => { - let word = stopWords.has(term) ? null : term; - if (word) { - // custom trimmer that doesn't strip @ and !, which are used in julia macro and function names - word = word - .replace(/^[^a-zA-Z0-9@!]+/, "") - .replace(/[^a-zA-Z0-9@!]+$/, ""); - } +}) +//////////////////////////////////////////////////////////////////////////////// +require(['jquery'], function($) { - return word ?? null; - }, - // add . as a separator, because otherwise "title": "Documenter.Anchors.add!", would not find anything if searching for "add!", only for the entire qualification - tokenize: (string) => string.split(/[\s\-\.]+/), - // options which will be applied during the search - searchOptions: { - boost: { title: 100 }, - fuzzy: 2, +/* +To get an in-depth about the thought process you can refer: https://hetarth02.hashnode.dev/series/gsoc + +PSEUDOCODE: + +Searching happens automatically as the user types or adjusts the selected filters. +To preserve responsiveness, as much as possible of the slow parts of the search are done +in a web worker. Searching and result generation are done in the worker, and filtering and +DOM updates are done in the main thread. The filters are in the main thread as they should +be very quick to apply. This lets filters be changed without re-searching with minisearch +(which is possible even if filtering is on the worker thread) and also lets filters be +changed _while_ the worker is searching and without message passing (neither of which are +possible if filtering is on the worker thread) + +SEARCH WORKER: + +Import minisearch + +Build index + +On message from main thread + run search + find the first 200 unique results from each category, and compute their divs for display + note that this is necessary and sufficient information for the main thread to find the + first 200 unique results from any given filter set + post results to main thread + +MAIN: + +Launch worker + +Declare nonconstant globals (worker_is_running, last_search_text, unfiltered_results) + +On text update + if worker is not running, launch_search() + +launch_search + set worker_is_running to true, set last_search_text to the search text + post the search query to worker + +on message from worker + if last_search_text is not the same as the text in the search field, + the latest search result is not reflective of the latest search query, so update again + launch_search() + otherwise + set worker_is_running to false + + regardless, display the new search results to the user + save the unfiltered_results as a global + update_search() + +on filter click + adjust the filter selection + update_search() + +update_search + apply search filters by looping through the unfiltered_results and finding the first 200 + unique results that match the filters + + Update the DOM +*/ + +/////// SEARCH WORKER /////// + +function worker_function(documenterSearchIndex, documenterBaseURL, filters) { + importScripts( + "https://cdn.jsdelivr.net/npm/minisearch@6.1.0/dist/umd/index.min.js" + ); + + let data = documenterSearchIndex.map((x, key) => { + x["id"] = key; // minisearch requires a unique for each object + return x; + }); + + // list below is the lunr 2.1.3 list minus the intersect with names(Base) + // (all, any, get, in, is, only, which) and (do, else, for, let, where, while, with) + // ideally we'd just filter the original list but it's not available as a variable + const stopWords = new Set([ + "a", + "able", + "about", + "across", + "after", + "almost", + "also", + "am", + "among", + "an", + "and", + "are", + "as", + "at", + "be", + "because", + "been", + "but", + "by", + "can", + "cannot", + "could", + "dear", + "did", + "does", + "either", + "ever", + "every", + "from", + "got", + "had", + "has", + "have", + "he", + "her", + "hers", + "him", + "his", + "how", + "however", + "i", + "if", + "into", + "it", + "its", + "just", + "least", + "like", + "likely", + "may", + "me", + "might", + "most", + "must", + "my", + "neither", + "no", + "nor", + "not", + "of", + "off", + "often", + "on", + "or", + "other", + "our", + "own", + "rather", + "said", + "say", + "says", + "she", + "should", + "since", + "so", + "some", + "than", + "that", + "the", + "their", + "them", + "then", + "there", + "these", + "they", + "this", + "tis", + "to", + "too", + "twas", + "us", + "wants", + "was", + "we", + "were", + "what", + "when", + "who", + "whom", + "why", + "will", + "would", + "yet", + "you", + "your", + ]); + + let index = new MiniSearch({ + fields: ["title", "text"], // fields to index for full-text search + storeFields: ["location", "title", "text", "category", "page"], // fields to return with results processTerm: (term) => { let word = stopWords.has(term) ? null : term; if (word) { + // custom trimmer that doesn't strip @ and !, which are used in julia macro and function names word = word .replace(/^[^a-zA-Z0-9@!]+/, "") .replace(/[^a-zA-Z0-9@!]+$/, ""); + + word = word.toLowerCase(); } return word ?? null; }, + // add . as a separator, because otherwise "title": "Documenter.Anchors.add!", would not + // find anything if searching for "add!", only for the entire qualification tokenize: (string) => string.split(/[\s\-\.]+/), - }, -}); + // options which will be applied during the search + searchOptions: { + prefix: true, + boost: { title: 100 }, + fuzzy: 2, + }, + }); -index.addAll(data); + index.addAll(data); + + /** + * Used to map characters to HTML entities. + * Refer: https://github.com/lodash/lodash/blob/main/src/escape.ts + */ + const htmlEscapes = { + "&": "&", + "<": "<", + ">": ">", + '"': """, + "'": "'", + }; + + /** + * Used to match HTML entities and HTML characters. + * Refer: https://github.com/lodash/lodash/blob/main/src/escape.ts + */ + const reUnescapedHtml = /[&<>"']/g; + const reHasUnescapedHtml = RegExp(reUnescapedHtml.source); + + /** + * Escape function from lodash + * Refer: https://github.com/lodash/lodash/blob/main/src/escape.ts + */ + function escape(string) { + return string && reHasUnescapedHtml.test(string) + ? string.replace(reUnescapedHtml, (chr) => htmlEscapes[chr]) + : string || ""; + } -let filters = [...new Set(data.map((x) => x.category))]; -var modal_filters = make_modal_body_filters(filters); -var filter_results = []; + /** + * Make the result component given a minisearch result data object and the value + * of the search input as queryString. To view the result object structure, refer: + * https://lucaong.github.io/minisearch/modules/_minisearch_.html#searchresult + * + * @param {object} result + * @param {string} querystring + * @returns string + */ + function make_search_result(result, querystring) { + let search_divider = `
`; + let display_link = + result.location.slice(Math.max(0), Math.min(50, result.location.length)) + + (result.location.length > 30 ? "..." : ""); // To cut-off the link because it messes with the overflow of the whole div + + if (result.page !== "") { + display_link += ` (${result.page})`; + } -$(document).on("keyup", ".documenter-search-input", function (event) { - // Adding a debounce to prevent disruptions from super-speed typing! - debounce(() => update_search(filter_results), 300); + let textindex = new RegExp(`${querystring}`, "i").exec(result.text); + let text = + textindex !== null + ? result.text.slice( + Math.max(textindex.index - 100, 0), + Math.min( + textindex.index + querystring.length + 100, + result.text.length + ) + ) + : ""; // cut-off text before and after from the match + + text = text.length ? escape(text) : ""; + + let display_result = text.length + ? "..." + + text.replace( + new RegExp(`${escape(querystring)}`, "i"), // For first occurrence + '$&' + ) + + "..." + : ""; // highlights the match + + let in_code = false; + if (!["page", "section"].includes(result.category.toLowerCase())) { + in_code = true; + } + + // We encode the full url to escape some special characters which can lead to broken links + let result_div = ` + +
+
${escape(result.title)}
+
${result.category}
+
+

+ ${display_result} +

+
+ ${display_link} +
+
+ ${search_divider} + `; + + return result_div; + } + + self.onmessage = function (e) { + let query = e.data; + let results = index.search(query, { + filter: (result) => { + // Only return relevant results + return result.score >= 1; + }, + }); + + // Pre-filter to deduplicate and limit to 200 per category to the extent + // possible without knowing what the filters are. + let filtered_results = []; + let counts = {}; + for (let filter of filters) { + counts[filter] = 0; + } + let present = {}; + + for (let result of results) { + cat = result.category; + cnt = counts[cat]; + if (cnt < 200) { + id = cat + "---" + result.location; + if (present[id]) { + continue; + } + present[id] = true; + filtered_results.push({ + location: result.location, + category: cat, + div: make_search_result(result, query), + }); + } + } + + postMessage(filtered_results); + }; +} + +// `worker = Threads.@spawn worker_function(documenterSearchIndex)`, but in JavaScript! +const filters = [ + ...new Set(documenterSearchIndex["docs"].map((x) => x.category)), +]; +const worker_str = + "(" + + worker_function.toString() + + ")(" + + JSON.stringify(documenterSearchIndex["docs"]) + + "," + + JSON.stringify(documenterBaseURL) + + "," + + JSON.stringify(filters) + + ")"; +const worker_blob = new Blob([worker_str], { type: "text/javascript" }); +const worker = new Worker(URL.createObjectURL(worker_blob)); + +/////// SEARCH MAIN /////// + +// Whether the worker is currently handling a search. This is a boolean +// as the worker only ever handles 1 or 0 searches at a time. +var worker_is_running = false; + +// The last search text that was sent to the worker. This is used to determine +// if the worker should be launched again when it reports back results. +var last_search_text = ""; + +// The results of the last search. This, in combination with the state of the filters +// in the DOM, is used compute the results to display on calls to update_search. +var unfiltered_results = []; + +// Which filter is currently selected +var selected_filter = ""; + +$(document).on("input", ".documenter-search-input", function (event) { + if (!worker_is_running) { + launch_search(); + } }); +function launch_search() { + worker_is_running = true; + last_search_text = $(".documenter-search-input").val(); + worker.postMessage(last_search_text); +} + +worker.onmessage = function (e) { + if (last_search_text !== $(".documenter-search-input").val()) { + launch_search(); + } else { + worker_is_running = false; + } + + unfiltered_results = e.data; + update_search(); +}; + $(document).on("click", ".search-filter", function () { if ($(this).hasClass("search-filter-selected")) { - $(this).removeClass("search-filter-selected"); + selected_filter = ""; } else { - $(this).addClass("search-filter-selected"); + selected_filter = $(this).text().toLowerCase(); } - // Adding a debounce to prevent disruptions from crazy clicking! - debounce(() => get_filters(), 300); + // This updates search results and toggles classes for UI: + update_search(); }); -/** - * A debounce function, takes a function and an optional timeout in milliseconds - * - * @function callback - * @param {number} timeout - */ -function debounce(callback, timeout = 300) { - clearTimeout(timer); - timer = setTimeout(callback, timeout); -} - /** * Make/Update the search component - * - * @param {string[]} selected_filters */ -function update_search(selected_filters = []) { - let initial_search_body = ` -
Type something to get started!
- `; - +function update_search() { let querystring = $(".documenter-search-input").val(); if (querystring.trim()) { - results = index.search(querystring, { - filter: (result) => { - // Filtering results - if (selected_filters.length === 0) { - return result.score >= 1; - } else { - return ( - result.score >= 1 && selected_filters.includes(result.category) - ); - } - }, - }); + if (selected_filter == "") { + results = unfiltered_results; + } else { + results = unfiltered_results.filter((result) => { + return selected_filter == result.category.toLowerCase(); + }); + } let search_result_container = ``; + let modal_filters = make_modal_body_filters(); let search_divider = `
`; if (results.length) { @@ -449,19 +690,23 @@ function update_search(selected_filters = []) { let count = 0; let search_results = ""; - results.forEach(function (result) { - if (result.location) { - // Checking for duplication of results for the same page - if (!links.includes(result.location)) { - search_results += make_search_result(result, querystring); - count++; - } - + for (var i = 0, n = results.length; i < n && count < 200; ++i) { + let result = results[i]; + if (result.location && !links.includes(result.location)) { + search_results += result.div; + count++; links.push(result.location); } - }); + } - let result_count = `
${count} result(s)
`; + if (count == 1) { + count_str = "1 result"; + } else if (count == 200) { + count_str = "200+ results"; + } else { + count_str = count + " results"; + } + let result_count = `
${count_str}
`; search_result_container = `
@@ -490,125 +735,37 @@ function update_search(selected_filters = []) { $(".search-modal-card-body").html(search_result_container); } else { - filter_results = []; - modal_filters = make_modal_body_filters(filters, filter_results); - if (!$(".search-modal-card-body").hasClass("is-justify-content-center")) { $(".search-modal-card-body").addClass("is-justify-content-center"); } - $(".search-modal-card-body").html(initial_search_body); + $(".search-modal-card-body").html(` +
Type something to get started!
+ `); } } /** * Make the modal filter html * - * @param {string[]} filters - * @param {string[]} selected_filters * @returns string */ -function make_modal_body_filters(filters, selected_filters = []) { - let str = ``; - - filters.forEach((val) => { - if (selected_filters.includes(val)) { - str += `${val}`; - } else { - str += `${val}`; - } - }); +function make_modal_body_filters() { + let str = filters + .map((val) => { + if (selected_filter == val.toLowerCase()) { + return `${val}`; + } else { + return `${val}`; + } + }) + .join(""); - let filter_html = ` + return `
Filters: ${str} -
- `; - - return filter_html; -} - -/** - * Make the result component given a minisearch result data object and the value of the search input as queryString. - * To view the result object structure, refer: https://lucaong.github.io/minisearch/modules/_minisearch_.html#searchresult - * - * @param {object} result - * @param {string} querystring - * @returns string - */ -function make_search_result(result, querystring) { - let search_divider = `
`; - let display_link = - result.location.slice(Math.max(0), Math.min(50, result.location.length)) + - (result.location.length > 30 ? "..." : ""); // To cut-off the link because it messes with the overflow of the whole div - - if (result.page !== "") { - display_link += ` (${result.page})`; - } - - let textindex = new RegExp(`\\b${querystring}\\b`, "i").exec(result.text); - let text = - textindex !== null - ? result.text.slice( - Math.max(textindex.index - 100, 0), - Math.min( - textindex.index + querystring.length + 100, - result.text.length - ) - ) - : ""; // cut-off text before and after from the match - - let display_result = text.length - ? "..." + - text.replace( - new RegExp(`\\b${querystring}\\b`, "i"), // For first occurrence - '$&' - ) + - "..." - : ""; // highlights the match - - let in_code = false; - if (!["page", "section"].includes(result.category.toLowerCase())) { - in_code = true; - } - - // We encode the full url to escape some special characters which can lead to broken links - let result_div = ` - -
-
${result.title}
-
${result.category}
-
-

- ${display_result} -

-
- ${display_link} -
-
- ${search_divider} - `; - - return result_div; -} - -/** - * Get selected filters, remake the filter html and lastly update the search modal - */ -function get_filters() { - let ele = $(".search-filters .search-filter-selected").get(); - filter_results = ele.map((x) => $(x).text().toLowerCase()); - modal_filters = make_modal_body_filters(filters, filter_results); - update_search(filter_results); +
`; } }) @@ -635,103 +792,107 @@ $(document).ready(function () { //////////////////////////////////////////////////////////////////////////////// require(['jquery'], function($) { -let search_modal_header = ` - -`; - -let initial_search_body = ` -
Type something to get started!
-`; - -let search_modal_footer = ` - -`; - -$(document.body).append( - ` - source
Base.:*Method
(*)(q::QuatRotation, w::QuatRotation)

Quternion Composition

Equivalent to

lmult(q) * SVector(w)
+rmult(w) * SVector(q)

Sets the output mapping equal to the mapping of w

source
Base.:*Method
(*)(q::QuatRotation, r::StaticVector)

Rotate a vector

Equivalent to hmat()' lmult(q) * rmult(q)' hmat() * r

source
Quaternions.slerpMethod
slerp(R1::Rotaion{3}, R2::Rotaion{3}, t::Real)

Perform spherical linear interpolation (Slerp) between rotations R1 and R2.

source
Rotations.add_errorMethod
add_error(R1::Rotation, e::RotationError)

"Adds" the rotation error e to the rotation R1 by converting e to a quaternion via its ErrorMap and then composing with R1.

Equivalent to

R1 ⊕ e
source
Rotations.hmatMethod
hmat()
+hmat(r::AbstractVector)

hmat()*r or hmat(r) converts r into a pure quaternion, where r is 3-dimensional.

hmat() == vmat()'

source
Rotations.isrotationFunction
isrotation(r)
+isrotation(r, tol)

Check whether r is a rotation matrix, where r * r' is within tol of the identity matrix (using the Frobenius norm). tol defaults to 1000 * eps(float(eltype(r))) or zero(T) for integer T.

source
Rotations.isrotationgeneratorFunction
isrotationgenerator(r)

Check whether r is a rotation generator matrix (skew-symmetric matrix).

source
Rotations.jacobianFunction
jacobian(::InvErrorMap, q::QuatRotation)

Jacobian of the inverse quaternion map, returning a 3×4 matrix. For all maps: jacobian(::InvErrorMap, QuatRotation(I)) = [0 I] = Hmat()'

source
Rotations.jacobianFunction
jacobian(::ErrorMap, ϕ)

Jacobian of the quaternion map that takes a three-dimensional vector ϕ and returns a unit quaternion. Returns a 4x3 Static Matrix

For all the maps (except the IdentityMap) jacobian(::ErrorMap, zeros(3)) = [0; I] = Hmat()'

source
Rotations.jacobianMethod
jacobian(::Type{output_param}, R::input_param)

Returns the jacobian for transforming from the input rotation parameterization to the output parameterization, centered at the value of R.

jacobian(R::rotation_type, X::AbstractVector)

Returns the jacobian for rotating the vector X by R.

source
Rotations.kinematicsMethod
kinematics(R::Rotation{3}, ω::AbstractVector)

The time derivative of the rotation R, according to the definition

\[Ṙ = \lim_{Δt → 0} \frac{R(t + Δt) - R(t)}{Δt}\]

where ω is the angular velocity. This is equivalent to

\[Ṙ = \lim_{Δt → 0} \frac{R δR - R}{Δt}\]

where $δR$ is some small rotation, parameterized by a small rotation $δθ$ about an axis $r$, such that $\lim_{Δt → 0} \frac{δθ r}{Δt} = ω$

The kinematics are extremely useful when computing the dynamics of rigid bodies, since Ṙ = kinematics(R,ω) is the first-order ODE for the evolution of the attitude dynamics.

See "Fundamentals of Spacecraft Attitude Determination and Control" by Markley and Crassidis Sections 3.1-3.2 for more details.

source
Rotations.lmultMethod
lmult(q::QuatRotation)
+lmult(q::StaticVector{4})

lmult(q2)*params(q1) returns a vector equivalent to q2*q1 (quaternion composition)

source
Rotations.nearest_rotationMethod
nearest_rotation(M) -> RotMatrix

Get the nearest special orthonormal matrix from given matrix M. See Wahba's problem for more information.

source
Rotations.paramsMethod
params(R::Rotation)

Return an SVector of the underlying parameters used by the rotation representation.

Example

p = MRP(1.0, 2.0, 3.0)
+Rotations.params(p) == @SVector [1.0, 2.0, 3.0]  # true
source
Rotations.perpendicular_vectorMethod
perpendicular_vector(vec)

Compute a vector perpendicular to vec by switching the two elements with largest absolute value, flipping the sign of the second largest, and setting the remaining element to zero.

source
Rotations.principal_valueMethod
principal_value(R::Rotation{3})

Background: All non RotMatrix rotation types can represent the same RotMatrix in two or more ways. Sometimes a particular set of numbers is better conditioned (e.g. MRP) or obeys a particular convention (e.g. AngleAxis has non-negative rotation). In order to preserve differentiability it is necessary to allow rotation representations to travel slightly away from the nominal domain; this is critical for applications such as optimization or dynamics.

This function takes a rotation type (e.g. QuatRotation, RotXY) and outputs a new rotation of the same type that corresponds to the same RotMatrix, but that obeys certain conventions or is better conditioned. The outputs of the function have the following properties:

  • all angles are between between -pi to pi (except for AngleAxis which is between 0 and pi).
  • all `QuatRotation have non-negative real part
  • the components of all MRP have a norm that is at most 1.
  • the RotationVec rotation is at most pi
source
Rotations.pure_quaternionMethod
pure_quaternion(v::AbstractVector)
+pure_quaternion(x, y, z)

Create a Quaternion with zero scalar part (i.e. q.q.s == 0).

source
Rotations.rmultMethod
rmult(q::QuatRotation)
+rmult(q::StaticVector{4})

rmult(q1)*params(q2) return a vector equivalent to q2*q1 (quaternion composition)

source
Rotations.rot_eltypeMethod

The element type for a rotation matrix with a given angle type is composed of trigonometric functions of that type.

source
Rotations.rotation_betweenFunction
rotation_between(u, v)

Compute the quaternion that rotates vector u so that it aligns with vector v, along the geodesic (shortest path).

source
Rotations.rotation_errorMethod
rotation_error(R1::Rotation, R2::Rotation, error_map::ErrorMap)

Compute the RotationError by calculating the "difference" between R1 and R2, i.e. R2\R1, then mapped to a three-parameter error using error_map.

Can be equivalently called using the default map with R1 ⊖ R2

If error_map::IdentityMap, then SVector(R1\R2)::SVector{3} is used as the error. Note this only works for three-parameter rotation representations such as RodriguesParam or MRP.

source
Rotations.tmatMethod
tmat()

tmat()*params(q)return a vector equivalent to inv(q), where q is a QuatRotation

source
Rotations.vmatMethod
vmat()

vmat()*params(q)returns the imaginary (vector) part of the quaternionq(equivalent tovector(q)``)

source
Rotations.∇composition1Method
∇composition1(R2::Rotation{3}, R1::Rotation{3})

Jacobian of R2*R1 with respect to R1

source
Rotations.∇composition2Method
∇composition2(R2::Rotation{3}, R1::Rotation{3})

Jacobian of R2*R1 with respect to R2

source
Rotations.∇differentialMethod
∇differential(q::QuatRotation)

Jacobian of lmult(q) QuatMap(ϕ), when ϕ is near zero.

Useful for converting Jacobians from R⁴ to R³ and correctly account for unit norm constraint. Jacobians for different differential quaternion parameterization are the same up to a constant.

source
Rotations.∇errMethod
∇err(p1::MRP, p2::MRP)

Jacobian of p1\p2 wrt p2

source
Rotations.∇jacobianFunction
∇jacobian(::InvErrorMap, q::QuatRotation, b::SVector{3})

Jacobian of G(q)'b, where G(q) = jacobian(::InvErrorMap, q), b is a 3-element vector

source
Rotations.∇rotateMethod
∇rotate(R::Rotation{3}, r::AbstractVector)

Jacobian of R*r with respect to the rotation

source
Rotations.∇²differentialMethod
∇²differential(q::QuatRotation, b::AbstractVector)

Jacobian of (∂/∂ϕ lmult(q) QuatMap(ϕ))b, evaluated at ϕ=0, and b has length 4.

source
Rotations.∇²errMethod
∇²err(p1::MRP, p2::MRP, b::StaticVector{3})

Jacobian of (∂/∂p p1\p2)'b wrt p2

source
diff --git a/dev/functions/index.html b/dev/functions/index.html index 9e719c5..a181468 100644 --- a/dev/functions/index.html +++ b/dev/functions/index.html @@ -35,17 +35,17 @@ 0.0 0.0 0.0

isrotation

Check the given matrix is rotation matrix.

example

(TBW)

nearest_rotation

Get the nearest special orthonormal matrix from given matrix M. The problem of finding the orthogonal matrix nearest to a given matrix is related to the Wahba's problem.

example

julia> M = randn(3,3)  # Generate random matrix3×3 Matrix{Float64}:
-  0.442069  0.39401    1.20134
- -0.166787  0.64132   -0.441644
-  0.967088  0.258446   0.997561
julia> R = nearest_rotation(M) # Find the nearest rotation matrix3×3 RotMatrix3{Float64} with indices SOneTo(3)×SOneTo(3): - 0.952151 0.267185 0.148395 - -0.220859 0.937131 -0.270196 - -0.211258 0.224493 0.951301
julia> U, V = R\M, M/R # Polar decomposition of M([0.253448090476701 0.1789170102382304 1.0306580453637688; 0.1789170102382302 0.7642936213738076 0.13104695135940536; 1.0306580453637684 0.13104695135940558 1.246583931693863], [0.7044634338168254 -0.052993540136089756 1.1378999548275333; -0.05299354013608957 0.7571677940178116 -0.24092946902475107; 1.1378999548275333 -0.24092946902475076 0.8026944157097348])
julia> U ≈ U' # U is a symmetric matrix (The same for V)true

rand

rand for $SO(2)$

The following types have the same algebraic structure as $SO(2)$

The random distribution is based on Haar measure.

example

julia> R = rand(Angle2d)2×2 Angle2d{Float64} with indices SOneTo(2)×SOneTo(2)(5.92495):
-  0.936517  0.350623
- -0.350623  0.936517

rand for $SO(3)$

The following types have an algebraic structure that is homomorphic to $SO(3)$.

example

julia> R = rand(RotationVec)3×3 RotationVec{Float64} with indices SOneTo(3)×SOneTo(3)(1.70704, -1.45996, -1.13718):
-  0.021227  -0.448394  -0.893584
- -0.976159  -0.202411   0.0783799
- -0.216016   0.870616  -0.442001

The random distribution is based on Haar measure.

rand for RotXY and etc.

There also are methods for rand(::RotXY) and other 2-axis rotations.

example

julia> R = rand(RotXY)3×3 RotXY{Float64} with indices SOneTo(3)×SOneTo(3)(5.72438, 1.13987):
-  0.41771    0.0       0.90858
- -0.481705   0.847889  0.221459
- -0.770376  -0.530173  0.354172

The random distribution is NOT based on Haar measure because the set of RotXY doesn't have group structure.

Note that:

+ 0.108071 0.815012 -1.01709 + 0.00314509 0.76479 0.518906 + -0.268036 -0.0841989 0.970901
julia> R = nearest_rotation(M) # Find the nearest rotation matrix3×3 RotMatrix3{Float64} with indices SOneTo(3)×SOneTo(3): + 0.603942 0.616426 -0.505245 + -0.49322 0.787004 0.370619 + 0.62609 0.0253642 0.779338
julia> U, V = R\M, M/R # Polar decomposition of M([-0.10409719452140989 0.06229432700073618 -0.26232723968797106; 0.06229432700073592 1.1021517238627405 -0.1939542073305788; -0.2623272396879715 -0.1939542073305794 1.4628578920200628], [1.0815434869290217 0.2111611642681816 -0.7043239732942626; 0.2111611642681809 0.7926584092522306 0.4257705695724016; -0.7043239732942627 0.42577056957240145 0.5867105251801409])
julia> U ≈ U' # U is a symmetric matrix (The same for V)true

rand

rand for $SO(2)$

The following types have the same algebraic structure as $SO(2)$

The random distribution is based on Haar measure.

example

julia> R = rand(Angle2d)2×2 Angle2d{Float64} with indices SOneTo(2)×SOneTo(2)(1.70268):
+ -0.131499  -0.991316
+  0.991316  -0.131499

rand for $SO(3)$

The following types have an algebraic structure that is homomorphic to $SO(3)$.

example

julia> R = rand(RotationVec)3×3 RotationVec{Float64} with indices SOneTo(3)×SOneTo(3)(0.412973, 0.498808, 2.00269):
+ -0.450884   -0.748863  0.485704
+  0.889193   -0.424226  0.171371
+  0.0777151   0.509152  0.857161

The random distribution is based on Haar measure.

rand for RotXY and etc.

There also are methods for rand(::RotXY) and other 2-axis rotations.

example

julia> R = rand(RotXY)3×3 RotXY{Float64} with indices SOneTo(3)×SOneTo(3)(0.342432, 4.231):
+ -0.463006  0.0       -0.886355
+ -0.297619  0.941941   0.155468
+  0.834894  0.335779  -0.436125

The random distribution is NOT based on Haar measure because the set of RotXY doesn't have group structure.

Note that:

diff --git a/dev/general_dimensional_rotations/index.html b/dev/general_dimensional_rotations/index.html index d848abe..c54e2fe 100644 --- a/dev/general_dimensional_rotations/index.html +++ b/dev/general_dimensional_rotations/index.html @@ -4,27 +4,27 @@ 0 1 0 0 0 0 1 0 0 0 0 1
julia> m = @SMatrix rand(4,4)4×4 StaticArraysCore.SMatrix{4, 4, Float64, 16} with indices SOneTo(4)×SOneTo(4): - 0.355895 0.838825 0.155947 0.937487 - 0.90939 0.691275 0.104106 0.428423 - 0.481759 0.84487 0.566498 0.833736 - 0.222166 0.428292 0.268192 0.129157
julia> r2 = nearest_rotation(m) # nearest rotation matrix from given matrix4×4 RotMatrix{4, Float64, 16} with indices SOneTo(4)×SOneTo(4): - -0.199257 0.577091 -0.412725 0.675959 - 0.955914 0.210665 -0.203357 -0.022237 - 0.179269 0.0451929 0.832365 0.522484 - -0.11995 0.787746 0.308987 -0.519225
julia> r3 = rand(RotMatrix{4}) # random rotation in SO(4)4×4 RotMatrix{4, Float64, 16} with indices SOneTo(4)×SOneTo(4): - -0.101093 -0.553769 -0.754009 0.338511 - 0.500042 0.329763 0.0495786 0.799223 - 0.838837 -0.0913955 -0.256878 -0.471182 - 0.189975 -0.759107 0.602516 0.156975
julia> r1*r2/r3 # multiplication and division4×4 RotMatrix{4, Float64, 16} with indices SOneTo(4)×SOneTo(4): - 0.240587 0.610446 -0.432367 -0.618492 - -0.0674902 0.519612 0.845318 -0.104334 - -0.493893 0.563393 -0.313755 0.58328 - -0.832846 -0.199868 -0.00733768 -0.516107
julia> s = log(r2) # logarithm of RotMatrix is a RotMatrixGenerator4×4 RotMatrixGenerator{4, Float64, 16} with indices SOneTo(4)×SOneTo(4): - 0.0 -0.740838 -0.675001 1.75919 - 0.740838 0.0 0.178532 -1.44671 - 0.675001 -0.178532 0.0 0.155563 - -1.75919 1.44671 -0.155563 0.0
julia> exp(s) # exponential of RotMatrixGenerator is a RotMatrix4×4 RotMatrix{4, Float64, 16} with indices SOneTo(4)×SOneTo(4): - -0.199257 0.577091 -0.412725 0.675959 - 0.955914 0.210665 -0.203357 -0.022237 - 0.179269 0.0451929 0.832365 0.522484 - -0.11995 0.787746 0.308987 -0.519225 + 0.49579 0.40281 0.0386866 0.0208903 + 0.739067 0.599312 0.00289439 0.587874 + 0.331874 0.601825 0.851533 0.516978 + 0.686723 0.0396792 0.83876 0.115409
julia> r2 = nearest_rotation(m) # nearest rotation matrix from given matrix4×4 RotMatrix{4, Float64, 16} with indices SOneTo(4)×SOneTo(4): + 0.441975 0.659781 -0.0984268 -0.599716 + 0.569614 0.21248 -0.352542 0.711412 + -0.246016 0.591097 0.679964 0.357393 + 0.647823 -0.412488 0.635355 -0.0806483
julia> r3 = rand(RotMatrix{4}) # random rotation in SO(4)4×4 RotMatrix{4, Float64, 16} with indices SOneTo(4)×SOneTo(4): + -0.457885 0.0284017 -0.104657 -0.882373 + -0.74795 -0.186907 0.552652 0.316564 + 0.41473 -0.705475 0.492436 -0.296329 + 0.242717 0.683055 0.664176 -0.182743
julia> r1*r2/r3 # multiplication and division4×4 RotMatrix{4, Float64, 16} with indices SOneTo(4)×SOneTo(4): + 0.35584 -0.698137 -0.152915 0.602163 + -0.845617 -0.435383 -0.298079 -0.0807646 + -0.257082 0.562449 -0.290102 0.730343 + -0.303676 -0.0818421 0.896441 0.312211
julia> s = log(r2) # logarithm of RotMatrix is a RotMatrixGenerator4×4 RotMatrixGenerator{4, Float64, 16} with indices SOneTo(4)×SOneTo(4): + 0.0 0.138605 0.33023 -1.17768 + -0.138605 0.0 -0.808326 1.21512 + -0.33023 0.808326 0.0 -0.308815 + 1.17768 -1.21512 0.308815 0.0
julia> exp(s) # exponential of RotMatrixGenerator is a RotMatrix4×4 RotMatrix{4, Float64, 16} with indices SOneTo(4)×SOneTo(4): + 0.441975 0.659781 -0.0984268 -0.599716 + 0.569614 0.21248 -0.352542 0.711412 + -0.246016 0.591097 0.679964 0.357393 + 0.647823 -0.412488 0.635355 -0.0806483 diff --git a/dev/index.html b/dev/index.html index 90b974a..d7d42ad 100644 --- a/dev/index.html +++ b/dev/index.html @@ -45,4 +45,4 @@ -0.94644 -0.415371 -0.688138 -0.353725 -0.258529 0.369901 0.362841 -0.597826 1.25153 -0.209024 -1.1474 0.763531 - 0.903621 1.17038 -0.319595 -1.22854 + 0.903621 1.17038 -0.319595 -1.22854 diff --git a/dev/objects.inv b/dev/objects.inv new file mode 100644 index 0000000000000000000000000000000000000000..e4f4a8b8a5eaa3fc463af6b580f7681f78ca2da9 GIT binary patch literal 1987 zcmV;!2R!&AAX9K?X>NERX>N99Zgg*Qc_4OWa&u{KZXhxWBOp+6Z)#;@bUGkXZ**aF zX>V?GE^2HFBOq2~a&u{KZaN?_E;lYP3L_v?Xk{RBWo=<;Ze(S0Aa78b#rNMXCQiPX<{x4c$~Fb$#UB^7{2oB_5yK=jkK#QTinP0g_kgR#B>onsS1P-*JVGB88dEJLmxPjZNo?xH<_Nv6mY_PS zHP6bbun5ZBn=JBz;$;!&@k{W6B$n2E_7kc(#1;r))jg>jK=5iU0GxrTEfC3W)7z|B zn+51fDYcWJj%9Eg7uNyr)}ZWG!@jbkL8e-1j7@LyI2Wok39=fvdqOd$*(QyG;+hf? z;5(8BJE|GGZFY1B@WVq@gdhGQ4KAq>r$&q#?WpGOdMUw_`2J}u&<(drWXz!pJ_YGP5) zAIY*0!^Ztlu%Bj)qLWcj&ViOXQ;!W0V>>v!P0sjF&);{law-H=mP!~8^dj)yrg?#r z#A0a)4|TM8(%McIH6?zKo$Z&a;TdR~tZ6 zIYF6NtPEh!7(bL;rvz4xEbKxL5>(2hw(E&izSyaj1yK||BIkqO-Sj&o_;dsyZ)?3l zv4B#gT9 zZj#IiVEa=f@c(`^v&YNiv2SpY5T8 zM|2B=5kWJTwrtf5Vd~P&`k^8li$<80e-8MFbGmA z`{16n$1Ypj;GK{HmVk)T2==3)uzvq?2xIeoE%=?yKM#ZZ@N5sAm8}@cR)p_z^RZq# z8}7B;BBk{PcIa6drn6?FhGwHy`+^ZxG@7#>Y#tJ)241ni%^rUckPnVXH)hG8&B_qi zip$|Rlf23IgI_Wj{MH*vlv%!>5x1Q>tm4?r*g0d|z%^FuCD9aoRD;xuZ_y;P;YLaE zN`8$>u7FvlC!Tmj04w9h4_7dQHJrxz@6mjQXaqf8jYpWUp?Cg2R+6FEAU#uG0;PrKi z*Dj{Z|5V@#MNUlv5vreS7+Xz0I2MAr<>A7`mg}b-cdnm&+$o;cf#S&>;O*)7ipqb@ z7o@l)WIzq+{PKU6T&ex-BI0d&vrT`of3kE1E~m~?{?m-3N6iD?IT_tg8tUUl9XYp` VZ$nG#<3{tTqt;g< -References · Rotations.jl
+References · Rotations.jl
diff --git a/dev/rotation_generator_types/index.html b/dev/rotation_generator_types/index.html index 3ec45d4..1ea7436 100644 --- a/dev/rotation_generator_types/index.html +++ b/dev/rotation_generator_types/index.html @@ -5,4 +5,4 @@ Angle2dGenerator RotMatrixGenerator{2}
julia> subtypes(RotationGenerator{3})2-element Vector{Any}: RotMatrixGenerator{3} - RotationVecGenerator

Overview of each type

For more information, see the sidebar page.

2D rotations

  • RotMatrixGenerator2{T}
    • Skew symmetric matrix in 2 dimensional Euclidean space.
  • Angle2dGenerator
    • Parametrized with one real number like Angle2d.

3D rotations

  • RotMatrixGenerator3{T}
    • Skew symmetric matrix in 3 dimensional Euclidean space.
  • RotationVecGenerator
    • Rotation generator around given axis. The length of axis vector represents its angle.
+ RotationVecGenerator

Overview of each type

For more information, see the sidebar page.

2D rotations

  • RotMatrixGenerator2{T}
    • Skew symmetric matrix in 2 dimensional Euclidean space.
  • Angle2dGenerator
    • Parametrized with one real number like Angle2d.

3D rotations

  • RotMatrixGenerator3{T}
    • Skew symmetric matrix in 3 dimensional Euclidean space.
  • RotationVecGenerator
    • Rotation generator around given axis. The length of axis vector represents its angle.
diff --git a/dev/rotation_types/index.html b/dev/rotation_types/index.html index 9a879a7..b477309 100644 --- a/dev/rotation_types/index.html +++ b/dev/rotation_types/index.html @@ -23,4 +23,4 @@ RotZY RotZYX RotZYZ - RotationVec

Overview of each type

For more information, see the sidebar page.

2D rotations

  • RotMatrix2{T}
    • Rotation matrix in 2 dimensional Euclidean space.
  • Angle2d
    • Parametrized with rotational angle.

3D rotations

  • RotMatrix3{T}
    • Rotation matrix in 3 dimensional Euclidean space.
  • RotX, RotYZ, RotXYZ and etc.
    • Euler angles.
  • AngleAxis
    • Rotation around given axis and angle.
  • RotationVec
    • Rotation around given axis. The length of axis vector represents its angle.
  • QuatRotation
    • A 3D rotation parameterized by a unit quaternion.
  • MRP
    • A 3D rotation encoded by the stereographic projection of a unit quaternion.
+ RotationVec

Overview of each type

For more information, see the sidebar page.

2D rotations

  • RotMatrix2{T}
    • Rotation matrix in 2 dimensional Euclidean space.
  • Angle2d
    • Parametrized with rotational angle.

3D rotations

  • RotMatrix3{T}
    • Rotation matrix in 3 dimensional Euclidean space.
  • RotX, RotYZ, RotXYZ and etc.
    • Euler angles.
  • AngleAxis
    • Rotation around given axis and angle.
  • RotationVec
    • Rotation around given axis. The length of axis vector represents its angle.
  • QuatRotation
    • A 3D rotation parameterized by a unit quaternion.
  • MRP
    • A 3D rotation encoded by the stereographic projection of a unit quaternion.
diff --git a/dev/search_index.js b/dev/search_index.js index 103e7f9..ae468fb 100644 --- a/dev/search_index.js +++ b/dev/search_index.js @@ -1,3 +1,3 @@ var documenterSearchIndex = {"docs": -[{"location":"3d_rotation_generator/#3D-Rotation-Generator","page":"3D Rotation Generators","title":"3D Rotation Generator","text":"","category":"section"},{"location":"3d_rotation_generator/","page":"3D Rotation Generators","title":"3D Rotation Generators","text":"using Rotations","category":"page"},{"location":"3d_rotation_generator/#RotMatrixGenerator3","page":"3D Rotation Generators","title":"RotMatrixGenerator3","text":"","category":"section"},{"location":"3d_rotation_generator/","page":"3D Rotation Generators","title":"3D Rotation Generators","text":"example","category":"page"},{"location":"3d_rotation_generator/","page":"3D Rotation Generators","title":"3D Rotation Generators","text":"m = rand(3,3)\ns = RotMatrixGenerator{3}(m - m')\nexp(s)","category":"page"},{"location":"3d_rotation_generator/#RotationVecGenerator","page":"3D Rotation Generators","title":"RotationVecGenerator","text":"","category":"section"},{"location":"3d_rotation_generator/","page":"3D Rotation Generators","title":"3D Rotation Generators","text":"example","category":"page"},{"location":"3d_rotation_generator/","page":"3D Rotation Generators","title":"3D Rotation Generators","text":"s = RotationVecGenerator(0.1,0.2,0.3)\nexp(s)\nlog(exp(s))\nrotation_angle(exp(s))\nrotation_angle(exp(2s))\nrotation_angle(exp(2s)) / rotation_angle(exp(s))","category":"page"},{"location":"functionreference/","page":"Function Reference","title":"Function Reference","text":"Modules = [Rotations]","category":"page"},{"location":"functionreference/#Rotations.Angle2d","page":"Function Reference","title":"Rotations.Angle2d","text":"struct Angle2d{T} <: Rotation{2,T}\n theta::T\nend\n\nA 2×2 rotation matrix parameterized by a 2D rotation by angle. Only the angle is stored inside the Angle2d type, values of getindex etc. are computed on the fly.\n\n\n\n\n\n","category":"type"},{"location":"functionreference/#Rotations.Angle2dGenerator","page":"Function Reference","title":"Rotations.Angle2dGenerator","text":"struct Angle2dGenerator{T} <: RotationGenerator{2,T}\n v::T\nend\n\nA 2×2 rotation generator matrix (i.e. skew-symmetric matrix). [ 0 -v v 0 ]\n\n\n\n\n\n","category":"type"},{"location":"functionreference/#Rotations.AngleAxis","page":"Function Reference","title":"Rotations.AngleAxis","text":"struct AngleAxis{T} <: Rotation{3,T}\nAngleAxis(Θ, x, y, z)\n\nA 3×3 rotation matrix parameterized by a 3D rotation by angle θ about an arbitrary axis [x, y, z].\n\nNote that the axis is not unique for θ = 0, and that this parameterization does not continuously map the neighbourhood of the identity rotation (and therefore might not be suitable for autodifferentation and optimization purposes).\n\nNote: by default, the constructor will renormalize the input so that the axis has length 1 (x² + y² + z² = 1).\n\nRenormalization can be skipped by passing false as an additional constructor argument, in which case the user provides the guarantee that the input arguments represent a normalized rotation axis. Operations on an AngleAxis with a rotation axis that does not have unit norm, created by skipping renormalization in this fashion, are not guaranteed to do anything sensible.\n\n\n\n\n\n","category":"type"},{"location":"functionreference/#Rotations.ErrorMap","page":"Function Reference","title":"Rotations.ErrorMap","text":"ErrorMap\n\nA nonlinear mapping between the space of unit quaternions and three-dimensional rotation errors.\n\nThese mappings are extremely useful for converting from globally nonsingular 3D rotation representations such as QuatRotation or RotMatrix3 to a three-parameter error that can be efficiently used in gradient-based optimization methods that optimize deviations about a current iterate using first or second-order information.\n\nUsage\n\nerrmap(v::AbstractVector) # \"forward\" map from a 3D error to a `QuatRotation`\ninv(errmap)(R::Rotation) # \"inverse\" map from a rotation (via `QuatRotation`) to a 3D error\n\nwhere errmap <: ErrorMap\n\nImplemented Maps\n\nCayleyMap: Uses RodriguesParam as the error representation (default). Goes singular at 180° and does not have a sign ambiguity.\nExponentialMap: Uses the canonical exponential map from Lie Group theory. Computationally expensive to compute. Exhibits kinematic singularities.\nMRPMap: Uses a scaled MRP as the error representation. Singular at 360° but has a sign ambiguity (with the \"shadow\" MRP set).\nQuatVecMap: Uses the vector part of the quaternions. Cheapest map to compute, but goes singular at 180° and suffers from sign ambiguity.\nIdentityMap: Maps values through directly. Only works with three-parameter rotation representations with the following methods: R(::SVector{3}) and SVector(::R)::SVector{3}\n\n\n\n\n\n","category":"type"},{"location":"functionreference/#Rotations.InvErrorMap","page":"Function Reference","title":"Rotations.InvErrorMap","text":"InvErrorMap\n\nThe nonlinear mapping from unit quaternions to a three-dimensional error state. Obtained by inverting an ErrorMap, i.e.\n\nInvCayleyMap() = inv(CayleyMap())\n\nUsage\n\nimap(R::Rotation) # \"inverse\" map from a rotation to a 3D error\ninv(imap)(v::AbstractVector) # \"forward\" map from a 3D error to a `QuatRotation`\n\nwhere imap <: InvErrorMap.\n\nSee ErrorMap for documentation on the implemented maps.\n\n\n\n\n\n","category":"type"},{"location":"functionreference/#Rotations.MRP","page":"Function Reference","title":"Rotations.MRP","text":"MRP{T} <: Rotation\n\nModified Rodrigues Parameter. Is a 3D parameterization of attitude, and is a sterographic projection of the 4D unit sphere onto the plane tangent to the negative real pole. They have a singularity at θ = ±360°.\n\nConstructors\n\nMRP(x, y, z) MRP(r::AbstractVector)\n\n\n\n\n\n","category":"type"},{"location":"functionreference/#Rotations.QuatRotation","page":"Function Reference","title":"Rotations.QuatRotation","text":"QuatRotation{T} <: Rotation\n\n4-parameter attitute representation that is singularity-free. Quaternions with unit norm represent a double-cover of SO(3). The QuatRotation does NOT strictly enforce the unit norm constraint, but certain methods will assume you have a unit quaternion. Follows the Hamilton convention for quaternions.\n\nConstructors\n\nQuatRotation(w,x,y,z)\nQuatRotation(q::AbstractVector)\n\nwhere w is the scalar (real) part, x, y, and z are the vector (imaginary) part, and q = [w,x,y,z].\n\n\n\n\n\n","category":"type"},{"location":"functionreference/#Rotations.RodriguesParam","page":"Function Reference","title":"Rotations.RodriguesParam","text":"RodriguesParam{T}\n\nRodrigues parameters are a three-dimensional parameterization of rotations. They have a singularity at 180° but do not inherit the sign ambiguities of quaternions or MRPs\n\n\n\n\n\n","category":"type"},{"location":"functionreference/#Rotations.RotMatrix","page":"Function Reference","title":"Rotations.RotMatrix","text":"struct RotMatrix{N,T} <: Rotation{N,T}\n\nA statically-sized, N×N unitary (orthogonal) matrix.\n\nNote: the orthonormality of the input matrix is not checked by the constructor.\n\n\n\n\n\n","category":"type"},{"location":"functionreference/#Rotations.RotMatrixGenerator","page":"Function Reference","title":"Rotations.RotMatrixGenerator","text":"struct RotMatrixGenerator{N,T} <: RotationGenerator{N,T}\n\nA statically-sized, N×N skew-symmetric matrix.\n\nNote: the skew-symmetricity of the input matrix is not checked by the constructor.\n\n\n\n\n\n","category":"type"},{"location":"functionreference/#Rotations.RotX","page":"Function Reference","title":"Rotations.RotX","text":"struct RotX{T} <: Rotation{3,T}\nRotX(theta)\n\nA 3×3 rotation matrix which represents a rotation by theta about the X axis.\n\n\n\n\n\n","category":"type"},{"location":"functionreference/#Rotations.RotXY","page":"Function Reference","title":"Rotations.RotXY","text":"struct RotXY{T} <: Rotation{3,T}\nRotXY(theta_x, theta_y)\n\nA 3×3 rotation matrix which represents a rotation by theta_y about the Y axis, followed by a rotation by theta_x about the X axis.\n\n\n\n\n\n","category":"type"},{"location":"functionreference/#Rotations.RotXYX","page":"Function Reference","title":"Rotations.RotXYX","text":"struct RotXYX{T} <: Rotation{3,T}\nRotXYX(theta1, theta2, theta3)\n\nA 3×3 rotation matrix parameterized by the \"proper\" XYX Euler angle convention, consisting of first a rotation about the X axis by theta3, followed by a rotation about the Y axis by theta2, and finally a rotation about the X axis by theta1.\n\n\n\n\n\n","category":"type"},{"location":"functionreference/#Rotations.RotXYZ","page":"Function Reference","title":"Rotations.RotXYZ","text":"struct RotXYZ{T} <: Rotation{3,T}\nRotXYZ(theta1, theta2, theta3)\nRotXYZ(roll=r, pitch=p, yaw=y)\n\nA 3×3 rotation matrix parameterized by the \"Tait-Bryant\" XYZ Euler angle convention, consisting of first a rotation about the Z axis by theta3, followed by a rotation about the Y axis by theta2, and finally a rotation about the X axis by theta1.\n\nThe keyword argument form applies roll, pitch and yaw to the X, Y and Z axes respectively, in XYZ order. (Because it is a right-handed coordinate system, note that positive pitch is heading in the negative Z axis).\n\n\n\n\n\n","category":"type"},{"location":"functionreference/#Rotations.RotXZ","page":"Function Reference","title":"Rotations.RotXZ","text":"struct RotXZ{T} <: Rotation{3,T}\nRotXZ(theta_x, theta_z)\n\nA 3×3 rotation matrix which represents a rotation by theta_z about the Z axis, followed by a rotation by theta_x about the X axis.\n\n\n\n\n\n","category":"type"},{"location":"functionreference/#Rotations.RotXZX","page":"Function Reference","title":"Rotations.RotXZX","text":"struct RotXZX{T} <: Rotation{3,T}\nRotXZX(theta1, theta2, theta3)\n\nA 3×3 rotation matrix parameterized by the \"proper\" XZX Euler angle convention, consisting of first a rotation about the X axis by theta3, followed by a rotation about the Z axis by theta2, and finally a rotation about the X axis by theta1.\n\n\n\n\n\n","category":"type"},{"location":"functionreference/#Rotations.RotXZY","page":"Function Reference","title":"Rotations.RotXZY","text":"struct RotXZY{T} <: Rotation{3,T}\nRotXZY(theta1, theta2, theta3)\nRotXZY(roll=r, pitch=p, yaw=y)\n\nA 3×3 rotation matrix parameterized by the \"Tait-Bryant\" XZY Euler angle convention, consisting of first a rotation about the Y axis by theta3, followed by a rotation about the Z axis by theta2, and finally a rotation about the X axis by theta1.\n\nThe keyword argument form applies roll, pitch and yaw to the X, Y and Z axes respectively, in XZY order. (Because it is a right-handed coordinate system, note that positive pitch is heading in the negative Z axis).\n\n\n\n\n\n","category":"type"},{"location":"functionreference/#Rotations.RotY","page":"Function Reference","title":"Rotations.RotY","text":"struct RotY{T} <: Rotation{3,T}\nRotY(theta)\n\nA 3×3 rotation matrix which represents a rotation by theta about the Y axis.\n\n\n\n\n\n","category":"type"},{"location":"functionreference/#Rotations.RotYX","page":"Function Reference","title":"Rotations.RotYX","text":"struct RotYX{T} <: Rotation{3,T}\nRotYX(theta_y, theta_x)\n\nA 3×3 rotation matrix which represents a rotation by theta_x about the X axis, followed by a rotation by theta_y about the Y axis.\n\n\n\n\n\n","category":"type"},{"location":"functionreference/#Rotations.RotYXY","page":"Function Reference","title":"Rotations.RotYXY","text":"struct RotYXY{T} <: Rotation{3,T}\nRotYXY(theta1, theta2, theta3)\n\nA 3×3 rotation matrix parameterized by the \"proper\" YXY Euler angle convention, consisting of first a rotation about the Y axis by theta3, followed by a rotation about the X axis by theta2, and finally a rotation about the Y axis by theta1.\n\n\n\n\n\n","category":"type"},{"location":"functionreference/#Rotations.RotYXZ","page":"Function Reference","title":"Rotations.RotYXZ","text":"struct RotYXZ{T} <: Rotation{3,T}\nRotYXZ(theta1, theta2, theta3)\nRotYXZ(roll=r, pitch=p, yaw=y)\n\nA 3×3 rotation matrix parameterized by the \"Tait-Bryant\" YXZ Euler angle convention, consisting of first a rotation about the Z axis by theta3, followed by a rotation about the X axis by theta2, and finally a rotation about the Y axis by theta1.\n\nThe keyword argument form applies roll, pitch and yaw to the X, Y and Z axes respectively, in YXZ order. (Because it is a right-handed coordinate system, note that positive pitch is heading in the negative Z axis).\n\n\n\n\n\n","category":"type"},{"location":"functionreference/#Rotations.RotYZ","page":"Function Reference","title":"Rotations.RotYZ","text":"struct RotYZ{T} <: Rotation{3,T}\nRotYZ(theta_y, theta_z)\n\nA 3×3 rotation matrix which represents a rotation by theta_z about the Z axis, followed by a rotation by theta_y about the Y axis.\n\n\n\n\n\n","category":"type"},{"location":"functionreference/#Rotations.RotYZX","page":"Function Reference","title":"Rotations.RotYZX","text":"struct RotYZX{T} <: Rotation{3,T}\nRotYZX(theta1, theta2, theta3)\nRotYZX(roll=r, pitch=p, yaw=y)\n\nA 3×3 rotation matrix parameterized by the \"Tait-Bryant\" YZX Euler angle convention, consisting of first a rotation about the X axis by theta3, followed by a rotation about the Z axis by theta2, and finally a rotation about the Y axis by theta1.\n\nThe keyword argument form applies roll, pitch and yaw to the X, Y and Z axes respectively, in YZX order. (Because it is a right-handed coordinate system, note that positive pitch is heading in the negative Z axis).\n\n\n\n\n\n","category":"type"},{"location":"functionreference/#Rotations.RotYZY","page":"Function Reference","title":"Rotations.RotYZY","text":"struct RotYZY{T} <: Rotation{3,T}\nRotYZY(theta1, theta2, theta3)\n\nA 3×3 rotation matrix parameterized by the \"proper\" YXY Euler angle convention, consisting of first a rotation about the Y axis by theta3, followed by a rotation about the Z axis by theta2, and finally a rotation about the Y axis by theta1.\n\n\n\n\n\n","category":"type"},{"location":"functionreference/#Rotations.RotZ","page":"Function Reference","title":"Rotations.RotZ","text":"struct RotZ{T} <: Rotation{3,T}\nRotZ(theta)\n\nA 3×3 rotation matrix which represents a rotation by theta about the Z axis.\n\n\n\n\n\n","category":"type"},{"location":"functionreference/#Rotations.RotZX","page":"Function Reference","title":"Rotations.RotZX","text":"struct RotZX{T} <: Rotation{3,T}\nRotZX(theta_z, theta_x)\n\nA 3×3 rotation matrix which represents a rotation by theta_x about the X axis, followed by a rotation by theta_z about the Z axis.\n\n\n\n\n\n","category":"type"},{"location":"functionreference/#Rotations.RotZXY","page":"Function Reference","title":"Rotations.RotZXY","text":"struct RotZXY{T} <: Rotation{3,T}\nRotZXY(theta1, theta2, theta3)\nRotZXY(roll=r, pitch=p, yaw=y)\n\nA 3×3 rotation matrix parameterized by the \"Tait-Bryant\" ZXY Euler angle convention, consisting of first a rotation about the Y axis by theta3, followed by a rotation about the X axis by theta2, and finally a rotation about the Z axis by theta1.\n\nThe keyword argument form applies roll, pitch and yaw to the X, Y and Z axes respectively, in ZXY order. (Because it is a right-handed coordinate system, note that positive pitch is heading in the negative Z axis).\n\n\n\n\n\n","category":"type"},{"location":"functionreference/#Rotations.RotZXZ","page":"Function Reference","title":"Rotations.RotZXZ","text":"struct RotZXZ{T} <: Rotation{3,T}\nRotZXZ(theta1, theta2, theta3)\n\nA 3×3 rotation matrix parameterized by the \"proper\" ZXZ Euler angle convention, consisting of first a rotation about the Z axis by theta3, followed by a rotation about the X axis by theta2, and finally a rotation about the Z axis by theta1.\n\n\n\n\n\n","category":"type"},{"location":"functionreference/#Rotations.RotZY","page":"Function Reference","title":"Rotations.RotZY","text":"struct RotZY{T} <: Rotation{3,T}\nRotZY(theta_z, theta_y)\n\nA 3×3 rotation matrix which represents a rotation by theta_y about the Y axis, followed by a rotation by theta_z about the Z axis.\n\n\n\n\n\n","category":"type"},{"location":"functionreference/#Rotations.RotZYX","page":"Function Reference","title":"Rotations.RotZYX","text":"struct RotZYX{T} <: Rotation{3,T}\nRotZYX(theta1, theta2, theta3)\nRotZYX(roll=r, pitch=p, yaw=y)\n\nA 3×3 rotation matrix parameterized by the \"Tait-Bryant\" ZYX Euler angle convention, consisting of first a rotation about the X axis by theta3, followed by a rotation about the Y axis by theta2, and finally a rotation about the Z axis by theta1.\n\nThe keyword argument form applies roll, pitch and yaw to the X, Y and Z axes respectively, in ZYX order. (Because it is a right-handed coordinate system, note that positive pitch is heading in the negative Z axis).\n\n\n\n\n\n","category":"type"},{"location":"functionreference/#Rotations.RotZYZ","page":"Function Reference","title":"Rotations.RotZYZ","text":"struct RotZYZ{T} <: Rotation{3,T}\nRotZYZ(theta1, theta2, theta3)\n\nA 3×3 rotation matrix parameterized by the \"proper\" ZXZ Euler angle convention, consisting of first a rotation about the Z axis by theta3, followed by a rotation about the Y axis by theta2, and finally a rotation about the Z axis by theta1.\n\n\n\n\n\n","category":"type"},{"location":"functionreference/#Rotations.Rotation","page":"Function Reference","title":"Rotations.Rotation","text":"abstract type Rotation{N,T} <: StaticMatrix{N,N,T}\n\nAn abstract type representing N-dimensional rotations. More abstractly, they represent unitary (orthogonal) N×N matrices.\n\n\n\n\n\n","category":"type"},{"location":"functionreference/#Rotations.RotationError","page":"Function Reference","title":"Rotations.RotationError","text":"RotationError{T<:Real, D<:ErrorMap} <: StaticVector{3,T}\n\nA three-parameter rotation error, converted to/from a QuatRotation using the ErrorMap D.\n\nUsage\n\nA RotationError is typically created using one of the following methods\n\nrotation_error(R1::Rotation, R2::Rotation, error_map::ErrorMap)\nR1 ⊖ R2\n\nwhich compute the difference between the rotations R1 and R2 and convert the result to a 3D rotation error using error_map.\n\nThe error can be \"added\" back to a rotation using the inverse operation:\n\nadd_error(R1::Rotation, e::RotationError)\nR1::Rotation ⊕ e::RotationError\n\n\n\n\n\n","category":"type"},{"location":"functionreference/#Rotations.RotationGenerator","page":"Function Reference","title":"Rotations.RotationGenerator","text":"abstract type RotationGenerator{N,T} <: StaticMatrix{N,N,T}\n\nAn abstract type representing N-dimensional rotation generator. More abstractly, they represent skew-symmetric real N×N matrices.\n\n\n\n\n\n","category":"type"},{"location":"functionreference/#Rotations.RotationVec","page":"Function Reference","title":"Rotations.RotationVec","text":"struct RotationVec{T} <: Rotation{3,T}\nRotationVec(sx, sy, sz)\n\nRodrigues vector parameterization of a 3×3 rotation matrix. The direction of the vector [sx, sy, sz] defines the axis of rotation, and the rotation angle is given by its norm.\n\n\n\n\n\n","category":"type"},{"location":"functionreference/#Rotations.RotationVecGenerator","page":"Function Reference","title":"Rotations.RotationVecGenerator","text":"struct RotationVecGenerator{T} <: RotationGenerator{2,T}\n x::T\n y::T\n z::T\nend\n\nA 3×3 rotation generator matrix (i.e. skew-symmetric matrix). [ 0 -z y z 0 -x -y x 0]\n\n\n\n\n\n","category":"type"},{"location":"functionreference/#Base.:*-Tuple{QuatRotation, QuatRotation}","page":"Function Reference","title":"Base.:*","text":"(*)(q::QuatRotation, w::QuatRotation)\n\nQuternion Composition\n\nEquivalent to\n\nlmult(q) * SVector(w)\nrmult(w) * SVector(q)\n\nSets the output mapping equal to the mapping of w\n\n\n\n\n\n","category":"method"},{"location":"functionreference/#Base.:*-Tuple{QuatRotation, StaticArraysCore.StaticArray{Tuple{N}, T, 1} where {N, T}}","page":"Function Reference","title":"Base.:*","text":"(*)(q::QuatRotation, r::StaticVector)\n\nRotate a vector\n\nEquivalent to hmat()' lmult(q) * rmult(q)' hmat() * r\n\n\n\n\n\n","category":"method"},{"location":"functionreference/#Quaternions.slerp-Tuple{QuatRotation, QuatRotation, Real}","page":"Function Reference","title":"Quaternions.slerp","text":"slerp(R1::Rotaion{3}, R2::Rotaion{3}, t::Real)\n\nPerform spherical linear interpolation (Slerp) between rotations R1 and R2.\n\n\n\n\n\n","category":"method"},{"location":"functionreference/#Rotations.add_error-Tuple{Rotation, Rotations.RotationError}","page":"Function Reference","title":"Rotations.add_error","text":"add_error(R1::Rotation, e::RotationError)\n\n\"Adds\" the rotation error e to the rotation R1 by converting e to a quaternion via its ErrorMap and then composing with R1.\n\nEquivalent to\n\nR1 ⊕ e\n\n\n\n\n\n","category":"method"},{"location":"functionreference/#Rotations.hmat-Union{Tuple{}, Tuple{Type{T}}, Tuple{T}} where T","page":"Function Reference","title":"Rotations.hmat","text":"hmat()\nhmat(r::AbstractVector)\n\nhmat()*r or hmat(r) converts r into a pure quaternion, where r is 3-dimensional.\n\nhmat() == vmat()'\n\n\n\n\n\n","category":"method"},{"location":"functionreference/#Rotations.isrotation","page":"Function Reference","title":"Rotations.isrotation","text":"isrotation(r)\nisrotation(r, tol)\n\nCheck whether r is a rotation matrix, where r * r' is within tol of the identity matrix (using the Frobenius norm). tol defaults to 1000 * eps(float(eltype(r))) or zero(T) for integer T.\n\n\n\n\n\n","category":"function"},{"location":"functionreference/#Rotations.isrotationgenerator","page":"Function Reference","title":"Rotations.isrotationgenerator","text":"isrotationgenerator(r)\n\nCheck whether r is a rotation generator matrix (skew-symmetric matrix).\n\n\n\n\n\n","category":"function"},{"location":"functionreference/#Rotations.jacobian","page":"Function Reference","title":"Rotations.jacobian","text":"jacobian(::ErrorMap, ϕ)\n\nJacobian of the quaternion map that takes a three-dimensional vector ϕ and returns a unit quaternion. Returns a 4x3 Static Matrix\n\nFor all the maps (except the IdentityMap) jacobian(::ErrorMap, zeros(3)) = [0; I] = Hmat()'\n\n\n\n\n\n","category":"function"},{"location":"functionreference/#Rotations.jacobian-2","page":"Function Reference","title":"Rotations.jacobian","text":"jacobian(::InvErrorMap, q::QuatRotation)\n\nJacobian of the inverse quaternion map, returning a 3×4 matrix. For all maps: jacobian(::InvErrorMap, QuatRotation(I)) = [0 I] = Hmat()'\n\n\n\n\n\n","category":"function"},{"location":"functionreference/#Rotations.jacobian-Tuple{Type{RotMatrix}, QuatRotation}","page":"Function Reference","title":"Rotations.jacobian","text":"jacobian(::Type{output_param}, R::input_param)\n\nReturns the jacobian for transforming from the input rotation parameterization to the output parameterization, centered at the value of R.\n\njacobian(R::rotation_type, X::AbstractVector)\n\nReturns the jacobian for rotating the vector X by R.\n\n\n\n\n\n","category":"method"},{"location":"functionreference/#Rotations.kinematics-Union{Tuple{Q}, Tuple{Q, AbstractVector}} where Q<:QuatRotation","page":"Function Reference","title":"Rotations.kinematics","text":"kinematics(R::Rotation{3}, ω::AbstractVector)\n\nThe time derivative of the rotation R, according to the definition\n\nR = lim_Δt 0 fracR(t + Δt) - R(t)Δt\n\nwhere ω is the angular velocity. This is equivalent to\n\nR = lim_Δt 0 fracR δR - RΔt\n\nwhere δR is some small rotation, parameterized by a small rotation δθ about an axis r, such that lim_Δt 0 fracδθ rΔt = ω\n\nThe kinematics are extremely useful when computing the dynamics of rigid bodies, since Ṙ = kinematics(R,ω) is the first-order ODE for the evolution of the attitude dynamics.\n\nSee \"Fundamentals of Spacecraft Attitude Determination and Control\" by Markley and Crassidis Sections 3.1-3.2 for more details.\n\n\n\n\n\n","category":"method"},{"location":"functionreference/#Rotations.lmult-Tuple{QuatRotation}","page":"Function Reference","title":"Rotations.lmult","text":"lmult(q::QuatRotation)\nlmult(q::StaticVector{4})\n\nlmult(q2)*params(q1) returns a vector equivalent to q2*q1 (quaternion composition)\n\n\n\n\n\n","category":"method"},{"location":"functionreference/#Rotations.nearest_rotation-Union{Tuple{StaticArraysCore.StaticArray{Tuple{N, N}, T, 2} where T}, Tuple{N}} where N","page":"Function Reference","title":"Rotations.nearest_rotation","text":"nearest_rotation(M) -> RotMatrix\n\nGet the nearest special orthonormal matrix from given matrix M. See Wahba's problem for more information.\n\n\n\n\n\n","category":"method"},{"location":"functionreference/#Rotations.params-Tuple{QuatRotation}","page":"Function Reference","title":"Rotations.params","text":"params(R::Rotation)\n\nReturn an SVector of the underlying parameters used by the rotation representation.\n\nExample\n\np = MRP(1.0, 2.0, 3.0)\nRotations.params(p) == @SVector [1.0, 2.0, 3.0] # true\n\n\n\n\n\n","category":"method"},{"location":"functionreference/#Rotations.perpendicular_vector-Tuple{StaticArraysCore.StaticArray{Tuple{3}, T, 1} where T}","page":"Function Reference","title":"Rotations.perpendicular_vector","text":"perpendicular_vector(vec)\n\nCompute a vector perpendicular to vec by switching the two elements with largest absolute value, flipping the sign of the second largest, and setting the remaining element to zero.\n\n\n\n\n\n","category":"method"},{"location":"functionreference/#Rotations.principal_value-Tuple{Rotation}","page":"Function Reference","title":"Rotations.principal_value","text":"principal_value(R::Rotation{3})\n\nBackground: All non RotMatrix rotation types can represent the same RotMatrix in two or more ways. Sometimes a particular set of numbers is better conditioned (e.g. MRP) or obeys a particular convention (e.g. AngleAxis has non-negative rotation). In order to preserve differentiability it is necessary to allow rotation representations to travel slightly away from the nominal domain; this is critical for applications such as optimization or dynamics.\n\nThis function takes a rotation type (e.g. QuatRotation, RotXY) and outputs a new rotation of the same type that corresponds to the same RotMatrix, but that obeys certain conventions or is better conditioned. The outputs of the function have the following properties:\n\nall angles are between between -pi to pi (except for AngleAxis which is between 0 and pi).\nall `QuatRotation have non-negative real part\nthe components of all MRP have a norm that is at most 1.\nthe RotationVec rotation is at most pi\n\n\n\n\n\n","category":"method"},{"location":"functionreference/#Rotations.pure_quaternion-Tuple{AbstractVector}","page":"Function Reference","title":"Rotations.pure_quaternion","text":"pure_quaternion(v::AbstractVector)\npure_quaternion(x, y, z)\n\nCreate a Quaternion with zero scalar part (i.e. q.q.s == 0).\n\n\n\n\n\n","category":"method"},{"location":"functionreference/#Rotations.rmult-Tuple{QuatRotation}","page":"Function Reference","title":"Rotations.rmult","text":"rmult(q::QuatRotation)\nrmult(q::StaticVector{4})\n\nrmult(q1)*params(q2) return a vector equivalent to q2*q1 (quaternion composition)\n\n\n\n\n\n","category":"method"},{"location":"functionreference/#Rotations.rot_eltype-Tuple{Any}","page":"Function Reference","title":"Rotations.rot_eltype","text":"The element type for a rotation matrix with a given angle type is composed of trigonometric functions of that type.\n\n\n\n\n\n","category":"method"},{"location":"functionreference/#Rotations.rotation_between","page":"Function Reference","title":"Rotations.rotation_between","text":"rotation_between(u, v)\n\nCompute the quaternion that rotates vector u so that it aligns with vector v, along the geodesic (shortest path).\n\n\n\n\n\n","category":"function"},{"location":"functionreference/#Rotations.rotation_error-Tuple{Rotation, Rotation, Rotations.ErrorMap}","page":"Function Reference","title":"Rotations.rotation_error","text":"rotation_error(R1::Rotation, R2::Rotation, error_map::ErrorMap)\n\nCompute the RotationError by calculating the \"difference\" between R1 and R2, i.e. R2\\R1, then mapped to a three-parameter error using error_map.\n\nCan be equivalently called using the default map with R1 ⊖ R2\n\nIf error_map::IdentityMap, then SVector(R1\\R2)::SVector{3} is used as the error. Note this only works for three-parameter rotation representations such as RodriguesParam or MRP.\n\n\n\n\n\n","category":"method"},{"location":"functionreference/#Rotations.tmat-Union{Tuple{}, Tuple{Type{T}}, Tuple{T}} where T","page":"Function Reference","title":"Rotations.tmat","text":"tmat()\n\ntmat()*params(q)return a vector equivalent to inv(q), where q is a QuatRotation\n\n\n\n\n\n","category":"method"},{"location":"functionreference/#Rotations.vmat-Union{Tuple{}, Tuple{Type{T}}, Tuple{T}} where T","page":"Function Reference","title":"Rotations.vmat","text":"vmat()\n\nvmat()*params(q)returns the imaginary (vector) part of the quaternionq(equivalent tovector(q)``)\n\n\n\n\n\n","category":"method"},{"location":"functionreference/#Rotations.∇composition1-Tuple{QuatRotation, QuatRotation}","page":"Function Reference","title":"Rotations.∇composition1","text":"∇composition1(R2::Rotation{3}, R1::Rotation{3})\n\nJacobian of R2*R1 with respect to R1\n\n\n\n\n\n","category":"method"},{"location":"functionreference/#Rotations.∇composition2-Tuple{QuatRotation, QuatRotation}","page":"Function Reference","title":"Rotations.∇composition2","text":"∇composition2(R2::Rotation{3}, R1::Rotation{3})\n\nJacobian of R2*R1 with respect to R2\n\n\n\n\n\n","category":"method"},{"location":"functionreference/#Rotations.∇differential-Tuple{QuatRotation}","page":"Function Reference","title":"Rotations.∇differential","text":"∇differential(q::QuatRotation)\n\nJacobian of lmult(q) QuatMap(ϕ), when ϕ is near zero.\n\nUseful for converting Jacobians from R⁴ to R³ and correctly account for unit norm constraint. Jacobians for different differential quaternion parameterization are the same up to a constant.\n\n\n\n\n\n","category":"method"},{"location":"functionreference/#Rotations.∇err-Tuple{MRP, MRP}","page":"Function Reference","title":"Rotations.∇err","text":"∇err(p1::MRP, p2::MRP)\n\nJacobian of p1\\p2 wrt p2\n\n\n\n\n\n","category":"method"},{"location":"functionreference/#Rotations.∇jacobian","page":"Function Reference","title":"Rotations.∇jacobian","text":"∇jacobian(::InvErrorMap, q::QuatRotation, b::SVector{3})\n\nJacobian of G(q)'b, where G(q) = jacobian(::InvErrorMap, q), b is a 3-element vector\n\n\n\n\n\n","category":"function"},{"location":"functionreference/#Rotations.∇rotate-Tuple{QuatRotation, AbstractVector}","page":"Function Reference","title":"Rotations.∇rotate","text":"∇rotate(R::Rotation{3}, r::AbstractVector)\n\nJacobian of R*r with respect to the rotation\n\n\n\n\n\n","category":"method"},{"location":"functionreference/#Rotations.∇²differential-Tuple{QuatRotation, AbstractVector}","page":"Function Reference","title":"Rotations.∇²differential","text":"∇²differential(q::QuatRotation, b::AbstractVector)\n\nJacobian of (∂/∂ϕ lmult(q) QuatMap(ϕ))b, evaluated at ϕ=0, and b has length 4.\n\n\n\n\n\n","category":"method"},{"location":"functionreference/#Rotations.∇²err-Tuple{MRP, MRP, AbstractVector}","page":"Function Reference","title":"Rotations.∇²err","text":"∇²err(p1::MRP, p2::MRP, b::StaticVector{3})\n\nJacobian of (∂/∂p p1\\p2)'b wrt p2\n\n\n\n\n\n","category":"method"},{"location":"visualizing/#Visualizing-Rotation","page":"Visualizing Rotations","title":"Visualizing Rotation","text":"","category":"section"},{"location":"visualizing/","page":"Visualizing Rotations","title":"Visualizing Rotations","text":"In general, 3 times 3 matrix has 9 parameters, so it's hard to visualize a matrix as a point. However, the Lie group SO(3) and SU(2) are 3-dimensional space, and it is able to visualize its element as a point in our 3-dimensional space.","category":"page"},{"location":"visualizing/#using-MRP","page":"Visualizing Rotations","title":"using MRP","text":"","category":"section"},{"location":"visualizing/","page":"Visualizing Rotations","title":"Visualizing Rotations","text":"(TBW)","category":"page"},{"location":"visualizing/#using-RodriguesParam","page":"Visualizing Rotations","title":"using RodriguesParam","text":"","category":"section"},{"location":"visualizing/","page":"Visualizing Rotations","title":"Visualizing Rotations","text":"(TBW)","category":"page"},{"location":"visualizing/#using-RotationVec","page":"Visualizing Rotations","title":"using RotationVec","text":"","category":"section"},{"location":"visualizing/","page":"Visualizing Rotations","title":"Visualizing Rotations","text":"(TBW)","category":"page"},{"location":"functions/#Common-Methods-for-Rotations","page":"Common Methods for Rotations","title":"Common Methods for Rotations","text":"","category":"section"},{"location":"functions/#rotation_angle,-rotation_axis","page":"Common Methods for Rotations","title":"rotation_angle, rotation_axis","text":"","category":"section"},{"location":"functions/#3D","page":"Common Methods for Rotations","title":"3D","text":"","category":"section"},{"location":"functions/","page":"Common Methods for Rotations","title":"Common Methods for Rotations","text":"A rotation matrix can be expressed with one rotation around an axis and angle. these function can calculate these values.","category":"page"},{"location":"functions/","page":"Common Methods for Rotations","title":"Common Methods for Rotations","text":"example","category":"page"},{"location":"functions/","page":"Common Methods for Rotations","title":"Common Methods for Rotations","text":"using Rotations","category":"page"},{"location":"functions/","page":"Common Methods for Rotations","title":"Common Methods for Rotations","text":"R = RotXYZ(2.4, -1.8, 0.5)\nθ = rotation_angle(R)\nn = rotation_axis(R)\n# These matrices are approximately equal.\nR ≈ AngleAxis(θ, n...)","category":"page"},{"location":"functions/#2D","page":"Common Methods for Rotations","title":"2D","text":"","category":"section"},{"location":"functions/","page":"Common Methods for Rotations","title":"Common Methods for Rotations","text":"R = Angle2d(2.4)\nθ = rotation_angle(R)","category":"page"},{"location":"functions/#Rotations.params","page":"Common Methods for Rotations","title":"Rotations.params","text":"","category":"section"},{"location":"functions/","page":"Common Methods for Rotations","title":"Common Methods for Rotations","text":"The parameters of the rotation can be obtained by Rotations.params.","category":"page"},{"location":"functions/","page":"Common Methods for Rotations","title":"Common Methods for Rotations","text":"example","category":"page"},{"location":"functions/","page":"Common Methods for Rotations","title":"Common Methods for Rotations","text":"using Rotations","category":"page"},{"location":"functions/","page":"Common Methods for Rotations","title":"Common Methods for Rotations","text":"R = one(RotMatrix{3}) # Identity matrix\nRotations.params(RotYZY(R)) # Proper Euler angles, (y,z,y)\nRotations.params(RotXYZ(R)) # Tait–Bryan angles, (x,y,z)\nRotations.params(AngleAxis(R)) # Rotation around an axis (theta, axis_x, axis_y, axis_z)\nRotations.params(RotationVec(R)) # Rotation vector (v_x, v_y, v_z)\nRotations.params(QuatRotation(R)) # Quaternion (w, x, y, z)\nRotations.params(RodriguesParam(R)) # Rodrigues Parameters (x, y, z)\nRotations.params(MRP(R)) # Modified Rodrigues Parameters (x, y, z)","category":"page"},{"location":"functions/#isrotation","page":"Common Methods for Rotations","title":"isrotation","text":"","category":"section"},{"location":"functions/","page":"Common Methods for Rotations","title":"Common Methods for Rotations","text":"Check the given matrix is rotation matrix.","category":"page"},{"location":"functions/","page":"Common Methods for Rotations","title":"Common Methods for Rotations","text":"example","category":"page"},{"location":"functions/","page":"Common Methods for Rotations","title":"Common Methods for Rotations","text":"(TBW)","category":"page"},{"location":"functions/#nearest_rotation","page":"Common Methods for Rotations","title":"nearest_rotation","text":"","category":"section"},{"location":"functions/","page":"Common Methods for Rotations","title":"Common Methods for Rotations","text":"using Rotations","category":"page"},{"location":"functions/","page":"Common Methods for Rotations","title":"Common Methods for Rotations","text":"Get the nearest special orthonormal matrix from given matrix M. The problem of finding the orthogonal matrix nearest to a given matrix is related to the Wahba's problem.","category":"page"},{"location":"functions/","page":"Common Methods for Rotations","title":"Common Methods for Rotations","text":"example","category":"page"},{"location":"functions/","page":"Common Methods for Rotations","title":"Common Methods for Rotations","text":"M = randn(3,3) # Generate random matrix\nR = nearest_rotation(M) # Find the nearest rotation matrix\nU, V = R\\M, M/R # Polar decomposition of M\nU ≈ U' # U is a symmetric matrix (The same for V)","category":"page"},{"location":"functions/#rand","page":"Common Methods for Rotations","title":"rand","text":"","category":"section"},{"location":"functions/","page":"Common Methods for Rotations","title":"Common Methods for Rotations","text":"using Rotations","category":"page"},{"location":"functions/#rand-for-SO(2)","page":"Common Methods for Rotations","title":"rand for SO(2)","text":"","category":"section"},{"location":"functions/","page":"Common Methods for Rotations","title":"Common Methods for Rotations","text":"The following types have the same algebraic structure as SO(2)","category":"page"},{"location":"functions/","page":"Common Methods for Rotations","title":"Common Methods for Rotations","text":"RotMatrix{2}\nAngle2d\nRotX\nRotY\nRotZ","category":"page"},{"location":"functions/","page":"Common Methods for Rotations","title":"Common Methods for Rotations","text":"The random distribution is based on Haar measure.","category":"page"},{"location":"functions/","page":"Common Methods for Rotations","title":"Common Methods for Rotations","text":"example","category":"page"},{"location":"functions/","page":"Common Methods for Rotations","title":"Common Methods for Rotations","text":"R = rand(Angle2d)","category":"page"},{"location":"functions/#rand-for-SO(3)","page":"Common Methods for Rotations","title":"rand for SO(3)","text":"","category":"section"},{"location":"functions/","page":"Common Methods for Rotations","title":"Common Methods for Rotations","text":"The following types have an algebraic structure that is homomorphic to SO(3).","category":"page"},{"location":"functions/","page":"Common Methods for Rotations","title":"Common Methods for Rotations","text":"RotMatrix{3}\nRotXYZ (and other Euler angles)\nAngleAxis\nRotationVec\nQuatRotation\nRodriguesParam\nMRP","category":"page"},{"location":"functions/","page":"Common Methods for Rotations","title":"Common Methods for Rotations","text":"example","category":"page"},{"location":"functions/","page":"Common Methods for Rotations","title":"Common Methods for Rotations","text":"R = rand(RotationVec)","category":"page"},{"location":"functions/","page":"Common Methods for Rotations","title":"Common Methods for Rotations","text":"The random distribution is based on Haar measure.","category":"page"},{"location":"functions/#rand-for-RotXY-and-etc.","page":"Common Methods for Rotations","title":"rand for RotXY and etc.","text":"","category":"section"},{"location":"functions/","page":"Common Methods for Rotations","title":"Common Methods for Rotations","text":"There also are methods for rand(::RotXY) and other 2-axis rotations.","category":"page"},{"location":"functions/","page":"Common Methods for Rotations","title":"Common Methods for Rotations","text":"example","category":"page"},{"location":"functions/","page":"Common Methods for Rotations","title":"Common Methods for Rotations","text":"R = rand(RotXY)","category":"page"},{"location":"functions/","page":"Common Methods for Rotations","title":"Common Methods for Rotations","text":"The random distribution is NOT based on Haar measure because the set of RotXY doesn't have group structure.","category":"page"},{"location":"functions/","page":"Common Methods for Rotations","title":"Common Methods for Rotations","text":"Note that:","category":"page"},{"location":"functions/","page":"Common Methods for Rotations","title":"Common Methods for Rotations","text":"rand(RotX) is same as RotX(2π*rand()).\nrand(RotXY) is same as RotXY(2π*rand(), 2π*rand()).\nrand(RotXYZ) is not same as RotXYZ(2π*rand(), 2π*rand(), 2π*rand()).\nBut rand(RotXYZ) is same as RotXYZ(rand(QuatRotation)).","category":"page"},{"location":"3d_euler/#3D-Rotation-with-Euler-Angles","page":"Euler Angles","title":"3D Rotation with Euler Angles","text":"","category":"section"},{"location":"3d_euler/","page":"Euler Angles","title":"Euler Angles","text":"Euler angles are a way to represent a rotation matrix with three rotations around cardinal axes.","category":"page"},{"location":"3d_euler/","page":"Euler Angles","title":"Euler Angles","text":"In Rotations.jl, there are 12 concrete types for Euler angles.","category":"page"},{"location":"3d_euler/","page":"Euler Angles","title":"Euler Angles","text":"Proper Euler angles\nRotZXZ, RotXYX, RotYZY, RotZYZ, RotXZX, RotYXY\nTait–Bryan angles\nRotXYZ, RotYZX, RotZXY, RotXZY, RotZYX, RotYXZ","category":"page"},{"location":"3d_euler/","page":"Euler Angles","title":"Euler Angles","text":"In addition, Rotations.jl provides concrete types that represent rotations in one or two axes.","category":"page"},{"location":"3d_euler/","page":"Euler Angles","title":"Euler Angles","text":"one axis\nRotX, RotY, RotZ\ntwo axes\nRotXY, RotYZ, RotZX, RotXZ, RotZY, RotYX","category":"page"},{"location":"3d_euler/#Rotation-around-one-axis","page":"Euler Angles","title":"Rotation around one axis","text":"","category":"section"},{"location":"3d_euler/","page":"Euler Angles","title":"Euler Angles","text":"beginaligned\nR_x(alpha)\n= beginpmatrix\n1 0 0 \n0 cos(alpha) -sin(alpha) \n0 sin(alpha) cos(alpha) \nendpmatrix \nR_y(alpha)\n= beginpmatrix\ncos(alpha) 0 sin(alpha) \n0 1 0 \n-sin(alpha) 0 cos(alpha) \nendpmatrix \nR_z(alpha)\n= beginpmatrix\ncos(alpha) -sin(alpha) 0\nsin(alpha) cos(alpha) 0\n0 0 1\nendpmatrix\nendaligned","category":"page"},{"location":"3d_euler/","page":"Euler Angles","title":"Euler Angles","text":"example","category":"page"},{"location":"3d_euler/","page":"Euler Angles","title":"Euler Angles","text":"using Rotations","category":"page"},{"location":"3d_euler/","page":"Euler Angles","title":"Euler Angles","text":"Here's an example for RotZ:","category":"page"},{"location":"3d_euler/","page":"Euler Angles","title":"Euler Angles","text":"α = 1.2 # Rotation angle\nR = RotZ(α)\nQ = [cos(α) -sin(α) 0\n sin(α) cos(α) 0\n 0 0 1]\n# These matrices are equal\nR == Q","category":"page"},{"location":"3d_euler/","page":"Euler Angles","title":"Euler Angles","text":"And more examples for RotX and RotY:","category":"page"},{"location":"3d_euler/","page":"Euler Angles","title":"Euler Angles","text":"# These matrices are equal\nRotX(α) == [1 0 0\n 0 cos(α) -sin(α)\n 0 sin(α) cos(α)]\n# These matrices are equal\nRotY(α) == [cos(α) 0 sin(α)\n 0 1 0\n -sin(α) 0 cos(α)]","category":"page"},{"location":"3d_euler/#Rotation-around-two-axes","page":"Euler Angles","title":"Rotation around two axes","text":"","category":"section"},{"location":"3d_euler/","page":"Euler Angles","title":"Euler Angles","text":"beginaligned\nR_xy(alphabeta)\n= R_x(alpha)R_y(beta)\n R_yx(alphabeta)\n= R_y(alpha)R_x(beta) \n\nR_yz(alphabeta)\n= R_y(alpha)R_z(beta)\n R_zy(alphabeta)\n= R_z(alpha)R_y(beta) \n\nR_zx(alphabeta)\n= R_z(alpha)R_x(beta)\n R_xz(alphabeta)\n= R_x(alpha)R_z(beta)\nendaligned","category":"page"},{"location":"3d_euler/","page":"Euler Angles","title":"Euler Angles","text":"example","category":"page"},{"location":"3d_euler/","page":"Euler Angles","title":"Euler Angles","text":"using Rotations","category":"page"},{"location":"3d_euler/","page":"Euler Angles","title":"Euler Angles","text":"α, β = 1.2, 4.7 # Rotation angles\nRotX(α) * RotY(β)\nRotXY(α, β)\n# These matrices are equal\nRotX(α) * RotY(β) == RotXY(α, β)","category":"page"},{"location":"3d_euler/#Rotation-around-three-axes-(Euler-Angles)","page":"Euler Angles","title":"Rotation around three axes (Euler Angles)","text":"","category":"section"},{"location":"3d_euler/","page":"Euler Angles","title":"Euler Angles","text":"Proper Euler angles","category":"page"},{"location":"3d_euler/","page":"Euler Angles","title":"Euler Angles","text":"beginaligned\nR_xyx(alpha beta gamma) = R_x(alpha) R_y(beta) R_x(gamma)\n R_yxy(alpha beta gamma) = R_y(alpha) R_x(beta) R_y(gamma) \nR_yzy(alpha beta gamma) = R_y(alpha) R_z(beta) R_y(gamma)\n R_zyz(alpha beta gamma) = R_z(alpha) R_y(beta) R_z(gamma) \nR_zxz(alpha beta gamma) = R_z(alpha) R_x(beta) R_z(gamma)\n R_xzx(alpha beta gamma) = R_x(alpha) R_z(beta) R_x(gamma)\nendaligned","category":"page"},{"location":"3d_euler/","page":"Euler Angles","title":"Euler Angles","text":"Tait–Bryan angles","category":"page"},{"location":"3d_euler/","page":"Euler Angles","title":"Euler Angles","text":"beginaligned\nR_xyz(alpha beta gamma) = R_x(alpha) R_y(beta) R_z(gamma)\n R_yxz(alpha beta gamma) = R_y(alpha) R_x(beta) R_z(gamma) \nR_yzx(alpha beta gamma) = R_y(alpha) R_z(beta) R_x(gamma)\n R_zyx(alpha beta gamma) = R_z(alpha) R_y(beta) R_x(gamma) \nR_zxy(alpha beta gamma) = R_z(alpha) R_x(beta) R_y(gamma)\n R_xzy(alpha beta gamma) = R_x(alpha) R_z(beta) R_y(gamma)\nendaligned","category":"page"},{"location":"3d_euler/","page":"Euler Angles","title":"Euler Angles","text":"example","category":"page"},{"location":"3d_euler/","page":"Euler Angles","title":"Euler Angles","text":"using Rotations","category":"page"},{"location":"3d_euler/","page":"Euler Angles","title":"Euler Angles","text":"α, β, γ = 1.2, 4.7, -0.4 # Rotation angles\nRotYXZ(α, β, γ)\nRotY(α)*RotX(β)*RotZ(γ)\n# These matrices are equal\nRotYXZ(α, β, γ) == RotY(α)*RotX(β)*RotZ(γ)","category":"page"},{"location":"2d_angle/#2D-Rotation-by-Angle","page":"Angle","title":"2D Rotation by Angle","text":"","category":"section"},{"location":"2d_angle/","page":"Angle","title":"Angle","text":"Angle2d is a type that internally has an angle as a parameter, and can be thought of as a lazy version of RotMatrix{2}.","category":"page"},{"location":"2d_angle/","page":"Angle","title":"Angle","text":"using Rotations","category":"page"},{"location":"2d_angle/#Angle2d","page":"Angle","title":"Angle2d","text":"","category":"section"},{"location":"2d_angle/","page":"Angle","title":"Angle","text":"example","category":"page"},{"location":"2d_angle/","page":"Angle","title":"Angle","text":"t = 1.2 # rotation angle\nm = [cos(t) -sin(t);sin(t) cos(t)]\nAngle2d(t) # construct from matrix\nRotMatrix{2}(t)\ndump(Angle2d(t))\ndump(RotMatrix{2}(t))","category":"page"},{"location":"2d_matrix/#2D-Rotation-Matrix","page":"Matrix","title":"2D Rotation Matrix","text":"","category":"section"},{"location":"2d_matrix/","page":"Matrix","title":"Matrix","text":"An 2 times 2 rotation matrix storing the rotation. This is a simple wrapper for a StaticArrays SMatrix{2,2,T}. A rotation matrix R should have the property I = R R^top, but this isn't enforced by the constructor. On the other hand, all the types below are guaranteed to be \"proper\" rotations for all input parameters (equivalently: parity conserving, in SO(2), det(R) = 1, or a rotation without reflection).","category":"page"},{"location":"2d_matrix/","page":"Matrix","title":"Matrix","text":"using Rotations","category":"page"},{"location":"2d_matrix/#RotMatrix2","page":"Matrix","title":"RotMatrix2","text":"","category":"section"},{"location":"2d_matrix/","page":"Matrix","title":"Matrix","text":"example","category":"page"},{"location":"2d_matrix/","page":"Matrix","title":"Matrix","text":"t = 1.2 # rotation angle\nm = [cos(t) -sin(t);sin(t) cos(t)]\nRotMatrix{2}(m) # construct from matrix\nRotMatrix{2}(t) # construct from angle","category":"page"},{"location":"2d_rotation_generator/#2D-Rotation-Generator","page":"2D Rotation Generators","title":"2D Rotation Generator","text":"","category":"section"},{"location":"2d_rotation_generator/","page":"2D Rotation Generators","title":"2D Rotation Generators","text":"using Rotations","category":"page"},{"location":"2d_rotation_generator/#RotMatrixGenerator2","page":"2D Rotation Generators","title":"RotMatrixGenerator2","text":"","category":"section"},{"location":"2d_rotation_generator/","page":"2D Rotation Generators","title":"2D Rotation Generators","text":"example","category":"page"},{"location":"2d_rotation_generator/","page":"2D Rotation Generators","title":"2D Rotation Generators","text":"m = rand(2,2)\ns = RotMatrixGenerator{2}(m - m')\nexp(s)\nlog(exp(s))","category":"page"},{"location":"2d_rotation_generator/#Angle2dGenerator","page":"2D Rotation Generators","title":"Angle2dGenerator","text":"","category":"section"},{"location":"2d_rotation_generator/","page":"2D Rotation Generators","title":"2D Rotation Generators","text":"example","category":"page"},{"location":"2d_rotation_generator/","page":"2D Rotation Generators","title":"2D Rotation Generators","text":"s = Angle2dGenerator(0.42)\nexp(s)\nlog(exp(s))\nrotation_angle(exp(s))\nrotation_angle(exp(2s))\nrotation_angle(exp(2s)) / rotation_angle(exp(s))","category":"page"},{"location":"reference/#Reference-for-rotations","page":"References","title":"Reference for rotations","text":"","category":"section"},{"location":"reference/#Published-articles","page":"References","title":"Published articles","text":"","category":"section"},{"location":"reference/","page":"References","title":"References","text":"\"Fundamentals of Spacecraft Attitude Determination and Control\" by Markley and Crassidis\nSee sections 2.1-2.9 for 3d rotation parametrization.\nSee sections 3.1-3.2 for kinematics.\n\"Derivation of the Euler-Rodrigues formula for three-dimensional rotations from the general formula for four-dimensional rotations\" by Johan Ernest Mebius\nThe conversion RotMatrix{3} to QuatRotaiton is based on this paper.\n\"Computing Exponentials of Skew Symmetric Matrices And Logarithms of Orthogonal Matrices\" by Jean Gallier and Dianna Xu\nSee this article for log and exp of rotation matrices in higher dimensions.","category":"page"},{"location":"reference/#Wikipedia-articles","page":"References","title":"Wikipedia articles","text":"","category":"section"},{"location":"reference/","page":"References","title":"References","text":"Rotation matrix\nQuaternion\nWahba's problem\nWahba's problem is related to the nearest_rotation function.\nPolar decomposition\nPolar decomposition is also related to the nearest_rotation function.","category":"page"},{"location":"reference/#Others","page":"References","title":"Others","text":"","category":"section"},{"location":"reference/","page":"References","title":"References","text":"\"Quaternions and 3d rotation, explained interactively\" by 3Blue1Brown\n\"Visualizing quaternions (4d numbers) with stereographic projection\" by 3Blue1Brown","category":"page"},{"location":"3d_quaternion/#3D-Rotation-with-Quaternion-and-Related-Parameters","page":"Quaternion and Related Parameters","title":"3D Rotation with Quaternion and Related Parameters","text":"","category":"section"},{"location":"3d_quaternion/","page":"Quaternion and Related Parameters","title":"Quaternion and Related Parameters","text":"using Rotations","category":"page"},{"location":"3d_quaternion/#QuatRotation","page":"Quaternion and Related Parameters","title":"QuatRotation","text":"","category":"section"},{"location":"3d_quaternion/","page":"Quaternion and Related Parameters","title":"Quaternion and Related Parameters","text":"A 3D rotation parameterized by a unit quaternion (versor). Note that the constructor will renormalize the quaternion to be a unit quaternion, and that although they follow the same multiplicative algebra as quaternions, it is better to think of QuatRotation as a 3 times 3 matrix rather than as a quaternion number.","category":"page"},{"location":"3d_quaternion/","page":"Quaternion and Related Parameters","title":"Quaternion and Related Parameters","text":"beginaligned\n leftw_mathrmQ + ix_mathrmQ + jy_mathrmQ + kz_mathrmQ in mathbbH x_mathrmQ y_mathrmQ z_mathrmQ in mathbbR right\n simeq S^3\nendaligned","category":"page"},{"location":"3d_quaternion/","page":"Quaternion and Related Parameters","title":"Quaternion and Related Parameters","text":"example","category":"page"},{"location":"3d_quaternion/","page":"Quaternion and Related Parameters","title":"Quaternion and Related Parameters","text":"one(QuatRotation) # identity rotation\nα, β, γ = 1.2, -0.8, 0.1;\nRotX(α) ≈ QuatRotation(cos(α/2),sin(α/2),0,0) # These matrices are equal\nRotY(β) ≈ QuatRotation(cos(β/2),0,sin(β/2),0) # These matrices are equal\nRotZ(γ) ≈ QuatRotation(cos(γ/2),0,0,sin(γ/2)) # These matrices are equal","category":"page"},{"location":"3d_quaternion/","page":"Quaternion and Related Parameters","title":"Quaternion and Related Parameters","text":"See also Quaternions.jl documentation.","category":"page"},{"location":"3d_quaternion/#RodriguesParam","page":"Quaternion and Related Parameters","title":"RodriguesParam","text":"","category":"section"},{"location":"3d_quaternion/","page":"Quaternion and Related Parameters","title":"Quaternion and Related Parameters","text":"A 3-parameter representation of 3D rotations that has a singularity at 180^circ. They can be interpreted as a projection of the unit quaternion onto the plane tangent to the quaternion identity. They are computationally efficient and do not have a sign ambiguity of unit quaternion.","category":"page"},{"location":"3d_quaternion/","page":"Quaternion and Related Parameters","title":"Quaternion and Related Parameters","text":"left\nbeginaligned\n beginaligned\n x_mathrmR = x_mathrmQw_mathrmQ \n y_mathrmR = y_mathrmQw_mathrmQ \n z_mathrmR = z_mathrmQw_mathrmQ\n endaligned\nendaligned\nright","category":"page"},{"location":"3d_quaternion/","page":"Quaternion and Related Parameters","title":"Quaternion and Related Parameters","text":"example","category":"page"},{"location":"3d_quaternion/","page":"Quaternion and Related Parameters","title":"Quaternion and Related Parameters","text":"one(RodriguesParam) # identity rotation\nα, β, γ = 1.2, -0.8, 0.1;\nRotX(α) ≈ RodriguesParam(tan(α/2),0,0) # These matrices are equal\nRotY(β) ≈ RodriguesParam(0,tan(β/2),0) # These matrices are equal\nRotZ(γ) ≈ RodriguesParam(0,0,tan(γ/2)) # These matrices are equal","category":"page"},{"location":"3d_quaternion/#MRP-(Modified-Rodrigues-Parameters)","page":"Quaternion and Related Parameters","title":"MRP (Modified Rodrigues Parameters)","text":"","category":"section"},{"location":"3d_quaternion/","page":"Quaternion and Related Parameters","title":"Quaternion and Related Parameters","text":"A 3D rotation encoded by the stereographic projection of a unit quaternion. This projection can be visualized as a pin hole camera, with the pin hole matching the quaternion -1+0i+0j+0k and the image plane containing the origin and having normal direction 1+0i+0j+0k. The \"identity rotation\" Quaternion(1.0,0,0,0) then maps to the MRP(0,0,0)","category":"page"},{"location":"3d_quaternion/","page":"Quaternion and Related Parameters","title":"Quaternion and Related Parameters","text":"These are similar to the Rodrigues vector in that the axis direction is stored in an unnormalized form, and the rotation angle is encoded in the length of the axis. This type has the nice property that the derivatives of the rotation matrix w.r.t. the MRP parameters are rational functions, making the MRP type a good choice for differentiation / optimization.","category":"page"},{"location":"3d_quaternion/","page":"Quaternion and Related Parameters","title":"Quaternion and Related Parameters","text":"They are frequently used in aerospace applications since they are a 3-parameter representation whose singularity happens at 360^circ. In practice, the singularity can be avoided with some switching logic between one of two equivalent MRPs (obtained by projecting the negated quaternion).","category":"page"},{"location":"3d_quaternion/","page":"Quaternion and Related Parameters","title":"Quaternion and Related Parameters","text":"left\nbeginaligned\n beginaligned\n x_mathrmM = dfracx_mathrmQw_mathrmQ-1 \n y_mathrmM = dfracy_mathrmQw_mathrmQ-1 \n z_mathrmM = dfracz_mathrmQw_mathrmQ-1\n endaligned\nendaligned\nright","category":"page"},{"location":"3d_quaternion/","page":"Quaternion and Related Parameters","title":"Quaternion and Related Parameters","text":"example","category":"page"},{"location":"3d_quaternion/","page":"Quaternion and Related Parameters","title":"Quaternion and Related Parameters","text":"one(MRP) # identity rotation\nα, β, γ = 1.2, -0.8, 0.1;\nRotX(α) ≈ MRP(sin(α/2)/(cos(α/2)-1),0,0) # These matrices are equal\nRotY(β) ≈ MRP(0,sin(β/2)/(cos(β/2)-1),0) # These matrices are equal\nRotZ(γ) ≈ MRP(0,0,sin(γ/2)/(cos(γ/2)-1)) # These matrices are equal","category":"page"},{"location":"3d_matrix/#3D-Rotation-Matrix","page":"Matrix","title":"3D Rotation Matrix","text":"","category":"section"},{"location":"3d_matrix/","page":"Matrix","title":"Matrix","text":"An 3 times 3 rotation matrix storing the rotation. This is a simple wrapper for a StaticArrays SMatrix{3,3,T}. A rotation matrix R should have the property I = R R^top, but this isn't enforced by the constructor. On the other hand, all the types below are guaranteed to be \"proper\" rotations for all input parameters (equivalently: parity conserving, in SO(3), det(R) = 1, or a rotation without reflection).","category":"page"},{"location":"3d_matrix/","page":"Matrix","title":"Matrix","text":"using Rotations","category":"page"},{"location":"3d_matrix/#RotMatrix3","page":"Matrix","title":"RotMatrix3","text":"","category":"section"},{"location":"3d_matrix/","page":"Matrix","title":"Matrix","text":"example","category":"page"},{"location":"3d_matrix/","page":"Matrix","title":"Matrix","text":"t = 1.2\nm1 = [cos(t) -sin(t) 0;sin(t) cos(t) 0;0 0 1]\nRotMatrix{3}(m1) # construct from matrix\nm2 = RotZ(t) # Other rotation type\nRotMatrix{3}(m2) # convert m2 to RotMatrix\nRotMatrix(m2) # Type parameter can be omitted.","category":"page"},{"location":"3d_angleaxis/#3D-Rotation-around-an-axis","page":"Angle and Axis","title":"3D Rotation around an axis","text":"","category":"section"},{"location":"3d_angleaxis/","page":"Angle and Axis","title":"Angle and Axis","text":"In Rotations.jl, there are two concrete types to represent a rotation with given an axis and an angle.","category":"page"},{"location":"3d_angleaxis/","page":"Angle and Axis","title":"Angle and Axis","text":"AngleAxis\nRotationVec","category":"page"},{"location":"3d_angleaxis/#AngleAxis","page":"Angle and Axis","title":"AngleAxis","text":"","category":"section"},{"location":"3d_angleaxis/","page":"Angle and Axis","title":"Angle and Axis","text":"A 3D rotation with fields theta, axis_x, axis_y, and axis_z to store the rotation angle and axis of the rotation. Like all other types in this package, once it is constructed it acts and behaves as a 3×3 AbstractMatrix. The axis will be automatically renormalized by the constructor to be a unit vector, so that theta always represents the rotation angle in radians.","category":"page"},{"location":"3d_angleaxis/","page":"Angle and Axis","title":"Angle and Axis","text":"beginaligned\nR_bmn (theta)\n= exp(theta K(bmn)) \n= I + (sintheta) K(bmn) + (1-costheta) K^2(bmn) \n= beginpmatrix\ncostheta + n_x^2 (1-costheta) n_xn_y (1-costheta) - n_z sintheta n_zn_x (1-costheta) + n_y sintheta \nn_xn_y (1-costheta) + n_z sintheta costheta + n_y^2 (1-costheta) n_yn_z (1-costheta) - n_x sintheta \nn_zn_x (1-costheta) - n_y sintheta n_yn_z (1-costheta) + n_x sintheta costheta + n_z^2 (1-costheta)\nendpmatrix \n\nK(bmn)\n= beginpmatrix\n0 -n_z n_y \nn_z 0 -n_x \n-n_y n_x 0\nendpmatrix \n\nbmn\n= beginpmatrix\nn_x \nn_y \nn_z\nendpmatrix\n\nquad left(bmn= 1right)\nendaligned","category":"page"},{"location":"3d_angleaxis/","page":"Angle and Axis","title":"Angle and Axis","text":"example","category":"page"},{"location":"3d_angleaxis/","page":"Angle and Axis","title":"Angle and Axis","text":"using Rotations, LinearAlgebra\n# 1/3 (120°) rotation around the (1/√3, 1/√3, 1/√3) vector\nR = AngleAxis(2π/3, 1/√3, 1/√3, 1/√3)\n# This matrix swaps the xyz coordinates\nR * [1,2,3]\nR^2\nR^3\n# These matrices are approximately equal\nR^3 ≈ I(3)","category":"page"},{"location":"3d_angleaxis/#RotationVec","page":"Angle and Axis","title":"RotationVec","text":"","category":"section"},{"location":"3d_angleaxis/","page":"Angle and Axis","title":"Angle and Axis","text":"A 3D rotation encoded by an angle-axis representation as angle * axis. This type is used in packages such as OpenCV.","category":"page"},{"location":"3d_angleaxis/","page":"Angle and Axis","title":"Angle and Axis","text":"beginaligned\nR(bmv)\n= R_bmn (theta) left(bmn = fracbmvbmv theta = bmv right)\nendaligned","category":"page"},{"location":"3d_angleaxis/","page":"Angle and Axis","title":"Angle and Axis","text":"note: Differentiation\nIf you're differentiating a Rodrigues Vector check the result is what you expect at theta = 0. The first derivative of the rotation should behave, but higher-order derivatives of it (as well as parameterization conversions) should be tested. The Stereographic Quaternion Projection (MRP) is the recommended three parameter format for differentiation.","category":"page"},{"location":"3d_angleaxis/","page":"Angle and Axis","title":"Angle and Axis","text":"example","category":"page"},{"location":"3d_angleaxis/","page":"Angle and Axis","title":"Angle and Axis","text":"using Rotations, LinearAlgebra\n# 1/3 (120°) rotation around the (1/√3, 1/√3, 1/√3) vector\nR = R = RotationVec(2π/3(√3), 2π/3(√3), 2π/3(√3))\n# This matrix swaps the xyz coordinates\nR * [1,2,3]\nR^2\nR^3\n# These matrices are approximately equal\nR^3 ≈ I(3)\n\nα, β, γ = 1.2, -0.8, 0.1;\nRotX(α) ≈ RotationVec(α,0,0) # These matrices are equal\nRotY(β) ≈ RotationVec(0,β,0) # These matrices are equal\nRotZ(γ) ≈ RotationVec(0,0,γ) # These matrices are equal","category":"page"},{"location":"rotation_types/#Rotation-Types","page":"Rotation Types","title":"Rotation Types","text":"","category":"section"},{"location":"rotation_types/#Abstract-rotations","page":"Rotation Types","title":"Abstract rotations","text":"","category":"section"},{"location":"rotation_types/","page":"Rotation Types","title":"Rotation Types","text":"A matrix R is called rotation matrix if R satisfies","category":"page"},{"location":"rotation_types/","page":"Rotation Types","title":"Rotation Types","text":"beginaligned\nR^top = R^-1 det(R)=1\nendaligned","category":"page"},{"location":"rotation_types/","page":"Rotation Types","title":"Rotation Types","text":"In Rotations.jl, there's an abstract type for rotations matrix, Rotation{L}. Where L is a size of the rotation matrix.","category":"page"},{"location":"rotation_types/#Type-hierarchy","page":"Rotation Types","title":"Type hierarchy","text":"","category":"section"},{"location":"rotation_types/","page":"Rotation Types","title":"Rotation Types","text":"using InteractiveUtils","category":"page"},{"location":"rotation_types/","page":"Rotation Types","title":"Rotation Types","text":"using Rotations, StaticArrays\nRotation <: StaticMatrix <: AbstractMatrix\nsubtypes(Rotation{2})\nsubtypes(Rotation{3})","category":"page"},{"location":"rotation_types/#Overview-of-each-type","page":"Rotation Types","title":"Overview of each type","text":"","category":"section"},{"location":"rotation_types/","page":"Rotation Types","title":"Rotation Types","text":"For more information, see the sidebar page.","category":"page"},{"location":"rotation_types/#2D-rotations","page":"Rotation Types","title":"2D rotations","text":"","category":"section"},{"location":"rotation_types/","page":"Rotation Types","title":"Rotation Types","text":"RotMatrix2{T}\nRotation matrix in 2 dimensional Euclidean space.\nAngle2d\nParametrized with rotational angle.","category":"page"},{"location":"rotation_types/#3D-rotations","page":"Rotation Types","title":"3D rotations","text":"","category":"section"},{"location":"rotation_types/","page":"Rotation Types","title":"Rotation Types","text":"RotMatrix3{T}\nRotation matrix in 3 dimensional Euclidean space.\nRotX, RotYZ, RotXYZ and etc.\nEuler angles.\nAngleAxis\nRotation around given axis and angle.\nRotationVec\nRotation around given axis. The length of axis vector represents its angle.\nQuatRotation\nA 3D rotation parameterized by a unit quaternion.\nMRP\nA 3D rotation encoded by the stereographic projection of a unit quaternion.","category":"page"},{"location":"rotation_generator_types/#Rotation-Generator-Types","page":"Rotation Generator Types","title":"Rotation Generator Types","text":"","category":"section"},{"location":"rotation_generator_types/#Abstract-rotation-generators","page":"Rotation Generator Types","title":"Abstract rotation generators","text":"","category":"section"},{"location":"rotation_generator_types/","page":"Rotation Generator Types","title":"Rotation Generator Types","text":"A matrix R is called skew-symmetric matrix if R satisfies","category":"page"},{"location":"rotation_generator_types/","page":"Rotation Generator Types","title":"Rotation Generator Types","text":"beginaligned\nR^top = -R\nendaligned","category":"page"},{"location":"rotation_generator_types/","page":"Rotation Generator Types","title":"Rotation Generator Types","text":"In Rotations.jl, there's an abstract type for skew-symmetric matrix, RotationGenerator{L}. Where L is a size of the skew-symmetric matrix.","category":"page"},{"location":"rotation_generator_types/#Type-hierarchy","page":"Rotation Generator Types","title":"Type hierarchy","text":"","category":"section"},{"location":"rotation_generator_types/","page":"Rotation Generator Types","title":"Rotation Generator Types","text":"using InteractiveUtils","category":"page"},{"location":"rotation_generator_types/","page":"Rotation Generator Types","title":"Rotation Generator Types","text":"using Rotations, StaticArrays\nRotationGenerator <: StaticMatrix <: AbstractMatrix\nsubtypes(RotationGenerator{2})\nsubtypes(RotationGenerator{3})","category":"page"},{"location":"rotation_generator_types/#Overview-of-each-type","page":"Rotation Generator Types","title":"Overview of each type","text":"","category":"section"},{"location":"rotation_generator_types/","page":"Rotation Generator Types","title":"Rotation Generator Types","text":"For more information, see the sidebar page.","category":"page"},{"location":"rotation_generator_types/#2D-rotations","page":"Rotation Generator Types","title":"2D rotations","text":"","category":"section"},{"location":"rotation_generator_types/","page":"Rotation Generator Types","title":"Rotation Generator Types","text":"RotMatrixGenerator2{T}\nSkew symmetric matrix in 2 dimensional Euclidean space.\nAngle2dGenerator\nParametrized with one real number like Angle2d.","category":"page"},{"location":"rotation_generator_types/#3D-rotations","page":"Rotation Generator Types","title":"3D rotations","text":"","category":"section"},{"location":"rotation_generator_types/","page":"Rotation Generator Types","title":"Rotation Generator Types","text":"RotMatrixGenerator3{T}\nSkew symmetric matrix in 3 dimensional Euclidean space.\nRotationVecGenerator\nRotation generator around given axis. The length of axis vector represents its angle.","category":"page"},{"location":"#Rotations","page":"Home","title":"Rotations","text":"","category":"section"},{"location":"","page":"Home","title":"Home","text":"3D rotations made easy in Julia","category":"page"},{"location":"","page":"Home","title":"Home","text":"note: Documentation\nThe documentation is still work in progress. For more information, see alsoREADME in the repository\nTests in the repository(TBW) comments are left in areas that have not yet been documented. Feel free to open pull requests and improve this document!","category":"page"},{"location":"#Installation","page":"Home","title":"Installation","text":"","category":"section"},{"location":"","page":"Home","title":"Home","text":"pkg> add Rotations","category":"page"},{"location":"#First-example","page":"Home","title":"First example","text":"","category":"section"},{"location":"","page":"Home","title":"Home","text":"using Rotations\n\n# 3D Rotation by Euler Angles\nR_euler = RotXYZ(1,2,3)\n\n# Get an angle and an axis of the rotation\nrotation_angle(R_euler), rotation_axis(R_euler)\n\n# Convert the rotation to unit quaternion\nR_quat = QuatRotation(R_euler)\n\n# Get quaternion parameters of the rotation\nRotations.params(R_quat)\n\n# Convert the rotation to MRP (Modified Rodrigues Parameters)\nR_mrp = MRP(R_euler)\nRotations.params(R_mrp)\n\n# Get parameters of the MRP\nRotations.params(R_mrp)\n\n# Also supports 2D rotation\nR_2d = Angle2d(π/6)\n\n# Also supports some differentiation\nRotations.jacobian(RotMatrix, R_quat)","category":"page"},{"location":"general_dimensional_rotations/#General-dimensional-Rotation","page":"General Dimensional Rotations","title":"General dimensional Rotation","text":"","category":"section"},{"location":"general_dimensional_rotations/","page":"General Dimensional Rotations","title":"General Dimensional Rotations","text":"Our main goal is to efficiently represent rotations in lower dimensions, such as 2D and 3D, but some operations on rotations in general dimensions are also supported.","category":"page"},{"location":"general_dimensional_rotations/","page":"General Dimensional Rotations","title":"General Dimensional Rotations","text":"using Rotations\nusing StaticArrays","category":"page"},{"location":"general_dimensional_rotations/","page":"General Dimensional Rotations","title":"General Dimensional Rotations","text":"example","category":"page"},{"location":"general_dimensional_rotations/","page":"General Dimensional Rotations","title":"General Dimensional Rotations","text":"r1 = one(RotMatrix{4}) # generate identity rotation matrix\nm = @SMatrix rand(4,4)\nr2 = nearest_rotation(m) # nearest rotation matrix from given matrix\nr3 = rand(RotMatrix{4}) # random rotation in SO(4)\nr1*r2/r3 # multiplication and division\ns = log(r2) # logarithm of RotMatrix is a RotMatrixGenerator\nexp(s) # exponential of RotMatrixGenerator is a RotMatrix","category":"page"}] +[{"location":"3d_rotation_generator/#3D-Rotation-Generator","page":"3D Rotation Generators","title":"3D Rotation Generator","text":"","category":"section"},{"location":"3d_rotation_generator/","page":"3D Rotation Generators","title":"3D Rotation Generators","text":"using Rotations","category":"page"},{"location":"3d_rotation_generator/#RotMatrixGenerator3","page":"3D Rotation Generators","title":"RotMatrixGenerator3","text":"","category":"section"},{"location":"3d_rotation_generator/","page":"3D Rotation Generators","title":"3D Rotation Generators","text":"example","category":"page"},{"location":"3d_rotation_generator/","page":"3D Rotation Generators","title":"3D Rotation Generators","text":"m = rand(3,3)\ns = RotMatrixGenerator{3}(m - m')\nexp(s)","category":"page"},{"location":"3d_rotation_generator/#RotationVecGenerator","page":"3D Rotation Generators","title":"RotationVecGenerator","text":"","category":"section"},{"location":"3d_rotation_generator/","page":"3D Rotation Generators","title":"3D Rotation Generators","text":"example","category":"page"},{"location":"3d_rotation_generator/","page":"3D Rotation Generators","title":"3D Rotation Generators","text":"s = RotationVecGenerator(0.1,0.2,0.3)\nexp(s)\nlog(exp(s))\nrotation_angle(exp(s))\nrotation_angle(exp(2s))\nrotation_angle(exp(2s)) / rotation_angle(exp(s))","category":"page"},{"location":"functionreference/","page":"Function Reference","title":"Function Reference","text":"Modules = [Rotations]","category":"page"},{"location":"functionreference/#Rotations.Angle2d","page":"Function Reference","title":"Rotations.Angle2d","text":"struct Angle2d{T} <: Rotation{2,T}\n theta::T\nend\n\nA 2×2 rotation matrix parameterized by a 2D rotation by angle. Only the angle is stored inside the Angle2d type, values of getindex etc. are computed on the fly.\n\n\n\n\n\n","category":"type"},{"location":"functionreference/#Rotations.Angle2dGenerator","page":"Function Reference","title":"Rotations.Angle2dGenerator","text":"struct Angle2dGenerator{T} <: RotationGenerator{2,T}\n v::T\nend\n\nA 2×2 rotation generator matrix (i.e. skew-symmetric matrix). [ 0 -v v 0 ]\n\n\n\n\n\n","category":"type"},{"location":"functionreference/#Rotations.AngleAxis","page":"Function Reference","title":"Rotations.AngleAxis","text":"struct AngleAxis{T} <: Rotation{3,T}\nAngleAxis(Θ, x, y, z)\n\nA 3×3 rotation matrix parameterized by a 3D rotation by angle θ about an arbitrary axis [x, y, z].\n\nNote that the axis is not unique for θ = 0, and that this parameterization does not continuously map the neighbourhood of the identity rotation (and therefore might not be suitable for autodifferentation and optimization purposes).\n\nNote: by default, the constructor will renormalize the input so that the axis has length 1 (x² + y² + z² = 1).\n\nRenormalization can be skipped by passing false as an additional constructor argument, in which case the user provides the guarantee that the input arguments represent a normalized rotation axis. Operations on an AngleAxis with a rotation axis that does not have unit norm, created by skipping renormalization in this fashion, are not guaranteed to do anything sensible.\n\n\n\n\n\n","category":"type"},{"location":"functionreference/#Rotations.ErrorMap","page":"Function Reference","title":"Rotations.ErrorMap","text":"ErrorMap\n\nA nonlinear mapping between the space of unit quaternions and three-dimensional rotation errors.\n\nThese mappings are extremely useful for converting from globally nonsingular 3D rotation representations such as QuatRotation or RotMatrix3 to a three-parameter error that can be efficiently used in gradient-based optimization methods that optimize deviations about a current iterate using first or second-order information.\n\nUsage\n\nerrmap(v::AbstractVector) # \"forward\" map from a 3D error to a `QuatRotation`\ninv(errmap)(R::Rotation) # \"inverse\" map from a rotation (via `QuatRotation`) to a 3D error\n\nwhere errmap <: ErrorMap\n\nImplemented Maps\n\nCayleyMap: Uses RodriguesParam as the error representation (default). Goes singular at 180° and does not have a sign ambiguity.\nExponentialMap: Uses the canonical exponential map from Lie Group theory. Computationally expensive to compute. Exhibits kinematic singularities.\nMRPMap: Uses a scaled MRP as the error representation. Singular at 360° but has a sign ambiguity (with the \"shadow\" MRP set).\nQuatVecMap: Uses the vector part of the quaternions. Cheapest map to compute, but goes singular at 180° and suffers from sign ambiguity.\nIdentityMap: Maps values through directly. Only works with three-parameter rotation representations with the following methods: R(::SVector{3}) and SVector(::R)::SVector{3}\n\n\n\n\n\n","category":"type"},{"location":"functionreference/#Rotations.InvErrorMap","page":"Function Reference","title":"Rotations.InvErrorMap","text":"InvErrorMap\n\nThe nonlinear mapping from unit quaternions to a three-dimensional error state. Obtained by inverting an ErrorMap, i.e.\n\nInvCayleyMap() = inv(CayleyMap())\n\nUsage\n\nimap(R::Rotation) # \"inverse\" map from a rotation to a 3D error\ninv(imap)(v::AbstractVector) # \"forward\" map from a 3D error to a `QuatRotation`\n\nwhere imap <: InvErrorMap.\n\nSee ErrorMap for documentation on the implemented maps.\n\n\n\n\n\n","category":"type"},{"location":"functionreference/#Rotations.MRP","page":"Function Reference","title":"Rotations.MRP","text":"MRP{T} <: Rotation\n\nModified Rodrigues Parameter. Is a 3D parameterization of attitude, and is a sterographic projection of the 4D unit sphere onto the plane tangent to the negative real pole. They have a singularity at θ = ±360°.\n\nConstructors\n\nMRP(x, y, z) MRP(r::AbstractVector)\n\n\n\n\n\n","category":"type"},{"location":"functionreference/#Rotations.QuatRotation","page":"Function Reference","title":"Rotations.QuatRotation","text":"QuatRotation{T} <: Rotation\n\n4-parameter attitute representation that is singularity-free. Quaternions with unit norm represent a double-cover of SO(3). The QuatRotation does NOT strictly enforce the unit norm constraint, but certain methods will assume you have a unit quaternion. Follows the Hamilton convention for quaternions.\n\nConstructors\n\nQuatRotation(w,x,y,z)\nQuatRotation(q::AbstractVector)\n\nwhere w is the scalar (real) part, x, y, and z are the vector (imaginary) part, and q = [w,x,y,z].\n\n\n\n\n\n","category":"type"},{"location":"functionreference/#Rotations.RodriguesParam","page":"Function Reference","title":"Rotations.RodriguesParam","text":"RodriguesParam{T}\n\nRodrigues parameters are a three-dimensional parameterization of rotations. They have a singularity at 180° but do not inherit the sign ambiguities of quaternions or MRPs\n\n\n\n\n\n","category":"type"},{"location":"functionreference/#Rotations.RotMatrix","page":"Function Reference","title":"Rotations.RotMatrix","text":"struct RotMatrix{N,T} <: Rotation{N,T}\n\nA statically-sized, N×N unitary (orthogonal) matrix.\n\nNote: the orthonormality of the input matrix is not checked by the constructor.\n\n\n\n\n\n","category":"type"},{"location":"functionreference/#Rotations.RotMatrixGenerator","page":"Function Reference","title":"Rotations.RotMatrixGenerator","text":"struct RotMatrixGenerator{N,T} <: RotationGenerator{N,T}\n\nA statically-sized, N×N skew-symmetric matrix.\n\nNote: the skew-symmetricity of the input matrix is not checked by the constructor.\n\n\n\n\n\n","category":"type"},{"location":"functionreference/#Rotations.RotX","page":"Function Reference","title":"Rotations.RotX","text":"struct RotX{T} <: Rotation{3,T}\nRotX(theta)\n\nA 3×3 rotation matrix which represents a rotation by theta about the X axis.\n\n\n\n\n\n","category":"type"},{"location":"functionreference/#Rotations.RotXY","page":"Function Reference","title":"Rotations.RotXY","text":"struct RotXY{T} <: Rotation{3,T}\nRotXY(theta_x, theta_y)\n\nA 3×3 rotation matrix which represents a rotation by theta_y about the Y axis, followed by a rotation by theta_x about the X axis.\n\n\n\n\n\n","category":"type"},{"location":"functionreference/#Rotations.RotXYX","page":"Function Reference","title":"Rotations.RotXYX","text":"struct RotXYX{T} <: Rotation{3,T}\nRotXYX(theta1, theta2, theta3)\n\nA 3×3 rotation matrix parameterized by the \"proper\" XYX Euler angle convention, consisting of first a rotation about the X axis by theta3, followed by a rotation about the Y axis by theta2, and finally a rotation about the X axis by theta1.\n\n\n\n\n\n","category":"type"},{"location":"functionreference/#Rotations.RotXYZ","page":"Function Reference","title":"Rotations.RotXYZ","text":"struct RotXYZ{T} <: Rotation{3,T}\nRotXYZ(theta1, theta2, theta3)\nRotXYZ(roll=r, pitch=p, yaw=y)\n\nA 3×3 rotation matrix parameterized by the \"Tait-Bryant\" XYZ Euler angle convention, consisting of first a rotation about the Z axis by theta3, followed by a rotation about the Y axis by theta2, and finally a rotation about the X axis by theta1.\n\nThe keyword argument form applies roll, pitch and yaw to the X, Y and Z axes respectively, in XYZ order. (Because it is a right-handed coordinate system, note that positive pitch is heading in the negative Z axis).\n\n\n\n\n\n","category":"type"},{"location":"functionreference/#Rotations.RotXZ","page":"Function Reference","title":"Rotations.RotXZ","text":"struct RotXZ{T} <: Rotation{3,T}\nRotXZ(theta_x, theta_z)\n\nA 3×3 rotation matrix which represents a rotation by theta_z about the Z axis, followed by a rotation by theta_x about the X axis.\n\n\n\n\n\n","category":"type"},{"location":"functionreference/#Rotations.RotXZX","page":"Function Reference","title":"Rotations.RotXZX","text":"struct RotXZX{T} <: Rotation{3,T}\nRotXZX(theta1, theta2, theta3)\n\nA 3×3 rotation matrix parameterized by the \"proper\" XZX Euler angle convention, consisting of first a rotation about the X axis by theta3, followed by a rotation about the Z axis by theta2, and finally a rotation about the X axis by theta1.\n\n\n\n\n\n","category":"type"},{"location":"functionreference/#Rotations.RotXZY","page":"Function Reference","title":"Rotations.RotXZY","text":"struct RotXZY{T} <: Rotation{3,T}\nRotXZY(theta1, theta2, theta3)\nRotXZY(roll=r, pitch=p, yaw=y)\n\nA 3×3 rotation matrix parameterized by the \"Tait-Bryant\" XZY Euler angle convention, consisting of first a rotation about the Y axis by theta3, followed by a rotation about the Z axis by theta2, and finally a rotation about the X axis by theta1.\n\nThe keyword argument form applies roll, pitch and yaw to the X, Y and Z axes respectively, in XZY order. (Because it is a right-handed coordinate system, note that positive pitch is heading in the negative Z axis).\n\n\n\n\n\n","category":"type"},{"location":"functionreference/#Rotations.RotY","page":"Function Reference","title":"Rotations.RotY","text":"struct RotY{T} <: Rotation{3,T}\nRotY(theta)\n\nA 3×3 rotation matrix which represents a rotation by theta about the Y axis.\n\n\n\n\n\n","category":"type"},{"location":"functionreference/#Rotations.RotYX","page":"Function Reference","title":"Rotations.RotYX","text":"struct RotYX{T} <: Rotation{3,T}\nRotYX(theta_y, theta_x)\n\nA 3×3 rotation matrix which represents a rotation by theta_x about the X axis, followed by a rotation by theta_y about the Y axis.\n\n\n\n\n\n","category":"type"},{"location":"functionreference/#Rotations.RotYXY","page":"Function Reference","title":"Rotations.RotYXY","text":"struct RotYXY{T} <: Rotation{3,T}\nRotYXY(theta1, theta2, theta3)\n\nA 3×3 rotation matrix parameterized by the \"proper\" YXY Euler angle convention, consisting of first a rotation about the Y axis by theta3, followed by a rotation about the X axis by theta2, and finally a rotation about the Y axis by theta1.\n\n\n\n\n\n","category":"type"},{"location":"functionreference/#Rotations.RotYXZ","page":"Function Reference","title":"Rotations.RotYXZ","text":"struct RotYXZ{T} <: Rotation{3,T}\nRotYXZ(theta1, theta2, theta3)\nRotYXZ(roll=r, pitch=p, yaw=y)\n\nA 3×3 rotation matrix parameterized by the \"Tait-Bryant\" YXZ Euler angle convention, consisting of first a rotation about the Z axis by theta3, followed by a rotation about the X axis by theta2, and finally a rotation about the Y axis by theta1.\n\nThe keyword argument form applies roll, pitch and yaw to the X, Y and Z axes respectively, in YXZ order. (Because it is a right-handed coordinate system, note that positive pitch is heading in the negative Z axis).\n\n\n\n\n\n","category":"type"},{"location":"functionreference/#Rotations.RotYZ","page":"Function Reference","title":"Rotations.RotYZ","text":"struct RotYZ{T} <: Rotation{3,T}\nRotYZ(theta_y, theta_z)\n\nA 3×3 rotation matrix which represents a rotation by theta_z about the Z axis, followed by a rotation by theta_y about the Y axis.\n\n\n\n\n\n","category":"type"},{"location":"functionreference/#Rotations.RotYZX","page":"Function Reference","title":"Rotations.RotYZX","text":"struct RotYZX{T} <: Rotation{3,T}\nRotYZX(theta1, theta2, theta3)\nRotYZX(roll=r, pitch=p, yaw=y)\n\nA 3×3 rotation matrix parameterized by the \"Tait-Bryant\" YZX Euler angle convention, consisting of first a rotation about the X axis by theta3, followed by a rotation about the Z axis by theta2, and finally a rotation about the Y axis by theta1.\n\nThe keyword argument form applies roll, pitch and yaw to the X, Y and Z axes respectively, in YZX order. (Because it is a right-handed coordinate system, note that positive pitch is heading in the negative Z axis).\n\n\n\n\n\n","category":"type"},{"location":"functionreference/#Rotations.RotYZY","page":"Function Reference","title":"Rotations.RotYZY","text":"struct RotYZY{T} <: Rotation{3,T}\nRotYZY(theta1, theta2, theta3)\n\nA 3×3 rotation matrix parameterized by the \"proper\" YXY Euler angle convention, consisting of first a rotation about the Y axis by theta3, followed by a rotation about the Z axis by theta2, and finally a rotation about the Y axis by theta1.\n\n\n\n\n\n","category":"type"},{"location":"functionreference/#Rotations.RotZ","page":"Function Reference","title":"Rotations.RotZ","text":"struct RotZ{T} <: Rotation{3,T}\nRotZ(theta)\n\nA 3×3 rotation matrix which represents a rotation by theta about the Z axis.\n\n\n\n\n\n","category":"type"},{"location":"functionreference/#Rotations.RotZX","page":"Function Reference","title":"Rotations.RotZX","text":"struct RotZX{T} <: Rotation{3,T}\nRotZX(theta_z, theta_x)\n\nA 3×3 rotation matrix which represents a rotation by theta_x about the X axis, followed by a rotation by theta_z about the Z axis.\n\n\n\n\n\n","category":"type"},{"location":"functionreference/#Rotations.RotZXY","page":"Function Reference","title":"Rotations.RotZXY","text":"struct RotZXY{T} <: Rotation{3,T}\nRotZXY(theta1, theta2, theta3)\nRotZXY(roll=r, pitch=p, yaw=y)\n\nA 3×3 rotation matrix parameterized by the \"Tait-Bryant\" ZXY Euler angle convention, consisting of first a rotation about the Y axis by theta3, followed by a rotation about the X axis by theta2, and finally a rotation about the Z axis by theta1.\n\nThe keyword argument form applies roll, pitch and yaw to the X, Y and Z axes respectively, in ZXY order. (Because it is a right-handed coordinate system, note that positive pitch is heading in the negative Z axis).\n\n\n\n\n\n","category":"type"},{"location":"functionreference/#Rotations.RotZXZ","page":"Function Reference","title":"Rotations.RotZXZ","text":"struct RotZXZ{T} <: Rotation{3,T}\nRotZXZ(theta1, theta2, theta3)\n\nA 3×3 rotation matrix parameterized by the \"proper\" ZXZ Euler angle convention, consisting of first a rotation about the Z axis by theta3, followed by a rotation about the X axis by theta2, and finally a rotation about the Z axis by theta1.\n\n\n\n\n\n","category":"type"},{"location":"functionreference/#Rotations.RotZY","page":"Function Reference","title":"Rotations.RotZY","text":"struct RotZY{T} <: Rotation{3,T}\nRotZY(theta_z, theta_y)\n\nA 3×3 rotation matrix which represents a rotation by theta_y about the Y axis, followed by a rotation by theta_z about the Z axis.\n\n\n\n\n\n","category":"type"},{"location":"functionreference/#Rotations.RotZYX","page":"Function Reference","title":"Rotations.RotZYX","text":"struct RotZYX{T} <: Rotation{3,T}\nRotZYX(theta1, theta2, theta3)\nRotZYX(roll=r, pitch=p, yaw=y)\n\nA 3×3 rotation matrix parameterized by the \"Tait-Bryant\" ZYX Euler angle convention, consisting of first a rotation about the X axis by theta3, followed by a rotation about the Y axis by theta2, and finally a rotation about the Z axis by theta1.\n\nThe keyword argument form applies roll, pitch and yaw to the X, Y and Z axes respectively, in ZYX order. (Because it is a right-handed coordinate system, note that positive pitch is heading in the negative Z axis).\n\n\n\n\n\n","category":"type"},{"location":"functionreference/#Rotations.RotZYZ","page":"Function Reference","title":"Rotations.RotZYZ","text":"struct RotZYZ{T} <: Rotation{3,T}\nRotZYZ(theta1, theta2, theta3)\n\nA 3×3 rotation matrix parameterized by the \"proper\" ZXZ Euler angle convention, consisting of first a rotation about the Z axis by theta3, followed by a rotation about the Y axis by theta2, and finally a rotation about the Z axis by theta1.\n\n\n\n\n\n","category":"type"},{"location":"functionreference/#Rotations.Rotation","page":"Function Reference","title":"Rotations.Rotation","text":"abstract type Rotation{N,T} <: StaticMatrix{N,N,T}\n\nAn abstract type representing N-dimensional rotations. More abstractly, they represent unitary (orthogonal) N×N matrices.\n\n\n\n\n\n","category":"type"},{"location":"functionreference/#Rotations.RotationError","page":"Function Reference","title":"Rotations.RotationError","text":"RotationError{T<:Real, D<:ErrorMap} <: StaticVector{3,T}\n\nA three-parameter rotation error, converted to/from a QuatRotation using the ErrorMap D.\n\nUsage\n\nA RotationError is typically created using one of the following methods\n\nrotation_error(R1::Rotation, R2::Rotation, error_map::ErrorMap)\nR1 ⊖ R2\n\nwhich compute the difference between the rotations R1 and R2 and convert the result to a 3D rotation error using error_map.\n\nThe error can be \"added\" back to a rotation using the inverse operation:\n\nadd_error(R1::Rotation, e::RotationError)\nR1::Rotation ⊕ e::RotationError\n\n\n\n\n\n","category":"type"},{"location":"functionreference/#Rotations.RotationGenerator","page":"Function Reference","title":"Rotations.RotationGenerator","text":"abstract type RotationGenerator{N,T} <: StaticMatrix{N,N,T}\n\nAn abstract type representing N-dimensional rotation generator. More abstractly, they represent skew-symmetric real N×N matrices.\n\n\n\n\n\n","category":"type"},{"location":"functionreference/#Rotations.RotationVec","page":"Function Reference","title":"Rotations.RotationVec","text":"struct RotationVec{T} <: Rotation{3,T}\nRotationVec(sx, sy, sz)\n\nRodrigues vector parameterization of a 3×3 rotation matrix. The direction of the vector [sx, sy, sz] defines the axis of rotation, and the rotation angle is given by its norm.\n\n\n\n\n\n","category":"type"},{"location":"functionreference/#Rotations.RotationVecGenerator","page":"Function Reference","title":"Rotations.RotationVecGenerator","text":"struct RotationVecGenerator{T} <: RotationGenerator{2,T}\n x::T\n y::T\n z::T\nend\n\nA 3×3 rotation generator matrix (i.e. skew-symmetric matrix). [ 0 -z y z 0 -x -y x 0]\n\n\n\n\n\n","category":"type"},{"location":"functionreference/#Base.:*-Tuple{QuatRotation, QuatRotation}","page":"Function Reference","title":"Base.:*","text":"(*)(q::QuatRotation, w::QuatRotation)\n\nQuternion Composition\n\nEquivalent to\n\nlmult(q) * SVector(w)\nrmult(w) * SVector(q)\n\nSets the output mapping equal to the mapping of w\n\n\n\n\n\n","category":"method"},{"location":"functionreference/#Base.:*-Tuple{QuatRotation, StaticArraysCore.StaticArray{Tuple{N}, T, 1} where {N, T}}","page":"Function Reference","title":"Base.:*","text":"(*)(q::QuatRotation, r::StaticVector)\n\nRotate a vector\n\nEquivalent to hmat()' lmult(q) * rmult(q)' hmat() * r\n\n\n\n\n\n","category":"method"},{"location":"functionreference/#Quaternions.slerp-Tuple{QuatRotation, QuatRotation, Real}","page":"Function Reference","title":"Quaternions.slerp","text":"slerp(R1::Rotaion{3}, R2::Rotaion{3}, t::Real)\n\nPerform spherical linear interpolation (Slerp) between rotations R1 and R2.\n\n\n\n\n\n","category":"method"},{"location":"functionreference/#Rotations.add_error-Tuple{Rotation, Rotations.RotationError}","page":"Function Reference","title":"Rotations.add_error","text":"add_error(R1::Rotation, e::RotationError)\n\n\"Adds\" the rotation error e to the rotation R1 by converting e to a quaternion via its ErrorMap and then composing with R1.\n\nEquivalent to\n\nR1 ⊕ e\n\n\n\n\n\n","category":"method"},{"location":"functionreference/#Rotations.hmat-Union{Tuple{}, Tuple{Type{T}}, Tuple{T}} where T","page":"Function Reference","title":"Rotations.hmat","text":"hmat()\nhmat(r::AbstractVector)\n\nhmat()*r or hmat(r) converts r into a pure quaternion, where r is 3-dimensional.\n\nhmat() == vmat()'\n\n\n\n\n\n","category":"method"},{"location":"functionreference/#Rotations.isrotation","page":"Function Reference","title":"Rotations.isrotation","text":"isrotation(r)\nisrotation(r, tol)\n\nCheck whether r is a rotation matrix, where r * r' is within tol of the identity matrix (using the Frobenius norm). tol defaults to 1000 * eps(float(eltype(r))) or zero(T) for integer T.\n\n\n\n\n\n","category":"function"},{"location":"functionreference/#Rotations.isrotationgenerator","page":"Function Reference","title":"Rotations.isrotationgenerator","text":"isrotationgenerator(r)\n\nCheck whether r is a rotation generator matrix (skew-symmetric matrix).\n\n\n\n\n\n","category":"function"},{"location":"functionreference/#Rotations.jacobian","page":"Function Reference","title":"Rotations.jacobian","text":"jacobian(::InvErrorMap, q::QuatRotation)\n\nJacobian of the inverse quaternion map, returning a 3×4 matrix. For all maps: jacobian(::InvErrorMap, QuatRotation(I)) = [0 I] = Hmat()'\n\n\n\n\n\n","category":"function"},{"location":"functionreference/#Rotations.jacobian-2","page":"Function Reference","title":"Rotations.jacobian","text":"jacobian(::ErrorMap, ϕ)\n\nJacobian of the quaternion map that takes a three-dimensional vector ϕ and returns a unit quaternion. Returns a 4x3 Static Matrix\n\nFor all the maps (except the IdentityMap) jacobian(::ErrorMap, zeros(3)) = [0; I] = Hmat()'\n\n\n\n\n\n","category":"function"},{"location":"functionreference/#Rotations.jacobian-Tuple{Type{RotMatrix}, QuatRotation}","page":"Function Reference","title":"Rotations.jacobian","text":"jacobian(::Type{output_param}, R::input_param)\n\nReturns the jacobian for transforming from the input rotation parameterization to the output parameterization, centered at the value of R.\n\njacobian(R::rotation_type, X::AbstractVector)\n\nReturns the jacobian for rotating the vector X by R.\n\n\n\n\n\n","category":"method"},{"location":"functionreference/#Rotations.kinematics-Union{Tuple{Q}, Tuple{Q, AbstractVector}} where Q<:QuatRotation","page":"Function Reference","title":"Rotations.kinematics","text":"kinematics(R::Rotation{3}, ω::AbstractVector)\n\nThe time derivative of the rotation R, according to the definition\n\nR = lim_Δt 0 fracR(t + Δt) - R(t)Δt\n\nwhere ω is the angular velocity. This is equivalent to\n\nR = lim_Δt 0 fracR δR - RΔt\n\nwhere δR is some small rotation, parameterized by a small rotation δθ about an axis r, such that lim_Δt 0 fracδθ rΔt = ω\n\nThe kinematics are extremely useful when computing the dynamics of rigid bodies, since Ṙ = kinematics(R,ω) is the first-order ODE for the evolution of the attitude dynamics.\n\nSee \"Fundamentals of Spacecraft Attitude Determination and Control\" by Markley and Crassidis Sections 3.1-3.2 for more details.\n\n\n\n\n\n","category":"method"},{"location":"functionreference/#Rotations.lmult-Tuple{QuatRotation}","page":"Function Reference","title":"Rotations.lmult","text":"lmult(q::QuatRotation)\nlmult(q::StaticVector{4})\n\nlmult(q2)*params(q1) returns a vector equivalent to q2*q1 (quaternion composition)\n\n\n\n\n\n","category":"method"},{"location":"functionreference/#Rotations.nearest_rotation-Union{Tuple{StaticArraysCore.StaticArray{Tuple{N, N}, T, 2} where T}, Tuple{N}} where N","page":"Function Reference","title":"Rotations.nearest_rotation","text":"nearest_rotation(M) -> RotMatrix\n\nGet the nearest special orthonormal matrix from given matrix M. See Wahba's problem for more information.\n\n\n\n\n\n","category":"method"},{"location":"functionreference/#Rotations.params-Tuple{QuatRotation}","page":"Function Reference","title":"Rotations.params","text":"params(R::Rotation)\n\nReturn an SVector of the underlying parameters used by the rotation representation.\n\nExample\n\np = MRP(1.0, 2.0, 3.0)\nRotations.params(p) == @SVector [1.0, 2.0, 3.0] # true\n\n\n\n\n\n","category":"method"},{"location":"functionreference/#Rotations.perpendicular_vector-Tuple{StaticArraysCore.StaticArray{Tuple{3}, T, 1} where T}","page":"Function Reference","title":"Rotations.perpendicular_vector","text":"perpendicular_vector(vec)\n\nCompute a vector perpendicular to vec by switching the two elements with largest absolute value, flipping the sign of the second largest, and setting the remaining element to zero.\n\n\n\n\n\n","category":"method"},{"location":"functionreference/#Rotations.principal_value-Tuple{Rotation}","page":"Function Reference","title":"Rotations.principal_value","text":"principal_value(R::Rotation{3})\n\nBackground: All non RotMatrix rotation types can represent the same RotMatrix in two or more ways. Sometimes a particular set of numbers is better conditioned (e.g. MRP) or obeys a particular convention (e.g. AngleAxis has non-negative rotation). In order to preserve differentiability it is necessary to allow rotation representations to travel slightly away from the nominal domain; this is critical for applications such as optimization or dynamics.\n\nThis function takes a rotation type (e.g. QuatRotation, RotXY) and outputs a new rotation of the same type that corresponds to the same RotMatrix, but that obeys certain conventions or is better conditioned. The outputs of the function have the following properties:\n\nall angles are between between -pi to pi (except for AngleAxis which is between 0 and pi).\nall `QuatRotation have non-negative real part\nthe components of all MRP have a norm that is at most 1.\nthe RotationVec rotation is at most pi\n\n\n\n\n\n","category":"method"},{"location":"functionreference/#Rotations.pure_quaternion-Tuple{AbstractVector}","page":"Function Reference","title":"Rotations.pure_quaternion","text":"pure_quaternion(v::AbstractVector)\npure_quaternion(x, y, z)\n\nCreate a Quaternion with zero scalar part (i.e. q.q.s == 0).\n\n\n\n\n\n","category":"method"},{"location":"functionreference/#Rotations.rmult-Tuple{QuatRotation}","page":"Function Reference","title":"Rotations.rmult","text":"rmult(q::QuatRotation)\nrmult(q::StaticVector{4})\n\nrmult(q1)*params(q2) return a vector equivalent to q2*q1 (quaternion composition)\n\n\n\n\n\n","category":"method"},{"location":"functionreference/#Rotations.rot_eltype-Tuple{Any}","page":"Function Reference","title":"Rotations.rot_eltype","text":"The element type for a rotation matrix with a given angle type is composed of trigonometric functions of that type.\n\n\n\n\n\n","category":"method"},{"location":"functionreference/#Rotations.rotation_between","page":"Function Reference","title":"Rotations.rotation_between","text":"rotation_between(u, v)\n\nCompute the quaternion that rotates vector u so that it aligns with vector v, along the geodesic (shortest path).\n\n\n\n\n\n","category":"function"},{"location":"functionreference/#Rotations.rotation_error-Tuple{Rotation, Rotation, Rotations.ErrorMap}","page":"Function Reference","title":"Rotations.rotation_error","text":"rotation_error(R1::Rotation, R2::Rotation, error_map::ErrorMap)\n\nCompute the RotationError by calculating the \"difference\" between R1 and R2, i.e. R2\\R1, then mapped to a three-parameter error using error_map.\n\nCan be equivalently called using the default map with R1 ⊖ R2\n\nIf error_map::IdentityMap, then SVector(R1\\R2)::SVector{3} is used as the error. Note this only works for three-parameter rotation representations such as RodriguesParam or MRP.\n\n\n\n\n\n","category":"method"},{"location":"functionreference/#Rotations.tmat-Union{Tuple{}, Tuple{Type{T}}, Tuple{T}} where T","page":"Function Reference","title":"Rotations.tmat","text":"tmat()\n\ntmat()*params(q)return a vector equivalent to inv(q), where q is a QuatRotation\n\n\n\n\n\n","category":"method"},{"location":"functionreference/#Rotations.vmat-Union{Tuple{}, Tuple{Type{T}}, Tuple{T}} where T","page":"Function Reference","title":"Rotations.vmat","text":"vmat()\n\nvmat()*params(q)returns the imaginary (vector) part of the quaternionq(equivalent tovector(q)``)\n\n\n\n\n\n","category":"method"},{"location":"functionreference/#Rotations.∇composition1-Tuple{QuatRotation, QuatRotation}","page":"Function Reference","title":"Rotations.∇composition1","text":"∇composition1(R2::Rotation{3}, R1::Rotation{3})\n\nJacobian of R2*R1 with respect to R1\n\n\n\n\n\n","category":"method"},{"location":"functionreference/#Rotations.∇composition2-Tuple{QuatRotation, QuatRotation}","page":"Function Reference","title":"Rotations.∇composition2","text":"∇composition2(R2::Rotation{3}, R1::Rotation{3})\n\nJacobian of R2*R1 with respect to R2\n\n\n\n\n\n","category":"method"},{"location":"functionreference/#Rotations.∇differential-Tuple{QuatRotation}","page":"Function Reference","title":"Rotations.∇differential","text":"∇differential(q::QuatRotation)\n\nJacobian of lmult(q) QuatMap(ϕ), when ϕ is near zero.\n\nUseful for converting Jacobians from R⁴ to R³ and correctly account for unit norm constraint. Jacobians for different differential quaternion parameterization are the same up to a constant.\n\n\n\n\n\n","category":"method"},{"location":"functionreference/#Rotations.∇err-Tuple{MRP, MRP}","page":"Function Reference","title":"Rotations.∇err","text":"∇err(p1::MRP, p2::MRP)\n\nJacobian of p1\\p2 wrt p2\n\n\n\n\n\n","category":"method"},{"location":"functionreference/#Rotations.∇jacobian","page":"Function Reference","title":"Rotations.∇jacobian","text":"∇jacobian(::InvErrorMap, q::QuatRotation, b::SVector{3})\n\nJacobian of G(q)'b, where G(q) = jacobian(::InvErrorMap, q), b is a 3-element vector\n\n\n\n\n\n","category":"function"},{"location":"functionreference/#Rotations.∇rotate-Tuple{QuatRotation, AbstractVector}","page":"Function Reference","title":"Rotations.∇rotate","text":"∇rotate(R::Rotation{3}, r::AbstractVector)\n\nJacobian of R*r with respect to the rotation\n\n\n\n\n\n","category":"method"},{"location":"functionreference/#Rotations.∇²differential-Tuple{QuatRotation, AbstractVector}","page":"Function Reference","title":"Rotations.∇²differential","text":"∇²differential(q::QuatRotation, b::AbstractVector)\n\nJacobian of (∂/∂ϕ lmult(q) QuatMap(ϕ))b, evaluated at ϕ=0, and b has length 4.\n\n\n\n\n\n","category":"method"},{"location":"functionreference/#Rotations.∇²err-Tuple{MRP, MRP, AbstractVector}","page":"Function Reference","title":"Rotations.∇²err","text":"∇²err(p1::MRP, p2::MRP, b::StaticVector{3})\n\nJacobian of (∂/∂p p1\\p2)'b wrt p2\n\n\n\n\n\n","category":"method"},{"location":"visualizing/#Visualizing-Rotation","page":"Visualizing Rotations","title":"Visualizing Rotation","text":"","category":"section"},{"location":"visualizing/","page":"Visualizing Rotations","title":"Visualizing Rotations","text":"In general, 3 times 3 matrix has 9 parameters, so it's hard to visualize a matrix as a point. However, the Lie group SO(3) and SU(2) are 3-dimensional space, and it is able to visualize its element as a point in our 3-dimensional space.","category":"page"},{"location":"visualizing/#using-MRP","page":"Visualizing Rotations","title":"using MRP","text":"","category":"section"},{"location":"visualizing/","page":"Visualizing Rotations","title":"Visualizing Rotations","text":"(TBW)","category":"page"},{"location":"visualizing/#using-RodriguesParam","page":"Visualizing Rotations","title":"using RodriguesParam","text":"","category":"section"},{"location":"visualizing/","page":"Visualizing Rotations","title":"Visualizing Rotations","text":"(TBW)","category":"page"},{"location":"visualizing/#using-RotationVec","page":"Visualizing Rotations","title":"using RotationVec","text":"","category":"section"},{"location":"visualizing/","page":"Visualizing Rotations","title":"Visualizing Rotations","text":"(TBW)","category":"page"},{"location":"functions/#Common-Methods-for-Rotations","page":"Common Methods for Rotations","title":"Common Methods for Rotations","text":"","category":"section"},{"location":"functions/#rotation_angle,-rotation_axis","page":"Common Methods for Rotations","title":"rotation_angle, rotation_axis","text":"","category":"section"},{"location":"functions/#3D","page":"Common Methods for Rotations","title":"3D","text":"","category":"section"},{"location":"functions/","page":"Common Methods for Rotations","title":"Common Methods for Rotations","text":"A rotation matrix can be expressed with one rotation around an axis and angle. these function can calculate these values.","category":"page"},{"location":"functions/","page":"Common Methods for Rotations","title":"Common Methods for Rotations","text":"example","category":"page"},{"location":"functions/","page":"Common Methods for Rotations","title":"Common Methods for Rotations","text":"using Rotations","category":"page"},{"location":"functions/","page":"Common Methods for Rotations","title":"Common Methods for Rotations","text":"R = RotXYZ(2.4, -1.8, 0.5)\nθ = rotation_angle(R)\nn = rotation_axis(R)\n# These matrices are approximately equal.\nR ≈ AngleAxis(θ, n...)","category":"page"},{"location":"functions/#2D","page":"Common Methods for Rotations","title":"2D","text":"","category":"section"},{"location":"functions/","page":"Common Methods for Rotations","title":"Common Methods for Rotations","text":"R = Angle2d(2.4)\nθ = rotation_angle(R)","category":"page"},{"location":"functions/#Rotations.params","page":"Common Methods for Rotations","title":"Rotations.params","text":"","category":"section"},{"location":"functions/","page":"Common Methods for Rotations","title":"Common Methods for Rotations","text":"The parameters of the rotation can be obtained by Rotations.params.","category":"page"},{"location":"functions/","page":"Common Methods for Rotations","title":"Common Methods for Rotations","text":"example","category":"page"},{"location":"functions/","page":"Common Methods for Rotations","title":"Common Methods for Rotations","text":"using Rotations","category":"page"},{"location":"functions/","page":"Common Methods for Rotations","title":"Common Methods for Rotations","text":"R = one(RotMatrix{3}) # Identity matrix\nRotations.params(RotYZY(R)) # Proper Euler angles, (y,z,y)\nRotations.params(RotXYZ(R)) # Tait–Bryan angles, (x,y,z)\nRotations.params(AngleAxis(R)) # Rotation around an axis (theta, axis_x, axis_y, axis_z)\nRotations.params(RotationVec(R)) # Rotation vector (v_x, v_y, v_z)\nRotations.params(QuatRotation(R)) # Quaternion (w, x, y, z)\nRotations.params(RodriguesParam(R)) # Rodrigues Parameters (x, y, z)\nRotations.params(MRP(R)) # Modified Rodrigues Parameters (x, y, z)","category":"page"},{"location":"functions/#isrotation","page":"Common Methods for Rotations","title":"isrotation","text":"","category":"section"},{"location":"functions/","page":"Common Methods for Rotations","title":"Common Methods for Rotations","text":"Check the given matrix is rotation matrix.","category":"page"},{"location":"functions/","page":"Common Methods for Rotations","title":"Common Methods for Rotations","text":"example","category":"page"},{"location":"functions/","page":"Common Methods for Rotations","title":"Common Methods for Rotations","text":"(TBW)","category":"page"},{"location":"functions/#nearest_rotation","page":"Common Methods for Rotations","title":"nearest_rotation","text":"","category":"section"},{"location":"functions/","page":"Common Methods for Rotations","title":"Common Methods for Rotations","text":"using Rotations","category":"page"},{"location":"functions/","page":"Common Methods for Rotations","title":"Common Methods for Rotations","text":"Get the nearest special orthonormal matrix from given matrix M. The problem of finding the orthogonal matrix nearest to a given matrix is related to the Wahba's problem.","category":"page"},{"location":"functions/","page":"Common Methods for Rotations","title":"Common Methods for Rotations","text":"example","category":"page"},{"location":"functions/","page":"Common Methods for Rotations","title":"Common Methods for Rotations","text":"M = randn(3,3) # Generate random matrix\nR = nearest_rotation(M) # Find the nearest rotation matrix\nU, V = R\\M, M/R # Polar decomposition of M\nU ≈ U' # U is a symmetric matrix (The same for V)","category":"page"},{"location":"functions/#rand","page":"Common Methods for Rotations","title":"rand","text":"","category":"section"},{"location":"functions/","page":"Common Methods for Rotations","title":"Common Methods for Rotations","text":"using Rotations","category":"page"},{"location":"functions/#rand-for-SO(2)","page":"Common Methods for Rotations","title":"rand for SO(2)","text":"","category":"section"},{"location":"functions/","page":"Common Methods for Rotations","title":"Common Methods for Rotations","text":"The following types have the same algebraic structure as SO(2)","category":"page"},{"location":"functions/","page":"Common Methods for Rotations","title":"Common Methods for Rotations","text":"RotMatrix{2}\nAngle2d\nRotX\nRotY\nRotZ","category":"page"},{"location":"functions/","page":"Common Methods for Rotations","title":"Common Methods for Rotations","text":"The random distribution is based on Haar measure.","category":"page"},{"location":"functions/","page":"Common Methods for Rotations","title":"Common Methods for Rotations","text":"example","category":"page"},{"location":"functions/","page":"Common Methods for Rotations","title":"Common Methods for Rotations","text":"R = rand(Angle2d)","category":"page"},{"location":"functions/#rand-for-SO(3)","page":"Common Methods for Rotations","title":"rand for SO(3)","text":"","category":"section"},{"location":"functions/","page":"Common Methods for Rotations","title":"Common Methods for Rotations","text":"The following types have an algebraic structure that is homomorphic to SO(3).","category":"page"},{"location":"functions/","page":"Common Methods for Rotations","title":"Common Methods for Rotations","text":"RotMatrix{3}\nRotXYZ (and other Euler angles)\nAngleAxis\nRotationVec\nQuatRotation\nRodriguesParam\nMRP","category":"page"},{"location":"functions/","page":"Common Methods for Rotations","title":"Common Methods for Rotations","text":"example","category":"page"},{"location":"functions/","page":"Common Methods for Rotations","title":"Common Methods for Rotations","text":"R = rand(RotationVec)","category":"page"},{"location":"functions/","page":"Common Methods for Rotations","title":"Common Methods for Rotations","text":"The random distribution is based on Haar measure.","category":"page"},{"location":"functions/#rand-for-RotXY-and-etc.","page":"Common Methods for Rotations","title":"rand for RotXY and etc.","text":"","category":"section"},{"location":"functions/","page":"Common Methods for Rotations","title":"Common Methods for Rotations","text":"There also are methods for rand(::RotXY) and other 2-axis rotations.","category":"page"},{"location":"functions/","page":"Common Methods for Rotations","title":"Common Methods for Rotations","text":"example","category":"page"},{"location":"functions/","page":"Common Methods for Rotations","title":"Common Methods for Rotations","text":"R = rand(RotXY)","category":"page"},{"location":"functions/","page":"Common Methods for Rotations","title":"Common Methods for Rotations","text":"The random distribution is NOT based on Haar measure because the set of RotXY doesn't have group structure.","category":"page"},{"location":"functions/","page":"Common Methods for Rotations","title":"Common Methods for Rotations","text":"Note that:","category":"page"},{"location":"functions/","page":"Common Methods for Rotations","title":"Common Methods for Rotations","text":"rand(RotX) is same as RotX(2π*rand()).\nrand(RotXY) is same as RotXY(2π*rand(), 2π*rand()).\nrand(RotXYZ) is not same as RotXYZ(2π*rand(), 2π*rand(), 2π*rand()).\nBut rand(RotXYZ) is same as RotXYZ(rand(QuatRotation)).","category":"page"},{"location":"3d_euler/#3D-Rotation-with-Euler-Angles","page":"Euler Angles","title":"3D Rotation with Euler Angles","text":"","category":"section"},{"location":"3d_euler/","page":"Euler Angles","title":"Euler Angles","text":"Euler angles are a way to represent a rotation matrix with three rotations around cardinal axes.","category":"page"},{"location":"3d_euler/","page":"Euler Angles","title":"Euler Angles","text":"In Rotations.jl, there are 12 concrete types for Euler angles.","category":"page"},{"location":"3d_euler/","page":"Euler Angles","title":"Euler Angles","text":"Proper Euler angles\nRotZXZ, RotXYX, RotYZY, RotZYZ, RotXZX, RotYXY\nTait–Bryan angles\nRotXYZ, RotYZX, RotZXY, RotXZY, RotZYX, RotYXZ","category":"page"},{"location":"3d_euler/","page":"Euler Angles","title":"Euler Angles","text":"In addition, Rotations.jl provides concrete types that represent rotations in one or two axes.","category":"page"},{"location":"3d_euler/","page":"Euler Angles","title":"Euler Angles","text":"one axis\nRotX, RotY, RotZ\ntwo axes\nRotXY, RotYZ, RotZX, RotXZ, RotZY, RotYX","category":"page"},{"location":"3d_euler/#Rotation-around-one-axis","page":"Euler Angles","title":"Rotation around one axis","text":"","category":"section"},{"location":"3d_euler/","page":"Euler Angles","title":"Euler Angles","text":"beginaligned\nR_x(alpha)\n= beginpmatrix\n1 0 0 \n0 cos(alpha) -sin(alpha) \n0 sin(alpha) cos(alpha) \nendpmatrix \nR_y(alpha)\n= beginpmatrix\ncos(alpha) 0 sin(alpha) \n0 1 0 \n-sin(alpha) 0 cos(alpha) \nendpmatrix \nR_z(alpha)\n= beginpmatrix\ncos(alpha) -sin(alpha) 0\nsin(alpha) cos(alpha) 0\n0 0 1\nendpmatrix\nendaligned","category":"page"},{"location":"3d_euler/","page":"Euler Angles","title":"Euler Angles","text":"example","category":"page"},{"location":"3d_euler/","page":"Euler Angles","title":"Euler Angles","text":"using Rotations","category":"page"},{"location":"3d_euler/","page":"Euler Angles","title":"Euler Angles","text":"Here's an example for RotZ:","category":"page"},{"location":"3d_euler/","page":"Euler Angles","title":"Euler Angles","text":"α = 1.2 # Rotation angle\nR = RotZ(α)\nQ = [cos(α) -sin(α) 0\n sin(α) cos(α) 0\n 0 0 1]\n# These matrices are equal\nR == Q","category":"page"},{"location":"3d_euler/","page":"Euler Angles","title":"Euler Angles","text":"And more examples for RotX and RotY:","category":"page"},{"location":"3d_euler/","page":"Euler Angles","title":"Euler Angles","text":"# These matrices are equal\nRotX(α) == [1 0 0\n 0 cos(α) -sin(α)\n 0 sin(α) cos(α)]\n# These matrices are equal\nRotY(α) == [cos(α) 0 sin(α)\n 0 1 0\n -sin(α) 0 cos(α)]","category":"page"},{"location":"3d_euler/#Rotation-around-two-axes","page":"Euler Angles","title":"Rotation around two axes","text":"","category":"section"},{"location":"3d_euler/","page":"Euler Angles","title":"Euler Angles","text":"beginaligned\nR_xy(alphabeta)\n= R_x(alpha)R_y(beta)\n R_yx(alphabeta)\n= R_y(alpha)R_x(beta) \n\nR_yz(alphabeta)\n= R_y(alpha)R_z(beta)\n R_zy(alphabeta)\n= R_z(alpha)R_y(beta) \n\nR_zx(alphabeta)\n= R_z(alpha)R_x(beta)\n R_xz(alphabeta)\n= R_x(alpha)R_z(beta)\nendaligned","category":"page"},{"location":"3d_euler/","page":"Euler Angles","title":"Euler Angles","text":"example","category":"page"},{"location":"3d_euler/","page":"Euler Angles","title":"Euler Angles","text":"using Rotations","category":"page"},{"location":"3d_euler/","page":"Euler Angles","title":"Euler Angles","text":"α, β = 1.2, 4.7 # Rotation angles\nRotX(α) * RotY(β)\nRotXY(α, β)\n# These matrices are equal\nRotX(α) * RotY(β) == RotXY(α, β)","category":"page"},{"location":"3d_euler/#Rotation-around-three-axes-(Euler-Angles)","page":"Euler Angles","title":"Rotation around three axes (Euler Angles)","text":"","category":"section"},{"location":"3d_euler/","page":"Euler Angles","title":"Euler Angles","text":"Proper Euler angles","category":"page"},{"location":"3d_euler/","page":"Euler Angles","title":"Euler Angles","text":"beginaligned\nR_xyx(alpha beta gamma) = R_x(alpha) R_y(beta) R_x(gamma)\n R_yxy(alpha beta gamma) = R_y(alpha) R_x(beta) R_y(gamma) \nR_yzy(alpha beta gamma) = R_y(alpha) R_z(beta) R_y(gamma)\n R_zyz(alpha beta gamma) = R_z(alpha) R_y(beta) R_z(gamma) \nR_zxz(alpha beta gamma) = R_z(alpha) R_x(beta) R_z(gamma)\n R_xzx(alpha beta gamma) = R_x(alpha) R_z(beta) R_x(gamma)\nendaligned","category":"page"},{"location":"3d_euler/","page":"Euler Angles","title":"Euler Angles","text":"Tait–Bryan angles","category":"page"},{"location":"3d_euler/","page":"Euler Angles","title":"Euler Angles","text":"beginaligned\nR_xyz(alpha beta gamma) = R_x(alpha) R_y(beta) R_z(gamma)\n R_yxz(alpha beta gamma) = R_y(alpha) R_x(beta) R_z(gamma) \nR_yzx(alpha beta gamma) = R_y(alpha) R_z(beta) R_x(gamma)\n R_zyx(alpha beta gamma) = R_z(alpha) R_y(beta) R_x(gamma) \nR_zxy(alpha beta gamma) = R_z(alpha) R_x(beta) R_y(gamma)\n R_xzy(alpha beta gamma) = R_x(alpha) R_z(beta) R_y(gamma)\nendaligned","category":"page"},{"location":"3d_euler/","page":"Euler Angles","title":"Euler Angles","text":"example","category":"page"},{"location":"3d_euler/","page":"Euler Angles","title":"Euler Angles","text":"using Rotations","category":"page"},{"location":"3d_euler/","page":"Euler Angles","title":"Euler Angles","text":"α, β, γ = 1.2, 4.7, -0.4 # Rotation angles\nRotYXZ(α, β, γ)\nRotY(α)*RotX(β)*RotZ(γ)\n# These matrices are equal\nRotYXZ(α, β, γ) == RotY(α)*RotX(β)*RotZ(γ)","category":"page"},{"location":"2d_angle/#2D-Rotation-by-Angle","page":"Angle","title":"2D Rotation by Angle","text":"","category":"section"},{"location":"2d_angle/","page":"Angle","title":"Angle","text":"Angle2d is a type that internally has an angle as a parameter, and can be thought of as a lazy version of RotMatrix{2}.","category":"page"},{"location":"2d_angle/","page":"Angle","title":"Angle","text":"using Rotations","category":"page"},{"location":"2d_angle/#Angle2d","page":"Angle","title":"Angle2d","text":"","category":"section"},{"location":"2d_angle/","page":"Angle","title":"Angle","text":"example","category":"page"},{"location":"2d_angle/","page":"Angle","title":"Angle","text":"t = 1.2 # rotation angle\nm = [cos(t) -sin(t);sin(t) cos(t)]\nAngle2d(t) # construct from matrix\nRotMatrix{2}(t)\ndump(Angle2d(t))\ndump(RotMatrix{2}(t))","category":"page"},{"location":"2d_matrix/#2D-Rotation-Matrix","page":"Matrix","title":"2D Rotation Matrix","text":"","category":"section"},{"location":"2d_matrix/","page":"Matrix","title":"Matrix","text":"An 2 times 2 rotation matrix storing the rotation. This is a simple wrapper for a StaticArrays SMatrix{2,2,T}. A rotation matrix R should have the property I = R R^top, but this isn't enforced by the constructor. On the other hand, all the types below are guaranteed to be \"proper\" rotations for all input parameters (equivalently: parity conserving, in SO(2), det(R) = 1, or a rotation without reflection).","category":"page"},{"location":"2d_matrix/","page":"Matrix","title":"Matrix","text":"using Rotations","category":"page"},{"location":"2d_matrix/#RotMatrix2","page":"Matrix","title":"RotMatrix2","text":"","category":"section"},{"location":"2d_matrix/","page":"Matrix","title":"Matrix","text":"example","category":"page"},{"location":"2d_matrix/","page":"Matrix","title":"Matrix","text":"t = 1.2 # rotation angle\nm = [cos(t) -sin(t);sin(t) cos(t)]\nRotMatrix{2}(m) # construct from matrix\nRotMatrix{2}(t) # construct from angle","category":"page"},{"location":"2d_rotation_generator/#2D-Rotation-Generator","page":"2D Rotation Generators","title":"2D Rotation Generator","text":"","category":"section"},{"location":"2d_rotation_generator/","page":"2D Rotation Generators","title":"2D Rotation Generators","text":"using Rotations","category":"page"},{"location":"2d_rotation_generator/#RotMatrixGenerator2","page":"2D Rotation Generators","title":"RotMatrixGenerator2","text":"","category":"section"},{"location":"2d_rotation_generator/","page":"2D Rotation Generators","title":"2D Rotation Generators","text":"example","category":"page"},{"location":"2d_rotation_generator/","page":"2D Rotation Generators","title":"2D Rotation Generators","text":"m = rand(2,2)\ns = RotMatrixGenerator{2}(m - m')\nexp(s)\nlog(exp(s))","category":"page"},{"location":"2d_rotation_generator/#Angle2dGenerator","page":"2D Rotation Generators","title":"Angle2dGenerator","text":"","category":"section"},{"location":"2d_rotation_generator/","page":"2D Rotation Generators","title":"2D Rotation Generators","text":"example","category":"page"},{"location":"2d_rotation_generator/","page":"2D Rotation Generators","title":"2D Rotation Generators","text":"s = Angle2dGenerator(0.42)\nexp(s)\nlog(exp(s))\nrotation_angle(exp(s))\nrotation_angle(exp(2s))\nrotation_angle(exp(2s)) / rotation_angle(exp(s))","category":"page"},{"location":"reference/#Reference-for-rotations","page":"References","title":"Reference for rotations","text":"","category":"section"},{"location":"reference/#Published-articles","page":"References","title":"Published articles","text":"","category":"section"},{"location":"reference/","page":"References","title":"References","text":"\"Fundamentals of Spacecraft Attitude Determination and Control\" by Markley and Crassidis\nSee sections 2.1-2.9 for 3d rotation parametrization.\nSee sections 3.1-3.2 for kinematics.\n\"Derivation of the Euler-Rodrigues formula for three-dimensional rotations from the general formula for four-dimensional rotations\" by Johan Ernest Mebius\nThe conversion RotMatrix{3} to QuatRotaiton is based on this paper.\n\"Computing Exponentials of Skew Symmetric Matrices And Logarithms of Orthogonal Matrices\" by Jean Gallier and Dianna Xu\nSee this article for log and exp of rotation matrices in higher dimensions.","category":"page"},{"location":"reference/#Wikipedia-articles","page":"References","title":"Wikipedia articles","text":"","category":"section"},{"location":"reference/","page":"References","title":"References","text":"Rotation matrix\nQuaternion\nWahba's problem\nWahba's problem is related to the nearest_rotation function.\nPolar decomposition\nPolar decomposition is also related to the nearest_rotation function.","category":"page"},{"location":"reference/#Others","page":"References","title":"Others","text":"","category":"section"},{"location":"reference/","page":"References","title":"References","text":"\"Quaternions and 3d rotation, explained interactively\" by 3Blue1Brown\n\"Visualizing quaternions (4d numbers) with stereographic projection\" by 3Blue1Brown","category":"page"},{"location":"3d_quaternion/#3D-Rotation-with-Quaternion-and-Related-Parameters","page":"Quaternion and Related Parameters","title":"3D Rotation with Quaternion and Related Parameters","text":"","category":"section"},{"location":"3d_quaternion/","page":"Quaternion and Related Parameters","title":"Quaternion and Related Parameters","text":"using Rotations","category":"page"},{"location":"3d_quaternion/#QuatRotation","page":"Quaternion and Related Parameters","title":"QuatRotation","text":"","category":"section"},{"location":"3d_quaternion/","page":"Quaternion and Related Parameters","title":"Quaternion and Related Parameters","text":"A 3D rotation parameterized by a unit quaternion (versor). Note that the constructor will renormalize the quaternion to be a unit quaternion, and that although they follow the same multiplicative algebra as quaternions, it is better to think of QuatRotation as a 3 times 3 matrix rather than as a quaternion number.","category":"page"},{"location":"3d_quaternion/","page":"Quaternion and Related Parameters","title":"Quaternion and Related Parameters","text":"beginaligned\n leftw_mathrmQ + ix_mathrmQ + jy_mathrmQ + kz_mathrmQ in mathbbH x_mathrmQ y_mathrmQ z_mathrmQ in mathbbR right\n simeq S^3\nendaligned","category":"page"},{"location":"3d_quaternion/","page":"Quaternion and Related Parameters","title":"Quaternion and Related Parameters","text":"example","category":"page"},{"location":"3d_quaternion/","page":"Quaternion and Related Parameters","title":"Quaternion and Related Parameters","text":"one(QuatRotation) # identity rotation\nα, β, γ = 1.2, -0.8, 0.1;\nRotX(α) ≈ QuatRotation(cos(α/2),sin(α/2),0,0) # These matrices are equal\nRotY(β) ≈ QuatRotation(cos(β/2),0,sin(β/2),0) # These matrices are equal\nRotZ(γ) ≈ QuatRotation(cos(γ/2),0,0,sin(γ/2)) # These matrices are equal","category":"page"},{"location":"3d_quaternion/","page":"Quaternion and Related Parameters","title":"Quaternion and Related Parameters","text":"See also Quaternions.jl documentation.","category":"page"},{"location":"3d_quaternion/#RodriguesParam","page":"Quaternion and Related Parameters","title":"RodriguesParam","text":"","category":"section"},{"location":"3d_quaternion/","page":"Quaternion and Related Parameters","title":"Quaternion and Related Parameters","text":"A 3-parameter representation of 3D rotations that has a singularity at 180^circ. They can be interpreted as a projection of the unit quaternion onto the plane tangent to the quaternion identity. They are computationally efficient and do not have a sign ambiguity of unit quaternion.","category":"page"},{"location":"3d_quaternion/","page":"Quaternion and Related Parameters","title":"Quaternion and Related Parameters","text":"left\nbeginaligned\n beginaligned\n x_mathrmR = x_mathrmQw_mathrmQ \n y_mathrmR = y_mathrmQw_mathrmQ \n z_mathrmR = z_mathrmQw_mathrmQ\n endaligned\nendaligned\nright","category":"page"},{"location":"3d_quaternion/","page":"Quaternion and Related Parameters","title":"Quaternion and Related Parameters","text":"example","category":"page"},{"location":"3d_quaternion/","page":"Quaternion and Related Parameters","title":"Quaternion and Related Parameters","text":"one(RodriguesParam) # identity rotation\nα, β, γ = 1.2, -0.8, 0.1;\nRotX(α) ≈ RodriguesParam(tan(α/2),0,0) # These matrices are equal\nRotY(β) ≈ RodriguesParam(0,tan(β/2),0) # These matrices are equal\nRotZ(γ) ≈ RodriguesParam(0,0,tan(γ/2)) # These matrices are equal","category":"page"},{"location":"3d_quaternion/#MRP-(Modified-Rodrigues-Parameters)","page":"Quaternion and Related Parameters","title":"MRP (Modified Rodrigues Parameters)","text":"","category":"section"},{"location":"3d_quaternion/","page":"Quaternion and Related Parameters","title":"Quaternion and Related Parameters","text":"A 3D rotation encoded by the stereographic projection of a unit quaternion. This projection can be visualized as a pin hole camera, with the pin hole matching the quaternion -1+0i+0j+0k and the image plane containing the origin and having normal direction 1+0i+0j+0k. The \"identity rotation\" Quaternion(1.0,0,0,0) then maps to the MRP(0,0,0)","category":"page"},{"location":"3d_quaternion/","page":"Quaternion and Related Parameters","title":"Quaternion and Related Parameters","text":"These are similar to the Rodrigues vector in that the axis direction is stored in an unnormalized form, and the rotation angle is encoded in the length of the axis. This type has the nice property that the derivatives of the rotation matrix w.r.t. the MRP parameters are rational functions, making the MRP type a good choice for differentiation / optimization.","category":"page"},{"location":"3d_quaternion/","page":"Quaternion and Related Parameters","title":"Quaternion and Related Parameters","text":"They are frequently used in aerospace applications since they are a 3-parameter representation whose singularity happens at 360^circ. In practice, the singularity can be avoided with some switching logic between one of two equivalent MRPs (obtained by projecting the negated quaternion).","category":"page"},{"location":"3d_quaternion/","page":"Quaternion and Related Parameters","title":"Quaternion and Related Parameters","text":"left\nbeginaligned\n beginaligned\n x_mathrmM = dfracx_mathrmQw_mathrmQ-1 \n y_mathrmM = dfracy_mathrmQw_mathrmQ-1 \n z_mathrmM = dfracz_mathrmQw_mathrmQ-1\n endaligned\nendaligned\nright","category":"page"},{"location":"3d_quaternion/","page":"Quaternion and Related Parameters","title":"Quaternion and Related Parameters","text":"example","category":"page"},{"location":"3d_quaternion/","page":"Quaternion and Related Parameters","title":"Quaternion and Related Parameters","text":"one(MRP) # identity rotation\nα, β, γ = 1.2, -0.8, 0.1;\nRotX(α) ≈ MRP(sin(α/2)/(cos(α/2)-1),0,0) # These matrices are equal\nRotY(β) ≈ MRP(0,sin(β/2)/(cos(β/2)-1),0) # These matrices are equal\nRotZ(γ) ≈ MRP(0,0,sin(γ/2)/(cos(γ/2)-1)) # These matrices are equal","category":"page"},{"location":"3d_matrix/#3D-Rotation-Matrix","page":"Matrix","title":"3D Rotation Matrix","text":"","category":"section"},{"location":"3d_matrix/","page":"Matrix","title":"Matrix","text":"An 3 times 3 rotation matrix storing the rotation. This is a simple wrapper for a StaticArrays SMatrix{3,3,T}. A rotation matrix R should have the property I = R R^top, but this isn't enforced by the constructor. On the other hand, all the types below are guaranteed to be \"proper\" rotations for all input parameters (equivalently: parity conserving, in SO(3), det(R) = 1, or a rotation without reflection).","category":"page"},{"location":"3d_matrix/","page":"Matrix","title":"Matrix","text":"using Rotations","category":"page"},{"location":"3d_matrix/#RotMatrix3","page":"Matrix","title":"RotMatrix3","text":"","category":"section"},{"location":"3d_matrix/","page":"Matrix","title":"Matrix","text":"example","category":"page"},{"location":"3d_matrix/","page":"Matrix","title":"Matrix","text":"t = 1.2\nm1 = [cos(t) -sin(t) 0;sin(t) cos(t) 0;0 0 1]\nRotMatrix{3}(m1) # construct from matrix\nm2 = RotZ(t) # Other rotation type\nRotMatrix{3}(m2) # convert m2 to RotMatrix\nRotMatrix(m2) # Type parameter can be omitted.","category":"page"},{"location":"3d_angleaxis/#3D-Rotation-around-an-axis","page":"Angle and Axis","title":"3D Rotation around an axis","text":"","category":"section"},{"location":"3d_angleaxis/","page":"Angle and Axis","title":"Angle and Axis","text":"In Rotations.jl, there are two concrete types to represent a rotation with given an axis and an angle.","category":"page"},{"location":"3d_angleaxis/","page":"Angle and Axis","title":"Angle and Axis","text":"AngleAxis\nRotationVec","category":"page"},{"location":"3d_angleaxis/#AngleAxis","page":"Angle and Axis","title":"AngleAxis","text":"","category":"section"},{"location":"3d_angleaxis/","page":"Angle and Axis","title":"Angle and Axis","text":"A 3D rotation with fields theta, axis_x, axis_y, and axis_z to store the rotation angle and axis of the rotation. Like all other types in this package, once it is constructed it acts and behaves as a 3×3 AbstractMatrix. The axis will be automatically renormalized by the constructor to be a unit vector, so that theta always represents the rotation angle in radians.","category":"page"},{"location":"3d_angleaxis/","page":"Angle and Axis","title":"Angle and Axis","text":"beginaligned\nR_bmn (theta)\n= exp(theta K(bmn)) \n= I + (sintheta) K(bmn) + (1-costheta) K^2(bmn) \n= beginpmatrix\ncostheta + n_x^2 (1-costheta) n_xn_y (1-costheta) - n_z sintheta n_zn_x (1-costheta) + n_y sintheta \nn_xn_y (1-costheta) + n_z sintheta costheta + n_y^2 (1-costheta) n_yn_z (1-costheta) - n_x sintheta \nn_zn_x (1-costheta) - n_y sintheta n_yn_z (1-costheta) + n_x sintheta costheta + n_z^2 (1-costheta)\nendpmatrix \n\nK(bmn)\n= beginpmatrix\n0 -n_z n_y \nn_z 0 -n_x \n-n_y n_x 0\nendpmatrix \n\nbmn\n= beginpmatrix\nn_x \nn_y \nn_z\nendpmatrix\n\nquad left(bmn= 1right)\nendaligned","category":"page"},{"location":"3d_angleaxis/","page":"Angle and Axis","title":"Angle and Axis","text":"example","category":"page"},{"location":"3d_angleaxis/","page":"Angle and Axis","title":"Angle and Axis","text":"using Rotations, LinearAlgebra\n# 1/3 (120°) rotation around the (1/√3, 1/√3, 1/√3) vector\nR = AngleAxis(2π/3, 1/√3, 1/√3, 1/√3)\n# This matrix swaps the xyz coordinates\nR * [1,2,3]\nR^2\nR^3\n# These matrices are approximately equal\nR^3 ≈ I(3)","category":"page"},{"location":"3d_angleaxis/#RotationVec","page":"Angle and Axis","title":"RotationVec","text":"","category":"section"},{"location":"3d_angleaxis/","page":"Angle and Axis","title":"Angle and Axis","text":"A 3D rotation encoded by an angle-axis representation as angle * axis. This type is used in packages such as OpenCV.","category":"page"},{"location":"3d_angleaxis/","page":"Angle and Axis","title":"Angle and Axis","text":"beginaligned\nR(bmv)\n= R_bmn (theta) left(bmn = fracbmvbmv theta = bmv right)\nendaligned","category":"page"},{"location":"3d_angleaxis/","page":"Angle and Axis","title":"Angle and Axis","text":"note: Differentiation\nIf you're differentiating a Rodrigues Vector check the result is what you expect at theta = 0. The first derivative of the rotation should behave, but higher-order derivatives of it (as well as parameterization conversions) should be tested. The Stereographic Quaternion Projection (MRP) is the recommended three parameter format for differentiation.","category":"page"},{"location":"3d_angleaxis/","page":"Angle and Axis","title":"Angle and Axis","text":"example","category":"page"},{"location":"3d_angleaxis/","page":"Angle and Axis","title":"Angle and Axis","text":"using Rotations, LinearAlgebra\n# 1/3 (120°) rotation around the (1/√3, 1/√3, 1/√3) vector\nR = RotationVec(2π/3(√3), 2π/3(√3), 2π/3(√3))\n# This matrix swaps the xyz coordinates\nR * [1,2,3]\nR^2\nR^3\n# These matrices are approximately equal\nR^3 ≈ I(3)\n\nα, β, γ = 1.2, -0.8, 0.1;\nRotX(α) ≈ RotationVec(α,0,0) # These matrices are equal\nRotY(β) ≈ RotationVec(0,β,0) # These matrices are equal\nRotZ(γ) ≈ RotationVec(0,0,γ) # These matrices are equal","category":"page"},{"location":"rotation_types/#Rotation-Types","page":"Rotation Types","title":"Rotation Types","text":"","category":"section"},{"location":"rotation_types/#Abstract-rotations","page":"Rotation Types","title":"Abstract rotations","text":"","category":"section"},{"location":"rotation_types/","page":"Rotation Types","title":"Rotation Types","text":"A matrix R is called rotation matrix if R satisfies","category":"page"},{"location":"rotation_types/","page":"Rotation Types","title":"Rotation Types","text":"beginaligned\nR^top = R^-1 det(R)=1\nendaligned","category":"page"},{"location":"rotation_types/","page":"Rotation Types","title":"Rotation Types","text":"In Rotations.jl, there's an abstract type for rotations matrix, Rotation{L}. Where L is a size of the rotation matrix.","category":"page"},{"location":"rotation_types/#Type-hierarchy","page":"Rotation Types","title":"Type hierarchy","text":"","category":"section"},{"location":"rotation_types/","page":"Rotation Types","title":"Rotation Types","text":"using InteractiveUtils","category":"page"},{"location":"rotation_types/","page":"Rotation Types","title":"Rotation Types","text":"using Rotations, StaticArrays\nRotation <: StaticMatrix <: AbstractMatrix\nsubtypes(Rotation{2})\nsubtypes(Rotation{3})","category":"page"},{"location":"rotation_types/#Overview-of-each-type","page":"Rotation Types","title":"Overview of each type","text":"","category":"section"},{"location":"rotation_types/","page":"Rotation Types","title":"Rotation Types","text":"For more information, see the sidebar page.","category":"page"},{"location":"rotation_types/#2D-rotations","page":"Rotation Types","title":"2D rotations","text":"","category":"section"},{"location":"rotation_types/","page":"Rotation Types","title":"Rotation Types","text":"RotMatrix2{T}\nRotation matrix in 2 dimensional Euclidean space.\nAngle2d\nParametrized with rotational angle.","category":"page"},{"location":"rotation_types/#3D-rotations","page":"Rotation Types","title":"3D rotations","text":"","category":"section"},{"location":"rotation_types/","page":"Rotation Types","title":"Rotation Types","text":"RotMatrix3{T}\nRotation matrix in 3 dimensional Euclidean space.\nRotX, RotYZ, RotXYZ and etc.\nEuler angles.\nAngleAxis\nRotation around given axis and angle.\nRotationVec\nRotation around given axis. The length of axis vector represents its angle.\nQuatRotation\nA 3D rotation parameterized by a unit quaternion.\nMRP\nA 3D rotation encoded by the stereographic projection of a unit quaternion.","category":"page"},{"location":"rotation_generator_types/#Rotation-Generator-Types","page":"Rotation Generator Types","title":"Rotation Generator Types","text":"","category":"section"},{"location":"rotation_generator_types/#Abstract-rotation-generators","page":"Rotation Generator Types","title":"Abstract rotation generators","text":"","category":"section"},{"location":"rotation_generator_types/","page":"Rotation Generator Types","title":"Rotation Generator Types","text":"A matrix R is called skew-symmetric matrix if R satisfies","category":"page"},{"location":"rotation_generator_types/","page":"Rotation Generator Types","title":"Rotation Generator Types","text":"beginaligned\nR^top = -R\nendaligned","category":"page"},{"location":"rotation_generator_types/","page":"Rotation Generator Types","title":"Rotation Generator Types","text":"In Rotations.jl, there's an abstract type for skew-symmetric matrix, RotationGenerator{L}. Where L is a size of the skew-symmetric matrix.","category":"page"},{"location":"rotation_generator_types/#Type-hierarchy","page":"Rotation Generator Types","title":"Type hierarchy","text":"","category":"section"},{"location":"rotation_generator_types/","page":"Rotation Generator Types","title":"Rotation Generator Types","text":"using InteractiveUtils","category":"page"},{"location":"rotation_generator_types/","page":"Rotation Generator Types","title":"Rotation Generator Types","text":"using Rotations, StaticArrays\nRotationGenerator <: StaticMatrix <: AbstractMatrix\nsubtypes(RotationGenerator{2})\nsubtypes(RotationGenerator{3})","category":"page"},{"location":"rotation_generator_types/#Overview-of-each-type","page":"Rotation Generator Types","title":"Overview of each type","text":"","category":"section"},{"location":"rotation_generator_types/","page":"Rotation Generator Types","title":"Rotation Generator Types","text":"For more information, see the sidebar page.","category":"page"},{"location":"rotation_generator_types/#2D-rotations","page":"Rotation Generator Types","title":"2D rotations","text":"","category":"section"},{"location":"rotation_generator_types/","page":"Rotation Generator Types","title":"Rotation Generator Types","text":"RotMatrixGenerator2{T}\nSkew symmetric matrix in 2 dimensional Euclidean space.\nAngle2dGenerator\nParametrized with one real number like Angle2d.","category":"page"},{"location":"rotation_generator_types/#3D-rotations","page":"Rotation Generator Types","title":"3D rotations","text":"","category":"section"},{"location":"rotation_generator_types/","page":"Rotation Generator Types","title":"Rotation Generator Types","text":"RotMatrixGenerator3{T}\nSkew symmetric matrix in 3 dimensional Euclidean space.\nRotationVecGenerator\nRotation generator around given axis. The length of axis vector represents its angle.","category":"page"},{"location":"#Rotations","page":"Home","title":"Rotations","text":"","category":"section"},{"location":"","page":"Home","title":"Home","text":"3D rotations made easy in Julia","category":"page"},{"location":"","page":"Home","title":"Home","text":"note: Documentation\nThe documentation is still work in progress. For more information, see alsoREADME in the repository\nTests in the repository(TBW) comments are left in areas that have not yet been documented. Feel free to open pull requests and improve this document!","category":"page"},{"location":"#Installation","page":"Home","title":"Installation","text":"","category":"section"},{"location":"","page":"Home","title":"Home","text":"pkg> add Rotations","category":"page"},{"location":"#First-example","page":"Home","title":"First example","text":"","category":"section"},{"location":"","page":"Home","title":"Home","text":"using Rotations\n\n# 3D Rotation by Euler Angles\nR_euler = RotXYZ(1,2,3)\n\n# Get an angle and an axis of the rotation\nrotation_angle(R_euler), rotation_axis(R_euler)\n\n# Convert the rotation to unit quaternion\nR_quat = QuatRotation(R_euler)\n\n# Get quaternion parameters of the rotation\nRotations.params(R_quat)\n\n# Convert the rotation to MRP (Modified Rodrigues Parameters)\nR_mrp = MRP(R_euler)\nRotations.params(R_mrp)\n\n# Get parameters of the MRP\nRotations.params(R_mrp)\n\n# Also supports 2D rotation\nR_2d = Angle2d(π/6)\n\n# Also supports some differentiation\nRotations.jacobian(RotMatrix, R_quat)","category":"page"},{"location":"general_dimensional_rotations/#General-dimensional-Rotation","page":"General Dimensional Rotations","title":"General dimensional Rotation","text":"","category":"section"},{"location":"general_dimensional_rotations/","page":"General Dimensional Rotations","title":"General Dimensional Rotations","text":"Our main goal is to efficiently represent rotations in lower dimensions, such as 2D and 3D, but some operations on rotations in general dimensions are also supported.","category":"page"},{"location":"general_dimensional_rotations/","page":"General Dimensional Rotations","title":"General Dimensional Rotations","text":"using Rotations\nusing StaticArrays","category":"page"},{"location":"general_dimensional_rotations/","page":"General Dimensional Rotations","title":"General Dimensional Rotations","text":"example","category":"page"},{"location":"general_dimensional_rotations/","page":"General Dimensional Rotations","title":"General Dimensional Rotations","text":"r1 = one(RotMatrix{4}) # generate identity rotation matrix\nm = @SMatrix rand(4,4)\nr2 = nearest_rotation(m) # nearest rotation matrix from given matrix\nr3 = rand(RotMatrix{4}) # random rotation in SO(4)\nr1*r2/r3 # multiplication and division\ns = log(r2) # logarithm of RotMatrix is a RotMatrixGenerator\nexp(s) # exponential of RotMatrixGenerator is a RotMatrix","category":"page"}] } diff --git a/dev/visualizing/index.html b/dev/visualizing/index.html index 2b6d690..543cbb0 100644 --- a/dev/visualizing/index.html +++ b/dev/visualizing/index.html @@ -1,2 +1,2 @@ -Visualizing Rotations · Rotations.jl

Visualizing Rotation

In general, $3 \times 3$ matrix has $9$ parameters, so it's hard to visualize a matrix as a point. However, the Lie group $SO(3)$ and $SU(2)$ are $3$-dimensional space, and it is able to visualize its element as a point in our $3$-dimensional space.

using MRP

(TBW)

using RodriguesParam

(TBW)

using RotationVec

(TBW)

+Visualizing Rotations · Rotations.jl

Visualizing Rotation

In general, $3 \times 3$ matrix has $9$ parameters, so it's hard to visualize a matrix as a point. However, the Lie group $SO(3)$ and $SU(2)$ are $3$-dimensional space, and it is able to visualize its element as a point in our $3$-dimensional space.

using MRP

(TBW)

using RodriguesParam

(TBW)

using RotationVec

(TBW)