WebSocket 프로토콜
시뮬레이션 채널은 10001번 포트의 WebSocket 연결입니다. 이 채널은 사용자의 애플리케이션과 서비스 간에 실시간 제어 및 상태 루프를 전달합니다.
기본 규칙: 한 메시지에 한 가지 답변만
이 서비스는 클라이언트로부터 수신하는 각 메시지에 대해 정확히 한 번씩 상태 업데이트를 전송합니다:
투표(polling)도, 구독도, 대역 외 자발적 전송도 없습니다. 전송 주기는 전적으로 사용자의 전송 빈도에 따라 결정됩니다.
1단계 — 초기 현황 파악 (서비스의 첫 번째 메시지)
접속 시, 해당 서비스는 전체 인스턴트 ~를 담은 config, state
et 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단계 — 첫 주문을 보내세요
초기 인벤토리를 분석하여 기기의 식별자를 확인한 다음, 세션 프로필, 초기 설정 및/또는 제어 명령이 포함된 메시지를 회신하십시오:
{
"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 (제외하고
config), 단, 구성 변경으로 인해 전체 스냅샷 전송이 트리거되는 경우는 예외입니다:
{
"session_id": 7,
"inverse3": [
{
"device_id": "049D",
"state": { "cursor_position": { … }, "cursor_velocity": { … }, … },
"status": { "ready": true, "calibrated": true, … }
}
]
}
4단계 — 반복하기
주문을 보내면 → 주문 처리 현황 업데이트를 받게 됩니다. 이 과정은 귀하가 주문을 보내는 빈도에 맞춰 반복됩니다.
configure ou commands
발신 메시지의 각 장치 항목에는 두 개의 사전이 포함될 수 있습니다:
| 사전 | 역할 | 지속성 |
|---|---|---|
configure | 개별 설정: 프리셋, 베이스, 마운트, 필터, 모듈 구성 | 변경될 때까지 저장됨 |
commands | 매 사이클마다 제어: 힘, 위치, 토크 | 한 번 붙이고는 잊어버린 것들 |
Voir 세션 구성 다음에 대한
전체 키 목록은 configure, 등 제어 명령 ~에 대한
항목들 commands.
set_transform 예외를 이루다set_transform 다음 위치에 있습니다 commands, 하지만 그녀는 지속적인 — 이 서비스는
새로운 값이 전송될 때까지 마지막 값을 유지합니다. 이는 이 서비스의 기능이
씬 내 탐색에 있기 때문입니다. 즉, 카메라 이동 중에는 변환 정보를 지속적으로 전송하지만, 버튼을 두 번 누르는 사이에는 마지막 위치가 그대로 유지되기를 원하기 때문입니다.
지표 execute
모든 입장 configure ou commands 다음이 포함될 수 있음 "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 et probe_orientation 이는 제어 명령(예: Haply Hub)을 전송하지 않는 세션에 대해
모니터링 용도로만 사용되는 연결 유지(keepalive) 메시지입니다. 세션에서 이미 set_cursor_force, set_cursor_position등, 탐사선도 보내지 마세요 — 기기의 상태는 이미 각 응답에 포함되어 있습니다.
이 두 가지를 결합하면 대역폭을 낭비할 뿐만 아니라 특정 이벤트를 유발할 수도 있습니다. session-probe-dropped.
명령이 적용되지 않는 것처럼 보인다면, 필드 이름이 잘못되었을 가능성이 높습니다. 현재 이 서비스는 인식되지 않는 JSON 키를 오류 메시지 없이 무시합니다. 서비스 로그를 확인하고API 참조 문서에서 필드 이름을 다시 확인해 보십시오. 이 동작은 향후 버전에서 변경될 예정입니다.