Welcome to the Second Life Forums Archive

These forums are CLOSED. Please visit the new forums HERE

Problem with LLMoveToTarget

Debbie Trilling
Our Lady of Peenemünde
Join date: 17 Oct 2006
Posts: 434
01-16-2008 14:20
Made a mistake when striping down the code: SleepMin should be 10.0, not 1.0

Corrected above.

As a second test, I'm also running a version where the StartOperation() in 'not_at_target' is replaced by MakeMove()
Haruki Watanabe
llSLCrash(void);
Join date: 28 Mar 2007
Posts: 434
01-16-2008 14:52
Debbie,

I was SHOCKED, when I ran the script for the first time and it stopped moving! ... until I saw that the max_sleep_time is 20 seconds... :)

I have it running right now (did some changes to the script right away, just where I think they'd be useful, although, I'm not gonna post them unless the cube moved for a couple of hours :)
Haruki Watanabe
llSLCrash(void);
Join date: 28 Mar 2007
Posts: 434
01-17-2008 13:03
Debbie,

No luck so far - it arbitrarily stops... :(

I keep on trying, though...
Debbie Trilling
Our Lady of Peenemünde
Join date: 17 Oct 2006
Posts: 434
01-17-2008 13:30
Sorry to hear that Haruki, and thank you for your efforts.

I have tried many permutations over the last few months, eventually just shrugging my shoulders and talking myself into blaming Havok1...
Meade Paravane
Hedgehog
Join date: 21 Nov 2006
Posts: 4,845
01-17-2008 14:02
I played with targetted moves about a year ago and it nearly made me insane..

One thing I remember was that when things started going weird, at_target didn't always return me the last value that got returned from llTarget.

I'd put a check in at_target and make sure that the first param is what you're expecting it to be.
_____________________
Tired of shouting clubs and lucky chairs? Vote for llParcelSay!!!
- Go here: http://jira.secondlife.com/browse/SVC-1224
- If you see "if you were logged in.." on the left, click it and log in
- Click the "Vote for it" link on the left
Debbie Trilling
Our Lady of Peenemünde
Join date: 17 Oct 2006
Posts: 434
01-18-2008 04:02
From: Meade Paravane
I'd put a check in at_target and make sure that the first param is what you're expecting it to be


Thanks Meade for this sound suggestion. I've already attempted a number of different variations of it as part of standard debugging.

The problem that arises is the sheer volume of messages that are generated, some 20-odd every 10 to 12 seconds and then perhaps for hours-on-end. If you log-off, IM's get capped very quickly; llOwnerSay/llSay is a spam nightmare. Also, when simulataneously running multiple objects with different versions of the script...well, you can imagine!

Although the original problem posed by the OP is now solved, it is unclear what changed to actually solve it. It is therefore difficult to isolate/define that change and apply the same principle(s) to other code. However, it *seems* that the answer was a code change, and so I see no reason why, eventually, after toil, trial and error, a solution could not be found.

It seems to me that the problem we are having in debugging is that we don't really understand the cause(s)/reason(s) why something would run perfectly as designed for an extended period of hours, then just stop for (as yet) no discernable reason.

Admitedly it does sound like its "running-out-of-steam" (friction/energy) but this raises questions in itself; why would two exactly the same objects running exactly the same script and started within a few seconds of each other have sometimes many of hours difference between one stopping and the other? I have no idea.

But please, any other suggestions are more than welcome...
Haruki Watanabe
llSLCrash(void);
Join date: 28 Mar 2007
Posts: 434
01-18-2008 04:41
Debbie,

I have a suspicion that the problem might lay withing this command:

llMoveToTarget(next, llVecDist(next, llGetPos())/metersPerSec);

when llVecDist(next, llGetPos())/metersPerSec is too small (< 0.2) the object won't move anymore...

I changed it now to this:

float damp = llVecDist(next, llGetPos())/metersPerSec;

if(damp < 0.3)
damp = 0.3;

llMoveToTarget(next, damp);

... and I'm testing it now... maybe? :)
Debbie Trilling
Our Lady of Peenemünde
Join date: 17 Oct 2006
Posts: 434
01-18-2008 05:19
Hi Haruki

Good catch!

I've set off a test version (5:18am SLT) with a hardcoded tau of "0.3", which is somewhat higher than I'd like, but hopefully is a stable value for testing purposes
Haruki Watanabe
llSLCrash(void);
Join date: 28 Mar 2007
Posts: 434
01-18-2008 05:31
/me keeps fingers crossed :D
Debbie Trilling
Our Lady of Peenemünde
Join date: 17 Oct 2006
Posts: 434
01-19-2008 05:21
From: Haruki Watanabe
I have a suspicion that the problem might lay withing this command: llMoveToTarget(next, llVecDist(next, llGetPos())/metersPerSec);


I definately think you are on to something here, Haruki. I have had two tests using a hardcoded value of '0.3' running now for an extended period of time.

Test1: As code in thread #50 above, but with a simple hardcoded tau of '0.3'

Test2: As code in thread #50 above with a hardcoded tau of '0.3' and the random z-vectors in function CheckPoints() significantly increased (ie: "0.75 + llFrand(0.55)" is changed to "3.75 + llFrand(3.55)";)

The good news is that both have been running for an extended period; the bad is that Test1 looks like a kangaroo with delirium tremors and Test2 a kangaroo on steroids.

Correcting this is hopefully a matter of fine-tuning and finding a happy balance between the tau value and the minimum random jump height.

But, curiouser and curiouser, having jumped this far down the rabbit hole I'm finding the the pause interval between jump-bursts (llSetTimerEvent(SleepTime)) is no longer occuring. That is, the object is consistantly in a jump cycle without any random 10 to 20 second wait. The easy way out, ofc, is to use a llSleep instead of a timer but this seems a little unsatisfactory.

Look forward to hearing your findings :)
Haruki Watanabe
llSLCrash(void);
Join date: 28 Mar 2007
Posts: 434
01-19-2008 09:44
Debbie,

