MantisBT - opensim
View Issue Details
0003298opensim[REGION] Script Functionspublic2009-03-14 10:192019-04-08 02:02
Data Rossini 
UbitUmarov 
normalminoralways
closedfixed 
 
 
Standalone (Multiple Regions)
ODE
Mono / Linux64
0003298: Prim moving with "llSetpos(pos)" and check position with llGetPos() never reach given end-position
Want to move a prim to a given destination and check reaching the end-position with llGetPos() != pos.
In SL prim and script stops after prim reaching the exactly end-position.
In OpenSim the script never stops and prim never reaching the *exactly* end-position.
Look at the script and outputs of script in SL and OpenSim.


_________________________________________
vector pos;

default
{
    state_entry()
    {

    }
    
    touch_start(integer touches)
    {
        pos = llGetPos();
        llOwnerSay("Old position is: " + (string)pos);
        pos.x = pos.x + 1.1111;
        pos.y = pos.y + 1.1111;
        pos.z = pos.z + 1.1111;
        integer count = 1;
        while (llGetPos() != pos) {
        // workaround //
        //while (llVecDist( llGetPos(), pos ) > 0.00005) {
            llOwnerSay((string)count + " New position should be: " + (string)pos);
            llSetPos(pos);
            llOwnerSay((string)count + " New position is: " + (string)llGetPos());
            count += 1;
        }
        llOwnerSay((string)count + " Reach end-position at: " + (string)pos);
    }
}
_________________________________________

Output in SL:

[12:23] Object: Old position is: <151.84030, 219.54250, 24.32660>
[12:23] Object: 1 New position should be: <152.95140, 220.65360, 25.43770>
[12:23] Object: 1 New position is: <152.95140, 220.65360, 25.43770>
[12:23] Object: 2 Reach end-position at: <152.95140, 220.65360, 25.43770>

It's OK here. Script stops, because pos == llGet(pos)


Output in OpenSim:

