주요 내용으로 이동

WebSocket 프로토콜

시뮬레이션 채널은포트 10001에 설정된 WebSocket 연결입니다. 이 채널은 애플리케이션과 서비스 간의 실시간 명령/상태 루프를 처리합니다.

핵심 규칙: 각 메시지에 대해 하나의 응답이 발생합니다.​

서비스는 클라이언트에서 전송해 온각 메시지에 대해정확히한 번씩 상태 업데이트를 전송합니다:

폴링, 구독 또는 아웃오브밴드 푸시 기능은 없습니다. 업데이트 주기는 전적으로 사용자의 전송 속도에 따라 결정됩니다.


1단계——초기 목록 (서비스에서 전송한 첫 번째 메시지)​

연결 시, 서비스는 감지된 각 기기에 대해 하나씩전체 스냅샷,여기에는 다음이 포함되어 있습니다. 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(제외) config):

{
"session_id": 7,
"inverse3": [
{
"device_id": "049D",
"state": { "cursor_position": { … }, "cursor_velocity": { … }, … },
"status": { "ready": true, "calibrated": true, … }
}
]
}

4단계 — 반복​

명령 전송 → 상태 업데이트 수신. 이 과정은 전송 속도에 따라 반복됩니다.


configure 와 commands​

보낸 메시지 내에서 각 기기 항목은 두 개의 매핑을 포함할 수 있습니다:

매핑용도지속성
configure일회성 설정: 프리셋, 베이스, 마운트, 필터, 모듈 구성변경될 때까지 유효함
commands주기별 제어: 힘, 위치, 토크한 번만 적용되며, 그 후에는 효력이 상실됩니다.

관련 configure 키의 전체 목록은 다음을 참조하십시오. 세션 구성;관련 commands 항목에 대해서는 다음을 참조하십시오. 제어 명령。

비고
set_transform 예외적인 경우입니다

set_transform ~에 위치한 commands 아래, 하지만 그것은지속적인——이 서비스는 사용자가 새로운 값을 전송할 때까지 마지막 값을 유지합니다. 이는 장면 이동 기능을 위한 것이기 때문입니다. 즉, 카메라가 이동할 때 변환 값을 스트리밍 방식으로 전송하지만, 두 번의 키 입력 사이에는 마지막 위치를 유지하기를 원하기 때문입니다.


execute 로고​

어떤 configure 또는 commands 모든 항목에는 다음이 포함될 수 있습니다 "execute": false,서비스를분석 및 검증부하를 가하되 이를 적용하지는 않는다.

{
"inverse3": [{
"device_id": "049D",
"configure": {
"preset": { "preset": "arm_front", "execute": true },
"damping": { "scalar": 0.0, "execute": false }
}
}]
}

이는반사 기반 직렬화기(예를 들어 Unity의 JsonUtility)매우 유용합니다. 이러한 직렬화기는 항상 모든 필드를 출력합니다: 사용되지 않는 항목을 execute: false,이렇게 하면 실제 설정을 덮어쓰지 않게 됩니다. 기본값은 true——이 표시가 생략된 경우 “정상 적용”을 의미합니다.


경고​

이미 명령을 전송 중인 경우, 더 이상 탐색을 수행하지 마십시오.

probe_position 와 probe_orientation 단순히 모니터링을 위한 연결 유지 메시지이며, 제어 명령을 전송하지 않는 세션(예: Haply Hub)에 적용됩니다. 세션에서 이미 전송을 시작한 경우 set_cursor_force、set_cursor_position 등과 같은 명령어,더 이상 탐지 메시지를 동시에 보내지 마십시오.——장비 상태 정보는 각 응답에 이미 포함되어 있습니다. 두 가지를 동시에 사용하면 대역폭을 낭비할 뿐만 아니라, 다음을 유발할 수도 있습니다. session-probe-dropped 사건.

알 수 없는 키는 아무런 메시지 없이 무시됩니다.

특정 명령이 아무런 효과가 없는 것처럼 보인다면, 필드명이 잘못되었을 가능성이 높습니다. 현재 이 서비스는 인식할 수 없는 JSON 키를 오류 메시지 없이 무시합니다. 서비스 로그를 확인하고 API 참조 문서를 대조하여 필드명을 확인해 주십시오. 이 동작은 향후 버전에서 변경될 예정입니다.