双电机龙门同步控制伪代码
目录
1. 上电与初始化
system_init()
{
init_encoder();
init_drive();
init_limit_input();
init_emergency_stop();
init_axis_controller(left_axis);
init_axis_controller(right_axis);
init_gantry_sync_controller();
state = IDLE;
}2. 回零流程
gantry_home()
{
state = HOMING;
home_single_axis(left_axis);
left_axis.home_offset = read_raw_encoder(left_axis);
home_single_axis(right_axis);
right_axis.home_offset = read_raw_encoder(right_axis);
left_axis.position = 0.0f;
right_axis.position = 0.0f;
sync_offset = left_axis.position - right_axis.position;
planner.position_ref = 0.0f;
planner.velocity_ref = 0.0f;
planner.target_position = 0.0f;
reset_pid(common_pid);
reset_pid(left_axis.position_pid);
reset_pid(left_axis.velocity_pid);
reset_pid(right_axis.position_pid);
reset_pid(right_axis.velocity_pid);
state = READY;
}3. 1 kHz 同步控制主循环
control_tick_1khz()
{
if (state == FAULT)
{
disable_drive_output();
return;
}
// 1. Read sensor
x1 = read_encoder(left_axis);
x2 = read_encoder(right_axis);
v1 = estimate_velocity(left_axis);
v2 = estimate_velocity(right_axis);
// 2. Update motion planner
planner_step();
x_ref = planner.position_ref;
v_ref = planner.velocity_ref;
// 3. Compute error
x_avg = 0.5f * (x1 + x2);
e_avg = x_ref - x_avg;
e_sync = (x1 - x2) - sync_offset;
v_sync = v1 - v2;
// 4. Cross-coupled controller
common_trim = PID_common(e_avg);
sync_trim = Kps * e_sync + Kds * v_sync;
sync_trim = clamp(sync_trim, -SYNC_TRIM_LIMIT, SYNC_TRIM_LIMIT);
common_trim = clamp(common_trim, -COMMON_TRIM_LIMIT, COMMON_TRIM_LIMIT);
pos_cmd_left = x_ref + common_trim - sync_trim;
pos_cmd_right = x_ref + common_trim + sync_trim;
// 5. Axis servo loop
axis_step(left_axis, pos_cmd_left, v_ref);
axis_step(right_axis, pos_cmd_right, v_ref);
// 6. Safety monitor
if (abs(e_sync) > SYNC_LIMIT)
{
state = FAULT;
emergency_stop();
}
}4. 单轴控制伪代码
axis_step(axis, pos_cmd, vel_ff)
{
pos_error = pos_cmd - axis.position;
vel_cmd = PID_position(axis.position_pid, pos_error) + vel_ff;
vel_cmd = clamp(vel_cmd, -VEL_LIMIT, VEL_LIMIT);
vel_error = vel_cmd - axis.velocity;
iq_cmd = PID_velocity(axis.velocity_pid, vel_error);
iq_cmd = clamp(iq_cmd, -IQ_LIMIT, IQ_LIMIT);
foc_current_control(axis, iq_cmd);
}5. 故障与恢复
fault_handler()
{
disable_drive_output();
latch_fault_code();
state = FAULT;
}
fault_reset()
{
if (emergency_stop_released() && limit_status_ok())
{
clear_fault_latch();
reset_pid(common_pid);
reset_pid(left_axis.position_pid);
reset_pid(left_axis.velocity_pid);
reset_pid(right_axis.position_pid);
reset_pid(right_axis.velocity_pid);
state = READY;
}
}6. 现场落地时的替换点
将伪代码替换为具体硬件实现时,重点替换以下接口:
read_encoder()estimate_velocity()home_single_axis()foc_current_control()disable_drive_output()emergency_stop()
其余控制逻辑可以保持不变。
如果这篇文章对你有帮助,欢迎请我喝杯咖啡 ☕
支付宝
微信