본문으로 건너뛰기

06. 통합 (Inverse3 + 무선 VerseGrip)

2. 이 튜토리얼은 기기 사용법에 관한 것입니다. 그립을 특정 방향으로 향하게 한 상태에서 버튼을 계속 누르고 있으면, 커서가 그 방향으로 이동합니다. Inverse3 커서는 구형의 작업 공간 내에서만 움직일 수 있습니다.

학습 내용:

  • 동일한 state 프레임 내의 두 가지 유형의 장치(inverse3 그리고 wireless_verse_grip)을 읽어들이기
  • 쿼터니언 그립의 방향(로컬의 +Y (축)을 꺼낸다
  • set_cursor_position 를 사용하여 계산된 목표 지점으로 커서를 이동합니다
  • 타깃을 안전한 작업 공간 구역 내로 제한한다. `Minverse `는 ` Inverse3 `보다 작은 반경을 사용한다.
  • 작업 공간 사전 설정(arm_front_centered)를 설정하여 원점이 도달 범위의 중앙에 오도록 한다

워크플로우​

  1. 두 기기를 모두 감지합니다:
    • C++ 이 버전은 시작 시 HTTP를 통해 GET /devices 을 조회한 후, 보정 프롬프트를 표시하고 ENTER 키 입력을 기다립니다.
    • 파이썬은 첫 번째 WebSocket 상태 프레임에서 두 장치의 ID를 읽어옵니다.
  2. 첫 번째 메시지에서 세션 프로필 을 등록하고,configure.preset: arm_front_centered 을 설정합니다(원샷 핸드셰이크).
  3. 각 틱마다, 그립의 orientation 그리고 buttons.{a, b} 의 상태를 읽어옵니다.
  4. 이동 버튼이 눌려 있는 경우, 그립의 월드 공간에서의 방향(R(q) · ĵ、회전 후의 (단위 + Y축)을 계산하고,SPEED 로 스케일링된 값을 대상 위치에 더합니다.
  5. 타깃을 작업 공간 구 내로 제한하고,set_cursor_position 로 전송합니다.
  6. (Python 전용) 기기의 config.type 에 따라 공의 반지름을 조정합니다.minverse 의 경우 0.04 m, 그 외의 경우는 0.10 m입니다.

매개변수​

이름기본값용도
SPEED0.01 m/tick버튼을 누르고 있는 동안의 이동 단계
RADIUS_INVERSE30.10 mInverse3 / Inverse3x용 작업 공간 제한 반경
RADIUS_MINVERSE0.04 mMinverse 용도별 작업 공간 제한 반경 (Python 전용 — C++의 경우 0.10 (고정)
PRINT_EVERY_MS200텔레메트리 전송 빈도 제한
세션 프로필 이름co.haply.inverse.tutorials:combinedHaply Hub에서 이 시뮬레이션을 식별
실행 전에 보정하기
  • Inverse3 자동 보정을 수행합니다(또는 그립을 잉크통에 올려놓고 LED가 켜질 때까지 기다립니다).
  • 잉크병에서 그립을 분리합니다.
  • A 또는 B 버튼을 누른 상태에서 그립을 돌립니다. 커서는 그립이 향하는 방향으로 이동합니다.

state 필드 읽기​

각 틱의 state 프레임에서 다음 내용을 읽어옵니다:

  • data.inverse3[0].state.cursor_position — vec3
  • data.wireless_verse_grip[0].state.orientation — quaternion
  • data.wireless_verse_grip[0].state.buttons.{a, b, c} — 참/거짓 값
  • (파이썬, 첫 번째 프레임만)data.inverse3[0].config.type — Inverse3 와 Minverse 중 어느 반지름을 사용할지 선택
  • (파이썬, 첫 번째 프레임만)data.inverse3[0].status.calibrated — false인 경우 사용자에게 메시지를 표시합니다

보내기 / 받기​

쿼터니언을 이용한 방향 구하기 계산(R(q) 에서 +Y (회전)과 구를 이용한 클램핑은 선형 대수학에서 흔히 다루는 계산입니다. 자세한 내용은 소스 파일을 참조하십시오. Inverse API 측에서는 핸드셰이크와 각 틱마다의 set_cursor_position 를 호출합니다.

단일 비동기 루프입니다. 파이썬은 첫 번째 state 프레임에서 두 장치의 ID를 읽습니다. 핸드셰이크에서는 첫 번째 set_cursor_position 프로필과 configure.preset: arm_front_centered 을 부여합니다.

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

if first_message:
first_message = False
inverse3_id = data["inverse3"][0]["device_id"]
grip_id = data["wireless_verse_grip"][0]["device_id"]
radius = get_workspace_radius(data["inverse3"][0].get("config", {}))

# Handshake: profile + preset + first position command
request_msg = {
"session": {"configure": {"profile": {"name": SLUG}}},
"inverse3": [{
"device_id": inverse3_id,
"configure": {"preset": {"preset": "arm_front_centered"}},
"commands": {"set_cursor_position": {"position": position}},
}],
}
else:
# Per tick: update position from grip pointing direction (classic math, not shown), send
request_msg = {
"inverse3": [{
"device_id": inverse3_id,
"commands": {"set_cursor_position": {"position": position}},
}],
}

await websocket.send(json.dumps(request_msg))
SDK 설치 프로그램에 포함되어 있음

튜토리얼 06도 SDK와 함께 로컬에 설치되어 있습니다. 서비스의 설치 디렉터리 아래에 있는 tutorials/06-haply-inverse-combined/ 를 참조하십시오.

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

관련: 제어 명령어(set_cursor_position) · 형(쿼터니언, vec3) · 마운트 및 작업 공간(사전 설정) · 튜토리얼 03 (무선 VG) · 튜토리얼 05 (위치 제어)