Files
duru_pcd_viewer/ROS2_이관_체크리스트.md
T
Dongubak beb4182f04 macos-native: clean branch for cloning and building the Tauri desktop app
Orphan branch with no history — includes the Tauri shell (src-tauri/) and
vendored Three.js (vendor/) that were never pushed before, so a fresh clone
can actually build the native app. Drops the large .pcd sample captures and
editor cruft (.obsidian, .DS_Store); they aren't needed to build or run the
app (point clouds load via drag-and-drop, not bundling).
2026-08-22 02:21:38 +09:00

253 lines
10 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# ROS2 PC 이관 체크리스트
이 대시보드는 **Mac에서 만들고, 가짜(mock) rosbridge 서버로 검증**했습니다.
FAST-LIVO2가 실제로 도는 ROS 2 Humble PC로 옮겨서 마무리해야 할 것들을 정리합니다.
사용법 자체는 `PCD_Viewer_가이드.md`에 있습니다. 이 문서는 **이관과 남은 작업**만 다룹니다.
---
## 0. 지금 어디까지 확실한가
정직하게 갈라두면 실기에서 삽질이 줄어듭니다.
| 항목 | 상태 |
|---|---|
| UI·측정(거리/포지션)·파일 로드 | ✅ 실제 PCD로 확인 |
| rosbridge 프로토콜, 토픽 자동 바인딩, 누적, 카메라, 텔레메트리 | ⚠️ **목 서버로만 확인** — 실기 미검증 |
| 라이브 맵 위 측정 | ⚠️ 목 서버 데이터로 확인 |
| 복셀 다운샘플 누적 + 재색인 | ⚠️ 목 서버로 확인 (25초 세션에서 유지율 41%→20%로 수렴) |
| 오프라인(CDN 차단) 구동 | ✅ unpkg 차단 상태로 확인 (3절) |
| 실제 FAST-LIVO2 토픽 이름·타입·필드 | ❌ **미확인 — 4절에서 기록할 것** |
| 실제 환경에서의 복셀 유지율·적정 크기 | ❌ 미확인 — 실기에서 6절 보고 조정 |
---
## 1. 옮길 파일
```
pcd_viewer.html ← 대시보드 본체 (이거 하나면 동작)
PCD_Viewer_가이드.md ← 사용법
ROS2_이관_체크리스트.md ← 이 문서
tools/mock-rosbridge.mjs ← 로봇 없이 테스트용 (선택, Node 필요)
```
`.pcd`는 옮길 필요 없습니다(용량만 큼). 실시간으로 볼 거고, 파일이 필요하면 그 PC에서 생성됩니다.
```bash
scp -r ~/Documents/"pcd viwer" user@ros2-pc:~/pcd_dashboard
```
---
## 2. 호스트 세팅
### 2-1. rosbridge
```bash
sudo apt install ros-humble-rosbridge-suite
ros2 launch rosbridge_server rosbridge_websocket_launch.xml # :9090
```
- `rosapi` 노드가 함께 떠야 합니다(위 launch에 포함). 토픽 목록을 읽는 데 씁니다.
- 확인: `ros2 node list | grep -E "rosbridge|rosapi"`
### 2-2. 뷰어 서빙
```bash
cd ~/pcd_dashboard
python3 -m http.server 8000 # 0.0.0.0 바인딩(기본) → 다른 PC에서도 접속 가능
```
### 2-3. 다른 PC에서 볼 때
- 브라우저: `http://<호스트IP>:8000/pcd_viewer.html`
- LIVE 주소: `ws://<호스트IP>:9090`**localhost 아님**
- 방화벽: 8000, 9090 열기
```bash
sudo ufw allow 8000/tcp && sudo ufw allow 9090/tcp
```
> **보안**: rosbridge는 인증이 없습니다. 붙는 사람이 토픽을 발행할 수도 있습니다.
> 신뢰된 LAN 안에서만 쓰고, 공인 IP로 열지 마세요.
---
## 3. 로봇 PC가 오프라인이면 (Three.js 로컬화)
기본값은 CDN(unpkg)에서 Three.js를 받습니다. 인터넷이 없으면 뷰어가 아예 안 뜹니다.
**아래 절차는 unpkg를 차단한 상태에서 실제로 검증했습니다.**
인터넷 되는 PC에서 받아서 같이 옮기면 됩니다:
```bash
cd ~/pcd_dashboard
mkdir -p vendor/three/controls vendor/three/loaders
curl -L -o vendor/three/three.module.js https://unpkg.com/three@0.160.0/build/three.module.js
curl -L -o vendor/three/controls/OrbitControls.js https://unpkg.com/three@0.160.0/examples/jsm/controls/OrbitControls.js
curl -L -o vendor/three/loaders/PCDLoader.js https://unpkg.com/three@0.160.0/examples/jsm/loaders/PCDLoader.js
```
`pcd_viewer.html`의 importmap을 이렇게 고칩니다 (디렉터리 구조를 지켜야 addon들이 `three`를 찾습니다):
```html
<script type="importmap">
{
"imports": {
"three": "./vendor/three/three.module.js",
"three/addons/": "./vendor/three/"
}
}
</script>
```
---
## 4. 첫 연결 — 순서와 기록할 것
### 4-1. 먼저 ROS 쪽에서 확인
```bash
ros2 topic list -t # 이름과 타입을 함께
ros2 topic hz /cloud_registered # 발행 주파수
ros2 topic echo /cloud_registered --field fields --once # x/y/z/rgb/intensity 구성
ros2 topic echo /cloud_registered --field width --once # 스캔당 점 개수
```
### 4-2. 여기에 실제 값을 적어두세요 (지금은 추정)
| 슬롯 | 뷰어가 기대하는 타입 | 실제 토픽 이름 | 실제 타입 | 비고 |
|---|---|---|---|---|
| CLOUD | `sensor_msgs/msg/PointCloud2` | (기록) | | 점/스캔: ___ , Hz: ___ |
| ODOM | `nav_msgs/msg/Odometry` | (기록) | | |
| PATH | `nav_msgs/msg/Path` | (기록) | | 없을 수도 있음 |
| IMAGE | `sensor_msgs/msg/CompressedImage` | (기록) | | raw `Image`면 5-1 |
> 뷰어는 **이름이 아니라 타입으로** 토픽을 찾습니다. 이름이 달라도 타입만 맞으면 드롭다운에 뜹니다.
> 자동 선택이 틀리면 드롭다운에서 바꾸면 됩니다.
### 4-3. 대시보드 연결
1. 브라우저 → LIVE 칸에 `ws://localhost:9090` → `연결`
2. **토픽 4칸이 채워지는지** 확인
3. **TELEMETRY의 Hz가 뜨는지** 확인 (``면 그 토픽은 조용하다는 뜻)
4. 맵이 자라는지, `F`로 뷰가 맞는지
5. 거리 모드로 라이브 맵 위 두 점 측정
---
## 5. 실기에서 걸릴 만한 것들
### 5-1. 카메라가 안 뜬다 — 가능성 높음
지금은 `CompressedImage`만 받습니다. FAST-LIVO2는 `/origin_img`를 **raw `sensor_msgs/msg/Image`**로
낼 수 있고, 그러면 IMAGE 드롭다운이 비어 있습니다.
우회(권장 — 대역폭도 훨씬 유리):
```bash
ros2 run image_transport republish raw in:=/origin_img compressed out:=/origin_img/compressed
```
근본 해결: 뷰어에 raw Image 디코딩 추가 (7절).
### 5-2. 클라우드에 rgb가 없다
`rgb`가 없으면 `intensity`를 회색 계조로 씁니다. 둘 다 없으면 균일 회색입니다.
FAST-LIVO2는 컬러 맵을 내므로 보통 `rgb`가 있지만, 설정에 따라 다릅니다.
### 5-3. 대역폭
전송은 JSON + base64라 바이너리의 약 1.33배입니다. 점당 16바이트면 **점당 약 21바이트**.
```
대역폭 ≈ 점/스캔 × Hz × 21 B/점
예) 10,000 × 10 Hz × 21 B ≈ 2.1 MB/s ≈ 17 Mbps
30,000 × 10 Hz × 21 B ≈ 6.4 MB/s ≈ 51 Mbps
```
같은 PC(localhost)나 유선 LAN이면 괜찮고, **Wi-Fi로 원격에서 보면 빠듯**합니다.
### 5-4. `rosapi 응답이 없습니다`
rosbridge는 떴는데 rosapi가 없는 경우입니다. launch 파일을 확인하거나
`ros2 run rosapi rosapi_node`를 따로 띄우세요.
---
## 6. 누적 버퍼와 복셀 크기 정하기
`/cloud_registered`는 **매 스캔을 통째로** 내보내고 스캔끼리 공간이 크게 겹칩니다.
그대로 쌓으면 6M 버퍼가 **1분 남짓**에 찹니다(1만 점 × 10Hz 기준).
그래서 **복셀 누적이 기본으로 켜져 있습니다**(5cm). 이미 점이 있는 복셀의 점은 버리므로,
누적량이 **돌린 시간이 아니라 본 공간 크기**에 비례합니다. 원리는 가이드 6-3절.
### 6-1. 실기에서 할 일: 유지율 보고 크기 정하기
TELEMETRY의 **복셀** 행에 `5cm · 유지 18.0%`처럼 나옵니다.
| 유지율이 | 뜻 | 조치 |
|---|---|---|
| 계속 50~100% | 복셀이 너무 작아 사실상 원본을 쌓는 중 | 크기를 키우세요 |
| 시간이 갈수록 하강·수렴 | 정상. 새로 보는 공간만 늘고 있음 | 그대로 |
| 5% 이하인데 맵이 성김 | 복셀이 너무 큼 | 줄이세요 |
크기를 바꾸면 **이미 쌓인 점도 즉시 재색인**됩니다(키우면 그 자리에서 솎임).
목 서버 기준 20cm → 50cm 재색인에서 108,690점 → 7,799점(7.2%)으로 줄었습니다.
### 6-2. 그래도 부족하면
```
버퍼가 차는 시간 ≈ LIVE_CAP / (점/스캔 × Hz × 유지율)
```
- **LIVE_CAP 상향**: `pcd_viewer.html`의 `const LIVE_CAP = 6_000_000;` → 예: `40_000_000`.
메모리는 **점당 약 15바이트**(40M ≈ 600MB). 좋은 PC면 감당됩니다.
- **누적 맵 토픽 구독**: FAST-LIVO2가 누적 맵 토픽(`/cloud_map` 등)을 낸다면,
그걸 물리고 **매번 통째로 교체**하는 방식이 더 쌀 수 있습니다. → 4-2에서 실제 토픽 확인.
> 복셀을 **끄면** 원본을 그대로 쌓습니다. 짧고 고밀도인 계측용입니다. 버퍼는 빨리 찹니다.
> 가득 차면 조용히 버리지 않고 **"가득 참"이라고 말하고 멈춥니다.**
---
## 7. 남은 개발 항목 (우선순위 순)
> **완료**: 복셀 다운샘플 누적(크기 슬라이더 + 재색인 포함). 6절 참고.
> 다만 복셀 인덱스는 `Set`이라 점 하나당 수십 바이트를 씁니다. 유지 점수가 수백만을
> 넘어가면 타입드 배열 해시로 바꾸는 게 다음 최적화입니다(지금은 필요 없을 가능성이 큼).
### 7-1. raw `sensor_msgs/msg/Image` 지원
- `CompressedImage`가 없는 환경 대비(5-1). rgb8/bgr8/mono8 → canvas ImageData.
- 대역폭이 크므로 throttle 필수.
### 7-2. CBOR 전송
- `subscribe`에 `compression: 'cbor'` + CBOR 디코더. base64 오버헤드(1.33배)를 없앱니다.
- 원격에서 볼 때만 의미 있음. localhost면 후순위.
### 7-3. 라이브 맵 저장
- 지금은 누적본을 **내보낼 수 없습니다**. FAST-LIVO2가 자체 저장하므로 필수는 아니지만,
"지금 화면의 이 맵"을 `.pcd`로 떨구는 버튼이 있으면 계측 워크플로에 유용합니다.
### 7-4. GPS 지오레퍼런싱 (위경도 표시)
- 가이드 8절 참고. 실시간이 붙었으므로 `sensor_msgs/msg/NavSatFix` 슬롯을 하나 더 두면
세션 중에 궤적↔GPS 정합을 계산할 수 있습니다.
### 7-5. 기타 후보
- 화면 하단 미니맵(위에서 본 궤적), 뷰 프리셋(Top/Front/Side)
- 여러 세션 비교(파일 + 라이브 동시 표시) — 지금은 활성 클라우드가 하나뿐입니다
---
## 8. 로봇 없이 테스트하기 (mock)
FAST-LIVO2를 안 켜고 대시보드만 확인할 때 씁니다. **Node 18+ 필요**(의존성 없음).
```bash
node tools/mock-rosbridge.mjs # ws://localhost:9090
```
가짜로 내보내는 것: `/cloud_registered`(10Hz, 컬러 PointCloud2), `/aft_mapped_to_init`(20Hz),
`/path`(5Hz), `/origin_img`(5Hz, PNG). 뷰어에서 `ws://localhost:9090`으로 연결하면
실제와 같은 경로로 동작합니다.
> 이 목 서버는 **개발용**입니다. 실기 검증을 대신하지 못합니다 — 실제 토픽 이름·필드·주파수는
> 4절에서 반드시 확인하세요.
---
## 9. 이관 순서 요약
1. 파일 복사 (1절)
2. 오프라인이면 Three.js 로컬화 (3절)
3. rosbridge + http.server 실행 (2절)
4. `ros2 topic list -t`로 **실제 토픽 기록** (4-2)
5. 대시보드 연결 → 4칸·Hz·맵 성장 확인 (4-3)
6. 카메라 안 뜨면 republish (5-1)
7. **복셀 유지율 확인** → 크기 조정. 그래도 모자라면 LIVE_CAP 상향 (6절)