.. _motor-modes: Modes of Operation ================== ORCA motors contain a variety of features, made possible by their integrated sensors and onboard controller. Many of these features are mutually incompatible: it does not make sense to use them simultaneously. To address this problem, the motor uses the concept of modes of operation. Depending on the current mode of the ORCA, its behaviour changes, and different methods of control become available. In this tutorial we explore how to interact with modes of operation from the SDK. We'll explain how to control the ORCA's mode and how to read it's current mode. ---- 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 Setting the Mode of Operation ----------------------------- Let's begin with controlling the mode of operation. Changing the motor to a specific mode is simple, and requires adding a single line of code. .. 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) ... The above statement commands the motor to enter sleep mode. In sleep mode, the motor won't output force, will try to clear motor errors, and will exhibit a natual braking effect. Because of this, this line of code is commonplace in most applications that use the SDK. Try opening IrisControls with your motor and then run the code. Try running the code again, but use ``ForceMode`` instead of ``SleepMode`` and see the effects of your command appear in IrisControls. (Optional) Reading the Mode of Operation ---------------------------------------- .. note:: Reading the mode of operation is a much less common operation than writing to it in practice. Feel free to ignore this section if reading the mode doesn't seem necessary for your application. Now let's access the motor's current mode. The current mode of the motor can be accessed by the ``get_mode()`` method of the ``Actuator``: .. tab-set:: :sync-group: language .. tab-item:: C++ :sync: cpp .. code-block:: cpp ... while(true) { std::cout << "Current Mode: " << motor.get_mode().value << " \r"; } ... .. tab-item:: Python :sync: python .. code-block:: python ... while True: print("Current Mode: " + str(motor.get_mode().value), end=" \r") ... Try running the program. Try opening IrisControls and switch between kinematic, haptic, and sleep modes! You may notice that instead of printing a string, like "Sleep Mode" or "Force Mode" it is instead printing a number. This is because each mode is encoded in the motor as an integer. The MotorMode enum in the SDK stores which mode corresponds to which integer. Let's add a helper function which converts these integers into names: .. tab-set:: :sync-group: language .. tab-item:: C++ :sync: cpp .. code-block:: cpp std::string motor_mode_to_string(int mode_val) { switch (mode_val) { case MotorMode::SleepMode: return "Sleep"; case MotorMode::ForceMode: return "Force"; case MotorMode::PositionMode: return "Position"; case MotorMode::HapticMode: return "Haptics"; case MotorMode::KinematicMode: return "Kinematic"; default: return "Not Sure"; } } .. tab-item:: Python :sync: python .. code-block:: python match mode_val: case MotorMode.SleepMode: return "Sleep" case MotorMode.ForceMode: return "Force" case MotorMode.PositionMode: return "Position" case MotorMode.HapticMode: return "Haptics" case MotorMode.KinematicMode: return "Kinematic" case _: return "Not Sure" This function is defined using a switch statement with one definition for each common motor mode. Let's apply it to our printing statement: .. tab-set:: :sync-group: language .. tab-item:: C++ :sync: cpp .. code-block:: cpp ... while(true) { std::cout << "Current Mode: " << motor_mode_to_string(motor.get_mode().value) << " \r"; } ... .. tab-item:: Python :sync: python .. code-block:: python ... while True: print("Current Mode: " + motor_mode_to_string(motor.get_mode().value), end=" \r") ... Try running the code and interacting with IrisControls again. The output should be much more readable. ---- Complete Example ---------------- .. tab-set:: :sync-group: language .. tab-item:: C++ :sync: cpp .. literalinclude:: Motor-Modes/main.cpp :language: cpp .. tab-item:: Python :sync: python .. literalinclude:: Motor-Modes/main.py :language: python