本文整理汇总了C++中MultibodySystem::realize方法的典型用法代码示例。如果您正苦于以下问题:C++ MultibodySystem::realize方法的具体用法?C++ MultibodySystem::realize怎么用?C++ MultibodySystem::realize使用的例子?那么, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类MultibodySystem
的用法示例。
在下文中一共展示了MultibodySystem::realize方法的15个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: testCompositeInertia
void testCompositeInertia() {
MultibodySystem mbs;
SimbodyMatterSubsystem pend(mbs);
Body::Rigid pointMass(MassProperties(3, Vec3(0), Inertia(0)));
// Point mass at x=1.5 rotating about (0,0,0).
MobilizedBody::Pin
body1( pend.Ground(), Transform(),
pointMass, Vec3(1.5,0,0));
const MobilizedBodyIndex body1x = body1.getMobilizedBodyIndex();
// A second body 2 units further along x, rotating about the
// first point mass origin.
MobilizedBody::Pin
body2( body1, Transform(),
pointMass, Vec3(2,0,0));
const MobilizedBodyIndex body2x = body2.getMobilizedBodyIndex();
State state = mbs.realizeTopology();
mbs.realize(state, Stage::Position);
Array_<SpatialInertia, MobilizedBodyIndex> R(pend.getNumBodies());
pend.calcCompositeBodyInertias(state, R);
// Calculate expected inertias about the joint axes.
Real expInertia2 = body2.getBodyMassProperties(state).getMass()*square(2);
Real expInertia1 = body1.getBodyMassProperties(state).getMass()*square(1.5)
+ body2.getBodyMassProperties(state).getMass()*square(3.5);
// Should be able to recover these inertias by projecting the composite
// body inertias onto the joint axes using H matrices.
const SpatialVec H1 = body1.getHCol(state, MobilizerUIndex(0));
const SpatialVec H2 = body2.getHCol(state, MobilizerUIndex(0));
SimTK_TEST_EQ(~H2*(R[body2x]*H2), expInertia2);
SimTK_TEST_EQ(~H1*(R[body1x]*H1), expInertia1);
// This should force realization of the composite body inertias.
SpatialInertia cbi = pend.getCompositeBodyInertia(state, body1);
body2.setAngle(state, Pi/4);
// This is not allowed until Position stage.
SimTK_TEST_MUST_THROW(pend.getCompositeBodyInertia(state, body1));
mbs.realize(state, Stage::Position);
// Now it should be OK.
cbi = pend.getCompositeBodyInertia(state, body1);
mbs.realize(state, Stage::Acceleration);
//cout << "udots=" << state.getUDot() << endl;
body1.setRate(state, 27);
mbs.realize(state, Stage::Acceleration);
//cout << "udots=" << state.getUDot() << endl;
}
示例2: createState
void createState(MultibodySystem& system, State& state, const Vector& qOverride=Vector()) {
system.realizeTopology();
state = system.getDefaultState();
Random::Uniform random;
for (int i = 0; i < state.getNY(); ++i)
state.updY()[i] = random.getValue();
if (qOverride.size())
state.updQ() = qOverride;
system.realize(state, Stage::Velocity);
Vector dummy;
system.project(state, ConstraintTol);
system.realize(state, Stage::Acceleration);
}
示例3: createState
void createState(MultibodySystem& system, State& state, const Vector& y=Vector()) {
system.realizeTopology();
state = system.getDefaultState();
if (y.size() > 0)
state.updY() = y;
else {
Random::Uniform random;
for (int i = 0; i < state.getNY(); ++i)
state.updY()[i] = random.getValue();
}
system.realize(state, Stage::Velocity);
// Solve to tight tolerance here
system.project(state, 1e-12);
system.realize(state, Stage::Acceleration);
}
示例4: testSpeedCoupler2
void testSpeedCoupler2() {
// Create a system involving a constraint that affects three different
// bodies.
MultibodySystem system;
SimbodyMatterSubsystem matter(system);
createGimbalSystem(system);
MobilizedBody& first = matter.updMobilizedBody(MobilizedBodyIndex(1));
std::vector<MobilizedBodyIndex> bodies(3);
std::vector<MobilizerUIndex> speeds(3);
bodies[0] = MobilizedBodyIndex(1);
bodies[1] = MobilizedBodyIndex(3);
bodies[2] = MobilizedBodyIndex(5);
speeds[0] = MobilizerUIndex(0);
speeds[1] = MobilizerUIndex(0);
speeds[2] = MobilizerUIndex(1);
Function* function = new CompoundFunction();
Constraint::SpeedCoupler coupler(matter, function, bodies, speeds);
State state;
createState(system, state);
// Make sure the constraint is satisfied.
Vector args(function->getArgumentSize());
for (int i = 0; i < args.size(); ++i)
args[i] = matter.getMobilizedBody(bodies[i]).getOneU(state, speeds[i]);
SimTK_TEST_EQ(0.0, function->calcValue(args));
// Simulate it and make sure the constraint is working correctly and
// energy is being conserved. This should be workless and power should
// always be zero (to the extent that the constraint is satisfied).
Real energy0 = system.calcEnergy(state);
RungeKuttaMersonIntegrator integ(system);
integ.setAccuracy(1e-6);
integ.setReturnEveryInternalStep(true);
integ.initialize(state);
while (integ.getTime() < 10.0) {
integ.stepTo(10.0);
const State& istate = integ.getState();
system.realize(istate, Stage::Acceleration);
const Real energy = system.calcEnergy(istate);
const Real power = coupler.calcPower(istate);
for (int i = 0; i < args.size(); ++i)
args[i] = matter.getMobilizedBody(bodies[i]).getOneU(istate, speeds[i]);
SimTK_TEST_EQ_TOL(0.0, function->calcValue(args),
integ.getConstraintToleranceInUse());
SimTK_TEST_EQ_TOL(0.0, power, 10*integ.getConstraintToleranceInUse());
// Energy conservation depends on global integration accuracy;
// accuracy returned here is local so we'll fudge at 10X.
const Real etol = 10*integ.getAccuracyInUse()
*std::max(std::abs(energy), std::abs(energy0));
SimTK_TEST_EQ_TOL(energy0, energy, etol);
}
}
示例5: testWeld
void testWeld() {
MultibodySystem system;
SimbodyMatterSubsystem matter(system);
GeneralForceSubsystem forces(system);
Force::UniformGravity gravity(forces, matter, Vec3(0, -1, 0));
Body::Rigid body(MassProperties(1.0, Vec3(0), Inertia(1)));
// Create two pendulums, each with two welded bodies. One uses a Weld MobilizedBody,
// and the other uses a Weld constraint.
Transform inboard(Vec3(0.1, 0.5, -1));
Transform outboard(Vec3(0.2, -0.2, 0));
MobilizedBody::Ball p1(matter.updGround(), Vec3(0), body, Vec3(0, 1, 0));
MobilizedBody::Ball p2(matter.updGround(), Vec3(0), body, Vec3(0, 1, 0));
MobilizedBody::Weld c1(p1, inboard, body, outboard);
MobilizedBody::Free c2(p2, inboard, body, outboard);
Constraint::Weld constraint(p2, inboard, c2, outboard);
// It is not a general test unless the Weld mobilizer has children!
MobilizedBody::Pin wchild1(c1, inboard, body, outboard);
MobilizedBody::Pin wchild2(c2, inboard, body, outboard);
Force::MobilityLinearSpring(forces, wchild1, 0, 1000, 0);
Force::MobilityLinearSpring(forces, wchild2, 0, 1000, 0);
State state = system.realizeTopology();
p1.setU(state, Vec3(1, 2, 3));
p2.setU(state, Vec3(1, 2, 3));
system.realize(state, Stage::Velocity);
system.project(state, 1e-10);
SimTK_TEST_EQ(c1.getBodyTransform(state), c2.getBodyTransform(state));
SimTK_TEST_EQ(c1.getBodyVelocity(state), c2.getBodyVelocity(state));
// Simulate it and see if both pendulums behave identically.
RungeKuttaMersonIntegrator integ(system);
TimeStepper ts(system, integ);
ts.initialize(state);
ts.stepTo(5);
system.realize(integ.getState(), Stage::Velocity);
SimTK_TEST_EQ_TOL(c1.getBodyTransform(integ.getState()),
c2.getBodyTransform(integ.getState()), 1e-10);
SimTK_TEST_EQ_TOL(c1.getBodyVelocity(integ.getState()),
c2.getBodyVelocity(integ.getState()), 1e-10);
}
示例6: testPrescribedMotion1
void testPrescribedMotion1() {
// Create a system requiring simple linear motion of one Q. This
// may require that the constraint do work.
// (The way the cylinder system is structured it only takes work to
// keep body one at a uniform velocity; the rest are in free fall.)
MultibodySystem system;
SimbodyMatterSubsystem matter(system);
createCylinderSystem(system);
MobilizedBodyIndex body = MobilizedBodyIndex(1);
MobilizerQIndex coordinate = MobilizerQIndex(1);
Vector coefficients(2);
coefficients[0] = 0.1;
coefficients[1] = 0.0;
Function* function = new Function::Linear(coefficients);
Constraint::PrescribedMotion constraint(matter, function, body, coordinate);
PowerMeasure<Real> powMeas(matter, constraint);
Measure::Zero zeroMeas(matter);
Measure::Integrate workMeas(matter, powMeas, zeroMeas);
State state;
createState(system, state);
workMeas.setValue(state, 0); // override createState
// Make sure the constraint is satisfied.
Vector args(1, state.getTime());
SimTK_TEST_EQ(function->calcValue(args),
matter.getMobilizedBody(body).getOneQ(state, coordinate));
// Simulate it and make sure the constraint is working correctly.
const Real energy0 = system.calcEnergy(state);
RungeKuttaMersonIntegrator integ(system);
integ.setReturnEveryInternalStep(true);
integ.initialize(state);
while (integ.getTime() < 10.0) {
integ.stepTo(10.0);
const State& istate = integ.getState();
system.realize(istate, Stage::Acceleration);
const Real energy = system.calcEnergy(istate);
const Real power = powMeas.getValue(istate);
const Real work = workMeas.getValue(istate);
Vector args(1, istate.getTime());
const Real q = matter.getMobilizedBody(body).getOneQ(istate, coordinate);
SimTK_TEST_EQ_TOL(function->calcValue(args), q,
integ.getConstraintToleranceInUse());
// Energy conservation depends on global integration accuracy;
// accuracy returned here is local so we'll fudge at 10X.
const Real etol = 10*integ.getAccuracyInUse()
*std::max(std::abs(energy-work), std::abs(energy0));
SimTK_TEST_EQ_TOL(energy0, energy-work, etol)
}
}
示例7: testConstraintForces
void testConstraintForces() {
// Weld one body to ground, push on it, verify that it reacts to match the load.
MultibodySystem system;
SimbodyMatterSubsystem matter(system);
GeneralForceSubsystem forces(system);
Body::Rigid body(MassProperties(1.0, Vec3(0), Inertia(1)));
MobilizedBody::Weld welded(matter.Ground(), Transform(),
body, Transform());
MobilizedBody::Free loose(matter.Ground(), Transform(),
body, Transform());
Constraint::Weld glue(matter.Ground(), Transform(),
loose, Transform());
// Apply forces to the body welded straight to ground.
Force::ConstantForce(forces, welded, Vec3(0,0,0), Vec3(1,2,3));
Force::ConstantTorque(forces, welded, Vec3(20,30,40));
// Apply the same forces to the "free" body which is welded by constraint.
Force::ConstantForce(forces, loose, Vec3(0,0,0), Vec3(1,2,3));
Force::ConstantTorque(forces, loose, Vec3(20,30,40));
State state = system.realizeTopology();
system.realize(state, Stage::Acceleration);
Vector_<SpatialVec> mobilizerReactions;
matter.calcMobilizerReactionForces(state, mobilizerReactions);
//NOT IMPLEMENTED YET:
//cout << "Weld constraint reaction on Ground: " << glue.getWeldReactionOnBody1(state) << endl;
//cout << "Weld constraint reaction on Body: " << glue.getWeldReactionOnBody2(state) << endl;
// Note that constraint forces have opposite sign to applied forces, because
// we calculate the multiplier lambda from M udot + ~G lambda = f_applied. We'll negate
// the calculated multipliers to turn these into applied forces.
const Vector mults = -state.getMultipliers();
Vector_<SpatialVec> constraintForces;
Vector mobilityForces;
matter.calcConstraintForcesFromMultipliers(state, mults,
constraintForces, mobilityForces);
MACHINE_TEST(constraintForces[loose.getMobilizedBodyIndex()],
mobilizerReactions[welded.getMobilizedBodyIndex()]);
// This returns just the forces on the weld's two bodies: in this
// case Ground and "loose", in that order.
Vector_<SpatialVec> glueForces =
glue.getConstrainedBodyForcesAsVector(state);
MACHINE_TEST(-glueForces[1], // watch the sign!
mobilizerReactions[welded.getMobilizedBodyIndex()]);
}
示例8: testCalculationMethods
void testCalculationMethods() {
// Create a system with two bodies.
MultibodySystem system;
SimbodyMatterSubsystem matter(system);
GeneralForceSubsystem forces(system);
Body::Rigid body(MassProperties(1.0, Vec3(0), Inertia(1)));
MobilizedBody::Free b1(matter.Ground(), body);
MobilizedBody::Free b2(matter.Ground(), body);
// Set all the state variables to random values.
system.realizeTopology();
State state = system.getDefaultState();
Random::Gaussian random;
for (int i = 0; i < state.getNY(); ++i)
state.updY()[i] = random.getValue();
system.realize(state, Stage::Acceleration);
// Test the low level methods for transforming points and vectors.
const Vec3 point(0.5, 1, -1.5);
SimTK_TEST_EQ(b1.findStationLocationInGround(state, Vec3(0)), b1.getBodyOriginLocation(state));
SimTK_TEST_EQ(b1.findStationAtGroundPoint(state, b1.findStationLocationInGround(state, point)), point);
SimTK_TEST_EQ(b2.findStationAtGroundPoint(state, b1.findStationLocationInGround(state, point)), b1.findStationLocationInAnotherBody(state, point, b2));
SimTK_TEST_EQ(b2.findStationAtGroundPoint(state, b1.findStationLocationInGround(state, Vec3(0))).norm(), (b1.getBodyOriginLocation(state)-b2.getBodyOriginLocation(state)).norm());
SimTK_TEST_EQ(b2.findMassCenterLocationInGround(state), b2.findStationLocationInGround(state, b2.getBodyMassCenterStation(state)));
SimTK_TEST_EQ(b1.expressVectorInGroundFrame(state, Vec3(0)), Vec3(0));
SimTK_TEST_EQ(b1.expressVectorInGroundFrame(state, point), b1.getBodyRotation(state)*point);
SimTK_TEST_EQ(b1.expressGroundVectorInBodyFrame(state, b1.expressVectorInGroundFrame(state, point)), point);
SimTK_TEST_EQ(b2.expressGroundVectorInBodyFrame(state, b1.expressVectorInGroundFrame(state, point)), b1.expressVectorInAnotherBodyFrame(state, point, b2));
// Test the routines for mapping locations, velocities, and accelerations.
Vec3 r, v, a;
b1.findStationLocationVelocityAndAccelerationInGround(state, point, r, v, a);
SimTK_TEST_EQ(v, b1.findStationVelocityInGround(state, point));
SimTK_TEST_EQ(a, b1.findStationAccelerationInGround(state, point));
{
Vec3 r2, v2;
b1.findStationLocationAndVelocityInGround(state, point, r2, v2);
SimTK_TEST_EQ(r, r2);
SimTK_TEST_EQ(v, v2);
}
SimTK_TEST_EQ(b1.findStationVelocityInGround(state, Vec3(0)), b1.getBodyOriginVelocity(state));
SimTK_TEST_EQ(b1.findStationAccelerationInGround(state, Vec3(0)), b1.getBodyOriginAcceleration(state));
SimTK_TEST_EQ(b1.findStationVelocityInGround(state, point), b1.findStationVelocityInAnotherBody(state, point, matter.Ground()));
}
示例9: ASSERT
bool testFitting
(const MultibodySystem& mbs, State& state,
const vector<MobilizedBodyIndex>& bodyIxs,
const vector<vector<Vec3> >& stations,
const vector<vector<Vec3> >& targetLocations,
Real minError, Real maxError, Real endDistance)
{
// Find the best fit.
Real reportedError = ObservedPointFitter::findBestFit(mbs, state, bodyIxs, stations, targetLocations, TOL);
cout << "[min,max]=" << minError << "," << maxError << " actual=" << reportedError << endl;
bool result = (reportedError <= maxError && reportedError >= minError);
// Verify that the error was calculated correctly.
Real error = 0.0;
int numStations = 0;
mbs.realize(state, Stage::Position);
const SimbodyMatterSubsystem& matter = mbs.getMatterSubsystem();
for (int i = 0; i < (int) bodyIxs.size(); ++i) {
MobilizedBodyIndex id = bodyIxs[i];
numStations += (int)stations[i].size();
for (int j = 0; j < (int) stations[i].size(); ++j)
error += (targetLocations[i][j]-matter.getMobilizedBody(id).getBodyTransform(state)*stations[i][j]).normSqr();
}
error = std::sqrt(error/numStations);
cout << "calc wrms=" << error << endl;
ASSERT(std::abs(1.0-error/reportedError) < 0.0001); // should match to machine precision
if (endDistance >= 0) {
// Verify that the ends are the correct distance apart.
Real distance = (matter.getMobilizedBody(bodyIxs[0]).getBodyOriginLocation(state)-matter.getMobilizedBody(bodyIxs[bodyIxs.size()-1]).getBodyOriginLocation(state)).norm();
cout << "required dist=" << endDistance << ", actual=" << distance << endl;
ASSERT(std::abs(1.0-endDistance/distance) < TOL);
}
return result;
}
示例10: testObservedPointFitter
static void testObservedPointFitter(bool useConstraint) {
int failures = 0;
for (int iter = 0; iter < ITERATIONS; ++iter) {
// Build a system consisting of a chain of bodies with occasional side chains, and
// a variety of mobilizers.
MultibodySystem mbs;
SimbodyMatterSubsystem matter(mbs);
Body::Rigid body = Body::Rigid(MassProperties(1, Vec3(0), Inertia(1)));
body.addDecoration(Transform(), DecorativeSphere(.1));
MobilizedBody* lastBody = &matter.Ground();
MobilizedBody* lastMainChainBody = &matter.Ground();
vector<MobilizedBody*> bodies;
Random::Uniform random(0.0, 1.0);
random.setSeed(iter);
for (int i = 0; i < NUM_BODIES; ++i) {
bool mainChain = random.getValue() < 0.5;
MobilizedBody* parent = (mainChain ? lastMainChainBody : lastBody);
int type = (int) (random.getValue()*4);
MobilizedBody* nextBody;
if (type == 0) {
MobilizedBody::Cylinder cylinder(*parent, Transform(Vec3(0, 0, 0)), body, Transform(Vec3(0, BOND_LENGTH, 0)));
nextBody = &matter.updMobilizedBody(cylinder.getMobilizedBodyIndex());
}
else if (type == 1) {
MobilizedBody::Slider slider(*parent, Transform(Vec3(0, 0, 0)), body, Transform(Vec3(0, BOND_LENGTH, 0)));
nextBody = &matter.updMobilizedBody(slider.getMobilizedBodyIndex());
}
else if (type == 2) {
MobilizedBody::Ball ball(*parent, Transform(Vec3(0, 0, 0)), body, Transform(Vec3(0, BOND_LENGTH, 0)));
nextBody = &matter.updMobilizedBody(ball.getMobilizedBodyIndex());
}
else {
MobilizedBody::Pin pin(*parent, Transform(Vec3(0, 0, 0)), body, Transform(Vec3(0, BOND_LENGTH, 0)));
nextBody = &matter.updMobilizedBody(pin.getMobilizedBodyIndex());
}
bodies.push_back(nextBody);
if (mainChain)
lastMainChainBody = nextBody;
lastBody = nextBody;
}
mbs.realizeTopology();
State s = mbs.getDefaultState();
matter.setUseEulerAngles(s, true);
mbs.realizeModel(s);
// Choose a random initial conformation.
vector<Real> targetQ(s.getNQ(), Real(0));
for (MobilizedBodyIndex mbx(1); mbx < matter.getNumBodies(); ++mbx) {
const MobilizedBody& mobod = matter.getMobilizedBody(mbx);
for (int i = 0; i < mobod.getNumQ(s); ++i) {
const QIndex qx0 = mobod.getFirstQIndex(s);
s.updQ()[qx0+i] = targetQ[qx0+i] = 2.0*random.getValue();
}
}
//cout << "q0=" << s.getQ() << endl;
mbs.realize(s, Stage::Position);
// Select some random stations on each body.
vector<vector<Vec3> > stations(NUM_BODIES);
vector<vector<Vec3> > targetLocations(NUM_BODIES);
vector<MobilizedBodyIndex> bodyIxs;
for (int i = 0; i < NUM_BODIES; ++i) {
MobilizedBodyIndex id = bodies[i]->getMobilizedBodyIndex();
bodyIxs.push_back(id);
int numStations = 1 + (int) (random.getValue()*4);
for (int j = 0; j < numStations; ++j) {
Vec3 pos(2.0*random.getValue()-1.0, 2.0*random.getValue()-1.0, 2.0*random.getValue()-1.0);
stations[i].push_back(pos);
targetLocations[i].push_back(bodies[i]->getBodyTransform(s)*pos);
}
}
Real distance = -1;
if (useConstraint) {
// Add a constraint fixing the distance between the first and last bodies.
Real distance = (bodies[0]->getBodyOriginLocation(s)-bodies[NUM_BODIES-1]->getBodyOriginLocation(s)).norm();
// (sherm 140506) Without this 1.001 this failed on clang.
Constraint::Rod(*bodies[0], Vec3(0), *bodies[NUM_BODIES-1], Vec3(0), 1.001*distance);
}
s = mbs.realizeTopology();
matter.setUseEulerAngles(s, true);
mbs.realizeModel(s);
// Try fitting it.
State initState = s;
// (sherm 140506) I raised this from .02 to .03 to make this more robust.
if (!testFitting(mbs, s, bodyIxs, stations, targetLocations, 0.0, 0.03, distance))
failures++;
//cout << "q1=" << s.getQ() << endl;
// Now add random noise to the target locations, and see if it can still fit decently.
Random::Gaussian gaussian(0.0, 0.15);
for (int i = 0; i < (int) targetLocations.size(); ++i) {
//.........这里部分代码省略.........
示例11: testForces
void testForces() {
MultibodySystem system;
SimbodyMatterSubsystem matter(system);
GeneralContactSubsystem contacts(system);
GeneralForceSubsystem forces(system);
// Create a triangle mesh in the shape of a pyramid, with the
// square base having area 1 (split into two triangles).
vector<Vec3> vertices;
vertices.push_back(Vec3(0, 0, 0));
vertices.push_back(Vec3(1, 0, 0));
vertices.push_back(Vec3(1, 0, 1));
vertices.push_back(Vec3(0, 0, 1));
vertices.push_back(Vec3(0.5, 1, 0.5));
vector<int> faceIndices;
int faces[6][3] = {{0, 1, 2}, {0, 2, 3}, {1, 0, 4},
{2, 1, 4}, {3, 2, 4}, {0, 3, 4}};
for (int i = 0; i < 6; i++)
for (int j = 0; j < 3; j++)
faceIndices.push_back(faces[i][j]);
// Create the mobilized bodies and configure the contact model.
Body::Rigid body(MassProperties(1.0, Vec3(0), Inertia(1)));
ContactSetIndex setIndex = contacts.createContactSet();
MobilizedBody::Translation mesh(matter.updGround(), Transform(), body, Transform());
contacts.addBody(setIndex, mesh, ContactGeometry::TriangleMesh(vertices, faceIndices), Transform());
contacts.addBody(setIndex, matter.updGround(), ContactGeometry::HalfSpace(), Transform(Rotation(-0.5*Pi, ZAxis), Vec3(0))); // y < 0
ElasticFoundationForce ef(forces, contacts, setIndex);
Real stiffness = 1e9, dissipation = 0.01, us = 0.1, ud = 0.05, uv = 0.01, vt = 0.01;
ef.setBodyParameters(ContactSurfaceIndex(0), stiffness, dissipation, us, ud, uv);
ef.setTransitionVelocity(vt);
ASSERT(ef.getTransitionVelocity() == vt);
State state = system.realizeTopology();
// Position the pyramid at a variety of positions and check the normal
// force.
for (Real depth = -0.1; depth < 0.1; depth += 0.01) {
mesh.setQToFitTranslation(state, Vec3(0, -depth, 0));
system.realize(state, Stage::Dynamics);
Real f = 0;
if (depth > 0)
f = stiffness*depth;
assertEqual(system.getRigidBodyForces(state, Stage::Dynamics)[mesh.getMobilizedBodyIndex()][1], Vec3(0, f, 0));
assertEqual(system.getRigidBodyForces(state, Stage::Dynamics)[matter.getGround().getMobilizedBodyIndex()][1], Vec3(0, -f, 0));
}
// Now do it with a vertical velocity and see if the dissipation force is correct.
for (Real depth = -0.105; depth < 0.1; depth += 0.01) {
mesh.setQToFitTranslation(state, Vec3(0, -depth, 0));
for (Real v = -1.0; v <= 1.0; v += 0.1) {
mesh.setUToFitLinearVelocity(state, Vec3(0, -v, 0));
system.realize(state, Stage::Dynamics);
Real f = (depth > 0 ? stiffness*depth*(1+dissipation*v) : 0);
if (f < 0)
f = 0;
assertEqual(system.getRigidBodyForces(state, Stage::Dynamics)[mesh.getMobilizedBodyIndex()][1], Vec3(0, f, 0));
}
}
// Do it with a horizontal velocity and see if the friction force is correct.
Vector_<SpatialVec> expectedForce(matter.getNumBodies());
for (Real depth = -0.105; depth < 0.1; depth += 0.01) {
mesh.setQToFitTranslation(state, Vec3(0, -depth, 0));
Real fh = 0;
if (depth > 0)
fh = stiffness*depth;
for (Real v = -1.0; v <= 1.0; v += 0.1) {
mesh.setUToFitLinearVelocity(state, Vec3(v, 0, 0));
system.realize(state, Stage::Dynamics);
const Real vrel = std::abs(v/vt);
Real ff = (v < 0 ? 1 : -1)*fh*(std::min(vrel, 1.0)*(ud+2*(us-ud)/(1+vrel*vrel))+uv*std::fabs(v));
const Vec3 totalForce = Vec3(ff, fh, 0);
expectedForce = SpatialVec(Vec3(0), Vec3(0));
Vec3 contactPoint1 = mesh.findStationAtGroundPoint(state, Vec3(2.0/3.0, 0, 1.0/3.0));
mesh.applyForceToBodyPoint(state, contactPoint1, 0.5*totalForce, expectedForce);
Vec3 contactPoint2 = mesh.findStationAtGroundPoint(state, Vec3(1.0/3.0, 0, 2.0/3.0));
mesh.applyForceToBodyPoint(state, contactPoint2, 0.5*totalForce, expectedForce);
SpatialVec actualForce = system.getRigidBodyForces(state, Stage::Dynamics)[mesh.getMobilizedBodyIndex()];
assertEqual(actualForce[0], expectedForce[mesh.getMobilizedBodyIndex()][0]);
assertEqual(actualForce[1], expectedForce[mesh.getMobilizedBodyIndex()][1]);
}
}
}
示例12: main
int main() {
// Build a system consisting of a chain of bodies with every possible mobilizer.
MultibodySystem mbs;
SimbodyMatterSubsystem matter(mbs);
Body::Rigid body = Body::Rigid(MassProperties(1, Vec3(0), Inertia(1)));
body.addDecoration(DecorativeSphere(.1));
Random::Uniform random(0.0, 2.0);
MobilizedBody lastBody = MobilizedBody::Pin(matter.Ground(), Transform(Vec3(0, 0, 0)), body, Transform(Vec3(random.getValue(), random.getValue(), random.getValue())));
lastBody = MobilizedBody::Slider(lastBody, Transform(Vec3(0, 0, 0)), body, Transform(Vec3(random.getValue(), random.getValue(), random.getValue())));
lastBody = MobilizedBody::Universal(lastBody, Transform(Vec3(0, 0, 0)), body, Transform(Vec3(random.getValue(), random.getValue(), random.getValue())));
lastBody = MobilizedBody::Cylinder(lastBody, Transform(Vec3(0, 0, 0)), body, Transform(Vec3(random.getValue(), random.getValue(), random.getValue())));
lastBody = MobilizedBody::BendStretch(lastBody, Transform(Vec3(0, 0, 0)), body, Transform(Vec3(random.getValue(), random.getValue(), random.getValue())));
lastBody = MobilizedBody::Planar(lastBody, Transform(Vec3(0, 0, 0)), body, Transform(Vec3(random.getValue(), random.getValue(), random.getValue())));
lastBody = MobilizedBody::Gimbal(lastBody, Transform(Vec3(0, 0, 0)), body, Transform(Vec3(random.getValue(), random.getValue(), random.getValue())));
lastBody = MobilizedBody::Ball(lastBody, Transform(Vec3(0, 0, 0)), body, Transform(Vec3(random.getValue(), random.getValue(), random.getValue())));
lastBody = MobilizedBody::Translation(lastBody, Transform(Vec3(0, 0, 0)), body, Transform(Vec3(random.getValue(), random.getValue(), random.getValue())));
lastBody = MobilizedBody::Free(lastBody, Transform(Vec3(0, 0, 0)), body, Transform(Vec3(random.getValue(), random.getValue(), random.getValue())));
lastBody = MobilizedBody::LineOrientation(lastBody, Transform(Vec3(0, 0, 0)), body, Transform(Vec3(random.getValue(), random.getValue(), random.getValue())));
lastBody = MobilizedBody::FreeLine(lastBody, Transform(Vec3(0, 0, 0)), body, Transform(Vec3(random.getValue(), random.getValue(), random.getValue())));
lastBody = MobilizedBody::Weld(lastBody, Transform(Vec3(0, 0, 0)), body, Transform(Vec3(random.getValue(), random.getValue(), random.getValue())));
lastBody = MobilizedBody::Screw(lastBody, Transform(Vec3(0, 0, 0)), body, Transform(Vec3(random.getValue(), random.getValue(), random.getValue())), 0.5);
lastBody = MobilizedBody::Ellipsoid(lastBody, Transform(Vec3(0, 0, 0)), body, Transform(Vec3(random.getValue(), random.getValue(), random.getValue())));
mbs.realizeTopology();
State& s = mbs.updDefaultState();
mbs.realizeModel(s);
// Choose a random initial conformation.
for (int i = 0; i < s.getNQ(); ++i)
s.updQ()[i] = random.getValue();
mbs.realize(s, Stage::Instance);
// The only constraints are the quaternions -- normalize them.
Vector temp;
mbs.project(s, 0.01);
mbs.realize(s, Stage::Position);
// Convert to Euler angles and make sure the positions are all the same.
State euler = s;
matter.convertToEulerAngles(s, euler);
mbs.realize(euler, Stage::Position);
for (int i = 0; i < matter.getNumBodies(); ++i) {
const MobilizedBody& body = matter.getMobilizedBody(MobilizedBodyIndex(i));
Real dist = (body.getBodyOriginLocation(euler)-body.getBodyOriginLocation(s)).norm();
ASSERT(dist < 1e-5);
}
// Now convert back to quaternions and make sure the positions are still the same.
State quaternions = s;
matter.convertToQuaternions(euler, quaternions);
mbs.realize(quaternions, Stage::Position);
for (int i = 0; i < matter.getNumBodies(); ++i) {
const MobilizedBody& body = matter.getMobilizedBody(MobilizedBodyIndex(i));
Real dist = (body.getBodyOriginLocation(quaternions)-body.getBodyOriginLocation(s)).norm();
ASSERT(dist < 1e-5);
}
// Compare the state variables to see if they have been accurately reproduced.
mbs.project(s, 0.01); // Normalize the quaternions
Real diff = std::sqrt((s.getQ()-quaternions.getQ()).normSqr()/s.getNQ());
ASSERT(diff < 1e-5);
std::cout << "Done" << std::endl;
}
示例13: main
int main(int argc, char** argv) {
try { // If anything goes wrong, an exception will be thrown.
MultibodySystem mbs; mbs.setUseUniformBackground(true);
GeneralForceSubsystem forces(mbs);
SimbodyMatterSubsystem pend(mbs);
DecorationSubsystem viz(mbs);
Force::UniformGravity gravity(forces, pend, Vec3(0, -g, 0));
MobilizedBody::Ball connector(pend.Ground(),
Transform(1*Vec3(0, 0, 0)),
MassProperties(1, Vec3(0,0,0), Inertia(10,20,30)),
Transform(1*Vec3(0, .5, 0)));
connector.setDefaultRadius(0.05); // for the artwork
//connector.setDefaultRotation( Rotation(Pi/4, Vec3(0,0,1) );
const Real m1 = 5;
const Real m2 = 1;
const Real radiusRatio = std::pow(m2/m1, 1./3.);
const Vec3 weight1Location(0, 0, -d/2); // in local frame of swinging body
const Vec3 weight2Location(0, 0, d/2); // in local frame of swinging body
const Vec3 COM = (m1*weight1Location+m2*weight2Location)/(m1+m2);
const MassProperties swingerMassProps
(m1+m2, COM, 1*Inertia(1,1,1) + m1*UnitInertia::pointMassAt(weight1Location)
+ m2*UnitInertia::pointMassAt(weight2Location));
MobilizedBody::Screw swinger(connector,
Transform( Rotation( 0*.7, Vec3(9,8,7) ),
1*Vec3(0,-.5,0)),
swingerMassProps,
Transform( Rotation(0*1.3, Vec3(0,0,1) ),
COM+0*Vec3(0,0,3)), // inboard joint location
0.3); // pitch
// Add a blue sphere around the weight.
viz.addBodyFixedDecoration(swinger, weight1Location,
DecorativeSphere(d/8).setColor(Blue).setOpacity(.2));
viz.addBodyFixedDecoration(swinger, weight2Location,
DecorativeSphere(radiusRatio*d/8).setColor(Green).setOpacity(.2));
viz.addRubberBandLine(GroundIndex, Vec3(0),
swinger, Vec3(0),
DecorativeLine().setColor(Blue).setLineThickness(10)
.setRepresentation(DecorativeGeometry::DrawPoints));
//forces.addMobilityConstantForce(swinger, 0, 10);
Force::ConstantTorque(forces, swinger, Vec3(0,0,10));
//forces.addConstantForce(swinger, Vec3(0), Vec3(0,10,0));
//forces.addConstantForce(swinger, Vec3(0,0,0), Vec3(10,10,0)); // z should do nothing
//forces.addMobilityConstantForce(swinger, 1, 10);
// forces.addMobilityConstantForce(swinger, 2, 60-1.2);
State s = mbs.realizeTopology(); // define appropriate states for this System
pend.setUseEulerAngles(s, true);
mbs.realizeModel(s);
mbs.realize(s);
// Create a study using the Runge Kutta Merson integrator
RungeKuttaMersonIntegrator myStudy(mbs);
myStudy.setAccuracy(1e-6);
// This will pick up decorative geometry from
// each subsystem that generates any, including of course the
// DecorationSubsystem, but not limited to it.
Visualizer display(mbs);
const Real expectedPeriod = 2*Pi*std::sqrt(d/g);
printf("Expected period: %g seconds\n", expectedPeriod);
const Real dt = 1./30; // output intervals
const Real finalTime = 1*expectedPeriod;
for (Real startAngle = 10; startAngle <= 90; startAngle += 10) {
s = mbs.getDefaultState();
connector.setQToFitRotation(s, Rotation(Pi/4, Vec3(1,1,1)) );
printf("time theta energy *************\n");
swinger.setQToFitTransform(s, Transform( Rotation( BodyRotationSequence, 0*Pi/2, XAxis, 0*Pi/2, YAxis ), Vec3(0,0,0) ));
swinger.setUToFitVelocity(s, SpatialVec(0*Vec3(1.1,1.2,1.3),Vec3(0,0,-1)));
s.updTime() = 0;
myStudy.initialize(s);
cout << "MassProperties in B=" << swinger.expressMassPropertiesInAnotherBodyFrame(myStudy.getState(),swinger);
cout << "MassProperties in G=" << swinger.expressMassPropertiesInGroundFrame(myStudy.getState());
cout << "Spatial Inertia =" << swinger.calcBodySpatialInertiaMatrixInGround(myStudy.getState());
int stepNum = 0;
for (;;) {
// Should check for errors and other interesting status returns.
myStudy.stepTo(myStudy.getTime() + dt);
const State& s = myStudy.getState(); // s is now the integrator's internal state
if ((stepNum++%10)==0) {
//.........这里部分代码省略.........
示例14: testJacobianBiasTerms
// Test calculations of Jacobian "bias" terms, where bias=JDot*u.
// We can estimate JDot using a numerical directional derivative
// since JDot = (DJ/Dq)*qdot ~= (J(q+h*qdot)-J(q-h*qdot))/2h.
// Then we multiply JDot*u and compare with the bias calculations.
// Or, we can estimate JDot*u directly with
// JDotu ~= (J(q+h*qdot)*u - J(q-h*qdot)*u)/2h
// using the fast "multiply by Jacobian" methods.
// We use both methods below.
void testJacobianBiasTerms() {
MultibodySystem system;
MyForceImpl* frcp;
makeSystem(false, system, frcp);
const SimbodyMatterSubsystem& matter = system.getMatterSubsystem();
State state = system.realizeTopology();
const int nq = state.getNQ();
const int nu = state.getNU();
const int nb = matter.getNumBodies();
system.realizeModel(state);
// Randomize state.
state.updQ() = Test::randVector(nq);
state.updU() = Test::randVector(nu);
const MobilizedBodyIndex whichBod(8);
const Vec3 whichPt(1,2,3);
system.realize(state, Stage::Velocity);
const Vector& q = state.getQ();
const Vector& u = state.getU();
const Vector& qdot = state.getQDot();
// sbias, fbias, sysbias are the JDot*u quantities we want to check.
const Vec3 sbias =
matter.calcBiasForStationJacobian(state, whichBod, whichPt);
const SpatialVec fbias =
matter.calcBiasForFrameJacobian(state, whichBod, whichPt);
Vector_<SpatialVec> sysbias;
matter.calcBiasForSystemJacobian(state, sysbias);
// These are for computing JDot first.
RowVector_<Vec3> JS_P, JS1_P, JS2_P, JSDot_P;
RowVector_<SpatialVec> JF_P, JF1_P, JF2_P, JFDot_P;
Matrix_<SpatialVec> J, J1, J2, JDot;
// These are for computing JDot*u directly.
Vec3 JS_Pu, JS1_Pu, JS2_Pu, JSDot_Pu;
SpatialVec JF_Pu, JF1_Pu, JF2_Pu, JFDot_Pu;
Vector_<SpatialVec> Ju, J1u, J2u, JDotu;
// Unperturbed:
matter.calcStationJacobian(state,whichBod,whichPt, JS_P);
matter.calcFrameJacobian(state,whichBod,whichPt, JF_P);
matter.calcSystemJacobian(state, J);
JS_Pu = matter.multiplyByStationJacobian(state,whichBod,whichPt,u);
JF_Pu = matter.multiplyByFrameJacobian(state,whichBod,whichPt,u);
matter.multiplyBySystemJacobian(state, u, Ju);
const Real Delta = 5e-6; // we'll use central difference
State perturbq = state;
// Perturbed +:
perturbq.updQ() = q + Delta*qdot;
system.realize(perturbq, Stage::Position);
matter.calcStationJacobian(perturbq,whichBod,whichPt, JS2_P);
matter.calcFrameJacobian(perturbq,whichBod,whichPt, JF2_P);
matter.calcSystemJacobian(perturbq, J2);
JS2_Pu = matter.multiplyByStationJacobian(perturbq,whichBod,whichPt,u);
JF2_Pu = matter.multiplyByFrameJacobian(perturbq,whichBod,whichPt,u);
matter.multiplyBySystemJacobian(perturbq,u, J2u);
// Perturbed -:
perturbq.updQ() = q - Delta*qdot;
system.realize(perturbq, Stage::Position);
matter.calcStationJacobian(perturbq,whichBod,whichPt, JS1_P);
matter.calcFrameJacobian(perturbq,whichBod,whichPt, JF1_P);
matter.calcSystemJacobian(perturbq, J1);
JS1_Pu = matter.multiplyByStationJacobian(perturbq,whichBod,whichPt,u);
JF1_Pu = matter.multiplyByFrameJacobian(perturbq,whichBod,whichPt,u);
matter.multiplyBySystemJacobian(perturbq,u, J1u);
// Estimate JDots:
JSDot_P = (JS2_P-JS1_P)/Delta/2;
JFDot_P = (JF2_P-JF1_P)/Delta/2;
JDot = (J2-J1)/Delta/2;
// Estimate JDotus:
JSDot_Pu = (JS2_Pu-JS1_Pu)/Delta/2;
JFDot_Pu = (JF2_Pu-JF1_Pu)/Delta/2;
JDotu = (J2u-J1u)/Delta/2;
// Calculate errors in JDot*u:
SimTK_TEST_EQ_TOL((JSDot_P*u-sbias).norm(), 0, SqrtEps);
SimTK_TEST_EQ_TOL((JFDot_P*u-fbias).norm(), 0, SqrtEps);
SimTK_TEST_EQ_TOL((JDot*u-sysbias).norm(), 0, SqrtEps);
// Calculate errors in JDotu:
SimTK_TEST_EQ_TOL((JSDot_Pu-sbias).norm(), 0, SqrtEps);
SimTK_TEST_EQ_TOL((JFDot_Pu-fbias).norm(), 0, SqrtEps);
SimTK_TEST_EQ_TOL((JDotu-sysbias).norm(), 0, SqrtEps);
//.........这里部分代码省略.........
示例15: main
//==============================================================================
// MAIN
//==============================================================================
int main() {
try { // catch errors if any
// Create the system, with subsystems for the bodies and some forces.
MultibodySystem system;
SimbodyMatterSubsystem matter(system);
GeneralForceSubsystem forces(system);
ContactTrackerSubsystem tracker(system);
CompliantContactSubsystem contact(system, tracker);
contact.setTransitionVelocity(transitionVelocity);
Force::Gravity(forces, matter, -YAxis, 9.81);
// Set up visualization and ask for a frame every 1/30 second.
Visualizer viz(system);
viz.setShowSimTime(true); viz.setShowFrameRate(true);
viz.addSlider("Speed", SpeedControlSlider, -10, 10, 0);
Visualizer::InputSilo* silo = new Visualizer::InputSilo();
viz.addInputListener(silo);
#ifdef ANIMATE
system.addEventReporter(new Visualizer::Reporter(viz, 1./30));
#endif
DecorativeText help("Any input to start; ESC to quit");
help.setIsScreenText(true);
viz.addDecoration(MobilizedBodyIndex(0),Vec3(0),help);
matter.setShowDefaultGeometry(false);
// Add the Ground contact geometry. Contact half space has -XAxis normal
// (right hand wall) so we have to rotate.
MobilizedBody& Ground = matter.updGround(); // Nicer name for Ground.
Ground.updBody().addContactSurface(Transform(YtoX,Vec3(0)),
ContactSurface(ContactGeometry::HalfSpace(),concrete));
// Add some speed bumps.
const int NBumps = 2; const Vec3 BumpShape(.8,0.2,2);
for (int i=0; i < NBumps; ++i) {
const Real x = -2*(i+1);
Ground.updBody().addContactSurface(Vec3(x,0,0),
ContactSurface(ContactGeometry::Ellipsoid(BumpShape), rubber));
Ground.updBody().addDecoration(Vec3(x,0,0),
DecorativeEllipsoid(BumpShape).setColor(Gray).setResolution(3));
}
// TORSO
const Real TorsoHeight = 1.1;
const Vec3 torsoHDims(1,.08,.8);
const Real torsoVolume = 8*torsoHDims[0]*torsoHDims[1]*torsoHDims[2];
const Real torsoMass = torsoVolume*rubber_density/10;
const Vec3 torsoCOM(0,-.75,0); // put it low for stability
Body::Rigid torsoInfo(MassProperties(torsoMass,torsoCOM,
UnitInertia::brick(torsoHDims).shiftFromCentroidInPlace(-torsoCOM)));
torsoInfo.addDecoration(Vec3(0),
DecorativeBrick(torsoHDims).setColor(Cyan));
// CRANK
const Vec3 crankCenter(0,0,0); // in torso frame
const Vec3 crankOffset(0,0,torsoHDims[2]+LinkDepth); // left/right offset
const Real MLen=15/100.; // crank radius
Body::Rigid crankInfo(MassProperties(.1,Vec3(0),
UnitInertia::cylinderAlongZ(MLen, LinkDepth)));
crankInfo.addDecoration(Vec3(0),
DecorativeBrick(Vec3(LinkWidth,LinkWidth,torsoHDims[2]))
.setColor(Black));
const Vec3 CrankConnect(MLen,0,0); // in crank frame
// Add the torso and crank mobilized bodies.
MobilizedBody::Free torso(Ground,Vec3(0,TorsoHeight,0), torsoInfo,Vec3(0));
MobilizedBody::Pin crank(torso,crankCenter, crankInfo, Vec3(0));
// Add the legs.
for (int i=-1; i<=1; ++i) {
const Vec3 offset = crankCenter + i*crankOffset;
const Vec3 linkSpace(0,0,2*LinkDepth);
const Rotation R_CP(i*2*Pi/3,ZAxis);
// Add crank bars for looks.
crank.addBodyDecoration(
Transform(R_CP, offset+1.5*MLen/2*R_CP.x()+(i==0?linkSpace:Vec3(0))),
DecorativeBrick(Vec3(1.5*MLen/2,LinkWidth,LinkDepth))
.setColor(Yellow));
addOneLeg(viz, torso, offset + i*linkSpace,
crank, R_CP*CrankConnect);
addOneLeg(viz, torso, Transform(Rotation(Pi,YAxis), offset + i*linkSpace),
crank, R_CP*CrankConnect);
}
// Add speed control.
Motion::Steady motor(crank, 0); // User controls speed.
system.addEventHandler
(new UserInputHandler(*silo, motor, Real(0.1))); //check input every 100ms
// Initialize the system and state.
State state = system.realizeTopology();
system.realize(state);
printf("Theo Jansen Strandbeest in 3D:\n");
printf("%d bodies, %d mobilities, -%d constraint equations -%d motions\n",
matter.getNumBodies(), state.getNU(), state.getNMultipliers(),
matter.getMotionMultipliers(state).size());
//.........这里部分代码省略.........