Problems with basic physics - coding error or SL?
|
|
Kafka Potato
Registered User
Join date: 23 Mar 2006
Posts: 17
|
11-27-2007 09:29
Ok... so here is a real simple thing. right after a collision, I want to stop a physical object in it's tracks.
The sample code works sometimes, but is currently failing a lot more than it works and often results in the object rocketing around really fast.
default { state_entry() { llSetBuoyancy(1.0); llSetStatus(STATUS_ROTATE_X | STATUS_ROTATE_Y, FALSE); }
collision_end(integer num_detected) { state sensing; }
}
state sensing { state_entry() {
llOwnerSay("Energy Level: " + (string)llGetEnergy()); llApplyImpulse(-llGetMass()*llGetVel(),FALSE); state default; }
}
Now this happens if I handle the llApplyImpulse in the collision handler as well. As you can see I am verifying that there is no energy loss issue. Also, the sim I am on is reporting both simfps and physics fps >40 at all times.
Still, if I grab the object and "throw" it against a wall (slow speeds) there is no consistent behavior. It will stop one time. It will move very slowly the next. and sometimes end up bouncing around so fast it can rocket someone and gets returned to me once it drifts far enough away.
Any ideas why this simple code doesn't work reliably on a well performing sim and at speeds approximating an avi's walk?
Thanks
|
|
Lex Neva
wears dorky glasses
Join date: 27 Nov 2004
Posts: 1,361
|
11-27-2007 10:32
The concept is sound, but I'm betting that your object is experiencing multiple collisions, possibly very many. It's repeatedly trying to stop itself by applying an impulse opposite to its momentum, and it's rocketing off because of floating point calculation inaccuracies and also perhaps the fact that the object's velocity changes between the time llGetVel() returns and the time that llApplyImpulse is called.
Once the object stops, you don't want it trying to stop again. I suggest maybe switching to a third state or something.
|
|
Kafka Potato
Registered User
Join date: 23 Mar 2006
Posts: 17
|
Good point... but I already tested for it
11-27-2007 10:36
Good point. It's part of why I have a state change to begin with. I can confirm that the applyImpulse is not being applied multiple times. I was having issues with multiple collisions, the single state change with no event handler for collision has been sufficient to suppress this. I think the value returned by llGetVel() is not updated often enough - even for very slow speeds. As a test I had at one point given out the value of llGetVal during the collision handler, just before executing the applyimpulse in the state change, and immediately after applyimpulse. During those tests the 3 values returned were always identical. personally I think havoc is fsck'd in SL. But I don't like to just announce a bug in a forum. More often than not it's a typo I have done 
|
|
Darien Caldwell
Registered User
Join date: 12 Oct 2006
Posts: 3,127
|
11-27-2007 12:31
From: Kafka Potato personally I think havoc is fsck'd in SL. I think just about everyone that's ever done anything involving physics would agree. LL isn't spending all their time working on Havok 4 for nothing. You should go to the Beta grid and try your script there with the new Havok 4 beta, see if it works better. Would be interesting to hear how it goes.
|
|
Bobbyb30 Zohari
SL Mentor Coach
Join date: 11 Nov 2006
Posts: 466
|
11-27-2007 12:37
If you own the object than perhaps try using llSetStatus(STATUS_PHYSICS,FALSE) Otherwise, I'd have to agree that SL has very bad math errors and that applying an opposite impulse would eventually cause it to travel in that direction.
|
|
Kafka Potato
Registered User
Join date: 23 Mar 2006
Posts: 17
|
I guess I'll try the beta grid
11-27-2007 13:07
I've known that havoc isn't very good. But the original script was much more complex, in that the object was self driven, detecting obstacles in it's path and then choosing a new direction to travel in. I am quite dissapointed to find that even what seem like trivial and basic physics calculations are so untimely as to be useless.
I can't really set the object to non-physical. Far too many things change, for starteres llApplyImpulse only works on physical objects. I mean, I could make something behave similarly if it were non-physical but that is not my objective. This is a "trivial" test case that is needed for my real goal.
I find it interesting, that the full version of the script was working about 80% of the time yesterday. I only created this stripped down version today when the failure rate was 100%.
|
|
Kafka Potato
Registered User
Join date: 23 Mar 2006
Posts: 17
|
Test case a little better in beta grid
11-27-2007 13:37
Well... the simple test script I've posted seems to work pretty well in the beta grid. Still not 100%
Putting back in the real logic... ie self driven physical bot that detects when it hits an obstacle and determines a new direction is still not working
Actually, if I just have the bot be self driven and forget any intelligence (ie pick a new random direction) it's still very flaky it's just as likely to rocket around as it is to stop- even in cases where it is not heading right back into the same obstacle.
I'll probably wait for havock 4 to go into main grid before I work on non-trivial behavior. Still what I'm seeing is not very promising. I admittedly know very little about SL's internals... but somehow this looks like more of an issue in the interface to the havok engine rather than the engine itself. While updating the engine may help.... the root cause seems to be timeliness off the data. And it really looks like the value returned for llGetVel() is not accurate. I may perform some other tests like I did on main grid to try and get a feel for how often the data returned from llGetVel() is actually updated.
Cheers
|
|
Darien Caldwell
Registered User
Join date: 12 Oct 2006
Posts: 3,127
|
11-27-2007 15:28
From: Kafka Potato Well... the simple test script I've posted seems to work pretty well in the beta grid. Still not 100%
Putting back in the real logic... ie self driven physical bot that detects when it hits an obstacle and determines a new direction is still not working
Actually, if I just have the bot be self driven and forget any intelligence (ie pick a new random direction) it's still very flaky it's just as likely to rocket around as it is to stop- even in cases where it is not heading right back into the same obstacle.
I'll probably wait for havock 4 to go into main grid before I work on non-trivial behavior. Still what I'm seeing is not very promising. I admittedly know very little about SL's internals... but somehow this looks like more of an issue in the interface to the havok engine rather than the engine itself. While updating the engine may help.... the root cause seems to be timeliness off the data. And it really looks like the value returned for llGetVel() is not accurate. I may perform some other tests like I did on main grid to try and get a feel for how often the data returned from llGetVel() is actually updated.
Cheers Now would probably be a good time to raise these issues in the JIRA, Perhaps they can fix them before Havok 4 rolls out. 
|
|
Seifert Surface
Mathematician
Join date: 14 Jun 2005
Posts: 912
|
11-27-2007 17:10
In my experience, llGetVel is accurate. I've made stuff involving llPushObject that does pretty much exactly the same thing as what you're doing.
The thing that can kill it though is the amount of scripting going on in the sim. I'm not entirely clear on the details, but the thread of a script's calculations can get cut up into different time slices, and so not all of your calculations get run at once. If the velocity is measured at one particular frame of the physics engine, but the impulse is not applied until a later frame, you get all sorts of problems.
It may be making things worse that you are applying the impulse right around the time when the physics engine is applying its own impulse for bouncing off whatever it hit. I would check to see if the velocity you are recording is in the direction the object was travelling before hitting something, or in the opposite direction.
Try it in a near empty sim, with not much scripting going on and see if it is more reliable. Whatever you do, don't be doing unnecessary calculations (or OwnerSaying etc) in between measuring the velocity and applying impulse (although you aren't doing it in this demo, so it isn't that here).
Oh, and one way to stop the thing without going non physical would be to turn on llMoveToTarget. That might mess up your stuff as well though.
_____________________
-Seifert Surface 2G!tGLf 2nLt9cG
|
|
Kafka Potato
Registered User
Join date: 23 Mar 2006
Posts: 17
|
11-28-2007 09:28
From: Seifert Surface ... The thing that can kill it though is the amount of scripting going on in the sim. I'm not entirely clear on the details, but the thread of a script's calculations can get cut up into different time slices, and so not all of your calculations get run at once. If the velocity is measured at one particular frame of the physics engine, but the impulse is not applied until a later frame, you get all sorts of problems.
It may be making things worse that you are applying the impulse right around the time when the physics engine is applying its own impulse for bouncing off whatever it hit. I would check to see if the velocity you are recording is in the direction the object was travelling before hitting something, or in the opposite direction.
... YOu got it exactly right - the rebound happens primarily when the llgetVel() returns from before the collision. You've just stated what I've observed very eloquently. Since I don't own a sim I can't really get a no scripts sim, but I've been doing these test on sim's which report very good FPS. In reality - if I can only run one thing - what good is it? I really like the idea of move2target. I might be able to make that work- It's worth a try. And I can tell you that if I assign llGetVel() and then apply impulse - the problem happens much more frequently. I know llGetVel() is stable when there is no change to velocity. But it seems useless if an acceleration is applied or even was recently applied. Heck... if I could reliably count llGetVel() to return my velocity just before the collision, I could use. But this indeterminate result is very hard to deal with, and requires even more calculations such as comparing the llGetVel() against the most recent vector for applyImpulse, etc...
|
|
Seifert Surface
Mathematician
Join date: 14 Jun 2005
Posts: 912
|
11-28-2007 14:08
Maybe try putting in a brief sleep before running the impulse, so that the velocity you get would definitely be from after when the physics engine does its bounce?
_____________________
-Seifert Surface 2G!tGLf 2nLt9cG
|
|
Squirrel Wood
Nuteater. Beware!
Join date: 14 Jun 2006
Posts: 471
|
11-29-2007 00:00
As for the suggestion to setting the object non physical:
You can do it and then immediately make it physical again.
That should stop it dead in its path.
Which is, as I assume, exactly what you want to achieve.
|