Exemplo n.º 1
0
/**
* This method is called at the beginning of an analysis so that any
* necessary initializations may be performed.
*
* This method is meant to be called at the beginning of an integration in
* Model::integBeginCallback() and has the same argument list.
*
* This method should be overridden in the child class.  It is
* included here so that the child class will not have to implement it if it
* is not necessary.
*
* @param state system State
* @param aStep Step number of the integration.
*
* @return -1 on error, 0 otherwise.
*/
int Actuation::
begin(SimTK::State& s)
{
    if (!proceed()) return(0);

    // NUMBER OF ACTUATORS
    int na = _model->getActuators().getSize();
    _na = na;
    // WORK ARRAY
    if (_fsp != NULL) delete[] _fsp;
    _fsp = new double[_na];

    // RESET STORAGE
    if (_forceStore == NULL)
        _forceStore = new Storage();
    if (_speedStore == NULL)
        _speedStore = new Storage();
    if (_powerStore == NULL)
        _powerStore = new Storage();

    // RESET STORAGE
    _forceStore->reset(s.getTime());
    _speedStore->reset(s.getTime());
    _powerStore->reset(s.getTime());

    // RECORD
    int status = 0;
    if (_forceStore->getSize() <= 0) {
        status = record(s);
    }

    return(status);
}
/**
 * This method is called at the beginning of an analysis so that any
 * necessary initializations may be performed.
 *
 * This method is meant to be called at the begining of an integration 
 *
 * This method should be overriden in the child class.  It is
 * included here so that the child class will not have to implement it if it
 * is not necessary.
 *
 * @param s current system state
 * @param aClientData General use pointer for sending in client data.
 *
 * @return -1 on error, 0 otherwise.
 */
int PointKinematics::
begin( SimTK::State& s)
{
	if(!proceed()) return(0);

	// RESET STORAGE
	_pStore->reset(s.getTime());
	_vStore->reset(s.getTime());
	_aStore->reset(s.getTime());

	int status = record(s);

	return(status);
}
Exemplo n.º 3
0
/**
 * This method is called at the beginning of an analysis so that any
 * necessary initializations may be performed.
 *
 * This method is meant to be called at the begining of an integration 
 *
 * @param s current state of System
 *
 * @return -1 on error, 0 otherwise.
 */
int Kinematics::
begin( SimTK::State& s )
{
	if(!proceed()) return(0);

	double time = s.getTime();
	
	// RESET STORAGE
	_pStore->reset(time);
	_vStore->reset(time);
	if (_aStore) _aStore->reset(time);

	// RECORD
	int status = 0;
	if(_pStore->getSize()<=0) {
        if(_recordAccelerations && s.getSystemStage() < SimTK::Stage::Acceleration ) 
            _model->getMultibodySystem().realize(s, SimTK::Stage::Acceleration);
		else
			_model->getMultibodySystem().realize(s, SimTK::Stage::Velocity);

		status = record(s);
	}

	return(status);
}
Exemplo n.º 4
0
/**
 * Record the ForceReporter quantities.
 */
int ForceReporter::record(const SimTK::State& s)
{
    if(_model==NULL) return(-1);

    // MAKE SURE ALL ForceReporter QUANTITIES ARE VALID
    _model->getMultibodySystem().realize(s, SimTK::Stage::Dynamics );

    StateVector nextRow = StateVector(s.getTime());

    // Model Forces
    auto forces = _model->getComponentList<Force>();

    for(auto& force : forces) {
        // If body force we need to record six values for torque+force
        // If muscle we record one scalar
        if (force.isDisabled(s)) continue;
        Array<double> values = force.getRecordValues(s);
        nextRow.getData().append(values);
    }

    if(_includeConstraintForces){
        // Model Constraints
        auto constraints = _model->getComponentList<Constraint>();
        for (auto& constraint : constraints) {
            if (constraint.isDisabled(s)) continue;
            Array<double> values = constraint.getRecordValues(s);
            nextRow.getData().append(values);
        }
    }
    _forceStore.append(nextRow);

    return(0);
}
Exemplo n.º 5
0
/**
 * initialize storages and analyses 
 * 
 * @param s system state before integration
 */
