주요 콘텐츠로 건너뛰기
버전: 3.5.x

05. 위치 제어

다음 방법을 통해 Inverse3 목표 위치로 이동시킵니다 set_cursor_position. 언어에 따라 상호작용 모델이 다릅니다 — C++는 일회성 무작위 목표 지점을 사용하는 반면, 파이썬은 키보드를 통해 지속적으로 이동합니다.

배울 내용:

  • 사용 set_cursor_position 위치 제어 모드용
  • 동일한 기본 명령에 대한 두 가지 상호작용 모델
  • 타깃을 작업 공간 구에 고정하기 — Minverse Inverse3보다 반지름이 더 작은 구를 Minverse
  • 원점을 작업 공간의 중심에 오도록 작업 공간 사전 설정을 지정하기

작업 흐름

C++ (무작위 대상 모델)

  1. 줄 단위로 버퍼링된 키 입력을 읽는 백그라운드 입력 스레드를 시작합니다 (n, +, -, q) 표준 입력(stdin)에서.
  2. WebSocket을 엽니다. 첫 번째 상태 프레임에서 다음을 등록합니다. 세션 프로필 그리고 설정 configure.preset: arm_front_centered. 구 내부에서 첫 번째 무작위 목표점을 생성합니다(거부 샘플링, 반경 0.08m).
  3. 매 초마다 다음을 전송합니다 set_cursor_position 현재 대상에 명령을 내립니다. 커서가 이를 부드럽게 따라갑니다. 서비스는 속도 제한을 적용하고 보간합니다.
  4. 사용자가 입력하면 n + ENTER 키를 누르면, 입력 스레드가 새로운 무작위 대상을 생성합니다. + / - 속도 조절; q 그만둔다.

파이썬 (누르고 이동 모델)

  1. WebSocket을 엽니다. 첫 번째 상태 프레임에서 다음을 확인합니다. status.calibrated — 기기가 아직 보정되지 않은 경우 사용자에게 알립니다.
  2. 읽기 config.type 작업 영역 반경을 선택하려면 (minverse = 0.04 m, 그 외의 경우 = 0.10 m).
  3. 등록하기 세션 프로필 그리고 설정 configure.preset: arm_front_centered.
  4. 매 초마다: 키보드 상태 확인 (W/A/S/D/Q/E), 다음을 통해 목표 위치를 업데이트합니다. SPEED 각 압축 축을 따라 작업 공간 구에 고정하고 전송 set_cursor_position. R 대상을 원점으로 재설정합니다.

매개변수

이름기본값 (C++)기본값 (Python)목적
workspace_radius / RADIUS_INVERSE30.08 m0.10 m (Inverse3) / 0.04 m (Minverse)표적 구의 반지름
speed_step / SPEED0.01 / 보도자료0.00005 m / 틱상호작용당 단계
PRINT_EVERY_MS100텔레메트리 스로틀 (Python)
세션 프로필co.haply.inverse.tutorials:position-control마찬가지로Haply 에서 식별
보정 확인 (Python)

파이썬 변이체 검사 status.calibrated 첫 번째 상태 프레임에서 시작하며, 기기가 보정되지 않은 경우 사용자에게 확인을 요청합니다. C++ 버전은 보정이 이미 완료된 것으로 가정합니다.

상태 필드 읽기

  • data.inverse3[0].device_id — 명령어 생성을 위해
  • data.inverse3[0].state.cursor_position — 원격 측정
  • (파이썬, 첫 번째 프레임만) data.inverse3[0].config.type — Inverse3 Minverse Inverse3 Minverse Inverse3 선택
  • (파이썬, 첫 번째 프레임만) data.inverse3[0].status.calibrated — false인 경우 사용자에게 확인 메시지를 표시합니다

보내기 / 받기

커뮤니케이션 워크플로

  • C++ 백그라운드에서 stdin 스레드를 실행하여 std::atomic<float> 대상; WebSocket 스레드는 매 틱마다 이를 읽습니다. n + ENTER를 누르면 입력 스레드가 새로운 무작위 대상을 생성합니다; on q두 스레드 모두 종료되었습니다.
  • 파이썬 단일 스레드 비동기 방식입니다. WebSocket 루프는 매 틱마다 키보드 상태를 폴링하고 업데이트합니다. position 직접.

Inverse-API 페이로드는 동일합니다. 첫 번째 틱에는 세션 프로필이 포함되며 + configure.preset, 이후의 틱은 오직 set_cursor_position.

단일 비동기 루프. 키보드 폴링 (handle_keys)는 매 틱마다 인라인으로 실행됩니다 — 스레드를 사용하지 않습니다. config.type 그리고 status.calibrated 첫 번째 상태 프레임에서 한 번 읽혀집니다.

async with websockets.connect(URI) as websocket:
while True:
msg = await websocket.recv()
data = json.loads(msg)

if first_message:
first_message = False
device_id = data["inverse3"][0]["device_id"]
radius = get_workspace_radius(data["inverse3"][0].get("config", {}))
# Handshake: profile + preset (one-shot)
request_msg = {
"session": {"configure": {"profile": {"name": SLUG}}},
"inverse3": [{
"device_id": device_id,
"configure": {"preset": {"preset": "arm_front_centered"}},
}],
}
else:
# Per tick: update position from keyboard (classic polling, not shown), send command
position = handle_keys(position, radius)
request_msg = {
"inverse3": [{
"device_id": device_id,
"commands": {"set_cursor_position": {"position": position}},
}],
}

await websocket.send(json.dumps(request_msg))

출처: Python · C++ · C++ Glaze

관련 기사: 제어 명령어 (set_cursor_position) · 마운트 및 작업 공간 (사전 설정) · 형식 (vec3) · 튜토리얼 06 (통합)