Odrive0.5.1-FOC电机控制核心代码 Odrive motor.cpp(.hpp)代码实现(三)

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;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值