void Manager::initialize(SimTK::State& s, double dt )
{
    // skip initializations for CMC's actuator system
    if( _writeToStorage && _performAnalyses ) { 

        double tReal = s.getTime();
    
        // STORE STARTING CONTROLS
        if (_model->isControlled()){
            _controllerSet->setModel(*_model);
            _controllerSet->storeControls(s, 0);
        }

        // STORE STARTING STATES
        if(hasStateStorage()) {
            // ONLY IF NO STATES WERE PREVIOUSLY STORED
            if(getStateStorage().getSize()==0) {
                SimTK::Vector stateValues = _model->getStateVariableValues(s);
                getStateStorage().store(0,tReal,stateValues.size(), &stateValues[0]);
            }
        }

        // ANALYSES 
        AnalysisSet& analysisSet = _model->updAnalysisSet();
        analysisSet.begin(s);
    }

    return;
}
//=============================================================================
// 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
}
    SimTK::Vec3 calcSomething(const SimTK::State& state) const {
        const_cast<Foo *>(this)->m_ctr++;
        m_mutableCtr++;

        double t = state.getTime();
        return SimTK::Vec3(t, t*t, sqrt(t));
    }
Exemplo n.º 8
0
/**
 * Filter the controls.  This method was introduced as a means of attempting
 * to reduce the sizes of residuals.  Unfortunately, the approach was
 * generally unsuccessful because the desired accelerations were not
 * achieved.
 *
 * @param aControlSet Set of controls computed by CMC.
 * @param aDT Current time window.
 * @param rControls Array of filtered controls.
 */
void CMC::
FilterControls(const SimTK::State& s, const ControlSet &aControlSet,double aDT,
               OpenSim::Array<double> &rControls,bool aVerbosePrinting)
{
    if(aDT <= SimTK::Zero) {
        if(aVerbosePrinting) cout<<"\nCMC.filterControls: aDT is practically 0.0, skipping!\n\n";
        return;
    }

    if(aVerbosePrinting) cout<<"\n\nFiltering controls to limit curvature...\n";

    int i;
    int size = rControls.getSize();
    Array<double> x0(0.0,size),x1(0.0,size),x2(0.0,size);

    // SET TIMES
    double t0,t1/*,t2*/;
    // t2 = s.getTime();
    t1 = s.getTime() - aDT;
    t0 = t1 - aDT;

    // SET CONTROL VALUES
    x2 = rControls;
    aControlSet.getControlValues(t1,x1);
    aControlSet.getControlValues(t0,x0);

    // LOOP OVER CONTROLS
    double m1,m2;
    double curvature;
    double thresholdCurvature = 2.0 * 0.05 / (aDT * aDT);
    
    //double thresholdSlopeDiff = 0.2 / aDT;
    for(i=0;i<size;i++) {
        m2 = (x2[i]-x1[i]) / aDT;
        m1 = (x1[i]-x0[i]) / aDT;

                
        curvature = (m2 - m1) / aDT;
        curvature = fabs(curvature);

        if(curvature<=thresholdCurvature) continue;
    
//      diff = fabs(m2) - fabs(m1);
//      cout<<"thresholdSlopeDiff="<<thresholdSlopeDiff<<"  slopeDiff="<<diff<<endl;
//      if(diff>thresholdSlopeDiff) continue;
        
        

        // ALTER CONTROL VALUE
        rControls[i] = (3.0*x2[i] + 2.0*x1[i] + x0[i]) / 6.0;

        // PRINT
        if(aVerbosePrinting) cout<<aControlSet[i].getName()<<": old="<<x2[i]<<" new="<<rControls[i]<<endl;
    }

    if(aVerbosePrinting) cout<<endl<<endl;
}
Exemplo n.º 9
0
/**
 * This method is called at the beginning of an analysis so that any
 * necessary initializations may be performed.
 *
 * This method is meant to be called at the beginning of an integration 
 *
 * This method should be overridden in the child class.  It is
 * included here so that the child class will not have to implement it if it
 * is not necessary.
 *
 * @param s System state
 *
 * @return -1 on error, 0 otherwise.
 */
