시뮬레이션 채널
개요
시뮬레이션 채널은 장치 상태를 교환하고 세션 또는 장치 명령을 전송하는 데 사용되는 고주파 양방향 WebSocket 채널입니다.
기본 URL: ws://localhost:10001
설정에서 포트를 변경할 수 있습니다.
핵심 계약 (중요):
- 클라이언트가 연결되면, 서비스는 모든 장치 목록이 포함된 초기 인벤토리 메시지를 전송합니다.
- 그 후, 서버는 클라이언트로부터 수신한 각 메시지에 대해 정확히 하나의 상태 업데이트 메시지를 전송합니다.
- 각 상태 업데이트에는 모든 장치의 상태(및 현황)가 포함됩니다.
:::info 모듈 이 페이지는 Simulation Channel의 핵심 프로토콜과 명령어를 설명합니다.
추가 모듈이나 기능은 자체 명령어 및/또는 상태 필드를 통해 시스템에 등록되고 기능을 확장할 수 있습니다. 이에 대한 내용은 모듈 섹션에서 별도로 설명되어 있습니다. :::
의전 규정
클라이언트 메시지당 하나의 응답
이 서비스는 클라이언트로부터 수신된 각 메시지에 대해, 모든 장치의 상태를 포함하는 하나의 상태 업데이트 메시지를 전송합니다.
이는 다음과 같은 의미입니다:
- 장치 상태에 대한 최신 정보를 확인하려면 무언가 (세션 명령, 프로브 명령 또는 장치 명령) 를 전송해야 합니다.
- 이 채널은 클라이언트 메시지에 의해 구동되는 "틱" 루프처럼 동작합니다.
힘을 가하지 않는 폴링 (탐색 명령)
힘을 가하거나 시뮬레이션 매개변수를 변경하지 않고 상태 변화를 관찰하려면 다음 프로빙 명령어를 사용하십시오:
probe_position~을 위해inverse3probe_orientationVerse 그립용
탐색 명령에는 명령 데이터가 포함되어 있지 않으며, 단순히 장치 정보 조회를 강제 실행하여 다음 상태 업데이트 시 위치 및 방향 데이터가 최신 상태로 유지되도록 합니다.
구성 대 상태
- 그리고 초기 재고 메시지에 기기가 포함되어 있습니다
config,state및status. - 일반 주별 현황 메시지에는 기기가 포함됩니다
state그리고status.
설정이 포함된 스냅샷이 다시 필요하면 다음을 사용하세요. session.force_render_full_state.
좌표계
Haply 기본적으로 Z축이 위쪽을 향하는 우좌표계를 Haply .
좌표가 해석되고 반환되는 방식에는 두 가지 세션 수준 제어 항목이 영향을 미칩니다:
- session.set_coordinate_origin: 모든 장치에 적용되는 좌표 원점을 변경합니다.
- session.set_basis: Haply 와 애플리케이션의 좌표계 간의 매핑을 변경합니다.
메시지 형식
이 섹션에서는 개략적인 구조와 메시지 유형에 대해 설명합니다. 자세한 예제는 이 문서의 뒷부분에서 확인할 수 있습니다.
기기 그룹
메시지는 최상위 수준에서 기기 유형별로 그룹화됩니다(예: inverse3, verse_grip, wireless_verse_grip). 각 장치 유형 키는 장치별 객체 배열에 매핑됩니다.
초기 인벤토리 (서버 → 클라이언트)
WebSocket 연결이 수립된 직후 한 번 전송됩니다.
각 항목에는 다음이 포함됩니다:
device_idconfigstatestatus
참조: 예시: 초기 인벤토리 페이로드
상태 업데이트 (서버 → 클라이언트)
클라이언트 메시지 하나당 한 번씩 전송됩니다.
각 항목에는 다음이 포함됩니다:
device_idstatestatus
참조: 예시: 상태 업데이트 페이로드
세션 명령어 엔벨로프 (클라이언트 → 서버)
세션 명령어는 현재 연결/세션에 적용되는 작업으로, 특정 장치에 국한되지 않습니다.
{
"session": {
"<command_name>": {
"...": "..."
}
}
}
장치 명령어 엔벨로프 (클라이언트 → 서버)
장치 명령은 장치 유형 키 아래에 배열 형태로 전송되므로, 단일 메시지로 하나 이상의 장치에 명령을 보낼 수 있습니다.
{
"<device_type>": [
{
"device_id": "<id>",
"commands": {
"<command_name>": {
"...": "..."
}
}
}
]
}
단일 메시지에 여러 항목을 포함하여 동일한 유형의 여러 장치를 제어할 수 있습니다.
참고: commands 이는 사전이며, 특정 장치에 대해 여러 명령을 처리할 수 있지만, 명령 유형당 하나만 허용됩니다.
명령어 참조
세션
전체 상태 강제 렌더링
모든 장치의 상태 및 구성에 대한 스냅샷을 요청합니다.
{
"session": {
"force_render_full_state": {}
}
}
좌표 원점 설정
모든 장치의 좌표 원점을 설정합니다.
{
"session": {
"set_coordinate_origin": {
"coordinate_origin": "workspace_center"
}
}
}
지원되는 값:
device_base(기본값)workspace_center
원점을 workspace_center, 그 (0, 0, 0) 위치가 기기 작업 영역의 중앙으로 이동하며, 이는 기기 유형에 따라 달라집니다.
기준 설정
현재 세션에 대한 기준 매핑을 설정합니다. 기준 매핑은 세션 전체에 걸쳐 Haply좌표계에서 사용자의 좌표계로 변환하는 방식을 지정합니다.
기본 사항을 설정한 후:
- 시스템에서 반환된 모든 상태는 해당 기저에서 표현됩니다.
- 다른 명령어의 일부로 전송하는 모든 값은 해당 기준에 따라 해석됩니다.
이 매핑은 Haply 기준으로 정의되며, 다음의 순열로 표현됩니다. X, Y, Z, 선택적으로 앞에 다음을 붙여 + 또는 -.
유효한 값의 예:
XYZ,ZYX+Y-Z+X,X-ZY
해석 예시:
YZX~을 의미한다Y맞아요,Z는 공격수입니다,X올라왔습니다.
언리얼(Unreal)과 같은 왼손잡이용 Z-up 시스템의 예시 (X-YZ):
{
"session": {
"set_basis": {
"basis": {
"permutation": "X-YZ"
}
}
}
}
모든 기기 명령어
검증 (모든 장치)
프로빙 명령을 사용하여 힘이나 기타 시뮬레이션 변경 사항을 적용하지 않고도 최신 위치 및 방향 정보를 요청합니다.
- inverse3:
probe_position - Verse 그립 (
verse_grip,wireless_verse_grip):probe_orientation
{
"inverse3": [
{
"device_id": "049D",
"commands": {
"probe_position": {}
}
}
],
"verse_grip": [
{
"device_id": "049D",
"commands": {
"probe_orientation": {}
}
}
],
"wireless_verse_grip": [
{
"device_id": "049D",
"commands": {
"probe_orientation": {}
}
}
]
}
Inverse3
명령을 보내려면 inverse3 장치에 대해, 일치하는 항목을 포함하고 device_id ~ 아래에서 inverse3 키입니다.
하나의 기기를 제어하려면:
{
"inverse3": [
{
"device_id": "049D",
"commands": {
"set_cursor_force": {
"values": {
"x": 1.0,
"y": 2.0,
"z": 3.0
}
}
}
}
]
}
한 번의 메시지로 여러 기기를 제어하세요:
{
"inverse3": [
{
"device_id": "049D",
"commands": {
"set_cursor_force": {
"values": {
"x": 1.0,
"y": 2.0,
"z": 3.0
}
}
}
},
{
"device_id": "049E",
"commands": {
"set_cursor_force": {
"values": {
"x": 1.0,
"y": 2.0,
"z": 3.0
}
}
}
}
]
}
커서 위치 설정
{
"inverse3": [
{
"device_id": "049D",
"commands": {
"set_cursor_position": {
"values": {
"x": 1.0,
"y": 2.0,
"z": 3.0
}
}
}
}
]
}
커서 힘 설정
{
"inverse3": [
{
"device_id": "049D",
"commands": {
"set_cursor_force": {
"values": {
"x": 1.0,
"y": 2.0,
"z": 3.0
}
}
}
}
]
}
각도 위치 설정
{
"inverse3": [
{
"device_id": "049D",
"commands": {
"set_angular_position": {
"values": {
"a0": 1.0,
"a1": 2.0,
"a2": 3.0
}
}
}
}
]
}
각도 토크 설정
{
"inverse3": [
{
"device_id": "049D",
"commands": {
"set_angular_torque": {
"values": {
"a0": 1.0,
"a1": 2.0,
"a2": 3.0
}
}
}
}
]
}
확장된 구절 그립
그리고 set_extension_data 이 명령은 Verse 그립용 확장 프로토콜의 일부로, 보드 확장 통신 프로토콜을 구현한 그립 버전에서 사용됩니다.
그립 확장 데이터 설정
지원되는 데이터 길이:
- 업스트림(클라이언트 → 장치) 최대 20바이트.
- 최대 12바이트의 다운스트림 데이터(장치 → 클라이언트)로, 상태 업데이트 메시지에 다음과 같이 반환됩니다.
state.extension_data.
데이터 사양:
- 배열 길이: 20바이트
- 값 범위: 각 값은 0~255입니다
{
"wireless_verse_grip": [
{
"device_id": "049D",
"commands": {
"set_extension_data": {
"extension_data": [
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
]
}
}
}
]
}
예시
초기 재고 탑재량
이 서비스는 WebSocket이 연결되면 전체 장치 목록이 포함된 메시지를 전송합니다. 초기 메시지에는 다음 내용이 포함됩니다. JSON 형식입니다:
{
"inverse3": [
{
"device_id": "04BA",
"config": {
"type": "inverse3",
"device_info": {
"minor_version": 1,
"major_version": 7,
"id": "04BA",
"model": 4,
"uuid": "2D35F80DD9005F599B68F49944CB04BA"
},
"port": "COM13",
"extended_device_id": "2D35F80DD9005F599B68F49944CB04BA",
"extended_firmware_version": "8C20FDC8010AA1E15AA133CDA2534874",
"gravity_compensation": {
"enabled": true,
"scaling_factor": 1
},
"handedness": "right",
"torque_scaling": {
"enabled": true
}
},
"state": {
"angular_position": {
"a0": -69.31704,
"a1": 137.62952,
"a2": 19.832787
},
"angular_velocity": {
"a0": 0,
"a1": 0,
"a2": 0
},
"body_orientation": {
"x": -0.01940918,
"y": 0.7026367,
"z": 0.00048828125,
"w": 0.7113037
},
"cursor_position": {
"x": 0.07842738,
"y": -0.14836666,
"z": 0.14297646
},
"cursor_velocity": {
"x": -0.011969013,
"y": 0.0012009288,
"z": -0.043197
},
"mode": "idle"
},
"status": {
"calibrated": false,
"in_use": false,
"power_supply": true,
"ready": true,
"started": true
}
}
],
"verse_grip": [
{
"device_id": "61548",
"config": {
"port": "COM3",
"type": "verse_grip"
},
"state": {
"button": false,
"hall": 0,
"orientation": {
"x": -0.5019531,
"y": 0.8632202,
"z": -0.048095703,
"w": -0.022338867
}
},
"status": {
"error": 0,
"ready": true
}
}
],
"wireless_verse_grip": [
{
"device_id": "0",
"config": {
"port": "COM6",
"type": "wireless_verse_grip",
"major_version": 1,
"minor_version": 4,
"hardware_version": 1
},
"state": {
"battery_level": 0.816,
"battery_voltage": 3.77,
"buttons": {
"a": false,
"b": false,
"c": false
},
"hall": 16,
"orientation": {
"x": -0.019866943,
"y": -0.017486572,
"z": 0.05508423,
"w": -0.9963989
}
},
"status": {
"connected": true,
"awake": true,
"ready": true
}
}
]
}
주 업데이트 페이로드
이 서비스는 수신된 각 메시지에 대해 모든 장치의 상태를 포함하는 상태 업데이트 메시지 하나를 전송합니다.
기계의 상태를 확인하려면, 미리 메시지를 전송해야 합니다(예를 들어, 프로브 명령이나 힘 값을 전송해야 하며, 값이 0일 경우에도 마찬가지입니다). 이는 힘을 가하지 않고 장치를 입력 소스(예: 위치 추적)로 사용할 때 특히 중요합니다.
상태 업데이트 메시지에는 다음 내용이 포함되어 있습니다. JSON 형식입니다:
{
"inverse3": [
{
"device_id": "04BA",
"state": {
"angular_position": {
"a0": -69.31704,
"a1": 137.62952,
"a2": 19.832787
},
"angular_velocity": {
"a0": 0,
"a1": 0,
"a2": 0
},
"body_orientation": {
"x": -0.01940918,
"y": 0.7026367,
"z": 0.00048828125,
"w": 0.7113037
},
"cursor_position": {
"x": 0.07842738,
"y": -0.14836666,
"z": 0.14297646
},
"cursor_velocity": {
"x": -0.011969013,
"y": 0.0012009288,
"z": -0.043197
},
"mode": "idle"
},
"status": {
"calibrated": false,
"in_use": false,
"power_supply": true,
"ready": true,
"started": true
}
}
],
"verse_grip": [
{
"device_id": "61548",
"state": {
"button": false,
"hall": 0,
"orientation": {
"x": -0.5019531,
"y": 0.8632202,
"z": -0.048095703,
"w": -0.022338867
}
},
"status": {
"error": 0,
"ready": true
}
}
],
"wireless_verse_grip": [
{
"device_id": "0",
"state": {
"battery_level": 0.816,
"battery_voltage": 3.77,
"buttons": {
"a": false,
"b": false,
"c": false
},
"hall": 16,
"orientation": {
"x": -0.019866943,
"y": -0.017486572,
"z": 0.05508423,
"w": -0.9963989
}
},
"status": {
"ready": true
}
}
],
"custom_verse_grip": [
{
"device_id": "0",
"state": {
"battery_level": 0.816,
"battery_voltage": 3.77,
"buttons": {
"a": false,
"b": false,
"c": false
},
"hall": 16,
"orientation": {
"x": -0.019866943,
"y": -0.017486572,
"z": 0.05508423,
"w": -0.9963989
},
"extension_data": [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
},
"status": {
"ready": true
}
}
]
}