06 bool Motor::do_checks()
调用check_DRV_fault函数检测DRV8301 是否触发硬件故障,触发则设置电机错误状态并触发安全保护机制。
bool Motor::do_checks() {
if (!check_DRV_fault()) {
set_error(ERROR_DRV_FAULT);
return false;
}
return true;
}
07 float Motor::effective_current_lim()
这段代码是 ODrive 中计算电机实际电流限制(effective current limit)的函数,它综合了多个限制因素(配置值、硬件能力、电压限制等),确保电流控制既满足用户需求,又不会超出系统安全范围。计算电机运行时允许的 实时最大电流值(单位:A)。
float Motor::effective_current_lim() {
float current_lim = config_.current_lim; // 用户设定的电流限制(如30A)
// Hardware limit
if (axis_->motor_.config_.motor_type == Motor::MOTOR_TYPE_GIMBAL) {
current_lim = std::min(current_lim, 0.98f*one_by_sqrt3*vbus_voltage); //云台电机(Gimbal Motor,电压控制模式)
} else {
current_lim = std::min(current_lim, axis_->motor_.current_control_.max_allowed_current); //普通电机(电流控制模式)
}
// Apply axis current limiters 允许外部模块(如温度监控、功率管理)动态注入额外限制。例如:温度过高时,TemperatureLimiter 可临时降低电流限制。
for (const CurrentLimiter* const limiter : axis_->current_limiters_) {
current_lim = std::min(current_lim, limiter->get_current_limit(config_.current_lim));
}
//缓存并返回结果
effective_current_lim_ = current_lim;
return effective_current_lim_;
}
云台电机(Gimbal Motor,电压控制模式)

普通电机(电流控制模式)

08 float Motor::max_available_torque()
这段代码是ODrive 中计算电机在当前条件下,可提供的最大扭矩(max available torque)的函数。
它会根据电机类型(普通电机或异步感应电机ACIM)和系统限制,动态计算实时可用的扭矩上限。
float Motor::max_available_torque() {
if (config_.motor_type == Motor::MOTOR_TYPE_ACIM) {
float max_torque = effective_current_lim() * config_.torque_constant * current_control_.acim_rotor_flux; //基于电流限制和电机参数计算理论扭矩。
max_torque = std::clamp(max_torque, 0.0f, config_.torque_lim); //确保结果不超过用户设定的扭矩限制(torque_lim)。
return max_torque;
}
else {
float max_torque = effective_current_lim() * config_.torque_constant;
max_torque = std::clamp(max_torque, 0.0f, config_.torque_lim);
return max_torque;
}
}
异步感应电机(ACIM)路径

普通电机(永磁同步电机PMSM等)路径


09 void Motor::log_timing(TimingLog_t log_idx)
这段代码是 ODrive 中用于记录电机控制时序关键点耗时 的函数。
- 核心作用:记录特定事件(如中断处理、控制循环)的耗时,单位是定时器时钟周期。
- 典型用途:
- 分析中断响应延迟
- 测量控制算法执行时间
- 调试实时性问题(如超时故障)
void Motor::log_timing(TimingLog_t log_idx) {
static const uint16_t clocks_per_cnt = (uint16_t)((float)TIM_1_8_CLOCK_HZ / (float)TIM_APB1_CLOCK_HZ); //计算定时器时钟与实际计数值的换算系数。
uint16_t timing = clocks_per_cnt * htim13.Instance->CNT; // TODO: Use a hw_config
if (log_idx < TIMING_LOG_NUM_SLOTS) {
timing_log_[log_idx] = timing; //预定义的数组,用于存储多个时序点数据,log_idx:指定存储位置(如 0=中断入口,1=控制算法开始,2=算法结束)。
}
}

10 float Motor::phase_current_from_adcval(uint32_t ADCValue)
这段代码是 ODrive 中将 ADC 原始值转换为电机相电流(单位:安培)的核心函数,主要用于电流采样信号的处理。
float Motor::phase_current_from_adcval(uint32_t ADCValue) {
int adcval_bal = (int)ADCValue - (1 << 11); //去除ADC偏置(硬件零漂) 1<<11 = 2048 将原始 ADC 值转换为 有符号数(-2048~+2047),代表电流方向(正/负)。
float amp_out_volt = (3.3f / (float)(1 << 12)) * (float)adcval_bal; //转换为放大器输出电压
float shunt_volt = amp_out_volt * phase_current_rev_gain_; //(3)
float current = shunt_volt * hw_config_.shunt_conductance; //(4)
return current;
}

