/** Internal method to convert the MarkerReferences into additional goals of the 
    of the base assembly solver, that is going to do the assembly.  */
void InverseKinematicsSolver::setupGoals(SimTK::State &s)
{
    // Setup coordinates performed by the base class
    AssemblySolver::setupGoals(s);

    _markerAssemblyCondition = new SimTK::Markers();

    // Setup markers goals
    // Get lists of all markers by names and corresponding weights from the MarkersReference
    const SimTK::Array_<SimTK::String> &markerNames = _markersReference.getNames();
    SimTK::Array_<double> markerWeights;  
    _markersReference.getWeights(s, markerWeights);
    // get markers defined by the model 
    const MarkerSet &modelMarkerSet = getModel().getMarkerSet();

    // get markers with specified tasks/weights
    const Set<MarkerWeight>& mwSet = _markersReference.updMarkerWeightSet();
    
    int index = -1;
    int wIndex = -1;
    SimTK::Transform X_BF;
    //Loop through all markers in the reference
    for(unsigned int i=0; i < markerNames.size(); ++i){
        // Check if we have this marker in the model, else ignore it
        index = modelMarkerSet.getIndex(markerNames[i], index);
        wIndex = mwSet.getIndex(markerNames[i],wIndex);
        if((index >= 0) && (wIndex >=0)){
            Marker &marker = modelMarkerSet[index];
            const SimTK::MobilizedBody& mobod =
                marker.getReferenceFrame().getMobilizedBody();

            X_BF = marker.getReferenceFrame().findTransformInBaseFrame();
            _markerAssemblyCondition->
                addMarker(marker.getName(), mobod, X_BF*marker.get_location(),

                markerWeights[i]);

            //cout << "IKSolver Marker: " << markerNames[i] << " " << marker.getName() << "  weight: " << markerWeights[i] << endl;
        }
    }

    // Add marker goal to the ik objective
    _assembler->adoptAssemblyGoal(_markerAssemblyCondition);
    // lock-in the order that the observations (markers) are in and this cannot change from frame to frame
    // and we can use an array of just the data for updating
    _markerAssemblyCondition->defineObservationOrder(markerNames);

    updateGoals(s);
}
Ejemplo n.º 2
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.");
    }
}