Jump to content

detecting that a physical object has been pushed


Judy Hynes
 Share

You are about to reply to a thread that has been inactive for 710 days.

Please take a moment to consider if this thread is worth bumping.

Recommended Posts

I am trying to figure out a reliable method to detect that a physical object has been pushed.  That is, something else called llPushObject (or I guess one of the other functions that can change an object's motion).  The object I want to detect on may be moving, so just detecting that it moved at all is not enough.

I looked over the available events, but nothing seems like it would get me what I want directly.  Having a force applied doesn't count as a "collision", all the "target" events are based on motion from llMoveToTarget, and moving start/end are related to keyframe motion.

I considered doing some kind of polling, like checking the object's velocity periodically and seeing if it experienced a "big change" from one sample to the next.  This seemed promising to me as the objects are "unpowered" so they just get an initial velocity and physics and gravity do the rest.  However,  just checking for a large magnitude difference in these samples isn't all that reliable in practice I've found.

timer()
{
	vector current_vel = llGetVel();
	float diff = llVecMag(current_vel-previous_vel);
	if(diff >= PUSH_DETECT_THRESHOLD)
	{
		llOwnerSay("Something pushed me");
	}
}

An object being accelerated by gravity will experience a whole range of velocity values over its travel.  If the timer samples perfectly on time every time, I might be able to make an upper bound of the difference that would be "natural" and declare anything else the result of an outside force acting on it.  But timer events in LSL are really bad at firing on time, at least for the sample rate's I'd need to pull this off, so any fixed threshold I choose will be "wrong" for a timer event that goes off "late" relative to the assumptions that set that threshold.

I tried collecting some data to see if I could establish a correlation between llGetRegionTimeDilation and the amount of velocity change observed, but this data was not correlated well at all when I tested it on a sim experiencing fluctuations in time dilation.

I suppose I could record the time of previous velocity sample with llGetTime and only evaluate the velocity difference if the elapsed time is close enough to the timer rate I was expecting for whatever threshold I set.  This has a chance of preventing false detects I guess, but means giving up trying to detect anything if the sim slows down, so it's not ideal.

Does anyone have ideas on how to approach the problem of detecting that an outside force has been applied to an object?  Or suggestions on refining this method of sampling the velocity for abrupt changes that would better handle the variability inherent in timer events?

 

Link to comment
Share on other sites

Ideally, gravitational force should only affect the Z component of velocity. (Obviously not quite true in RL, but I think it's always true in SL.) That means you can treat the problem as a two-dimensional one and only look at changes in velocity with respect to X or Y as long as your object is in the air. You can also simplify the problem by disregarding any changes that are due to collisions, or at least by detecting collisions so that you know when to reset your sampling algorithm. I have never been sure whether the SL physics engine takes friction with the air into account, but I suspect not. Wind is a factor, however.  Fortunately, you can sample for that with llWind and can build it into your model too.  It's too much to hope that you can account for all external forces, because there are precision limits to everything and there's a certain amount of stochastic noise.  Still, I bet you can write a fairly sensitive routine to account for the bigger forces that you really care about.

Edited by Rolig Loon
typos. as always.
Link to comment
Share on other sites

Besides the intellectual intrigue of the problem as stated, I'm having trouble thinking of a case in which I would expect a script that I didn't write* to apply a force to an object that I own, through llPushObject rather than direct contact. Having an attachment/HUD detect if the wearing avatar is being pushed seems reasonable**, but that doesn't seem to be your use-case.

Often when LSL doesn't let you do some specific thing, it's useful to take a step back and think about the broader picture of the end result you're trying to achieve and think if there's a better way of going about it. I'm just guessing, but "detecting if an object was pushed by llPushObject" seems like an instrumental part of a larger design to me, and perhaps not actually what you need to do.

*If you wrote the pushing script, you could of course llRegionSayTo(); the pushed object that it's being pushed.

**For that I'd try and test the direction of llGetVel(), vs <1,0,0>*llGetRot(); making sure the avatar isn't seated nor in mouse-look. turning off detection while controls are in use, and using some trick or other to not fire directly after a collision (I wouldn't be surprised if you'd need to do some tricky logic to not trigger directly *before* a collision as well.)

Link to comment
Share on other sites

@Rolig Loon

Excellent point that freely-moving objects will see most of the change in the Z dimension even if there's wind at play.  You're right that wanting to know what all possible external forces are would be tough.  Fortunately, just knowing that any external force of any type was applied (even if I don't know precisely where it came from) is good enough for my purposes.

Some initial experimentation shows that wind indeed is NOT a factor, at least for the objects I tried.  I launched a 0.25m radius sphere at various angles measuring the velocity periodically as before but examining all the x,y,z components.  It is indeed true that x and y components do not change at all despite the wind, which itself changed quite a bit more or less randomly during my testing.  I also tried with a much larger object (2m sphere) to see if there's some kind of surface area threshold for wind to affect things, but that object also experienced no change at all in the x or y directions. Despite the one-sentence claim on the wiki (with no further information) that wind affects physical objects, I can see no evidence of it here.  (Maybe it's only true for object with different buoyancy or something.)

I think knowing if it changed in the horizontal plane will turn out to be good enough.  I'll have to think about whether I care if it's being pushed straight up or down, which still has the original problem of how to detect an "additional" force beyond gravity.  None of the above makes that problem any easier.  If anyone has more ideas on the "z-force" problem I'd love to hear it.

 

@Quistess Alpha

You make a good point that explaining the "solution" that I want could preclude someone helping me go an entirely different direction if only they knew the "problem" I wanted to solve.  In this case, llPushObject is just the most obvious way I could think of to change a moving object's direction.  Another obvious way is by colliding with something during its flight, but fortunately there's an event for that.  But LSL allows for forces to be applied at a distance to any object owned by anyone and with no (direct) reporting of accountability for where the extra force came from (that I know of).  The situation I'm working on happens on sims with push enabled and on which I don't control every script that runs there.  Hence the possibility exists that something, somewhere can push stuff around, and it would be handy if I could know it's happening even if I don't know the source.

Edited by Judy Hynes
fix wiki link
Link to comment
Share on other sites

5 minutes ago, Judy Hynes said:

If anyone has more ideas on the "z-force" problem I'd love to hear it.

Only one small clarifying observation. I think that you will very rarely find that anything other than gravity will exert a force that is entirely in the vertical direction. Therefore, it still makes sense to treat the problem as two dimensional in X and Y.  Your greatest uncertainty will arise when the perturbing force in that plane is small, so changes in your object's velocity may be hard to detect among the noise.  Still, unless you are truly interested in detecting those very small pushes, you can make a lot of progress by just ignoring them as well as any velocity changes in Z.

Link to comment
Share on other sites

Another avenue to explore is testing llGetAccel();

If it's neither ZERO_VECTOR, nor <0,0,-9.8>, then some non-gravitational force or impulse (or collision) is being applied to the object.

kinda fun to play with:

default
{   state_entry()
    {   vector accel;
        while(TRUE)
        {   accel=llGetAccel();
            if(llVecDist(accel,ZERO_VECTOR)>0.01 && llVecDist(accel,<0,0,-9.8>)>0.01)
            {   llOwnerSay((string)accel);
                llSleep(0.2);
            }
            llSleep(0);
        }
    }
}

 

Edited by Quistess Alpha
  • Like 1
Link to comment
Share on other sites

4 hours ago, Quistess Alpha said:

I'm having trouble thinking of a case in which I would expect a script that I didn't write to apply a force to an object that I own

There are weapons which push things. "Gangsta Bat" (L$0 on Marketplace) is one such. Other than in combat areas, pushing other people's objects is considered rude.

A few special purpose objects push avatars. There are things which move avatars off the landing point of busy parcels to avoid pileups. There's an older escalator (not mine) which works by pushing. There are sports devices, such as golf clubs, which use pushing. Other than that, pushing is rare.

What problem are you trying to solve?

  • Like 1
Link to comment
Share on other sites

@Quistess Alpha

I did some playing around with llGetAccel and it is a handy way to see the forces on an object.  However, using it as a detection method doesn't seem like it would pan out.  The acceleration change imparted by pushes or even collisions doesn't seem to last long enough to show up when just polling it in a periodic timer, no matter how fast the timer is firing.  So trying to catch something accelerating an object in the act this way isn't really feasible.  Detecting the velocity change does work reliably of course, since that is a persistent change we can detect even after the acceleration has come and gone.

 

Link to comment
Share on other sites

i would probably go with a timer that checks position. If the position changes, and is not captured by start_collision and the change isn't accounted for by wind or by gravity then some other script moved it

calibrating the timer to behave as if it was in real time is a bit of an issue. A example of calibrating a timer is here:

 

Link to comment
Share on other sites

36 minutes ago, Profaitchikenz Haiku said:

Why not have a moving_start event?

i think Judy's object can already be moving, so if another script pushes the object in another direction then the moving_start event won't fire

think of say pitching a baseball at a batter.  The baseball is moving.  If the batter can capture the uuid of the baseball then they could alter the trajectory of the ball (llPushObject on push enabled land). When so then the batter can end up with a much higher batting average than a batter without the script assist

Link to comment
Share on other sites

You are about to reply to a thread that has been inactive for 710 days.

Please take a moment to consider if this thread is worth bumping.

Please sign in to comment

You will be able to leave a comment after signing in



Sign In Now
 Share

×
×
  • Create New...