int BodyKinematics::
begin(SimTK::State& s )
{
    if(!proceed()) return(0);

    // RESET STORAGE
    _pStore->reset(s.getTime());
    _vStore->reset(s.getTime());
    _aStore->reset(s.getTime());

    // RECORD
    int status = 0;
    if(_pStore->getSize()<=0) {
        status = record(s);
    }

    return(status);
}
Exemplo n.º 10
0
    void IKSolverParallel::pushState(const SimTK::State& s) {

        GeneralisedCoordinatesData currentData(nCoordinates_);
        std::vector<double> q(nCoordinates_);
        SimTK::Vector stateQ(s.getQ());
        for (unsigned i(0); i < nCoordinates_; ++i)
            q[i] = stateQ[i];
        currentData.setQ(q);
        outputGeneralisedCoordinatesQueue_.push({ s.getTime(), currentData });
    }
// compute the control value for an actuator
void PrescribedController::computeControls(const SimTK::State& s, SimTK::Vector& controls) const
{
    SimTK::Vector actControls(1, 0.0);
    SimTK::Vector time(1, s.getTime());

    for(int i=0; i<getActuatorSet().getSize(); i++){
        actControls[0] = get_ControlFunctions()[i].calcValue(time);
        getActuatorSet()[i].addInControls(actControls, controls);
    }  
}
Exemplo n.º 12
0
void ControllerSet::storeControls( const SimTK::State& s, int step  )
{
    int size = _actuatorSet->getSize();
    
	if( size > 0 )
	{
		_controlStore->store( step, s.getTime(), getModel().getNumControls(), 
			                  &(getModel().getControls(s)[0]) );
    }
}
Array<bool> InducedAccelerationsSolver::
    applyContactConstraintAccordingToExternalForces(SimTK::State &s)
{
    Array<bool> constraintOn(false, _replacementConstraints.getSize());
    double t = s.getTime();

    for(int i=0; i<_forcesToReplace.getSize(); i++){
        ExternalForce* exf = dynamic_cast<ExternalForce*>(&_forcesToReplace[i]);
        SimTK::Vec3 point, force, gpoint;

        force = exf->getForceAtTime(t);
        
        // If the applied force is "significant" replace it with a constraint
        if (force.norm() > _forceThreshold){
            // get the point of contact from applied external force
            point = exf->getPointAtTime(t);
            // point should be expressed in the "applied to" body for consistency across all constraints
            if(exf->getPointExpressedInBodyName() != exf->getAppliedToBodyName()){
                int appliedToBodyIndex = getModel().getBodySet().getIndex(exf->getAppliedToBodyName());
                if(appliedToBodyIndex < 0){
                    cout << "External force appliedToBody " <<  exf->getAppliedToBodyName() << " not found." << endl;
                }

                int expressedInBodyIndex = getModel().getBodySet().getIndex(exf->getPointExpressedInBodyName());
                if(expressedInBodyIndex < 0){
                    cout << "External force expressedInBody " <<  exf->getPointExpressedInBodyName() << " not found." << endl;
                }

                const Body &appliedToBody = getModel().getBodySet().get(appliedToBodyIndex);
                const Body &expressedInBody = getModel().getBodySet().get(expressedInBodyIndex);

                getModel().getMultibodySystem().realize(s, SimTK::Stage::Velocity);
                getModel().getSimbodyEngine().transformPosition(s, expressedInBody, point, appliedToBody, point);
            }

            _replacementConstraints[i].setContactPointForInducedAccelerations(s, point);

            // turn on the constraint
            _replacementConstraints[i].setDisabled(s, false);
            // return the state of the constraint
            constraintOn[i] = true;

        }
        else{
            // turn off the constraint
            _replacementConstraints[i].setDisabled(s, true);
            // return the state of the constraint
            constraintOn[i] = false;
        }
    }

    return constraintOn;
}
void StaticOptimizationTarget::
printPerformance(const SimTK::State& s, double *parameters)
{
    double p;
    setCurrentState( &s );
    objectiveFunc(SimTK::Vector(getNumParameters(),parameters,true),true,p);
    SimTK::Vector constraints(getNumConstraints());
    constraintFunc(SimTK::Vector(getNumParameters(),parameters,true),true,constraints);
    cout << endl;
    cout << "time = " << s.getTime() <<" Performance =" << p << 
    " Constraint violation = " << sqrt(~constraints*constraints) << endl;
}
Exemplo n.º 15
0
// Controller Interface. 
// compute the control value for all actuators this Controller is responsible for
void CMC::computeControls(const SimTK::State& s, SimTK::Vector& controls)  const
{
    SimTK_ASSERT( _controlSet.getSize() == getActuatorSet().getSize() , 
        "CMC::computeControls number of controls does not match number of actuators.");
    
    SimTK::Vector actControls(1, 0.0);
    for(int i=0; i<getActuatorSet().getSize(); i++){
        actControls[0] = _controlSet[_controlSetIndices[i]].getControlValue(s.getTime());
        getActuatorSet()[i].addInControls(actControls, controls);
    }

    // double *val = &controls[0];
}
Exemplo n.º 16
0
/**
 * Record the kinematics.
 *
 * @return 0 of success, -1 on error.
 */
