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:

#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)

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.

...
motor.set_mode(MotorMode::SleepMode);
...
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:

...
while(true)
{
        std::cout << "Current Mode: " << motor.get_mode().value << "           \r";
}
...
...
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:

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";
        }
}
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:

...
while(true)
{
        std::cout << "Current Mode: " << motor_mode_to_string(motor.get_mode().value) << "           \r";
}
...
...
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

#include <iostream>
#include "actuator.h" 

using namespace orcaSDK;

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 "Unknown";
	}
}

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);

	while (true) {
		std::cout << "Current Mode: " << motor_mode_to_string(motor.get_mode().value) << "                 \r";
	}

	return 0;
}
from pyorcasdk import Actuator, MotorMode

def motor_mode_to_string(mode_val):
	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 "Unknown"


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)

while True:
	print("Current Mode: " + motor_mode_to_string(motor.get_mode().value), end="        \r")