Welcome to the Second Life Forums Archive

These forums are CLOSED. Please visit the new forums HERE

can I perform multiple "llSensor" calls in a row for different object names?

Greg Hauptmann
Registered User
Join date: 30 Oct 2005
Posts: 283
01-30-2006 21:57
Hi,

I'm currently offline but wanting to check whether I can perform multiple "llSensor" calls in a row for different object names? (i.e. wanting to sense several object, who have unique names, but noting the call doesn't allow wildcards in the name I think) That is, I want to make sure the 2nd "llSensor" call doesn't cancel the 1st one? Can anyone confirm?

I wanted to then pick up the responses in a "sensor" event, and match up the sensed results with the object names using "llDetectedName".

Depending on how SL works I'm guessing if I send out say 10 llSensor calls in a row that I could get them returning in different batches of "sensor" events perhaps. Will be interesting to see.

The alternative if the above doesn't work is to sense each object successfully one by one, however I'm really trying to parrellel this to get the overall time down for the sensing stage.


Tks
Introvert Petunia
over 2 billion posts
Join date: 11 Sep 2004
Posts: 2,065
01-30-2006 22:07
Based on this note in llSensorRemove I would assume that each llSensor() call replaces the previous one much like llSetText() does.
Note that unlike a listener, there is no need to specify the sensor by key. This is because objects can only contain one sensor per prim.
which would imply that you'd have to serialize the llSensor() calls within the sensor event handler as its last action.
Masakazu Kojima
ケロ
Join date: 23 Apr 2004
Posts: 232
01-30-2006 22:27
CODE
default {
state_entry() {
llSensor( "A", NULL_KEY, PASSIVE, 32, PI );
llSensor( "B", NULL_KEY, PASSIVE, 32, PI );
llSensor( "C", NULL_KEY, PASSIVE, 32, PI );
}

sensor(integer num) { llOwnerSay(llDetectedName(0)); }
no_sensor() { llOwnerSay("no sensor"); }
}

I tested with this, and only the first sensor worked. Putting 2-10 second sleeps between each sensor makes the first and third work, but not the second.
Greg Hauptmann
Registered User
Join date: 30 Oct 2005
Posts: 283
01-30-2006 23:18
Tks Masakazu - I'll have to stick with my current sequential method then :(. Very kind of you to test for me.
Greg
Eloise Pasteur
Curious Individual
Join date: 14 Jul 2004
Posts: 1,952
01-31-2006 09:18
I don't doubt the results, although I'm surprised to see that putting sleeps let more than one of the sensors fire.

Triggering the first one *should* fire a sensor which takes you to a sensor() or no_sensor() event and I wouldn't expect it to take you back to the state_entry() event.

Serial it is, unless you have a multi-prim object and each prim has a sensor for parallel processing. Can I strongly urge you NOT to do it repeatedly - even well filtered sensors are sim hogs as I understand it, and although there might be no other way if there is it would be friendlier.
Masakazu Kojima
ケロ
Join date: 23 Apr 2004
Posts: 232
01-31-2006 09:37
From: Eloise Pasteur
Triggering the first one *should* fire a sensor which takes you to a sensor() or no_sensor() event and I wouldn't expect it to take you back to the state_entry() event.
The sensor() and no_sensor() are events and are queued just like any other. Firing a sensor (or any other kind of event) does not take you out of the event you are in.

CODE
default {
state_entry() {
llSensor( "A", NULL_KEY, PASSIVE, 32, PI );
while (TRUE) // forever
llSleep(999); // go back to bed
}

sensor(integer num) { llOwnerSay(llDetectedName(0)); }
no_sensor() { llOwnerSay("no sensor"); }
}

If you did this, your state_entry() event handler would never exit, and neither sensor event handler would ever be entered. Your script will only enter a different event handler when a new event arrives and it is not currently doing anything, or another event handler exits and there are more events waiting.

http://secondlife.com/badgeo/wakka.php?wakka=Events
Damien Took
Meat Popsicle
Join date: 3 Dec 2004
Posts: 151
01-31-2006 10:02
I can't test this from work but have you tried:

CODE
llSensor( "A" | "B" | "C", NULL_KEY, PASSIVE, 32, PI ); 


Also, I have script that uses wildcards to detect an AV/object. Though it does the filtering in the sensor.
But I can think of one way to use one sensor to find the name that matches the wildcard and then remove itself (sensor) to start another sensor using the full name as the filter.
I can post the script later this evening if you like.
Is that what you are looking for?
Masakazu Kojima
ケロ
Join date: 23 Apr 2004
Posts: 232
01-31-2006 10:08
From: Damien Took
llSensor( "A" | "B" | "C", NULL_KEY, PASSIVE, 32, PI );

