void testVisModel(string fileName)
{

    Model* model = new Model(fileName, true);
    SimTK::State& si = model->initSystem();
    ModelDisplayHints mdh; 
    SimTK::Array_<SimTK::DecorativeGeometry> geometryToDisplay;
    model->generateDecorations(true, mdh, si, geometryToDisplay);
    cout << geometryToDisplay.size() << endl;
    model->generateDecorations(false, mdh, si, geometryToDisplay);
    cout << geometryToDisplay.size() << endl;
    DecorativeGeometryImplementationText dgiText;
    for (unsigned i = 0; i < geometryToDisplay.size(); i++)
        geometryToDisplay[i].implementGeometry(dgiText);

    std::string baseName = fileName.substr(0, fileName.find_last_of('.'));
    std::ifstream t("vis_" + baseName + ".txt");
    if (!t.good()) throw OpenSim::Exception("Could not open file.");
    std::stringstream buffer;
    buffer << t.rdbuf();
    std::string fromFile = buffer.str();
    std::string fromModel = dgiText.getAsString();
    cout << "From Model " << endl << "=====" << endl;
    cout << fromModel << endl;
    cout << "From File " << endl << "=====" << endl;
    cout << fromFile << endl;
    int same = fromFile.compare(fromModel);
    delete model;
    ASSERT(same == 0, __FILE__, __LINE__, "Files do not match.");
}
// Handle conversion from older format
void VisibleObject::updateFromXMLNode(SimTK::Xml::Element& aNode, int versionNumber)
{ 
    SimTK::Array_<SimTK::String> oldGeometryFiles;
	if ( versionNumber < XMLDocument::getLatestVersion()){
		if (versionNumber<20101){
			SimTK::Xml::element_iterator visPropIter = aNode.element_begin("VisibleProperties");
			// Get geometry files and Preferences if any and set them into 
			if (visPropIter!=aNode.element_end()){
				// Move display_prference, and show_axes nodes up to VisibleObject
				SimTK::Xml::element_iterator  prefIter = visPropIter->element_begin("display_preference");
				if (prefIter!= visPropIter->element_end()){
					SimTK::Xml::Node moveNode = visPropIter->removeNode(prefIter);
					aNode.insertNodeAfter(aNode.element_end(), moveNode);
				}
				SimTK::Xml::element_iterator  showAxesIter = visPropIter->element_begin("show_axes");
				if (showAxesIter!=aNode.element_end()){
					SimTK::Xml::Node moveNode = visPropIter->removeNode(showAxesIter);
					aNode.insertNodeAfter(aNode.element_end(), moveNode);
				}
			}
			SimTK::Xml::element_iterator geometryIter = aNode.element_begin("geometry_files");
			string propValue="";
			bool hasPieces=false;
			if (geometryIter!= aNode.element_end()){
				geometryIter->getValueAs(oldGeometryFiles);
			}
        }
    }
	Object::updateFromXMLNode(aNode, versionNumber);
    if (oldGeometryFiles.size()>0){
        for(unsigned i=0; i< oldGeometryFiles.size(); i++) 
            setGeometryFileName(i, oldGeometryFiles[i]);
    }
}
/** Update all markers weights by order in the markersReference passed in to
    construct the solver. */
