Auto Zeroing¶
ORCA motors are inherently position sensing, however they do not have a concept of absolute position. When you first power on your ORCA motor, it doesn’t know how much room it has to move on each side before it will reach its shaft’s end stops. Because of this, it simply assumes it’s starting position to be near zero. This can be an undesirable characteristic for users who wish to operate their motor via any position controlling mode. To remedy this, ORCA motors have a function to help it find it’s true zero, so your application can behave consitently between power cycles. This is the ORCA’s auto zeroing feature.
Auto zeroing is an ORCA motor feature that initiates a routine bringing the shaft to its fully retracted position until it reaches a hard stop, then sets the zero position to that location. In this tutorial, we will demonstrate how to use the SDK to initiate auto zeroing, detect when it’s completed, and determine if it completed successfully.
Prerequisites¶
(Optional) We recommend reading the ORCA Series Reference Manual’s section “Controllers -> Auto Zeroing”. The reference manual can be found on our downloads page.
We’ll start with the following code as our baseline:
#include <iostream>
#include "actuator.h"
using namespace orcaSDK ;
int main() {
Actuator motor;
int serial_port;
std::cout << "Please input the serial port number of your connected motor. ";
std::cin >> serial_port;
motor.open_serial_port(serial_port);
return 0;
}
from pyorcasdk import Actuator
motor = Actuator()
serial_port = int(input("Please input the serial port number of your connected motor. "))
motor.open_serial_port(serial_port)
Additional Setup¶
We’ll begin by setting the motor to SleepMode, in order to clear any existing errors and help ensure the motor is in a good state to auto zero.
...
motor.set_mode(MotorMode::SleepMode);
...
from pyorcasdk import MotorMode
...
motor.set_mode(MotorMode.SleepMode)
Enable Auto Zeroing¶
By default, ORCA motors exist in a mode in which any detected negative positions get updated to be the new zero. In this mode, moving the shaft manually until it touches each end stop effectively “zeroes” your motor. This default mode is incompatible with auto zeroing, so we need to adjust it.
...
motor.write_register_blocking(ORCAReg::ZERO_MODE, ORCAReg::ZERO_MODE_Values::AUTO_ZERO_ENABLED);
...
import pyorcasdk.orca_registers as orca_reg
...
motor.write_register_blocking(orca_reg.ZERO_MODE, orca_reg.ZERO_MODE_AUTO_ZERO_ENABLED)
Perform Auto Zeroing¶
In order to initiate auto zeroing, simply set the mode of operation to Auto Zero mode.
...
motor.set_mode(MotorMode::AutoZeroMode);
...
from pyorcasdk import MotorMode
...
motor.set_mode(MotorMode.AutoZeroMode)
Try running the code! If all goes well, the motor should travel to one end of the shaft before stopping. At this point, your motor’s relative zero position should have been updated.
Detect Auto Zero Completion¶
When the auto zeroing routine completes, the motor will do one of two things, depending on whether the routine was successful. To determine if Auto Zeroing has finished, we check for two things:
If the motor’s mode has changed out of Auto Zero mode, auto zeroing has completed successfully.
If an ‘auto zero failed’ error (value 8192) has occurred, the auto zero routine has failed.
...
while (true) {
auto error_check = motor.get_errors();
if (error_check.value & ORCAReg::ERROR_0_Values::AUTO_ZERO_FAILED_Mask) {
std::cout << "Auto Zeroing Failed." << std::endl;
break;
}
else if (motor.get_mode().value != MotorMode::AutoZeroMode) {
std::cout << "Auto Zeroing Complete!" << std::endl;
break;
}
}
...
...
while True:
error_check = motor.get_errors()
if error_check.value & orca_reg.ERROR_0_AUTO_ZERO_FAILED_Mask:
print("Auto Zeroing Failed.")
break
elif motor.get_mode().value != MotorMode.AutoZeroMode:
print("Auto Zeroing Complete!")
break
(Optional) Configuring Auto Zero¶
Multiple behaviours of your motor’s auto zero behaviour can be customized. Those customizable pieces of behaviour include:
The maximum force that the ORCA can apply during auto zeroing.
The speed at which the shaft should move during auto zeroing.
The mode of operation that the motor should transition to upon successful auto zeroing.
Here is the corresponding code for configuring each of these parameters.
...
// Limit force to 30 newtons
motor.write_register_blocking(ORCAReg::AUTO_ZERO_FORCE_N, 30);
// Set speed to 50 millimeters per second
motor.write_register_blocking(ORCAReg::AUTO_ZERO_SPEED_MMPS, 50);
// Switch to sleep mode on successful auto zeroing
motor.write_register_blocking(ORCAReg::AUTO_ZERO_EXIT_MODE, MotorMode::SleepMode);
...
...
# Limit force to 30 newtons
motor.write_register_blocking(orca_reg.AUTO_ZERO_FORCE_N, 30)
# Set speed to 50 millimeters per second
motor.write_register_blocking(orca_reg.AUTO_ZERO_SPEED_MMPS, 50)
# Switch to sleep mode on successful auto zeroing
motor.write_register_blocking(orca_reg.AUTO_ZERO_EXIT_MODE, MotorMode.SleepMode)
...
Complete Example¶
#include <iostream>
#include "actuator.h"
using namespace orcaSDK ;
int main() {
Actuator motor;
int serial_port;
std::cout << "Please input the serial port number of your connected motor. ";
std::cin >> serial_port;
motor.open_serial_port(serial_port);
motor.set_mode(MotorMode::SleepMode);
motor.write_register_blocking(ORCAReg::ZERO_MODE, ORCAReg::ZERO_MODE_Values::AUTO_ZERO_ENABLED);
// Limit force to 30 newtons
motor.write_register_blocking(ORCAReg::AUTO_ZERO_FORCE_N, 30);
// Set speed to 50 millimeters per second
motor.write_register_blocking(ORCAReg::AUTO_ZERO_SPEED_MMPS, 50);
// Switch to sleep mode on successful auto zeroing
motor.write_register_blocking(ORCAReg::AUTO_ZERO_EXIT_MODE, MotorMode::SleepMode);
motor.set_mode(MotorMode::AutoZeroMode);
while (true) {
auto error_check = motor.get_errors();
if (error_check.value & ORCAReg::ERROR_0_Values::AUTO_ZERO_FAILED_Mask) {
std::cout << "Auto Zeroing Failed." << std::endl;
break;
}
else if (motor.get_mode().value != MotorMode::AutoZeroMode) {
std::cout << "Auto Zeroing Complete!" << std::endl;
break;
}
}
return 0;
}
from pyorcasdk import Actuator, MotorMode
import pyorcasdk.orca_registers as orca_reg
motor = Actuator()
serial_port = int(input("Please input the serial port number of your connected motor. "))
motor.open_serial_port(serial_port)
motor.set_mode(MotorMode.SleepMode)
motor.write_register_blocking(orca_reg.ZERO_MODE, orca_reg.ZERO_MODE_AUTO_ZERO_ENABLED)
# Limit force to 30 newtons
motor.write_register_blocking(orca_reg.AUTO_ZERO_FORCE_N, 30)
# Set speed to 50 millimeters per second
motor.write_register_blocking(orca_reg.AUTO_ZERO_SPEED_MMPS, 50)
# Switch to sleep mode on successful auto zeroing
motor.write_register_blocking(orca_reg.AUTO_ZERO_EXIT_MODE, MotorMode.SleepMode)
motor.set_mode(MotorMode.AutoZeroMode)
while True:
error_check = motor.get_errors()
if error_check.value & orca_reg.ERROR_0_AUTO_ZERO_FAILED_Mask:
print("Auto Zeroing Failed.")
break
elif motor.get_mode().value != MotorMode.AutoZeroMode:
print("Auto Zeroing Complete!")
break