int Kinematics::record(const SimTK::State& s)
{
	if(_recordAccelerations){
		_model->getMultibodySystem().realize(s, SimTK::Stage::Acceleration);
    }
	else{
		_model->getMultibodySystem().realize(s, SimTK::Stage::Velocity);
    }
	// RECORD RESULTS
	const CoordinateSet& cs = _model->getCoordinateSet();
	int nvalues = _coordinateIndices.getSize();
	for(int i=0;i<nvalues;i++){
		_values[i] = cs[_coordinateIndices[i]].getValue(s);
		if(getInDegrees() && (cs[_coordinateIndices[i]].getMotionType() == Coordinate::Rotational))
			_values[i] *= SimTK_RADIAN_TO_DEGREE;
	}
	_pStore->append(s.getTime(),nvalues,&_values[0]);

	for(int i=0;i<nvalues;i++){
		_values[i] = cs[_coordinateIndices[i]].getSpeedValue(s);
		if(getInDegrees() && (cs[_coordinateIndices[i]].getMotionType() == Coordinate::Rotational))
			_values[i] *= SimTK_RADIAN_TO_DEGREE;
	}

	_vStore->append(s.getTime(),nvalues,&_values[0]);

	if(_recordAccelerations) {
		for(int i=0;i<nvalues;i++){
			_values[i] = cs[_coordinateIndices[i]].getAccelerationValue(s);
			if(getInDegrees() && (cs[_coordinateIndices[i]].getMotionType() == Coordinate::Rotational))
				_values[i] *= SimTK_RADIAN_TO_DEGREE;
		}
		_aStore->append(s.getTime(),nvalues,&_values[0]);
	}


	return(0);
}
void PrescribedForce::computeForce(const SimTK::State& state, 
                              SimTK::Vector_<SimTK::SpatialVec>& bodyForces, 
                              SimTK::Vector& generalizedForces) const
{
    const bool pointIsGlobal = get_pointIsGlobal();
    const bool forceIsGlobal = get_forceIsGlobal();
    const FunctionSet& forceFunctions = getForceFunctions();
    const FunctionSet& pointFunctions = getPointFunctions();
    const FunctionSet& torqueFunctions = getTorqueFunctions();

    double time = state.getTime();
    SimTK::Vector  timeAsVector(1, time);

    const bool hasForceFunctions  = forceFunctions.getSize()==3;
    const bool hasPointFunctions  = pointFunctions.getSize()==3;
    const bool hasTorqueFunctions = torqueFunctions.getSize()==3;

    const PhysicalFrame& frame =
        getConnector<PhysicalFrame>("frame").getConnectee();
    const Ground& gnd = getModel().getGround();
    if (hasForceFunctions) {
        Vec3 force(forceFunctions[0].calcValue(timeAsVector), 
                   forceFunctions[1].calcValue(timeAsVector), 
                   forceFunctions[2].calcValue(timeAsVector));
        if (!forceIsGlobal)
            force = frame.expressVectorInAnotherFrame(state, force, gnd);

        Vec3 point(0); // Default is body origin.
        if (hasPointFunctions) {
            // Apply force to a specified point on the body.
            point = Vec3(pointFunctions[0].calcValue(timeAsVector), 
                         pointFunctions[1].calcValue(timeAsVector), 
                         pointFunctions[2].calcValue(timeAsVector));
            if (pointIsGlobal)
                point = gnd.findLocationInAnotherFrame(state, point, frame);

        }
        applyForceToPoint(state, frame, point, force, bodyForces);
    }
    if (hasTorqueFunctions){
        Vec3 torque(torqueFunctions[0].calcValue(timeAsVector), 
                    torqueFunctions[1].calcValue(timeAsVector), 
                    torqueFunctions[2].calcValue(timeAsVector));
        if (!forceIsGlobal)
            torque = frame.expressVectorInAnotherFrame(state, torque, gnd);

         applyTorque(state, frame, torque, bodyForces);
    }
}
Exemplo n.º 18
0
    // WITNESS FUNCTION
    SimTK::Real getValue(const SimTK::State& s) const
	{

		// keep returning a positive value while the contact settles out
		double simTime = s.getTime();
		if (simTime < settleTime) {
			return 100.0;
		}

		// total vertical force applied to both feet
		Array<double> force_foot_r = _model.getForceSet().get("foot_r").getRecordValues(s);
		Array<double> force_foot_l = _model.getForceSet().get("foot_l").getRecordValues(s);
		double netGRFVertical = -force_foot_r[1] - force_foot_l[1];
		return netGRFVertical - _forceThreshold;
	}
