Biorbd
IMUs.cpp
1 #define BIORBD_API_EXPORTS
2 #include "RigidBody/IMUs.h"
3 
4 #include <rbdl/Model.h>
5 #include <rbdl/Kinematics.h>
6 #include "Utils/String.h"
7 #include "Utils/Matrix.h"
8 #include "Utils/Rotation.h"
9 #include "RigidBody/GeneralizedCoordinates.h"
10 #include "RigidBody/Joints.h"
11 #include "RigidBody/Segment.h"
12 #include "RigidBody/IMU.h"
13 
15  m_IMUs(std::make_shared<std::vector<biorbd::rigidbody::IMU>>())
16 {
17  //ctor
18 }
19 
21 {
22  m_IMUs = other.m_IMUs;
23 }
24 
26 {
27 
28 }
29 
31 {
33  copy.DeepCopy(*this);
34  return copy;
35 }
36 
38 {
39  m_IMUs->resize(other.m_IMUs->size());
40  for (unsigned int i=0; i<other.m_IMUs->size(); ++i)
41  (*m_IMUs)[i] = (*other.m_IMUs)[i].DeepCopy();
42 }
43 
45  bool technical,
46  bool anatomical)
47 {
48  m_IMUs->push_back(biorbd::rigidbody::IMU(technical, anatomical));
49 }
50 
51 // Add a new marker to the existing pool of markers
53  const biorbd::utils::RotoTransNode &RotoTrans,
54  bool technical,
55  bool anatomical)
56 {
57  m_IMUs->push_back(biorbd::rigidbody::IMU(RotoTrans, technical, anatomical));
58 }
59 
60 unsigned int biorbd::rigidbody::IMUs::nbIMUs() const
61 {
62  return static_cast<unsigned int>(m_IMUs->size());
63 }
64 
65 
66 // Get the markers in the global reference
67 const std::vector<biorbd::rigidbody::IMU>& biorbd::rigidbody::IMUs::IMU() const
68 {
69  return *m_IMUs;
70 }
71 
72 std::vector<biorbd::rigidbody::IMU> biorbd::rigidbody::IMUs::IMU(const biorbd::utils::String& segmentName)
73 {
74  std::vector<biorbd::rigidbody::IMU> pos;
75  for (unsigned int i=0; i<nbIMUs(); ++i) // Scan through all the markers and select the good ones
76  if (!IMU(i).parent().compare(segmentName))
77  pos.push_back(IMU(i));
78  return pos;
79 }
80 
82 {
83  return (*m_IMUs)[idx];
84 }
85 
86 // Get the IMUs at the position given by Q
87 std::vector<biorbd::rigidbody::IMU> biorbd::rigidbody::IMUs::IMU(
89  bool updateKin)
90 {
91  // Assuming that this is also a Joints type (via BiorbdModel)
92  biorbd::rigidbody::Joints &model = dynamic_cast<biorbd::rigidbody::Joints &>(*this);
93  if (updateKin) {
94  model.UpdateKinematicsCustom (&Q);
95  }
96 
97  std::vector<biorbd::rigidbody::IMU> pos;
98  for (unsigned int i=0; i<nbIMUs(); ++i)
99  pos.push_back(IMU(Q, i, false));
100 
101  return pos;
102 }
103 
104 // Get an IMU at the position given by Q
107  unsigned int idx,
108  bool updateKin)
109 {
110  // Assuming that this is also a Joints type (via BiorbdModel)
111  biorbd::rigidbody::Joints &model = dynamic_cast<biorbd::rigidbody::Joints &>(*this);
112  if (updateKin) {
113  model.UpdateKinematicsCustom (&Q);
114  }
115 
116  biorbd::rigidbody::IMU node = IMU(idx);
117  unsigned int id = static_cast<unsigned int>(model.GetBodyBiorbdId(node.parent()));
118 
119  return model.globalJCS(id) * node;
120 }
121 
122 // Get the technical IMUs
123 std::vector<biorbd::rigidbody::IMU> biorbd::rigidbody::IMUs::technicalIMU(
125  bool updateKin)
126 {
127  // Assuming that this is also a Joints type (via BiorbdModel)
128  biorbd::rigidbody::Joints &model = dynamic_cast<biorbd::rigidbody::Joints &>(*this);
129  if (updateKin) {
130  model.UpdateKinematicsCustom (&Q);
131  }
132 
133  std::vector<biorbd::rigidbody::IMU> pos;
134  for (unsigned int i=0; i<nbIMUs(); ++i)
135  if ( IMU(i).isTechnical() ){
136  pos.push_back(IMU(Q, i, updateKin));
137  }
138  return pos;
139 }
140 // Get the technical IMUs in the local reference
141 std::vector<biorbd::rigidbody::IMU> biorbd::rigidbody::IMUs::technicalIMU()
142 {
143  std::vector<biorbd::rigidbody::IMU> pos;
144  for (unsigned int i=0; i<nbIMUs(); ++i)
145  if ( IMU(i).isTechnical() )
146  pos.push_back(IMU(i));// Forward kinematics
147  return pos;
148 }
149 
150 // Get all the anatomical IMUs
151 std::vector<biorbd::rigidbody::IMU> biorbd::rigidbody::IMUs::anatomicalIMU(
153  bool updateKin)
154 {
155  // Assuming that this is also a Joints type (via BiorbdModel)
156  biorbd::rigidbody::Joints &model = dynamic_cast<biorbd::rigidbody::Joints &>(*this);
157  if (updateKin) {
158  model.UpdateKinematicsCustom (&Q);
159  }
160 
161  std::vector<biorbd::rigidbody::IMU> pos;
162  for (unsigned int i=0; i<nbIMUs(); ++i)
163  if ( IMU(i).isAnatomical() ){
164  pos.push_back(IMU(Q, i, updateKin));
165  }
166  return pos;
167 }
168 // Get the anatomical IMUs in the local reference
169 std::vector<biorbd::rigidbody::IMU> biorbd::rigidbody::IMUs::anatomicalIMU()
170 {
171  std::vector<biorbd::rigidbody::IMU> pos;
172  for (unsigned int i=0; i<nbIMUs(); ++i)
173  if ( IMU(i).isAnatomical() )
174  pos.push_back(IMU(i));// Forward kinematics
175  return pos;
176 }
177 
178 std::vector<biorbd::rigidbody::IMU> biorbd::rigidbody::IMUs::segmentIMU(
180  unsigned int idx,
181  bool updateKin)
182 {
183  // Assuming that this is also a Joints type (via BiorbdModel)
184  biorbd::rigidbody::Joints &model = dynamic_cast<biorbd::rigidbody::Joints &>(*this);
185  if (updateKin) {
186  model.UpdateKinematicsCustom (&Q);
187  }
188 
189  // Segment name to find
190  biorbd::utils::String name(model.segment(idx).name());
191 
192  std::vector<biorbd::rigidbody::IMU> pos;
193  for (unsigned int i=0; i<nbIMUs(); ++i) // scan all the markers and select the right ones
194  if (!((*m_IMUs)[i]).parent().compare(name))
195  pos.push_back(IMU(Q,i,false));
196 
197  return pos;
198 }
199 
200 // Get the Jacobian of the markers
201 std::vector<biorbd::utils::Matrix> biorbd::rigidbody::IMUs::IMUJacobian(
203  bool updateKin)
204 {
205  return IMUJacobian(Q, updateKin, false);
206 }
207 
208 // Get the Jacobian of the technical markers
209 std::vector<biorbd::utils::Matrix> biorbd::rigidbody::IMUs::TechnicalIMUJacobian(
211  bool updateKin)
212 {
213  return IMUJacobian(Q, updateKin, true);
214 }
215 
216 
217 // Protected function
218 std::vector<biorbd::utils::Matrix> biorbd::rigidbody::IMUs::IMUJacobian(
220  bool updateKin,
221  bool lookForTechnical)
222 {
223  // Assuming that this is also a Joints type (via BiorbdModel)
224  biorbd::rigidbody::Joints &model = dynamic_cast<biorbd::rigidbody::Joints &>(*this);
225  if (updateKin) {
226  model.UpdateKinematicsCustom (&Q);
227  }
228 
229  std::vector<biorbd::utils::Matrix> G;
230 
231  for (unsigned int idx=0; idx<nbIMUs(); ++idx){
232  // Actual marker
233  biorbd::rigidbody::IMU node = IMU(idx);
234  if (lookForTechnical && !node.isTechnical())
235  continue;
236 
237  unsigned int id = model.GetBodyId(node.parent().c_str());
238  biorbd::utils::Matrix G_tp(biorbd::utils::Matrix::Zero(9,model.dof_count));
239 
240  // Calculate the Jacobian of this Tag
241  model.CalcMatRotJacobian(Q, id, node.rot(), G_tp, false); // False for speed
242 
243  G.push_back(G_tp);
244  }
245 
246  return G;
247 }
248 
250 {
251  unsigned int nbTech = 0;
252  if (nbTech == 0) // If the function has never been called before
253  for (biorbd::rigidbody::IMU imu : *m_IMUs)
254  if (imu.isTechnical())
255  ++nbTech;
256 
257  return nbTech;
258 }
259 
261 {
262  unsigned int nbAnat = 0;
263  if (nbAnat == 0) // If the function has never been called before
264  for (biorbd::rigidbody::IMU imu : *m_IMUs)
265  if (imu.isAnatomical())
266  ++nbAnat;
267 
268  return nbAnat;
269 }
270 
271 std::vector<biorbd::utils::String> biorbd::rigidbody::IMUs::IMUsNames()
272 {
273  // Extract the name of all the markers of a model
274  std::vector<biorbd::utils::String> names;
275  for (unsigned int i=0; i<nbIMUs(); ++i)
276  names.push_back(IMU(i).biorbd::utils::Node::name());
277  return names;
278 }
279 
280 std::vector<biorbd::utils::String> biorbd::rigidbody::IMUs::technicalIMUsNames()
281 {
282  // Extract the names of all the technical markers of a model
283  std::vector<biorbd::utils::String> names;
284  for (unsigned int i=0; i<nbIMUs(); ++i)
285  if (IMU(i).isTechnical())
286  names.push_back(IMU(i).biorbd::utils::Node::name());
287 
288  return names;
289 }
290 
291 std::vector<biorbd::utils::String> biorbd::rigidbody::IMUs::anatomicalIMUsNames()
292 {
293  // Extract the names of all the anatomical markers of a model
294  std::vector<biorbd::utils::String> names;
295  for (unsigned int i=0; i<nbIMUs(); ++i)
296  if (IMU(i).isAnatomical())
297  names.push_back(IMU(i).biorbd::utils::Node::name());
298 
299  return names;
300 }
biorbd::rigidbody::IMU::isAnatomical
bool isAnatomical() const
Return if the IMU is anatomical.
Definition: IMU.cpp:66
biorbd::rigidbody::IMUs::nbTechIMUs
unsigned int nbTechIMUs()
Return the number of technical inertial measurement units (IMU)
Definition: IMUs.cpp:249
biorbd::rigidbody::IMU
Class IMU.
Definition: IMU.h:23
biorbd::rigidbody::GeneralizedCoordinates
Class GeneralizedCoordinates.
Definition: GeneralizedCoordinates.h:15
biorbd::rigidbody::IMUs::IMU
const std::vector< biorbd::rigidbody::IMU > & IMU() const
Return all the IMU in the local reference of the segment.
Definition: IMUs.cpp:67
biorbd::utils::RotoTransNode
A RotoTrans which is attached to a segment.
Definition: RotoTransNode.h:16
biorbd::utils::Node::name
const biorbd::utils::String & name() const
Return the name of the node.
Definition: Node.cpp:59
biorbd::rigidbody::Joints::globalJCS
biorbd::utils::RotoTrans globalJCS(const biorbd::rigidbody::GeneralizedCoordinates &Q, const biorbd::utils::String &name)
Return the joint coordinate system (JCS) for the segment in global reference frame at a given Q.
Definition: Joints.cpp:267
biorbd::rigidbody::Joints::GetBodyBiorbdId
int GetBodyBiorbdId(const biorbd::utils::String &segmentName) const
Return the biorbd body identification.
Definition: Joints.cpp:245
biorbd::rigidbody::IMUs::segmentIMU
std::vector< biorbd::rigidbody::IMU > segmentIMU(const biorbd::rigidbody::GeneralizedCoordinates &Q, unsigned int idx, bool updateKin=true)
Return all the inertial measurement units (IMU) on a specified segment.
Definition: IMUs.cpp:178
biorbd::rigidbody::IMUs::nbIMUs
unsigned int nbIMUs() const
Return the number of inertial measurement units (IMU) in the set.
Definition: IMUs.cpp:60
biorbd::rigidbody::Joints
This is the core of the musculoskeletal model in biorbd.
Definition: Joints.h:40
biorbd::rigidbody::IMUs::IMUsNames
std::vector< biorbd::utils::String > IMUsNames()
Return the names of the inertial measurement units (IMU)
Definition: IMUs.cpp:271
biorbd::rigidbody::Joints::segment
const biorbd::rigidbody::Segment & segment(unsigned int idx) const
Get a segment of index idx.
Definition: Joints.cpp:189
biorbd::utils::Matrix
A wrapper for the Eigen::MatrixXd.
Definition: Matrix.h:21
biorbd::rigidbody::Joints::CalcMatRotJacobian
void CalcMatRotJacobian(const biorbd::rigidbody::GeneralizedCoordinates &Q, unsigned int segmentIdx, const RigidBodyDynamics::Math::Matrix3d &rotation, RigidBodyDynamics::Math::MatrixNd &G, bool updateKin)
Calculate the jacobian matrix of a rotation matrix.
Definition: Joints.cpp:1072
biorbd::rigidbody::IMUs
Hold a set of IMUs.
Definition: IMUs.h:22
biorbd::rigidbody::IMUs::m_IMUs
std::shared_ptr< std::vector< biorbd::rigidbody::IMU > > m_IMUs
All the inertial Measurement Units.
Definition: IMUs.h:234
biorbd::rigidbody::IMUs::~IMUs
virtual ~IMUs()
Destroy the class properly.
Definition: IMUs.cpp:25
biorbd::utils::String
Wrapper around the std::string class with augmented functionality.
Definition: String.h:17
biorbd::rigidbody::IMUs::TechnicalIMUJacobian
std::vector< biorbd::utils::Matrix > TechnicalIMUJacobian(const biorbd::rigidbody::GeneralizedCoordinates &Q, bool updateKin=true)
Return the jacobian of the technical inertial measurement units (IMU)
Definition: IMUs.cpp:209
biorbd::rigidbody::IMUs::addIMU
void addIMU(bool technical=true, bool anatomical=true)
Add a new inertial measurement unit to the set.
Definition: IMUs.cpp:44
biorbd::rigidbody::IMUs::anatomicalIMU
std::vector< biorbd::rigidbody::IMU > anatomicalIMU()
Return all the anatomical inertial measurement units (IMU) in their respective segment local referenc...
Definition: IMUs.cpp:169
biorbd::rigidbody::IMUs::IMUJacobian
std::vector< biorbd::utils::Matrix > IMUJacobian(const biorbd::rigidbody::GeneralizedCoordinates &Q, bool updateKin=true)
Return the jacobian of the inertial measurement units (IMU)
Definition: IMUs.cpp:201
biorbd::rigidbody::IMUs::technicalIMU
std::vector< biorbd::rigidbody::IMU > technicalIMU()
Return all the technical inertial measurement units (IMU) in their respective segment local reference...
Definition: IMUs.cpp:141
biorbd::rigidbody::IMUs::DeepCopy
biorbd::rigidbody::IMUs DeepCopy() const
Deep copy of the inertial measurement units data.
Definition: IMUs.cpp:30
biorbd::rigidbody::Joints::UpdateKinematicsCustom
void UpdateKinematicsCustom(const biorbd::rigidbody::GeneralizedCoordinates *Q=nullptr, const biorbd::rigidbody::GeneralizedVelocity *Qdot=nullptr, const biorbd::rigidbody::GeneralizedAcceleration *Qddot=nullptr)
Update the kinematic variables such as body velocities and accelerations in the model to reflect the ...
Definition: Joints.cpp:1063
biorbd::utils::Node::parent
const biorbd::utils::String & parent() const
Return the parent name of the node.
Definition: Node.cpp:64
biorbd::rigidbody::IMUs::technicalIMUsNames
std::vector< biorbd::utils::String > technicalIMUsNames()
Return the names of the technical inertial measurement units (IMU)
Definition: IMUs.cpp:280
biorbd::rigidbody::IMU::isTechnical
bool isTechnical() const
Return if the IMU is technical.
Definition: IMU.cpp:71
biorbd::rigidbody::IMUs::nbAnatIMUs
unsigned int nbAnatIMUs()
Return the number of anatomical inertial measurement units (IMU)
Definition: IMUs.cpp:260
biorbd::utils::RotoTrans::rot
biorbd::utils::Rotation rot() const
Return the rotation matrix.
Definition: RotoTrans.cpp:97
biorbd::rigidbody::IMUs::IMUs
IMUs()
Construct inertial measurement units set.
Definition: IMUs.cpp:14
biorbd::rigidbody::IMUs::anatomicalIMUsNames
std::vector< biorbd::utils::String > anatomicalIMUsNames()
Return the names of the anatomical inertial measurement units (IMU)
Definition: IMUs.cpp:291