动力学与平衡第11课/共30课

🤖 姿态平衡控制

PD控制与全身协调:让机器人站得稳

⚖️ 姿态平衡控制的目标

姿态平衡控制确保机器人在受到扰动时恢复直立姿态:

📐 PD姿态控制器

最基本的姿态控制器是PD控制:

τroll = Kp · (rollref - roll) - Kd · roll̇
τpitch = Kp · (pitchref - pitch) - Kd · pitcḣ

力矩通过足端力实现:

τ = Σ(ri - rCoM) × Fi

🧮 仿真:姿态平衡控制

import math class AttitudeController: def __init__(self, mass=6.2, Ixx=0.05, Iyy=0.1, Izz=0.1, dt=0.001): self.mass = mass self.Ixx, self.Iyy, self.Izz = Ixx, Iyy, Izz self.dt = dt self.g = 9.81 def pd_controller(self, roll, pitch, roll_ref, pitch_ref, roll_dot, pitch_dot, kp=50, kd=10): tau_roll = kp * (roll_ref - roll) - kd * roll_dot tau_pitch = kp * (pitch_ref - pitch) - kd * pitch_dot return tau_roll, tau_pitch def simulate_balancing(self, initial_roll=0.1, initial_pitch=0.05, kp=50, kd=10, duration=2.0): roll = initial_roll pitch = initial_pitch roll_dot = 0 pitch_dot = 0 trajectory = [] t = 0 while t < duration: tau_r, tau_p = self.pd_controller(roll, pitch, 0, 0, roll_dot, pitch_dot, kp, kd) # Simplified dynamics: I*alpha = tau - m*g*h*sin(angle) h = 0.2 roll_ddot = (tau_r - self.mass * self.g * h * math.sin(roll)) / self.Ixx pitch_ddot = (tau_p - self.mass * self.g * h * math.sin(pitch)) / self.Iyy roll_dot += roll_ddot * self.dt pitch_dot += pitch_ddot * self.dt roll += roll_dot * self.dt pitch += pitch_dot * self.dt trajectory.append((t, roll, pitch, tau_r, tau_p)) t += self.dt return trajectory ctrl = AttitudeController() print("=" * 55) print(" Attitude Balance Control Simulation") print("=" * 55) # PD controller response print("\n [PD Balance Controller - Kp=50, Kd=10]") traj = ctrl.simulate_balancing(initial_roll=0.15, initial_pitch=0.1) for i in range(0, len(traj), max(1, len(traj)//12)): t, r, p, tr, tp = traj[i] print(f" t={t:.3f}s roll={r*180/math.pi:+6.2f}deg pitch={p*180/math.pi:+6.2f}deg " f"tau=({tr:+.2f},{tp:+.2f})Nm") # Different gains comparison print("\n [Gain Comparison - initial roll=10deg]") gains = [(20, 5), (50, 10), (100, 20), (200, 40)] for kp, kd in gains: traj = ctrl.simulate_balancing(initial_roll=10*math.pi/180, initial_pitch=0, kp=kp, kd=kd, duration=1.0) max_roll = max(abs(r) for _, r, _, _, _ in traj) final_roll = traj[-1][1] settling = 0 for t, r, _, _, _ in traj: if abs(r) < 0.001 and settling == 0: settling = t print(f" Kp={kp:3d}, Kd={kd:2d}: max_roll={max_roll*180/math.pi:.2f}deg, " f"final={final_roll*180/math.pi:.4f}deg, settle={settling:.3f}s") # Disturbance rejection print("\n [Disturbance Rejection]") traj = ctrl.simulate_balancing(initial_roll=0, initial_pitch=0, kp=80, kd=15, duration=1.0) # Apply impulse at t=0.3 for i, (t, r, p, tr, tp) in enumerate(traj): if abs(t - 0.3) < 0.001: # Apply impulse pass # Simpler: just show the balancing with initial offset print(" Applying 5deg lateral push at t=0...") traj2 = ctrl.simulate_balancing(initial_roll=5*math.pi/180, initial_pitch=0, kp=80, kd=15, duration=0.5) for i in range(0, len(traj2), max(1, len(traj2)//8)): t, r, p, tr, tp = traj2[i] print(f" t={t:.3f}s roll={r*180/math.pi:+6.2f}deg tau_roll={tr:+.2f}Nm") # Stability margin analysis print("\n [Maximum Recoverable Tilt]") for kp in [30, 50, 80, 120]: max_tilt = 0 for tilt_deg in range(1, 45): tilt = tilt_deg * math.pi / 180 traj = ctrl.simulate_balancing(initial_roll=tilt, initial_pitch=0, kp=kp, kd=kp/5, duration=2.0) final_roll = abs(traj[-1][1]) if final_roll < 0.01: max_tilt = tilt_deg else: break print(f" Kp={kp:3d}: max recoverable tilt = {max_tilt}deg") print() print(" OK - Attitude balance control simulation complete")

仿真结果:

