MindMap Gallery FOC_control
这个是一个清晰的void ControlLoop_lRQHandler的思维导图,主要说明了定义机电的电流采样的结构体、调用函数、电流测量并校准等内容,每个内容下又分了好几个层级进行说明。这样的思维导图由主题、分支和关键词组成,它模仿了人脑的神经网络结构,通过图形化的方式将中心思想或问题的放射性结构展现出来,帮助使用者更好的理解内容。
Edited at 2022-09-02 06:40:51class Motor
motor.hpp & motor.cpp
pwm_update_cb(uint32_t output_timestamp)
apply_pwm_timings(uint16_t timings[3], bool tentative)
Main Topic
Idq_setpoint_src_
Idq_setpoint_ = Idq_setpoint_src_.present();
??? FOC电流控制的,d,q轴电流给定值,是如何更新的 ???
class FieldOrientedController
update
void FieldOrientedController::update(uint32_t timestamp) { CRITICAL_SECTION() { ctrl_timestamp_ = timestamp; enable_current_control_ = enable_current_control_src_; Idq_setpoint_ = Idq_setpoint_src_.present(); Vdq_setpoint_ = Vdq_setpoint_src_.present(); phase_ = phase_src_.present(); phase_vel_ = phase_vel_src_.present(); } }
get_alpha_beta_output
Ialpha_beta;
vbus_voltage_measured_ = vbus_voltage; Ialpha_beta_measured_ = Ialpha_beta;
class FieldOrientedController
on_measurement
Store the measurements,存储到: vbus_voltage_measured_, Ialpha_beta_measured_,
class AlphaBetaFrameController
on_measurement
进行Clark变换,由3相电流, 计算得到Ialpha_beta
void ControlLoop_IRQHandler(void)
定义电机的3相电流采样的结构体 current0, current1
// Ensure that all the ADCs are done std::optional<Iph_ABC_t> current0; std::optional<Iph_ABC_t> current1;
调用函数fetch_and_reset_adcs(¤t0, ¤t1), 以取出ADC采样的电机的3相电流
if (!fetch_and_reset_adcs(¤t0, ¤t1)) { motors[0].disarm_with_error(Motor::ERROR_BAD_TIMING); motors[1].disarm_with_error(Motor::ERROR_BAD_TIMING); }
...
// If the motor FETs are not switching then we can't measure the current // because for this we need the low side FET to conduct. // So for now we guess the current to be 0 (this is not correct shortly after // disarming and when the motor spins fast in idle). Passing an invalid // current reading would create problems with starting FOC. if (!(TIM1->BDTR & TIM_BDTR_MOE_Msk)) { current0 = {0.0f, 0.0f}; } if (!(TIM8->BDTR & TIM_BDTR_MOE_Msk)) { current1 = {0.0f, 0.0f}; }
电流测量并校准 current_meas_cb()
motors[0].current_meas_cb(timestamp - TIM1_INIT_COUNT, current0); motors[1].current_meas_cb(timestamp, current1);
Runs the periodic control loop:
odrv.control_loop_cb(timestamp);
...
// By this time the ADCs for both M0 and M1 should have fired again. But // let's wait for them just to be sure. MEASURE_TIME(odrv.task_times_.dc_calib_wait) { while (!(ADC2->SR & ADC_SR_EOC)); }
调用函数fetch_and_reset_adcs(¤t0, ¤t1), 以取出ADC采样的电机的3相电流
if (!fetch_and_reset_adcs(¤t0, ¤t1)) { motors[0].disarm_with_error(Motor::ERROR_BAD_TIMING); motors[1].disarm_with_error(Motor::ERROR_BAD_TIMING); }
计算dc校准值
motors[0].dc_calib_cb(timestamp + TIM_1_8_PERIOD_CLOCKS * (TIM_1_8_RCR + 1) - TIM1_INIT_COUNT, current0); motors[1].dc_calib_cb(timestamp + TIM_1_8_PERIOD_CLOCKS * (TIM_1_8_RCR + 1), current1);
调用函数pwm_update_cb(), 以更新PWM
motors[0].pwm_update_cb(timestamp + 3 * TIM_1_8_PERIOD_CLOCKS * (TIM_1_8_RCR + 1) - TIM1_INIT_COUNT); motors[1].pwm_update_cb(timestamp + 3 * TIM_1_8_PERIOD_CLOCKS * (TIM_1_8_RCR + 1));
...
if (timestamp_ != timestamp + TIM_1_8_PERIOD_CLOCKS * (TIM_1_8_RCR + 1)) { motors[0].disarm_with_error(Motor::ERROR_CONTROL_DEADLINE_MISSED); motors[1].disarm_with_error(Motor::ERROR_CONTROL_DEADLINE_MISSED); }
...
odrv.task_timers_armed_ = odrv.task_timers_armed_ && !TaskTimer::enabled;
...
TaskTimer::enabled = false;
exit
tim->CCR1 = timings[0]; tim->CCR2 = timings[1]; tim->CCR3 = timings[2];
class Motor
apply_pwm_timings
class Motor
pwm_update_cb
进行SVPWM计算,输出为: pwm_timings[0],pwm_timings[1],pwm_timings[2]
class FieldOrientedController
get_alpha_beta_output
进行FOC算法,包括: Park变换,电流环PI计算,Inverse Park变换;
class AlphaBetaFrameController
get_output
进行SVPWM计算,输出为: pwm_timings[0],pwm_timings[1],pwm_timings[2]
foc.cpp
foc.hpp
File inclusion relationship
motor.cpp
motor.hpp
class AlphaBetaFrameController
on_measurement
进行Clark变换,由3相电流, 计算得到Ialpha_beta
get_output
进行SVPWM计算,输出为: pwm_timings[0],pwm_timings[1],pwm_timings[2]
class FieldOrientedController
on_measurement
Store the measurements,存储到: vbus_voltage_measured_, Ialpha_beta_measured_,
get_alpha_beta_output
进行FOC算法,包括: Park变换,电流环PI计算,Inverse Park变换;
update
用于更新下面的变量: ctrl_timestamp_, [HCLK ticks] enable_current_control_, (true or false) Idq_setpoint_, (d,q轴电流给定)[A] Vdq_setpoint_, (d,q轴电压给定)[V] phase_, ()[rad] phase_vel_, ()[rad/s]
phase_control_law.hpp
!!!No phase_control_law.cpp!!!
class FieldOrientedController
reset()
update()
on_measurement()
get_alpha_beta_output()
virtual ODriveIntf::MotorIntf::Error get_output( uint32_t output_timestamp, float (&pwm_timings)[N_PHASES], std::optional<float>* ibus) = 0
virtual ODriveIntf::MotorIntf::Error on_measurement( std::optional<float> vbus_voltage, std::optional<std::array<float, N_PHASES>> currents, uint32_t input_timestamp) = 0
virtual void reset() = 0
class AlphaBetaFrameController
on_measurement()
ODriveIntf::MotorIntf::Error on_measurement( std::optional<float> vbus_voltage, std::optional<std::array<float, 3>> currents, uint32_t input_timestamp) final;
get_output()
ODriveIntf::MotorIntf::Error get_output( uint32_t output_timestamp, float (&pwm_timings)[3], std::optional<float>* ibus) final;
on_measurement()
virtual ODriveIntf::MotorIntf::Error on_measurement( std::optional<float> vbus_voltage, std::optional<float2D> Ialpha_beta, uint32_t input_timestamp) = 0;
get_alpha_beta_output()
virtual ODriveIntf::MotorIntf::Error get_alpha_beta_output( uint32_t output_timestamp, std::optional<float2D>* mod_alpha_beta, std::optional<float>* ibus) = 0;
012345
常数constant
{}
大括号
class_name
类的名字
variable_name
变量的名字
()
小括号
function_name
函数的名字
kewords
关键字
class PhaseControlLaw
reset()
virtual void reset() = 0;
on_measurement()
virtual ODriveIntf::MotorIntf::Error on_measurement( std::optional<float> vbus_voltage, std::optional<std::array<float, N_PHASES>> currents, uint32_t input_timestamp) = 0;
get_output()
virtual ODriveIntf::MotorIntf::Error get_output( uint32_t output_timestamp, float (&pwm_timings)[N_PHASES], std::optional<float>* ibus) = 0;