1 #define BIORBD_API_EXPORTS
2 #include "Muscles/Geometry.h"
4 #include <rbdl/Model.h>
5 #include <rbdl/Kinematics.h>
6 #include "Utils/Error.h"
7 #include "Utils/Matrix.h"
8 #include "Utils/RotoTrans.h"
9 #include "RigidBody/Joints.h"
10 #include "RigidBody/GeneralizedCoordinates.h"
11 #include "RigidBody/GeneralizedVelocity.h"
12 #include "Muscles/WrappingObject.h"
13 #include "Muscles/PathModifiers.h"
14 #include "Muscles/Characteristics.h"
15 #include "Muscles/ViaPoint.h"
16 #include "Muscles/PathModifiers.h"
19 m_origin(std::make_shared<biorbd::utils::Vector3d>()),
20 m_insertion(std::make_shared<biorbd::utils::Vector3d>()),
21 m_originInGlobal(std::make_shared<biorbd::utils::Vector3d>(biorbd::utils::Vector3d::Zero())),
22 m_insertionInGlobal(std::make_shared<biorbd::utils::Vector3d>(biorbd::utils::Vector3d::Zero())),
23 m_pointsInGlobal(std::make_shared<std::vector<biorbd::utils::Vector3d>>()),
24 m_pointsInLocal(std::make_shared<std::vector<biorbd::utils::Vector3d>>()),
25 m_jacobian(std::make_shared<biorbd::utils::Matrix>()),
26 m_G(std::make_shared<biorbd::utils::Matrix>()),
27 m_jacobianLength(std::make_shared<biorbd::utils::Matrix>()),
28 m_length(std::make_shared<biorbd::utils::Scalar>(0)),
29 m_muscleTendonLength(std::make_shared<biorbd::utils::Scalar>(0)),
30 m_velocity(std::make_shared<biorbd::utils::Scalar>(0)),
31 m_isGeometryComputed(std::make_shared<bool>(false)),
32 m_isVelocityComputed(std::make_shared<bool>(false)),
33 m_posAndJacoWereForced(std::make_shared<bool>(false))
41 m_origin(std::make_shared<biorbd::utils::Vector3d>(origin)),
42 m_insertion(std::make_shared<biorbd::utils::Vector3d>(insertion)),
43 m_originInGlobal(std::make_shared<biorbd::utils::Vector3d>(biorbd::utils::Vector3d::Zero())),
44 m_insertionInGlobal(std::make_shared<biorbd::utils::Vector3d>(biorbd::utils::Vector3d::Zero())),
45 m_pointsInGlobal(std::make_shared<std::vector<biorbd::utils::Vector3d>>()),
46 m_pointsInLocal(std::make_shared<std::vector<biorbd::utils::Vector3d>>()),
47 m_jacobian(std::make_shared<biorbd::utils::Matrix>()),
48 m_G(std::make_shared<biorbd::utils::Matrix>()),
49 m_jacobianLength(std::make_shared<biorbd::utils::Matrix>()),
50 m_length(std::make_shared<biorbd::utils::Scalar>(0)),
51 m_muscleTendonLength(std::make_shared<biorbd::utils::Scalar>(0)),
52 m_velocity(std::make_shared<biorbd::utils::Scalar>(0)),
53 m_isGeometryComputed(std::make_shared<bool>(false)),
54 m_isVelocityComputed(std::make_shared<bool>(false)),
55 m_posAndJacoWereForced(std::make_shared<bool>(false))
69 *m_origin = other.
m_origin->DeepCopy();
98 if (*m_posAndJacoWereForced){
101 "Warning, using updateKinematics overrides the"
102 " previously sent position and jacobian");
103 *m_posAndJacoWereForced =
false;
111 setMusclesPointsInGlobal(model, *Q);
117 _updateKinematics(Qdot);
127 if (*m_posAndJacoWereForced){
129 false,
"Warning, using updateKinematics overrides the"
130 " previously sent position and jacobian");
131 *m_posAndJacoWereForced =
false;
140 setMusclesPointsInGlobal(model, *Q, &pathModifiers);
146 _updateKinematics(Qdot, &characteristics, &pathModifiers);
150 std::vector<biorbd::utils::Vector3d>& musclePointsInGlobal,
154 *m_posAndJacoWereForced =
true;
157 setMusclesPointsInGlobal(musclePointsInGlobal);
160 jacobian(jacoPointsInGlobal);
163 _updateKinematics(Qdot);
167 std::vector<biorbd::utils::Vector3d>& musclePointsInGlobal,
172 *m_posAndJacoWereForced =
true;
175 setMusclesPointsInGlobal(musclePointsInGlobal);
178 jacobian(jacoPointsInGlobal);
181 _updateKinematics(Qdot, &c);
188 *m_origin = position;
198 *m_insertion = position;
209 return *m_originInGlobal;
214 return *m_insertionInGlobal;
218 biorbd::utils::Error::check(*m_isGeometryComputed,
"Geometry must be computed at least once before calling musclesPointsInGlobal()");
219 return *m_pointsInGlobal;
231 return *m_muscleTendonLength;
248 return m_jacobian->block(0,0,3,m_jacobian->cols());
253 return m_jacobian->block(m_jacobian->rows()-3,0,3,m_jacobian->cols());
258 return m_jacobian->block(3*idxViaPoint,0,3,m_jacobian->cols());
264 return *m_jacobianLength;
275 length(characteristics, pathModifiers);
276 *m_isGeometryComputed =
true;
279 computeJacobianLength();
280 if (Qdot !=
nullptr){
282 *m_isVelocityComputed =
true;
285 *m_isVelocityComputed =
false;
293 m_originInGlobal->block(0,0,3,1) = RigidBodyDynamics::CalcBodyToBaseCoordinates(model, Q, model.GetBodyId(m_origin->parent().c_str()), *m_origin,
false);
294 return *m_originInGlobal;
302 m_insertionInGlobal->block(0,0,3,1) = RigidBodyDynamics::CalcBodyToBaseCoordinates(model, Q, model.GetBodyId(m_insertion->parent().c_str()), *m_insertion,
false);
303 return *m_insertionInGlobal;
307 std::vector<biorbd::utils::Vector3d> &ptsInGlobal)
310 m_pointsInLocal->clear();
311 *m_pointsInGlobal = ptsInGlobal;
320 m_pointsInLocal->clear();
321 m_pointsInGlobal->clear();
324 if (pathModifiers->
nbWraps()!=0){
340 w.
wrapPoints(RT,po_mus,pi_mus,po_wrap, pi_wrap);
344 "please contact pariterre@hotmail.com");
345 m_pointsInLocal->push_back(originInLocal());
346 m_pointsInLocal->push_back(
348 model, Q, model.GetBodyId(w.
parent().c_str()),po_wrap,
false),
350 m_pointsInLocal->push_back(
352 model, Q, model.GetBodyId(w.
parent().c_str()),pi_wrap,
false),
354 m_pointsInLocal->push_back(insertionInLocal());
357 m_pointsInGlobal->push_back(originInGlobal());
358 m_pointsInGlobal->push_back(po_wrap);
359 m_pointsInGlobal->push_back(pi_wrap);
360 m_pointsInGlobal->push_back(insertionInGlobal());
365 m_pointsInLocal->push_back(originInLocal());
366 m_pointsInGlobal->push_back(originInGlobal(model, Q));
367 for (
unsigned int i=0; i<pathModifiers->
nbObjects(); ++i){
369 m_pointsInLocal->push_back(node);
370 m_pointsInGlobal->push_back(RigidBodyDynamics::CalcBodyToBaseCoordinates(model, Q, model.GetBodyId(node.
parent().c_str()), node,
false));
372 m_pointsInLocal->push_back(insertionInLocal());
373 m_pointsInGlobal->push_back(insertionInGlobal(model,Q));
377 m_pointsInLocal->push_back(originInLocal());
378 m_pointsInLocal->push_back(insertionInLocal());
379 m_pointsInGlobal->push_back(originInGlobal(model, Q));
380 m_pointsInGlobal->push_back(insertionInGlobal(model,Q));
386 setJacobianDimension(model);
393 *m_muscleTendonLength = 0;
396 if (pathModifiers !=
nullptr && pathModifiers->
nbWraps()!=0){
403 biorbd::utils::Scalar lengthWrap(0);
408 *m_muscleTendonLength = ((*m_pointsInGlobal)[0] - pi_wrap).norm() +
410 (*m_pointsInGlobal->end() - po_wrap).norm();
414 for (
unsigned int i=0; i<m_pointsInGlobal->size()-1; ++i)
415 *m_muscleTendonLength += ((*m_pointsInGlobal)[i+1] - (*m_pointsInGlobal)[i]).norm();
429 *m_velocity = (jacobianLength()*Qdot)[0];
435 *m_jacobian = biorbd::utils::Matrix::Zero(
static_cast<unsigned int>(m_pointsInLocal->size()*3), model.dof_count);
436 *m_G = biorbd::utils::Matrix::Zero(3, model.dof_count);
449 for (
unsigned int i=0; i<m_pointsInLocal->size(); ++i){
451 RigidBodyDynamics::CalcPointJacobian(model, Q, model.GetBodyId((*m_pointsInLocal)[i].parent().c_str()), (*m_pointsInLocal)[i], *m_G,
false);
452 m_jacobian->block(3*i,0,3,model.dof_count) = *m_G;
458 *m_jacobianLength = biorbd::utils::Matrix::Zero(1, m_jacobian->cols());
459 const std::vector<biorbd::utils::Vector3d>& p = *m_pointsInGlobal;
460 for (
unsigned int i=0; i<p.size()-1 ; ++i){
461 *m_jacobianLength += (( p[i+1] - p[i] ).transpose() * (jacobian(i+1) - jacobian(i)))
463 ( p[i+1] - p[i] ).norm();