/**
 * Record the kinematics.
 */
int PointKinematics::
record(const SimTK::State& s)
{
	const SimbodyEngine& de = _model->getSimbodyEngine();

	// VARIABLES
	SimTK::Vec3 vec;

	// POSITION
	de.getPosition(s, *_body,_point,vec);
	if(_relativeToBody){

		de.transformPosition(s, de.getGroundBody(), vec, *_relativeToBody, vec);
	}

	_pStore->append(s.getTime(),vec);

	// VELOCITY
	de.getVelocity(s, *_body,_point,vec);
	if(_relativeToBody){
		de.transform(s, de.getGroundBody(), vec, *_relativeToBody, vec);
	}

	_vStore->append(s.getTime(),vec);

	// ACCELERATIONS
	_model->getMultibodySystem().realize(s, SimTK::Stage::Acceleration);
	de.getAcceleration(s, *_body,_point,vec);
	if(_relativeToBody){
		de.transform(s, de.getGroundBody(), vec, *_relativeToBody, vec);
	}

	_aStore->append(s.getTime(),vec);

	return(0);
}
Exemplo n.º 20
0
/** get the values of the MarkersReference */
void  MarkersReference::getValues(const SimTK::State &s, SimTK::Array_<Vec3> &values) const
{
    double time =  s.getTime();

    int before=0, after=0;
    // get index for time 
    _markerData->findFrameRange(time, time, before, after);
    if(before > after || after < 0)
        throw Exception("MarkersReference: No index corresponding to time of frame.");
    else if(after-before > 0){
        before = abs(_markerData->getFrame(before).getFrameTime()-time) < abs(_markerData->getFrame(after).getFrameTime()-time) ? before : after;
    }

    values = _markerData->getFrame(before).getMarkers();
}
/**
 * Given SimTK::State object extract all the values necessary to report forces, application location
 * frame, etc. used in conjunction with getRecordLabels and should return same size Array
 */
