1 #define BIORBD_API_EXPORTS
2 #include "Utils/Quaternion.h"
4 #include "Utils/Vector3d.h"
5 #include "Utils/Vector.h"
6 #include "Utils/RotoTrans.h"
7 #include "Utils/Error.h"
8 #include "Utils/Rotation.h"
12 RigidBodyDynamics::Math::Vector4d (1, 0, 0, 0),
13 m_Kstab(kStabilizer) {
19 RigidBodyDynamics::Math::Vector4d (other),
20 m_Kstab(other.m_Kstab) {
25 const RigidBodyDynamics::Math::Vector4d &vec4,
27 RigidBodyDynamics::Math::Vector4d (vec4),
34 const biorbd::utils::Scalar& w,
35 const biorbd::utils::Scalar& x,
36 const biorbd::utils::Scalar& y,
37 const biorbd::utils::Scalar& z,
39 RigidBodyDynamics::Math::Vector4d(w, x, y, z),
40 m_Kstab(kStabilizer) {
45 const biorbd::utils::Scalar& w,
48 RigidBodyDynamics::Math::Vector4d(w, vec3[0], vec3[1], vec3[2]),
49 m_Kstab(kStabilizer) {
84 (*
this)[0] * q[0] - (*
this)[1] * q[1] - (*
this)[2] * q[2] - (*
this)[3] * q[3],
85 (*
this)[0] * q[1] + (*
this)[1] * q[0] + (*
this)[2] * q[3] - (*
this)[3] * q[2],
86 (*
this)[0] * q[2] + (*
this)[2] * q[0] + (*
this)[3] * q[1] - (*
this)[1] * q[3],
87 (*
this)[0] * q[3] + (*
this)[3] * q[0] + (*
this)[1] * q[2] - (*
this)[2] * q[1],
88 (this->m_Kstab + q.
m_Kstab) / 2);
92 const biorbd::utils::Scalar& scalar)
const
95 this->RigidBodyDynamics::Math::Vector4d::operator*(scalar), this->m_Kstab);
102 this->RigidBodyDynamics::Math::Vector4d::operator*(
103 static_cast<double>(scalar)), this->m_Kstab);
106 #ifdef BIORBD_USE_CASADI_MATH
111 this->RigidBodyDynamics::Math::Vector4d::operator*(scalar),
120 (this->m_Kstab + other.
m_Kstab) / 2);
127 (this->m_Kstab + other.
m_Kstab) / 2);
131 const biorbd::utils::Scalar& angle,
132 const biorbd::utils::Scalar& x,
133 const biorbd::utils::Scalar& y,
134 const biorbd::utils::Scalar& z,
136 biorbd::utils::Scalar angle_copy(angle);
137 biorbd::utils::Scalar st = std::sin (angle_copy * M_PI / 360.);
139 std::cos (angle_copy * M_PI / 360.), st * x, st * y, st * z, kStab);
143 const biorbd::utils::Scalar& angle,
146 biorbd::utils::Scalar angle_copy(angle);
147 biorbd::utils::Scalar d = axis.norm();
148 biorbd::utils::Scalar s2 = std::sin (angle_copy * 0.5) / d;
150 std::cos(angle_copy * 0.5),
151 axis[0] * s2, axis[1] * s2, axis[2] * s2, kStab
158 return fromMatrix(rt.
rot(), kStab);
164 biorbd::utils::Scalar w = std::sqrt (1. + mat(0,0) + mat(1,1) + mat(2,2)) * 0.5;
167 (mat(2,1) - mat(1,2)) / (w * 4.),
168 (mat(0,2) - mat(2,0)) / (w * 4.),
169 (mat(1,0) - mat(0,1)) / (w * 4.),
198 bool skipAsserts)
const {
199 #ifndef BIORBD_USE_CASADI_MATH
202 "The Quaternion norm is not equal to one");
207 biorbd::utils::Scalar w = (*this)[0];
208 biorbd::utils::Scalar x = (*this)[1];
209 biorbd::utils::Scalar y = (*this)[2];
210 biorbd::utils::Scalar z = (*this)[3];
212 1 - 2*y*y - 2*z*z, 2*x*y - 2*w*z, 2*x*z + 2*w*y,
213 2*x*y + 2*w*z, 1 - 2*x*x - 2*z*z, 2*y*z - 2*w*x,
214 2*x*z - 2*w*y, 2*y*z + 2*w*x, 1 - 2*x*x - 2*y*y);
218 #ifndef BIORBD_USE_CASADI_MATH
223 biorbd::utils::Scalar s = std::sqrt (squaredNorm() * quat.squaredNorm());
226 #ifndef BIORBD_USE_CASADI_MATH
230 biorbd::utils::Scalar angle = acos (dot(quat) / s);
231 #ifdef BIORBD_USE_CASADI_MATH
234 if (angle == 0. || std::isnan(angle)) {
239 biorbd::utils::Scalar d = 1. / std::sin (angle);
240 biorbd::utils::Scalar p0 = std::sin ((1. - alpha) * angle);
241 biorbd::utils::Scalar p1 = std::sin (alpha * angle);
243 #ifdef BIORBD_USE_CASADI_MATH
245 casadi::MX::lt(dot (quat), 0.),
246 RigidBodyDynamics::Math::Vector4d( ((*
this) * p0 - quat * p1) * d),
247 RigidBodyDynamics::Math::Vector4d( ((*
this) * p0 + quat * p1) * d)),
248 (this->m_Kstab + quat.
m_Kstab) / 2);
251 if (dot (quat) < 0.) {
252 return Quaternion( ((*
this) * p0 - quat * p1) * d, this->m_Kstab);
254 return Quaternion( ((*
this) * p0 + quat * p1) * d,
255 (this->m_Kstab + quat.
m_Kstab) / 2);
263 -(*
this)[1],-(*
this)[2],-(*
this)[3],
271 biorbd::utils::Scalar omega_norm = omega.norm();
272 return fromAxisAngle (
273 dt * omega_norm, omega / omega_norm, this->m_Kstab) * (*this);
281 res_quat = conjugate() * res_quat;
289 RigidBodyDynamics::Math::MatrixNd m(4, 3);
290 m(0, 0) = -(*this)[1]; m(0, 1) = -(*this)[2]; m(0, 2) = -(*this)[3];
291 m(1, 0) = (*this)[0]; m(1, 1) = -(*this)[3]; m(1, 2) = (*this)[2];
292 m(2, 0) = (*this)[3]; m(2, 1) = (*this)[0]; m(2, 2) = -(*this)[1];
293 m(3, 0) = -(*this)[2]; m(3, 1) = (*this)[1]; m(3, 2) = (*this)[0];
304 biorbd::utils::Scalar dph, dth, dps, ph, th, ps;
305 dph = eulerDot[0]; dth = eulerDot[1]; dps = eulerDot[2];
306 ph = euler[0]; th = euler[1]; ps = euler[2];
307 if (!seq.compare(
"xyz")) {
308 w[0] = dph*std::cos(th)*std::cos(ps) + dth*std::sin(ps);
309 w[1] = dth*std::cos(ps) - dph*std::cos(th)*std::sin(ps);
310 w[2] = dph*std::sin(th) + dps;
321 #ifdef BIORBD_USE_CASADI_MATH
322 biorbd::utils::Scalar qw = (*this)(0);
323 biorbd::utils::Scalar qx = (*this)(1);
324 biorbd::utils::Scalar qy = (*this)(2);
325 biorbd::utils::Scalar qz = (*this)(3);
327 biorbd::utils::Scalar& qw = (*this)(0);
328 biorbd::utils::Scalar& qx = (*this)(1);
329 biorbd::utils::Scalar& qy = (*this)(2);
330 biorbd::utils::Scalar& qz = (*this)(3);
332 RigidBodyDynamics::Math::Matrix4d Q =
333 RigidBodyDynamics::Math::Matrix4d(
340 RigidBodyDynamics::Math::Vector4d w_tp (m_Kstab*w.
norm()*(1-this->norm()), w(0), w(1), w(2));
341 RigidBodyDynamics::Math::Vector4d newQuat(0.5 * Q * w_tp);
348 #ifdef BIORBD_USE_CASADI_MATH
355 *
this = *
this / this->norm();