Multi-axis Zaber devices are capable of synchronizing the movement of parallel axes using a feature called lockstep.
The library offers a way to control these lockstep groups.
Setup
Before using lockstep, check if the device is capable of using the feature by ensuring the lockstep.numgroups setting has a non-zero value (this setting indicates how many lockstep groups the device supports; a value of 0 or a failing command indicates it is not supported).
Python
C#
C++
JavaScript
MATLAB
Java
MATLAB (legacy)
num_groups = device.settings.get('lockstep.numgroups')
print('Number of lockstep groups possible: ', num_groups)
const numGroups = await device.settings.get('lockstep.numgroups');
console.log('Number of lockstep groups possible:', numGroups);
var numGroups = device.Settings.Get("lockstep.numgroups");
Console.WriteLine("Number of lockstep groups possible: {0}", numGroups);
doublenumGroups= device.getSettings().get("lockstep.numgroups");
System.out.println("Number of lockstep groups possible: " + numGroups);
numGroups = device.getSettings().get('lockstep.numgroups');
fprintf('Number of lockstep groups possible: %d', numGroups);
numGroups = device.Settings.get('lockstep.numgroups');
fprintf('Number of lockstep groups possible: %d', numGroups);
double numGroups = device.getSettings().get("lockstep.numgroups");
std::cout << "Number of lockstep groups possible: " << numGroups << std::endl;
Enabling
Before enabling a lockstep group, home each axis individually and align the axes to your desired offset.
The offset is the distance between the axes in the lockstep group.
This offset saves upon enabling a lockstep group, and the device will maintain it during movement.
Once you have set up the axes, use the following code to enable the lockstep group for axis 1 and 2.
Note that you can provide more than two axes.
Python
C#
C++
JavaScript
MATLAB
Java
MATLAB (legacy)
# get lockstep group with ID 1 from device
lockstep = device.get_lockstep(1)
# enable itifnot lockstep.is_enabled():
lockstep.enable(1, 2)
// get lockstep group with ID 1 from deviceconst lockstep = device.getLockstep(1);
// enable itif (!(await lockstep.isEnabled())) {
await lockstep.enable(1, 2);
}
// get lockstep group with ID 1 from devicevar lockstep = device.GetLockstep(1);
// enable itif (!lockstep.IsEnabled()) {
lockstep.Enable(1, 2);
}
// import zaber.motion.ascii.Connection;// import zaber.motion.ascii.Device;// import zaber.motion.ascii.Lockstep;// import zaber.motion.Units;// get lockstep group with ID 1 from deviceLocksteplockstep= device.getLockstep(1);
// enable itif (!lockstep.isEnabled()) {
lockstep.enable(1, 2);
}
% get lockstep group with ID 1 from device
lockstep = device.getLockstep(1);
% enable itif ~lockstep.isEnabled()
lockstep.enable([1, 2]);
end
% get lockstep group with ID 1 from device
lockstep = device.getLockstep(1);
% enable itif ~lockstep.isEnabled()
lockstep.enable(1, 2);
end
// get lockstep group with ID 1 from device
Lockstep lockstep = device.getLockstep(1);
// enable itif (!lockstep.isEnabled()) {
lockstep.enable(1, 2);
}
Once you enable a lockstep group, you will not be able to send movement commands to the axes in it.
Movement
With an enabled lockstep group, you can use movement commands on the lockstep instance similarly to an individual axis, although there are some specific things to note.
Unit conversion is based on the resolution of the first axis of the lockstep group.
For absolute movement commands, the group moves the first axis to an absolute position while the second axis maintains its offset.
When you send a home command to a lockstep group, it considers both axes; the group retracts until it detects the home sensor of any axis in the group.
The example below illustrates the use of some lockstep movement commands.
Python
C#
C++
JavaScript
MATLAB
Java
MATLAB (legacy)
# move a lockstep group so the first axis is at position 1000
lockstep.move_absolute(1000)
# move the lockstep group additional 10mm
lockstep.move_relative(10, Units.LENGTH_MILLIMETRES)
# return to home
lockstep.home()
// move a lockstep group so the first axis is at position 1000await lockstep.moveAbsolute(1000);
// move the lockstep group additional 10mmawait lockstep.moveRelative(10, Length.mm);
// return to homeawait lockstep.home();
// move a lockstep group so the first axis is at position 1000
lockstep.MoveAbsolute(1000);
// move the lockstep group additional 10mm
lockstep.MoveRelative(10, Units.Length_Millimetres);
// return to home
lockstep.Home();
// move a lockstep group so the first axis is at position 1000
lockstep.moveAbsolute(1000);
// move the lockstep group additional 10mm
lockstep.moveRelative(10, Units.LENGTH_MILLIMETRES);
// return to home
lockstep.home();
% move a lockstep group so the first axis is at position 1000
lockstep.moveAbsolute(1000);
% move the lockstep group additional 10mm
lockstep.moveRelative(10, Units.LENGTH_MILLIMETRES);
% return to home
lockstep.home();
% move a lockstep group so the first axis is at position 1000
lockstep.moveAbsolute(1000);
% move the lockstep group additional 10mm
lockstep.moveRelative(10, Units.Length("mm"));
% return to home
lockstep.home();
// move a lockstep group so the first axis is at position 1000
lockstep.moveAbsolute(1000);
// move the lockstep group additional 10mm
lockstep.moveRelative(10, Units::LENGTH_MILLIMETRES);
// return to home
lockstep.home();
The
wait_until_idle
method can also be used on a lockstep group.
Python
C#
C++
JavaScript
MATLAB
Java
MATLAB (legacy)
# move with wait until idle flag false
lockstep.move_relative(1000, Units.NATIVE, False)
# ...# wait until the movement has stopped later on
lockstep.wait_until_idle()
// move with wait until idle flag falseawait lockstep.moveRelative(1000, Units.NATIVE, { waitUntilIdle: false });
// ...// wait until the movement has stopped later onawait lockstep.waitUntilIdle();
// move with wait until idle flag false
lockstep.MoveRelative(1000, Units.Native, waitUntilIdle: false);
// ...// wait until the movement has stopped later on
lockstep.WaitUntilIdle();
// move with wait until idle flag false
lockstep.moveRelative(1000, Units.NATIVE, false);
// ...// wait until the movement has stopped later on
lockstep.waitUntilIdle();
% move with wait until idle flag false
lockstep.moveRelative(1000, Units.NATIVE, false);
% ...% wait until the movement has stopped later on
lockstep.waitUntilIdle();
% move with wait until idle flag false
lockstep.moveRelative(1000, Units.Native, waitUntilIdle=false);
% ...% wait until the movement has stopped later on
lockstep.waitUntilIdle();
// move with wait until idle flag false
lockstep.moveRelative(1000, Units::NATIVE, false);
// ...// wait until the movement has stopped later on
lockstep.waitUntilIdle();
Lockstep Information
Once you enable a lockstep group, you can get information about it such as the group ID, the measured twist between the axes, the intended offset between the axes, whether it is busy or not, and the axes numbers in the group.
Twist and offset measurements allow unit conversion, but keep in mind that the conversion is based on the resolution of the first axis in the group.