Visualizer frame rate capped at 90fps

Simbody is useful for internal coordinate and coarse grained molecule modeling, large scale mechanical models like skeletons, and anything else that can be modeled as bodies interconnected by joints, acted upon by forces, and restricted by constraints.
POST REPLY
User avatar
Claudio Pizzolato
Posts: 48
Joined: Sat Apr 30, 2011 7:05 am

Visualizer frame rate capped at 90fps

Post by Claudio Pizzolato » Thu Jun 26, 2014 12:33 am

Hello forum!

I've been playing around with the visualizer in the latest days. For testing purposes I'm trying to achieve the highest fps possible on the visualizer. I've created a little script that generates a single sphere which motion is prescribed through some simple equations. No dynamics, integration or other fancy things.

This is the code I've been using, tested on different machines, and on both linux and win7.

Code: Select all

 
#include "Simbody.h"
#define _USE_MATH_DEFINES
#include <math.h>
#include <chrono>
#include <thread>
#include <fstream> 

int main() {

    SimTK::MultibodySystem system;
    SimTK::SimbodyMatterSubsystem matter(system);

    SimTK::Body::Rigid sphereBody;
    sphereBody.addDecoration(SimTK::Transform(), SimTK::DecorativeSphere(SimTK::Real(0.1)).setColor(SimTK::Red));

    SimTK::MobilizedBody::Free freeSphere(matter.updGround(), sphereBody);
   
    SimTK::Visualizer viz(system);
    viz.setShowFrameRate(true);
    viz.setBackgroundType(SimTK::Visualizer::BackgroundType::SolidColor);
    viz.setBackgroundColor(SimTK::Black);
    viz.setMode(SimTK::Visualizer::Mode::RealTime);
    viz.setShutdownWhenDestructed(true);
    viz.setDesiredBufferLengthInSec(0);
    system.realizeTopology();
    SimTK::State state = system.getDefaultState();
    freeSphere.setQ(state, SimTK::Vec7(0, 0, 0, 1, 1, 1, 0));

    system.realize(state);
    viz.report(state);
    std::ofstream outF("dumpStats.txt");
    viz.setDesiredFrameRate(200);
    unsigned nFrames(0), frameCounter(0);
    unsigned timeStepMilliseconds = 5;
    auto start = std::chrono::system_clock::now();
    while (1) {

        double x(sin(nFrames*timeStepMilliseconds*1e-3));
        double y(cos(nFrames*timeStepMilliseconds*1e-3));
        double z((x + y) / 2);
        freeSphere.setQToFitTranslation(state, SimTK::Vec3(x, y, z));
    //    viz.report(state);
        viz.drawFrameNow(state);
        viz.dumpStats(outF);
        ++frameCounter;
        ++nFrames;
     //   std::this_thread::sleep_for(std::chrono::milliseconds(timeStepMilliseconds));

        if ((std::chrono::duration_cast<std::chrono::milliseconds >(std::chrono::system_clock::now() - start)) > std::chrono::milliseconds(1000)) {
            std::cout << "\n" << frameCounter << "\n";
            start = std::chrono::system_clock::now();
            frameCounter = 0;
        }
    }
    return 0;
}
As you can see there's a while cycle that tries to generate as more frame as possible. Since the geometry is simple I would expect to have really high fps, however I get limited at 90. I've already disabled the vsync on my graphic card, and in this way I've managed to move from 60 to 90 fps. I've also tested the three different modes (Visualizer::Mode), and tried both drawFrameNow() and report().

I looked at the visualizer code, but I couldn't find any hardcoded frame rate limiter. Does anyone have any idea of what could be the cause? Am I doing something in the wrong way?

User avatar
Michael Sherman
Posts: 806
Joined: Fri Apr 01, 2005 6:05 pm

Re: Visualizer frame rate capped at 90fps

Post by Michael Sherman » Thu Jun 26, 2014 9:53 am

Hi, Claudio. Interesting -- I tried your program on my Windows box and saw similar behavior. At first it was limited to 60fps. The visualizer had a call to setVsync(true) which I changed to setVsync(false) (the code says it only works on Windows -- if you know how to turn off vsync on Linux and OSX please fix!). Then the frame rate went up to about 100 (98,99 ish). That looks a lot like a 10ms limit, so I searched the simbody-visualizer code for 10ms and hit the jackpot:

Code: Select all

static void keepAliveIdleFunc() {
    static const double SleepTime   = 1./100; // 10ms
    // ...
    sleepInSec(SleepTime); // take a short break
}
That code is here.

I changed that to 1./200 and the frame rate went up from 100 to 200fps. So that is apparently what is limiting the rate.

The comments there indicate that the keepAliveIdleFunc() was necessary to avoid hangs on some platforms, which I vaguely remember. This could be a problem with glut implementations on some machines; I'm not sure. If you can find a better way to make this work without the sleep, that would be great. Otherwise you can at least remove it for your testing. In fact you might not need the keepAlive at all on your machine.

Regards,
Sherm

User avatar
Monica Reggiani
Posts: 2
Joined: Wed May 19, 2010 4:08 am

Re: Visualizer frame rate capped at 90fps

Post by Monica Reggiani » Thu Jun 26, 2014 4:55 pm

Hi Sherm,
I'm currently collaborating with Claudio on producing annoying questions for you :)

We've just tested your solution on Linux machine and it is working and we are able to reach more than 400 FPS.

An easy workaround we are using to disable vsync in linux is to execute the program with vblank_mode=0 in front.

As a test we used glxgears benchmark.

Code: Select all

 
vblank_mode=0 glxgears
resulted on an average of 1850FPS vs. 60FPS on our Ubuntu machine.

Thanks again for you help... see you at the next question :)
Monica

User avatar
Michael Sherman
Posts: 806
Joined: Fri Apr 01, 2005 6:05 pm

Re: Visualizer frame rate capped at 90fps

Post by Michael Sherman » Thu Jun 26, 2014 9:31 pm

Thanks for the update, Monica!

Regards,
Sherm

POST REPLY