void InverseKinematicsSolver::updateMarkerWeights(const SimTK::Array_<double> &weights)
{
    if(_markersReference.updMarkerWeightSet().getSize() == weights.size()){
        for(unsigned int i=0; i<weights.size(); i++){
            _markersReference.updMarkerWeightSet()[i].setWeight(weights[i]);
            _markerAssemblyCondition->changeMarkerWeight(SimTK::Markers::MarkerIx(i), weights[i]);
        }
    }
    else
        throw Exception("InverseKinematicsSolver::updateMarkerWeights: invalid size of weights.");
}
Example #4
0
void Geometry::generateDecorations(bool fixed, const ModelDisplayHints& hints, const SimTK::State& state,
    SimTK::Array_<SimTK::DecorativeGeometry>& appendToThis) const
{
    if (!fixed) return; // serialized Geometry is assumed fixed
    SimTK::Array_<SimTK::DecorativeGeometry> decos;
    implementCreateDecorativeGeometry(decos);
    if (decos.size() == 0) return;
    setDecorativeGeometryTransform(decos, state);
    for (unsigned i = 0; i < decos.size(); i++){
        setDecorativeGeometryAppearance(decos[i]);
        appendToThis.push_back(decos[i]);
    }
}
int SegmentedQuinticBezierToolkit::calcIndex(double x, 
                                             const SimTK::Array_<SimTK::Vector>& bezierPtsX)
{
    int idx = 0;
    bool flag_found = false;

    int n = bezierPtsX.size(); 
    for(int i=0; i<n; i++){
        if( x >= bezierPtsX[i](0) && x < bezierPtsX[i](5) ){
            idx = i;
            flag_found = true;
            break; 
        }
    }

    //Check if the value x is identically the last point
    if(!flag_found && x == bezierPtsX[n-1](5)){
        idx = n-1;
        flag_found = true;
    }

    SimTK_ERRCHK_ALWAYS( (flag_found == true), 
        "SegmentedQuinticBezierToolkit::calcIndex", 
        "Error: A value of x was used that is not within the Bezier curve set.");

    return idx;
}
Example #6
0
void checkMarkersReferenceConsistencyFromTool(InverseKinematicsTool& ik)
{
    MarkersReference markersReference;
    SimTK::Array_<CoordinateReference> coordinateReferences;

    ik.populateReferences(markersReference, coordinateReferences);
    const IKTaskSet& tasks = ik.getIKTaskSet();

    // Need a model to get a state, doesn't matter which model.
    Model model;
    SimTK::State& state = model.initSystem();

    SimTK::Array_<string> names = markersReference.getNames();
    SimTK::Array_<double> weights;
    markersReference.getWeights(state, weights);

    for (unsigned int i=0; i < names.size(); ++i) {
        std::cout << names[i] << ": " << weights[i];
        int ix = tasks.getIndex(names[i]);
        if (ix > -1) {
            cout << " in TaskSet: " << tasks[ix].getWeight() << endl;
            SimTK_ASSERT_ALWAYS(weights[i] == tasks[ix].getWeight(),
                "Mismatched weight to marker task");
        }
        else {
            cout << " default: " << markersReference.get_default_weight() << endl;
            SimTK_ASSERT_ALWAYS(
                weights[i] == markersReference.get_default_weight(),
                "Mismatched weight to default weight");
        }
    }
}
	double calcDerivative(const SimTK::Array_<int>& derivComponents, const SimTK::Vector& x) const {
		if (derivComponents.size() == 1){
			if (derivComponents[0]==0){
				SimTK::Vector x1(1);
				x1[0] = x[0];
				return scale*f1->calcDerivative(derivComponents, x1);
			}
			else if (derivComponents[0]==1)
				return -1;
		}
		else if(derivComponents.size() == 2){
			if (derivComponents[0]==0 && derivComponents[1] == 0){
				SimTK::Vector x1(1);
				x1[0] = x[0];
				return scale*f1->calcDerivative(derivComponents, x1);
			}
		}
        return 0;
    }
