rbdlsim/3rdparty/rbdl/tests/ImpulsesTests.cc

282 lines
8.7 KiB
C++

#include <UnitTest++.h>
#include <iostream>
#include "rbdl/Logging.h"
#include "rbdl/Model.h"
#include "rbdl/Constraints.h"
#include "rbdl/Dynamics.h"
#include "rbdl/Kinematics.h"
using namespace std;
using namespace RigidBodyDynamics;
using namespace RigidBodyDynamics::Math;
const double TEST_PREC = 1.0e-14;
struct ImpulsesFixture {
ImpulsesFixture () {
ClearLogOutput();
model = new Model;
model->gravity = Vector3d (0., -9.81, 0.);
// base body
base = Body (
1.,
Vector3d (0., 1., 0.),
Vector3d (1., 1., 1.)
);
joint_rotzyx = Joint (
SpatialVector (0., 0., 1., 0., 0., 0.),
SpatialVector (0., 1., 0., 0., 0., 0.),
SpatialVector (1., 0., 0., 0., 0., 0.)
);
base_id = model->AddBody (0, Xtrans (Vector3d (0., 0., 0.)), joint_rotzyx, base);
// child body (3 DoF)
child = Body (
1.,
Vector3d (0., 1., 0.),
Vector3d (1., 1., 1.)
);
child_id = model->AddBody (base_id, Xtrans (Vector3d (1., 0., 0.)), joint_rotzyx, child);
Q = VectorNd::Zero(model->dof_count);
QDot = VectorNd::Zero(model->dof_count);
QDDot = VectorNd::Zero(model->dof_count);
Tau = VectorNd::Zero(model->dof_count);
contact_body_id = child_id;
contact_point = Vector3d (0., 1., 0.);
contact_normal = Vector3d (0., 1., 0.);
ClearLogOutput();
}
~ImpulsesFixture () {
delete model;
}
Model *model;
unsigned int base_id, child_id;
Body base, child;
Joint joint_rotzyx;
VectorNd Q;
VectorNd QDot;
VectorNd QDDot;
VectorNd Tau;
unsigned int contact_body_id;
Vector3d contact_point;
Vector3d contact_normal;
ConstraintSet constraint_set;
};
TEST_FIXTURE(ImpulsesFixture, TestContactImpulse) {
constraint_set.AddContactConstraint(contact_body_id, contact_point, Vector3d (1., 0., 0.), NULL, 0.);
constraint_set.AddContactConstraint(contact_body_id, contact_point, Vector3d (0., 1., 0.), NULL, 0.);
constraint_set.AddContactConstraint(contact_body_id, contact_point, Vector3d (0., 0., 1.), NULL, 0.);
constraint_set.Bind (*model);
constraint_set.v_plus[0] = 0.;
constraint_set.v_plus[1] = 0.;
constraint_set.v_plus[2] = 0.;
QDot[0] = 0.1;
QDot[1] = -0.2;
QDot[2] = 0.1;
Vector3d point_velocity;
{
SUPPRESS_LOGGING;
point_velocity = CalcPointVelocity (*model, Q, QDot, contact_body_id, contact_point, true);
}
// cout << "Point Velocity = " << point_velocity << endl;
VectorNd qdot_post (QDot.size());
ComputeConstraintImpulsesDirect (*model, Q, QDot, constraint_set, qdot_post);
// cout << LogOutput.str() << endl;
// cout << "QdotPost = " << qdot_post << endl;
{
SUPPRESS_LOGGING;
point_velocity = CalcPointVelocity (*model, Q, qdot_post, contact_body_id, contact_point, true);
}
// cout << "Point Velocity = " << point_velocity << endl;
CHECK_ARRAY_CLOSE (Vector3d (0., 0., 0.).data(), point_velocity.data(), 3, TEST_PREC);
}
TEST_FIXTURE(ImpulsesFixture, TestContactImpulseRotated) {
constraint_set.AddContactConstraint(contact_body_id, contact_point, Vector3d (1., 0., 0.), NULL, 0.);
constraint_set.AddContactConstraint(contact_body_id, contact_point, Vector3d (0., 1., 0.), NULL, 0.);
constraint_set.AddContactConstraint(contact_body_id, contact_point, Vector3d (0., 0., 1.), NULL, 0.);
constraint_set.Bind (*model);
constraint_set.v_plus[0] = 0.;
constraint_set.v_plus[1] = 0.;
constraint_set.v_plus[2] = 0.;
Q[0] = 0.2;
Q[1] = -0.5;
Q[2] = 0.1;
Q[3] = -0.4;
Q[4] = -0.1;
Q[5] = 0.4;
QDot[0] = 0.1;
QDot[1] = -0.2;
QDot[2] = 0.1;
Vector3d point_velocity;
{
SUPPRESS_LOGGING;
point_velocity = CalcPointVelocity (*model, Q, QDot, contact_body_id, contact_point, true);
}
// cout << "Point Velocity = " << point_velocity << endl;
VectorNd qdot_post (QDot.size());
ComputeConstraintImpulsesDirect (*model, Q, QDot, constraint_set, qdot_post);
// cout << LogOutput.str() << endl;
// cout << "QdotPost = " << qdot_post << endl;
{
SUPPRESS_LOGGING;
point_velocity = CalcPointVelocity (*model, Q, qdot_post, contact_body_id, contact_point, true);
}
// cout << "Point Velocity = " << point_velocity << endl;
CHECK_ARRAY_CLOSE (Vector3d (0., 0., 0.).data(), point_velocity.data(), 3, TEST_PREC);
}
TEST_FIXTURE(ImpulsesFixture, TestContactImpulseRotatedCollisionVelocity) {
constraint_set.AddContactConstraint(contact_body_id, contact_point, Vector3d (1., 0., 0.), NULL, 1.);
constraint_set.AddContactConstraint(contact_body_id, contact_point, Vector3d (0., 1., 0.), NULL, 2.);
constraint_set.AddContactConstraint(contact_body_id, contact_point, Vector3d (0., 0., 1.), NULL, 3.);
constraint_set.Bind (*model);
constraint_set.v_plus[0] = 1.;
constraint_set.v_plus[1] = 2.;
constraint_set.v_plus[2] = 3.;
Q[0] = 0.2;
Q[1] = -0.5;
Q[2] = 0.1;
Q[3] = -0.4;
Q[4] = -0.1;
Q[5] = 0.4;
QDot[0] = 0.1;
QDot[1] = -0.2;
QDot[2] = 0.1;
Vector3d point_velocity;
{
SUPPRESS_LOGGING;
point_velocity = CalcPointVelocity (*model, Q, QDot, contact_body_id, contact_point, true);
}
// cout << "Point Velocity = " << point_velocity << endl;
VectorNd qdot_post (QDot.size());
ComputeConstraintImpulsesDirect (*model, Q, QDot, constraint_set, qdot_post);
// cout << LogOutput.str() << endl;
// cout << "QdotPost = " << qdot_post << endl;
{
SUPPRESS_LOGGING;
point_velocity = CalcPointVelocity (*model, Q, qdot_post, contact_body_id, contact_point, true);
}
// cout << "Point Velocity = " << point_velocity << endl;
CHECK_ARRAY_CLOSE (Vector3d (1., 2., 3.).data(), point_velocity.data(), 3, TEST_PREC);
}
TEST_FIXTURE(ImpulsesFixture, TestContactImpulseRangeSpaceSparse) {
Q[0] = 0.2;
Q[1] = -0.5;
Q[2] = 0.1;
Q[3] = -0.4;
Q[4] = -0.1;
Q[5] = 0.4;
QDot[0] = 0.1;
QDot[1] = -0.2;
QDot[2] = 0.1;
constraint_set.AddContactConstraint(contact_body_id, contact_point, Vector3d (1., 0., 0.), NULL, 1.);
constraint_set.AddContactConstraint(contact_body_id, contact_point, Vector3d (0., 1., 0.), NULL, 2.);
constraint_set.AddContactConstraint(contact_body_id, contact_point, Vector3d (0., 0., 1.), NULL, 3.);
constraint_set.Bind (*model);
constraint_set.v_plus[0] = 1.;
constraint_set.v_plus[1] = 2.;
constraint_set.v_plus[2] = 3.;
ConstraintSet constraint_set_rangespace;
constraint_set_rangespace = constraint_set.Copy();
constraint_set_rangespace.Bind (*model);
VectorNd qdot_post_direct (QDot.size());
ComputeConstraintImpulsesDirect (*model, Q, QDot, constraint_set, qdot_post_direct);
VectorNd qdot_post_rangespace (QDot.size());
ComputeConstraintImpulsesRangeSpaceSparse (*model, Q, QDot, constraint_set_rangespace, qdot_post_rangespace);
Vector3d point_velocity_direct = CalcPointVelocity (*model, Q, qdot_post_direct, contact_body_id, contact_point, true);
Vector3d point_velocity_rangespace = CalcPointVelocity (*model, Q, qdot_post_rangespace, contact_body_id, contact_point, true);
CHECK_ARRAY_CLOSE (qdot_post_direct.data(), qdot_post_rangespace.data(), qdot_post_direct.rows(), TEST_PREC);
CHECK_ARRAY_CLOSE (Vector3d (1., 2., 3.).data(), point_velocity_direct.data(), 3, TEST_PREC);
CHECK_ARRAY_CLOSE (Vector3d (1., 2., 3.).data(), point_velocity_rangespace.data(), 3, TEST_PREC);
}
TEST_FIXTURE(ImpulsesFixture, TestContactImpulseNullSpace) {
Q[0] = 0.2;
Q[1] = -0.5;
Q[2] = 0.1;
Q[3] = -0.4;
Q[4] = -0.1;
Q[5] = 0.4;
QDot[0] = 0.1;
QDot[1] = -0.2;
QDot[2] = 0.1;
constraint_set.AddContactConstraint(contact_body_id, contact_point, Vector3d (1., 0., 0.), NULL, 1.);
constraint_set.AddContactConstraint(contact_body_id, contact_point, Vector3d (0., 1., 0.), NULL, 2.);
constraint_set.AddContactConstraint(contact_body_id, contact_point, Vector3d (0., 0., 1.), NULL, 3.);
constraint_set.Bind (*model);
constraint_set.v_plus[0] = 1.;
constraint_set.v_plus[1] = 2.;
constraint_set.v_plus[2] = 3.;
ConstraintSet constraint_set_nullspace;
constraint_set_nullspace = constraint_set.Copy();
constraint_set_nullspace.Bind (*model);
VectorNd qdot_post_direct (QDot.size());
ComputeConstraintImpulsesDirect (*model, Q, QDot, constraint_set, qdot_post_direct);
VectorNd qdot_post_nullspace (QDot.size());
ComputeConstraintImpulsesNullSpace (*model, Q, QDot, constraint_set, qdot_post_nullspace);
Vector3d point_velocity_direct = CalcPointVelocity (*model, Q, qdot_post_direct, contact_body_id, contact_point, true);
Vector3d point_velocity_nullspace = CalcPointVelocity (*model, Q, qdot_post_nullspace, contact_body_id, contact_point, true);
CHECK_ARRAY_CLOSE (qdot_post_direct.data(), qdot_post_nullspace.data(), qdot_post_direct.rows(), TEST_PREC);
CHECK_ARRAY_CLOSE (Vector3d (1., 2., 3.).data(), point_velocity_direct.data(), 3, TEST_PREC);
CHECK_ARRAY_CLOSE (Vector3d (1., 2., 3.).data(), point_velocity_nullspace.data(), 3, TEST_PREC);
}