RdlTwoLegModelTests.cpp
Go to the documentation of this file.
1 #include <gtest/gtest.h>
2 
3 #include "UnitTestUtils.hpp"
4 
5 #include <iostream>
6 
7 #include "rdl_dynamics/Model.h"
11 
12 using namespace std;
13 using namespace RobotDynamics;
14 using namespace RobotDynamics::Math;
15 
16 const double TEST_PREC = 1.0e-13;
17 
18 struct RdlTwoLegModelTests : public testing::Test
19 {
20 };
21 
23 
25 
26 Joint joint_txtyrz(SpatialVector(0., 0., 0., 1., 0., 0.), SpatialVector(0., 0., 0., 0., 1., 0.), SpatialVector(0., 0., 1., 0., 0., 0.));
27 Joint joint_rot_z(SpatialVector(0., 0., 1., 0., 0., 0.));
28 
33 
38 
40 {
43 };
44 
46 {
57 };
58 
60 {
80 };
81 
83 {
91 };
92 
94 {
101 };
102 
103 const double ModelMass = 73.;
104 const double ModelHeight = 1.741;
105 
106 // absolute lengths!
107 double segment_lengths[SegmentLengthsNameLast] = { 0.4346, 0.4222, 0.4340, 0.0317, 0.2581 };
108 
110 {
115 };
116 
117 Vector3d joint_location[JointLocationLast] = { Vector3d(0., 0., 0.), Vector3d(0., -0.2425 * ModelHeight, 0.), Vector3d(0., -0.2529 * ModelHeight, 0.) };
118 
120 {
126 };
127 
128 double segment_mass[SegmentMassLast] = { 0.4346 * ModelMass, 0.1416 * ModelMass, 0.0433 * ModelMass, 0.0137 * ModelMass };
129 
131 {
137 };
138 
139 Vector3d com_position[COMNameLast] = { Vector3d(0., 0.3469 * ModelHeight, 0.), Vector3d(0., 0.2425 * ModelHeight, 0.), Vector3d(0., 0.2529 * ModelHeight, 0.),
140  Vector3d(0.0182 * ModelHeight, 0., 0.) };
141 
143 {
149 };
150 
151 Vector3d rgyration[RGyrationLast] = { Vector3d(0.1981, 0.1021, 0.1848), Vector3d(0.1389, 0.0629, 0.1389), Vector3d(0.1123, 0.0454, 0.1096),
152  Vector3d(0.0081, 0.0039, 0.0078) };
153 
154 Vector3d heel_point(0., 0., 0.);
155 Vector3d medial_point(0., 0., 0.);
156 
157 void init_model(Model* model)
158 {
159  assert(model);
160 
161  constraint_set_right = ConstraintSet();
162  constraint_set_left = ConstraintSet();
163  constraint_set_left_flat = ConstraintSet();
164  constraint_set_both = ConstraintSet();
165 
166  model->gravity = SpatialVector(0., 0., 0., 0., -9.81, 0.);
167 
168  // hip
169  hip_body = Body(segment_mass[SegmentMassHip], com_position[COMHip], rgyration[RGyrationHip]);
170 
171  // lateral right
172  upper_leg_right_body = Body(segment_mass[SegmentMassThigh], com_position[COMThigh], rgyration[RGyrationThigh]);
173  lower_leg_right_body = Body(segment_mass[SegmentMassShank], com_position[COMShank], rgyration[RGyrationShank]);
174  foot_right_body = Body(segment_mass[SegmentMassFoot], com_position[COMFoot], rgyration[RGyrationFoot]);
175 
176  // lateral left
177  upper_leg_left_body = Body(segment_mass[SegmentMassThigh], com_position[COMThigh], rgyration[RGyrationThigh]);
178  lower_leg_left_body = Body(segment_mass[SegmentMassShank], com_position[COMShank], rgyration[RGyrationShank]);
179  foot_left_body = Body(segment_mass[SegmentMassFoot], com_position[COMFoot], rgyration[RGyrationFoot]);
180 
181  // add hip to the model (planar, 3 DOF)
182  hip_id = model->addBody(0, Xtrans(Vector3d(0., 0., 0.)), joint_txtyrz, hip_body);
183 
184  //
185  // right leg
186  //
187 
188  unsigned int temp_id = 0;
189 
190  // add right upper leg
191  temp_id = model->addBody(hip_id, Xtrans(Vector3d(0., 0., 0.)), joint_rot_z, upper_leg_right_body);
192  upper_leg_right_id = temp_id;
193 
194  // add the right lower leg (only one DOF)
195  temp_id = model->addBody(temp_id, Xtrans(joint_location[JointLocationKnee]), joint_rot_z, lower_leg_right_body);
196  lower_leg_right_id = temp_id;
197 
198  // add the right foot (1 DOF)
199  temp_id = model->addBody(temp_id, Xtrans(joint_location[JointLocationAnkle]), joint_rot_z, foot_right_body);
200  foot_right_id = temp_id;
201 
202  //
203  // left leg
204  //
205 
206  // add left upper leg
207  temp_id = model->addBody(hip_id, Xtrans(Vector3d(0., 0., 0.)), joint_rot_z, upper_leg_left_body);
208  upper_leg_left_id = temp_id;
209 
210  // add the left lower leg (only one DOF)
211  temp_id = model->addBody(temp_id, Xtrans(joint_location[JointLocationKnee]), joint_rot_z, lower_leg_left_body);
212  lower_leg_left_id = temp_id;
213 
214  // add the left foot (1 DOF)
215  temp_id = model->addBody(temp_id, Xtrans(joint_location[JointLocationAnkle]), joint_rot_z, foot_left_body);
216  foot_left_id = temp_id;
217 
218  // cerr << "--- model created (" << model->dof_count << " DOF) ---" << endl;
219 
220  // contact data
221 
222  // the contact points for heel and toe
223  heel_point.set(-0.05, -0.0317, 0.);
224  medial_point.set(-0.05, -0.0317 + segment_lengths[SegmentLengthsFoot], 0.);
225 
226  constraint_set_right.addConstraint(foot_right_id, heel_point, Vector3d(1., 0., 0.), "right_heel_x");
227  constraint_set_right.addConstraint(foot_right_id, heel_point, Vector3d(0., 1., 0.), "right_heel_y");
228 
229  constraint_set_left.addConstraint(foot_left_id, heel_point, Vector3d(1., 0., 0.), "left_heel_x");
230  constraint_set_left.addConstraint(foot_left_id, heel_point, Vector3d(0., 1., 0.), "left_heel_y");
231 
232  constraint_set_both.addConstraint(foot_right_id, heel_point, Vector3d(1., 0., 0.), "right_heel_x");
233  constraint_set_both.addConstraint(foot_right_id, heel_point, Vector3d(0., 1., 0.), "right_heel_y");
234  constraint_set_both.addConstraint(foot_right_id, heel_point, Vector3d(0., 0., 1.), "right_heel_z");
235 
236  constraint_set_both.addConstraint(foot_left_id, heel_point, Vector3d(1., 0., 0.), "left_heel_x");
237  constraint_set_both.addConstraint(foot_left_id, heel_point, Vector3d(0., 1., 0.), "left_heel_y");
238  constraint_set_both.addConstraint(foot_left_id, heel_point, Vector3d(0., 0., 1.), "left_heel_z");
239 
240  constraint_set_right.bind(*model);
241  constraint_set_left.bind(*model);
242  constraint_set_both.bind(*model);
243 }
244 
245 template <typename T>
246 void copy_values(T* dest, const T* src, size_t count)
247 {
248  memcpy(dest, src, count * sizeof(T));
249 }
250 
251 TEST(RdlTwoLegModelTests, TestForwardDynamicsContactsDirectFootmodel)
252 {
253  Model* model = new Model;
254 
255  init_model(model);
256 
257  Q.resize(model->dof_count);
258  QDot.resize(model->dof_count);
259  QDDot.resize(model->dof_count);
260  Tau.resize(model->dof_count);
261 
262  Q[0] = -0.2;
263  Q[1] = 0.9;
264  Q[2] = 0;
265  Q[3] = -0.15;
266  Q[4] = -0.15;
267  Q[5] = 0.1;
268  Q[6] = 0.15;
269  Q[7] = -0.15;
270  Q[8] = 0;
271 
272  QDot.setZero();
273 
274  Tau[0] = 0;
275  Tau[1] = 0;
276  Tau[2] = 0;
277  Tau[3] = 1;
278  Tau[4] = 1;
279  Tau[5] = 1;
280  Tau[6] = 1;
281  Tau[7] = 1;
282  Tau[8] = 1;
283 
284  Vector3d contact_accel_left;
285  Vector3d contact_vel_left;
286  Vector3d contact_force = Vector3d::Zero();
287 
288  VectorNd QDDot_aba(QDDot);
289  VectorNd QDDot_lag(QDDot);
290  forwardDynamics(*model, Q, QDot, Tau, QDDot_aba);
291  RobotDynamics::Math::MatrixNd H = RobotDynamics::Math::MatrixNd::Zero(model->qdot_size, model->qdot_size);
292  RobotDynamics::Math::VectorNd C = RobotDynamics::Math::VectorNd::Zero(model->qdot_size);
293  forwardDynamicsLagrangian(*model, Q, QDot, Tau, QDDot_lag, H, C);
294 
295  unsigned int body_id = constraint_set_left.body[0];
296  Vector3d contact_point = constraint_set_left.point[0];
297 
298  MatrixNd G(3, Q.size());
299  calcPointJacobian(*model, Q, body_id, contact_point, G, true);
300 
301  forwardDynamicsContactsDirect(*model, Q, QDot, Tau, constraint_set_left, QDDot);
302 
303  contact_force[0] = constraint_set_left.force[0];
304  contact_force[1] = constraint_set_left.force[1];
305 
306  EXPECT_EQ(body_id, foot_left_id);
307  EXPECT_EQ(contact_point, heel_point);
308 
309  contact_accel_left = calcPointAcceleration(*model, Q, QDot, QDDot, foot_left_id, heel_point);
310  contact_vel_left = calcPointVelocity(*model, Q, QDot, foot_left_id, heel_point);
311 
312  EXPECT_TRUE(unit_test_utils::checkVector3dEpsilonClose(Vector3d(0., 0., 0.), contact_accel_left, TEST_PREC));
313 
314  delete model;
315 }
316 
317 TEST(RdlTwoLegModelTests, TestClearContactsInertiaMatrix)
318 {
319  Model* model = new Model;
320 
321  init_model(model);
322 
323  Q.resize(model->dof_count);
324  QDot.resize(model->dof_count);
325  QDDot.resize(model->dof_count);
326  Tau.resize(model->dof_count);
327 
328  Q[0] = -0.2;
329  Q[1] = 0.9;
330  Q[2] = 0;
331  Q[3] = -0.15;
332  Q[4] = -0.15;
333  Q[5] = 0.1;
334  Q[6] = 0.15;
335  Q[7] = -0.15;
336  Q[8] = 0;
337 
338  QDot.setZero();
339 
340  Tau[0] = 0;
341  Tau[1] = 0;
342  Tau[2] = 0;
343  Tau[3] = 1;
344  Tau[4] = 1;
345  Tau[5] = 1;
346  Tau[6] = 1;
347  Tau[7] = 1;
348  Tau[8] = 1;
349 
350  VectorNd QDDot_aba(QDDot);
351  VectorNd QDDot_lag(QDDot);
352 
353  // initialize matrix with erroneous values
354  constraint_set_right.bound = false;
355  constraint_set_right.H = MatrixNd::Zero(model->dof_count, model->dof_count);
356  for (unsigned int i = 0; i < model->dof_count; i++)
357  {
358  for (unsigned int j = 0; j < model->dof_count; j++)
359  {
360  constraint_set_right.H(i, j) = 1.234;
361  }
362  }
363 
364  constraint_set_right.bind(*model);
365 
366  forwardDynamicsContactsDirect(*model, Q, QDot, Tau, constraint_set_right, QDDot_lag);
367  forwardDynamicsContactsKokkevis(*model, Q, QDot, Tau, constraint_set_right, QDDot_aba);
368 
369  EXPECT_TRUE(unit_test_utils::checkVectorNdEpsilonClose(QDDot_lag, QDDot_aba, TEST_PREC * QDDot_lag.norm()));
370 
371  delete model;
372 }
373 
374 int main(int argc, char** argv)
375 {
376  ::testing::InitGoogleTest(&argc, argv);
377  return RUN_ALL_TESTS();
378 }
Joint joint_rot_z(SpatialVector(0., 0., 1., 0., 0., 0.))
static bool checkVectorNdEpsilonClose(const RobotDynamics::Math::VectorNd &v1, const RobotDynamics::Math::VectorNd &v2, const double epsilon)
const double ModelMass
void calcPointJacobian(Model &model, const Math::VectorNd &Q, unsigned int body_id, const Math::Vector3d &point_position, Math::MatrixNd &G, bool update_kinematics=true)
Computes the 3D point jacobian for a point on a body.
Definition: Kinematics.cc:510
TEST(RdlTwoLegModelTests, TestForwardDynamicsContactsDirectFootmodel)
unsigned int upper_leg_left_id
Describes all properties of a single body.
Definition: Body.h:30
VectorNd Tau
ConstraintSet constraint_set_both
void init_model(Model *model)
unsigned int lower_leg_right_id
unsigned int foot_left_id
VectorNd QDDot
bool bound
Whether the constraint set was bound to a model (mandatory!).
Definition: Contacts.h:233
ConstraintSet constraint_set_right
ConstraintSet constraint_set_left_flat
VectorNd QDot
SpatialTransform Xtrans(const Vector3d &r)
Get pure translation transform.
VectorNd Q
unsigned int addConstraint(unsigned int body_id, const Math::Vector3d &body_point, const Math::Vector3d &world_normal, const char *constraint_name=NULL, double normal_acceleration=0.)
Adds a constraint to the constraint set.
Definition: Contacts.cc:27
std::vector< Math::Vector3d > point
Definition: Contacts.h:237
Body lower_leg_left_body
Math::FrameVector calcPointAcceleration(Model &model, const Math::VectorNd &Q, const Math::VectorNd &QDot, const Math::VectorNd &QDDot, unsigned int body_id, const Math::Vector3d &point_position, bool update_kinematics=true)
Computes the linear acceleration of a point on a body.
Definition: Kinematics.cc:1593
int main(int argc, char **argv)
Math::MotionVector gravity
the cartesian vector of the gravity
Definition: Model.h:196
Body upper_leg_left_body
unsigned int hip_id
Vector3d heel_point(0., 0., 0.)
Body lower_leg_right_body
unsigned int addBody(const unsigned int parent_id, const Math::SpatialTransform &joint_frame, const Joint &joint, const Body &body, std::string body_name="")
Connects a given body to the model.
Definition: Model.cc:271
Body foot_right_body
void forwardDynamicsContactsDirect(Model &model, const Math::VectorNd &Q, const Math::VectorNd &QDot, const Math::VectorNd &Tau, ConstraintSet &CS, Math::VectorNd &QDDot)
Computes forward dynamics with contact by constructing and solving the full lagrangian equation...
Definition: Contacts.cc:343
Math::FrameVector calcPointVelocity(Model &model, const Math::VectorNd &Q, const Math::VectorNd &QDot, unsigned int body_id, const Math::Vector3d &point_position, bool update_kinematics=true)
Computes the velocity of a point on a body.
Definition: Kinematics.cc:1422
Structure that contains both constraint information and workspace memory.
Definition: Contacts.h:168
unsigned int upper_leg_right_id
void copy_values(T *dest, const T *src, size_t count)
std::vector< unsigned int > body
Definition: Contacts.h:236
Describes a joint relative to the predecessor body.
Definition: Joint.h:228
Vector3d joint_location[JointLocationLast]
const double TEST_PREC
SegmentLengthsNames
Eigen::VectorXd VectorNd
Definition: rdl_eigenmath.h:25
unsigned int lower_leg_left_id
Vector3d medial_point(0., 0., 0.)
ConstraintSet constraint_set_left
Body hip_body
unsigned int foot_right_id
Joint joint_txtyrz(SpatialVector(0., 0., 0., 1., 0., 0.), SpatialVector(0., 0., 0., 0., 1., 0.), SpatialVector(0., 0., 1., 0., 0., 0.))
double segment_mass[SegmentMassLast]
Contains all information about the rigid body model.
Definition: Model.h:121
bool bind(const Model &model)
Initializes and allocates memory for the constraint set.
Definition: Contacts.cc:62
Math types such as vectors and matrices and utility functions.
Definition: ForceVector.hpp:21
Eigen::MatrixXd MatrixNd
Definition: rdl_eigenmath.h:26
void set(const Eigen::Vector3d &v)
Definition: rdl_eigenmath.h:83
double segment_lengths[SegmentLengthsNameLast]
static bool checkVector3dEpsilonClose(const RobotDynamics::Math::Vector3d &v1, const RobotDynamics::Math::Vector3d &v2, const double epsilon)
Vector3d com_position[COMNameLast]
void forwardDynamics(Model &model, const Math::VectorNd &Q, const Math::VectorNd &QDot, const Math::VectorNd &Tau, Math::VectorNd &QDDot, Math::SpatialForceV *f_ext=nullptr, bool update_kinematics=true)
Computes forward dynamics with the Articulated Body Algorithm.
Definition: Dynamics.cc:455
Body foot_left_body
void forwardDynamicsLagrangian(Model &model, const Math::VectorNd &Q, const Math::VectorNd &QDot, const Math::VectorNd &Tau, Math::VectorNd &QDDot, Math::MatrixNd &H, Math::VectorNd &C, Math::LinearSolver linear_solver=Math::LinearSolverColPivHouseholderQR, Math::SpatialForceV *f_ext=nullptr, bool update_kinematics=true)
Computes forward dynamics by building and solving the full Lagrangian equation.
Definition: Dynamics.cc:579
unsigned int dof_count
number of degrees of freedoms of the model
Definition: Model.h:169
Namespace for all structures of the RobotDynamics library.
Definition: Body.h:21
const double ModelHeight
Body upper_leg_right_body
Math::MatrixNd H
Workspace for the joint space inertia matrix.
Definition: Contacts.h:257
unsigned int qdot_size
The size of the.
Definition: Model.h:187
void forwardDynamicsContactsKokkevis(Model &model, const Math::VectorNd &Q, const Math::VectorNd &QDot, const Math::VectorNd &Tau, ConstraintSet &CS, Math::VectorNd &QDDot)
Computes forward dynamics that accounts for active contacts in ConstraintSet.
Definition: Contacts.cc:682
Vector3d rgyration[RGyrationLast]


rdl_dynamics
Author(s):
autogenerated on Tue Apr 20 2021 02:25:28