본문으로 건너뛰기

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": []
}

3개의 블록은 각각 다른 빈도로 업데이트됩니다:

블록포함된 내용변경 빈도
config펌웨어 정보, 프리셋, basis, 마운트, 필터거의 변경되지 않음 — 명시적인 설정 변경 시에만
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 참조 문서와 일치하는지 확인해 주십시오. 이 동작은 향후 버전에서 변경될 예정입니다.