OpenSim::Array<double> PrescribedForce::getRecordValues(const SimTK::State& state) const {
    OpenSim::Array<double>  values(SimTK::NaN);

    const bool pointIsGlobal = get_pointIsGlobal();
    const bool forceIsGlobal = get_forceIsGlobal();

    const FunctionSet& forceFunctions = getForceFunctions();
    const FunctionSet& pointFunctions = getPointFunctions();
    const FunctionSet& torqueFunctions = getTorqueFunctions();

    const bool appliesForce   = forceFunctions.getSize()==3;
    const bool pointSpecified = pointFunctions.getSize()==3;
    const bool appliesTorque  = torqueFunctions.getSize()==3;

    // This is bad as it duplicates the code in computeForce we'll cleanup after it works!
    const double time = state.getTime();
    const SimTK::Vector timeAsVector(1, time);
    const PhysicalFrame& frame =
        getConnector<PhysicalFrame>("frame").getConnectee();
    const Ground& gnd = getModel().getGround();
    if (appliesForce) {
        Vec3 force = getForceApplied(state);
        if (!forceIsGlobal)
            force = frame.expressVectorInAnotherFrame(state, force, gnd);

        if (!pointSpecified) {
            //applyForce(*_body, force);
            for (int i=0; i<3; i++) values.append(force[i]);
        } else {
            Vec3 point = getApplicationPoint(state);
            if (pointIsGlobal)
                point = gnd.findLocationInAnotherFrame(state, point, frame);

            //applyForceToPoint(*_body, point, force);
            for (int i=0; i<3; i++) values.append(force[i]);
            for (int i=0; i<3; i++) values.append(point[i]);
        }
    }
    if (appliesTorque) {
        Vec3 torque = getTorqueApplied(state);
        if (!forceIsGlobal)
            torque = frame.expressVectorInAnotherFrame(state, torque, gnd);

        for (int i=0; i<3; i++) values.append(torque[i]);
        //applyTorque(*_body, torque);
    }
    return values;
};
Exemplo n.º 22
0
/**
 * Apply the muscle's force at its points of attachment to the bodies.
 */
void Muscle::computeForce(const SimTK::State& s, 
                          SimTK::Vector_<SimTK::SpatialVec>& bodyForces, 
                          SimTK::Vector& generalizedForces) const
{
    Super::computeForce(s, bodyForces, generalizedForces); // Calls compute actuation.

    // NOTE: Actuation could be negative, in particular during CMC, when the optimizer
    // is computing gradients, but in those cases the actuation will be 
    // overridden and will not be computed by the muscle
    if (!isActuationOverridden(s) && (getActuation(s) < -SimTK::SqrtEps)) {
        string msg = getConcreteClassName()
            + "::computeForce, muscle "+ getName() + " force < 0";
        cout << msg << " at time = " << s.getTime() << endl;
        //throw Exception(msg);
    }
}
/**
 * This method is called at the beginning of an analysis so that any
 * necessary initializations may be performed.
 *
 * This method is meant to be called at the begining of an integration in
 * Model::integBeginCallback() and has the same argument list.
 *
 * @param aStep Step number of the integration.
 * @param aDT Size of the time step that will be attempted.
 * @param aT Current time in the integration.
 * @param aX Current control values.
 * @param aY Current states.
 * @param aYP Current pseudo states.
 * @param aDYDT Current state derivatives.
 *
 * @return -1 on error, 0 otherwise.
 */
int AnalysisPlugin_Template::
begin(SimTK::State& s)
{
    if(!proceed()) return(0);

    // RESET STORAGE
    _storePos.reset(s.getTime());  //->reset(s.getTime());

    // RECORD
    int status = 0;
    if(_storePos.getSize()<=0) {
        status = record(s);
    }

    return(status);
}
/**
 * This method is called at the beginning of an analysis so that any
 * necessary initializations may be performed.
 *
 * This method is meant to be called at the begining of an integration 
 *
 * @param s reference to the current state
 *
 * @return -1 on error, 0 otherwise.
 */
int JointReaction::
begin(SimTK::State& s)
{
	if(!proceed()) return(0);
	// Read forces file here rather than during initialization
	setupStorage();

	// RESET STORAGE
	_storeReactionLoads.reset(s.getTime());

	// RECORD
	int status = 0;
	if(_storeReactionLoads.getSize()<=0) {
		status = record(s);
	}

	return(status);
}
Exemplo n.º 25
0
/** Obtain a model configuration that meets the assembly conditions  
    (desired values and constraints) given a state that satisfies or
    is close to satisfying the constraints. Note there can be no change
    in the number of constraints or desired coordinates. Desired
    coordinate values can and should be updated between repeated calls
    to track a desired trajectory of coordinate values. */
