Waiting for multiple signals

Hi experts!

I am rather new to python programming and I’m struggling with modelling this component:
I have modelled my own belt conveyor and now I want to connect different signals to it and each signal triggers a different movement eg., moving a belt to adjust to the size of the product.

I don’t know how to program the script so that it waits until a signal is triggered and then move the respective joint (with servo.moveJoint(0,…)). I’ve already tried using onSignal (signal) or conditiontrigger (in a while loop) and if…elif inside a while loop but with no success.

For what I’ve learned so far:
-onSignal doesn’t let me use commands for movement that need time like .movejoint.
-conditiontrigger looks like it needs to be executed in the order or if not it won’t enter on the next conditiontrigger
-the if… elif option gets the program hooked.

Does someone know how to program this?

Thanks in advance.

Hi,

Use a while loop,
inside it,
if you need a positive or negative trigger (rising/falling edge) =>
triggerCondition(lambda: getTrigger() == yourSignal and yourSignal.Value)
if you do not need a trigger, but simply wait until a value is something, and the value change could have already happend =>
condition(lambda: yourSignal.Value)

In OnSignal, you are correct, you are not allowed to spend simulation time, e.g. moving a servo, unless it is immediate motions.

Hey @line_out ,

Thanks for your answer. I tried the triggerCondition method inside a while loop as follows:

    #WHILE LOOP INSIDE DEF ONRUN()
    while sim.IsRunning == True:
    #MOVEMENT OF STOPS:
    triggerCondition ( lambda:getTrigger()==sensorSignal and sensorSignal.Value)
    servo.moveJoint(0,30)
    triggerCondition ( lambda:getTrigger()==sensorSignal and sensorSignal.Value==False)
    servo.moveJoint(0,0)

    #MOVEMENT OF BELTS IN X AXIS:
    triggerCondition ( lambda:getTrigger()==PresetSignal and PresetSignal.Value) 
    servo2.moveJoint(0,-180)
    triggerCondition ( lambda:getTrigger()==PresetSignal and PresetSignal.Value==False)
    servo2.moveJoint(0,0)

As I said, when I try this method looks like I must run the script in order. If I try to trigger the “PresetSignal” before “sensorSignal” it does nothing. Any ideas on how to solve it?

Thanks again,

Aha yes, you must have them in order, you can solve it in 2 ways,

either you do something like:
triggerCondition ( lambda:getTrigger() in [sensorSignal, PresetSignal ])
if sensorSignal.Value:
doSomething
elif not sensorSignal.Value:
do something else
elif PresetSignal .Value:
do something else
etc.

or you create a queue in OnRun:
def OnSignal(signal):
if signal == sensorSignal and sensorSignal .Value:
queue.append((0,30))
elif signal == sensorSignal and not sensorSignal .Value:
queue.append((0,0))

def OnRun():
global queue
queue = []
while True:
condition(lambda: queue)
target = queue.pop(0)
servo2.moveJoint(target[0], target[1])

1 Like

Thanks @line_out !!

I tried out the first one and it worked perfectly fine although I had to change one elif since it wasn’t working at first somehow. Here’s the code:

  while sim.IsRunning == True:
  triggerCondition ( lambda:getTrigger() in [sensorSignal,PresetSignal])
  #MOVEMENT OF STOPS:
  if PresetSignal.Value:
    servo2.moveJoint(0,-180)
  elif PresetSignal.Value==False:
    servo2.moveJoint(0,0)
  #MOVEMENT OF BELTS IN X AXIS
  if sensorSignal.Value:
    servo.moveJoint(0,30)
  elif sensorSignal.Value==False:
    servo.moveJoint(0,0)

Thanks, I really appreciate your help.

1 Like

By the way, when do you recommend to use more than one python script for a component?

For virtual commissioning purposes I have many inputs/outputs per component that may happen in parallel so I was wondering if it was wise to use more than one python script.

Thanks for your help.

1 Like

Hi, remember that each script, creates like a sandbox (uses system resources), so the more is not merrier. Only have more then one, if you have things that require parallel execution that is not solvable in 1 thread so to speak.

1 Like