[11:11] Test llSetPos llGetPos: Old position is: <86.267105,186.000000,28.878643>
[11:11] Test llSetPos llGetPos: 1 New position should be: <87.378205,187.111100,29.989743>
[11:11] Test llSetPos llGetPos: 1 New position is: <87.378204,187.111099,29.989742>
[11:11] Test llSetPos llGetPos: 2 New position should be: <87.378205,187.111100,29.989743>
[11:11] Test llSetPos llGetPos: 2 New position is: <87.378204,187.111099,29.989742>
[11:11] Test llSetPos llGetPos: 3 New position should be: <87.378205,187.111100,29.989743>
[11:11] Test llSetPos llGetPos: 3 New position is: <87.378204,187.111099,29.989742>
[11:11] Test llSetPos llGetPos: 4 New position should be: <87.378205,187.111100,29.989743>
[11:11] Test llSetPos llGetPos: 4 New position is: <87.378204,187.111099,29.989742>
[11:11] Test llSetPos llGetPos: 5 New position should be: <87.378205,187.111100,29.989743>
[11:11] Test llSetPos llGetPos: 5 New position is: <87.378204,187.111099,29.989742>
[11:11] Test llSetPos llGetPos: 6 New position should be: <87.378205,187.111100,29.989743>
[11:11] Test llSetPos llGetPos: 6 New position is: <87.378204,187.111099,29.989742>
[11:11] Test llSetPos llGetPos: 7 New position should be: <87.378205,187.111100,29.989743>
[11:11] Test llSetPos llGetPos: 7 New position is: <87.378204,187.111099,29.989742>
[11:11] Test llSetPos llGetPos: 8 New position should be: <87.378205,187.111100,29.989743>
[11:11] Test llSetPos llGetPos: 8 New position is: <87.378204,187.111099,29.989742>
[11:11] Test llSetPos llGetPos: 9 New position should be: <87.378205,187.111100,29.989743>
[11:11] Test llSetPos llGetPos: 9 New position is: <87.378204,187.111099,29.989742>
[11:11] Test llSetPos llGetPos: 10 New position should be: <87.378205,187.111100,29.989743>
[11:11] Test llSetPos llGetPos: 10 New position is: <87.378204,187.111099,29.989742>
[11:11] Test llSetPos llGetPos: 11 New position should be: <87.378205,187.111100,29.989743>
[11:11] Test llSetPos llGetPos: 11 New position is: <87.378204,187.111099,29.989742>
[11:11] Test llSetPos llGetPos: 12 New position should be: <87.378205,187.111100,29.989743>
[11:11] Test llSetPos llGetPos: 12 New position is: <87.378204,187.111099,29.989742>
[11:11] Test llSetPos llGetPos: 13 New position should be: <87.378205,187.111100,29.989743>
[11:11] Test llSetPos llGetPos: 13 New position is: <87.378204,187.111099,29.989742>
[11:11] Test llSetPos llGetPos: 14 New position should be: <87.378205,187.111100,29.989743>
...
...
Script seems never stop and prim never reach end position. There is allways a differenz in positions
No tags attached.
duplicate of 0002787closed HomerHorwitz llSetPos is not precise 
Issue History
2009-03-14 10:19Data RossiniNew Issue
2009-03-14 10:19Data RossiniSVN Revision => 8790
2009-03-14 10:19Data RossiniRun Mode => Standalone (Multiple Regions)
2009-03-14 10:19Data RossiniPhysics Engine => ODE
2009-03-14 10:19Data RossiniEnvironment => Mono / Linux64
2009-03-14 10:19Data RossiniMono Version => 2.0.1
2009-03-14 10:21Data RossiniSummaryPrim moving with "llSetpos(pos)" and llGetPos() never reach given end position => Prim moving with "llSetpos(pos)" and check position with llGetPos() never reach given end position
2009-03-14 10:23Data RossiniSummaryPrim moving with "llSetpos(pos)" and check position with llGetPos() never reach given end position => Prim moving with "llSetpos(pos)" and check position with llGetPos() never reach given end-position
2009-03-14 10:23Data RossiniDescription Updated
2009-03-14 10:26Data RossiniDescription Updated
2009-03-14 11:24FrankNicholsNote Added: 0009961
2009-03-14 11:28Ewe LoonNote Added: 0009963
2009-03-14 11:34Ewe LoonRelationship addedduplicate of 0002787
2009-03-14 11:44Ewe LoonNote Added: 0009965
2009-03-14 11:47Ewe LoonNote Edited: 0009963
2009-03-14 11:48HomerHorwitzNote Added: 0009967
2009-03-14 12:27Data RossiniDescription Updated
2009-03-14 12:33Data RossiniNote Added: 0009971
2009-03-14 12:56Ewe LoonNote Added: 0009972
2009-03-14 12:59Ewe LoonNote Edited: 0009972
2009-03-14 13:02Ewe LoonNote Edited: 0009972
2011-07-23 23:02makopoppoNote Added: 0019054
2011-07-23 23:02makopoppoStatusnew => confirmed
2019-02-05 06:52tampaNote Added: 0034149
2019-04-08 02:02UbitUmarovMono Version2.0.1 =>
2019-04-08 02:02UbitUmarovNote Added: 0035063
2019-04-08 02:02UbitUmarovStatusconfirmed => closed
2019-04-08 02:02UbitUmarovAssigned To => UbitUmarov
2019-04-08 02:02UbitUmarovResolutionopen => fixed
2019-04-08 02:22UbitUmarovNote Edited: 0035063bug_revision_view_page.php?bugnote_id=35063#r7961
2019-04-08 02:25UbitUmarovNote Edited: 0035063bug_revision_view_page.php?bugnote_id=35063#r7962

Notes
(0009961)
FrankNichols   
2009-03-14 11:24   
You should never program expecting exact positions. (exact anything when using floating point). Instead you should test for being within a range of a target location.

Hopefully this script is just to demonstrate the "problem" and not something that would be used in the wild. This script would be a serious lag generator.