Well - it seems that you're one step further than me! :) my object still stops after a certain time. But I do think that playing with the tau and the range in llTarget() will eventually do the trick...

Another thought I had - the distances you move your object, are pretty small. Did you ever try to just use llSetPos() instead of llMoveToTarget()? For short distances, it might look even better than it's looking now (or is it more a «hop» than a «move» with llSetPos()?)...

I keep on trying, though! :)

Cheers!

[edit]

I just tried the llSetPos()-Version and ... it looks like (to quote you) a Kangaroo on steroids... :) - So this obviously ain't an option...
Debbie Trilling
Our Lady of Peenemünde
Join date: 17 Oct 2006
Posts: 434
01-19-2008 10:02
Hi Haruki

We are trying to produce a "bounce", a movement with a degree of "springiness" at the end of it, rather than the simple deadstop movement that llSetPos() provides.

The distances are quite small, as you say, and my instinct is that this may be contributing to the problem. I've therefore re-jigged function CheckPoints() to this and am currently running a test using it. A second test alongside is using llSleep rather than a timer.

CODE

CheckPoints()
{

//start with a clean slate
checkPoint = [];

// NB: the order that the following lines appear in is important. Do not change or subject checkPoint to llListRandomize.
// now we'll set some random jump points as offsets of the start position
// jump to the left & right & up
checkPoint += (list)<(0.88 + llFrand(0.88) * -1), 0.83 + llFrand(0.83), 1.75 + llFrand(1.58)>;
// and return back down to the same z co-ord as Start Point, but with some right & left offset
checkPoint += (list)<0.90 + llFrand(0.90), (0.95 + llFrand(0.95) * -1), 0.00>;
// jump to the left & right & up
checkPoint += (list)<(0.90 + llFrand(0.90) * -1), 0.85 + llFrand(0.85), 1.45 + llFrand(1.88)>;
// and return back down to the same z co-ord as Start Point, but with some right & left offset
checkPoint += (list)<0.85 + llFrand(0.85), (0.95 + llFrand(0.95) * -1), 0.00>;
// jump to the left & right & up
checkPoint += (list)<(1.03 + llFrand(1.03) * -1), 0.90 + llFrand(0.90), 1.65 + llFrand(1.68)>;
// and return back down to the same z co-ord as Start Point, but with some right & left offset
checkPoint += (list)<0.95 + llFrand(0.95), (0.95 + llFrand(0.95) * -1), 0.00>;
// jump to the left & right & up
checkPoint += (list)<(0.93 + llFrand(0.93) * -1), 0.85 + llFrand(0.85), 1.70 + llFrand(1.63)>;
// and return back down to the same z co-ord as Start Point, but with some right & left offset
checkPoint += (list)<0.90 + llFrand(0.90), (0.90 + llFrand(0.90) * -1), 0.00>;
// jump to the left & right & up
checkPoint += (list)<(0.90 + llFrand(0.90) * -1), 0.85 + llFrand(0.85), 1.95 + llFrand(1.35)>;
// and return back down to the same z co-ord as Start Point, but with some right & left offset
checkPoint += (list)<0.80 + llFrand(0.80), (0.95 + llFrand(0.95) * -1), 0.00>;
// jump to the left & right & up
checkPoint += (list)<(0.90 + llFrand(0.90) * -1), 0.85 + llFrand(0.85), 1.55 + llFrand(1.78)>;
// and return back down to the same z co-ord as Start Point, but with some right & left offset
checkPoint += (list)<0.80 + llFrand(0.80), (0.95 + llFrand(0.95) * -1), 0.00>;
// jump to the left & right & up
checkPoint += (list)<(0.90 + llFrand(0.90) * -1), 0.85 + llFrand(0.85), 1.75 + llFrand(1.58)>;
// and return back down to the same z co-ord as Start Point, but with some right & left offset
checkPoint += (list)<0.80 + llFrand(0.80), (0.95 + llFrand(0.95) * -1), 0.00>;
// jump to the left & right & up
checkPoint += (list)<(0.90 + llFrand(0.90) * -1), 0.90 + llFrand(0.90), 1.35 + llFrand(1.98)>;
// and return back down to the same z co-ord as Start Point, but with some right & left offset
checkPoint += (list)<0.78 + llFrand(0.78), (0.78 + llFrand(0.78) * -1), 0.00>;
// jump to the left & right & up
checkPoint += (list)<(0.90 + llFrand(0.90) * -1), 0.85 + llFrand(0.85), 1.55 + llFrand(1.78)>;
// and return back down to the same z co-ord as Start Point, but with some right & left offset
checkPoint += (list)<0.65 + llFrand(0.65), (0.65 + llFrand(0.65) * -1), 0.00>;
// jump to the left & right & up
checkPoint += (list)<(0.60 + llFrand(0.60) * -1), 0.60 + llFrand(0.60), 1.25 + llFrand(2.08)>;

// the first offset in the list should equal the Start Position
checkPoint = (list)<0.0,0.0,0.0> + checkPoint;
}
Debbie Trilling
Our Lady of Peenemünde
Join date: 17 Oct 2006
Posts: 434
01-19-2008 11:34
Test using new version of CheckPoints() and llSleep() has stopped
Test using new version of CheckPoints() and a timer is currently working fine