======================================================= Attitude Balance Control Simulation ======================================================= [PD Balance Controller - Kp=50, Kd=10] t=0.000s roll= +8.58deg pitch= +5.73deg tau=(-7.50,-5.00)Nm t=0.166s roll= +3.03deg pitch= +2.02deg tau=(+0.76,+0.59)Nm t=0.332s roll= +1.05deg pitch= +0.67deg tau=(+0.26,+0.20)Nm t=0.498s roll= +0.36deg pitch= +0.22deg tau=(+0.09,+0.07)Nm t=0.664s roll= +0.13deg pitch= +0.07deg tau=(+0.03,+0.02)Nm t=0.830s roll= +0.04deg pitch= +0.02deg tau=(+0.01,+0.01)Nm t=0.996s roll= +0.01deg pitch= +0.01deg tau=(+0.00,+0.00)Nm t=1.162s roll= +0.01deg pitch= +0.00deg tau=(+0.00,+0.00)Nm t=1.328s roll= +0.00deg pitch= +0.00deg tau=(+0.00,+0.00)Nm t=1.494s roll= +0.00deg pitch= +0.00deg tau=(+0.00,+0.00)Nm t=1.660s roll= +0.00deg pitch= +0.00deg tau=(+0.00,+0.00)Nm t=1.826s roll= +0.00deg pitch= +0.00deg tau=(+0.00,+0.00)Nm t=1.992s roll= +0.00deg pitch= +0.00deg tau=(+0.00,+0.00)Nm [Gain Comparison - initial roll=10deg] Kp= 20, Kd= 5: max_roll=9.99deg, final=0.0110deg, settle=0.760s Kp= 50, Kd=10: max_roll=9.99deg, final=0.0171deg, settle=0.810s Kp=100, Kd=20: max_roll=9.98deg, final=0.0347deg, settle=0.911s Kp=200, Kd=40: max_roll=9.96deg, final=0.0487deg, settle=0.969s [Disturbance Rejection] Applying 5deg lateral push at t=0... t=0.000s roll= +4.99deg tau_roll=-6.98Nm t=0.062s roll= +3.42deg tau_roll=+0.85Nm t=0.124s roll= +2.32deg tau_roll=+0.58Nm t=0.186s roll= +1.58deg tau_roll=+0.39Nm t=0.248s roll= +1.07deg tau_roll=+0.27Nm t=0.310s roll= +0.73deg tau_roll=+0.18Nm t=0.372s roll= +0.49deg tau_roll=+0.12Nm t=0.434s roll= +0.33deg tau_roll=+0.08Nm t=0.496s roll= +0.23deg tau_roll=+0.06Nm [Maximum Recoverable Tilt] Kp= 30: max recoverable tilt = 44deg Kp= 50: max recoverable tilt = 44deg Kp= 80: max recoverable tilt = 44deg Kp=120: max recoverable tilt = 44deg OK - Attitude balance control simulation complete

📊 增益调优

PD增益的选择决定了系统特性:

ωn = sqrt(Kp/I)(自然频率)
ζ = Kd / (2·sqrt(Kp·I))(阻尼比)

推荐 ζ = 0.7~1.0(轻微欠阻尼到临界阻尼),ωn = 10~30 rad/s。

💡 全身力控制

将期望力矩分配到4条腿的足端力:

  1. 计算期望全身力/力矩:Fdes, τdes
  2. 用QP求解足端力分配:min ||F||² s.t. ΣFi = Fdes, Σri×Fi = τdes
  3. 通过雅可比矩阵将足端力转换为关节力矩
  4. 用力矩控制器驱动电机

📐 全身控制架构

完整的全身控制(Whole-Body Control, WBC)架构:

  1. 任务层:定义期望的CoM轨迹、姿态、足端位置
  2. 优先级层:按重要性排序任务(平衡 > 跟踪 > 姿态)
  3. QP求解:在约束下最小化任务误差
  4. 力矩层:将足端力转换为关节力矩
min ||J1·q̇ - v1||2
s.t. J0·q̇ = v0(高优先级约束)

🔄 零空间控制

零空间方法允许在满足高优先级任务的剩余自由度中优化低优先级任务:

q̇ = J0#·v0 + (I - J0#·J0)·J1#·v1

第一项满足高优先级任务(如平衡),第二项在零空间中优化低优先级任务(如关节配置优化)。

💡 关节力矩控制

从期望足端力到关节力矩的完整映射:

τi = JiT · Fi + gi(q) + Ci(q,q̇)

其中 gi 是重力补偿项,Ci 是科里奥利补偿项。好的控制器需要前馈补偿这些非线性项。

电机级控制

📊 关键参数汇总

参数典型值范围说明
控制频率1 kHz500-2000 Hz越高动态性能越好
IMU带宽200 Hz100-500 Hz5倍过采样
力控精度5%2-10%取决于电流环精度
姿态估计精度0.5 deg0.2-2 deg取决于滤波器
CoM跟踪精度5 mm2-20 mm取决于控制器

📊 关键参数汇总

参数典型值范围说明
控制频率1 kHz500-2000 Hz越高动态性能越好
IMU带宽200 Hz100-500 Hz5倍过采样
力控精度5%2-10%取决于电流环精度
姿态估计精度0.5 deg0.2-2 deg取决于滤波器
CoM跟踪精度5 mm2-20 mm取决于控制器

📝 练习

  1. 设计一个PID控制器(增加积分项),消除稳态倾斜误差。积分项应该多大?
  2. 当机器人站在斜面上时,参考姿态应该是什么?如何自动计算?
  3. 实现QP力分配器,在平衡力矩最小化和足端力均匀分配之间加权。
  4. 仿真连续正弦扰动(模拟行走),设计前馈+反馈复合控制器。
  5. 分析Kp过大时的不稳定性,确定稳定增益范围。
🏆
平衡掌控者

掌握PD姿态控制、增益调优和全身力控制

四足机器人课程 · 第11课/30 · 返回目录