PDA

View Full Version : delaying proximity reaction makes sensor unresponsive for the time of delay


jelly
11-21-2016, 03:32 AM
In a recent post I had a problem implementing a delay in the proximity manager and Jeff has suggested the solution of using "vizproximity.waitEnter" and a while loop:

def proximityTask():
global handstate
while True:
yield vizproximity.waitEnter(SensorIndexFinger)
print 'entered sensor'
yield viztask.waitTime(2)
print 'two seconds elapsed'
handstate = 1

viztask.schedule(proximityTask())

However, with this code I have a new problem and I decided to open up a new thread:

What happens now is that, once the sensor is entered, the action (change of the variable handstate from 0 to 1), will be delayed by two seconds. However if I happen to enter the sensor again very quickly, before these two 2 seconds have elapsed, nothing happens, as it seems that it is not registered that the sensor has been entered, until the first action takes place.

I wonder if there is a way around this? I tried to to the following: I will change a new variable upon entry but then I will make a new function where I say that IF the new variable "condition" is equal to 1 then after 2 seconds the handstate should change to 1 (= delayed action). This way I am hoping that I am not delaying the action itself in the proximity manager, I am delaying it outside of that function so that the proximity manager can freely register all entries.



def EnterProximity_IndexFinger(e): # decide what happens on sensor entry
global handstate, condition
e.sensor == SensorIndexFinger
condition = 1
print condition
manager.onEnter(SensorIndexFinger,EnterProximity_I ndexFinger)

with this I am just changing the variable condition and the I will try to use that in the following way:

def Handdelay():
global handstate, condition
print "now"
if condition == 1:
#yield vizproximity.waitEnter(SensorIndexFinger)
yield viztask.waitTime(2)
handstate = 1
print "open hand"
else:
handstate = 0

viztask.schedule(Handdelay())

Unfortunately, the condition change is registered as soon as I enter the sensor, but the function which is supposed to call the delayed action (handstate changing to 1) is not working.

I would be very grateful for help!

Jeff
11-21-2016, 11:22 AM
It sounds like you need to determine whether the sensor was exited before two seconds elapsed. If that's the case, use the viztask.waitAny (http://docs.worldviz.com/vizard/#commands/viztask/waitAny.htm) command to help with this:

def proximityTask():

waitEnter = vizproximity.waitEnter(SensorIndexFinger)
waitExit = vizproximity.waitExit(SensorIndexFinger)
waitTime = viztask.waitTime(2)

while True:
yield waitEnter
print 'entered sensor'

d = yield viztask.waitAny( [ waitExit, waitTime ] )

if d.condition is waitExit:
print 'Sensor exited before two seconds'
else:
print '2 seconds elapsed'

viztask.schedule(proximityTask())

jelly
11-22-2016, 10:02 AM
I have tried this code but what it does is, it triggers the action as long as the sensor is still entered, after 2 seconds and does not do that if the sensor is exited before 2 seconds have elapsed.

I actually think this might be a different issue:

I want an action to be triggered with a delay, every single time a sensor is entered. If I use waitEnter and waitTime what I achieve is that I "block" the sensor - nothing is registered until the action (and the 2 second delay) are carried out. So it cannot be that I trigger the action EVERY time a sensor is entered, because the 2 second delay creates a minimum of time that needs to have passed before another sensor entry is even registered. Basically, I want the sensor to be entered instantly, each time, and only the action - which is a consequence of the sensor entry - should be triggered with a delay.

Another illustration:

1) If I approach an object, I enter its sensor and I trigger an action of that object.
2) If I want a 2 second delay: I approach an object, I enter its sensor and I trigger an action of that object only after 2 seconds.
3) The problem comes now: If I approach an object a second time within one second of the first time, nothing will happen, because the program is still carrying out the action with delay scheduled as a response to the first approach.

Jeff
11-22-2016, 11:07 AM
Try the following example. After the sensor enter event occurs in the proximity task another task is called that handles the delay:

import viz
import vizproximity
import viztask

viz.go()

dojo = viz.addChild('dojo.osgb')

#Create proximity manager
manager = vizproximity.Manager()
manager.setDebug(viz.ON)

#Add main viewpoint as proximity target
target = vizproximity.Target(viz.MainView)
manager.addTarget(target)

#Create sensor using static matrix
sensor = vizproximity.Sensor(vizproximity.Sphere(1.0),sourc e=viz.Matrix.translate(0,1.5,3))
manager.addSensor(sensor)

def delayTask():
yield viztask.waitTime(2)
print '2 seconds elapsed'

def proximityTask():
while True:
yield vizproximity.waitEnter(sensor)
print 'entered sensor'
viztask.schedule(delayTask())

viztask.schedule(proximityTask())

jelly
11-23-2016, 04:20 AM
Jeff, thank you very much! It works perfectly, I have adapted it for my script:

def delayTask():
global handstate
yield viztask.waitTime(2)
handstate = 1
print '2 seconds elapsed'
yield viztask.waitTime(0.7)
handstate = 0

def proximityTask():
while True:
yield vizproximity.waitEnter(SensorIndexFinger)
print 'entered sensor'
viztask.schedule(delayTask())

viztask.schedule(proximityTask())

I think I had a good intuition that I needed two steps or two functions to implement this, but I was stuck thinking that I needed the "manager.onEnter". Thanks again!