Cancel system.gui.transform

I’m using system.gui.transform with a duration to move a container to X,Y positions supplied by PLC tags. This works, except when I begin a new movement with another system.gui.transform before the previous move has completed its duration. Then I see erratic behavior with the container quickly bouncing back and forth between the two destinations before ultimately landing on the newest one. Is there a way I can cancel the transformation in process before executing a new one? Or another method to handle this case?

Function I am using:
system.gui.transform(container, newX, newY, duration=5000, acceleration= 4)

Ignition 7.9.12

One of the original applications for objectScript() (from Simulation Aids) was precisely this sort of animation. (Animation via system.gui.transform() didn’t exist yet.) Instead of computing a complete series of steps and applying them unconditionally on a fixed pace, the approach with objectScript() is to maintain a state machine and compute each step as it occurs. It is more complicated to implement, but handles any change in target gracefully. You can even model the acceleration on a curve from one target to the next. The demo project has an example (without accel) on the last tab.

I created and posted a 40-second video using the SimAids demo project showing the animation:

https://www.automation-pros.com/simaids/SimAids-MotionDemo.mkv

From the manual (system.gui.transform):

  • Returns
    PyObject animation - An animation object that the script can use to pause(), resume(), or cancel() the transformation.

Is that what you're looking for?

Thank you Phil. I’m on the road this week, but will examine this module when I return.

It may very well be, but I could not figure out how to implement it.

Well, it shouldn’t be so hard… :wink:

  1. Create client project script in ‘Scripting/Project Library/’ (Ignition8) or ‘Project/Scripts/Script Library’ (Ignition7.9) with the name ‘global_variables’
  2. Put this inside:
_transformObject = None
  1. On the Vision window put rectangle box and 4 buttons.
  2. Name buttons as ‘Start’, ‘Pause’, ‘Resume’ and ‘Cancel’.
  3. In the ‘Start’ button ‘ActionPerformed’ event put this code:
event.source.parent.getComponent('Rectangle').relX = 50
project.global_variables._transformObject = system.gui.transform(component=event.source.parent.getComponent('Rectangle'), newX=710, duration=10000, acceleration=system.gui.ACCL_FAST_TO_SLOW)
  1. In the ‘Pause’ button ‘ActionPerformed’ event put this code:
if project.global_variables._transformObject is not None:
	project.global_variables._transformObject.pause()
  1. In the ‘Resume’ button ‘ActionPerformed’ event put this code:
if project.global_variables._transformObject is not None:
	project.global_variables._transformObject.resume()
  1. In the ‘Cancel’ button ‘ActionPerformed’ event put this code:
if project.global_variables._transformObject is not None:
	project.global_variables._transformObject.cancel()

And that’s it…

This is a great example. Thanks. I had some time today to attempt this, but I do have 50 objects moving on my screen utilizing this method and I still see too much erratic behavior. I am able to significantly decrease this behavior by doing the transform with a newX and newY without a duration (so it happens immediately and is over). Some examples of the problems I see in addition to the jerky movement are the containers being briefly invisible and also them falling behind other objects even though they are on top.