Instead use the llTarget(...) and at_target(...) to detect when you are withing a specific range of the destination.
(0009963)
Ewe Loon   
2009-03-14 11:28   
(edited on: 2009-03-14 11:47)
this error ocurs because Opensim stores numbers as Single Presision (32bit) where the scripts only use Double presision (64bit)

because of the conversion there is always going to be a small discrepency

i recomemd for testing positions use something like

if (llVecDist(DesternationPos,CurrentPos)<0.00001)

(0009965)
Ewe Loon   
2009-03-14 11:44   
perhaps to solve this we could change the vector comparison operator from

public static bool operator ==(Vector3 lhs, Vector3 rhs)
{
   return (lhs.x == rhs.x && lhs.y == rhs.y && lhs.z == rhs.z);
}
to
public static bool operator ==(Vector3 lhs, Vector3 rhs)
{
   return (abs(lhs.x - rhs.x)<0.00001 && abs(lhs.y - rhs.y)<0.00001 && abs(lhs.z - rhs.z)<0.00001);

to account for this discrepancy
What do the rest of you think
}
(0009967)
HomerHorwitz   
2009-03-14 11:48   
-1

== is the equality operator. If v1 - v2 != ZERO_VECTOR, then v1 == v2 should be false, because they just aren't equal.
(0009971)
Data Rossini   
2009-03-14 12:33   
Thank you, for help!

Have change the script like this.

//while (llGetPos() != pos) {
// workaround //
while (llVecDist( llGetPos(), pos ) > 0.00005) {
  ...
}

But it is difference between SL and OpenSim, so that some script not work.
(0009972)
Ewe Loon   
2009-03-14 12:56   
(edited on: 2009-03-14 13:02)
the above suggestion is not ideal anyway,
neither is running scripts that work in double presission values when everything they manipulate is single presission,

Ideally Both scripts and Opensim would use the same pression and what is sent to and from the client viewer
this would mean
A) less time wasted converting between double and single presission
B) Comparisons wouldnt fail due the Conversion Inaccuracy

Perhaps someone whould add a new new function to compair vectors at single presision level
e.g.

public bool osCompairVector(LSL_Vector v1, LSL_Vector v2)
{
  return (((float)v1.x==(float)v2.x)&&((float)v1.y==(float)v2.y)&&((float)v1.z==(float)v2.z));
}

and

public bool osIsPosition(LSL_Vector v1)
{
  Vector3 pos = m_host.GetWorldPosition();
  return (((float)v1.x==pos.x)&&((float)v1.y==pos.y)&&((float)v1.z==pos.z));
}

(0019054)
makopoppo   
2011-07-23 23:02   
The issue still exists in current 0.7.2-dev.
(0034149)
tampa   
2019-02-05 06:52   
Confirmed on master, XEngine and YEngine, produces spam on console:

15:51:14 - [EVENT MANAGER]: Delegate for TriggerOnChatBroadcast failed - continuing. Object reference not set to an instance of an object at OpenSim.Region.CoreModules.Avatar.Chat.ChatModule.OnChatBroadcast (System.Object sender, OpenSim.Framework.OSChatMessage c) [0x0019a] in <0f8eaf1920a749638cbf45b463daeb84>:0
  at OpenSim.Region.Framework.Scenes.EventManager.TriggerOnChatBroadcast (System.Object sender, OpenSim.Framework.OSChatMessage chat) [0x00029] in <53fc407b565a4f629718bdf136e6182f>:0

using original script.
(0035063)
UbitUmarov   
2019-04-08 02:02   
(edited on: 2019-04-08 02:25)
totally wrong scripting.

(llGetPos() != pos) it totally wrong. that is a exact compare and will fail most cases
use the new osApproxEquals funtions or the ones recommended above
also position resolution in this case may le less that 1.e5, something like 0.01 .. 0.001 is a lot safer

and this assuming the object was actually totally free to move.
llSetPos(pos) is a unconditional command, it will set the position if possible
if it fails, you should not keep trying the same at full blast. (it also has restrictions)

the fact opensim uses double precision (64bit) for LSL_Float is just a historical waste. Everything LSL interacts with is plain float (32bit)