Biorbd
Actuators.cpp
1 #define BIORBD_API_EXPORTS
2 #include "Actuators/Actuators.h"
3 
4 #include <vector>
5 #include "Utils/Error.h"
6 #include "RigidBody/GeneralizedTorque.h"
7 #include "RigidBody/GeneralizedCoordinates.h"
8 #include "RigidBody/GeneralizedVelocity.h"
9 #include "RigidBody/Joints.h"
10 #include "Actuators/Actuator.h"
11 #include "Actuators/ActuatorGauss3p.h"
12 #include "Actuators/ActuatorGauss6p.h"
13 #include "Actuators/ActuatorConstant.h"
14 #include "Actuators/ActuatorLinear.h"
15 
17  m_all(std::make_shared<std::vector<std::pair<std::shared_ptr<biorbd::actuator::Actuator>, std::shared_ptr<biorbd::actuator::Actuator>>>>()),
18  m_isDofSet(std::make_shared<std::vector<bool>>(1)),
19  m_isClose(std::make_shared<bool>(false))
20 {
21  (*m_isDofSet)[0] = false;
22 }
23 
25  const biorbd::actuator::Actuators& other) :
26  m_all(other.m_all),
27  m_isDofSet(other.m_isDofSet),
28  m_isClose(other.m_isClose)
29 {
30 
31 }
32 
33 
35 {
36 
37 }
38 
40 {
41  m_all->resize(other.m_all->size());
42  for (unsigned int i=0; i<other.m_all->size(); ++i){
43  if ((*other.m_all)[i].first->type() == biorbd::actuator::TYPE::CONSTANT)
44  (*m_all)[i].first = std::make_shared<biorbd::actuator::ActuatorConstant>(
45  static_cast<const biorbd::actuator::ActuatorConstant&>( *(*other.m_all)[i].first) );
46  else if ((*other.m_all)[i].first->type() == biorbd::actuator::TYPE::LINEAR)
47  (*m_all)[i].first = std::make_shared<biorbd::actuator::ActuatorLinear>(
48  static_cast<const biorbd::actuator::ActuatorLinear&>( *(*other.m_all)[i].first) );
49  else if ((*other.m_all)[i].first->type() == biorbd::actuator::TYPE::GAUSS3P)
50  (*m_all)[i].first = std::make_shared<biorbd::actuator::ActuatorGauss3p>(
51  static_cast<const biorbd::actuator::ActuatorGauss3p&>( *(*other.m_all)[i].first) );
52  else if ((*other.m_all)[i].first->type() == biorbd::actuator::TYPE::GAUSS6P)
53  (*m_all)[i].first = std::make_shared<biorbd::actuator::ActuatorGauss6p>(
54  static_cast<const biorbd::actuator::ActuatorGauss6p&>( *(*other.m_all)[i].first) );
55  else
57  biorbd::actuator::TYPE_toStr((*other.m_all)[i].first->type()))
58  + " in DeepCopy");
59  if ((*other.m_all)[i].second->type() == biorbd::actuator::TYPE::CONSTANT)
60  (*m_all)[i].second = std::make_shared<biorbd::actuator::ActuatorConstant>(
61  static_cast<const biorbd::actuator::ActuatorConstant&>( *(*other.m_all)[i].second) );
62  else if ((*other.m_all)[i].second->type() == biorbd::actuator::TYPE::LINEAR)
63  (*m_all)[i].second = std::make_shared<biorbd::actuator::ActuatorLinear>(
64  static_cast<const biorbd::actuator::ActuatorLinear&>( *(*other.m_all)[i].second) );
65  else if ((*other.m_all)[i].second->type() == biorbd::actuator::TYPE::GAUSS3P)
66  (*m_all)[i].second = std::make_shared<biorbd::actuator::ActuatorGauss3p>(
67  static_cast<const biorbd::actuator::ActuatorGauss3p&>( *(*other.m_all)[i].second) );
68  else if ((*other.m_all)[i].second->type() == biorbd::actuator::TYPE::GAUSS6P)
69  (*m_all)[i].second = std::make_shared<biorbd::actuator::ActuatorGauss6p>(
70  static_cast<const biorbd::actuator::ActuatorGauss6p&>( *(*other.m_all)[i].second) );
71  else
73  biorbd::actuator::TYPE_toStr((*other.m_all)[i].second->type()))
74  + " in DeepCopy");
75  }
76  m_isDofSet->resize(other.m_isDofSet->size());
77  for (unsigned int i=0; i<other.m_isDofSet->size(); ++i)
78  (*m_isDofSet)[i] = (*other.m_isDofSet)[i];
79  *m_isClose = *other.m_isClose;
80 }
81 
83 {
85  !*m_isClose, "You can't add actuator after closing the model");
86 
87  // Assuming that this is also a Joints type (via BiorbdModel)
88  const biorbd::rigidbody::Joints &model = dynamic_cast<biorbd::rigidbody::Joints &>(*this);
89 
90  // Verify that the target dof is associated to a dof that
91  // already exists in the model
93  act.index()<model.nbDof(), "Sent index is out of dof range");
94 
95  // For speed purposes and coherence with the Q,
96  // set the actuator to the same index as its associated dof
97  unsigned int idx(act.index());
98 
99  // If there are less actuators declared than dof,
100  // the vector must be enlarged
101  if (idx >= m_all->size()){
102  m_all->resize(idx+1);
103  m_isDofSet->resize((idx+1)*2, false);
104  }
105 
106  // Add an actuator to the pool of actuators according to its type
107  if (act.type() == biorbd::actuator::TYPE::CONSTANT){
108  if (act.direction() == 1){
109  (*m_all)[idx].first = std::make_shared<biorbd::actuator::ActuatorConstant>(static_cast<const biorbd::actuator::ActuatorConstant&>(act));
110  (*m_isDofSet)[idx*2] = true;
111  }
112  else{
113  (*m_all)[idx].second = std::make_shared<biorbd::actuator::ActuatorConstant>(static_cast<const biorbd::actuator::ActuatorConstant&>(act));
114  (*m_isDofSet)[idx*2+1] = true;
115  }
116  return;
117  }
118  else if (act.type() == biorbd::actuator::TYPE::LINEAR){
119  if (act.direction() == 1){
120  (*m_all)[idx].first = std::make_shared<biorbd::actuator::ActuatorLinear>(static_cast<const biorbd::actuator::ActuatorLinear&>(act));
121  (*m_isDofSet)[idx*2] = true;
122  }
123  else{
124  (*m_all)[idx].second = std::make_shared<biorbd::actuator::ActuatorLinear>(static_cast<const biorbd::actuator::ActuatorLinear&>(act));
125  (*m_isDofSet)[idx*2+1] = true;
126  }
127  return;
128  }
129  else if (act.type() == biorbd::actuator::TYPE::GAUSS3P){
130  if (act.direction() == 1){
131  (*m_all)[idx].first = std::make_shared<biorbd::actuator::ActuatorGauss3p>(static_cast<const biorbd::actuator::ActuatorGauss3p&>(act));
132  (*m_isDofSet)[idx*2] = true;
133  }
134  else {
135  (*m_all)[idx].second = std::make_shared<biorbd::actuator::ActuatorGauss3p>(static_cast<const biorbd::actuator::ActuatorGauss3p&>(act));
136  (*m_isDofSet)[idx*2+1] = true;
137  }
138  return;
139  }
140  else if (act.type() == biorbd::actuator::TYPE::GAUSS6P){
141  if (act.direction() == 1){
142  (*m_all)[idx].first = std::make_shared<biorbd::actuator::ActuatorGauss6p>(static_cast<const biorbd::actuator::ActuatorGauss6p&>(act));
143  (*m_isDofSet)[idx*2] = true;
144  }
145  else{
146  (*m_all)[idx].second = std::make_shared<biorbd::actuator::ActuatorGauss6p>(static_cast<const biorbd::actuator::ActuatorGauss6p&>(act));
147  (*m_isDofSet)[idx*2+1] = true;
148  }
149  return;
150  }
151  else
152  biorbd::utils::Error::raise("Actuator type not found");
153 
154 }
155 
157 {
158  // Assuming that this is also a Joints type (via BiorbdModel)
159  const biorbd::rigidbody::Joints &model = dynamic_cast<biorbd::rigidbody::Joints &>(*this);
160 
162  model.nbDof()==m_all->size(),
163  "All dof must have their actuators set");
164 
165  for (unsigned int i=0; i<m_all->size()*2; ++i)
166  biorbd::utils::Error::check((*m_isDofSet)[i],
167  "All DoF must have their actuators set "
168  "before closing the model");
169 
170  *m_isClose = true;
171 }
172 
173 const std::pair<std::shared_ptr<biorbd::actuator::Actuator>,
174 std::shared_ptr<biorbd::actuator::Actuator>>&
176 {
177  biorbd::utils::Error::check(dof<nbActuators(), "Idx asked is higher than number of actuator");
178  return (*m_all)[dof];
179 }
181  unsigned int dof,
182  bool concentric)
183 {
184  const std::pair<std::shared_ptr<biorbd::actuator::Actuator>, std::shared_ptr<biorbd::actuator::Actuator>>&
185  tp(actuator(dof));
186 
187  if (concentric)
188  return *tp.first;
189  else
190  return *tp.second;
191 }
192 
194 {
195  return static_cast<unsigned int>(m_all->size());
196 }
197 
199  const biorbd::utils::Vector& activation,
202 {
203  // Set qdot to be positive if concentric and negative is excentric
204  biorbd::rigidbody::GeneralizedVelocity QdotResigned(Qdot);
205  for (unsigned int i=0; i<Qdot.size(); ++i){
206 #ifdef BIORBD_USE_CASADI_MATH
207  QdotResigned(i) = casadi::MX::if_else(
208  casadi::MX::lt(activation(i), 0),
209  -Qdot(i), Qdot(i));
210 #else
211  if (activation(i)<0){
212  QdotResigned(i) = -Qdot(i);
213  }
214 #endif
215  }
216 
217  // Calculate the maximal torques
218  biorbd::rigidbody::GeneralizedTorque GeneralizedTorque(
219  torqueMax(activation,Q,QdotResigned));
220 
221  // Put the signs
222  for (unsigned int i=0; i<GeneralizedTorque.size(); ++i)
223  GeneralizedTorque(i) = GeneralizedTorque(i) * activation(i);
224 
225  return GeneralizedTorque;
226 }
227 
228 
229 std::pair<biorbd::rigidbody::GeneralizedTorque, biorbd::rigidbody::GeneralizedTorque>
233 {
234  biorbd::utils::Error::check(*m_isClose, "Close the actuator model before calling torqueMax");
235 
236  // Assuming that this is also a Joints type (via BiorbdModel)
237  const biorbd::rigidbody::Joints &model = dynamic_cast<biorbd::rigidbody::Joints &>(*this);
238 
239  std::pair<biorbd::rigidbody::GeneralizedTorque, biorbd::rigidbody::GeneralizedTorque> maxGeneralizedTorque_all =
241 
242  for (unsigned int i=0; i<model.nbDof(); ++i){
243  std::pair<std::shared_ptr<Actuator>, std::shared_ptr<Actuator>> GeneralizedTorque_tp(actuator(i));
244  for (unsigned p=0; p<2; ++p){
245  if (p==0) // First
246  if (std::dynamic_pointer_cast<ActuatorGauss3p> (GeneralizedTorque_tp.first))
247  maxGeneralizedTorque_all.first[i] = std::static_pointer_cast<ActuatorGauss3p> (GeneralizedTorque_tp.first)->torqueMax(Q, Qdot);
248  else if (std::dynamic_pointer_cast<ActuatorConstant> (GeneralizedTorque_tp.first))
249  maxGeneralizedTorque_all.first[i] = std::static_pointer_cast<ActuatorConstant> (GeneralizedTorque_tp.first)->torqueMax();
250  else if (std::dynamic_pointer_cast<ActuatorLinear> (GeneralizedTorque_tp.first))
251  maxGeneralizedTorque_all.first[i] = std::static_pointer_cast<ActuatorLinear> (GeneralizedTorque_tp.first)->torqueMax(Q);
252  else if (std::dynamic_pointer_cast<ActuatorGauss6p> (GeneralizedTorque_tp.first))
253  maxGeneralizedTorque_all.first[i] = std::static_pointer_cast<ActuatorGauss6p> (GeneralizedTorque_tp.first)->torqueMax(Q, Qdot);
254  else
255  biorbd::utils::Error::raise("Wrong type (should never get here because of previous safety)");
256  else // Second
257  if (std::dynamic_pointer_cast<ActuatorGauss3p> (GeneralizedTorque_tp.second))
258  maxGeneralizedTorque_all.second[i] = std::static_pointer_cast<ActuatorGauss3p> (GeneralizedTorque_tp.second)->torqueMax(Q, Qdot);
259  else if (std::dynamic_pointer_cast<ActuatorConstant> (GeneralizedTorque_tp.second))
260  maxGeneralizedTorque_all.second[i] = std::static_pointer_cast<ActuatorConstant> (GeneralizedTorque_tp.second)->torqueMax();
261  else if (std::dynamic_pointer_cast<ActuatorLinear> (GeneralizedTorque_tp.second))
262  maxGeneralizedTorque_all.second[i] = std::static_pointer_cast<ActuatorLinear> (GeneralizedTorque_tp.second)->torqueMax(Q);
263  else if (std::dynamic_pointer_cast<ActuatorGauss6p> (GeneralizedTorque_tp.second))
264  maxGeneralizedTorque_all.second[i] = std::static_pointer_cast<ActuatorGauss6p> (GeneralizedTorque_tp.second)->torqueMax(Q, Qdot);
265  else
266  biorbd::utils::Error::raise("Wrong type (should never get here because of previous safety)");
267  }
268  }
269 
270  return maxGeneralizedTorque_all;
271 }
272 
273 
275  const utils::Vector &activation,
278 {
279  biorbd::utils::Error::check(*m_isClose, "Close the actuator model before calling torqueMax");
280 
281  // Assuming that this is also a Joints type (via BiorbdModel)
282  const biorbd::rigidbody::Joints &model = dynamic_cast<biorbd::rigidbody::Joints &>(*this);
283 
284  biorbd::rigidbody::GeneralizedTorque maxGeneralizedTorque_all(model);
285 
286  for (unsigned int i=0; i<model.nbDof(); ++i){
287 #ifdef BIORBD_USE_CASADI_MATH
288  maxGeneralizedTorque_all[i] = casadi::MX::if_else(
289  casadi::MX::ge(activation(i, 0), 0),
290  getTorqueMaxDirection(actuator(i).first, Q, Qdot),
291  getTorqueMaxDirection(actuator(i).second, Q, Qdot));
292 #else
293  if (activation[i] >= 0) // First
294  maxGeneralizedTorque_all[i] = getTorqueMaxDirection(actuator(i).first, Q, Qdot);
295  else
296  maxGeneralizedTorque_all[i] = getTorqueMaxDirection(actuator(i).second, Q, Qdot);
297 #endif
298  }
299 
300  return maxGeneralizedTorque_all;
301 }
302 
304  const std::shared_ptr<biorbd::actuator::Actuator> actuator,
306  const biorbd::rigidbody::GeneralizedVelocity& Qdot) const
307 {
308  if (std::dynamic_pointer_cast<ActuatorGauss3p> (actuator))
309  return std::static_pointer_cast<ActuatorGauss3p> (actuator)->torqueMax(Q, Qdot);
310  else if (std::dynamic_pointer_cast<ActuatorConstant> (actuator))
311  return std::static_pointer_cast<ActuatorConstant> (actuator)->torqueMax();
312  else if (std::dynamic_pointer_cast<ActuatorLinear> (actuator))
313  return std::static_pointer_cast<ActuatorLinear> (actuator)->torqueMax(Q);
314  else if (std::dynamic_pointer_cast<ActuatorGauss6p> (actuator))
315  return std::static_pointer_cast<ActuatorGauss6p> (actuator)->torqueMax(Q, Qdot);
316  else
317  biorbd::utils::Error::raise("Wrong type (should never get here because of previous safety)");
318 
319 }
biorbd::actuator::Actuators
Class holder for a set of actuators.
Definition: Actuators.h:26
biorbd::actuator::Actuators::torque
biorbd::rigidbody::GeneralizedTorque torque(const biorbd::utils::Vector &activation, const biorbd::rigidbody::GeneralizedCoordinates &Q, const biorbd::rigidbody::GeneralizedVelocity &Qdot)
Return the generalized torque.
Definition: Actuators.cpp:198
biorbd::actuator::Actuator::type
biorbd::actuator::TYPE type() const
Return the type of the actuator.
Definition: Actuator.cpp:73
biorbd::utils::Vector
Wrapper of the Eigen VectorXd.
Definition: Vector.h:20
biorbd::actuator::Actuator
Class Actuator.
Definition: Actuator.h:20
biorbd::actuator::ActuatorConstant
Class ActuatorConstant is a joint actuator type which maximum is contant.
Definition: ActuatorConstant.h:14
biorbd::actuator::Actuators::Actuators
Actuators()
Construct actuators.
Definition: Actuators.cpp:16
biorbd::actuator::Actuators::m_isDofSet
std::shared_ptr< std::vector< bool > > m_isDofSet
If DoF all dof are set.
Definition: Actuators.h:123
biorbd::actuator::Actuators::~Actuators
virtual ~Actuators()
Destroy actuators class properly.
Definition: Actuators.cpp:34
biorbd::rigidbody::GeneralizedCoordinates
Class GeneralizedCoordinates.
Definition: GeneralizedCoordinates.h:15
biorbd::rigidbody::Joints::nbDof
unsigned int nbDof() const
Return the number of degrees of freedom (DoF)
Definition: Joints.cpp:87
biorbd::actuator::Actuators::addActuator
void addActuator(const biorbd::actuator::Actuator &a)
Add an actuator to the set of actuators.
Definition: Actuators.cpp:82
biorbd::actuator::Actuators::torqueMax
std::pair< biorbd::rigidbody::GeneralizedTorque, biorbd::rigidbody::GeneralizedTorque > torqueMax(const biorbd::rigidbody::GeneralizedCoordinates &Q, const biorbd::rigidbody::GeneralizedVelocity &Qdot)
Return two vectors of max torque (it is impossible to know if eccentric or concentric is required,...
Definition: Actuators.cpp:230
biorbd::actuator::ActuatorGauss3p
Class ActuatorGauss3p is a joint actuator type which maximum is 3 parameter gaussian (Gauss3p)
Definition: ActuatorGauss3p.h:20
biorbd::actuator::Actuators::actuator
const std::pair< std::shared_ptr< biorbd::actuator::Actuator >, std::shared_ptr< biorbd::actuator::Actuator > > & actuator(unsigned int dof)
Return a specific concentric/eccentric actuator.
Definition: Actuators.cpp:175
biorbd::actuator::Actuators::nbActuators
unsigned int nbActuators() const
Return the toal number of actuators.
Definition: Actuators.cpp:193
biorbd::utils::Error::raise
static void raise(const biorbd::utils::String &message)
Throw an error message.
Definition: Error.cpp:4
biorbd::rigidbody::Joints
This is the core of the musculoskeletal model in biorbd.
Definition: Joints.h:40
biorbd::actuator::Actuators::closeActuator
void closeActuator()
Indicate to biorbd to are done adding actuators, sanity checks are performed.
Definition: Actuators.cpp:156
biorbd::actuator::Actuators::getTorqueMaxDirection
biorbd::utils::Scalar getTorqueMaxDirection(const std::shared_ptr< Actuator > actuator, const rigidbody::GeneralizedCoordinates &Q, const rigidbody::GeneralizedVelocity &Qdot) const
getTorqueMaxDirection Get the max torque of a specific actuator (interface necessary because of CasAD...
Definition: Actuators.cpp:303
biorbd::actuator::Actuators::m_isClose
std::shared_ptr< bool > m_isClose
If the set is ready.
Definition: Actuators.h:124
biorbd::rigidbody::GeneralizedTorque
Class GeneralizedTorque.
Definition: GeneralizedTorque.h:15
biorbd::actuator::Actuator::direction
int direction() const
Return the direction of the actuator.
Definition: Actuator.cpp:68
biorbd::actuator::ActuatorGauss6p
Class ActuatorGauss6p is a joint actuator type which maximum is bimodal 6 parameter gaussian (Gauss6p...
Definition: ActuatorGauss6p.h:18
biorbd::utils::String
Wrapper around the std::string class with augmented functionality.
Definition: String.h:17
biorbd::actuator::Actuators::DeepCopy
void DeepCopy(const biorbd::actuator::Actuators &other)
Deep copy of the actuator holder from other actuator holder.
Definition: Actuators.cpp:39
biorbd::actuator::ActuatorLinear
Class ActuatorLinear is a joint actuator type that linearly evolves.
Definition: ActuatorLinear.h:18
biorbd::actuator::Actuator::index
unsigned int index() const
Return the index of the DoF associated with actuator.
Definition: Actuator.cpp:63
biorbd::rigidbody::GeneralizedVelocity
Class GeneralizedVelocity.
Definition: GeneralizedVelocity.h:15
biorbd::utils::Error::check
static void check(bool cond, const biorbd::utils::String &message)
Assert that raises the error message if false.
Definition: Error.cpp:10
biorbd::actuator::Actuators::m_all
std::shared_ptr< std::vector< std::pair< std::shared_ptr< biorbd::actuator::Actuator >, std::shared_ptr< biorbd::actuator::Actuator > > > > m_all
All the actuators reunited /pair (+ or -)
Definition: Actuators.h:122