NaN when using a Vector3f very fast?

Your professor is not correct about memory sharing.  I'd have to look at the whole code to be able to tell you the exact cause for sure, but I know from writing Cloth implementations and the springs in the ChaseCamera that implementing Springs using a literal implementation of hooke's equation is unstable (springs in general are tricky.)  The problem usually lies in your "dt" variable fluctuating based on what the cpu is doing in the background.  If dt is ever exceptionally large, your v_alt and s_alt values will be unusally low or high and it will carry that value to the next loop, compounding the problem over and over until it is NaN (ie. the value was too big - either in the positive or negative direction - to represent as a float in Java.)  It doesn't take very many loops for that to happen.



One thing you might do to lengthen the time your sim can run is instead of:

trans = new Vector3f(0,s,0);



do this to prevent lots of object creation (less gc means a smoother cpu run):

trans.y = s;



Unfortunately, the only real way to keep the NaN from appearing is to either check the numbers as they are generated and keep them in a "real" range or change the implementation to not reuse the old velocity and acceleration (you could use position to derive those values)  Both have some issues still.

Another thing you could do to keep your simulation running is detect NaN and reset your simulation to 0.

Hope some of that helped!

trans = new Vector3f(0,(float) s,0);



This means your calculated result get's placed in a new Vector every time. Less than ideal, but there is absolutly no way jME can influence the result of your calculations. Not sure what your professor is saying but it sounds like he does not understandJava. When a primitive variable (such as int, float, double, etc.) is assigned to another variable, always a copy is made.

So you could do :

myBox.getLocalTranslation().y = (float)s;



And even then in no way could anything in the Vector3f class influence s. The error must be in your calculations somewhere.

I forgot to mention something:



If i don't update the box's position ( comment out the line in simpleUpdate)  I don't get the NaN problem. Same with the implementation in opengl4java.



Very crazy problem …

what do you mean by "but the simpleUpdate method seem not to be called in frequent way"?



when running calcEuler from the simpleUpdate method the box seems to stand still, just because calcEuler is called alot less frequently than when running through your thread. your thread doesnt do any Thread.yield or Thread.sleep so calcEuler runs thousands of times on every jme update, so the box has come to rest before showing up in 3d…



using a higher "dt" will show some action again, but also give higher instability offcourse…i didn't get any NaN's but i suspect it is either instability explosion or a threading issue.

MrCoder said:

what do you mean by "but the simpleUpdate method seem not to be called in frequent way"?

With opengl4java i can set up how often per second the display-method is called.
How often JME calls the simpleUpdate() method? It seems to to be frequently, i.e. ~60 times per second.

when running calcEuler from the simpleUpdate method the box seems to stand still, just because calcEuler is called alot less frequently than when running through your thread. your thread doesnt do any Thread.yield or Thread.sleep so calcEuler runs thousands of times on every jme update, so the box has come to rest before showing up in 3d...

dt must be very small to get good results. if it's about 0,001 the result of the calculation would be very wrong after a few moments.
So i need to calc with a small dt and many iterations/seconds ...
Using a sleep(1) in the thread it's too slow.

using a higher "dt" will show some action again, but also give higher instability offcourse...i didn't get any NaN's but i suspect it is either instability explosion or a threading issue.

hmm, you don't get an NaN ?? Hmm, maybe it's a hardware/driver issue ?! I will try it on different pc's ...

-Alex

ok, first of all, i'm a jme noob and math is my natural enemy, so take everything from me with a grain of salt…

i don't get any nans here, either, and the app runs fine for billions of calculations.

as far as i know simpleUpdate() runs as fast as possible without limitations. (add grain of salt here :P)

you could use other implementations of AbstractGame with either a fixed frame- or logicrate.

Yeah, your're right.

I currently testing the same program with another computer. runs fine without any NaN … hmm, okay. So it's not the program's fault, and of course not mine :slight_smile:



On my machines i only get this error with my laptop. IBm Thinkpad R51e, 1,7Ghz Dothan-Centrino,  1GB RAM, Windows Xp Prof., Java 5 Update 7, ATI Radeon 9000 …

Don't know what's wrong with this machine… I will try some things like diabling powermanagement of the graphics card and so on …



