diff --git a/Firmware/MotorControl/controller.cpp b/Firmware/MotorControl/controller.cpp index 9c4e97ca..5ef968ce 100644 --- a/Firmware/MotorControl/controller.cpp +++ b/Firmware/MotorControl/controller.cpp @@ -199,6 +199,12 @@ bool Controller::update() { } anticogging_pos_estimate = pos_setpoint_; // FF the position setpoint instead of the pos_estimate } break; + case INPUT_MODE_TUNING: { + const auto time = axis_->loop_counter_ * current_meas_period; + pos_setpoint_ = autotuning_.pos_amplitude * our_arm_sin_f32((2.0f * M_PI * autotuning_.pos_frequency) * time + autotuning_.pos_phase); + vel_setpoint_ = autotuning_.vel_amplitude * our_arm_sin_f32((2.0f * M_PI * autotuning_.vel_frequency) * time + autotuning_.vel_phase); + torque_setpoint_ = autotuning_.torque_amplitude * our_arm_sin_f32((2.0f * M_PI * autotuning_.torque_frequency) * time + autotuning_.torque_phase); + } break; default: { set_error(ERROR_INVALID_INPUT_MODE); return false; diff --git a/Firmware/MotorControl/controller.hpp b/Firmware/MotorControl/controller.hpp index bcd2a9c6..ba69e39c 100644 --- a/Firmware/MotorControl/controller.hpp +++ b/Firmware/MotorControl/controller.hpp @@ -3,7 +3,7 @@ class Controller : public ODriveIntf::ControllerIntf { public: - typedef struct { + struct Anticogging_t { uint32_t index = 0; float cogging_map[3600]; bool pre_calibrated = false; @@ -12,7 +12,19 @@ public: float calib_vel_threshold = 1.0f; float cogging_ratio = 1.0f; bool anticogging_enabled = true; - } Anticogging_t; + }; + + struct Autotuning_t { + float pos_amplitude = 0.0f; + float pos_frequency = 0.0f; + float pos_phase = 0.0f; + float vel_amplitude = 0.0f; + float vel_frequency = 0.0f; + float vel_phase = 0.0f; + float torque_amplitude = 0.0f; + float torque_frequency = 0.0f; + float torque_phase = 0.0f; + }; struct Config_t { ControlMode control_mode = CONTROL_MODE_POSITION_CONTROL; //see: ControlMode_t @@ -92,6 +104,8 @@ public: float input_filter_kp_ = 0.0f; float input_filter_ki_ = 0.0f; + Autotuning_t autotuning_; + bool input_pos_updated_ = false; bool trajectory_done_ = true; diff --git a/Firmware/odrive-interface.yaml b/Firmware/odrive-interface.yaml index 7af706dc..235be911 100644 --- a/Firmware/odrive-interface.yaml +++ b/Firmware/odrive-interface.yaml @@ -896,6 +896,18 @@ interfaces: calib_vel_threshold: float32 cogging_ratio: readonly float32 anticogging_enabled: bool + autotuning: + c_is_class: False + attributes: + pos_amplitude: float32 + pos_frequency: float32 + pos_phase: float32 + vel_amplitude: float32 + vel_frequency: float32 + vel_phase: float32 + torque_amplitude: float32 + torque_frequency: float32 + torque_phase: float32 functions: move_incremental: doc: Moves the axes' goal point by a specified increment. @@ -1347,6 +1359,12 @@ valuetypes: ### Valid Control modes * `CONTROL_MODE_POSITION_CONTROL` + Tuning: + brief: Implements a tuning mode + doc: | + Used for tuning your odrive, this mode allows the user to set different frequencies. + Set control_mode for the loop you want to tune, then set the frequency desired. + The ODrive will send a 1 turn amplitude sine wave to the controller with the given frequency and phase. ODrive.Motor.MotorType: values: diff --git a/tools/odrive/enums.py b/tools/odrive/enums.py index f1b9ff4b..6b38d74b 100644 --- a/tools/odrive/enums.py +++ b/tools/odrive/enums.py @@ -64,6 +64,7 @@ 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 MOTOR_TYPE_HIGH_CURRENT = 0