跳转至

Kp / Kd 参数说明

在仿真 (Isaac Gym)

PD 控制器:

\[\tau = K_p e_p + K_d e_v\]
  • \(K_p\):刚度
  • \(K_d\):阻尼
  • \(e_p\):位置误差
  • \(e_v\):速度误差

在真实机器人执行器

PID 控制器:

\[I = P_p P_v e_p + P_v e_v\]
\[\tau' = g I K_t = g(P_p P_v K_t e_p + P_v K_t e_v)\]
  • \(P_p\):位置环比例参数
  • \(P_v\):速度环比例参数
  • \(g\):齿轮比
  • \(K_t\):扭矩常数

Sim-to-Real 参数对齐关系

当满足 \(\tau = \tau'\) 时,仿真与实机参数的对应关系如下:

\[K_p = g P_p P_v K_t\]
\[K_d = g P_v K_t\]

由此推导出实机配置参数:

\[P_v = \frac{K_d}{K_t \cdot g}\]
\[P_p = \frac{K_p}{K_d}\]

关节逻辑代码片段

void RealRobot::computeJointPdParams() {
  joint_Kp_s = joint_Kp_;
  joint_Kd_s = joint_Kd_;

  for (int i = 0; i < robot_dof_nums_; i++) {
    if (bAdam_u_) {
      // Adam-U 逻辑
      joint_Kp_(i) = joint_Kp_(i) / joint_Kd_(i);
      joint_Kd_(i) = joint_Kd_(i) / PConfig::getInstance().kdScale()(i);
    } else {
      // Adam 逻辑:踝关节特殊处理
      if (i == kAnkleJoint1 || i == kAnkleJoint2) {
        joint_Kp_(i) = joint_Kp_(i - 1);
        joint_Kd_(i) = joint_Kd_(i - 1);
      } else {
        joint_Kp_(i) = joint_Kp_(i) / joint_Kd_(i);
        joint_Kd_(i) = joint_Kd_(i) / PConfig::getInstance().kdScale()(i);
      }
    }
  }

  std::cout << "joint_Kp: " << joint_Kp_.transpose() << std::endl;
  std::cout << "joint_Kd: " << joint_Kd_.transpose() << std::endl;
}