cisst-saw
Loading...
Searching...
No Matches
msh3Utilities.h
Go to the documentation of this file.
1/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2/* ex: set filetype=cpp softtabstop=4 shiftwidth=4 tabstop=4 cindent expandtab: */
3// ****************************************************************************
4//
5// Copyright (c) 2014, Seth Billings, Russell Taylor, Johns Hopkins University
6// All rights reserved.
7//
8// Redistribution and use in source and binary forms, with or without
9// modification, are permitted provided that the following conditions are
10// met:
11//
12// 1. Redistributions of source code must retain the above copyright
13// notice, this list of conditions and the following disclaimer.
14//
15// 2. Redistributions in binary form must reproduce the above copyright
16// notice, this list of conditions and the following disclaimer in the
17// documentation and/or other materials provided with the distribution.
18//
19// 3. Neither the name of the copyright holder nor the names of its
20// contributors may be used to endorse or promote products derived from
21// this software without specific prior written permission.
22//
23// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
24// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
25// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
26// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
27// HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
28// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
29// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
30// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
31// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
32// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
33// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34//
35// ****************************************************************************
36
37#ifndef _msh3Utilities_h
38#define _msh3Utilities_h
39
40#include <string>
41#include <regex>
42
47
48// get current working directory
49std::string getcwd_str();
50
51// compute a noise covariance matrix having different noise
52// magnitude parallel vs. perpendicular to a given point
53// normal orientation
54vct3x3 ComputePointCovariance( const vct3 &norm, double normPerpVar, double normPrllVar);
55
56// Decompositions for covariance matrices
57
58// eigen values in descending order
59void ComputeCovEigenValues_SVD(const vct3x3 &M, vct3 &eigenValues);
60// eigen values in descending order
61void ComputeCovEigenValues_Trig(const vct3x3 &M, vct3 &eigenValues);
62
63// eigen values in descending order
64// eigen vectors listed by column and has determinant = 1 (i.e. a rotation matrix)
65void ComputeCovEigenDecomposition_NonIter(const vct3x3 &M, vct3 &eigenValues, vct3x3 &eigenVectors);
66
67// eigen values in descending order
68// eigen vectors listed by column
69void ComputeCovEigenDecomposition_SVD(const vct3x3 &M, vct3 &eigenValues, vct3x3 &eigenVectors);
70
71// This method is much less efficient than the SVD method
72// eigen values in descending order
73// eigen vectors listed by column
74void ComputeCovEigenDecomposition_SEP(const vct3x3 &M, vct3 &eigenValues, vct3x3 &eigenVectors);
75
77
78void ComputeCovInverse_SVD(const vct3x3 &M, vct3x3 &Minv);
79
80// this is method is 20% slower than the non-iterative method
81// using eigen decomposition, but much faster than the SVD method
82void ComputeCovInverse_Nmr(const vct3x3 &M, vct3x3 &Minv);
83
84//--- Inline Functions ---//
85//
86// must be fully defined in header file
87//
88
89// efficient calculation for symmetric form R*M*Rt
90// where M is a symmetric covariance matrix and
91// R is an orthogonal matrix.
92// Note: using this form is only slightly more efficient
93// than calling R*M*R.Transpose.
94// Time comparison for 100 trials:
95// time: 0.000241665
96// time: 0.000265216
98{
99 static vct3x3 RMRt, MRt;
100 MRt.ProductOf(M, R.Transpose());
101 RMRt.Element(0, 0) = vctDotProduct(R.Row(0), MRt.Column(0));
102 RMRt.Element(0, 1) = vctDotProduct(R.Row(0), MRt.Column(1));
103 RMRt.Element(1, 0) = RMRt.Element(0, 1);
104 RMRt.Element(0, 2) = vctDotProduct(R.Row(0), MRt.Column(2));
105 RMRt.Element(2, 0) = RMRt.Element(0, 2);
106 RMRt.Element(1, 1) = vctDotProduct(R.Row(1), MRt.Column(1));
107 RMRt.Element(1, 2) = vctDotProduct(R.Row(1), MRt.Column(2));
108 RMRt.Element(2, 1) = RMRt.Element(1, 2);
109 RMRt.Element(2, 2) = vctDotProduct(R.Row(2), MRt.Column(2));
110 return RMRt;
111}
112
113
114// Compute rodrigues vector of rotation between two vectors, using an efficient
115// approximation in case of small offset angles
116inline vct3 ApproxRodriguesRotationBetweenUnitVectors(double DotProd, const vct3 &XProd)
117{
118 // Computing magnitude if the angle (alpha) between two vectors
119 // |XProd| = sin(alpha)
120 // DotProd = cos(alpha)
121 //
122 // rodriguez vector = XProd.Normalized()*alpha
123 // ~ cannot apply this equation indiscriminantly, however, since the
124 // norm of XProd blows up for approximately parrallel vectors
125 //
126 // alpha ~= sin(alpha) for alpha up to 30deg (at 30deg error is approx 5%)
127 // => for alpha <= 30*pi/180, |Xprod| may be used for angle magnitude
128 // and rodriguez vector is simply = XProd vector.
129 // Otherwise, acos(DotProd) should be used for alpha. It is important
130 // to use acos(DotProd) rather than asin(|XProd|) because asin(alpha)
131 // cannot discrimiate between "alpha" and "180deg-alpha", i.e. it cannot
132 // discriminate vectors greater and smaller than 90 degrees, whereas
133 // acos(DotProd) can. range of asin(|XProd|) = (-90deg,+90deg)
134 // range of acos(DotProd) = (0deg,+180deg)
135 //
136 // In any event, XProd should never be used for the rodriguez vector when
137 // the angle between vectors is more than 90deg, as this will produce
138 // a rodriguez vector for an angle less than 90deg.
139 //
140 // Note: For alpha = 30deg, DotProd = cos(alpha*pi/180) = 0.8660
141 //
142 if (DotProd >= 0.8660) {
143 // small angle approximation alpha ~= sin(alpha)
144 return XProd;
145 }
146 else {
147 // large angle calculation (XProd.Normalized() won't blow up)
148 return XProd.Normalized()*acos(DotProd);
149 }
150}
151
152// Compute rodrigues vector of rotation between two vectors
153inline vct3 RodriguesRotationBetweenUnitVectors(double DotProd, const vct3 &XProd)
154{
155 // Computing magnitude if the angle (alpha) between two vectors
156 //
157 // At alpha = 5deg; error in alpha ~= sin(alpha) approx is about 0.1%
158 //
159 // Note: For alpha = 5deg, DotProd = cos(alpha*pi/180) = 0.9962
160 //
161 if (DotProd >= 0.9962) {
162 // small angle approximation alpha ~= sin(alpha)
163 return XProd;
164 }
165 else {
166 // large angle calculation (XProd.Normalized() won't blow up)
167 return XProd.Normalized()*acos(DotProd);
168 }
169}
170
171// compute the Jacobian matrices of rotation wrt each element of a Rodrigues vector
172// a ~ Rodrigues rotation vector
173// dRa ~ Jacobian of R(a) wrt ax,ay,az
175
176// Converts from yaw/pitch/roll euler angles (azimuth/elevation/roll) to rotation matrix
177// assumes euler angles with local frame-of-reference
178// assumes angles given in degrees
179vctRot3 euler2rot(double yaw, double pitch, double roll);
180
181inline vct3x3 skew(const vct3 &v)
182{
183 return vct3x3(
184 0.0, -v[2], v[1],
185 v[2], 0.0, -v[0],
186 -v[1], v[0], 0.0
187 );
188}
189inline void skew(const vct3 &v, vct3x3 &sk)
190{
191 sk.Assign(
192 0.0, -v[2], v[1],
193 v[2], 0.0, -v[0],
194 -v[1], v[0], 0.0
195 );
196}
197inline void skew(const vct3 &v, vctDynamicMatrixRef<double> &sk)
198{
199 assert(sk.rows() == 3 && sk.cols() == 3);
200 sk.Assign(
201 0.0, -v[2], v[1],
202 v[2], 0.0, -v[0],
203 -v[1], v[0], 0.0
204 );
205}
206
207inline size_t sub2ind(const vctFixedSizeVector<size_t, 3> & size, const size_t i, const size_t j, const size_t k)
208{
209 return i + size(0) * j + size(0) * size(1) * k;
210}
211
212inline double round6(double d){
213 return std::round(d*1E6)/1E6;
214}
215
216inline double round3(double d){
217 return std::round(d*1E3)/1E3;
218}
219
220inline std::string ltrim(const std::string& s) {
221 return std::regex_replace(s, std::regex("^\\s+"), std::string(""));
222}
223
224inline std::string rtrim(const std::string& s) {
225 return std::regex_replace(s, std::regex("\\s+$"), std::string(""));
226}
227
228inline std::string trim(const std::string& s) {
229 return ltrim(rtrim(s));
230}
231
232// Compute the centroid for a set of vetors
234
235// Compute the weighted centroid for a set of vectors
237
238// linspacee
239vctDoubleVec linspace(const double &min, const double &max, const int &n);
240
242
243const double m_to_mm=1000.0;
244
245#endif // _msh3Utilities_h
ThisType & Assign(const vctDynamicConstMatrixBase< __matrixOwnerType, value_type > &other)
Definition vctDynamicMatrixBase.h:509
Dynamic matrix referencing existing memory.
Definition vctDynamicMatrixRef.h:75
Definition vctForwardDeclarations.h:131
TransposeValueType Transpose() const
Definition vctFixedSizeConstMatrixBase.h:1060
ColumnRefType Column(size_type index)
Definition vctFixedSizeMatrixBase.h:249
RowRefType Row(size_type index)
Definition vctFixedSizeMatrixBase.h:244
ThisType & ProductOf(const vctFixedSizeConstMatrixBase< _rows, _cols, __rowStride, __colStride, value_type, __dataPtrType > &matrix, const value_type scalar)
Definition vctFixedSizeMatrixBase.h:909
reference Element(size_type rowIndex, size_type colIndex)
Definition vctFixedSizeMatrixBase.h:231
ThisType & Assign(const vctFixedSizeConstMatrixBase< _rows, _cols, __rowStride, __colStride, __elementType, __dataPtrType > &other)
Definition vctFixedSizeMatrixBase.h:475
Implementation of a fixed-size vector using template metaprogramming.
Definition vctFixedSizeVector.h:54
void CISST_EXPORT ComputeCovEigenDecomposition_SVD(const vct2x2 &C, vct2 &eigVal, vct2x2 &eigVct)
vctRot3 euler2rot(double yaw, double pitch, double roll)
std::string trim(const std::string &s)
Definition msh3Utilities.h:228
vct3 vctCentroid(const vctDynamicVector< vct3 > &A)
vct3x3 skew(const vct3 &v)
Definition msh3Utilities.h:181
const double m_to_mm
Definition msh3Utilities.h:243
std::string ltrim(const std::string &s)
Definition msh3Utilities.h:220
double round3(double d)
Definition msh3Utilities.h:216
void ComputeCovInverse_SVD(const vct3x3 &M, vct3x3 &Minv)
void ComputeRodriguesJacobians(const vct3 &a, vctFixedSizeVector< vctRot3, 3 > &dRa)
void ComputeCovEigenValues_Trig(const vct3x3 &M, vct3 &eigenValues)
void ComputeCovEigenDecomposition_NonIter(const vct3x3 &M, vct3 &eigenValues, vct3x3 &eigenVectors)
vct3 ApproxRodriguesRotationBetweenUnitVectors(double DotProd, const vct3 &XProd)
Definition msh3Utilities.h:116
vct3 RodriguesRotationBetweenUnitVectors(double DotProd, const vct3 &XProd)
Definition msh3Utilities.h:153
void ComputeCovEigenValues_SVD(const vct3x3 &M, vct3 &eigenValues)
std::string rtrim(const std::string &s)
Definition msh3Utilities.h:224
vct3x3 ComputePointCovariance(const vct3 &norm, double normPerpVar, double normPrllVar)
std::string getcwd_str()
void ComputeCovInverse_Nmr(const vct3x3 &M, vct3x3 &Minv)
void ComputeCovEigenDecomposition_SEP(const vct3x3 &M, vct3 &eigenValues, vct3x3 &eigenVectors)
vct3 vctWeightedMean(const vctDynamicVector< vct3 > &A, const vctDoubleVec &W)
size_t sub2ind(const vctFixedSizeVector< size_t, 3 > &size, const size_t i, const size_t j, const size_t k)
Definition msh3Utilities.h:207
double round6(double d)
Definition msh3Utilities.h:212
vct3x3 & Calc_RMRt(vct3x3 &R, vct3x3 &M)
Definition msh3Utilities.h:97
vctDoubleVec linspace(const double &min, const double &max, const int &n)
void ComputeCovInverse_NonIter(const vct3x3 &M, vct3x3 &Minv)
vctDoubleVec ComputeInverseTrilinearInterp(const vct3 &p, const vctDynamicVector< vct3 > &points)
size_type size(void) const
Definition vctDynamicConstMatrixBase.h:228
const value_type & W(void) const
Definition vctDynamicConstVectorBase.h:286
_elementType vctDotProduct(const vctDynamicConstVectorBase< _vector1OwnerType, _elementType > &vector1, const vctDynamicConstVectorBase< _vector2OwnerType, _elementType > &vector2)
Definition vctDynamicConstVectorBase.h:1087
Typedef for dynamic vectors.
vctDynamicVector< double > vctDoubleVec
Definition vctDynamicVectorTypes.h:37
Typedef for fixed size matrices.
vctFixedSizeMatrix< double, 3, 3 > vct3x3
Definition vctFixedSizeMatrixTypes.h:59
Typedef for fixed size vectors.
vctFixedSizeVector< double, 3 > vct3
Definition vctFixedSizeVectorTypes.h:46
Typedef for different transformations.
vctMatrixRotation3< double, VCT_ROW_MAJOR > vctRot3
Definition vctTransformationTypes.h:109