コード例 #1
0
/**
 * Compute all constraints given x.
 */
void ActuatorForceTargetFast::
computeConstraintVector(SimTK::State& s, const Vector &x,Vector &c) const
{
    CMC_TaskSet&  taskSet = _controller->updTaskSet();
    const Set<Actuator>& fSet = _controller->getActuatorSet();

    int nf = fSet.getSize();

    // Now override the actuator forces with computed active force
    // (from static optimization) but also include the passive force
    // contribution of muscles when applying forces to the model
    for(int i=0;i<nf;i++) {
        ScalarActuator* act = dynamic_cast<ScalarActuator*>(&fSet[i]);
        act->overrideActuation(s, true);
        act->setOverrideActuation(s, x[i]);
    }
    _controller->getModel().getMultibodySystem().realize(s, SimTK::Stage::Acceleration );

    taskSet.computeAccelerations(s);
    Array<double> &w = taskSet.getWeights();
    Array<double> &aDes = taskSet.getDesiredAccelerations();
    Array<double> &a = taskSet.getAccelerations();

    // CONSTRAINTS
    for(int i=0; i<getNumConstraints(); i++)
        c[i]=w[i]*(aDes[i]-a[i]);

    // reset the actuator control 
    for(int i=0;i<fSet.getSize();i++) {
        ScalarActuator* act = dynamic_cast<ScalarActuator*>(&fSet[i]);
        act->overrideActuation(s, false);
    }

    _controller->getModel().getMultibodySystem().realizeModel(s);
}
コード例 #2
0
//=============================================================================
// ACCELERATION
//=============================================================================
//
void StaticOptimizationTarget::
computeAcceleration(SimTK::State& s, const SimTK::Vector &parameters,SimTK::Vector &rAccel) const
{
    double time = s.getTime();
    

    const ForceSet& fs = _model->getForceSet();
    for(int i=0,j=0;i<fs.getSize();i++)  {
        ScalarActuator *act = dynamic_cast<ScalarActuator*>(&fs.get(i));
         if( act ) {
             act->setOverrideActuation(s, parameters[j] * _optimalForce[j]);
             j++;
         }
    }

    _model->getMultibodySystem().realize(s,SimTK::Stage::Acceleration);

    SimTK::Vector udot = _model->getMatterSubsystem().getUDot(s);

    for(int i=0; i<_accelerationIndices.getSize(); i++) 
        rAccel[i] = udot[_accelerationIndices[i]];

    //QueryPerformanceCounter(&stop);
    //double duration = (double)(stop.QuadPart-start.QuadPart)/(double)frequency.QuadPart;
    //std::cout << "computeAcceleration time = " << (duration*1.0e3) << " milliseconds" << std::endl;

    // 1.45 ms
}
コード例 #3
0
//=============================================================================
// ANALYSIS
//=============================================================================
//
void InverseDynamics::
computeAcceleration(SimTK::State& s, double *aF,double *rAccel) const
{
    for(int i=0,j=0; i<_forceSet->getSize(); i++) {
        ScalarActuator* act = dynamic_cast<ScalarActuator*>(&_forceSet->get(i));
        if( act ) {
            act->setOverrideActuation(s, aF[j++]);
        }
    }

    // NEED TO APPLY OTHER FORCES (e.g. Prescribed) FROM ORIGINAL MODEL 

    _modelWorkingCopy->getMultibodySystem().realize(s,SimTK::Stage::Acceleration);

    SimTK::Vector udot = _modelWorkingCopy->getMatterSubsystem().getUDot(s);

    for(int i=0; i<_accelerationIndices.getSize(); i++) 
        rAccel[i] = udot[_accelerationIndices[i]];

}
コード例 #4
0
void ActuatorForceTarget::
computePerformanceVectors(SimTK::State& s, const Vector &aF, Vector &rAccelPerformanceVector, Vector &rForcePerformanceVector)
{
    const Set<Actuator> &fSet = _controller->getActuatorSet();

    for(int i=0;i<fSet.getSize();i++) {
        ScalarActuator* act = dynamic_cast<ScalarActuator*>(&fSet[i]);
        act->setOverrideActuation(s, aF[i]);
        act->overrideActuation(s, true);
    }

    _controller->getModel().getMultibodySystem().realize(s, SimTK::Stage::Acceleration );

    CMC_TaskSet& taskSet = _controller->updTaskSet();
    taskSet.computeAccelerations(s);
    Array<double> &w = taskSet.getWeights();
    Array<double> &aDes = taskSet.getDesiredAccelerations();
    Array<double> &a = taskSet.getAccelerations();

    // PERFORMANCE
    double sqrtStressTermWeight = sqrt(_stressTermWeight);
    for(int i=0;i<fSet.getSize();i++) {
        ScalarActuator* act = dynamic_cast<ScalarActuator*>(&fSet[i]);
        rForcePerformanceVector[i] = sqrtStressTermWeight * act->getStress(s);
     }

    int nacc = aDes.getSize();
    for(int i=0;i<nacc;i++) rAccelPerformanceVector[i] = sqrt(w[i]) * (a[i] - aDes[i]);

    // reset the actuator control
    for(int i=0;i<fSet.getSize();i++) {
        ScalarActuator* act = dynamic_cast<ScalarActuator*>(&fSet[i]);
        act->overrideActuation(s, false);
    }


}
コード例 #5
0
/* Solve for the induced accelerations (udot_f) for a Force in the model 
   identified by its name. */
