09. WebSocket 작업 공간 탐색기
다음으로 이동하세요 기기의 작업 공간 위치(실시간) 명령을 지속적으로 전송함으로써 set_transform WebSocket 채널을 통해. 이 튜토리얼에서는 HTTP를 사용하여 세션과 기기를 식별합니다(바로 그 튜토리얼 08), 그런 다음 매 사이클마다 위치 업데이트를 전송하기 위해 WebSocket 연결을 엽니다.
이는 두 가지 변환 연산 간의 차이를 잘 보여줍니다:
| 작전 | 튜토리얼 | 일반적인 사용 예 |
|---|---|---|
configure.mount — 지속적 편집 변환 | 08 | 기기의 물리적 조립 방식을 설명하기 위해 한 번만(또는 드물게) 정의됨 |
set_transform — 작업 공간의 지속적인 변화 | 09 (이 튜토리얼) | 이 역시 영구적으로 유지되지만, 작업 공간에서 실시간으로 탐색할 수 있도록 매 사이클마다 지속적으로 전송될 수 있습니다. |
두 명령어 모두 다음을 통해 사용할 수 있습니다. HTTP 및 WebSocket, 그리고 이 둘은 모두 지속적인 : 이 서비스는 사용자가 마지막으로 전송한 값을 저장합니다. 차이점은 업데이트의 목적과 빈도에 있습니다: configure.mount 드문 업데이트(물리적 설치)에 최적화되어 있는 반면, set_transform 고주파 스트리밍(씬 탐색)에 최적화되어 있습니다.
사용하세요 set_transform 작업 공간의 시작점이 실행 중에 변화하는 요소를 따라가야 할 때: 손을 따라가거나, 절차적 오프셋을 애니메이션화하거나, 작업자가 가상 작업 공간을 실시간으로 이동할 수 있도록 할 때 등입니다.
별도로 보면, configure.mount et set_transform 겉보기에는 같은 효과를 내는 것처럼 보이지만, 사실은 겹쳐진 : 좌표 파이프라인에서 작업 공간 변환이 적용됩니다 par-dessus 편집 (device → basis → mount → workspace → application). 참조 편집 및 작업 공간 전체 파이프라인에 대해.
사용 사례
- 작업 공간 내에서 실시간 탐색. 햅틱 장면이 중단되지 않은 상태에서 커서를 장치(이펙터가 도달하는 지정된 영역)의 작업 공간 내에서 이동시킬 수 있습니다.
- 운영자가 직접 제어하는 정렬. 메인 햅틱 애플리케이션이 실행되는 동안, 다른 단말기에서 누군가가 화살표 키를 계속 누르고 있어 작업 공간을 이동시키도록 하세요. 이는 라이브 세션 중 작업 공간에서 보정 작업을 수행할 때 유용합니다.
- 작업 공간의 절차적 이동. 각 사이클마다 위치에만 영향을 미치는 변환 보정값을 전송하여 스크립트(오디오 반응형, 물리 기반 등)를 통해 작업 공간의 위치를 제어합니다.
선행 조건
튜토리얼 09를 진행하려면 활성 WebSocket 세션이 필요합니다. 즉, 이미 실행 중인 햅틱 루프 내에 Inverse3 가 설정된 클라이언트가 있어야 합니다. 튜토리얼 09는 이 세션에 연결된 후 작업 공간을 실시간으로 이동시킵니다.
Haply Hub를 열고 Orb 데모를 실행하세요. 그러면 즉시 타겟팅할 수 있는 지속형 햅틱 세션이 열립니다:
./09-haply-inverse-ws-remote-control --session co.haply.hub::demo-orb
python 09-haply-inverse-ws-remote-control.py --session "co.haply.hub::demo-orb"
Orb 씬은 작업 공간의 원점에 구체를 표시합니다. 튜토리얼 09에서 설명한 대로 작업 공간을 이동하면 씬 전체가 실시간으로 이동하므로, 즉각적인 시각적 피드백을 얻을 수 있습니다.
햅틱 루프를 실행하는 다른 튜토리얼(01~07)도 모두 작동합니다. 첫 번째 터미널에서 해당 튜토리얼을 실행한 다음, 두 번째 터미널에서 튜토리얼 09를 시작하고, 튜토리얼이 대화형 방식으로 세션을 탐색하도록 두세요.
이용률
# Discover session interactively, use first detected device
./09-haply-inverse-ws-remote-control
python 09-haply-inverse-ws-remote-control.py
# Target the Haply Hub Orb demo directly
./09-haply-inverse-ws-remote-control --session co.haply.hub::demo-orb
python 09-haply-inverse-ws-remote-control.py --session "co.haply.hub::demo-orb"
# Target a session directly, specify device
./09-haply-inverse-ws-remote-control --session :my_profile:0 --device A14
python 09-haply-inverse-ws-remote-control.py --session "#42" --device A14
명령어
- 파이썬
- C++
키를 길게 누르고 있으면 계속 이동합니다. 키에서 손을 떼면 멈춥니다.
| 그 말이 맞네요 | 액션 |
|---|---|
→ / ← | +X / −X |
↑ / ↓ | +Y / −Y |
Page Up / Page Down | +Z / −Z |
= / - | 탐색 속도 높이기 / 낮추기 |
0 | 작업 공간을 초기 상태로 재설정 |
H | 도움말 보기 |
Esc | 포기자 (Ctrl+C (이것도 작동합니다) |
줄 단위: 명령어를 입력한 후 Enter 키를 누르세요.
| 주문 | 액션 |
|---|---|
x+[N] / x-[N] | X축 속도를 ±N mm/프레임으로 설정합니다 (x+ (현재 기본 속도를 사용합니다) |
y+[N] / y-[N] | Y축 속도를 ±N mm/프레임으로 설정 |
z+[N] / z-[N] | Z축 속도를 ±N mm/프레임으로 설정하십시오. |
s+[N] / s-[N] | 기본 속도를 ±N mm/프레임으로 조정 |
stop | 모든 기어를 중립으로 되돌리기 |
reset | 속도를 0으로 재설정하고 원점으로 돌아가기 |
h | 도움말 보기 |
Ctrl+C (또는 Ctrl+D / EOF)를 눌러 종료하십시오.
작동 원리
1단계 — HTTP: 세션 및 기기 파악
이 튜토리얼에서는 동일한 유틸리티 함수들을 재사용합니다. discover_session() / discover_device() que le 튜토리얼 08 : GET /sessions (ou GET /sessions/<selector> avec --session), 그 다음 GET /devices (또는 직접적인 활용) --device). 두 함수 모두 동일한 CLI 옵션을 지원하며, 텍스트는 SESSION_HELP 동일함: 튜토리얼 00 또는 08에 나온 선택기는 수정 없이 여기에서도 작동합니다.
2단계 — WebSocket 세션, 첫 번째 메시지를 통한 협상
이 튜토리얼은 다음으로 WebSocket 연결을 열며 ws://localhost:10001. Au 수신한 첫 번째 메시지, 세션 프로필 기록을 전송합니다:
{
"session": {"configure": {"profile": {"name": "co.haply.inverse.tutorials:ws-remote-control"}}},
"inverse3": [{"device_id": "...", "commands": {"set_transform": {"transform": {"position": {"x": 0, "y": 0, "z": 0}}}}}]
}
다음 티크들은 생략합니다 session — 제어판만 inverse3 이 전송됩니다.
3단계 — set_transform 매 틱마다
set_transform 수락합니다 부분 변환 — 수정하고자 하는 필드만 선택하세요. 이 튜토리얼에서는 위치만 전송하며, 회전과 크기는 세션의 기본값(다음에 정의된 값)을 유지합니다. configure.mount(해당되는 경우).
{
"inverse3": [{"device_id": "...", "commands": {"set_transform": {"transform": {"position": {"x": 0.02, "y": 0.0, "z": 0.01}}}}}]
}
포지션은 틱 단위로 누적됩니다. 약 1 kHz에서 서비스가 다시 적용됩니다. set_transform 매 틱마다 (0차 순서 유지) 처리되므로, 작업 공간은 마지막으로 전송된 위치에 그대로 유지됩니다.
set_transform ou configure.mount두 명령어 모두 세션당 하나의 영구 변환을 저장하지만, 작업 공간 변환은 par-dessus 파이프라인 내의 편집 (참조: 편집 및 작업 공간). 튜토리얼 09가 재생되는 동안 set_transform 각 틱마다, 새로운 WebSocket 프레임은 이전에 브로드캐스트된 작업 공간 변환을 대체합니다. 따라서 브로드캐스트를 수신하는 다른 모든 클라이언트는 set_transform 동일한 기기에 대한 주문은 다음 틱에서 덮어쓰게 됩니다. configure.mount 독립적이며 그 가치를 유지합니다. 실제로는 각 관심사별로 채널을 하나씩 선택하세요. 물리적 구성에 대해서는 ‘설정’ 채널을, set_transform 실시간 탐색을 위해.
스레드 모델 (C++)
이 C++ 튜토리얼에서는 위치 누적기를 공유하는 두 개의 스레드를 사용합니다:
| 스레드 | 역할 |
|---|---|
| 스레드 주체 | Lit std::getline(std::cin, ...), 토큰을 분석하고, 업데이트합니다 nav_vel[] et default_step |
| WebSocket 리콜 스레드 | 진전을 이루다 nav_pos[] avec nav_vel[] * dt, 직렬화 set_transform 그리고 그것을 보내고 |
std::mutex nav_mutex 보호자 nav_pos[], nav_vel[] et default_step. 타임스탬프 last_tick 그리고 지표는 first_ws_msg 이들은 WS 리콜에서 로컬이며 뮤텍스가 필요하지 않습니다.
ws.onmessage = [&](const std::string &) {
float pos_snap[3];
{
std::lock_guard<std::mutex> lk(nav_mutex);
for (int i = 0; i < 3; ++i) nav_pos[i] += nav_vel[i] * 0.001f; // mm/frame → m
for (int i = 0; i < 3; ++i) pos_snap[i] = nav_pos[i];
}
// build and send set_transform with pos_snap
};
출처
튜토리얼 09는 SDK와 함께 로컬에 설치되어 있습니다 — 다음을 참조하십시오 tutorials/09-haply-inverse-ws-remote-control/ 서비스 설치 디렉터리에서.
관련 항목: 주문 set_transform · 세션 — 첫 메시지에서 협상 · 편집 및 작업 공간 · 선택기 · 튜토리얼 08 — 원격 HTTP 구성 · 튜토리얼 07 — 기초 및 조립