*
This commit is contained in:
@@ -0,0 +1,21 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2017 Oskar Weigl
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
@@ -0,0 +1,87 @@
|
||||
|
||||
#include "Arduino.h"
|
||||
#include "ODriveArduino.h"
|
||||
|
||||
// Print with stream operator
|
||||
template<class T> inline Print& operator <<(Print &obj, T arg) { obj.print(arg); return obj; }
|
||||
template<> inline Print& operator <<(Print &obj, float arg) { obj.print(arg, 4); return obj; }
|
||||
|
||||
ODriveArduino::ODriveArduino(Stream& serial)
|
||||
: serial_(serial) {}
|
||||
|
||||
void ODriveArduino::SetPosition(int motor_number, float position) {
|
||||
SetPosition(motor_number, position, 0.0f, 0.0f);
|
||||
}
|
||||
|
||||
void ODriveArduino::SetPosition(int motor_number, float position, float velocity_feedforward) {
|
||||
SetPosition(motor_number, position, velocity_feedforward, 0.0f);
|
||||
}
|
||||
|
||||
void ODriveArduino::SetPosition(int motor_number, float position, float velocity_feedforward, float current_feedforward) {
|
||||
serial_ << "p " << motor_number << " " << position << " " << velocity_feedforward << " " << current_feedforward << "\n";
|
||||
}
|
||||
|
||||
void ODriveArduino::SetVelocity(int motor_number, float velocity) {
|
||||
SetVelocity(motor_number, velocity, 0.0f);
|
||||
}
|
||||
|
||||
void ODriveArduino::SetVelocity(int motor_number, float velocity, float current_feedforward) {
|
||||
serial_ << "v " << motor_number << " " << velocity << " " << current_feedforward << "\n";
|
||||
}
|
||||
|
||||
void ODriveArduino::SetCurrent(int motor_number, float current) {
|
||||
serial_ << "c " << motor_number << " " << current << "\n";
|
||||
}
|
||||
|
||||
void ODriveArduino::TrapezoidalMove(int motor_number, float position) {
|
||||
serial_ << "t " << motor_number << " " << position << "\n";
|
||||
}
|
||||
|
||||
float ODriveArduino::readFloat() {
|
||||
return readString().toFloat();
|
||||
}
|
||||
|
||||
float ODriveArduino::GetVelocity(int motor_number) {
|
||||
serial_<< "r axis" << motor_number << ".encoder.vel_estimate\n";
|
||||
return ODriveArduino::readFloat();
|
||||
}
|
||||
|
||||
float ODriveArduino::GetPosition(int motor_number) {
|
||||
serial_ << "r axis" << motor_number << ".encoder.pos_estimate\n";
|
||||
return ODriveArduino::readFloat();
|
||||
}
|
||||
|
||||
int32_t ODriveArduino::readInt() {
|
||||
return readString().toInt();
|
||||
}
|
||||
|
||||
bool ODriveArduino::run_state(int axis, int requested_state, bool wait_for_idle, float timeout) {
|
||||
int timeout_ctr = (int)(timeout * 10.0f);
|
||||
serial_ << "w axis" << axis << ".requested_state " << requested_state << '\n';
|
||||
if (wait_for_idle) {
|
||||
do {
|
||||
delay(100);
|
||||
serial_ << "r axis" << axis << ".current_state\n";
|
||||
} while (readInt() != AXIS_STATE_IDLE && --timeout_ctr > 0);
|
||||
}
|
||||
|
||||
return timeout_ctr > 0;
|
||||
}
|
||||
|
||||
String ODriveArduino::readString() {
|
||||
String str = "";
|
||||
static const unsigned long timeout = 1000;
|
||||
unsigned long timeout_start = millis();
|
||||
for (;;) {
|
||||
while (!serial_.available()) {
|
||||
if (millis() - timeout_start >= timeout) {
|
||||
return str;
|
||||
}
|
||||
}
|
||||
char c = serial_.read();
|
||||
if (c == '\n')
|
||||
break;
|
||||
str += c;
|
||||
}
|
||||
return str;
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
|
||||
#ifndef ODriveArduino_h
|
||||
#define ODriveArduino_h
|
||||
|
||||
#include "Arduino.h"
|
||||
#include "ODriveEnums.h"
|
||||
|
||||
class ODriveArduino {
|
||||
public:
|
||||
ODriveArduino(Stream& serial);
|
||||
|
||||
// Commands
|
||||
void SetPosition(int motor_number, float position);
|
||||
void SetPosition(int motor_number, float position, float velocity_feedforward);
|
||||
void SetPosition(int motor_number, float position, float velocity_feedforward, float current_feedforward);
|
||||
void SetVelocity(int motor_number, float velocity);
|
||||
void SetVelocity(int motor_number, float velocity, float current_feedforward);
|
||||
void SetCurrent(int motor_number, float current);
|
||||
void TrapezoidalMove(int motor_number, float position);
|
||||
// Getters
|
||||
float GetVelocity(int motor_number);
|
||||
float GetPosition(int motor_number);
|
||||
// General params
|
||||
float readFloat();
|
||||
int32_t readInt();
|
||||
|
||||
// State helper
|
||||
bool run_state(int axis, int requested_state, bool wait_for_idle, float timeout = 10.0f);
|
||||
private:
|
||||
String readString();
|
||||
|
||||
Stream& serial_;
|
||||
};
|
||||
|
||||
#endif //ODriveArduino_h
|
||||
@@ -0,0 +1,203 @@
|
||||
|
||||
#ifndef ODriveEnums_h
|
||||
#define ODriveEnums_h
|
||||
|
||||
/* TODO: This file is dangerous because the enums could potentially change between API versions. Should transmit as part of the JSON.
|
||||
** To regenerate this file, nagivate to the top level of the ODrive repository and run:
|
||||
** python Firmware/interface_generator_stub.py --definitions Firmware/odrive-interface.yaml --template tools/arduino_enums_template.j2 --output Arduino/ODriveArduino/ODriveEnums.h
|
||||
*/
|
||||
|
||||
// ODrive.GpioMode
|
||||
enum GpioMode {
|
||||
GPIO_MODE_DIGITAL = 0,
|
||||
GPIO_MODE_DIGITAL_PULL_UP = 1,
|
||||
GPIO_MODE_DIGITAL_PULL_DOWN = 2,
|
||||
GPIO_MODE_ANALOG_IN = 3,
|
||||
GPIO_MODE_UART_A = 4,
|
||||
GPIO_MODE_UART_B = 5,
|
||||
GPIO_MODE_UART_C = 6,
|
||||
GPIO_MODE_CAN_A = 7,
|
||||
GPIO_MODE_I2C_A = 8,
|
||||
GPIO_MODE_SPI_A = 9,
|
||||
GPIO_MODE_PWM = 10,
|
||||
GPIO_MODE_ENC0 = 11,
|
||||
GPIO_MODE_ENC1 = 12,
|
||||
GPIO_MODE_ENC2 = 13,
|
||||
GPIO_MODE_MECH_BRAKE = 14,
|
||||
GPIO_MODE_STATUS = 15,
|
||||
};
|
||||
|
||||
// ODrive.StreamProtocolType
|
||||
enum StreamProtocolType {
|
||||
STREAM_PROTOCOL_TYPE_FIBRE = 0,
|
||||
STREAM_PROTOCOL_TYPE_ASCII = 1,
|
||||
STREAM_PROTOCOL_TYPE_STDOUT = 2,
|
||||
STREAM_PROTOCOL_TYPE_ASCII_AND_STDOUT = 3,
|
||||
};
|
||||
|
||||
// ODrive.Can.Protocol
|
||||
enum Protocol {
|
||||
PROTOCOL_SIMPLE = 0x00000001,
|
||||
};
|
||||
|
||||
// ODrive.Axis.AxisState
|
||||
enum AxisState {
|
||||
AXIS_STATE_UNDEFINED = 0,
|
||||
AXIS_STATE_IDLE = 1,
|
||||
AXIS_STATE_STARTUP_SEQUENCE = 2,
|
||||
AXIS_STATE_FULL_CALIBRATION_SEQUENCE = 3,
|
||||
AXIS_STATE_MOTOR_CALIBRATION = 4,
|
||||
AXIS_STATE_ENCODER_INDEX_SEARCH = 6,
|
||||
AXIS_STATE_ENCODER_OFFSET_CALIBRATION = 7,
|
||||
AXIS_STATE_CLOSED_LOOP_CONTROL = 8,
|
||||
AXIS_STATE_LOCKIN_SPIN = 9,
|
||||
AXIS_STATE_ENCODER_DIR_FIND = 10,
|
||||
AXIS_STATE_HOMING = 11,
|
||||
AXIS_STATE_ENCODER_HALL_POLARITY_CALIBRATION = 12,
|
||||
AXIS_STATE_ENCODER_HALL_PHASE_CALIBRATION = 13,
|
||||
};
|
||||
|
||||
// ODrive.Encoder.Mode
|
||||
enum EncoderMode {
|
||||
ENCODER_MODE_INCREMENTAL = 0,
|
||||
ENCODER_MODE_HALL = 1,
|
||||
ENCODER_MODE_SINCOS = 2,
|
||||
ENCODER_MODE_SPI_ABS_CUI = 256,
|
||||
ENCODER_MODE_SPI_ABS_AMS = 257,
|
||||
ENCODER_MODE_SPI_ABS_AEAT = 258,
|
||||
ENCODER_MODE_SPI_ABS_RLS = 259,
|
||||
ENCODER_MODE_SPI_ABS_MA732 = 260,
|
||||
};
|
||||
|
||||
// ODrive.Controller.ControlMode
|
||||
enum ControlMode {
|
||||
CONTROL_MODE_VOLTAGE_CONTROL = 0,
|
||||
CONTROL_MODE_TORQUE_CONTROL = 1,
|
||||
CONTROL_MODE_VELOCITY_CONTROL = 2,
|
||||
CONTROL_MODE_POSITION_CONTROL = 3,
|
||||
};
|
||||
|
||||
// ODrive.Controller.InputMode
|
||||
enum InputMode {
|
||||
INPUT_MODE_INACTIVE = 0,
|
||||
INPUT_MODE_PASSTHROUGH = 1,
|
||||
INPUT_MODE_VEL_RAMP = 2,
|
||||
INPUT_MODE_POS_FILTER = 3,
|
||||
INPUT_MODE_MIX_CHANNELS = 4,
|
||||
INPUT_MODE_TRAP_TRAJ = 5,
|
||||
INPUT_MODE_TORQUE_RAMP = 6,
|
||||
INPUT_MODE_MIRROR = 7,
|
||||
INPUT_MODE_TUNING = 8,
|
||||
};
|
||||
|
||||
// ODrive.Motor.MotorType
|
||||
enum MotorType {
|
||||
MOTOR_TYPE_HIGH_CURRENT = 0,
|
||||
MOTOR_TYPE_GIMBAL = 2,
|
||||
MOTOR_TYPE_ACIM = 3,
|
||||
};
|
||||
|
||||
// ODrive.Error
|
||||
enum ODriveError {
|
||||
ODRIVE_ERROR_NONE = 0x00000000,
|
||||
ODRIVE_ERROR_CONTROL_ITERATION_MISSED = 0x00000001,
|
||||
ODRIVE_ERROR_DC_BUS_UNDER_VOLTAGE = 0x00000002,
|
||||
ODRIVE_ERROR_DC_BUS_OVER_VOLTAGE = 0x00000004,
|
||||
ODRIVE_ERROR_DC_BUS_OVER_REGEN_CURRENT = 0x00000008,
|
||||
ODRIVE_ERROR_DC_BUS_OVER_CURRENT = 0x00000010,
|
||||
ODRIVE_ERROR_BRAKE_DEADTIME_VIOLATION = 0x00000020,
|
||||
ODRIVE_ERROR_BRAKE_DUTY_CYCLE_NAN = 0x00000040,
|
||||
ODRIVE_ERROR_INVALID_BRAKE_RESISTANCE = 0x00000080,
|
||||
};
|
||||
|
||||
// ODrive.Can.Error
|
||||
enum CanError {
|
||||
CAN_ERROR_NONE = 0x00000000,
|
||||
CAN_ERROR_DUPLICATE_CAN_IDS = 0x00000001,
|
||||
};
|
||||
|
||||
// ODrive.Axis.Error
|
||||
enum AxisError {
|
||||
AXIS_ERROR_NONE = 0x00000000,
|
||||
AXIS_ERROR_INVALID_STATE = 0x00000001,
|
||||
AXIS_ERROR_MOTOR_FAILED = 0x00000040,
|
||||
AXIS_ERROR_SENSORLESS_ESTIMATOR_FAILED = 0x00000080,
|
||||
AXIS_ERROR_ENCODER_FAILED = 0x00000100,
|
||||
AXIS_ERROR_CONTROLLER_FAILED = 0x00000200,
|
||||
AXIS_ERROR_WATCHDOG_TIMER_EXPIRED = 0x00000800,
|
||||
AXIS_ERROR_MIN_ENDSTOP_PRESSED = 0x00001000,
|
||||
AXIS_ERROR_MAX_ENDSTOP_PRESSED = 0x00002000,
|
||||
AXIS_ERROR_ESTOP_REQUESTED = 0x00004000,
|
||||
AXIS_ERROR_HOMING_WITHOUT_ENDSTOP = 0x00020000,
|
||||
AXIS_ERROR_OVER_TEMP = 0x00040000,
|
||||
AXIS_ERROR_UNKNOWN_POSITION = 0x00080000,
|
||||
};
|
||||
|
||||
// ODrive.Motor.Error
|
||||
enum MotorError {
|
||||
MOTOR_ERROR_NONE = 0x00000000,
|
||||
MOTOR_ERROR_PHASE_RESISTANCE_OUT_OF_RANGE = 0x00000001,
|
||||
MOTOR_ERROR_PHASE_INDUCTANCE_OUT_OF_RANGE = 0x00000002,
|
||||
MOTOR_ERROR_DRV_FAULT = 0x00000008,
|
||||
MOTOR_ERROR_CONTROL_DEADLINE_MISSED = 0x00000010,
|
||||
MOTOR_ERROR_MODULATION_MAGNITUDE = 0x00000080,
|
||||
MOTOR_ERROR_CURRENT_SENSE_SATURATION = 0x00000400,
|
||||
MOTOR_ERROR_CURRENT_LIMIT_VIOLATION = 0x00001000,
|
||||
MOTOR_ERROR_MODULATION_IS_NAN = 0x00010000,
|
||||
MOTOR_ERROR_MOTOR_THERMISTOR_OVER_TEMP = 0x00020000,
|
||||
MOTOR_ERROR_FET_THERMISTOR_OVER_TEMP = 0x00040000,
|
||||
MOTOR_ERROR_TIMER_UPDATE_MISSED = 0x00080000,
|
||||
MOTOR_ERROR_CURRENT_MEASUREMENT_UNAVAILABLE = 0x00100000,
|
||||
MOTOR_ERROR_CONTROLLER_FAILED = 0x00200000,
|
||||
MOTOR_ERROR_I_BUS_OUT_OF_RANGE = 0x00400000,
|
||||
MOTOR_ERROR_BRAKE_RESISTOR_DISARMED = 0x00800000,
|
||||
MOTOR_ERROR_SYSTEM_LEVEL = 0x01000000,
|
||||
MOTOR_ERROR_BAD_TIMING = 0x02000000,
|
||||
MOTOR_ERROR_UNKNOWN_PHASE_ESTIMATE = 0x04000000,
|
||||
MOTOR_ERROR_UNKNOWN_PHASE_VEL = 0x08000000,
|
||||
MOTOR_ERROR_UNKNOWN_TORQUE = 0x10000000,
|
||||
MOTOR_ERROR_UNKNOWN_CURRENT_COMMAND = 0x20000000,
|
||||
MOTOR_ERROR_UNKNOWN_CURRENT_MEASUREMENT = 0x40000000,
|
||||
MOTOR_ERROR_UNKNOWN_VBUS_VOLTAGE = 0x80000000,
|
||||
MOTOR_ERROR_UNKNOWN_VOLTAGE_COMMAND = 0x100000000,
|
||||
MOTOR_ERROR_UNKNOWN_GAINS = 0x200000000,
|
||||
MOTOR_ERROR_CONTROLLER_INITIALIZING = 0x400000000,
|
||||
MOTOR_ERROR_UNBALANCED_PHASES = 0x800000000,
|
||||
};
|
||||
|
||||
// ODrive.Controller.Error
|
||||
enum ControllerError {
|
||||
CONTROLLER_ERROR_NONE = 0x00000000,
|
||||
CONTROLLER_ERROR_OVERSPEED = 0x00000001,
|
||||
CONTROLLER_ERROR_INVALID_INPUT_MODE = 0x00000002,
|
||||
CONTROLLER_ERROR_UNSTABLE_GAIN = 0x00000004,
|
||||
CONTROLLER_ERROR_INVALID_MIRROR_AXIS = 0x00000008,
|
||||
CONTROLLER_ERROR_INVALID_LOAD_ENCODER = 0x00000010,
|
||||
CONTROLLER_ERROR_INVALID_ESTIMATE = 0x00000020,
|
||||
CONTROLLER_ERROR_INVALID_CIRCULAR_RANGE = 0x00000040,
|
||||
CONTROLLER_ERROR_SPINOUT_DETECTED = 0x00000080,
|
||||
};
|
||||
|
||||
// ODrive.Encoder.Error
|
||||
enum EncoderError {
|
||||
ENCODER_ERROR_NONE = 0x00000000,
|
||||
ENCODER_ERROR_UNSTABLE_GAIN = 0x00000001,
|
||||
ENCODER_ERROR_CPR_POLEPAIRS_MISMATCH = 0x00000002,
|
||||
ENCODER_ERROR_NO_RESPONSE = 0x00000004,
|
||||
ENCODER_ERROR_UNSUPPORTED_ENCODER_MODE = 0x00000008,
|
||||
ENCODER_ERROR_ILLEGAL_HALL_STATE = 0x00000010,
|
||||
ENCODER_ERROR_INDEX_NOT_FOUND_YET = 0x00000020,
|
||||
ENCODER_ERROR_ABS_SPI_TIMEOUT = 0x00000040,
|
||||
ENCODER_ERROR_ABS_SPI_COM_FAIL = 0x00000080,
|
||||
ENCODER_ERROR_ABS_SPI_NOT_READY = 0x00000100,
|
||||
ENCODER_ERROR_HALL_NOT_CALIBRATED_YET = 0x00000200,
|
||||
};
|
||||
|
||||
// ODrive.SensorlessEstimator.Error
|
||||
enum SensorlessEstimatorError {
|
||||
SENSORLESS_ESTIMATOR_ERROR_NONE = 0x00000000,
|
||||
SENSORLESS_ESTIMATOR_ERROR_UNSTABLE_GAIN = 0x00000001,
|
||||
SENSORLESS_ESTIMATOR_ERROR_UNKNOWN_CURRENT_MEASUREMENT = 0x00000002,
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,6 @@
|
||||
# ODriveArduino
|
||||
Arduino library for the ODrive
|
||||
|
||||
To install the library, first clone this repository. In the Arduino IDE select: *Sketch -> Include Library -> Add .ZIP Library...*
|
||||
|
||||
Select the enclosing folder (e.g. ODriveArduino) to add it. Restarting the Arduino IDE may be necessary to see the examples in the *File* dropdown. Check the included example *ODriveArduinoTest* for basic usage.
|
||||
+121
@@ -0,0 +1,121 @@
|
||||
// includes
|
||||
#include <HardwareSerial.h>
|
||||
#include <SoftwareSerial.h>
|
||||
#include <ODriveArduino.h>
|
||||
// Printing with stream operator helper functions
|
||||
template<class T> inline Print& operator <<(Print &obj, T arg) { obj.print(arg); return obj; }
|
||||
template<> inline Print& operator <<(Print &obj, float arg) { obj.print(arg, 4); return obj; }
|
||||
|
||||
|
||||
////////////////////////////////
|
||||
// Set up serial pins to the ODrive
|
||||
////////////////////////////////
|
||||
|
||||
// Below are some sample configurations.
|
||||
// You can comment out the default Teensy one and uncomment the one you wish to use.
|
||||
// You can of course use something different if you like
|
||||
// Don't forget to also connect ODrive GND to Arduino GND.
|
||||
|
||||
// Teensy 3 and 4 (all versions) - Serial1
|
||||
// pin 0: RX - connect to ODrive TX
|
||||
// pin 1: TX - connect to ODrive RX
|
||||
// See https://www.pjrc.com/teensy/td_uart.html for other options on Teensy
|
||||
HardwareSerial& odrive_serial = Serial1;
|
||||
|
||||
// Arduino Mega or Due - Serial1
|
||||
// pin 19: RX - connect to ODrive TX
|
||||
// pin 18: TX - connect to ODrive RX
|
||||
// See https://www.arduino.cc/reference/en/language/functions/communication/serial/ for other options
|
||||
// HardwareSerial& odrive_serial = Serial1;
|
||||
|
||||
// Arduino without spare serial ports (such as Arduino UNO) have to use software serial.
|
||||
// Note that this is implemented poorly and can lead to wrong data sent or read.
|
||||
// pin 8: RX - connect to ODrive TX
|
||||
// pin 9: TX - connect to ODrive RX
|
||||
// SoftwareSerial odrive_serial(8, 9);
|
||||
|
||||
|
||||
// ODrive object
|
||||
ODriveArduino odrive(odrive_serial);
|
||||
|
||||
void setup() {
|
||||
// ODrive uses 115200 baud
|
||||
odrive_serial.begin(115200);
|
||||
|
||||
// Serial to PC
|
||||
Serial.begin(115200);
|
||||
while (!Serial) ; // wait for Arduino Serial Monitor to open
|
||||
|
||||
Serial.println("ODriveArduino");
|
||||
Serial.println("Setting parameters...");
|
||||
|
||||
// In this example we set the same parameters to both motors.
|
||||
// You can of course set them different if you want.
|
||||
// See the documentation or play around in odrivetool to see the available parameters
|
||||
for (int axis = 0; axis < 2; ++axis) {
|
||||
odrive_serial << "w axis" << axis << ".controller.config.vel_limit " << 10.0f << '\n';
|
||||
odrive_serial << "w axis" << axis << ".motor.config.current_lim " << 11.0f << '\n';
|
||||
// This ends up writing something like "w axis0.motor.config.current_lim 10.0\n"
|
||||
}
|
||||
|
||||
Serial.println("Ready!");
|
||||
Serial.println("Send the character '0' or '1' to calibrate respective motor (you must do this before you can command movement)");
|
||||
Serial.println("Send the character 's' to exectue test move");
|
||||
Serial.println("Send the character 'b' to read bus voltage");
|
||||
Serial.println("Send the character 'p' to read motor positions in a 10s loop");
|
||||
}
|
||||
|
||||
void loop() {
|
||||
|
||||
if (Serial.available()) {
|
||||
char c = Serial.read();
|
||||
|
||||
// Run calibration sequence
|
||||
if (c == '0' || c == '1') {
|
||||
int motornum = c-'0';
|
||||
int requested_state;
|
||||
|
||||
requested_state = AXIS_STATE_MOTOR_CALIBRATION;
|
||||
Serial << "Axis" << c << ": Requesting state " << requested_state << '\n';
|
||||
if(!odrive.run_state(motornum, requested_state, true)) return;
|
||||
|
||||
requested_state = AXIS_STATE_ENCODER_OFFSET_CALIBRATION;
|
||||
Serial << "Axis" << c << ": Requesting state " << requested_state << '\n';
|
||||
if(!odrive.run_state(motornum, requested_state, true, 25.0f)) return;
|
||||
|
||||
requested_state = AXIS_STATE_CLOSED_LOOP_CONTROL;
|
||||
Serial << "Axis" << c << ": Requesting state " << requested_state << '\n';
|
||||
if(!odrive.run_state(motornum, requested_state, false /*don't wait*/)) return;
|
||||
}
|
||||
|
||||
// Sinusoidal test move
|
||||
if (c == 's') {
|
||||
Serial.println("Executing test move");
|
||||
for (float ph = 0.0f; ph < 6.28318530718f; ph += 0.01f) {
|
||||
float pos_m0 = 2.0f * cos(ph);
|
||||
float pos_m1 = 2.0f * sin(ph);
|
||||
odrive.SetPosition(0, pos_m0);
|
||||
odrive.SetPosition(1, pos_m1);
|
||||
delay(5);
|
||||
}
|
||||
}
|
||||
|
||||
// Read bus voltage
|
||||
if (c == 'b') {
|
||||
odrive_serial << "r vbus_voltage\n";
|
||||
Serial << "Vbus voltage: " << odrive.readFloat() << '\n';
|
||||
}
|
||||
|
||||
// print motor positions in a 10s loop
|
||||
if (c == 'p') {
|
||||
static const unsigned long duration = 10000;
|
||||
unsigned long start = millis();
|
||||
while(millis() - start < duration) {
|
||||
for (int motor = 0; motor < 2; ++motor) {
|
||||
Serial << odrive.GetPosition(motor) << '\t';
|
||||
}
|
||||
Serial << '\n';
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user