본문으로 이동

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 참조 문서에서 필드 이름을 다시 확인해 보십시오. 이 동작은 향후 버전에서 변경될 예정입니다.