Ejemplo n.º 1
0
void testLoadObjFile() {
    string file;
    file += "# This is a comment\n";
    file += "v -1.0 1.0 2.0\n";
    file += "v -2.0 2.0 3.0\n";
    file += "v -3.0 3.0 \\\n";
    file += "4.0\n";
    file += "v -4.0 4.0 5.0\n";
    file += "v -5.0 5.0 6.0\n";
    file += "f 1 2 3\n";
    file += "f 2// 3/4/5 4//2\n";
    file += "f -3 -2/3/4 -1\n";
    file += "f 1 3\\\n";
    file += "5 2\n";
    PolygonalMesh mesh;
    stringstream stream(file);
    mesh.loadObjFile(stream);
    ASSERT(mesh.getNumVertices() == 5);
    ASSERT(mesh.getNumFaces() == 4);
    for (int i = 0; i < mesh.getNumVertices(); i++) {
        const Vec3& pos = mesh.getVertexPosition(i);
        ASSERT(pos[0] == -(i+1));
        ASSERT(pos[1] == i+1);
        ASSERT(pos[2] == i+2);
    }
    for (int i = 0; i < 3; i++) {
        ASSERT(mesh.getNumVerticesForFace(i) == 3);
        ASSERT(mesh.getFaceVertex(i, 0) == i);
        ASSERT(mesh.getFaceVertex(i, 1) == i+1);
        ASSERT(mesh.getFaceVertex(i, 2) == i+2);
    }
    ASSERT(mesh.getNumVerticesForFace(3) == 4);
    ASSERT(mesh.getFaceVertex(3, 0) == 0);
    ASSERT(mesh.getFaceVertex(3, 1) == 2);
    ASSERT(mesh.getFaceVertex(3, 2) == 4);
    ASSERT(mesh.getFaceVertex(3, 3) == 1);
}
Ejemplo n.º 2
0
void flexionFDSimulationWithHitMap(Model& model)
{
	addFlexionController(model);
	//addExtensionController(model);
	//addTibialLoads(model, 0);

    model.setUseVisualizer(true);

	// init system
	std::time_t result = std::time(nullptr);
	std::cout << "\nBefore initSystem() " << std::asctime(std::localtime(&result)) << endl;
	SimTK::State& si = model.initSystem();
	result = std::time(nullptr);
	std::cout << "\nAfter initSystem() " << std::asctime(std::localtime(&result)) << endl;
	
	// set gravity
	//model.updGravityForce().setGravityVector(si, Vec3(-9.80665,0,0));
	//model.updGravityForce().setGravityVector(si, Vec3(0,0,0));
	
	//setHipAngle(model, si, 90);
	//setKneeAngle(model, si, 0, false, false);
	//model.equilibrateMuscles( si);

	MultibodySystem& system = model.updMultibodySystem();
	SimbodyMatterSubsystem& matter = system.updMatterSubsystem();
	GeneralForceSubsystem forces(system);
	ContactTrackerSubsystem  tracker(system);
    CompliantContactSubsystem contactForces(system, tracker);
	contactForces.setTrackDissipatedEnergy(true);
    //contactForces.setTransitionVelocity(1e-3);

	for (int i=0; i < matter.getNumBodies(); ++i) {
		MobilizedBodyIndex mbx(i);
		if (i==19 || i==20 || i==22)// || i==15 || i==16)
		{
			MobilizedBody& mobod = matter.updMobilizedBody(mbx);
			std::filebuf fb;
			//cout << mobod.updBody().
			if (i==19)
				fb.open ( "../resources/femur_lat_r.obj",std::ios::in);
			else if (i==20)
				fb.open ( "../resources/femur_med_r.obj",std::ios::in);
			else if (i==22)
				fb.open ( "../resources/tibia_upper_r.obj",std::ios::in);
			//else if (i==15)
				//fb.open ( "../resources/meniscus_lat_r.obj",std::ios::in);
			//else if (i==16)
				//fb.open ( "../resources/meniscus_med_r.obj",std::ios::in);
			std::istream is(&fb);
			PolygonalMesh polMesh;
			polMesh.loadObjFile(is);
			fb.close();
			SimTK::ContactGeometry::TriangleMesh mesh(polMesh);
			ContactSurface contSurf;//(mesh, ContactMaterial(1.0e6, 1, 1, 0.03, 0.03), 0.001);
			if (i==19 || i==20 || i==22)
				contSurf = ContactSurface(mesh, ContactMaterial(10, 1, 1, 0.03, 0.03), 0.001);
			//else if (i==15 || i==16)
				//contSurf = ContactSurface(mesh, ContactMaterial(10, 3, 1, 0.03, 0.03), 0.001);
			DecorativeMesh showMesh(mesh.createPolygonalMesh());
			showMesh.setOpacity(0.5);
			mobod.updBody().addDecoration( showMesh);
			mobod.updBody().addContactSurface(contSurf);
		}
    }

	ModelVisualizer& viz(model.updVisualizer());
	//Visualizer viz(system);
	viz.updSimbodyVisualizer().addDecorationGenerator(new HitMapGenerator(system,contactForces));
    viz.updSimbodyVisualizer().setMode(Visualizer::RealTime);
    viz.updSimbodyVisualizer().setDesiredBufferLengthInSec(1);
    viz.updSimbodyVisualizer().setDesiredFrameRate(30);
    viz.updSimbodyVisualizer().setGroundHeight(-3);
    viz.updSimbodyVisualizer().setShowShadows(true);
	
    Visualizer::InputSilo* silo = new Visualizer::InputSilo();
	viz.updSimbodyVisualizer().addInputListener(silo);
    Array_<std::pair<String,int> > runMenuItems;
    runMenuItems.push_back(std::make_pair("Go", GoItem));
    runMenuItems.push_back(std::make_pair("Replay", ReplayItem));
    runMenuItems.push_back(std::make_pair("Quit", QuitItem));
    viz.updSimbodyVisualizer().addMenu("Run", RunMenuId, runMenuItems);

    Array_<std::pair<String,int> > helpMenuItems;
    helpMenuItems.push_back(std::make_pair("TBD - Sorry!", 1));
    viz.updSimbodyVisualizer().addMenu("Help", HelpMenuId, helpMenuItems);

    system.addEventReporter(new MyReporter(system,contactForces,ReportInterval));
	//system.addEventReporter(new Visualizer::Reporter(viz.updSimbodyVisualizer(), ReportInterval));
	
    // Check for a Run->Quit menu pick every <x> second.
	system.addEventHandler(new UserInputHandler(*silo, 0.001));

	system.realizeTopology();

	//Show ContactSurfaceIndex for each contact surface
  //  for (int i=0; i < matter.getNumBodies(); ++i) {
		//MobilizedBodyIndex mbx(i);
  //      const MobilizedBody& mobod = matter.getMobilizedBody(mbx);
  //      const int nsurfs = mobod.getBody().getNumContactSurfaces();
        //printf("mobod %d has %d contact surfaces\n", (int)mbx, nsurfs);
		////cout << "mobod with mass: " << (float)mobod.getBodyMass(si) << " has " << nsurfs << " contact surfaces" << endl;
		// //for (int i=0; i<nsurfs; ++i) {
  //          //printf("%2d: index %d\n", i, 
  //                 //(int)tracker.getContactSurfaceIndex(mbx,i)); 
  //      //}
  //  }

	//cout << "tracker num of surfaces: " << tracker.getNumSurfaces() << endl;

	//State state = system.getDefaultState();
	//viz.report(state);
	State& state = model.initializeState();
	viz.updSimbodyVisualizer().report(state);

	// Add reporters
    ForceReporter* forceReporter = new ForceReporter(&model);
    model.addAnalysis(forceReporter);

	CustomAnalysis* customReporter = new CustomAnalysis(&model, "r");
	model.addAnalysis(customReporter);

	// Create the integrator and manager for the simulation.
	SimTK::RungeKuttaMersonIntegrator integrator(model.getMultibodySystem());
	//SimTK::CPodesIntegrator integrator(model.getMultibodySystem());
	//integrator.setAccuracy(.01);
	//integrator.setAccuracy(1e-3);
	//integrator.setFixedStepSize(0.001);
	Manager manager(model, integrator);

	// Define the initial and final simulation times
	double initialTime = 0.0;
	double finalTime = 0.2;

	// Integrate from initial time to final time
	manager.setInitialTime(initialTime);
	manager.setFinalTime(finalTime);
	std::cout<<"\n\nIntegrating from "<<initialTime<<" to " <<finalTime<<std::endl;

	result = std::time(nullptr);
	std::cout << "\nBefore integrate(si) " << std::asctime(std::localtime(&result)) << endl;

	manager.integrate(state);

	result = std::time(nullptr);
	std::cout << "\nAfter integrate(si) " << std::asctime(std::localtime(&result)) << endl;

	// Save the simulation results
	Storage statesDegrees(manager.getStateStorage());
	statesDegrees.print("../outputs/states_flex.sto");
	model.updSimbodyEngine().convertRadiansToDegrees(statesDegrees);
	statesDegrees.setWriteSIMMHeader(true);
	statesDegrees.print("../outputs/states_degrees_flex.mot");
	// force reporter results
	forceReporter->getForceStorage().print("../outputs/force_reporter_flex.mot");
	//customReporter->print( "../outputs/custom_reporter_flex.mot");

	//cout << "You can choose 'Replay'" << endl;
	int menuId, item;
	unsigned int frameRate = 5;
	do { 
		cout << "Please choose 'Replay' or 'Quit'" << endl;
		viz.updInputSilo().waitForMenuPick(menuId, item);

        if (item != ReplayItem && item != QuitItem) 
            cout << "\aDude... follow instructions!\n";
		if (item == ReplayItem)
		{
			cout << "Type desired frame rate (integer) for playback and press Enter (default = 1) : ";
			//frameRate = cin.get();		
			cin >> frameRate;
			if (cin.fail()) 
			{
				cout << "Not an int. Setting default frame rate." << endl;
				cin.clear();
				cin.ignore(std::numeric_limits<int>::max(),'\n');
				frameRate = 1;
			}

			//cout << "saveEm size: " << saveEm.size() << endl;
			for (unsigned int i=0; i<saveEm.size(); i++)
			{
				viz.updSimbodyVisualizer().drawFrameNow(saveEm.getElt(i));
				if (frameRate == 0)
					frameRate = 1;
				usleep(1000000/frameRate);
			}
		}
	} while (menuId != RunMenuId || item != QuitItem);
}
Ejemplo n.º 3
0
int main() {
  try
  { std::cout << "Current working directory: " 
              << Pathname::getCurrentWorkingDirectory() << std::endl;

    // Create the system.
    
    MultibodySystem         system; system.setUseUniformBackground(true);
    SimbodyMatterSubsystem  matter(system);
    GeneralForceSubsystem   forces(system);
    Force::UniformGravity   gravity(forces, matter, 0*Vec3(2, -9.8, 0));

    ContactTrackerSubsystem  tracker(system);
    CompliantContactSubsystem contactForces(system, tracker);
    contactForces.setTrackDissipatedEnergy(true);

    GeneralContactSubsystem OLDcontact(system);
    const ContactSetIndex OLDcontactSet = OLDcontact.createContactSet();

    contactForces.setTransitionVelocity(1e-3);

    std::ifstream meshFile1, meshFile2;
    PolygonalMesh femurMesh; 
    meshFile1.open("ContactBigMeshes_Femur.obj"); 
    femurMesh.loadObjFile(meshFile1); meshFile1.close();
    PolygonalMesh patellaMesh; 
    meshFile2.open("ContactBigMeshes_Patella.obj"); 
    patellaMesh.loadObjFile(meshFile2); meshFile2.close();

    ContactGeometry::TriangleMesh femurTri(femurMesh);
    ContactGeometry::TriangleMesh patellaTri(patellaMesh);

    DecorativeMesh showFemur(femurTri.createPolygonalMesh());
    Array_<DecorativeLine> femurNormals;
    const Real NormalLength = .02;
    //for (int fx=0; fx < femurTri.getNumFaces(); ++fx)
    //    femurNormals.push_back(
    //    DecorativeLine(femurTri.findCentroid(fx),
    //                   femurTri.findCentroid(fx)
    //                       + NormalLength*femurTri.getFaceNormal(fx)));

    DecorativeMesh showPatella(patellaTri.createPolygonalMesh());
    Array_<DecorativeLine> patellaNormals;
    //for (int fx=0; fx < patellaTri.getNumFaces(); ++fx)
    //    patellaNormals.push_back(
    //    DecorativeLine(patellaTri.findCentroid(fx),
    //                   patellaTri.findCentroid(fx)
    //                       + NormalLength*patellaTri.getFaceNormal(fx)));

    // This transform has the meshes close enough that their OBBs overlap
    // but in the end none of the faces are touching.
    const Transform X_FP(
        Rotation(Mat33( 0.97107625831404454, 0.23876955530133021, 0,
                       -0.23876955530133021, 0.97107625831404454, 0,
                        0,                   0,                   1), true),
        Vec3(0.057400580865008571, 0.43859170879135373, 
             -0.00016506240185135300)
        );


    const Real fFac =1; // to turn off friction
    const Real fDis = .5*0.2; // to turn off dissipation
    const Real fVis =  .1*.1; // to turn off viscous friction
    const Real fK = 100*1e6; // pascals

    // Put femur on ground at origin
    matter.Ground().updBody().addDecoration(Vec3(0,0,0),
        showFemur.setColor(Cyan).setOpacity(.2));
    matter.Ground().updBody().addContactSurface(Vec3(0,0,0),
        ContactSurface(femurTri,
            ContactMaterial(fK*.01,fDis*.9,fFac*.8,fFac*.7,fVis*10),
            .01 /*thickness*/));


    Body::Rigid patellaBody(MassProperties(1.0, Vec3(0), Inertia(1)));
    patellaBody.addDecoration(Transform(), 
        showPatella.setColor(Red).setOpacity(.2));
    patellaBody.addContactSurface(Transform(),
        ContactSurface(patellaTri,
            ContactMaterial(fK*.001,fDis*.9,fFac*.8,fFac*.7,fVis*10),
            .01 /*thickness*/));

    MobilizedBody::Free patella(matter.Ground(), Transform(Vec3(0)), 
                                patellaBody,    Transform(Vec3(0)));


    //// The old way ...
    //OLDcontact.addBody(OLDcontactSet, ball,
    //    pyramid, Transform());

    //OLDcontact.addBody(OLDcontactSet, matter.updGround(),
    //    ContactGeometry::HalfSpace(), Transform(R_xdown, Vec3(0,-3,0)));
    //ElasticFoundationForce ef(forces, OLDcontact, OLDcontactSet);
    //Real stiffness = 1e6, dissipation = 0.01, us = 0.1, 
    //    ud = 0.05, uv = 0.01, vt = 0.01;
    ////Real stiffness = 1e6, dissipation = 0.1, us = 0.8, 
    ////    ud = 0.7, uv = 0.01, vt = 0.01;

    //ef.setBodyParameters(ContactSurfaceIndex(0), 
    //    stiffness, dissipation, us, ud, uv);
    //ef.setTransitionVelocity(vt);
    //// end of old way.

    Visualizer viz(system);
    Visualizer::Reporter& reporter = *new Visualizer::Reporter(viz, ReportInterval);
    viz.addDecorationGenerator(new ForceArrowGenerator(system,contactForces));
    MyReporter& myRep = *new MyReporter(system,contactForces,ReportInterval);

    system.addEventReporter(&myRep);
    system.addEventReporter(&reporter);

    // Initialize the system and state.
    
    system.realizeTopology();
    State state = system.getDefaultState();

    viz.report(state);
    printf("Reference state -- hit ENTER\n");
    cout << "t=" << state.getTime() 
         << " q=" << patella.getQAsVector(state)  
         << " u=" << patella.getUAsVector(state)  
         << endl;
    char c=getchar();

    patella.setQToFitTransform(state, ~X_FP);
    viz.report(state);
    printf("Initial state -- hit ENTER\n");
    cout << "t=" << state.getTime() 
         << " q=" << patella.getQAsVector(state)  
         << " u=" << patella.getUAsVector(state)  
         << endl;
    c=getchar();
    
    // Simulate it.
    const clock_t start = clock();

    RungeKutta3Integrator integ(system);
    TimeStepper ts(system, integ);
    ts.initialize(state);
    ts.stepTo(2.0);

    const double timeInSec = (double)(clock()-start)/CLOCKS_PER_SEC;
    const int evals = integ.getNumRealizations();
    cout << "Done -- took " << integ.getNumStepsTaken() << " steps in " <<
        timeInSec << "s for " << ts.getTime() << "s sim (avg step=" 
        << (1000*ts.getTime())/integ.getNumStepsTaken() << "ms) " 
        << (1000*ts.getTime())/evals << "ms/eval\n";

    printf("Using Integrator %s at accuracy %g:\n", 
        integ.getMethodName(), integ.getAccuracyInUse());
    printf("# STEPS/ATTEMPTS = %d/%d\n", integ.getNumStepsTaken(), integ.getNumStepsAttempted());
    printf("# ERR TEST FAILS = %d\n", integ.getNumErrorTestFailures());
    printf("# REALIZE/PROJECT = %d/%d\n", integ.getNumRealizations(), integ.getNumProjections());


    while(true) {
        for (int i=0; i < (int)saveEm.size(); ++i) {
            viz.report(saveEm[i]);
        }
        getchar();
    }

  } catch (const std::exception& e) {
    std::printf("EXCEPTION THROWN: %s\n", e.what());
    exit(1);

  } catch (...) {
    std::printf("UNKNOWN EXCEPTION THROWN\n");
    exit(1);
  }

    return 0;
}