Third test started using a supporting second script to apply a small impulse if object hasn't moved position after 45 seconds, as suggested by Seifert Surface a couple of days ago:

CODE

vector CurrPos;
vector ObjVel;

default
{
state_entry()
{
ObjVel = llGetMass() * <0.0,0.0,5.0>;
CurrPos = llGetPos();
llSetTimerEvent(45.0);
}


timer()
{

if (llGetPos() == CurrPos)
{
llSetStatus(STATUS_PHYSICS, TRUE);
llApplyImpulse(ObjVel, TRUE);
}
CurrPos = llGetPos();
}
}
Haruki Watanabe
llSLCrash(void);
Join date: 28 Mar 2007
Posts: 434
01-19-2008 13:32
Debbie,

I'm currently trying the same with a second script. I guess, that this is the best approach to keep it moving.
Also, I found out that small distances might cause problems. Therefore, I set the range in llTarget(targ, range) - to a very small number (0.1). This results in small hiccups now and then (the object goes way beyond it's target, but eventually finds back on track).

Right now, the object is behaving _very_ strange - it moves once and then stops... Maybe I destroyed the whole thing now... :)

Hope you're more successful than I am...
Haruki Watanabe
llSLCrash(void);
Join date: 28 Mar 2007
Posts: 434
01-20-2008 00:13
Debbie,

It DOES look promising this time... :)

I added several stuff to stop and start the MoveToTarget and so far, it's running...

And - it's with your original vectors and a minimal tau of 0.2 (lower isn't recommended by the wiki) and with the sleep in between...

I'll have some sleep now and keep my fingers crossed that I outwitted it... :)
Debbie Trilling
Our Lady of Peenemünde
Join date: 17 Oct 2006
Posts: 434
01-21-2008 13:23
Hi Haruki! How they bouncing?

My single cube has been going for 48+ hours now, with pauses, and no manual intervention. The Kangaroo object itself (31 prims) just under that, but required a lil nudge on 2 seperate occasions.