void AssemblySolver::track(SimTK::State &s)
{

    // move the target locations or angles, etc... just do not change number of goals
    // and their type (constrained vs. weighted)

    if(_assembler && _assembler->isInitialized()){
        updateGoals(s);
    }
    else{
        throw Exception(
            "AssemblySolver::track() failed: assemble() must be called first.");
    }

    /* TODO: Useful to include through debug message/log in the future
    printf("UNASSEMBLED(track) CONFIGURATION (normerr=%g, maxerr=%g, cost=%g)\n",
        _assembler->calcCurrentErrorNorm(), 
        max(abs(_assembler->getInternalState().getQErr())), 
        _assembler->calcCurrentGoal() );
    cout << "Model numQs: " << _assembler->getInternalState().getNQ() 
        << " Assembler num freeQs: " << _assembler->getNumFreeQs() << endl;
    */

    try{
        // Now do the assembly and return the updated state.
        _assembler->track(s.getTime());

        // update the state from the result of the assembler 
        _assembler->updateFromInternalState(s);
        
        /* TODO: Useful to include through debug message/log in the future
        printf("Tracking: t= %f (acc=%g tol=%g normerr=%g, maxerr=%g, cost=%g)\n", 
            s.getTime(),
            _assembler->getAccuracyInUse(), _assembler->getErrorToleranceInUse(), 
            _assembler->calcCurrentErrorNorm(), max(abs(_assembler->getInternalState().getQErr())),
            _assembler->calcCurrentGoal()); 
        */
    }
    catch (const std::exception& ex)
    {
        std::cout << "AssemblySolver::track() attempt Failed: " << ex.what() << std::endl;
        throw Exception("AssemblySolver::track() attempt failed.");
    }
}
Exemplo n.º 26
0
/**
 * Compute the controls for Actuator's that this Controller is charge of.
 *
 */
void CorrectionController::computeControls(const SimTK::State& s, SimTK::Vector& controls) const
{
	// NUMBER OF MODEL COORDINATES, SPEEDS, AND ACTUATORS
	// (ALL ARE PROBABLY EQUAL)
	int nq = _model->getNumCoordinates();
	int nu = _model->getNumSpeeds();

	double t = s.getTime();
	
	// GET CURRENT DESIRED COORDINATES AND SPEEDS
	// Note: yDesired[0..nq-1] will contain the generalized coordinates
	// and yDesired[nq..nq+nu-1] will contain the generalized speeds.
	Array<double> yDesired(0.0,nq+nu);
	getDesiredStatesStorage().getDataAtTime(t, nq+nu,yDesired);
	
	SimTK::Vector actControls(1, 0.0);

   	for(int i=0; i< getActuatorSet().getSize(); i++){
		CoordinateActuator* act = 
			dynamic_cast<CoordinateActuator*>(&getActuatorSet().get(i));
		SimTK_ASSERT( act,  "CorrectionController::computeControls dynamic cast failed");

		Coordinate *aCoord = act->getCoordinate();
		if( aCoord->isConstrained(s) ) {
			actControls =  0.0;
		} 
		else
		{
			double qval = aCoord->getValue(s);
			double uval = aCoord->getSpeedValue(s);

    		// COMPUTE EXCITATIONS
			double oneOverFmax = 1.0 / act->getOptimalForce();
			double pErr = qval - yDesired[2*i];
			double vErr = uval - yDesired[2*i+1];
			double pErrTerm = _kp*oneOverFmax*pErr;
			double vErrTerm = _kv*oneOverFmax*vErr;
			actControls = -vErrTerm - pErrTerm;
		}

		
		getActuatorSet()[i].addInControls(actControls, controls);
	}
}
/**
 * Compute and record the results.
 *
 * This method, for the purpose of example, records the position and
 * orientation of each body in the model.  You will need to customize it
 * to perform your analysis.
 *
 * @param aT Current time in the simulation.
 * @param aX Current values of the controls.
 * @param aY Current values of the states: includes generalized coords and speeds
 */
int AnalysisPlugin_Template::
record(const SimTK::State& s)
{
    // VARIABLES
    double dirCos[3][3];
    SimTK::Vec3 vec,angVec;
    double Mass = 0.0;

    // GROUND BODY
    const Body& ground = _model->getGroundBody();

    // POSITION
    const BodySet& bodySet = _model->getBodySet();

