第一节:关节控制基础——电机选型与编码器原理、关节动力学模型、PID控制基础与调参

大家好,我是你们的老朋友。今天咱们正式开干,聊聊关节控制最底层的那些事儿。

说实话,我见过太多做强化学习的同学,一上来就撸算法,结果在真机上连个电机都转不利索。为什么?因为底层基础没打牢。你想想看,算法再漂亮,执行器响应慢半拍,或者反馈信号全是噪声,那一切都是白搭。

所以这一节,咱们把关节控制的三个基石掰开揉碎了讲清楚。嗯,内容有点干,但都是硬货。

1.1 电机选型:别让执行器拖了后腿

选电机这事儿,我个人的习惯是:先算负载,再定类型,最后看驱动器。

第一步:算扭矩

关节需要多大的扭矩?别靠猜。公式很简单:

τ_required = J * α + τ_gravity + τ_friction

其中:

  • J:负载惯量(kg·m²)
  • α:目标角加速度(rad/s²)
  • τ_gravity:重力矩(尤其对机械臂的肩关节)
  • τ_friction:摩擦力矩(别忽略,低速时它占大头)

第二步:选类型

电机类型 优点 缺点 适用场景
直流有刷电机 控制简单,成本低 电刷磨损,寿命短 低成本教育机器人
直流无刷电机(BLDC) 效率高,寿命长 需要电子换向,控制复杂 工业机器人、协作机器人
步进电机 开环位置控制,价格低 高速扭矩小,易丢步 3D打印机、小型关节
伺服电机 精度高,响应快 贵,需要配套驱动器 高性能关节、人形机器人
我的经验: 做强化学习落地,我强烈建议用伺服电机+谐波减速器的组合。虽然贵点,但反馈精度和响应速度能让你少掉很多头发。我曾经在一个项目里贪便宜用了步进电机,结果算法收敛了,关节却因为丢步一直在抖……那叫一个崩溃。

1.2 编码器原理:你的眼睛在哪里?

电机选好了,怎么知道它转了多少?靠编码器。

编码器分两种:

  • 增量式编码器:输出脉冲信号,只能知道相对位置变化。断电后位置丢失,需要归零。
  • 式编码器:每个位置对应唯一编码,上电就知道当前角度。贵,但真香。

我个人更偏爱式编码器,尤其是多圈式。为什么?因为强化学习训练过程中,关节可能会被外力随意掰动。如果是增量式,每次上电都得手动归零,训练流程直接打断。你想想看,半夜跑实验,第二天发现数据全废了,就因为忘了归零……

分辨率怎么选?

编码器的分辨率决定了你能感知到的最小角度变化。公式:

分辨率(度) = 360° / 线数

比如一个1000线的增量式编码器,分辨率是0.36°。听起来还行?但如果你加了100:1的减速器,关节端的分辨率就变成了0.0036°。嗯,够用了。

注意: 编码器信号容易受干扰。我曾经在调试时发现角度读数莫名其妙跳变,查了两天才发现是电机动力线和编码器信号线走在一起了。记住:信号线必须屏蔽,且远离动力线。

1.3 关节动力学模型:理解你的“身体”

做控制,你得知道你的关节长什么样。动力学模型就是关节的“物理身份证”。

最简单的单关节模型:

J * θ̈ + b * θ̇ + K * θ = τ

其中:

  • J:转动惯量
  • b:阻尼系数
  • K:刚度系数(如果有弹性元件)
  • τ:施加的扭矩

这个模型虽然简单,但足够我们理解核心逻辑。实际项目中,我会用系统辨识的方法来获取这些参数。比如给关节一个阶跃信号,记录响应曲线,然后拟合出J和b。

下面是我画的一个单关节动力学模型示意图,帮你直观理解:

单关节动力学模型示意图 电机 减速器 负载 τ_m τ_out J, b, K 编码器反馈
核心要点: 动力学模型是你设计控制器的依据。模型越准,控制效果越好。但别追求完美——强化学习的一大优势就是能在一定程度上补偿模型误差。

1.4 PID控制基础与调参:老司机的基本功

PID控制,说白了就是三个字:比例、积分、微分。公式长这样:

u(t) = Kp * e(t) + Ki * ∫e(t)dt + Kd * de(t)/dt

其中:

  • Kp:比例增益——误差越大,输出越大。调大了会震荡,调小了反应慢。
  • Ki:积分增益——消除稳态误差。但调大了会超调,甚至积分饱和。
  • Kd:微分增益——抑制震荡,提高响应速度。但对噪声敏感。

调参口诀(我自己的经验):

  1. 先调Kp,从小到大,直到出现轻微震荡。
  2. 然后加一点Kd,把震荡压下去。
  3. 最后加Ki,消除稳态误差。
  4. 重复以上步骤,直到满意。
避坑指南: 我曾经在调一个高减速比关节时,Kp给得太大,结果电机直接啸叫,吓得我赶紧断电。后来发现是微分项放大了编码器的量化噪声。解决办法:在微分项前加一个低通滤波器,或者直接用“微分先行”结构。

代码示例:位置式PID

class PIDController:
    def __init__(self, Kp, Ki, Kd, dt):
        self.Kp = Kp
        self.Ki = Ki
        self.Kd = Kd
        self.dt = dt
        self.integral = 0
        self.prev_error = 0
    
    def compute(self, target, current):
        error = target - current
        self.integral += error * self.dt
        derivative = (error - self.prev_error) / self.dt
        
        output = self.Kp * error + self.Ki * self.integral + self.Kd * derivative
        
        self.prev_error = error
        return output

这个代码看着简单,但实际用的时候有几个坑:

  • 积分限幅:防止积分项无限累积,导致“积分饱和”。我一般把积分项限制在输出范围的±20%。
  • 微分滤波:对误差做一阶低通滤波,再求微分。代码里加一行就行。
  • 输出限幅:别让控制器输出超过电机能承受的范围。
重要提醒: PID参数不是调一次就完事的。负载变化、摩擦变化、甚至温度变化都会影响效果。所以做强化学习时,我通常把PID作为底层执行器,上层用RL来动态调整参数或者补偿扭矩。这样既保证了稳定性,又有了智能性。

好了,这一节的内容就到这儿。电机选型、编码器原理、动力学模型、PID调参——这四个东西是关节控制的四梁八柱。你把这些搞明白了,后面学强化学习落地才会事半功倍。

可可精品资料库