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).
This commit is contained in:
@@ -0,0 +1,252 @@
|
||||
# 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절)
|
||||
Reference in New Issue
Block a user