# 真实车间运控参数标定

这个目录只处理运控参数标定的车间电脑侧边界。真实车辆动作仍由 Windows 车端 agent 执行，车间电脑负责下发评估任务、采集运控评估数据、底盘响应和外部真值轨迹，然后把这些文件写入 `dataset_index.yaml`。

## 数据流

```text
车间电脑总控
  -> 车端 agent 执行运控评估任务
  -> 车间电脑采集 control_eval / reference_signal / chassis_response / truth_trajectory
  -> dataset_index_to_site_data_input.py 生成 site_data_input.yaml
  -> control_calibration_service 或离线算法读取 data_input.*
  -> 算法输出 control/estimated_params.yaml
  -> stage_control_parameter_commit.py 生成 pending_control_commit.yaml
  -> approve_control_pending_parameters.py 生成 approved_control_parameter_handoff.yaml
```

## 数据文件

固定 CSV 协议见：

```bash
src/site_deployment/workshop_control_calibration_real/control_csv_contract.md
```

最小数据输入包括：

- `control/control_eval.csv`
- `control/reference_signal.csv`
- `control/chassis_response.csv`
- `external/truth_trajectory.csv`

这些文件会写到 `dataset_index.yaml` 的 `data_inputs.control.*`，再自动转换为 `control_calibration_service` 的 `data_input.*` 参数。

控制器约束：

- PID 可以用于速度、航向、角速度、舵角等回路。
- `controller_algorithm: pid` 时，必须在算法输出中填写明确的 `control_role` 和 `loop_name`。
- `control_axis: combined` 且使用 PID 时，必须使用 `pid_loops` 分别列出每个 PID 回路，不能用一个含糊的 PID 表达横纵向联合参数。

## Smoke

生成一套合成运控数据并写入数据集索引：

```bash
python3 src/site_deployment/workshop_control_calibration_real/replay_control_smoke.py \
  --session-id control_smoke_001 \
  --site-id site_a \
  --vehicle-id agv_001 \
  --session-dir /tmp/agv_control_smoke \
  --dataset-index-path /tmp/agv_control_smoke/dataset_index.yaml \
  --control-axis combined \
  --controller-algorithm mpc
```

生成 `site_data_input.yaml`：

```bash
python3 src/deployment/tools/finalize_site_session.py \
  --site-profile src/deployment/profiles/site_template.yaml \
  --session-dir /tmp/agv_control_smoke \
  --dataset-index /tmp/agv_control_smoke/dataset_index.yaml \
  --output /tmp/agv_control_smoke/site_data_input.yaml \
  --no-strict
```

## 真实采集

车间电脑侧可以直接订阅现场 ROS 话题并落盘：

```bash
python3 src/site_deployment/workshop_control_calibration_real/capture_control_session.py \
  --config /data/agv_calib/site_a/control_data.yaml \
  --session-id session_001 \
  --site-id site_a \
  --vehicle-id agv_001 \
  --session-dir /data/agv_calib/site_a/session_001 \
  --dataset-index-path /data/agv_calib/site_a/session_001/dataset_index.yaml \
  --duration-sec 60.0
```

默认订阅：

- `/control/telemetry`
- `/chassis/telemetry`
- `/workshop/external_localization/vehicle/pose`

如果现场话题不同，可以通过 `--control-telemetry-topic`、`--chassis-telemetry-topic`、`--external-pose-topic` 覆盖。

## 评估任务 profile

现场推荐评估动作已经固化在：

```bash
src/site_deployment/workshop_control_calibration_real/config/control_evaluation_profile.yaml
```

该文件按 `ackermann`、`differential`、`single_steer_wheel`、`multi_steer_wheel` 拆分，固定每类底盘建议跑的轨迹跟踪、速度阶跃、加减速和停车精度任务。每个任务同时声明 `control_axis`、`controller_algorithm`、`control_role` 和必要的外部真值质量门限。

校验并查看摘要：

