Jump to content

llSensorRepeat as a timer ?


Calamari
 Share

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

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

Recommended Posts

I thought I'd share this as I can see it could have some other uses, but I'm wondering if there's some reason this would be bad that I'm missing?

I coulden't use a timer event for this because the timer is all ready in use, and gets reset each time an avatar interacts with the object.  I'm using the no_sensor event as a 24 hour timer (it's ok if the times not exact) to reset the pos and rot to get rid of a small amount of drift from KFM.  I've tried this several other ways that work, but found the sensor to added the least amount of run time.

I thought this would be a really bad idea, but after trying it I'm surprised to see it's only adding about 0.00002 ms to the run time.  I see in the caveats there can be problems detecting near sim borders, but don't see that being a problem because it's set to never detect anything, an agent can't have a 1 letter name. 

 

default
{
    state_entry()
    {                      
        llSensorRepeat( "q", "", AGENT , 0.01, 0.01, 86400.0 );
    }
    no_sensor()
    {
        llOwnerSay("test");
    }
}

 

Link to comment
Share on other sites

That's one of many standard ways to run an extra timer in an LSL event.  It works well and with minimal effect on sim load, as you noted.  Especially when you are firing the sensor only once a day and looking 0.1m from your object, the load is really insignificant.

When I use this method, I have always looked for "Bill the Pirate", on the theory that pirates are very elusive and hardly likely to show up anywhere near anything I build.  :smileytongue:

Link to comment
Share on other sites


Rolig Loon wrote:

That's one of many standard ways to run an extra timer in an LSL event.  It works well and with minimal effect on sim load, as you noted.  Especially when you are firing the sensor only once a day and looking 0.1m from your object, the load is really insignificant.

When I use this method, I have always looked for "Bill the Pirate", on the theory that pirates are very elusive and hardly likely to show up anywhere near anything I build.  :smileytongue:

love your use of "Bill the Pirate"  I would have suggested using any linden name as completely safe, but glad to see the new CEO is ruining that option by letting Lindens back in world. :)

You got me curious about what the other standard methods to run extra timers are. I can think of several ways to count time but so far only the Sensor Repeat / no_sensor works exactly the same way as a timer that comes to mind.  I'll have to look in to that more.

Link to comment
Share on other sites

The other most common method is multiplexing. Start a heartbeat timer that triggers, say, once a second. Increment a counter each time it triggers. Then if you have events that you want to occur every 10 seconds, put a test in the timer event that says

if ( !gCount%10){    // Do my special thing}

 If you have some other event that should happen only once a minute, write

if ( !gCount%60){    // Do my other special thing}

 You can stack as many as you like.  You're just counting heartbeats.

Another method would be to run a timer in a second script in your object and then send a linked message to your main script when it triggers.

 

 

 

Link to comment
Share on other sites

Thanks Roling, My current project is using 3 times, 2 are multiplexing, one of those in a separate script that is turned off when not in use, plus a 3rd timer in the main script using sensor repeat.  I've been working a lot on reducing the number of timer used and thinking about when a time can or can't be combined.  I had learned the multiplexing from one of your other post it's been a big help thanks again :)  The term heartbeat timer got me thinking that here must all ready be terms for the ways I'm using timers or how they are set up, I think this will point me in the right direction of more things I need to look up.

Link to comment
Share on other sites

  • 4 weeks later...
  • 7 years later...

I am using the sensor sweep as a fine grained secondary timer. The main timer is on an hour loop. Yes, I know I could have done it differently, but for now, that is the setup. 

llSensorRepeat("", NULL_KEY, AGENT, 0.1, 0.1, 1);

I use this statement, along with the no_sensor event, when I noticed something odd. If I am in the same region, no_sensor triggers about once a second (a little less, since a lot is going on in the script). If the region is empty - devoid of any agent - the triggering speed halves!

I assume the Lab has inlcuded some mechanisms by now, to slow down certain stuff when nobody is around?

 

Edited by Peter Stindberg
  • Like 1
Link to comment
Share on other sites

10 hours ago, Peter Stindberg said:

I assume the Lab has inlcuded some mechanisms by now, to slow down certain stuff when nobody is around?

Yeah, but it's been around a pretty long time. You can use llGetEnv() to test "region_idle" to see when it goes into effect. More details here from back in 2012 when it was new.

Link to comment
Share on other sites

I changed the script to use a single - regular - timer yesterday, and the effect persists. If I set the interval to a second, and write every completed 60 seconds into a log, when the region is empty, I only get about 32 entries.

Strangely enough, I have region_idle detection in the script already, but it never fired. I need to check its implementation again.

Link to comment
Share on other sites

a way to help with this is realtime calibration (as best we can)


we can write our calibration method in different ways as they suit our app. The basic principle tho being: when the script is running too slow for our app, have the event fire sooner. When the script is running too fast for our app, slow down event firing

using a timer for example of this kind of technique

float PERIOD = 1.0;   // the timer realtime period that we want to slave toward. 1.0 = once every second
float LENGTH = 60.0;  // the number of past timer events from which we calculate the next timer period

float aggregate;      // the total of realtime event periods for the length
float previous;       // the realtime the previous event fired


state_entry()
{
   aggregate = PERIOD * LENGTH;   
   previous = llGetTime();
   llSetTimerEvent(aggregate / LENGTH);  // = PERIOD to begin with
}

timer()
{
   // get the current time
   float time = llGetTime();

   // deduct the average of aggregate then add the latest elapsed realtime period
   aggregate += (time - previous) - (aggregate / LENGTH);
 
   // save current time
   previous = time;

   // when our script is firing at a average realtime greater than PERIOD (going slow)
   // then we want to increase the rate of the timer. Decreasing the rate conversely
 
   llSetTimerEvent(PERIOD / (aggregate / LENGTH));
}

 

  • Like 5
Link to comment
Share on other sites

That is a good solution @Mollymews!

For coarse-resolution scripts I usually have a "seconds to full hour" routine, that I call at the end of the timer:

float SecondsToFullHour()
{
list TimeStamp = llParseString2List(llGetTimestamp(),["-",":"],["T"]);
return 60 - llList2Integer(TimeStamp,6) + ((60 - 1 - llList2Integer(TimeStamp,5)) * 60);
}
  • Thanks 1
Link to comment
Share on other sites

9 hours ago, Peter Stindberg said:

For coarse-resolution scripts I usually have a "seconds to full hour" routine, that I call at the end of the timer:

float SecondsToFullHour()
{
list TimeStamp = llParseString2List(llGetTimestamp(),["-",":"],["T"]);
return 60 - llList2Integer(TimeStamp,6) + ((60 - 1 - llList2Integer(TimeStamp,5)) * 60);
}

something to consider

when our resolution is 1 second then I tend to go with llGetUnixTime(). Which can help to make our code a little more efficient. Example:

integer secondsToFullHour = 60 - llGetUnixTime() % 60;

this also allows us to more readily inline the function while remaining code descriptive.  Uses less clock cycles than does parsing llGetTimeStamp() and by inlining we save the 500+ compiled bytes that a user-defined function costs

 

oops. Just noticed my snippet is seconds to next minute. Seconds to next hour is

integer secondsToFullHour = 3600 - llGetUnixTime() % 3600;

 

Edited by Mollymews
oops
  • Like 1
Link to comment
Share on other sites

You are about to reply to a thread that has been inactive for 765 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...