How do I wait for a signal (say “triggerSignal”) from a component (say “fromComponent”) in a different component using the condition statement. The question seems very straightforward but somehow I cannot get it to work.
I had similar issues. I think its because you need to connect the signal in the properties to the pythons script. So signal in component(a) is connect to python script in component(a) but not to the python script in component(b).
I am using a robot so I found it far easier to connect the signals to the robot and control it from there.
If you dont have a robot then I guess you would need to create an output signal in component(a) and connect to an input signal on component(b). So output (a) trigger input (b) and the python script looks at the input (b).
I havent tried that as I just found it so much easier to do everything through the robot inputs and outputs in my case.
It is not very intuitive that you need to connect the signal to the script in order to get the trigger events. This is there to improve the performance so that only the desired signals will generate events. I usually use this simple code to make sure that the signal is creating events.
There’s also a slight difference with condition and triggerCondition.
Condition will test the condition when the python execution reaches that line. If the condition is false it will continue waiting next trigger and will test it again on every trigger.
triggerCondition won’t test the condition when the line is reached in the python execution, it will test it first time on the next trigger.
Let’s say if you have a sensor on a conveyor and the part has already arrived on the sensor before your python code reaches the condition line. If you are using triggerCondition it won’t pass the line, it will wait a next trigger which might not ever come because the sensor is already blocked. condition would pass it because it would do the ‘test’ when the line is reached and it would notice that, oh, there’s a part already, let’s move on.
I have the same problem as original poster. I dont understand how to add other behaviours to the Connections list in this case. Is there a method for it?
In order to listen a signal within another component you have to add the listening script to the connections of the signal behavior (in the component to be listened).
In the following example, “Transition” signal of “ShapeFeeder” is listened from the component containing the script.
from vcScript import *
app = getApplication()
comp = getComponent()
monitoredSignal = None
def OnStart():
global monitoredSignal
this = comp.findBehaviour("PythonScript")
monitoredComp = app.findComponent("ShapeFeeder")
monitoredSignal = monitoredComp.findBehaviour("TransitionSignal")
print monitoredSignal
print monitoredSignal.Connections
if this not in monitoredSignal.Connections:
monitoredSignal.Connections = monitoredSignal.Connections + [this]
print monitoredSignal.Connections
def OnRun():
n = 0
while True:
triggerCondition(lambda: getTrigger() == monitoredSignal and getTrigger().Value == True)
n += 1
print n, "New component created!"
After running the sim, you should see the additional PythonScript added to the Transition signal Connections which is invoked when ever the signal is triggered.
Writing behaviors to other component’s signal.Connections is throwing error, but working ok.
Adding other behaviors to the Connections list using API is not prevented, and this approach works ok. However, sometimes this might be a bit unstable, for example components objects can be lost when layout has been changed or reopened, etc. That’s why you might see the warning printed in the Output window:
Warning: Assigning value of incorrect type for property ‘Connections’ in script ‘Human (Anna)::ResourceScript’. Property type is ‘List<Ref >’.
To avoid this problem, safer approach would be to register to signal.OnValueChange event.
Remember to use evaluateCondition() to re-evaluate the condition when waiting on that line.
Here is an example:
from vcScript import *
app = getApplication()
comp = getComponent()
monitoredSignal = None
triggerer = None
def OnStart():
global monitoredSignal
monitoredComp = app.findComponent("Shape Feeder")
monitoredSignal = monitoredComp.findBehaviour("TransitionSignal")
monitoredSignal.OnValueChange = on_transition_signal
def on_transition_signal(signal):
global triggerer
triggerer = signal
evaluateCondition()
def OnRun():
global triggerer
n = 0
while True:
triggerCondition(lambda: triggerer == monitoredSignal and triggerer.Value == True)
triggerer = None
n += 1
print n, "New component created!"