diff --git a/Firmware/MotorControl/controller.cpp b/Firmware/MotorControl/controller.cpp index 89eb9a5e..6dbb6878 100644 --- a/Firmware/MotorControl/controller.cpp +++ b/Firmware/MotorControl/controller.cpp @@ -163,8 +163,8 @@ bool Controller::update(float* torque_setpoint_output) { vel_setpoint_ += step; torque_setpoint_ = (step / current_meas_period) * config_.inertia; } break; - case INPUT_MODE_CURRENT_RAMP: { - float max_step_size = std::abs(current_meas_period * config_.current_ramp_rate); + case INPUT_MODE_TORQUE_RAMP: { + float max_step_size = std::abs(current_meas_period * config_.torque_ramp_rate); float full_step = input_torque_ - torque_setpoint_; float step = std::clamp(full_step, -max_step_size, max_step_size); @@ -319,11 +319,10 @@ bool Controller::update(float* torque_setpoint_output) { torque = limitVel(config_.vel_limit, *vel_estimate_src, vel_gain, torque); } - // Current limiting - // TODO: Change to controller working in torque units - // and get the torque limits from a function of the motor + // Limit max torque to a user defined torque limit. This functions as an acceleration limit. + // The motor object handles current limiting bool limited = false; - float Tlim = axis_->motor_.effective_torque_lim(); + float Tlim = axis_->motor_.config_.torque_lim; if (torque > Tlim) { limited = true; torque = Tlim; diff --git a/Firmware/MotorControl/controller.hpp b/Firmware/MotorControl/controller.hpp index 69ae5162..851f265c 100644 --- a/Firmware/MotorControl/controller.hpp +++ b/Firmware/MotorControl/controller.hpp @@ -28,7 +28,7 @@ public: float vel_limit = 20000.0f; // [counts/s] Infinity to disable. float vel_limit_tolerance = 1.2f; // ratio to vel_lim. Infinity to disable. float vel_ramp_rate = 10000.0f; // [(counts/s) / s] - float current_ramp_rate = 1.0f; // A / sec + float torque_ramp_rate = 0.1f; // Nm / sec bool setpoints_in_cpr = false; float inertia = 0.0f; // [A/(count/s^2)] float input_filter_bandwidth = 2.0f; // [1/s] diff --git a/Firmware/MotorControl/motor.cpp b/Firmware/MotorControl/motor.cpp index 568f9373..2c7ab5f9 100644 --- a/Firmware/MotorControl/motor.cpp +++ b/Firmware/MotorControl/motor.cpp @@ -177,19 +177,19 @@ bool Motor::do_checks() { return true; } -float Motor::effective_torque_lim() { +float Motor::effective_current_lim() { // Configured limit - float torque_lim = config_.torque_lim; + float current_lim = config_.current_lim; // Hardware limit if (axis_->motor_.config_.motor_type == Motor::MOTOR_TYPE_GIMBAL) { - torque_lim = std::min(torque_lim, 0.98f*one_by_sqrt3*vbus_voltage); //gimbal motor is voltage control, not Nm or A + current_lim = std::min(current_lim, 0.98f*one_by_sqrt3*vbus_voltage); //gimbal motor is voltage control } else { - torque_lim = std::min(torque_lim, axis_->motor_.current_control_.max_allowed_torque); + current_lim = std::min(current_lim, axis_->motor_.current_control_.max_allowed_current); } // Thermal limit - torque_lim = std::min(torque_lim, thermal_torque_lim_); + current_lim = std::min(current_lim, thermal_current_lim_); - return torque_lim; + return current_lim; } void Motor::log_timing(TimingLog_t log_idx) { @@ -359,7 +359,7 @@ bool Motor::FOC_current(float Id_des, float Iq_des, float I_phase, float pwm_pha ictrl.Id_measured += ictrl.I_measured_report_filter_k * (Id - ictrl.Id_measured); // Check for violation of current limit - float I_trip = (effective_torque_lim() + config_.torque_lim_margin) / config_.torque_constant; + float I_trip = effective_current_lim() + config_.current_lim_margin; if (SQ(Id) + SQ(Iq) > SQ(I_trip)) { set_error(ERROR_CURRENT_LIMIT_VIOLATION); return false; @@ -441,13 +441,20 @@ bool Motor::FOC_current(float Id_des, float Iq_des, float I_phase, float pwm_pha bool Motor::update(float torque_setpoint, float phase, float phase_vel) { - float current_setpoint = torque_setpoint / config_.torque_constant; - current_setpoint *= config_.direction; + float current_setpoint; phase *= config_.direction; phase_vel *= config_.direction; + if (config_.motor_type == MOTOR_TYPE_ACIM) { + current_setpoint = torque_setpoint / (config_.torque_constant * fmax(current_control_.acim_rotor_flux, config_.acim_gain_min_flux)); + } + else { + current_setpoint = torque_setpoint / config_.torque_constant; + } + current_setpoint *= config_.direction; + // TODO: 2-norm vs independent clamping (current could be sqrt(2) bigger) - float ilim = effective_torque_lim() / config_.torque_constant; + float ilim = effective_current_lim(); float id = std::clamp(current_control_.Id_setpoint, -ilim, ilim); float iq = std::clamp(current_setpoint, -ilim, ilim); diff --git a/Firmware/MotorControl/motor.hpp b/Firmware/MotorControl/motor.hpp index 6aaaaf18..178a99db 100644 --- a/Firmware/MotorControl/motor.hpp +++ b/Firmware/MotorControl/motor.hpp @@ -29,7 +29,6 @@ public: float Id_measured; // [A] float I_measured_report_filter_k; float max_allowed_current; // [A] - float max_allowed_torque; // [Nm] float overcurrent_trip_level; // [A] float acim_rotor_flux; // [A] float async_phase_vel; // [rad/s electrical] @@ -96,7 +95,7 @@ public: bool do_checks(); float get_inverter_temp(); bool update_thermal_limits(float fet_temp); - float effective_torque_lim(); + float effective_current_lim(); void log_timing(TimingLog_t log_idx); float phase_current_from_adcval(uint32_t ADCValue); bool measure_phase_resistance(float test_current, float max_voltage); @@ -153,7 +152,6 @@ public: .Id_measured = 0.0f, .I_measured_report_filter_k = 1.0f, .max_allowed_current = 0.0f, - .max_allowed_torque = 0.0f, .overcurrent_trip_level = 0.0f, .acim_rotor_flux = 0.0f, .async_phase_vel = 0.0f, diff --git a/Firmware/odrive-interface.yaml b/Firmware/odrive-interface.yaml index 5fbfc10d..38e8a936 100644 --- a/Firmware/odrive-interface.yaml +++ b/Firmware/odrive-interface.yaml @@ -376,7 +376,6 @@ interfaces: Id_measured: float32 I_measured_report_filter_k: float32 max_allowed_current: readonly float32 - max_allowed_torque: readonly float32 overcurrent_trip_level: readonly float32 acim_rotor_flux: float32 async_phase_vel: readonly float32 @@ -497,9 +496,9 @@ interfaces: type: float32 doc: Ratio to `vel_limit`. Infinity to disable. vel_ramp_rate: float32 - current_ramp_rate: + torque_ramp_rate: type: float32 - unit: A / sec + unit: Nm / sec homing_speed: type: float32 unit: counts/s @@ -692,7 +691,7 @@ valuetypes: PosFilter: MixChannels: TrapTraj: - CurrentRamp: + TorqueRamp: Mirror: diff --git a/docs/commands.md b/docs/commands.md index ba915564..618ddaba 100644 --- a/docs/commands.md +++ b/docs/commands.md @@ -77,7 +77,7 @@ Possible values are: * `INPUT_MODE_POS_FILTER` * `INPUT_MODE_MIX_CHANNELS` * `INPUT_MODE_TRAP_TRAJ` -* `INPUT_MODE_CURRENT_RAMP` +* `INPUT_MODE_TORQUE_RAMP` * `INPUT_MODE_MIRROR` For more information, see [input_modes](input_modes.md). @@ -97,7 +97,7 @@ Possible values are: * `INPUT_MODE_POS_FILTER` * `INPUT_MODE_MIX_CHANNELS` * `INPUT_MODE_TRAP_TRAJ` -* `INPUT_MODE_CURRENT_RAMP` +* `INPUT_MODE_TORQUE_RAMP` * `INPUT_MODE_MIRROR` ## System monitoring commands diff --git a/docs/getting-started.md b/docs/getting-started.md index 968cf34b..9426f395 100644 --- a/docs/getting-started.md +++ b/docs/getting-started.md @@ -348,7 +348,7 @@ You can now control the velocity with `axis.controller.input_vel = 5000` [count/ ### Torque control Set `axis.controller.config.control_mode = CONTROL_MODE_CURRENT_CONTROL`.
-You can now control the torque with `axis.controller.input_torque = 3` [Nm]. +You can now control the torque with `axis.controller.input_torque = 0.1` [Nm]. Note: If you exceed `vel_limit` in current control mode, the current is reduced. To disable this, set `axis.controller.enable_current_mode_vel_limit = False`. diff --git a/docs/input_modes.md b/docs/input_modes.md index 4b0657d9..53463ad0 100644 --- a/docs/input_modes.md +++ b/docs/input_modes.md @@ -13,7 +13,7 @@ The Input Modes currently valid are: * `INPUT_MODE_POS_FILTER` * `INPUT_MODE_MIX_CHANNELS` * `INPUT_MODE_TRAP_TRAJ` -* `INPUT_MODE_CURRENT_RAMP` +* `INPUT_MODE_TORQUE_RAMP` * `INPUT_MODE_MIRROR` --- @@ -85,11 +85,11 @@ Implementes an online trapezoidal trajectory planner. ### Valid Control Modes: * `CONTROL_MODE_POSITION_CONTROL` -## INPUT_MODE_CURRENT_RAMP -Ramp a current command from the current value to the target value. +## INPUT_MODE_TORQUE_RAMP +Ramp a torque command from the current value to the target value. ### Configuration Values: -* `.controller.config.current_ramp_rate` +* `.controller.config.torque_ramp_rate` ### Valid Inputs: * `input_torque` diff --git a/tools/.vscode/launch.json b/tools/.vscode/launch.json index 69a77ee7..9a36a076 100644 --- a/tools/.vscode/launch.json +++ b/tools/.vscode/launch.json @@ -9,7 +9,7 @@ "type": "python", "request": "launch", "stopOnEntry": true, - "pythonPath": "${config:python.interpreterPath}", + "pythonPath": "${command:python.pythonPath}", "program": "${file}", "cwd": "${workspaceRoot}", "env": {},