It seems that Seifert's suggestion of a second script providing a small impulse is a viable workaround. I found that "llGetMass() * <0.0,0.0,5.0>" proved far too stong for 31 prims, and apparantly NASA have recently reported seeing the first Kangaroo in space, expected to collide with Mars on 30th Jan. I've therefore adjusted the impulse to "llGetMass() * <0.0,0.0,1.0>"

My scripts use a tau of "0.3" and the revised CheckPoints() function. I'd be eager to see a time-proved version using a tau of "0.2" and the original CheckPoints() function, if you've managed to outwit it.

BTW: will send you a copy of the fabulous Cartoonimals Kangaroo (created by Duggy Bing) when we have all these wrinkles finally ironed out. Thanks for all your efforts :)
Haruki Watanabe
llSLCrash(void);
Join date: 28 Mar 2007
Posts: 434
01-21-2008 13:49
Hey Debbie,

I've got it moving for several hours now, with the original Vectors and no 2nd script...

I'm kinda tired, so I post the script without any further explanation...
Just try it and lemme know whether it's working for your as well...
I guess you'll see where my changes are (added some «Edit by Haruki» to the code now and then)...

CODE


integer CheckPointsSet = FALSE;
list checkPoint = [];
vector startCheck = <0.0,0.0,0.0>;
integer thisCheck = -1;
vector startingPoint = <0.0,0.0,0.0>;
float metersPerSec = 6.0;
integer targetHandle = 0;
float SoundVolume = 1.0;
float SleepMin = 1.0;
float SleepMax = 5.0; // Made this smaller so I can speed testing up...

CheckPoints()
{

//start with a clean slate
checkPoint = [];

// NB: the order that the following lines appear in is important. Do not change or subject checkPoint to llListRandomize.
// now we'll set some random jump points as offsets of the start position
// jump to the left & right & up
checkPoint += (list)<(0.40 + llFrand(0.35) * -1), 0.45 + llFrand(0.25), 0.75 + llFrand(0.55)>;
// and return back down to the same z co-ord as Start Point, but with some right & left offset
checkPoint += (list)<0.55 + llFrand(0.25), (0.45 + llFrand(0.45) * -1), 0.00>;
// jump to the left & right & up
checkPoint += (list)<(0.45 + llFrand(0.35) * -1), 0.45 + llFrand(0.25), 0.45 + llFrand(0.75)>;
// and return back down to the same z co-ord as Start Point, but with some right & left offset
checkPoint += (list)<0.35 + llFrand(0.25), (0.45 + llFrand(0.45) * -1), 0.00>;
// jump to the left & right & up
checkPoint += (list)<(0.55 + llFrand(0.50) * -1), 0.45 + llFrand(0.35), 0.65 + llFrand(0.85)>;
// and return back down to the same z co-ord as Start Point, but with some right & left offset
checkPoint += (list)<0.45 + llFrand(0.45), (0.45 + llFrand(0.45) * -1), 0.00>;
// jump to the left & right & up
checkPoint += (list)<(0.48 + llFrand(0.35) * -1), 0.45 + llFrand(0.30), 0.70 + llFrand(0.55)>;
// and return back down to the same z co-ord as Start Point, but with some right & left offset
checkPoint += (list)<0.45 + llFrand(0.35), (0.55 + llFrand(0.45) * -1), 0.00>;
// jump to the left & right & up
checkPoint += (list)<(0.45 + llFrand(0.35) * -1), 0.45 + llFrand(0.25), 0.95 + llFrand(0.35)>;
// and return back down to the same z co-ord as Start Point, but with some right & left offset
checkPoint += (list)<0.35 + llFrand(0.25), (0.45 + llFrand(0.45) * -1), 0.00>;
// jump to the left & right & up
checkPoint += (list)<(0.45 + llFrand(0.35) * -1), 0.45 + llFrand(0.25), 0.55 + llFrand(0.55)>;
// and return back down to the same z co-ord as Start Point, but with some right & left offset
checkPoint += (list)<0.35 + llFrand(0.25), (0.45 + llFrand(0.45) * -1), 0.00>;
// jump to the left & right & up
checkPoint += (list)<(0.45 + llFrand(0.35) * -1), 0.45 + llFrand(0.25), 0.75 + llFrand(0.55)>;
// and return back down to the same z co-ord as Start Point, but with some right & left offset
checkPoint += (list)<0.35 + llFrand(0.25), (0.45 + llFrand(0.45) * -1), 0.00>;
// jump to the left & right & up
checkPoint += (list)<(0.40 + llFrand(0.40) * -1), 0.45 + llFrand(0.35), 0.35 + llFrand(0.55)>;
// and return back down to the same z co-ord as Start Point, but with some right & left offset
checkPoint += (list)<0.35 + llFrand(0.25), (0.45 + llFrand(0.25) * -1), 0.00>;
// jump to the left & right & up
checkPoint += (list)<(0.45 + llFrand(0.35) * -1), 0.45 + llFrand(0.25), 0.55 + llFrand(0.75)>;
// and return back down to the same z co-ord as Start Point, but with some right & left offset
checkPoint += (list)<0.15 + llFrand(0.15), (0.15 + llFrand(0.15) * -1), 0.00>;
// jump to the left & right & up
checkPoint += (list)<(0.05 + llFrand(0.15) * -1), 0.05 + llFrand(0.15), 0.25 + llFrand(0.65)>;

// the first offset in the list should equal the Start Position
//checkPoint = (list)<0.0,0.0,0.0> + checkPoint;
checkPoint += (list)startingPoint; // Changed this to the last offset in the list
// might cause hiccups
// Edit Haruki -> why <0.0,0.0,0.0>? Guess this should be startingPoint?
}