```bash
python3 src/site_deployment/workshop_control_calibration_real/control_evaluation_profile.py \
  --profile src/site_deployment/workshop_control_calibration_real/config/control_evaluation_profile.yaml
```

导出总控可接收的 `requested_tasks` 片段：

```bash
python3 src/site_deployment/workshop_control_calibration_real/control_evaluation_profile.py \
  --profile src/site_deployment/workshop_control_calibration_real/config/control_evaluation_profile.yaml \
  --chassis-type differential \
  --format requested_tasks \
  --output /data/agv_calib/site_a/control_requested_tasks.yaml
```

导出的任务片段和 `RequestedCalibrationTask` 对齐。后续接入总控时，可以把这些运控评估拆成多个阶段，而不是只跑一个默认轨迹。

按 profile 下发运控评估任务，并同步采集现场数据：

```bash
python3 src/site_deployment/workshop_control_calibration_real/run_control_profile_capture.py \
  --config /data/agv_calib/site_a/control_data.yaml \
  --evaluation-profile src/site_deployment/workshop_control_calibration_real/config/control_evaluation_profile.yaml \
  --chassis-type differential \
  --session-id session_001 \
  --site-id site_a \
  --vehicle-id agv_001 \
  --session-dir /data/agv_calib/site_a/session_001 \
  --dataset-index-path /data/agv_calib/site_a/session_001/dataset_index.yaml
```

如果只想跑某一个评估任务，可以增加 `--task-code control.differential.speed_step_low`。

本地 smoke 验证 profile runner：

```bash
python3 src/site_deployment/workshop_control_calibration_real/smoke_test_control_profile_capture.py \
  --chassis-type differential \
  --task-code control.differential.speed_step_low
```

这个 smoke 会启动假的运控 action server、运控遥测、底盘遥测和外部真值话题，只验证车间电脑侧的“下发任务、采集落盘、写入 dataset_index”链路。

总控 smoke 已支持直接读取运控评估 profile：

```bash
python3 src/simulation/tools/smoke_test_workshop_orchestrator.py \
  --tasks external,chassis,control,sensor_intrinsic \
  --chassis-profile-type differential \
  --control-evaluation-profile src/site_deployment/workshop_control_calibration_real/config/control_evaluation_profile.yaml
```

也可以从现场 profile 自动读取：

```bash
python3 src/simulation/tools/smoke_test_workshop_orchestrator.py \
  --site-profile src/deployment/profiles/site_template.yaml \
  --tasks external,chassis,control,sensor_intrinsic
```

## 参数结果交接

算法工程师应输出：

```bash
/tmp/agv_control_smoke/control/estimated_params.yaml
```

格式模板：

```bash
src/site_deployment/workshop_control_calibration_real/config/control_estimated_params_template.yaml
```

按底盘类型拆好的默认模板：

```bash
src/site_deployment/workshop_control_calibration_real/config/control_estimated_params_differential_template.yaml
src/site_deployment/workshop_control_calibration_real/config/control_estimated_params_single_steer_wheel_template.yaml
src/site_deployment/workshop_control_calibration_real/config/control_estimated_params_multi_steer_wheel_template.yaml
src/site_deployment/workshop_control_calibration_real/config/control_estimated_params_ackermann_template.yaml
```

每类底盘推荐标定哪些控制回路见：

```bash
src/site_deployment/workshop_control_calibration_real/config/control_role_profiles.yaml
```

生成待审批包：

```bash
python3 src/site_deployment/workshop_control_calibration_real/stage_control_parameter_commit.py \
  --dataset-index /tmp/agv_control_smoke/dataset_index.yaml \
  --estimated-params /tmp/agv_control_smoke/control/estimated_params.yaml
```

审批并生成车间电脑侧交接包：

```bash
python3 src/site_deployment/workshop_control_calibration_real/approve_control_pending_parameters.py \
  /tmp/agv_control_smoke/control/pending_control_commit.yaml \
  --operator-id operator_001
```

当前交接包只表示“车间电脑侧已经审批通过，等待车端写参适配器处理”。车端写参实现暂不在本目录内处理。
