Synchronous Axes Movement (Lockstep)¶
This example shows how to perform synchronous movement (lockstep) of two axes. Examples assumes one device with two axes. Typical usage of lockstep is parallel gantry mechanism. Further technical information can be found in the following article:
https://www.zaber.com/technical-articles/driving-parallel-axes-with-lockstep-movement
Goal is to perform movement to initial position of 50 mm and then move for 3 second at slow speed. The second axis must have constant offset of 20 mm to the first axis all the time. See the picture.
Program will initially retrieve lockstep information from the device. If the lockstep is not enabled program performs procedure to activate it. Procedure first homes both axes and then set axis 2 to designated offset of 20 mm. Then lockstep is enabled upon axis 1 and 2. From that point on both axes will move synchronously.
# retrieve lockstep info
info = lockstep.info()
# if lockstep is not enabled execute following procedure before movement
if not info.is_enabled:
# home both axes
axis1.home()
axis2.home()
# set axis2 to offset of 20 mm
offset_position = int(20 * 1000 / DEVICE_MICROSTEP_SIZE_MICROMETERS)
axis2.move_abs(offset_position)
# enable lockstep
lockstep.enable(axis1=AXIS_1_NUMBER, axis2=AXIS_2_NUMBER)
Procedure of enabling lockstep serves solely to demonstrate functionality of library. Proper lockstep setup involves mechanical mounting. Instruction from article referenced at top of the page should be followed. In your actual automation program if lockstep is not enabled program should most likely exit with error.
Program continues with movement execution using lockstep
object.
First homing is performed following by movement to initial position of 50 mm.
Then lockstep.move_vel(velocity)
starts movement at specific speed.
Program waits 3 second and stops movement using lockstep.stop()
.
At the end homing is performed to return device to default position.
# home lockstep
lockstep.home()
# move to initial distance of 50 mm
initial_position = int(50 * 1000 / DEVICE_MICROSTEP_SIZE_MICROMETERS)
lockstep.move_abs(initial_position)
# start moving at velocity of 5 mm/s
velocity = int(5 * 1000 / DEVICE_MICROSTEP_SIZE_MICROMETERS * DEVICE_TIME)
lockstep.move_vel(velocity)
# wait 3 seconds
time.sleep(3)
# stop movement
lockstep.stop()
# home lockstep
lockstep.home()
Once the lockstep is enabled device will always move axes synchronously.
All commands performing movement of just one axis will fail.
This includes also commands sent from other software as Zaber Console.
In order to move both axes lockstep
object must be used.
Lockstep can be turned off by calling lockstep.disable()
.
Disabling lockstep makes axes move independently again.
Doing so when axes are mechanically tied may result in damaging devices and other equipment.
# uncomment following line to disable the lockstep at the end
# lockstep.disable()
Please change the port in the code to appropriate port on you computer (e.g. COM3
).
Note that when the program is running, no other program can access the computer port.
# choose appropriate port on your computer (currently COM5)
SERIAL_PORT = "COM5"
Example is using mathematical conversion between device specific microsteps and millimeters. Correct conversion results depend on right value of constant:
# device specific value used to convert distance to microsteps
DEVICE_MICROSTEP_SIZE_MICROMETERS = 0.15625 # micrometers
Please set appropriate values depending on what device is used. Values can be found in devices’ datasheets as “Microstep Size (Default Resolution)”.
More details on lockstep can be found in the following document: https://www.zaber.com/wiki/Manuals/ASCII_Protocol_Manual#lockstep
Example code (Download
):
import time
from zaber.serial import AsciiSerial, AsciiDevice
# device specific value used to convert distance to microsteps
DEVICE_MICROSTEP_SIZE_MICROMETERS = 0.15625 # micrometers
# zaber specific value used to convert time
DEVICE_TIME = 1.6384
# choose appropriate port on your computer (currently COM5)
SERIAL_PORT = "COM5"
# assuming the device has number 1
DEVICE_NUMBER = 1
# lockstep will be activated upon axes 1 and 2
AXIS_1_NUMBER = 1
AXIS_2_NUMBER = 2
def main():
# choose appropriate port on your computer (currently COM5)
port = AsciiSerial(SERIAL_PORT)
# assuming designated device has number 1
device = AsciiDevice(port, DEVICE_NUMBER)
# creating manipulation objects for axes
axis1 = device.axis(AXIS_1_NUMBER)
axis2 = device.axis(AXIS_2_NUMBER)
# creating manipulation object for lockstep
lockstep = device.lockstep()
# retrieve lockstep info
info = lockstep.info()
# if lockstep is not enabled execute following procedure before movement
if not info.is_enabled:
# home both axes
axis1.home()
axis2.home()
# set axis2 to offset of 20 mm
offset_position = int(20 * 1000 / DEVICE_MICROSTEP_SIZE_MICROMETERS)
axis2.move_abs(offset_position)
# enable lockstep
lockstep.enable(axis1=AXIS_1_NUMBER, axis2=AXIS_2_NUMBER)
# at this point lockstep is always enabled and axes move synchronously
# from this point all movements must be performed using "lockstep" object
# home lockstep
lockstep.home()
# move to initial distance of 50 mm
initial_position = int(50 * 1000 / DEVICE_MICROSTEP_SIZE_MICROMETERS)
lockstep.move_abs(initial_position)
# start moving at velocity of 5 mm/s
velocity = int(5 * 1000 / DEVICE_MICROSTEP_SIZE_MICROMETERS * DEVICE_TIME)
lockstep.move_vel(velocity)
# wait 3 seconds
time.sleep(3)
# stop movement
lockstep.stop()
# home lockstep
lockstep.home()
# uncomment following line to disable the lockstep at the end
# lockstep.disable()
# run main function on program start
if __name__ == '__main__':
main()