마운트 및 워크스페이스 변환
두 가지 변환이 애플리케이션 공간에서 장치의 위치를 지정합니다. 파이프라인을 이해하면 올바른 변환을 고르는 데 도움이 됩니다.
좌표 파이프라인
| 단계 | 역할 | 설정 방법 | 영구 저장 여부 |
|---|---|---|---|
| 기준 좌표계 | 축을 재매핑합니다 (예: Z-up → Y-up) | session.configure.basis — 튜토리얼 08 (HTTP 원격 구성) | 예 |
| 마운트 변환 | 장치의 물리적 장착 오프셋 (암 위치, 회전, 스케일) | configure.mount 또는 configure.preset — 튜토리얼 08 (HTTP 원격 구성) | 예 |
| 워크스페이스 변환 | 카메라 / 장면 탐색에 따른 드리프트 | commands.set_transform — 튜토리얼 09 (WebSocket 틱별 스트리밍) | 예 (값 유지) |
마운트 변환
마운트는 장치가 물리적으로 놓인 위치를 나타냅니다. 즉 암 오프셋, 방향, 스케일을 포함합니다. 한 번 설정되며(또는 사용자가 물리적 설치 구성을 변경할 때 설정되며), 런타임에는 거의 업데이트되지 않습니다.
프리셋 (공장 기본 구성)
마운트를 직접 계산하는 대신, 이름이 지정된 프리셋을 선택하십시오:
| 프리셋 | 원점 배치 | 암 방향 |
|---|---|---|
defaults | 장치 베이스 | 전방 (암 앞면) |
arm_front | 장치 베이스 | 전방 |
arm_front_centered | 워크스페이스 중심 | 전방 |
led_front | 장치 베이스 | LED 측 전방 |
led_front_centered | 워크스페이스 중심 | LED 측 전방 |
custom | 수동 — 마운트를 직접 설정 | — |
프리셋은 마운트, 기준 좌표계, 워크스페이스 원점을 한 번에 설정합니다.
마운트 직접 설정
- WebSocket
- HTTP
{
"inverse3": [{
"device_id": "049D",
"configure": {
"mount": {
"transform": {
"position": { "x": 0.0, "y": 0.0, "z": 0.0 },
"rotation": { "x": 0.0, "y": 0.0, "z": 0.0, "w": 1.0 },
"scale": { "x": 1.0, "y": 1.0, "z": 1.0 }
}
}
}
}]
}
curl -X POST "http://localhost:10001/inverse3/049D/config/mount?session=:0" \
-H "Content-Type: application/json" \
-d '{"transform":{"position":{"x":0,"y":0,"z":0},"rotation":{"w":1,"x":0,"y":0,"z":0},"scale":{"x":1,"y":1,"z":1}}}'
mount와 preset은 상호 배타적입니다같은 메시지에 두 가지를 모두 보내면 의미가 모호하므로, 서비스가 이를 거부합니다.
둘 중 하나를 선택하십시오: 이름이 지정된 preset(마운트를 자동으로 설정함) 또는 명시적인
mount 변환.
마운트를 보낼 때는 변환을 감싸야 합니다: { "mount": { "transform": { … } } }.
스냅샷에서 마운트를 읽을 때는 감싸지 않은 평평한 구조입니다: { "mount": { "position": …, "rotation": …, "scale": … } }.
이는 의도된 설계입니다. 명령은 통합된 command_data 래퍼를 사용하고, 스냅샷은 core::transform을 직접 직렬화하기 때문입니다.
워크스페이스 변환
워크스페이스 변환은 마운트 위에 적용되는 런타임 드리프트입니다. 일반적인 사용 사례는 장면 탐색입니다. 즉 장치는 물리적으로 제자리에 둔 채 애플리케이션 뷰를 패닝, 회전 또는 확대/축소하는 것입니다.
마운트와 워크스페이스 변환은 모두 영구적입니다. 서비스는 마지막으로 보낸 값을 기억합니다. 차이는 용도와 성능에 있습니다:
- 마운트는 한 번 설정되어 그대로 유지되도록 설계되었습니다. 물리적 설치 구성을 나타내며, 드물게 업데이트되도록 최적화되어 있습니다.
- 워크스페이스 변환은 높은 빈도로 스트리밍되도록 설계되었습니다(예: 카메라 탐색 중 매 프레임). 내부 파이프라인은 이 업데이트 주기에 맞게 최적화되어 있습니다.
- WebSocket
- HTTP
{
"inverse3": [{
"device_id": "049D",
"commands": {
"set_transform": {
"transform": {
"position": { "x": 1.0, "y": 0.0, "z": 0.0 },
"rotation": { "x": 0.0, "y": 0.0, "z": 0.0, "w": 1.0 },
"scale": { "x": 1.0, "y": 1.0, "z": 1.0 }
}
}
}
}]
}
curl -X POST "http://localhost:10001/inverse3/049D/state/transform?session=:0" \
-H "Content-Type: application/json" \
-d '{"transform":{"position":{"x":1,"y":0,"z":0},"rotation":{"w":1,"x":0,"y":0,"z":0},"scale":{"x":1,"y":1,"z":1}}}'
GET은 현재 변환을 반환하고, DELETE는 항등 변환(identity)으로 재설정합니다.
마운트 또는 워크스페이스를 스케일링하면 장치가 렌더링하는 힘이 바뀝니다. 스케일링이 접촉력 계산에 사용되는 **관통 깊이(penetration depth)**에 영향을 주기 때문입니다. 예를 들어 2x 스케일은 관통 깊이를 대략 절반으로 줄입니다(장치의 이동 범위에 비해 가상 장면이 두 배 커지기 때문입니다). 따라서 결과 힘은 1x에서 느끼는 힘의 대략 절반입니다. 반대로 0.5x 스케일은 힘을 대략 두 배로 만듭니다.
이는 보통 원하는 동작입니다. 햅틱 장면을 축소하면 접촉이 자연스럽게 약해지고("더 멀리 있는" 상태입니다), 확대하면 접촉이 더 강해집니다. 사용자가 확대/축소하는 동안 강성을 일정하게 유지해야 하는 등 원하는 동작이 아니라면, 힘 이득(gain)을 역으로 스케일링하여 보정하십시오.
연속적인 이동(버블 내비게이션, 속도 제어 드리프트)이 필요하다면, 틱마다 set_transform을 수동으로 스트리밍하는 대신 Navigation 모듈을 사용하십시오. 이 모듈이 물리 연산, 햅틱 피드백, 워크스페이스 경계 처리를 대신 담당합니다.