    for(int i=0;i<_bodyIndices.getSize();i++) {

        const Body& body = bodySet.get(_bodyIndices[i]);
        SimTK::Vec3 com = body.getMassCenter();

        // GET POSITIONS AND EULER ANGLES
        _model->getSimbodyEngine().getPosition(s,body,com,vec);
        _model->getSimbodyEngine().getDirectionCosines(s,body,dirCos);
        _model->getSimbodyEngine().convertDirectionCosinesToAngles(dirCos,
            &angVec[0],&angVec[1],&angVec[2]);

        // CONVERT TO DEGREES?
        if(getInDegrees()) {
            angVec *= SimTK_RADIAN_TO_DEGREE;
        }           

        // FILL KINEMATICS ARRAY
        int I=6*i;
        memcpy(&_bodypos[I],&vec[0],3*sizeof(double));
        memcpy(&_bodypos[I+3],&angVec[0],3*sizeof(double));
    }
    _storePos.append(s.getTime(),_bodypos.getSize(),&_bodypos[0]);

    // VELOCITY 

    // ACCELERATIONS


    return(0);
}
Exemplo n.º 28
0
/**
 * This method is called at the beginning of an analysis so that any
 * necessary initializations may be performed.
 *
 * This method is meant to be called at the begining of an integration in
 * Model::integBeginCallback() and has the same argument list.
 *
 * @param s SimTK:State
 *
 * @return -1 on error, 0 otherwise.
 */
int InducedAccelerations::begin(SimTK::State &s)
{
	if(!proceed()) return(0);

	initialize(s);

	// RESET STORAGES
	for(int i = 0; i<_storeInducedAccelerations.getSize(); i++){
		_storeInducedAccelerations[i]->reset(s.getTime());
	}

	cout << "Performing Induced Accelerations Analysis" << endl;

	// RECORD
	int status = 0;
	status = record(s);

	return(status);
}
Exemplo n.º 29
0
/**
 * This method is called at the beginning of an analysis so that any
 * necessary initializations may be performed.
 *
 *
 * This method should be overridden in the child class.  It is
 * included here so that the child class will not have to implement it if it
 * is not necessary.
 *
 * @param state system State
 * @param aStep Step number of the integration.
 *
 * @return -1 on error, 0 otherwise.
 */
int ForceReporter::
begin(SimTK::State& s)
{
    if(!proceed()) return(0);

    tidyForceNames();
    // LABELS
    constructColumnLabels(s);
    // RESET STORAGE
    _forceStore.reset(s.getTime());

    // RECORD
    int status = 0;
    if(_forceStore.getSize()<=0) {
        status = record(s);
    }

    return(status);
}
Exemplo n.º 30
0
/**
 * Record the ForceReporter quantities.
 */
int ForceReporter::record(const SimTK::State& s)
{
    if(_model==NULL) return(-1);

    // MAKE SURE ALL ForceReporter QUANTITIES ARE VALID
    _model->getMultibodySystem().realize(s, SimTK::Stage::Dynamics );

    StateVector nextRow = StateVector(s.getTime());

    // NUMBER OF Forces
    const ForceSet& forces = _model->getForceSet(); // This does not contain gravity
    int nf = forces.getSize();

    for(int i=0;i<nf;i++) {
        // If body force we need to record six values for torque+force
        // If muscle we record one scalar
        OpenSim::Force& nextForce = (OpenSim::Force&)forces[i];
        if (nextForce.isDisabled(s)) continue;
        Array<double> values = nextForce.getRecordValues(s);
        nextRow.getData().append(values);
    }

    if(_includeConstraintForces){
        // NUMBER OF Constraints
        const ConstraintSet& constraints = _model->getConstraintSet(); // This does not contain gravity
        int nc = constraints.getSize();

        for(int i=0;i<nc;i++) {
            OpenSim::Constraint& nextConstraint = (OpenSim::Constraint&)constraints[i];
            if (nextConstraint.isDisabled(s)) continue;
            Array<double> values = nextConstraint.getRecordValues(s);
            nextRow.getData().append(values);
        }
    }
    _forceStore.append(nextRow);

    return(0);
}