본문으로 이동

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

명령어​

키를 길게 누르고 있으면 계속 이동합니다. 키에서 손을 떼면 멈춥니다.

그 말이 맞네요액션
→ / ←+X / −X
↑ / ↓+Y / −Y
Page Up / Page Down+Z / −Z
= / -탐색 속도 높이기 / 낮추기
0작업 공간을 초기 상태로 재설정
H도움말 보기
Esc포기자 (Ctrl+C (이것도 작동합니다)

작동 원리​

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
};

출처​

SDK 설치 프로그램이 함께 제공됩니다.

튜토리얼 09는 SDK와 함께 로컬에 설치되어 있습니다 — 다음을 참조하십시오 tutorials/09-haply-inverse-ws-remote-control/ 서비스 설치 디렉터리에서.

관련 항목: 주문 set_transform · 세션 — 첫 메시지에서 협상 · 편집 및 작업 공간 · 선택기 · 튜토리얼 08 — 원격 HTTP 구성 · 튜토리얼 07 — 기초 및 조립