thanks so far to all the people for testing the code…



regards,

Alex

yes simpleUpdate just runs as fast as it can…



why don't you iterate your calcEuler yourself in the simpleUpdate method(so you won't have to go through the fuzz with threads s :wink: )

something like this perhaps(just writing without validating anything)


    private final int calcsPerSecond = 1000000;
    private final float counterThreshold = 1.0f / calcsPerSecond;
    private float counter = 0;
    protected void simpleUpdate() {
        counter += tpf;
        while (counter > counterThreshold) {
            calcEuler();
            counter -= counterThreshold;
        }

        boxEuler.getLocalTranslation().y = (float) s;
    }

What the f*ck ?!



I think i found the cause why I get NaN's …



At university i have to use the cisco cpn client software to get connected to the internet and the university net.

If I am connected with the vpn i get NaN's after a few seconds.

I disconnected the vpn and guess what? The programs runs over minutes without any NaN …



Currently I'm trying to reproduce this problem on another pc …

…working…



And guess what? Now, with the installed and connected cisco vpn client on my second computer there are also NaN's …



This is crazy, isn't it?



Maybe the Devs of JME can comfirm this. If it's true that the Cisco VPN Client cann cause such problem in alle JME / OpenGL4Java Programs it should be mentioned somewhere… maybe wiki or faq …



regards

Alex

MrCoder said:

yes simpleUpdate just runs as fast as it can...

why don't you iterate your calcEuler yourself in the simpleUpdate method(so you won't have to go through the fuzz with threads *s* ;) )
something like this perhaps(just writing without validating anything)


    private final int calcsPerSecond = 1000000;
    private final float counterThreshold = 1.0f / calcsPerSecond;
    private float counter = 0;
    protected void simpleUpdate() {
        counter += tpf;
        while (counter > counterThreshold) {
            calcEuler();
            counter -= counterThreshold;
        }

        boxEuler.getLocalTranslation().y = (float) s;
    }




That's the point... simpleUpdate isn't running that fast as my external thread runs... If I try so call the calcEuler method in simleUpdate it's running veeeeeeeeeery slow.
I don't know why... But now i solved the problem (see my post with the cisco vpn client).

- Alex

are you saying that the method-call to calcEuler is slow when calling it from simpleUpdate??? sounds like something is really messed up on that university-comp :slight_smile:

MrCoder said:

are you saying that the method-call to calcEuler is slow when calling it from simpleUpdate??? sounds like something is really messed up on that university-comp :)


Ok, my fault. it's not slow... It seems that simpleUpdate ist not called fast enough, and so calcEuler isn't called often enough...
If I put a counter in simpleUpdate, after a few seconds the counter is over 5000 ... But for using a "dt" that is about 0,0000001 the calcEuler must be called more often than simpleUpdate is called. And the first working solution was the idea with the 2nd thread that calls calcEuler as fast as java can.

btw: It's not a university-comp... It's my personal laptop... And all other things are running fine.. And now, with VPN disconnected my simulation-program is also running fine...

- Alex

did you read the code i posted at all?

if simple update is called once a second for example, calcEuler will be called "calcsPerSecond" times in that update…

MrCoder said:

did you read the code i posted at all?
if simple update is called once a second for example, calcEuler will be called "calcsPerSecond" times in that update...


Sorry, I was too fast. Didn't see that.

But yes, that would be the another solution. Calling calcEuler many many times and then set the new position.
But with your solution it's still not working with the vpn connected... :)  Cisco VPN s*cks :)
- Alex

hehe just wanted to get that through(even if it wasnt important and the code was crappy) :wink:



really sucks when you get errors like that…very hard to locate the bug etc…good thing you found it! :slight_smile:

yeah, and the craziest thing is that it seems to be the same problem when using opengl4java … I will check that also …


  • Alex


does it happen when you don't use any opengl code?



if not it would be interesting to know what would happen if you use opengl in c for example. :slight_smile:

If i don't update the box's position and vpn is connected there's no problem with NaN …

Other openGL-stuff, i.e. playing 3D games work fine …



Must have to to with the combination of

  • Java
  • OpenGL
  • Cisco VPN Client


  • Alex