1 #define BIORBD_API_EXPORTS
2 #include "Utils/Rotation.h"
4 #include "Utils/Error.h"
5 #include "Utils/Vector3d.h"
6 #include "Utils/String.h"
7 #include "Utils/Vector.h"
8 #include "Utils/Matrix.h"
10 #include "RigidBody/NodeSegment.h"
13 const RigidBodyDynamics::Math::Matrix3d& matrix) :
14 RigidBodyDynamics::Math::Matrix3d(matrix)
19 #ifdef BIORBD_USE_CASADI_MATH
22 const RigidBodyDynamics::Math::MatrixNd &m) :
23 RigidBodyDynamics::Math::Matrix3d(m)
31 const biorbd::utils::Scalar& v00,
const biorbd::utils::Scalar& v01,
const biorbd::utils::Scalar& v02,
32 const biorbd::utils::Scalar& v10,
const biorbd::utils::Scalar& v11,
const biorbd::utils::Scalar& v12,
33 const biorbd::utils::Scalar& v20,
const biorbd::utils::Scalar& v21,
const biorbd::utils::Scalar& v22) :
34 RigidBodyDynamics::Math::Matrix3d (v00, v01, v02, v10, v11, v12, v20, v21, v22)
42 RigidBodyDynamics::Math::Matrix3d(fromEulerAngles(rotation, rotationSequence))
48 const RigidBodyDynamics::Math::SpatialTransform &st) :
49 RigidBodyDynamics::Math::Matrix3d(st.E)
57 return this->block(0,idx, 3, 1);
61 const RigidBodyDynamics::Math::SpatialTransform& st)
72 seq.length() ==
static_cast<unsigned int>(rot.rows()),
73 "Rotation and sequence of rotation must be the same length");
78 RigidBodyDynamics::Math::Matrix3d tp;
79 for (
unsigned int i=0; i<seq.length(); ++i){
80 biorbd::utils::Scalar cosVi(std::cos(rot[i]));
81 biorbd::utils::Scalar sinVi(std::sin(rot[i]));
83 tp = RigidBodyDynamics::Math::Matrix3d(1, 0, 0,
87 else if (seq.
tolower()[i] ==
'y')
88 tp = RigidBodyDynamics::Math::Matrix3d(cosVi, 0, sinVi,
92 else if (seq.
tolower()[i] ==
'z')
93 tp = RigidBodyDynamics::Math::Matrix3d(cosVi, -sinVi, 0,
99 out.block(0,0,3,3) = out.block(0,0,3,3) * tp;
105 const std::pair<biorbd::rigidbody::NodeSegment, biorbd::rigidbody::NodeSegment> &axis1markers,
106 const std::pair<biorbd::rigidbody::NodeSegment, biorbd::rigidbody::NodeSegment> &axis2markers,
107 const std::pair<biorbd::utils::String, biorbd::utils::String>& axesNames,
111 std::vector<unsigned int> map(3);
112 std::vector<unsigned int> toMultiply(2);
113 if (!axesNames.first.tolower().compare(
"x")){
115 if (!axesNames.second.tolower().compare(
"y")){
127 else if (!axesNames.first.tolower().compare(
"y")){
129 if (!axesNames.second.tolower().compare(
"x")){
141 else if (!axesNames.first.tolower().compare(
"z")){
143 if (!axesNames.second.tolower().compare(
"x")){
157 std::vector<biorbd::utils::Vector3d> axes(3);
158 axes[map[0]] = axis1markers.second - axis1markers.first;
159 axes[map[1]] = axis2markers.second - axis2markers.first;
160 axes[map[2]] = axes[toMultiply[0]].cross(axes[toMultiply[1]]);
163 if (!axisToRecalculate.
tolower().compare(
"x")){
164 axes[0] = axes[1].cross(axes[2]);
165 }
else if (!axisToRecalculate.
tolower().compare(
"y")){
166 axes[1] = axes[2].cross(axes[0]);
167 }
else if (!axisToRecalculate.
tolower().compare(
"z")){
168 axes[2] = axes[0].cross(axes[1]);
173 for (
unsigned int i=0; i<3; ++i){
174 r_out.block(0, i, 3, 1) = axes[i];
180 const std::pair<biorbd::rigidbody::NodeSegment, biorbd::rigidbody::NodeSegment> &axis1markers,
181 const std::pair<biorbd::rigidbody::NodeSegment, biorbd::rigidbody::NodeSegment> &axis2markers,
182 const std::pair<biorbd::utils::String, biorbd::utils::String>& axesNames,
186 fromMarkersNonNormalized(axis1markers, axis2markers, axesNames, axisToRecalculate));
189 for (
unsigned int i=0; i<3; ++i){
191 r_out.block<3, 1>(0, i).normalize();
202 if (!seq.compare(
"zyzz"))
207 if (!seq.compare(
"x")) {
208 v[0] = std::asin(r(2, 1));
210 else if (!seq.compare(
"y")) {
211 v[0] = std::asin(r(0, 2));
213 else if (!seq.compare(
"z")) {
214 v[0] = std::asin(r(1, 0));
216 else if (!seq.compare(
"xy")) {
217 v[0] = std::asin(r(2,1));
218 v[1] = std::asin(r(0,2));
220 else if (!seq.compare(
"xz")) {
221 v[0] = -std::asin(r(1,2));
222 v[1] = -std::asin(r(0,1));
224 else if (!seq.compare(
"yx")) {
225 v[0] = -std::asin(r(2,0));
226 v[1] = -std::asin(r(1,2));
228 else if (!seq.compare(
"yz")) {
229 v[0] = std::asin(r(0,2));
230 v[1] = std::asin(r(1,0));
232 else if (!seq.compare(
"zx")) {
233 v[0] = std::asin(r(1,0));
234 v[1] = std::asin(r(2,1));
236 else if (!seq.compare(
"zy")) {
237 v[0] = -std::asin(r(0,1));
238 v[1] = -std::asin(r(2,0));
240 else if (!seq.compare(
"xyz")) {
241 v[0] = std::atan2(-r(1,2), r(2,2));
242 v[1] = std::asin(r(0,2));
243 v[2] = std::atan2(-r(0,1), r(0,0));
245 else if (!seq.compare(
"xzy")) {
246 v[0] = std::atan2(r(2,1), r(1,1));
247 v[1] = std::asin(-r(0,1));
248 v[2] = std::atan2(r(0,2), r(0,0));
250 else if (!seq.compare(
"yxz")) {
251 v[0] = std::atan2(r(0,2), r(2,2));
252 v[1] = std::asin(-r(1,2));
253 v[2] = std::atan2(r(1,0), r(1,1));
255 else if (!seq.compare(
"yzx")) {
256 v[0] = std::atan2(-r(2,0), r(0,0));
257 v[1] = std::asin(r(1,0));
258 v[2] = std::atan2(-r(1,2), r(1,1));
260 else if (!seq.compare(
"zxy")) {
261 v[0] = std::atan2(-r(0,1), r(1,1));
262 v[1] = std::asin(r(2,1));
263 v[2] = std::atan2(-r(2,0), r(2,2));
265 else if (!seq.compare(
"zyx")) {
266 v[0] = std::atan2(r(1,0), r(0,0));
267 v[1] = std::asin(-r(2,0));
268 v[2] = std::atan2(r(2,1), r(2,2));
270 else if (!seq.compare(
"zxz")) {
271 v[0] = std::atan2(r(0,2), -r(1,2));
272 v[1] = std::acos(r(2,2));
273 v[2] = std::atan2(r(2,0), r(2,1));
275 else if (!seq.compare(
"zyz")) {
276 v[0] = std::atan2(r(1,2), r(0,2));
277 v[1] = std::acos(r(2,2));
278 v[2] = std::atan2(r(2,1), -r(2,0));
280 else if (!seq.compare(
"zyzz")) {
281 v[0] = std::atan2(r(1,2), r(0,2));
282 v[1] = std::acos(r(2,2));
283 v[2] = std::atan2(r(2,1), -r(2,0)) + v[0];
292 #ifndef BIORBD_USE_CASADI_MATH
294 const std::vector<biorbd::utils::Rotation> & mToMean)
296 RigidBodyDynamics::Math::Matrix3d m_tp;
300 for (
unsigned int i = 0; i<mToMean.size(); ++i){
303 m_tp = m_tp/mToMean.size();
306 Eigen::JacobiSVD<Eigen::Matrix3d> svd(
307 m_tp, Eigen::ComputeFullU | Eigen::ComputeFullV);
318 #ifndef BIORBD_USE_CASADI_MATH
321 "The Rotation matrix norm is not equal to one");
328 os << a.block(0,0,3,3);