# 🛠️ AutoCalib-Workshop: 传感器自动标定仿真车间

本项目基于 NVIDIA Isaac Sim 和 ROS 2，搭建了一个用于多传感器联合标定（Camera + LiDAR）的仿真车间环境。场景内置了 4 个全局机械式旋转激光雷达和标定相机，用于输出高精度的合成数据，以供标定算法和 SLAM 算法的测试与验证。

## 📑 目录
1. [环境依赖](#1-环境依赖)
2. [快速开始](#2-快速开始)
3. [输出的 ROS 2 话题](#3-输出的-ros-2-话题)
4. [团队协作与 Git 配置指南 (必读)](#4-团队协作与-git-配置指南-必读)
5. [开发与分支规范](#5-开发与分支规范)

---

## 1. 环境依赖

本项目不依赖 Omniverse Launcher，而是采用 **纯 Python (pip) 安装的 Isaac Sim**，便于团队在不同机器（或云端服务器）上快速复现环境。

- **操作系统:** Ubuntu 22.04
- **ROS 2:** Humble Hawksbill
- **Python 环境:** Conda (Python 3.10)
- **仿真引擎:** Isaac Sim 4.2+ (`isaacsim` pip package)

---

## 2. 快速开始

### 2.1 克隆代码
> ⚠️ **注意**：如果您是本团队的开发者，请优先完成 [第 4 节的 Git 配置指南](#4-团队协作与-git-配置指南-必读)，然后再克隆代码。

使用 HTTPS 方式克隆（无需提前配置 SSH）：
```bash
git clone https://github.com/RuiLi-Class/AutoCalib-Workshop.git 
cd AutoCalib-Workshop
```

### 2.2 配置虚拟环境与依赖
请确保机器上已安装 Miniconda 或 Anaconda。

```bash
# 创建并激活 Conda 环境
conda create -n AutoCalib_Workshop python=3.10 -y
conda activate AutoCalib_Workshop

# 安装 Isaac Sim 核心包 (基于 NVIDIA 官方源)
pip install isaacsim==4.2.0.2 isaacsim-extscache-physics==4.2.0.2 isaacsim-extscache-kit==4.2.0.2 isaacsim-extscache-kit-sdk==4.2.0.2 --extra-index-url https://pypi.nvidia.com

# 安装 boto3 botocore s3transfer 功能包，将下列脚本复制到终端执行
python -c """
import sys
import os
import glob
import subprocess

# 1. 动态获取当前的 Python 环境根目录 (例如 /home/nvidia/.../AutoCalib_Workshop)
env_base = sys.prefix

# 2. 使用通配符动态搜索 isaacsim 的 pip_prebundle 目录，无视具体版本号和系统用户名
search_pattern = os.path.join(env_base, 'lib', 'python*', 'site-packages', 'isaacsim', 'extscache', 'omni.kit.pip_archive*', 'pip_prebundle')
matches = glob.glob(search_pattern)

if not matches:
    print('❌ 错误: 在当前环境中未找到 Isaac Sim 的 pip_prebundle 缓存目录。请确认 Isaac Sim 已正确安装。')
    sys.exit(1)

prebundle_path = matches[0]
sys.path.insert(0, prebundle_path)

try:
    import botocore
    ver = botocore.__version__
    print('=========================================')
    print(f'[*] 成功动态定位到底层 botocore 路径: {prebundle_path}')
    print(f'[*] Isaac Sim 内部的 botocore 版本为: {ver}')
    print(f'[*] 正在为你安装完美匹配的 boto3=={ver} ...')
    print('=========================================')
    
    # 3. 强制安装匹配的 boto3
    subprocess.check_call([sys.executable, '-m', 'pip', 'install', f'boto3=={ver}'])
    print('[*] 🎉 修复完成！现在运行仿真脚本不会再报版本冲突错误了。')
except ImportError:
    print('❌ 错误: 找到了目录，但里面没有 botocore 模块。')
"""
```

### 2.3 运行仿真车间
每次运行前，请务必先 source ROS 2 环境，否则底层的 ROS 2 Bridge 插件将无法加载并发布话题！

```bash
# 1. 激活 ROS 2 环境 (请根据实际安装路径调整)
source /opt/ros/humble/setup.bash

# 2. 激活 Python 虚拟环境
conda activate AutoCalib_Workshop

# 3. 启动仿真脚本
python build_calibration_room.py
```

---

## 3. 输出的 ROS 2 话题

脚本成功运行后，将在局域网内广播以下 ROS 2 话题。可直接使用 RViz2 订阅查看。

💡 **RViz2 可视化提示：** 必须将 RViz2 的 Fixed Frame 设置为 `World`，方可查看到静止、规整的 3D 车间点云。

| 数据类型             | 话题名称 (Topic)                  | 说明                                               |
|------------------| -------------------------------- | -------------------------------------------------- |
| TF 树           s | `/tf`                            | 包含所有雷达与相机的全局坐标关系 (World -> Lidar_xx) |
| 图像               |`/workshop/camera/image_raw`      | 标定板对齐相机 (720p, 20Hz)                         |
| 点云 (前左)          | `/workshop/lidar/fl/pointcloud`  | 机械旋转雷达 FL (fullScan 模式聚合的 360° 全帧点云)  |
| 点云 (前右)          | `/workshop/lidar/fr/pointcloud`  | 机械旋转雷达 FR (fullScan 模式聚合的 360° 全帧点云)  |
| 点云 (后左)          | `/workshop/lidar/bl/pointcloud`  | 机械旋转雷达 BL (fullScan 模式聚合的 360° 全帧点云)  |
| 点云 (后右)          | `/workshop/lidar/br/pointcloud`  | 机械旋转雷达 BR (fullScan 模式聚合的 360° 全帧点云)  |

---

## 4. 团队协作与 Git 配置指南 (必读)

新加入的团队成员，请严格按照以下步骤配置本地 Git 环境，以便顺畅地与组织私有仓库进行交互（使用 HTTPS 方式）。

### 4.1 声明你的 Git 身份
在首次提交代码前，必须全局设置你的身份信息：

```bash
git config --global user.name "你的名字或GitHub用户名"
git config --global user.email "你注册GitHub的邮箱@example.com"
```

### 4.2 配置 HTTPS 访问 (使用 Personal Access Token)
由于 GitHub 已废弃密码验证，HTTPS 方式需要使用 **Personal Access Token (PAT)** 作为密码。请按以下步骤生成并配置 token：

1. **生成 Token：**
   - 登录 GitHub，点击右上角头像 → **Settings** → **Developer settings** → **Personal access tokens** → **Tokens (classic)**。
   - 点击 **Generate new token (classic)**。
   - 在 **Note** 中输入用途说明（例如 “Isaac Sim 开发”）。
   - 设置过期时间（建议选 90 天或自定义）。
   - 在 **Select scopes** 中勾选 **`repo`**（完全控制私有仓库）以及必要的 **`workflow`** 权限（如需操作 GitHub Actions）。
   - 点击 **Generate token**，**立即复制并保存生成的 token**（页面刷新后将无法再次查看）。

2. **配置 Git 凭据存储（避免每次输入密码）：**
   ```bash
   # 启用 Git 凭据缓存（默认缓存 15 分钟）
   git config --global credential.helper cache
   
   # 或者使用更持久的存储（凭据将明文保存在磁盘，请确保系统安全）
   git config --global credential.helper store
   ```
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

3. **首次推送时输入凭据：**
   - 执行 `git push` 等需要鉴权的操作时，Git 会提示输入用户名和密码。
   - **用户名**：输入你的 GitHub 用户名。
   - **密码**：输入刚才生成的 Personal Access Token（不是你的登录密码）。
   - 如果配置了 credential helper，后续操作将不再重复提示。

### 4.3 关键：切勿忽略 .gitignore
Isaac Sim 和 ROS 2 运行期间会产生海量的缓存文件（如 `*.usd.cache`、`__pycache__`、`log/` 等）。

**严禁将这些大文件推送到远程仓库！**  
本仓库根目录已配置好 `.gitignore` 文件，请在执行 `git add .` 时确保不要使用 `-f` 强行添加被忽略的文件。

---

## 5. 开发与分支规范

为了保证代码库的稳定，请团队成员遵守以下 Git 协作工作流。

### 5.1 分支命名规范
在创建新分支时，请使用 **前缀/功能描述** 的格式（例如：`feature/lidar-sync`）。

| 前缀       | 适用场景                               | 示例                          |
| ---------- | -------------------------------------- | ----------------------------- |
| `feature/` | **新功能**：新增传感器、模型或标定算法 | `feature/add-calibration-node` |
| `bugfix/`  | **修复错误**：解决代码逻辑、话题发布等 Bug | `bugfix/fix-tf-error`          |
| `docs/`    | **文档更新**：修改 README 或注释       | `docs/update-readme`           |
| `refactor/`| **代码重构**：优化代码结构而不改变功能 | `refactor/clean-lidar-logic`   |
| `test/`    | **测试**：增加单元测试或仿真验证脚本   | `test/calibration-verify`      |

### 5.2 保护主分支
绝对不要直接在 `main` 分支上开发和提交代码。`main` 分支仅用于存放稳定、经过测试的代码。

### 5.3 切分支干活
开始新功能开发（如编写新的标定算法节点）时，请从最新的 `main` 切出一个独立分支：
```bash
git checkout main
git pull origin main
git checkout -b feature/your_feature_name
```

### 5.4 提交与推送
```bash
git add .
git commit -m "feat: 添加了xxx功能"
git push origin feature/your_feature_name
```

### 5.5 代码合并 (Code Review)
开发完成后，请在 GitHub 页面上针对您的分支发起 **Pull Request (PR)**。由其他团队成员进行 Code Review，确认无误后再 Merge 合并入 `main` 分支。

---