StopOperation()
{
llSetTimerEvent(0.0);
thisCheck = -1;
llSetStatus(STATUS_PHYSICS, FALSE);
llStopMoveToTarget();
llTargetRemove(targetHandle);
llSetPos(startingPoint);
}


StartOperation()
{
startingPoint = llGetPos();
thisCheck = 0;

MakeMove();
}


MakeMove()
{
vector next;

if(llList2Vector(checkPoint, thisCheck) != startingPoint)
{
next = startingPoint + llList2Vector(checkPoint, thisCheck);
}
else
{
next = startingPoint;
}

// Edit Haruki

targetHandle = llTarget(next, 0.1); // the «range» is the distance that the at_target-event
// «scans» to detect whether the object is at the target
// or not - so no need to do some math here
float damp = llVecDist(next, llGetPos())/metersPerSec;

if(damp < 0.2)
damp = 0.2;

llSetStatus(STATUS_PHYSICS, TRUE);
llMoveToTarget(next, damp);

// Added the next two lines just to make sure the sucker is moving... :)

llSleep(0.2);
llMoveToTarget(next, damp);

// End Edit Haruki
}

default
{
on_rez(integer start_param)
{
llResetScript();
}

state_entry()
{
llSetStatus(STATUS_PHYSICS | STATUS_PHANTOM | STATUS_ROTATE_X | STATUS_ROTATE_Y | STATUS_ROTATE_Z, FALSE);
llSetBuoyancy(1.0); // Make Object floating
startCheck = llGetPos();
llSetText("", <1.0, 1.0, 1.0>, 1.0);
}

touch_start(integer total_number)
{
startingPoint = llGetPos(); // Why startCheck?
CheckPoints();
StartOperation();
}

at_target(integer tnum, vector targetpos, vector ourpos)
{
if(tnum == targetHandle)
{
llStopMoveToTarget();
llSetStatus(STATUS_PHYSICS, FALSE);
llTargetRemove(targetHandle);

thisCheck++; // Moved this out - so when we reach List-Length, the Move will not be
// Made again, since we're back at the starting point

// Edit Haruki

llSetPos(targetpos); // Set the Object back to the starting-point

// End Edit Haruki

if(thisCheck == llGetListLength(checkPoint))
{

thisCheck = 0;

CheckPoints();

llSetText("Checking Points", <1.0, 1.0, 1.0>, 1.0);

float SleepDiff = SleepMax - SleepMin;
float SleepTime = SleepMin + llFrand(SleepDiff);
llSetTimerEvent(SleepTime);
}
else
{
//thisCheck++;
MakeMove();
}

// play sound effect when at Start Position z co-ord (odd number positions in list)
if (((thisCheck % 2) != 0) && (SoundVolume > 0.00))
{
llPlaySound("c02681b3-52f3-dfa0-416b-3f414fb01aef",SoundVolume);
}
}
// at_target end
}

timer()
{
llSetTimerEvent(0.0);
MakeMove();
// timer end
}

// default end
}

Debbie Trilling
Our Lady of Peenemünde
Join date: 17 Oct 2006
Posts: 434
01-21-2008 14:54
Haruki

How are you declaring variable "next" in MakeMove()?

Also, does this use a supporting second impulse script?
Haruki Watanabe
llSLCrash(void);
Join date: 28 Mar 2007
Posts: 434
01-21-2008 15:17
Debbie,

