# Pinocchio Dual Data

> 当 wbc_pbr_lifecycle_controller 中运动学（computeFK/wbcSolve）和动力学（computePbrTau）共用同一个 pinocchio::Data 导致 rnea 数据污染时，必须采用双 Data 隔离方案。触发关键词：pinocchio Data 污染、rnea 错误、运动学动力学隔离、双 data、方案1.

- Skill: `frankjie09/pinocchio-dual-data` (Agent Skill)
- Install (CLI): `npx skillmds@latest add frankjie09/pinocchio-dual-data`
- Raw SKILL.md: https://api.skillmd.com/api/skills/frankjie09/pinocchio-dual-data/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Coding & Dev Tools
- Author: FrankJIE09 (https://skillmd.com/u/frankjie09)
- Updated: 2026-09-22
- Page: https://skillmd.com/skills/frankjie09/pinocchio-dual-data

---


# Pinocchio 运动学与动力学双 Data 隔离（方案 1）

## 问题

`pinocchio::Data` 内部有共享的工作缓冲区（`data.a[]`, `data.v[]`），不同算法共用同一 `data` 对象时会产生交叉污染：

```
computeFK（运动学）:
  computeJointJacobians(q) → 在 data.a[]/data.v[] 中留临时中间值

computePbrTau（动力学）:
  rnea(data, q, v, a) → 读到上一步的脏残留 → 结果错误（如重力 +30% 偏差）
```

## 解决方案 1：双 Data 对象物理隔离

**原则**：运动学管线和动力学管线分别拥有独立的 `pinocchio::Data` 对象，互不干扰。

```cpp
// 头文件
pinocchio::Data pin_data_;      // 运动学专用：computeFK, wbcSolve
pinocchio::Data pin_data_dyn_;  // 动力学专用：computePbrTau
```

### 初始化

```cpp
// on_configure 或 initTargets 中
pin_data_ = pinocchio::Data(pin_model_);
pin_data_dyn_ = pinocchio::Data(pin_model_);
```

### computeFK / wbcSolve

```cpp
// computeFK：用 pin_data_，不做改动
pinocchio::framesForwardKinematics(pin_model_, pin_data_, q_full);
pinocchio::updateFramePlacements(pin_model_, pin_data_);
pinocchio::computeJointJacobians(pin_model_, pin_data_, q_full);

// wbcSolve：用 pin_data_，读取 FK 结果
const auto& J_task = pin_data_.J;  // FK 计算的雅可比
```

### computePbrTau

```cpp
// 用 pin_data_dyn_，不会被 computeFK 污染
pinocchio::rnea(pin_model_, pin_data_dyn_, q_full, v_ref, a_ref);
// 或用 nonLinearEffects + crba 两步：
// pinocchio::nonLinearEffects(pin_model_, pin_data_dyn_, q_full, v_ref);
// pinocchio::crba(pin_model_, pin_data_dyn_, q_full);
```

## 检查清单

- [ ] `pin_data_dyn_` 仅在 `computePbrTau`（及 `initDob`）中使用
- [ ] `pin_data_` 仅在 `computeFK` / `wbcSolve` / `initTargets` 中使用
- [ ] 两个 `Data` 对象都从同一个 `pin_model_` 创建
- [ ] 初始化在同一生命周期阶段完成（`on_configure` 或 `initTargets`）

## 禁止做法

```cpp
// ❌ 禁止：运动学函数中使用 pin_data_dyn_
computeFK() {
  pinocchio::computeJointJacobians(pin_model_, pin_data_dyn_, q);  // 污染动力学 data
}

// ❌ 禁止：动力学函数中使用 pin_data_
computePbrTau() {
  pinocchio::rnea(pin_model_, pin_data_, q, v, a);  // 读到运动学残留
}
```

