.. _auto-zeroing: 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 ------------- - :ref:`motor-modes` - :ref:`motor-error-handling` - (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: .. tab-set:: :sync-group: language .. tab-item:: C++ :sync: cpp .. literalinclude:: shared/boilerplate.cpp :language: cpp .. tab-item:: Python :sync: python .. literalinclude:: shared/boilerplate.py :language: python 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. .. tab-set:: :sync-group: language .. tab-item:: C++ :sync: cpp .. code-block:: cpp ... motor.set_mode(MotorMode::SleepMode); ... .. tab-item:: Python :sync: python .. code-block:: python 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. .. tab-set:: :sync-group: language .. tab-item:: C++ :sync: cpp .. code-block:: cpp ... motor.write_register_blocking(ORCAReg::ZERO_MODE, ORCAReg::ZERO_MODE_Values::AUTO_ZERO_ENABLED); ... .. tab-item:: Python :sync: python .. code-block:: python 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`. .. tab-set:: :sync-group: language .. tab-item:: C++ :sync: cpp .. code-block:: cpp ... motor.set_mode(MotorMode::AutoZeroMode); ... .. tab-item:: Python :sync: python .. code-block:: python 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. .. tab-set:: :sync-group: language .. tab-item:: C++ :sync: cpp .. code-block:: cpp ... 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; } } ... .. tab-item:: Python :sync: python .. code-block:: python ... 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. .. tab-set:: :sync-group: language .. tab-item:: C++ :sync: cpp .. code-block:: cpp ... // 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); ... .. tab-item:: Python :sync: python .. code-block:: python ... # 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 ---------------- .. tab-set:: :sync-group: language .. tab-item:: C++ :sync: cpp .. literalinclude:: Auto-Zeroing/main.cpp :language: cpp .. tab-item:: Python :sync: python .. literalinclude:: Auto-Zeroing/main.py :language: python