11 bool Motor::measure_phase_resistance(float test_current, float max_voltage)
这段代码是 ODrive 中用于测量电机相电阻(phase resistance)的函数,通过注入测试电流并测量电压降来计算电阻值。
作用:动态测量电机相电阻(单位:Ω),用于自动校准或故障检测。
输入参数:test_current:测试电流幅值(如5A)。max_voltage:允许的最大测试电压(防止过压损坏)。
输出:true:测量成功,结果存入 config_.phase_resistance。false:测量失败(错误码记录在 axis_->error_)。
bool Motor::measure_phase_resistance(float test_current, float max_voltage) {
static const float kI = 10.0f; // 积分增益 [(V/s)/A] 控制电压调整速度。
static const int num_test_cycles = (int)(3.0f / CURRENT_MEAS_PERIOD); // 总测试时间3秒
float test_voltage = 0.0f;
size_t i = 0;
axis_->run_control_loop([&](){
float Ialpha = -(current_meas_.phB + current_meas_.phC); //电流采样:计算A相电流 Ialpha = -(I_B + I_C)(基尔霍夫电流定律)。
test_voltage += (kI * current_meas_period) * (test_current - Ialpha); //PI控制:调整测试电压,使电流跟踪设定值 test_current
//电压限幅:确保 test_voltage 不超过 max_voltage
if (test_voltage > max_voltage || test_voltage < -max_voltage)
return set_error(ERROR_PHASE_RESISTANCE_OUT_OF_RANGE), false;
// 电压注入:沿A相施加测试电压
if (!enqueue_voltage_timings(test_voltage, 0.0f))
return false; // error set inside enqueue_voltage_timings
log_timing(TIMING_LOG_MEAS_R);
return ++i < num_test_cycles;
});
if (axis_->error_ != Axis::ERROR_NONE)
return false;
//相电阻计算,欧姆定律
float R = test_voltage / test_current;
config_.phase_resistance = R;
return true; // if we ran to completion that means success
}
12 bool Motor::measure_phase_inductance(float voltage_low, float voltage_high)
这段代码是 ODrive 中用于测量电机相电感(phase inductance)的函数,通过施加交变电压并测量电流变化率来计算电感值。
作用:动态测量电机相电感(单位:H),用于电机参数自动辨识。
输入参数:voltage_low:低电平测试电压(如-5V)voltage_high:高电平测试电压(如+5V)
输出:true:测量成功,结果存入 config_.phase_inductance,false:测量失败(错误码记录在 axis_->error_)
bool Motor::measure_phase_inductance(float voltage_low, float voltage_high) {
float test_voltages[2] = {voltage_low, voltage_high}; // 交替施加的电压
float Ialphas[2] = {0.0f}; // 存储两个阶段的电流累计值
static const int num_cycles = 5000; // 每个电压状态的循环次数
size_t t = 0;
axis_->run_control_loop([&](){
int i = t & 1; // 交替选择0或1(电压高低切换)
Ialphas[i] += -current_meas_.phB - current_meas_.phC; // 累计A相电流
// 沿α轴注入测试电压
if (!enqueue_voltage_timings(test_voltages[i], 0.0f))
return false; // error set inside enqueue_voltage_timings
log_timing(TIMING_LOG_MEAS_L);
return ++t < (num_cycles << 1); // 总循环次数=2*num_cycles
});
if (axis_->error_ != Axis::ERROR_NONE)
return false;
float v_L = 0.5f * (voltage_high - voltage_low); //有效电压幅值
float dI_by_dt = (Ialphas[1] - Ialphas[0]) / (current_meas_period * (float)num_cycles);
float L = v_L / dI_by_dt; // L = ΔV / (ΔI/Δt)
config_.phase_inductance = L;
if (L < 2e-6f || L > 4000e-6f) // 合理范围检查:2μH~4mH
return set_error(ERROR_PHASE_INDUCTANCE_OUT_OF_RANGE), false;
return true;
}
13 bool Motor::run_calibration()
这段代码是 ODrive 中执行电机参数自动校准(Calibration)的核心函数,它根据电机类型自动选择需要校准的参数,并更新控制器增益。
作用:自动测量电机关键参数(相电阻、相电感)并更新控制器。
适用电机类型:大电流电机(MOTOR_TYPE_HIGH_CURRENT)、异步感应电机(MOTOR_TYPE_ACIM)、云台电机(MOTOR_TYPE_GIMBAL,跳过校准)
校准流程:测量相电阻(measure_phase_resistance)、测量相电感(measure_phase_inductance)、更新电流环增益(update_current_controller_gains)
bool Motor::run_calibration() {
float R_calib_max_voltage = config_.resistance_calib_max_voltage; //电阻测量时的最大允许电压(防止过压损坏)
if (config_.motor_type == MOTOR_TYPE_HIGH_CURRENT
|| config_.motor_type == MOTOR_TYPE_ACIM) {
// 测量相电阻和电感
if (!measure_phase_resistance(config_.calibration_current, R_calib_max_voltage))
return false;
if (!measure_phase_inductance(-R_calib_max_voltage, R_calib_max_voltage))
return false;
} else if (config_.motor_type == MOTOR_TYPE_GIMBAL) {
// no calibration needed
} else {
return false;
}
update_current_controller_gains();
is_calibrated_ = true;
return true;
}
14 bool Motor::enqueue_modulation_timings(float mod_alpha, float mod_beta)
这段代码作用是将SVPWM(空间矢量脉宽调制)计算出来的占空比时间转换为定时器的实际比较值,以准备下一周期的驱动波形,控制三相无刷电机(BLDC)运行。
参数:mod_alpha, mod_beta:α-β 坐标系下的电压矢量(通过 Clarke & Park 变换得到的电压目标)。
bool Motor::enqueue_modulation_timings(float mod_alpha, float mod_beta) {
float tA, tB, tC; //用于保存三相(A、B、C)PWM比较值的归一化时间(范围通常在0~1之间)。
//调用 SVM(空间矢量调制)算法,输入 αβ 坐标下的电压向量,输出 A/B/C 三相的 PWM 比值(tA、tB、tC)。
if (SVM(mod_alpha, mod_beta, &tA, &tB, &tC) != 0)
return set_error(ERROR_MODULATION_MAGNITUDE), false;
//下面三行:将归一化的 tA/tB/tC 转换为实际定时器比较值
next_timings_[0] = (uint16_t)(tA * (float)TIM_1_8_PERIOD_CLOCKS);
next_timings_[1] = (uint16_t)(tB * (float)TIM_1_8_PERIOD_CLOCKS);
next_timings_[2] = (uint16_t)(tC * (float)TIM_1_8_PERIOD_CLOCKS);
标记下一周期的 PWM 数据为有效,等待驱动底层将其加载到实际寄存器中。
next_timings_valid_ = true;
return true;
}
15 bool Motor::enqueue_voltage_timings(float v_alpha, float v_beta)
这段代码是电压控制方式(Voltage Control Mode)下生成下一周期 PWM 调制信号的关键部分。enqueue_voltage_timings 通过输入 α-β 坐标下的期望电压向量 (v_alpha, v_beta),结合母线电压(vbus_voltage),计算出归一化调制矢量 (mod_alpha, mod_beta),并交由 enqueue_modulation_timings() 处理,最终生成 PWM 时间参数。
bool Motor::enqueue_voltage_timings(float v_alpha, float v_beta) {
//vbus_voltage:母线电压,即电源直流电压(比如 24V、48V)2/3:是 Clarke 变换后,三相变两相的电压变换系数。
float vfactor = 1.0f / ((2.0f / 3.0f) * vbus_voltage);
//这一步计算的是将物理电压值转换为 SVM 归一化单位的系数,目的是把 (v_alpha, v_beta) 这样的单位为 V 的值转换为 SVPWM 使用的 [–1, 1] 的无量纲值。
float mod_alpha = vfactor * v_alpha;
float mod_beta = vfactor * v_beta;
if (!enqueue_modulation_timings(mod_alpha, mod_beta))
return false;
log_timing(TIMING_LOG_FOC_VOLTAGE);
return true;
}