v3.5.0
1년 전 API 재작성 이후 가장 큰 릴리스입니다. 3.5.0은 통합 3D 수학 레이어, 완전한 Minverse 지원, 타입이 지정된 이벤트 스트림, 완전한 설정 API, 그리고 더 정리된 HTTP 인터페이스를 도입합니다. 이와 함께 1년 동안의 버그 수정과 사용성 개선도 포함되어 있습니다.
주요 내용
- 통합 3D 수학 레이어 — 장치 basis(프레임), 마운트 변환, 작업 공간 변환, 내비게이션 변환을 위한 일급 프리미티브를 갖춘 조합 가능한 변환 파이프라인이며, 로컬, 세션, 애플리케이션, 내부 공간 간의 명시적 변환을 함께 제공합니다.
- Bubble Navigation — 형상이 정의된 영역(SDF 프리미티브)을 통해 대규모 가상 작업 공간을 탐색하며, 속도 매핑 기반 속도 제어, 히스테리시스를 고려한 충돌 감지, 선택적인 커서 방향 드리프트를 제공합니다. HTTP 및 WebSocket 기반으로 전체 설정이 가능하며, 앱 공간 왕복 변환을 지원합니다.
- 타입이 지정된 이벤트 스트림 — 장치 수명 주기, 안전 알림, 보정, 배터리, 제어 주기 경고, 지원 중단 힌트를 위한 전용 WebSocket 이벤트 채널입니다.
- 설정 API — HTTP CRUD, 타입 힌트, 범위 제약, 설명을 지원하는 완전한 키-값 설정 시스템으로, 기존의 중첩된 구성 파일을 대체합니다.
- 일관된 장치 구성 — 모든 장치에 대해 하나의 HTTP 라우트 세트를 제공합니다:
basis,mount,preset,transform,filters,handedness,torque_scaling,gravity_compensation,home_return. - 동기화된 Minverse + 펜 보정 — 장치와 펜이 이제 함께 보정되며, 그립이 물리적으로 장착될 때까지 보정 상태가 잠긴 상태로 유지됩니다.
- 사용성 개선 HTTP — 인덱스 기반 장치 선택자(ID 없이 인덱스로 장치 지정), WebSocket 간에 공유되는 통합 요청/응답 형식, 선택적으로 사용하는
{ok, error, data}엔벨로프(?format=json), 와일드카드 세션 선택자를 제공합니다.
새로운 기능
장치
- Minverse — 이번 릴리스와 함께 공식 지원이 제공됩니다: 장치 감지, 준비(ready) 시퀀스, 안전 알림, 동기화된 보정 워크플로.
- Ruko 및 Kingfisher가 공식 그립 제품 유형으로 인식됩니다.
- 장치 시뮬레이터 지원 — 실제 하드웨어와 함께 소프트웨어로 시뮬레이션된 장치를 감지하고 통신할 수 있습니다.
- 연결 루프 보호 — 잘못 동작하는 포트는 자동으로 차단되며,
POST /ports/{port}/reset으로 재설정합니다. - 펜 장착 하트비트 — 디바운스를 적용하여 그립의 장착/분리를 안정적으로 감지합니다.
세션, 명령 및 WebSocket
- 세션 프로필 필터링 및 지속성 — 세션은 서비스가 재연결 후에도 기억하는 프로필 이름과 필요한 SDK 버전을 선언하며, 클라이언트와 모니터링 도구는 해당 프로필로 세션을 필터링하고 대상으로 지정할 수 있습니다.
- 세션별 명령 버퍼 — 느린 세션 하나가 다른 세션을 더 이상 멈추게 하지 않습니다.
- 단발성 명령용 명시적
configure맵 — 장치별basis,preset,mount,force_gate,damping과 세션별profile,basis가 이제 모두configure에 포함됩니다. 출력 구성 맵과 맞추어, 전송한 값과 읽어 온 값이 왕복 일치합니다. - 사용자 지정 장치 마운트 — 내장 작업 공간 프리셋(
defaults,arm_front,arm_front_centered,led_front,led_front_centered) 중 하나를 선택하거나 명시적 변환을 전송할 수 있습니다. 수동 마운트 변경 시 프리셋은 자동으로custom으로 전환됩니다. - 이름이 지정된 명령 필드 —
position,vector,angles,torques가 일반적인values배열을 대체합니다. set_angular_torques가set_angular_torque를 대체합니다(단수형은 지원 중단됨).- 세션 프레임 확장 — v3.0 및 v3.1 세션 프레임에 확장 가능한
config,state,status객체가 포함됩니다. 새로운 출력 필드로는current_cursor_force,current_cursor_position,current_angular_torques,current_angular_position,control_domain,control_mode,transform,transform_velocity, 확장된config.*, 그리고status.safety(기본적으로 숨김)가 있습니다. - 부분 변환 업데이트 — 마운트, 작업 공간 변환, 내비게이션 형상에서 변경하려는 하위 필드(
position,rotation,scale)만 전송하면 됩니다.
HTTP
GET /— 서비스 버전.GET/POST/DELETE /settings및/settings/*— 전체 키-값 설정 API.GET /sessions/{session}및GET/POST/DELETE /sessions/{session}/profile.GET /devices?session=<selector>— 장치 좌표를 지정된 세션의 애플리케이션 공간으로 변환합니다.- 인덱스 기반 장치 선택자 — ID를 몰라도 인덱스로 모든 장치를 지정할 수 있습니다(첫 번째 Inverse3의 경우
/inverse3/0/..., Inverse 계열의 모든 장치의 경우/inverse*/*/...). - 통합 요청/응답 형식 — POST/GET 본문은 WebSocket에서 사용하는 것과 동일한
command_dataJSON 형식을 사용합니다. 한 전송 방식을 기준으로 작성한 코드는 다른 전송 방식에서도 동작합니다. - 선택적 엔벨로프 — 모든 라우트에서
?format=json으로 활성화할 수 있으며,/settings*및GET /home_return은 기본값으로{ok, error, data}를 사용합니다. 원시 형식을 원하면?format=plain을 사용합니다. - 세션 선택자 와일드카드 — 프로필 이름에서
*는 임의의 문자열을,?는 단일 문자를 의미합니다. - 퍼센트 디코딩된 선택자 —
%2A,%3A등은 라우팅 전에 디코딩됩니다.
이벤트
communication/events/port의 전용 WebSocket 이벤트 스트림입니다.- 타입이 지정된 이벤트 카테고리 24종이 있으며, 장치 수명 주기, 안전(e-brake, 이물질 감지, 스톨), 보정 실패, 배터리 알림, 세션 경고, 제어 주기 낮음/임계, 입력 검증, 지원 중단 힌트를 포함합니다.
관측성
- 프로파일링 시 로그 메시지가 레벨별 색상과 함께 Tracy로 전달됩니다.
- 모든 HTTP 핸들러에 Tracy 존이 설정됩니다.
- 메인 루프 타이밍 통계 이벤트.
- 로그 디렉터리와 서버 호스트 이름을 구성할 수 있습니다(Docker 친화적).
3.6 예정 기능
- SDF 햅틱 이펙트(SDF HFX) — 기반 작업은 3.5에 반영되었습니다(모듈, 수명 주기, 모듈이 제공하는 명령/상태 직렬화). 공개 API는 전체 문서와 함께 3.6에 출시될 예정입니다.
개선 사항
- 힘 진동 필터링 — 축별 진동 감지, 8단계 점진적 복구, 히스테리시스를 적용한 진입 투표, 비대칭 해제 구간을 포함합니다.
- 런타임 force-gate 필터 — WebSocket 또는 HTTP에서
configure.force_gate.gain으로 구성할 수 있으며, 지속 저장되는 기본값을 제공합니다. - 메인 루프 최대 주파수를 32 kHz로 상향 (정밀 응용 분야용).
- 더 작은 WebSocket 페이로드 — 기본값인 항등(identity) 변환 하위 필드(
position = 0,rotation = identity,scale = 1)는 기본적으로 출력에서 생략됩니다. 이를 통해 페이로드 크기가 줄어들고, 4 KB 메시지 제한을 가진 이전 Unity 패키지와의 호환성이 복원됩니다. 고급 설정 두 가지(serialization/explicit_fields,serialization/force_complete_transforms)를 사용하면, 이를 필요로 하는 소비자를 위해 모든 필드를 다시 포함할 수 있습니다. - 메인 루프 지터 감소 — JSON 파싱 및 네트워크 전송 중에도 WebSocket 메시지 처리가 메인 루프 틱을 차단하지 않으며, 세션 틱 스케줄링이 응답 직렬화보다 앞으로 옮겨졌습니다.
- 서버는 기본적으로 localhost 전용 —
communication/bind_all_interfaces설정으로 네트워크 접근을 활성화할 수 있습니다. - 장치 선택자 와일드카드에 접두사 구문 사용 (예:
inverse*는 Inverse 계열의 모든 장치와 일치합니다). - 댐핑 명령이
force_gate와 함께configure맵으로 옮겨졌습니다. - 회전 파일 로거가 이전 로거를 대체하며, 디렉터리를 구성할 수 있습니다.
- 모듈이 제공하는 명령 및 상태 — 모듈은 핵심 스키마를 건드리지 않고도 자체 명령을 주입하고 필드를 구성하며, 상태 출력을 WebSocket 프레임에 추가할 수 있습니다.
수정 사항
1년간의 버그 수정이 포함되어 있으며, 가장 영향이 큰 항목은 아래와 같습니다.
- 특정 조건에서 세션 속도가 불규칙하게 나타나는 문제.
- **GripHook (Verse Grip Stopper)**가 시뮬레이션이 실행되지 않을 때 깔끔하게 해제되지 않던 문제.
- Inverse3 타임아웃이 지나치게 짧게 설정되어, 부팅이 느린 장치에서 연결 끊김 루프를 유발하던 문제.
- Windows에서 서비스가 깔끔하게 종료되지 않음 — 종료 시 HTTP 서버가 항상 정리되지는 않던 문제.
- 서비스가 이전 펌웨어 버전에 지원되지 않는 명령을 보냈을 때 발생하던 재연결 루프.
- Bluetooth 어댑터가 있는 시스템에서 Bluetooth 장치 열거가 로그를 과도하게 채우던 문제.
- 서비스를 연속으로 여러 번 재시작할 때 발생하던 충돌.
- 절전 모드에서 복귀한 후 Ubuntu 노트북에서 발생하던 무선 Verse Grip 동글 멈춤 현상.
- Linux 및 macOS에서 무선 Verse Grip 핸드셰이크가 첫 번째 감지 시도에 실패하면 이제 올바르게 대체 절차로 전환됩니다.
- MacOS 설정 파일 위치 — 설정이 잘못된 경로 대신
~/Library/Application Support/에 저장되도록 변경되었습니다. - Linux 및 macOS의 SIGSEGV 신호 처리 — 다중 스레드 충돌 캡처가 활성화된 경우 프로세스가 치명적인 신호에서 더 이상 무한 반복하지 않습니다.
- 세션 간 명령 덮어쓰기 — 한 세션의 설정 명령이 다른 세션의 명령으로 조용히 대체될 수 있었으나, 이제 올바르게 필터링되고 병합됩니다.
- Probe 명령의 설정 덮어쓰기 —
probe_position을 전송하는 모니터링 세션(예: Haply Hub)이 대기 중인 basis / preset / profile 변경 사항을 더 이상 조용히 덮어쓰지 않습니다. - 프로토타입 그립 표시 — 프로토타입 하드웨어가 커스텀 그립 대신 표준 그립으로 잘못 표시되던 문제.
- 마이그레이션하지 않은 클라이언트를 위해 레거시
set_basis행렬 규칙이 다시 지원됩니다. - 세션 연결 해제 시 Inverse3 힘 킥이 더 이상 잔여 힘 스파이크를 발생시키지 않습니다.
- 빠른 연결 및 연결 해제가 반복되는 동안 발생하던 WebSocket 연결 손실 경쟁 상태.
- 일부 발신 페이로드에서 **WebSocket
session_id**가0으로 직렬화되던 문제. - Windows에서
--dev와 함께 사용할 때 이제--log-level이 적용됩니다(이전에는debug로 조용히 재설정되었습니다).
지원 중단 안내
여전히 동작하지만 향후 메이저 버전에서 제거될 예정입니다. 해당하는 경우 응답에 deprecation_warning 필드가 포함됩니다.
| 지원 중단 대상 | 대체 항목 |
|---|---|
POST /force_scale | POST /settings/devices/inverse*/filters/force_scale/gain |
POST /gravity_compensation | POST /{device}/{id}/config/gravity_compensation |
POST /torque_scaling | POST /{device}/{id}/config/torque_scaling |
POST /device_handedness | POST /{device}/{id}/config/handedness |
POST /serial_enable | POST /settings/communication/serial/enabled |
POST /experimental/features/grip_dropped_simulation_stopper | 설정 API |
POST /experimental/features/screensaver_enable | 설정 API |
WebSocket command_data.values | position, vector, angles, torques |
WebSocket set_angular_torque | set_angular_torques |
WebSocket probe_cursor_position | probe_position |
WebSocket set_coordinate_origin | configure.preset |
WebSocket 세션 수준 set_basis | configure.basis |
호환성 참고 사항
3.4.19 대비 호환성을 깨뜨리는 중대한 변경은 없습니다. 기존 연동에 대한 참고 사항은 다음 두 가지입니다:
- 지원 중단된 HTTP 엔드포인트는 이제 응답에
deprecation_warning필드를 포함합니다. 응답 스키마를 엄격하게 검증하는 클라이언트는 이 추가 필드를 허용해야 합니다. - WebSocket
command_data의values필드는 지원 중단되었지만 여전히 파싱됩니다. 명명된 필드를 사용하는 것을 권장합니다.
튜토리얼 및 문서
- 새 튜토리얼: 05 위치 제어(Position Control), 06 통합(Inverse3 + Verse Grip), 07 Basis 및 마운트(Basis and Mount), 08 HTTP 원격 설정기(Remote Configurator), 09 WebSocket 원격 제어(Remote Control), 10 이벤트 스트림 리스너(Event Stream Listener).
- 새로운 Glaze 변형: 기존 nlohmann/json 변형과 함께, 모든 C++ 튜토리얼에 대한 새로운 Glaze 변형(
cpp-glz/)이 추가되었습니다. - 모든 튜토리얼 재작성: v3.1 API에 맞게 재작성되었습니다(포트 10001,
configure.preset, 명명된 명령 필드,print_state()헬퍼). - 제거: 기존 Verse Grip Stopper 튜토리얼이 제거되었으며, 새로운 통합 튜토리얼로 대체되었습니다.
- 공개 문서 갱신: SDK 가이드, API 참조, 하드웨어 페이지 전반이 새로 고쳐졌습니다.