본문으로 바로 가기

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