Hit object with joystick input, how to avoid pass through

toglia

28-01-2010 03:17:08

Hello, I have been pulling my hair with this thing and I thought maybe you guys can help me out?

My latest task for the "pinball" project I am working on, is to offer the user hitting the ball with joystick input (its really a usb plug and play pinball plunger). Doesn't sound complicated right?

One of the key requirements of the project is to be as most precise as possible with the plunger feel cause it can influence this game play greatly.
At first I was using delta times, and delta positions to calculate delta velocities, and when the plunger was in the hit point I would "addForce" with that value. That was almost perfect, but it was not consistent, or not as consistent as needed. I would get almost 40 to 50% percent of variation with very similar plunger situations.

Then I tried the most logical approach. I attatched a sphere (or square) actor to the tip of the plunger, so I would let PhysX do its force math when the two bodies collide. The problem was that clearly setGlobalPosition is not in the capability of helping cause that doesn't imply inertia or linear velocity data. I also did some tests with setLinearVelocity and got some good results, but using linear velocity to match the real plunger position is not very straightforward... So here's my question. Is there any method that let me position my actor to specific locations (joystick input) and still do valid collision checks?

Thanks!

LucaMoller

01-02-2010 20:16:17

I had that kind of problem when I wanted to make my ragdoll answer to other characters atacks ( you know, I had to set the position of the actors involved in the attack to be always together with 3D model attack animation, just like you do with your joystick). But I didnt need the precision you need, so I solved it in a bad way xD...

You said you tried to addForce when the collision ocurred based on the speed you detected on the joystick, but there is a problem with that: for how much time you will addForce? The objects probably wont stay colliding the same amount of time in every collision and I suspect that the different collinding times explain the 50% difference you noticed sometimes...

So, what do you do? Instead of adding a force to the ball, calculate and set the linear momentum (using setLinearMomentum() )it should have after the collision ( you can calculate it easily if you have the speed of the joystick calculated the way you said with deltas... you think about a restitution coeficient for the collision and do the math :wink: ). I guess this should work much better than adding forces.
Hope this helps! :)

Anyway, if anyone know a way of solving this in a more natural way using physX, I'm curious to know too :wink:

toglia

05-02-2010 00:08:04

Hi Luca,
The thing is that if I check the velocity at the contact position it varies from hit to hit, when it shouldn't, so calculating the velocity with the deltas isn't that much precise. I'll do some more graph later to see where its exactly changing, but I suspect the delta time can play an irregular role in the math. Right now I think its useless to try some other physics approach until I don't get a regular hit velocity.

toglia

05-02-2010 18:34:51

I know this probably belongs in a game math forum, but anyway, since we're already talking about it, I'll share my current pseudo code for calculating delta velocities.

1) get current joystick position
1) update delta time
2) get average of last N number of position // This is to soften the movement and take out some vibration off, should be small (like 20) and is somewhat dependent on the frame rate, but independent to the average size cause I have everything precalculated per frame.
3) delta velocity = (current position - average position)/delta time // I subtract from the average cause high frame rates can cause the velocity to always be zero.

If anyone sees any flaw or could foresee any reason why the velocity would change with very similar hits, please reply.

PD: its not really a flighting joystick, its a digital pinball plunger:
http://www.nanotechent.com/digitalplunger.php

LucaMoller

05-02-2010 21:55:31

Maybe you should try to detach the rates of updating the joystick from the frame rate. Then, to prevent vibrations, I wouldn't use the current position , I would use 2 averages, one for the current position(average1), one for the last position(average2). Imagine you get updates from your joystick position 60 times in a second (independent of the video frame rate). You make the average1 with the 5 last positions you got, and the average2 with the 5 others of 6th to the 10th last update. Use your speed as the (average1 - average2)/deltatime (5 was an arbitrary number, you may increase or descrease it, just do some testing and find a good number :wink: ).

toglia

06-02-2010 00:39:09

Looks like a good idea, will try!

Buuut!

Today I did some more testing.
Firstly I changed the timing measures from float milliseconds to long int microseconds. Velocity had to be real so I changed it to double. OIS joystick data was left untouched and left integer too. Then to make the problem even smaller I forgot about doing averages and did some plain old "last frame - current frame" plunger position to get the movement step then I would get an instantaneous velocity which was possible with the added precision.

I was doing like 2500 fps, thats like 400 microseconds per frame and graphed some hits. I was terribly surprised that my peak velocities were not the same, never!!! I mean the plunger reached different "highest velocity" from hit to hit, and it was not a 10% difference, or 20%, it was like a 30% to 40% of variance. I'm starting to suspect maybe doing a repeatable hit with a digital plunger can't be done.

Tomorrow I will do the same but in a console application to see how can it change.

Luca, your idea looks logical, but my results today left me skeptical.

Any hardware controlling expert out there? :mrgreen:

LucaMoller

06-02-2010 17:34:22

I think the difference you are seeing is a consequence of using the actual position, and the last position of the joystick to calculate de velocity instead of using averages (your joystick had to have a VERY good precision so this could work at high rates of updating, because higher the rates of updating the difference from positions you get from the joystick start to become smaller and smaller, and the smaller difference you want to capture the better precision you need).
Try to implement the ideia of the averages, test some other numbers than 5 too, and I think maybe you will get a good result.

LucaMoller

06-02-2010 17:42:05

Another thing, I think that rates of updating like 2500Hz maybe are much higher than what you need and should use for that. You can try to use some fixed smaller rates (like 1000Hz, 500Hz, 300Hz, 120Hz, 60Hz) and see if you can get any better results with those.

toglia

11-02-2010 15:32:45

A fast update, we realized that the hardware frequency was too low for being useful on rapid movements. The frequency was like 30 cycles per second and an entire hit sequence lasted less than that, so weird stuff happened depending on how synchronized was the hit and the hardware update.