int main()
{
    SimTK::Array_<std::string> failures;

    // get all registered Components
    SimTK::Array_<Component*> availableComponents;

    // starting with type Frame
    ArrayPtrs<Frame> availableFrames;
    Object::getRegisteredObjectsOfGivenType(availableFrames);
    for (int i = 0; i < availableFrames.size(); ++i) {
        availableComponents.push_back(availableFrames[i]);
    }

    // then type Joint
    ArrayPtrs<Joint> availableJoints;
    Object::getRegisteredObjectsOfGivenType(availableJoints);
    for (int i = 0; i < availableJoints.size(); ++i) {
        availableComponents.push_back(availableJoints[i]);
    }

    // continue with Constraint, Actuator, Frame, ...
    //Example of an updated force that passes
    ArrayPtrs<PointToPointSpring> availablePointToPointSpring;
    Object::getRegisteredObjectsOfGivenType(availablePointToPointSpring);
    availableComponents.push_back(availablePointToPointSpring[0]);

    for (unsigned int i = 0; i < availableComponents.size(); i++) {
        try {
            testComponent(*availableComponents[i]);
        }
        catch (const std::exception& e) {
            cout << "*******************************************************\n";
            cout<< "FAILURE: " << availableComponents[i]->getConcreteClassName() << endl;
            cout<< e.what() << endl;
            failures.push_back(availableComponents[i]->getConcreteClassName());
        }
    }
    
    if (!failures.empty()) {
        cout << "*******************************************************\n";
        cout << "Done, with failure(s): " << failures << endl;
        cout << failures.size() << "/" << availableComponents.size() 
            << " components failed test." << endl;
        cout << 100 * (availableComponents.size() - failures.size()) / availableComponents.size()
            << "% components passed." << endl;
        cout << "*******************************************************\n" << endl;
        return 1;
    }
    cout << "\ntestComponents PASSED. " << availableComponents.size() 
        << " components were tested." << endl;
}
int main()
{
    try {
        Storage result("Arm26_optimized_states.sto"),
                standard("std_Arm26_optimized_states.sto");
        CHECK_STORAGE_AGAINST_STANDARD(result, standard, Array<double>(0.01, 16),
            __FILE__, __LINE__, "Arm26 states failed comparison test");
        cout << "Arm26 states comparison test passed\n";

        // Ensure the optimization result acheived a velocity of at least
        // REF_MAX_VEL, and that the control values are within either 20% of the
        // reference values or 0.05 in absolute value.
        ifstream resFile;
        resFile.open("Arm26_optimization_result");
        ASSERT(resFile.is_open(), __FILE__, __LINE__,
               "Can't open optimization result file" );

        SimTK::Array_<double> resVec;
        for ( ; ; ) {
            double tmp;
            resFile >> tmp;
            if (!resFile.good())
                break;
            resVec.push_back(tmp);
        }

        ASSERT(resVec.size() == ARM26_DESIGN_SPACE_DIM+1, __FILE__, __LINE__,
               "Optimization result size mismatch" );
        
        // Ensure the optimizer found a local minimum we expect.
        for (int i = 0; i < ARM26_DESIGN_SPACE_DIM-1; ++i) {
            ASSERT(fabs(resVec[i] - refControls[i])/refControls[i] < 0.2 ||
                   fabs(resVec[i] - refControls[i]) < 0.05, __FILE__, __LINE__,
                   "Control value does not match reference" );
        }
        ASSERT(resVec[ARM26_DESIGN_SPACE_DIM] > REF_MAX_VEL, __FILE__, __LINE__,
               "Optimized velocity smaller than reference" );

        cout << "Arm26 optimization results passed\n";
    }
    catch (const Exception& e) {
        e.print(cerr);
        return 1;
    }
    cout << "Done" << endl;
    return 0;
}
Example #10
0
/**
 * Compute Transform of a Geometry w.r.t. passed in Frame
 * Both Frame(s) could be Bodies, state is assumed to be realized to position
*/
void Geometry::setDecorativeGeometryTransform(SimTK::Array_<SimTK::DecorativeGeometry>& decorations, const SimTK::State& state) const
{
    const Frame& myFrame = getFrame();
    const Frame& bFrame = myFrame.findBaseFrame();
    const PhysicalFrame* bPhysicalFrame = dynamic_cast<const PhysicalFrame*>(&bFrame);
    if (bPhysicalFrame == nullptr){
        // throw exception something is wrong
        throw (Exception("Frame for Geometry " + getName() + " is not attached to a PhysicalFrame."));
    }
    const SimTK::MobilizedBodyIndex& idx = bPhysicalFrame->getMobilizedBodyIndex();
    SimTK::Transform transformInBaseFrame = myFrame.findTransformInBaseFrame();
    for (unsigned i = 0; i < decorations.size(); i++){
        decorations[i].setBodyId(idx);
        decorations[i].setTransform(transformInBaseFrame);
        decorations[i].setIndexOnBody(i);
    }
}
int main()
{
	try {	
		Storage result("Arm26_noActivation_states.sto"), standard("std_Arm26_noActivation_states.sto");
		CHECK_STORAGE_AGAINST_STANDARD(result, standard, Array<double>(0.01, 16), __FILE__, __LINE__, "Arm26 no activation states failed");
		cout << "Arm26 no activation states passed\n";

		// Check the optimization result acheived at least a velocity of 5.43 m/s, and that the control values are within either 20% 
		// of the reference values or 0.05 in absolute value.
		ifstream resFile; 
		resFile.open("Arm26_optimization_result"); 
		ASSERT(resFile.is_open(), __FILE__, __LINE__, "Can't open optimization result file" );

		SimTK::Array_<double> resVec;
		for ( ; ; ) {
			double tmp;
			resFile >> tmp;   
			if (!resFile.good()) 
				break; 
			resVec.push_back(tmp); 
		}
	
		ASSERT(resVec.size() == ARM26_DESIGN_SPACE_DIM+1, __FILE__, __LINE__, "Optimization result size mismatch" );
		
		// We don't enforce the optimizer to find precisedly the same local minimum for now.   	
		/*for (int i = 0; i < ARM26_DESIGN_SPACE_DIM-1; i++) {
			ASSERT(fabs(resVec[i] - refControls[i])/refControls[i] < 0.2 || fabs(resVec[i] - refControls[i]) < 0.05, __FILE__, __LINE__, "Control value does not match reference" );
		}*/
		ASSERT(resVec[ARM26_DESIGN_SPACE_DIM] > REF_MAX_VEL, __FILE__, __LINE__, "Optimized velocity smaller than reference" );
		
		cout << "Arm26 optimization results passed\n";
	}
	catch (const Exception& e) {
        e.print(cerr);
        return 1;
    }
    cout << "Done" << endl;
    return 0;
}
Example #12
0
/** Override of the default implementation to account for versioning. */
void CustomJoint::
updateFromXMLNode(SimTK::Xml::Element& aNode, int versionNumber)
{
	int documentVersion = versionNumber;
	if ( documentVersion < XMLDocument::getLatestVersion()){
		if (Object::getDebugLevel()>=1)
			cout << "Updating CustomJoint to latest format..." << endl;
		// Version before refactoring spatialTransform
		if (documentVersion<10901){
			// replace TransformAxisSet with SpatialTransform
			/////renameChildNode("TransformAxisSet", "SpatialTransform");
			// Check how many TransformAxes are defined
			SimTK::Xml::element_iterator spatialTransformNode = 
                aNode.element_begin("TransformAxisSet");
			if (spatialTransformNode == aNode.element_end()) return;

			SimTK::Xml::element_iterator axesSetNode = 
                spatialTransformNode->element_begin("objects");
			/////if (axesSetNode != NULL)
			/////	spatialTransformNode->removeChild(axesSetNode);
			/////DOMElement*grpNode = XMLNode::GetFirstChildElementByTagName(spatialTransformNode,"groups");
			/////if (grpNode != NULL)
			/////	spatialTransformNode->removeChild(grpNode);
			// (0, 1, 2 rotations & 3, 4, 5 translations then remove the is_rotation node)
			SimTK::Array_<SimTK::Xml::Element> list = 
                axesSetNode->getAllElements();
			unsigned int listLength = list.size();
			int objectsFound = 0;
			Array<int> translationIndices(-1, 0);
			Array<int>  rotationIndices(-1, 0);
			int nextAxis = 0;
			std::vector<TransformAxis *> axes;
			// Add children for all six axes here
			//////_node->removeChild(SpatialTransformNode);
			
			// Create a blank Spatial Transform and use it to populate the 
            // XML structure
			for(int i=0; i<6; i++)
				updSpatialTransform()[i].setFunction(new OpenSim::Constant(0));
			
			Array<OpenSim::TransformAxis*> oldAxes;
			for(unsigned int j=0;j<listLength;j++) {
				// getChildNodes() returns all types of DOMNodes including 
                // comments, text, etc., but we only want
				// to process element nodes
				SimTK::Xml::Element objElmt = list[j];
				string objectType = objElmt.getElementTag();
                // (sherm) this is cleaning up old TransformAxis here but
                // that should really be done in TransformAxis instead.
				if (objectType == "TransformAxis"){
					OpenSim::TransformAxis* readAxis = 
                        new OpenSim::TransformAxis(objElmt);
					assert(nextAxis <=5);
					bool isRotation = false;
					SimTK::Xml::element_iterator rotationNode = 
                        objElmt.element_begin("is_rotation");
					if (rotationNode != objElmt.element_end()){
						SimTK::String sValue = 
                            rotationNode->getValueAs<SimTK::String>();
						bool value = (sValue.toLower() == "true");
								isRotation = value;
						objElmt.eraseNode(rotationNode);
							}
					SimTK::Xml::element_iterator coordinateNode = 
                        objElmt.element_begin("coordinate");
					SimTK::String coordinateName = 
                        coordinateNode->getValueAs<SimTK::String>();
					Array<std::string> names("");
					names.append(coordinateName);
					readAxis->setCoordinateNames(names);
					SimTK::Xml::element_iterator axisNode = 
                        objElmt.element_begin("axis");
					
					SimTK::Vec3 axisVec= axisNode->getValueAs<SimTK::Vec3>();
					readAxis->setAxis(axisVec);
					if (isRotation){
						rotationIndices.append(nextAxis);
					}
					else {
						translationIndices.append(nextAxis);
					}
					axes.push_back(readAxis);
					nextAxis++;
				}
			}
			assert(rotationIndices.getSize() <=3);
			assert(translationIndices.getSize() <=3);
			//XMLNode::RemoveChildren(SpatialTransformAxesNode);
			int nRotations = rotationIndices.getSize();
			int nTranslations = translationIndices.getSize();
			// Now copy coordinateName, Axis, Function into proper slot
			for (int i=0; i<nRotations; i++){
				updSpatialTransform()[i] = *axes[rotationIndices[i]];
			}
			updSpatialTransform().constructIndependentAxes(nRotations, 0);
			// Add Translations from old list then pad with default ones, 
            // make sure no singularity.
			for (int i=0; i<nTranslations; i++){
				updSpatialTransform()[i+3] = *axes[translationIndices[i]];
			}
			updSpatialTransform().constructIndependentAxes(nTranslations, 3);
		}
	}

    // Delegate to superclass now.
	Super::updateFromXMLNode(aNode, versionNumber);

	const CoordinateSet& coordinateSet = get_CoordinateSet();

	// Fix coordinate type post deserialization
	// Fix coordinate type post deserialization
	for (int i=0; i<coordinateSet.getSize(); i++){
		OpenSim::Coordinate& nextCoord = coordinateSet.get(i);
		// Find TransformAxis for the coordinate and use it to set Coordinate's motionType
		for(int axisIndex=0; axisIndex<6; axisIndex++){
			const TransformAxis& nextAxis = getSpatialTransform()[axisIndex];
			const Property<std::string>& coordNames = nextAxis.getCoordinateNames();
			if (coordNames.findIndex(nextCoord.getName())!=-1){
				coordinateSet.get(i).setMotionType((axisIndex>2)? 
						Coordinate::Translational : Coordinate::Rotational);
				break;
			}
		}
	}
	// Axes should be independent otherwise Simbody throws an exception in addToSystem
	double tol = 1e-5;
    // Verify that none of the rotation axes are colinear
	const std::vector<SimTK::Vec3> axes=getSpatialTransform().getAxes();
	for(int startIndex=0; startIndex<=3; startIndex+=3){
        if(((axes[startIndex+0]%axes[startIndex+1]).norm() < tol)||
			((axes[startIndex+0]%axes[startIndex+2]).norm() < tol)||
			((axes[startIndex+1]%axes[startIndex+2]).norm() < tol)){
				throw(Exception("CustomJoint " + getName() + 
                    " has colinear axes and so is not well-defined."
                    " Please fix and retry loading.."));
		}
	}
    updProperty_SpatialTransform().setValueIsDefault(false);
}
/** Compute and return the distance errors between all model marker and observations. */
void InverseKinematicsSolver::computeCurrentSquaredMarkerErrors(SimTK::Array_<double> &markerErrors)
{
    markerErrors.resize(_markerAssemblyCondition->getNumMarkers());
    for(unsigned int i=0; i<markerErrors.size(); i++)
        markerErrors[i] = _markerAssemblyCondition->findCurrentMarkerErrorSquared(SimTK::Markers::MarkerIx(i));
}
/** Compute and return the spatial locations of all markers in ground. */
void InverseKinematicsSolver::computeCurrentMarkerLocations(SimTK::Array_<SimTK::Vec3> &markerLocations)
{
    markerLocations.resize(_markerAssemblyCondition->getNumMarkers());
    for(unsigned int i=0; i<markerLocations.size(); i++)
        markerLocations[i] = _markerAssemblyCondition->findCurrentMarkerLocation(SimTK::Markers::MarkerIx(i));
}
Example #15
0
int main()
{
    int itc = 0;
    SimTK::Array_<std::string> failures;

    try { ++itc;
        testInverseKinematicsSolverWithOrientations(); 
    }
    catch (const std::exception& e) {
        cout << e.what() << endl;
        failures.push_back("testInverseKinematicsSolverWithOrientations");
    }

    try {
        ++itc;
        testInverseKinematicsSolverWithEulerAnglesFromFile();
    }
    catch (const std::exception& e) {
        cout << e.what() << endl;
        failures.push_back("testInverseKinematicsSolverWithEulerAnglesFromFile");
    }

    try {
        ++itc;
        testMarkerWeightAssignments("subject01_Setup_InverseKinematics.xml");
    }
    catch (const std::exception& e) {
        cout << e.what() << endl;
        failures.push_back("testMarkerWeightAssignments");
    }

    Storage  standard("std_subject01_walk1_ik.mot");
    try {
        InverseKinematicsTool ik1("subject01_Setup_InverseKinematics.xml");
        ik1.run();
        Storage result1(ik1.getOutputMotionFileName());
        CHECK_STORAGE_AGAINST_STANDARD(result1, standard, 
            std::vector<double>(24, 0.2), __FILE__, __LINE__, 
            "testInverseKinematicsGait2354 failed");
        cout << "testInverseKinematicsGait2354 passed" << endl;
    }
    catch (const std::exception& e) {
        cout << e.what() << endl;
        failures.push_back("testInverseKinematicsGait2354");
    }

    try {
        InverseKinematicsTool ik2("subject01_Setup_InverseKinematics_NoModel.xml");
        Model mdl("subject01_simbody.osim");
        mdl.initSystem();
        ik2.setModel(mdl);
        ik2.run();
        Storage result2(ik2.getOutputMotionFileName());
        CHECK_STORAGE_AGAINST_STANDARD(result2, standard, 
            std::vector<double>(24, 0.2), __FILE__, __LINE__, 
            "testInverseKinematicsGait2354 GUI workflow failed");
        cout << "testInverseKinematicsGait2354 GUI workflow passed" << endl;
    }
    catch (const std::exception& e) {
        cout << e.what() << endl;
        failures.push_back("testInverseKinematicsGait2354_GUI_workflow");
    }

    try {
        InverseKinematicsTool ik3("constraintTest_setup_ik.xml");
        ik3.run();
        cout << "testInverseKinematicsConstraintTest passed" << endl;
    }
    catch (const std::exception& e) {
        cout << e.what() << endl;
        failures.push_back("testInverseKinematicsConstraintTest");
    }

    if (!failures.empty()) {
        cout << "Done, with " << failures.size() << " failure(s) out of ";
        cout << itc << " test cases." << endl;
        cout << "Failure(s): " << failures << endl;
        return 1;
    }

    cout << "Done. All cases passed." << endl;
    return 0;
}
void testOrientationsReference()
{
    // column labels for orientation sensor data
    vector<std::string> labels{ "A", "B", "C", "D", "E", "F" };
    // for testing construct a set of marker weights in a different order 
    vector<int> order = { 3, 5, 1, 4, 0, 2 };

    size_t nc = labels.size(); // number of columns of orientation data
    size_t nr = 5;             // number of rows of orientation data

    TimeSeriesTable_<SimTK::Rotation> orientationData;
    orientationData.setColumnLabels(labels);
    for (size_t r{ 0 }; r < nr; ++r) {
        SimTK::RowVector_<SimTK::Rotation> row{ int(nc), SimTK::Rotation() };
        orientationData.appendRow(0.1*r, row);
    }

    Set<OrientationWeight> orientationWeights;
    for (size_t m{ 0 }; m < nc; ++m)
        orientationWeights.adoptAndAppend(
            new OrientationWeight(labels[order[m]], double(order[m])));

    std::cout << orientationWeights.dump() << std::endl;

    OrientationsReference orientationsRef(orientationData, &orientationWeights);

    Model model;
    SimTK::State& s = model.initSystem();
    s.updTime() = 0.0;

    SimTK::Array_<string> names = orientationsRef.getNames();

    SimTK::Array_<double> weights;
    orientationsRef.getWeights(s, weights);

    SimTK_ASSERT_ALWAYS(names.size() == weights.size(),
        "Number of markers does not match number of weights.");

    for (unsigned int i{ 0 }; i < names.size(); ++i) {
        std::cout << names[i] << ": " << weights[i] << std::endl;
        SimTK_ASSERT_ALWAYS(weights[i] == double(i),
            "Mismatched weight to marker.");
    }

    // Add marker weights for markers not present in the data
    orientationWeights.adoptAndAppend(new OrientationWeight("X", 0.1));
    orientationWeights.insert(0, new OrientationWeight("Y", 0.01));

    OrientationsReference orientationsRef2(orientationData, &orientationWeights);

    auto& oWeightSet = orientationsRef2.get_orientation_weights();

    // verify that internal weight set was updated 
    std::cout << oWeightSet.dump() << std::endl;

    names = orientationsRef2.getNames();
    orientationsRef2.getWeights(s, weights);

    SimTK_ASSERT_ALWAYS(names.size() == weights.size(),
        "Number of orientation sensors does not match number of weights.");

    for (unsigned int i = 0; i < names.size(); ++i) {
        std::cout << names[i] << ": " << weights[i] << std::endl;
        SimTK_ASSERT_ALWAYS(weights[i] == double(i),
            "Mismatched weight to orientation sensor.");
    }
}
int main()
{
    SimTK::Array_<std::string> failures;

    // get all registered Components
    SimTK::Array_<Component*> availableComponents;

    // starting with type Frame
    ArrayPtrs<Frame> availableFrames;
    Object::getRegisteredObjectsOfGivenType(availableFrames);
    for (int i = 0; i < availableFrames.size(); ++i) {
        availableComponents.push_back(availableFrames[i]);
    }

    // next with type Point
    ArrayPtrs<Point> availablePoints;
    Object::getRegisteredObjectsOfGivenType(availablePoints);
    for (int i = 0; i < availablePoints.size(); ++i) {
        availableComponents.push_back(availablePoints[i]);
    }

    // then type Joint
    ArrayPtrs<Joint> availableJoints;
    Object::getRegisteredObjectsOfGivenType(availableJoints);
    for (int i = 0; i < availableJoints.size(); ++i) {
        availableComponents.push_back(availableJoints[i]);
    }

    // then type TwoFrameLinker<Constraint>
    ArrayPtrs<TwoFrameLinker<Constraint, PhysicalFrame> > availableLink2Constraints;
    Object::getRegisteredObjectsOfGivenType(availableLink2Constraints);
    for (int i = 0; i < availableLink2Constraints.size(); ++i) {
        availableComponents.push_back(availableLink2Constraints[i]);
    }

    // then type TwoFrameLinker<Force> which are all the BushingForces
    ArrayPtrs<TwoFrameLinker<Force, PhysicalFrame> > availableBushingForces;
    Object::getRegisteredObjectsOfGivenType(availableBushingForces);
    for (int i = 0; i < availableBushingForces.size(); ++i) {
        availableComponents.push_back(availableBushingForces[i]);
    }

    // Test PrescribedForce
    std::unique_ptr<PrescribedForce> f(new PrescribedForce());
    availableComponents.push_back(f.get());
    // continue with other Constraints, Forces, Actuators, ...
    //Examples of updated forces that pass
    ArrayPtrs<PointToPointSpring> availablePointToPointSpring;
    Object::getRegisteredObjectsOfGivenType(availablePointToPointSpring);
    availableComponents.push_back(availablePointToPointSpring[0]);

    /** //Uncomment when dependencies of CoordinateCouplerConstraints are 
    // specified as Connectors 
    ArrayPtrs<Constraint> availableConstraints;
    Object::getRegisteredObjectsOfGivenType(availableConstraints);
    for (int i = 0; i < availableConstraints.size(); ++i) {
        availableComponents.push_back(availableConstraints[i]);
    }
    */

    for (unsigned int i = 0; i < availableComponents.size(); i++) {
        try {
            testComponent(*availableComponents[i]);
        }
        catch (const std::exception& e) {
            cout << "*******************************************************\n";
            cout<< "FAILURE: " << availableComponents[i]->getConcreteClassName() << endl;
            cout<< e.what() << endl;
            failures.push_back(availableComponents[i]->getConcreteClassName());
        }
    }
    
    if (!failures.empty()) {
        cout << "*******************************************************\n";
        cout << "Done, with failure(s): " << failures << endl;
        cout << failures.size() << "/" << availableComponents.size() 
            << " components failed test." << endl;
        cout << 100 * (availableComponents.size() - failures.size()) / availableComponents.size()
            << "% components passed." << endl;
        cout << "*******************************************************\n" << endl;
        return 1;
    }
    cout << "\ntestComponents PASSED. " << availableComponents.size() 
        << " components were tested." << endl;
}