const SimTK::Vector& InducedAccelerationsSolver::solve(const SimTK::State& s,
                const string& forceName,
                bool computeActuatorPotentialOnly,
                SimTK::Vector_<SimTK::SpatialVec>* constraintReactions)
{
    int nu = _modelCopy.getNumSpeeds();
    double aT = s.getTime();

    SimTK::State& s_solver = _modelCopy.updWorkingState();

    //_modelCopy.initStateWithoutRecreatingSystem(s_solver);
    // Just need to set current time and kinematics to determine state of constraints
    s_solver.setTime(aT);
    s_solver.updQ()=s.getQ();
    s_solver.updU()=s.getU();

    // Check the external forces and determine if contact constraints should be applied at this time
    // and turn constraint on if it should be.
    Array<bool> constraintOn = applyContactConstraintAccordingToExternalForces(s_solver);

    // Hang on to a state that has the right flags for contact constraints turned on/off
    _modelCopy.setPropertiesFromState(s_solver);
    // Use this state for the remainder of this step (record)
    s_solver = _modelCopy.getMultibodySystem().realizeTopology();
    // DO NOT recreate the system, will lose location of constraint
    _modelCopy.initStateWithoutRecreatingSystem(s_solver);

    //cout << "Solving for contributor: " << _contributors[c] << endl;
    // Need to be at the dynamics stage to disable a force
    s_solver.setTime(aT);
    _modelCopy.getMultibodySystem().realize(s_solver, SimTK::Stage::Dynamics);
        
    if(forceName == "total"){
        // Set gravity ON
        _modelCopy.getGravityForce().enable(s_solver);

        //Use same conditions on constraints
        s_solver.updU() = s.getU();
        s_solver.updU() = s.getZ();

        //Make sure all the actuators are on!
        for(int f=0; f<_modelCopy.getActuators().getSize(); f++){
            _modelCopy.updActuators().get(f).setDisabled(s_solver, false);
        }

        // Get to  the point where we can evaluate unilateral constraint conditions
        _modelCopy.getMultibodySystem().realize(s_solver, SimTK::Stage::Acceleration);

        /* *********************************** ERROR CHECKING *******************************
        SimTK::Vec3 pcom =_modelCopy.getMultibodySystem().getMatterSubsystem().calcSystemMassCenterLocationInGround(s_solver);
        SimTK::Vec3 vcom =_modelCopy.getMultibodySystem().getMatterSubsystem().calcSystemMassCenterVelocityInGround(s_solver);
        SimTK::Vec3 acom =_modelCopy.getMultibodySystem().getMatterSubsystem().calcSystemMassCenterAccelerationInGround(s_solver);

        SimTK::Matrix M;
        _modelCopy.getMultibodySystem().getMatterSubsystem().calcM(s_solver, M);
        cout << "mass matrix: " << M << endl;

        SimTK::Inertia sysInertia = _modelCopy.getMultibodySystem().getMatterSubsystem().calcSystemCentralInertiaInGround(s_solver);
        cout << "system inertia: " << sysInertia << endl;

        SimTK::SpatialVec sysMomentum =_modelCopy.getMultibodySystem().getMatterSubsystem().calcSystemMomentumAboutGroundOrigin(s_solver);
        cout << "system momentum: " << sysMomentum << endl;

        const SimTK::Vector &appliedMobilityForces = _modelCopy.getMultibodySystem().getMobilityForces(s_solver, SimTK::Stage::Dynamics);
        appliedMobilityForces.dump("All Applied Mobility Forces");
        
        // Get all applied body forces like those from contact
        const SimTK::Vector_<SimTK::SpatialVec>& appliedBodyForces = _modelCopy.getMultibodySystem().getRigidBodyForces(s_solver, SimTK::Stage::Dynamics);
        appliedBodyForces.dump("All Applied Body Forces");

        SimTK::Vector ucUdot;
        SimTK::Vector_<SimTK::SpatialVec> ucA_GB;
        _modelCopy.getMultibodySystem().getMatterSubsystem().calcAccelerationIgnoringConstraints(s_solver, appliedMobilityForces, appliedBodyForces, ucUdot, ucA_GB) ;
        ucUdot.dump("Udots Ignoring Constraints");
        ucA_GB.dump("Body Accelerations");

        SimTK::Vector_<SimTK::SpatialVec> constraintBodyForces(_constraintSet.getSize(), SimTK::SpatialVec(SimTK::Vec3(0)));
        SimTK::Vector constraintMobilityForces(0);

        int nc = _modelCopy.getMultibodySystem().getMatterSubsystem().getNumConstraints();
        for (SimTK::ConstraintIndex cx(0); cx < nc; ++cx) {
            if (!_modelCopy.getMultibodySystem().getMatterSubsystem().isConstraintDisabled(s_solver, cx)){
                cout << "Constraint " << cx << " enabled!" << endl;
            }
        }
        //int nMults = _modelCopy.getMultibodySystem().getMatterSubsystem().getTotalMultAlloc();

        for(int i=0; i<constraintOn.getSize(); i++) {
            if(constraintOn[i])
                _constraintSet[i].calcConstraintForces(s_solver, constraintBodyForces, constraintMobilityForces);
        }
        constraintBodyForces.dump("Constraint Body Forces");
        constraintMobilityForces.dump("Constraint Mobility Forces");
        // ******************************* end ERROR CHECKING *******************************/
    
        for(int i=0; i<constraintOn.getSize(); i++) {
            _replacementConstraints[i].setDisabled(s_solver, !constraintOn[i]);
            // Make sure we stay at Dynamics so each constraint can evaluate its conditions
            _modelCopy.getMultibodySystem().realize(s_solver, SimTK::Stage::Acceleration);
        }

        // This should also push changes to defaults for unilateral conditions
        _modelCopy.setPropertiesFromState(s_solver);

    }
    else if(forceName == "gravity"){
        // Set gravity ON
        _modelCopy.updForceSubsystem().setForceIsDisabled(s_solver, _modelCopy.getGravityForce().getForceIndex(), false);

        // zero velocity
        s_solver.setU(SimTK::Vector(nu,0.0));

        // disable other forces
        for(int f=0; f<_modelCopy.getForceSet().getSize(); f++){
            _modelCopy.updForceSet()[f].setDisabled(s_solver, true);
        }
    }
    else if(forceName == "velocity"){       
        // Set gravity off
        _modelCopy.updForceSubsystem().setForceIsDisabled(s_solver, _modelCopy.getGravityForce().getForceIndex(), true);

        // non-zero velocity
        s_solver.updU() = s.getU();
            
        // zero actuator forces
        for(int f=0; f<_modelCopy.getActuators().getSize(); f++){
            _modelCopy.updActuators().get(f).setDisabled(s_solver, true);
        }
        // Set the configuration (gen. coords and speeds) of the model.
        _modelCopy.getMultibodySystem().realize(s_solver, SimTK::Stage::Velocity);
    }
    else{ //The rest are actuators      
        // Set gravity OFF
        _modelCopy.updForceSubsystem().setForceIsDisabled(s_solver, _modelCopy.getGravityForce().getForceIndex(), true);

        // zero actuator forces
        for(int f=0; f<_modelCopy.getActuators().getSize(); f++){
            _modelCopy.updActuators().get(f).setDisabled(s_solver, true);
        }

        // zero velocity
        SimTK::Vector U(nu,0.0);
        s_solver.setU(U);
        s_solver.updZ() = s.getZ();
        // light up the one Force who's contribution we are looking for
        int ai = _modelCopy.getForceSet().getIndex(forceName);
        if(ai<0){
            cout << "Force '"<< forceName << "' not found in model '" <<
                _modelCopy.getName() << "'." << endl;
        }
        Force &force = _modelCopy.getForceSet().get(ai);
        force.setDisabled(s_solver, false);

        ScalarActuator *actuator = dynamic_cast<ScalarActuator*>(&force);
        if(actuator){
            if(computeActuatorPotentialOnly){
                actuator->overrideActuation(s_solver, true);
                actuator->setOverrideActuation(s_solver, 1.0);
            }
        }

        // Set the configuration (gen. coords and speeds) of the model.
        _modelCopy.getMultibodySystem().realize(s_solver, SimTK::Stage::Model);
        _modelCopy.getMultibodySystem().realize(s_solver, SimTK::Stage::Velocity);

    }// End of if to select contributor 

    // cout << "Constraint 0 is of "<< _constraintSet[0].getConcreteClassName() << " and should be " << constraintOn[0] << " and is actually " <<  (_constraintSet[0].isDisabled(s_solver) ? "off" : "on") << endl;
    // cout << "Constraint 1 is of "<< _constraintSet[1].getConcreteClassName() << " and should be " << constraintOn[1] << " and is actually " <<  (_constraintSet[1].isDisabled(s_solver) ? "off" : "on") << endl;

    // After setting the state of the model and applying forces
    // Compute the derivative of the multibody system (speeds and accelerations)
    _modelCopy.getMultibodySystem().realize(s_solver, SimTK::Stage::Acceleration);

    // Sanity check that constraints hasn't totally changed the configuration of the model
    // double error = (s.getQ()-s_solver.getQ()).norm();

    // Report reaction forces for debugging
    /*
    SimTK::Vector_<SimTK::SpatialVec> constraintBodyForces(_constraintSet.getSize());
    SimTK::Vector mobilityForces(0);

    for(int i=0; i<constraintOn.getSize(); i++) {
        if(constraintOn[i])
            _constraintSet.get(i).calcConstraintForces(s_solver, constraintBodyForces, mobilityForces);
    }*/

    return s_solver.getUDot();
}