There is no | operator for strings, so this just gives a type mismatch error.
Sky Honey
Coder
Join date: 16 May 2005
Posts: 105
01-31-2006 12:00
From llSensorRepeat
From: someone
A script can have only one sensor at a time. The current sensor is removed by another call to llSensorRepeat or llSensor (or llSensorRemove, obviously).
Damien Took
Meat Popsicle
Join date: 3 Dec 2004
Posts: 151
01-31-2006 12:23
Masakazu,

I was afraid of that. :rolleyes:

Greg,

I would say the best bet is to put a filter in the sensor.
I would think that multiple sensors would cause some heavy lag.
Argent Stonecutter
Emergency Mustelid
Join date: 20 Sep 2005
Posts: 20,263
01-31-2006 13:11
I think you have to have the sensor/no_sensor events kick off the subsequent sensors. If you need to have more sensors running in parallel, you'll have to run multiple scripts.

This code handles up to 127 concurrent sensors with a resolution of 1/8 meters out to max sensor range.
CODE

multi_sensor(list names, integer type, key id, float range)
{
integer n = llGetListLength(names);
integer i;

for(i = 0; i < n; i++)
{
llMessageLinked(LINK_SET,
((i + 1)<<24) | (type << 16) | llTrunc(range * 8),
llList2String(names, i), id);
}
}
//...
link_message(integer from,integer num, string name, key id)
{
if(!(num & (1<<31))) return;
if(num&(1<<30))
{
handle_multi_sensor_end(num&127);
return;
}
vector off = <
((float)((num>>20)&65535))/8,
((float)((num>>10)&65535))/8,
((float)( num &65535))/8
>;
handle_multi_sensor(off+llGetPos(),name,id);
}


Then the child script does this:
CODE

state_entry()
{
my_id = some_function_of(llGetScriptName());
}
link_message(integer from,integer num, string name, key id)
{
integer id = (num>>24)-1;
if(id != my_id) return;
integer type = (num>>16)&255;
float range = ((float)(num & 65535)) / 8;
llSensor(name,type,id,range,PI);
}
sensor(integer num)
{
for(i = 0; i < num; i++)
{
vector off = llDetectedPos(i) - llGetPos();
string name = llDetectedName(i);
key id = llDetectedKey(i);
llMessageLinked(LINK_SET,
(1<<31)|llTrunc(off.x*8)<<20|llTrunc(off.y*8)<<10|llTrunc(off.z*8),
name, id);
}
llMessageLinked(LINK_SET,(3<<30)|my_id,"",NULL_KEY);
}
no_sensor()
{
llMessageLinked(LINK_SET,(3<<30)|my_id,"",NULL_KEY);
}
Greg Hauptmann
Registered User
Join date: 30 Oct 2005
Posts: 283
01-31-2006 21:31
I wonder what is less laggy/better for sim: (a) multiple sensors per Argent's suggestion or (b) 96m sense for all owner objects then filter through them? :confused:
Eloise Pasteur
Curious Individual
Join date: 14 Jul 2004
Posts: 1,952
02-01-2006 04:06
Hard to say, there are so many variables in the mix...

But remember sensor will only return 16 pings at a time - generally searching for specific items is much more likely to find them.
Argent Stonecutter
Emergency Mustelid
Join date: 20 Sep 2005
Posts: 20,263
02-01-2006 14:59
Yeh, I created a scanner to look for other people's stuff on my land, and since I can't llSensor for anything BUT llGetOwner() I eventually scripted a prim to traverse the whole place in little jumps doing repeated small calls.

That DEFINITELY requires more work from the server (albeit over a longer period) than running half a dozen llSensor()s in parallel. I don't think it'd be possible, in the general case, to do it without multiple calls.

If time isn't that big an issue, an easier answer is:

CODE

list pending_names;
float pending_range;
integer pending_type;
multi_sensor(list names,integer type,float range)
{
if(llGetListLength(names) != 0)
{
pending_names = names;
pending_range = range;
pending_type = type;
}
if(llGetListLength(pending_names) == 0)
{
//...
return;
}

string name = llList2String(pending_names, 0);
pending_names = llList2List(pending_names, 1, -1);
llSensor(name, pending_type, ...);
}
//...
sensor(integer num)
{
integer i;
for(i = 0; i < num; i++)
{
frob(llDetectedFoo(i), llDetectedBar(i));
snog(llDetectedRube(i));
//...
}
multi_sensor([], 0);
}
no_sensor()
{
multi_sensor([], 0);
}
Greg Hauptmann
Registered User
Join date: 30 Oct 2005
Posts: 283
02-02-2006 18:45
From: Argent Stonecutter
Then the child script does this:
Kind of tricky interpretting what you are doing here (with the bitwise ops and all). :)

For a general "senseObjectIDs(list listOfNames)" type call I would imagine you would want a way to ping the child scripts to see which are still busy/which are free, so you then use the next available no?