3. 伺服电机驱动配置
任务说明
本案例目标是在LinuxCNC中配置一台带增量编码器反馈的伺服驱动器,实现闭环位置控制。你将完成:驱动器使能信号与方向/脉冲接口的配置、编码器反馈通道的接入、以及PID位置环参数的初步整定。最终通过LinuxCNC的HAL示波器或halscope观察实际位置跟随指令位置,验证闭环控制有效。
环境与依赖
- LinuxCNC 2.8或2.9(安装时选择
linuxcnc-sim或linuxcnc-uspace即可,本案例不依赖实时内核) - 模拟伺服驱动器:使用LinuxCNC自带的
sim驱动(hal_parport+sim_encoder)来模拟真实伺服驱动器的脉冲/方向接口与编码器反馈 - 配置文件:
custom.hal与custom_postgui.hal(由StepConf生成,本案例直接编辑)
实现步骤
使用StepConf向导创建一台“三轴铣床”配置(或直接使用现有配置),轴数量选1即可。关键配置如下:
- 并行端口地址:
0x378(模拟环境无实际硬件也可) - 步进/方向引脚:
pin 2(步进)、pin 3(方向) - 编码器反馈:使用
sim_encoder生成模拟编码器信号,接入encoderHAL组件 - 驱动器使能:使用
pin 17作为使能输出
关键完整代码
以下为custom.hal的完整内容,实现伺服驱动器的脉冲/方向输出、编码器反馈采集与闭环位置控制:
# ===== 伺服驱动器接口配置 =====
# 加载并行端口驱动
loadrt hal_parport cfg="0x378 out"
setp parport.0.pin-2-out-invert 0
setp parport.0.pin-3-out-invert 0
setp parport.0.pin-17-out-invert 0
# 加载步进发生器(脉冲/方向)
loadrt stepgen step_type=0,0,0
addf stepgen.0.make-pulses base-thread
addf stepgen.0.capture-position base-thread
addf stepgen.1.make-pulses base-thread
addf stepgen.1.capture-position base-thread
addf stepgen.2.make-pulses base-thread
addf stepgen.2.capture-position base-thread
# 连接步进/方向信号到并行端口
net step-cmd.0 = stepgen.0.step
net dir-cmd.0 = stepgen.0.dir
net step-out.0 = parport.0.pin-2-out
net dir-out.0 = parport.0.pin-3-out
newsig step-cmd.0 bit
newsig dir-cmd.0 bit
newsig step-out.0 bit
newsig dir-out.0 bit
setp parport.0.pin-2-out-reset 1
setp parport.0.pin-3-out-reset 1
# 驱动器使能信号
net servo-enable = parport.0.pin-17-out
newsig servo-enable bit
# ===== 编码器反馈 =====
# 模拟编码器(每转4000脉冲,4倍频后16000 counts/rev)
loadrt sim_encoder num_chan=1
addf sim-encoder.0.update base-thread
setp sim-encoder.0.position-scale 16000
# 编码器计数器
loadrt encoder num_chan=1
addf encoder.0.update-counter base-thread
addf encoder.0.capture-position base-thread
setp encoder.0.position-scale 16000
# 连接模拟编码器到计数器
net enc-a.0 = sim-encoder.0.a
net enc-b.0 = sim-encoder.0.b
newsig enc-a.0 bit
newsig enc-b.0 bit
# ===== 闭环位置控制 =====
# 将stepgen的指令位置作为位置环给定
net axis-cmd-pos = stepgen.0.position-cmd
net axis-fb-pos = encoder.0.position
# PID控制器
loadrt pid num_chan=1
addf pid.0.do-pid-calcs servo-thread
setp pid.0.Pgain 1000
setp pid.0.Igain 0
setp pid.0.Dgain 0
setp pid.0.bias 0
setp pid.0.FF0 0
setp pid.0.FF1 0
setp pid.0.FF2 0
setp pid.0.maxoutput 1000
setp pid.0.maxerror 0
# 连接PID输入输出
net pid-cmd = pid.0.command
net pid-fb = pid.0.feedback
net pid-out = pid.0.output
newsig pid-cmd float
newsig pid-fb float
newsig pid-out float
# PID输出作为速度指令给stepgen(位置环+速度内环)
net step-vel-cmd = pid.0.output
setp stepgen.0.velocity-cmd 0
# 使能信号连接
net axis-enable = pid.0.enable
net axis-enable = stepgen.0.enable
net axis-enable = encoder.0.enable
# 初始化
setp stepgen.0.position-scale 16000
setp stepgen.0.maxvel 1000
setp stepgen.0.maxaccel 1000
在custom_postgui.hal中添加以下内容,将PID输出连接到stepgen的速度指令:
# 将PID输出连接到stepgen速度指令
net step-vel-cmd => stepgen.0.velocity-cmd
运行与验证
- 将上述
custom.hal内容替换到配置目录中对应文件,保存后启动LinuxCNC(选择该配置)。 - 在LinuxCNC界面中,进入“MDI”模式,输入
G0 X10并执行,观察轴是否移动到10mm位置。 - 打开终端运行
halscope,添加信号:stepgen.0.position-cmd(指令位置)和encoder.0.position(实际反馈位置)。 - 在MDI中执行一段小幅往复运动(如
G0 X5、G0 X0),在示波器上观察两条曲线。
通过条件:实际位置曲线(encoder.0.position)能快速跟随指令位置曲线(stepgen.0.position-cmd),稳态误差小于0.01mm,且无持续振荡。若出现振荡,减小pid.0.Pgain至500左右;若跟随过慢,适当增大Pgain。
常见问题
- 轴不动:检查
parport.0.pin-17-out是否为高电平(使能有效),可用halcmd show pin parport.0.pin-17-out查看。 - 位置误差大:确认
encoder.0.position-scale与stepgen.0.position-scale一致(均为16000),否则位置环会存在比例偏差。 - 电机啸叫/振荡:Pgain过大导致,按上述方法调小。