Emergency Stop

Hi,

i tried to interrupt the movejoint command but all my ideas went wrong. So is there a posibility to simulate an emergency stop or a stop by user at the current position ?

Regards,

LA-CU

You want to stop a servo?

Ah sorry forgot to mention it. Yes i’d like to stop a servo under some circumstances.

A servo executing a movement for joint is a time consuming process in API. So one “solution” is to use two scripts: one for moving joints, the other for stopping them. It might work in one script, but have not tested. All you are really doing is running the servo with a heartbeat/pulse and using an event handler to immediately move joints controlled by servo in zero simulation time. It won’t work if you disable servo, and I always use moveImmediate().

StartStopServo.vcmx (22.8 KB)

1 Like

Slice one servo move to maybe 100 or 1000 steps.

In each step, if emergency signal fired, then break the loop.

Up vote for Chungmin’s answer. It is pretty straightforward to write a module for doing that, so you can import it in other scripts. Not sure though if performance of app is better with heartbeat approach or loop of steps… 8-O

Your script works perfectly fine. I integrated your stopjointscript in movejoint with some additional changes, but my Simulation stops itself while im running the script.

from vcScript import *
comp = getComponent()
servo = comp.findBehaviour(“ServoController”)
app = getApplication()
sim = app.getSimulation()
sim.IgnoreEvents = True

def OnSignal( signal ):
value = servo.getJointValue(0)
print signal.Value
if signal.Value == True:
servostop(value)
else:
sim.continueRun()

def OnRun():
servo.moveJoint(0,900)

def servostop(value):
servo.moveImmediate(value-0.01)

 

 

Tried something new:

 

from vcScript import *
comp = getComponent()
servo = comp.findBehaviour(“ServoController”)
stop = comp.findBehaviour(‘Stop’)
start = comp.findBehaviour(‘Start’)

def OnSignal( signal ):
if(signal.Name == ‘Stop’):
stop()

def OnRun():
triggerCondition(lambda:start.Value == True)
servo.moveJoint(0,900)

def stop():
value = servo.getJointValue(0)
print value
servo.moveImmediate(value-0.01)

 

same result. The Simulation stops automatically if i call the stop method. I have to reset the simulation afterwards.

 

Regards

I’ve tried both of your snippets both won’t stop the simulation in my case. Unfortunately I’m not able to tell you why. I’ve controlled the layout by PLC.

You can find the layout in the attachment. It’s just the layout of zesty with your script(s) and some minor changes. I’ve disabled Heartbeat since your script’s wont use that anyway.

Which VC Version are you using?

Greetings Felix

EmergencyStopServo.vcmx (24.6 KB)

@felix

works fine for me in 4.0.5. tested your layout by adding extra script behavior with this code. of course, in this example the signal.signal() method is used. if you still get issues then try with OnValueChange event handler.


from vcScript import *

def OnSignal( signal ):
pass

def OnRun():
delay(5)
comp = getComponent()
signal = comp.findBehaviour(“Stop”)
signal.signal(True)


@zesty

Yeah, I guess that it works how it’s supposed to be in our cases, I’m just wondering why LA-CU got issues. One of my guesses would be a different VC Version. I’ve also used the official release version of 4.0.5 (build 77886).

Greetings Felix

@felix

sorry, i misread your previous post.

@anon94827467

click the Program tab, and then check the Limits group to see if any of those options are enabled.

Forcing the servo movement to stop immediately is not so easy to model and unfortunately there is no standard api call at the moment. You always have to use scripting workarounds although this is a common requirement when doing virtual commissioning. I would recommand to use the suspendRun() and resumeRun() methods to interrupt and restart the servo movement.

 

1 Like

@felix @zesty sorry couldn’t test your scripts. Unfortunately i’m not at work at the moment.

@Ralle

suspendRun() came also to my mind, but it doesn’t fit the requirements. An emergency stop was just an easy example to explain my problem, but i have to stop und start various servos at different positions and different times in the simulation.

 

Regards

For virtual commissioning tasks we are using several ‘motion controllers’ based on suspendRun() and resumeRun() and they are working fine. Also to start/stop various servos at different positions and different times. For each servo to be controlled you will need a seperat script.

The only limitation is that you don’t have a decceleration ramp. The stopping is always abrupt.

1 Like

@Felix

Hello there! I ran your program, why do I have to wait a few seconds to restart after stopping?

@Ralle

hello,Ralle!Do you have a similar example? Can you give me a reference? thank you!!!

Hi,

This is so frequently asked topic, that I decided to share some examples here, how you could implement the emergency stop function.

When using servo controller, you can add new targets to the joints at any given time. For emergency stopping you can just give the current joint values as targets. However, it is not possible to “stop” the internal motion controller, although the servo motion is stopped in 3D scene. This is why you need to use SuspendRun() and ResumeRun() anytime you give new targets.

Use rounding when comparing the current values to the targets, since there is certain tolerance when the servo is not going to move (e.g. 1e-12 mm distance)

Please see the simple example “Lifter_Button-Controlled” to understand the basic idea and more sophisticated example “Lifter_Signal-Controlled” for implementing lifter for virtual commissioning with I/Os.

 

When you program robot executor and want to stop the robot controller with emergency stop event, you can create a python script which is disabling robot executor (Executor::IsEnabled == False). That is causing the robot not to stop immediately, but still move to the current target.

To stop immediately, you could create a new target with the current joint values, then call servo.moveImmedate().

When emergency stop is released, you just enable the robot executor again, and the robot will continue from the next motion point. So this approach is skipping the next target in the moment emergency button was pressed. However, when releasing the emergency stop, it would be possible to force the robot to move to the next target by using python, before enabling the robot executor again.

And like @ralle mentioned, in any of these examples, there is no decceleration ramp. The stopping is always immediate.

Please see the attachment “EmergencyStopForRobotExecutor”, which is simple example stopping the executor by python, and the other, a bit more fancy attachment “RobotReactionSpeedGame”

Lifter_Button-Controlled.vcmx (154 KB)

Lifter_Signal-Controlled.vcmx (154 KB)

EmergencyStopForRobotExecutor-1.vcmx (263 KB)

RobotReactionSpeedGame-1.vcmx (1.42 MB)

In a blocking task, when the right signal (True) moves to the right (True), a certain task triggers the left signal when the object moves to the right, then the object stops moving, the state of the right signal is True, the state of the left signal is True, and the movement signal is False.

在一个阻塞的任务中,某任务当右信号(True)向右移动(True),在物体向右移动时触发左信号此时物体停止运动,右信号状态为True,左信号状态为True,移动信号为False,请问同时刻可以实现吗???

伺服控制-2.vcmx (2.41 MB)

In a blocking task, when the right signal (True) moves to the right (True), a certain task triggers the left signal when the object moves to the right, then the object stops moving, the state of the right signal is True, the state of the left signal is True, and the movement signal is False.Can it be achieved at the same time?

在一个阻塞的任务中,某任务当右信号(True)向右移动(True),在物体向右移动时触发左信号此时物体停止运动,右信号状态为True,左信号状态为True,移动信号为False,请问同时刻可以实现吗? 请给意见,谢谢。

 

伺服控制.vcmx (2.41 MB)