Sorry, I edited the script here and deleted the declaration for vector next...
I corrected the script above now...

... and - it doesn't support a 2nd script - but it should be fairly easy, to implement one...

I got the object running for quite some time now without haveing a 2nd script, though...
Haruki Watanabe
llSLCrash(void);
Join date: 28 Mar 2007
Posts: 434
01-25-2008 07:15
Debbie,

Yes - I'm still working on it :)

Meanwhile, I have the suspicion, that consecutive calls to llMoveToTarget which are applied too fast, cause the script go mad...

simply added a llSleep(0.2) before every new call to your function MakeMove() and so far, it's behaving...
If it's still moving in a few hours, I'm gonna post the actual version of the script...
Debbie Trilling
Our Lady of Peenemünde
Join date: 17 Oct 2006
Posts: 434
01-25-2008 07:43
Thanks Haruki

I'm having some success too. Have had one 31 prim object hopping successfully now for 36+ hours, and another for 15+ hours

I combined some of your script with my own for this test, but the important changes *seems* to me to be the following lines. These tests use a hardcoded tau value of 0.25.

llMoveToTarget(next, 0.25);
llSleep(0.2);
llMoveToTarget(next, 0.25);

But it is definately looking promising.

The object creator (I'm only doing the scripting for these products) decided that the first version of function CheckPoints() wasn't an energetic enough hop, and the second version out-of-proportion for the height of his 'Roo.

I'm therefore playing around with the values in that function to find acceptable values. But these are aesthetic changes based on how it is felt a Cartoon Kangaroo behaves, rather than anything we are addressing here
Taeas Stirling
Registered User
Join date: 4 Sep 2004
Posts: 74
01-26-2008 14:31
Hi folks. I have had a pod of whales swimming in the elf land seas for months now, some without a touch for the whole while. No jerks jumps or weird movements. Not even sim resets seems to phase them.
I use
pos = (vector)data;
llLookAt(pos, 0.5, 0.5);
llMoveToTarget(pos,1);
llSleep(1);
fed vectors from a note card reader. I think the reader gives it a better persistance. If the server drops the ball or misses a move_to call your dead in the water
Tryptofaa Sands
Registered User
Join date: 25 Mar 2007
Posts: 6
02-24-2008 06:26
Hey folks :) I've been making a swimming squid that uses llMoveToTarget and llTarget to know when it gets there, and sure enough I too was having this issue where they would suddenly stop for no apparent reason. I found a somewhat simple solution...

moving_end(){
llMoveToTarget(targetPos, tau);
}

the moving_end event seems to detect when these freezes occur, but also detects when you drag the object and let go, so you may want to add a condition that it will only repeat the llMoveToTarget function if it's actually currently moving to a target! But all it seems to need is a repeat of llMoveToTarget to give it a kickstart to continue. My squid has been swimming on it's own for 5 days now!

Hope this helps!

Tryp
Chaz Longstaff
Registered User
Join date: 11 Oct 2006
Posts: 685
04-16-2008 15:01
Hey guys, if any of y'all is still watching this thread, does any of this still work post April 8th / 9th?
Johan Laurasia
Fully Rezzed
Join date: 31 Oct 2006
Posts: 1,394
04-17-2008 03:22
Sorry I'm chiming in on this so late, but your issue IS with it running out of steam. you have the range in the llTarget set to 0.1. llMoveToTarget() damps as it approaches the target, and with a range of 1/10 of a meter, it must be slowing to an absolute crawl. Try setting the range to 1 or 1.5 meters, and move your destination waypoint a meter or two farther away. That way, far less damping will occur by the time the at_target is triggered, and it will have enough energy to get within the range of the waypoint and still trigger the at_target event. The reason it's stopping at different times is due to the wind. Wind is sometimes high, sometimes low. When your object is moving into the direction of the wind, AND the wind is high enough, it's shaving off enough energy to slow the object down such that it's not moving at all. Easy fix here, set a reasonable at_target trigger range, like 1.5 meters works great.

Some other things to consider... is the object set to phantom? I set mine to phantom so it doesnt get clipped by anything, which can steal energy. Also, is part of it dragging on the ground? Even if it's set to phantom, if it drags on the ground, it WILL clip the ground. (Ground != object), so it will clip phantom or not.

Also, I didnt see an llSetBuoyancy(1.0) in there.... toss that in, trust me, it'll come in handy down the road as your script becomes more complex, it'll keep it from falling out of the sky.
1 2 3 4