WebSocket 프로토콜
시뮬레이션 채널은 포트 10001의 WebSocket 연결입니다. 이 채널은 애플리케이션과 서비스 간에 명령어와 상태로 구성된 실시간 루프를 전송합니다.
기본 규칙: 메시지당 한 번의 답변
이 서비스는 클라이언트로부터 수신하는 각 메시지에 대해 정확히 하나의 상태 업데이트를 전송합니다:
폴링, 구독, 대역 외 푸시 기능은 없습니다. 전송 주기는 전적으로 사용자의 전송 빈도에 따라 결정됩니다.
1단계 — 초기 현황 파악 (서비스 측의 첫 번째 메시지)
연결을 설정할 때 서비스는 전체 스냅샷 MIT config, state 그리고 status 인식된 각 장치에 대해:
{
"session_id": 7,
"inverse3": [
{
"device_id": "049D",
"config": {
"type": "inverse3",
"port": "COM12",
"device_info": { "major_version": 7, "minor_version": 4, "id": "049D", "device_type": 4, "uuid": "…" },
"extended_device_id": "…",
"extended_firmware_version": "…",
"gravity_compensation": { "enabled": true, "scaling_factor": 1.0 },
"handedness": "right",
"streaming_mode": "USB",
"torque_scaling": { "enabled": true },
"home_return": { "enabled": false },
"preset": "defaults",
"basis": { "permutation": "XYZ" },
"mount": { "position": { "x": 0, "y": 0, "z": 0 }, "rotation": { "w": 1, "x": 0, "y": 0, "z": 0 }, "scale": { "x": 1, "y": 1, "z": 1 } },
"filters": {
"force_gate": { "gain": 0.3 },
"damping": { "scalar": 0.0 }
}
},
"state": {
"cursor_position": { "x": 0.0, "y": -0.12, "z": 0.15 },
"cursor_velocity": { "x": 0.0, "y": 0.0, "z": 0.0 },
"angular_position": { "a0": 0.0, "a1": 0.0, "a2": 0.0 },
"angular_velocity": { "a0": 0.0, "a1": 0.0, "a2": 0.0 },
"body_orientation": { "w": 1.0, "x": 0.0, "y": 0.0, "z": 0.0 },
"current_cursor_force": { "x": 0.0, "y": 0.0, "z": 0.0 },
"current_cursor_position": { "x": 0.0, "y": 0.0, "z": 0.0 },
"current_angular_torques": { "a0": 0.0, "a1": 0.0, "a2": 0.0 },
"current_angular_position": { "a0": 0.0, "a1": 0.0, "a2": 0.0 },
"control_domain": "cartesian",
"control_mode": "idle",
"transform": { "position": { "x": 0, "y": 0, "z": 0 }, "rotation": { "w": 1, "x": 0, "y": 0, "z": 0 }, "scale": { "x": 1, "y": 1, "z": 1 } },
"transform_velocity": { "position": { "x": 0, "y": 0, "z": 0 }, "rotation": { "w": 1, "x": 0, "y": 0, "z": 0 }, "scale": { "x": 0, "y": 0, "z": 0 } }
},
"status": {
"calibrated": true,
"in_use": false,
"power_supply": true,
"ready": true,
"started": true
}
}
],
"verse_grip": [],
"wireless_verse_grip": []
}
이 세 블록은 각각 다른 갱신 주기를 가지고 있습니다:
| 차단 | 포함 사항 | 변경 빈도 |
|---|---|---|
config | 펌웨어 정보, 프리셋, 기본 설정, 몽타주, 필터 | 드물게, 명시적인 구성 변경이 있을 때만 발생합니다. |
state | 위치, 속도, 힘, 방향, 변환 | 매 틱마다 (고주파) |
status | 준비됨, 보정됨, 전원 공급 중, 사용 중 | 가끔 (낮은 빈도) |
2단계 — 첫 번째 명령어 전송
초기 현황 정보를 분석하여 기기 ID를 확인하십시오. 그런 다음 세션 프로필, 필요한 경우 초기 구성 및/또는 제어 명령이 포함된 메시지를 전송하십시오:
{
"session": {
"configure": {
"profile": { "name": "co.haply.inverse.tutorials:hello-floor" }
}
},
"inverse3": [
{
"device_id": "049D",
"configure": {
"preset": { "preset": "arm_front_centered" }
},
"commands": {
"set_cursor_force": { "vector": { "x": 0.0, "y": 0.0, "z": 0.0 } }
}
}
]
}
3단계 — 후속 상태 업데이트
첫 번째 교환이 끝난 후, 이 서비스는 더 이상 state + status (ohne config), 단, 구성 변경으로 인해 전체 스냅샷 푸시가 트리거되는 경우는 예외입니다:
{
"session_id": 7,
"inverse3": [
{
"device_id": "049D",
"state": { "cursor_position": { … }, "cursor_velocity": { … }, … },
"status": { "ready": true, "calibrated": true, … }
}
]
}
4단계 — 반복하기
명령을 전송하면 → 상태 업데이트를 받게 됩니다. 루프는 사용자의 전송 주파수에 맞춰 계속 실행됩니다.
configure vs. commands
보내는 메시지에 포함된 각 기기 항목에는 두 개의 맵이 포함될 수 있습니다:
| 지도 | Zweck | 지속성 |
|---|---|---|
configure | 일회성 설정: 프리셋, 기본 설정, 설치, 필터, 모듈 구성 | 변경될 때까지 저장됩니다 |
commands | 틱당 제어: 힘, 위치, 토크 | 한 번 사용하고 나면 잊어버리게 된다 |
다음의 전체 목록은 configure-키를 다음에서 확인하실 수 있습니다 세션 구성, 그리고 그 commands-다음 항목 아래 제어 명령어.
set_transform 는 특수한 경우입니다set_transform ~에 속한다 commands, 하지만 지속적인 — 이 서비스는 사용자가 새로운 값을 전송할 때까지 마지막 값을 유지합니다. 이는 이 서비스의 목적이 장면 이동에 있기 때문입니다. 즉, 카메라 이동 중에 변환을 스트리밍하되, 입력 사이에는 마지막 위치가 유지되기를 원하기 때문입니다.
Das Flag execute
모든 항목 configure 또는 commands kann "execute": false 포함되어 있어, 해당 서비스가 페이로드를 파싱 및 유효성 검사, 그것을 적용하지 않고.
{
"inverse3": [{
"device_id": "049D",
"configure": {
"preset": { "preset": "arm_front", "execute": true },
"damping": { "scalar": 0.0, "execute": false }
}
}]
}
이 기능은 다음 경우에 유용합니다. 반사 기반 직렬화기 (예: JsonUtility (Unity에서), 항상 모든 필드를 출력하는 경우: 사용하지 않는 항목은 execute: false, 실제 설정을 덮어쓰지 않도록 하기 위해서입니다. 기본값은 true — 플래그를 생략하면 “일반적으로 적용”함을 의미합니다.
경고
probe_position 그리고 probe_orientation 이는 제어 명령을 전송하지 않는 세션(예: Haply 허브)에 대한 순수한 모니터링용 키팔라이브입니다. 세션이 이미 set_cursor_force, set_cursor_position 등등을 전송합니다, 추가 샘플을 보내지 마십시오 — 기기 상태는 어차피 모든 응답에 포함되어 있습니다. 두 가지를 동시에 전송하면 대역폭을 낭비할 뿐만 아니라 session-probe-dropped-이벤트 트리거하기.
명령이 아무런 효과가 없는 것처럼 보인다면, 필드 이름이 잘못된 것일 가능성이 높습니다. 현재 이 서비스는 알 수 없는 JSON 키를 오류 메시지 없이 무시합니다. 서비스 로그를 확인하고 필드 이름을 API 참조 문서와 대조해 보십시오. 이 동작은 향후 버전에서 변경될 예정입니다.