update Arduino lib to new ascii protocol

This commit is contained in:
Oskar Weigl
2018-06-09 18:24:34 -07:00
parent 375156db6c
commit bdbd0409ed
4 changed files with 65 additions and 126 deletions
+15 -53
View File
@@ -27,7 +27,7 @@ void ODriveArduino::SetPosition(int motor_number, float position, float velocity
}
void ODriveArduino::SetPosition(int motor_number, float position, float velocity_feedforward, float current_feedforward) {
serial_ << "$p " << motor_number << " " << position << " " << velocity_feedforward << " " << current_feedforward << "!";
serial_ << "p " << motor_number << " " << position << " " << velocity_feedforward << " " << current_feedforward << "\n";
}
void ODriveArduino::SetVelocity(int motor_number, float velocity) {
@@ -35,60 +35,9 @@ void ODriveArduino::SetVelocity(int motor_number, float velocity) {
}
void ODriveArduino::SetVelocity(int motor_number, float velocity, float current_feedforward) {
serial_ << "$v " << motor_number << " " << velocity << " " << current_feedforward << "!";
serial_ << "v " << motor_number << " " << velocity << " " << current_feedforward << "\n";
}
float ODriveArduino::getBusVoltage() {
serial_ << "$g 0 0!";
return readFloat();
}
float ODriveArduino::GetParameter(int motor_number, ParamNamesFloat parameter) {
int idx = kMotorOffsetFloat + kMotorStrideFloat * motor_number + parameter;
serial_ << "$g 0 " << idx << "!";
return readString().toFloat();
}
int32_t ODriveArduino::GetParameter(int motor_number, ParamNamesInt32 parameter) {
int idx = kMotorOffsetInt32 + kMotorStrideInt32 * motor_number + parameter;
serial_ << "$g 1 " << idx << "!";
return readString().toInt();
}
bool ODriveArduino::GetParameter(int motor_number, ParamNamesBool parameter) {
int idx = kMotorOffsetBool + kMotorStrideBool * motor_number + parameter;
serial_ << "$g 2 " << idx << "!";
return readString().toInt();
}
uint16_t ODriveArduino::GetParameter(int motor_number, ParamNamesUint16 parameter) {
int idx = kMotorOffsetUint16 + kMotorStrideUint16 * motor_number + parameter;
serial_ << "$g 3 " << idx << "!";
return readString().toInt();
}
void ODriveArduino::SetParameter(int motor_number, ParamNamesFloat parameter, float value) {
int idx = kMotorOffsetFloat + kMotorStrideFloat * motor_number + parameter;
serial_ << "$s 0 " << idx << " " << value << "!";
}
void ODriveArduino::SetParameter(int motor_number, ParamNamesInt32 parameter, int32_t value) {
int idx = kMotorOffsetInt32 + kMotorStrideInt32 * motor_number + parameter;
serial_ << "$s 1 " << idx << " " << value << "!";
}
void ODriveArduino::SetParameter(int motor_number, ParamNamesBool parameter, bool value) {
int idx = kMotorOffsetBool + kMotorStrideBool * motor_number + parameter;
serial_ << "$s 2 " << idx << " " << value << "!";
}
void ODriveArduino::SetParameter(int motor_number, ParamNamesUint16 parameter, uint16_t value) {
int idx = kMotorOffsetUint16 + kMotorStrideUint16 * motor_number + parameter;
serial_ << "$s 3 " << idx << " " << value << "!";
}
float ODriveArduino::readFloat() {
return readString().toFloat();
}
@@ -97,6 +46,19 @@ int32_t ODriveArduino::readInt() {
return readString().toInt();
}
bool ODriveArduino::run_state(int axis, int requested_state, bool wait) {
int timeout_ctr = 100;
serial_ << "w axis" << axis << ".requested_state " << requested_state << '\n';
if (wait) {
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;
+17 -63
View File
@@ -6,83 +6,37 @@
class ODriveArduino {
public:
enum ParamNamesFloat {
PARAM_FLOAT_POS_SETPOINT,
PARAM_FLOAT_POS_GAIN,
PARAM_FLOAT_VEL_SETPOINT,
PARAM_FLOAT_VEL_GAIN,
PARAM_FLOAT_VEL_INTEGRATOR_GAIN,
PARAM_FLOAT_VEL_INTEGRATOR_CURRENT,
PARAM_FLOAT_VEL_LIMIT,
PARAM_FLOAT_CURRENT_SETPOINT,
PARAM_FLOAT_CALIBRATION_CURRENT,
PARAM_FLOAT_PHASE_INDUCTANCE,
PARAM_FLOAT_PHASE_RESISTANCE,
PARAM_FLOAT_CURRENT_MEAS_PHB,
PARAM_FLOAT_CURRENT_MEAS_PHC,
PARAM_FLOAT_DC_CALIB_PHB,
PARAM_FLOAT_DC_CALIB_PHC,
PARAM_FLOAT_SHUNT_CONDUCTANCE,
PARAM_FLOAT_PHASE_CURRENT_REV_GAIN,
PARAM_FLOAT_CURRENT_CONTROL_CURRENT_LIM,
PARAM_FLOAT_CURRENT_CONTROL_P_GAIN,
PARAM_FLOAT_CURRENT_CONTROL_I_GAIN,
PARAM_FLOAT_CURRENT_CONTROL_V_CURRENT_CONTROL_INTEGRAL_D,
PARAM_FLOAT_CURRENT_CONTROL_V_CURRENT_CONTROL_INTEGRAL_Q,
PARAM_FLOAT_CURRENT_CONTROL_IBUS,
PARAM_FLOAT_ENCODER_PHASE,
PARAM_FLOAT_ENCODER_PLL_POS,
PARAM_FLOAT_ENCODER_PLL_VEL,
PARAM_FLOAT_ENCODER_PLL_KP,
PARAM_FLOAT_ENCODER_PLL_KI,
};
enum ParamNamesInt32 {
PARAM_INT_CONTROL_MODE,
PARAM_INT_ENCODER_ENCODER_OFFSET,
PARAM_INT_ENCODER_ENCODER_STATE,
PARAM_INT_ERROR,
};
enum ParamNamesBool{
PARAM_BOOL_THREAD_READY,
PARAM_BOOL_ENABLE_CONTROL,
PARAM_BOOL_DO_CALIBRATION,
PARAM_BOOL_CALIBRATION_OK,
};
enum ParamNamesUint16{
PARAM_UINT16_CONTROL_DEADLINE,
PARAM_UINT16_LAST_CPU_TIME,
enum AxisState_t {
AXIS_STATE_UNDEFINED = 0, //<! will fall through to idle
AXIS_STATE_IDLE = 1, //<! disable PWM and do nothing
AXIS_STATE_STARTUP_SEQUENCE = 2, //<! the actual sequence is defined by the config.startup_... flags
AXIS_STATE_FULL_CALIBRATION_SEQUENCE = 3, //<! run all calibration procedures, then idle
AXIS_STATE_MOTOR_CALIBRATION = 4, //<! run motor calibration
AXIS_STATE_SENSORLESS_CONTROL = 5, //<! run sensorless control
AXIS_STATE_ENCODER_INDEX_SEARCH = 6, //<! run encoder index search
AXIS_STATE_ENCODER_OFFSET_CALIBRATION = 7, //<! run encoder offset calibration
AXIS_STATE_CLOSED_LOOP_CONTROL = 8 //<! run closed loop control
};
ODriveArduino(Stream& serial);
// Get
float getBusVoltage();
float GetParameter(int motor_number, ParamNamesFloat parameter);
int32_t GetParameter(int motor_number, ParamNamesInt32 parameter);
bool GetParameter(int motor_number, ParamNamesBool parameter);
uint16_t GetParameter(int motor_number, ParamNamesUint16 parameter);
// Set
// 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 SetParameter(int motor_number, ParamNamesFloat parameter, float value);
void SetParameter(int motor_number, ParamNamesInt32 parameter, int32_t value);
void SetParameter(int motor_number, ParamNamesBool parameter, bool value);
void SetParameter(int motor_number, ParamNamesUint16 parameter, uint16_t value);
private:
// General params
float readFloat();
int32_t readInt();
// State helper
bool run_state(int axis, int requested_state, bool wait);
private:
String readString();
Stream& serial_;
};
#endif //ODriveArduino_h
#endif //ODriveArduino_h
@@ -20,20 +20,20 @@ void setup() {
Serial.begin(115200);
while (!Serial) ; // wait for Arduino Serial Monitor to open
Serial.println("ODriveArduino alpha.");
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.
for (int motor = 0; motor < 2; ++motor) {
odrive.SetParameter(motor, odrive.PARAM_FLOAT_CURRENT_CONTROL_CURRENT_LIM, 10.0f); // [A]
odrive.SetParameter(motor, odrive.PARAM_FLOAT_VEL_LIMIT, 20000.0f); // [counts/s]
odrive.SetParameter(motor, odrive.PARAM_FLOAT_POS_GAIN, 20.0f); // [(counts/s) / counts]
odrive.SetParameter(motor, odrive.PARAM_FLOAT_VEL_GAIN, 15.0f/10000.0f); // [A/(counts/s)]
odrive.SetParameter(motor, odrive.PARAM_FLOAT_VEL_INTEGRATOR_GAIN, 0.0f/10000.0f); // [A/(counts/s * s)]
// 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 " << 22000.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");
@@ -44,8 +44,26 @@ void loop() {
if (Serial.available()) {
char c = Serial.read();
// Run calibration sequence
if (c == '0' || c == '1') {
int requested_state;
requested_state = ODriveArduino::AXIS_STATE_MOTOR_CALIBRATION;
Serial << "Axis" << c << ": Requesting state " << requested_state << '\n';
odrive.run_state(atoi(c), requested_state, true);
requested_state = ODriveArduino::AXIS_STATE_ENCODER_OFFSET_CALIBRATION;
Serial << "Axis" << c << ": Requesting state " << requested_state << '\n';
odrive.run_state(atoi(c), requested_state, true);
requested_state = ODriveArduino::AXIS_STATE_CLOSED_LOOP_CONTROL;
Serial << "Axis" << c << ": Requesting state " << requested_state << '\n';
odrive.run_state(atoi(c), requested_state, false); // don't wait
}
// 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 = 20000.0f * cos(ph);
float pos_m1 = 20000.0f * sin(ph);
@@ -57,7 +75,8 @@ void loop() {
// Read bus voltage
if (c == 'b') {
Serial << "Vbus voltage: " << odrive.getBusVoltage() << '\n';
odrive_serial << "r vbus_voltage\n";
Serial << "Vbus voltage: " << odrive.readFloat() << '\n';
}
// print motor positions in a 10s loop
@@ -66,7 +85,8 @@ void loop() {
unsigned long start = millis();
while(millis() - start < duration) {
for (int motor = 0; motor < 2; ++motor) {
Serial << odrive.GetParameter(motor, odrive.PARAM_FLOAT_ENCODER_PLL_POS) << '\t';
odrive_serial << "r axis" << motor << ".encoder.pos_estimate\n";
Serial << odrive.readFloat() << '\t';
}
Serial << '\n';
}
+4 -1
View File
@@ -38,7 +38,10 @@
"tuple": "cpp",
"type_traits": "cpp",
"typeinfo": "cpp",
"algorithm": "cpp"
"algorithm": "cpp",
"chrono": "cpp",
"condition_variable": "cpp",
"future": "cpp"
}
}
}