Skip to main content
Version : 3.5.x

Migration vers la version 3.5

Cette page constitue le guide de mise à niveau complet pour Inverse Service 3.5. Elle couvre toutes les fonctionnalités obsolètes encore présentes dans le service — les anciennes 3.0 format de transmission qui devrait être supprimé en 4.0, les points de terminaison HTTP obsolètes, et les commandes de simulation de canal de session obsolètes — ainsi que le seul nouveau Nouveauté de la version 3.5 : le format de sortie « Wireless Verse Grip » (en option).

Toutes les fonctionnalités obsolètes répertoriées ici sont toujours acceptées pour des raisons de compatibilité ascendante. La mise à niveau ne provoque aucune rupture de compatibilité — prévoyez de migrer lorsque cela vous convient.


3.0 contre 3.x Versions de l'API

Le service propose deux formats JSON parallèles : l'ancien 3.0 format sur le port 10000 et le courant 3.x format sur le port 10001. Les deux restent disponibles pour des raisons de compatibilité ascendante — 3.0 Les intégrations continuent de fonctionner sans changement après la mise à niveau.

avertissement

3.0 La prise en charge de la version de l'API sera abandonnée pour les 4.0.

  • 3.0 API

  • 3.x API

    • Entièrement documenté dans le 3.x pages de documentation.
    • HTTP sur http://localhost:10001/.
    • Websockets au port 10001.
    • Des fonctionnalités améliorées et une intégration plus rapide avec les moteurs de jeu.

Effectuez la mise à niveau quand cela vous convient, sans perturber vos processus de travail actuels.


Points de terminaison HTTP obsolètes

Les points de terminaison suivants sont toujours acceptés, mais génèrent un avertissement de dépréciation. Ils seront supprimés dans 4.0. Utilisez plutôt les itinéraires de remplacement.

Chemin obsolèteRemplacement
POST /force_scalePOST /settings/devices/force_scale
POST /gravity_compensationPOST /{type}/{id}/config/gravity_compensation
POST /torque_scalingPOST /{type}/{id}/config/torque_scaling
POST /device_handednessPOST /{type}/{id}/config/handedness
POST /serial_enablePOST /settings/system/serial_enable
POST /experimental/features/grip_dropped_simulation_stopperPOST /settings/features/grip_hook/enabled
POST /experimental/features/screensaver_enablePOST /settings/features/screensaver/enabled

Chaque itinéraire obsolète déclenche un http-route-deprecated événement sur la chaîne des événements, diffusant à la fois l'ancien itinéraire et son remplaçant.


Commandes obsolètes relatives aux canaux de session

Les deux commandes de simulation au niveau de la session ci-dessous sont obsolètes et seront supprimées dans une prochaine version majeure. Elles sont toujours acceptées sur le réseau ; les nouvelles intégrations devraient utiliser la configure les entrées répertoriées dans la colonne « Remplacement ».

Chaque commande obsolète déclenche un command-deprecated événement sur la chaîne des événements.

session.set_coordinate_origininverse3[*].configure.preset

// Old — deprecated
{ "session": { "set_coordinate_origin": { "coordinate_origin": "workspace_center" } } }

// New — canonical
{ "inverse3": [ { "device_id": "…", "configure": { "preset": { "preset": "arm_front_centered" } } } ] }

Cartographie des valeurs :

Ancien coordinate_originNouveau préréglage
device_basearm_front (ou defaults)
workspace_centerarm_front_centered

Les préréglages sont appliqués à chaque appareil via inverse3[*].configure.preset (ou configure.preset (concernant les entrées relatives à la poignée Verse / au dispositif sans fil Verse), et non comme un commutateur valable pour toute la session. Voir la Section « Configurer » Consultez le guide de simulation pour obtenir la liste complète des noms de préréglages.

session.set_basissession.configure.basis

// Old — deprecated
{ "session": { "set_basis": { "basis": { "permutation": "X-ZY" } } } }

// New — canonical
{ "session": { "configure": { "basis": { "permutation": "XZ-Y" } } } }
Modification de la convention de signe des axes

L'interprétation des axes et des signes diffère entre les deux commandes. Une permutation qui a produit le mappage correct sous session.set_basis peut produire un transformation inverse sous session.configure.basis — vous devrez peut-être inverser le signe sur un ou plusieurs axes lors de la migration.

Exemple : une session qui s'est déroulée correctement avec session.set_basis + "permutation": "X-ZY" aura généralement besoin de "permutation": "XZ-Y" sous session.configure.basis. Vérifiez toujours à nouveau la transformation obtenue avant de déployer une migration.


Format de sortie du Wireless Verse Grip (3,5 mm, en option)

La version 3.5 du service ajoute un format JSON optionnel pour les appareils Wireless Verse Grip (y compris les variantes personnalisées Ruko et Kingfisher) à la fois dans les images complètes et les images en streaming sur le canal de simulation v3.1.

Cette migration est facultative

3.5 est fourni avec serialization/wireless_verse_grip/legacy_mode = true par défaut. Les clients existants utilisant une version antérieure à la 3.5 continuent de fonctionner sans modification de configuration ni de modification du code — vous pouvez mettre à niveau le service sans toucher à votre intégration.

Ne procédez à la migration que si vous vouloir la nouvelle forme : plus épurée config.type / config.sub_type séparation et contrôle explicite permettant de déterminer si les poignées personnalisées sont dupliquées dans l'ensemble du wireless_verse_grip et custom_verse_grip tableaux. Pour vous inscrire, définissez serialization/wireless_verse_grip/legacy_mode = false et suivez la suite de cette section.

Le changement est additif sur le fil — la version 3.1 de la charge utile reste inchangée — et est entièrement contrôlée par quatre paramètres d'exécution sous serialization/wireless_verse_grip/. Les clients qui souhaitent conserver la forme antérieure à la version 3.5 l'obtiennent automatiquement ; ceux qui optent pour la nouvelle forme peuvent régler trois autres paramètres pour modeler le son.

Qui pourrait vouloir migrer ?

Tout client analysant le wireless_verse_grip ou custom_verse_grip Les tableaux d'une charge utile v3.1 peuvent tirer parti de la nouvelle structure :

  • Intégrations de plugins Unity qui lisent les entrées WVG via JsonUtility
  • Intégrations TouchDesigner utilisant le flux WebSocket
  • Exemples de code Python / C++ classés par thème config.type (par exemple "ruko" / "kingfisher")

Les clients qui se contentent d'analyser inverse3 ou verse_grip les tableaux sont non concerné quels que soient les paramètres.

S'inscrire

Retourner legacy_mode à false pour activer la nouvelle forme. Il y a deux façons de procéder :

curl -X POST http://127.0.0.1:10001/settings/serialization/wireless_verse_grip/legacy_mode \
-H 'Content-Type: application/json' \
-d 'false'

Le service renvoie immédiatement un instantané complet afin que les clients en cours de lecture puissent voir la nouvelle forme dès l'image suivante.

Une fois legacy_mode = false, les autres boutons (explicit_custom, extended_data/raw_data, extended_data/custom_fields) s'activent. Voir la matrice des boutons ci-dessous.

À quoi ressemble cette nouvelle forme ?

Lorsque vous vous inscrivez (legacy_mode = false), la charge utile démêle des axes qui étaient auparavant entremêlés :

  1. config.type est la famille d'origine, par entrée — "wireless_verse_grip" pour les rangées de stylets, "custom_verse_grip" pour les lignes personnalisées (Ruko, Kingfisher, prototype).
  2. config.sub_type est un nouveau domaine (uniquement pour le formulaire d'adhésion) portant le sous-type de matériel physique — "stylus", "prototype", "ruko"ou "kingfisher". Il sérialise le wireless_verse_grip::subtype énumération directement, distincte de config.type's device_type enum. Auparavant, le stylet et le prototype étaient tous deux sérialisés sous la forme "wireless_verse_grip"; chacune a désormais sa propre valeur. Le mode hérité pas émettre sub_type.
  3. Partager des poignées personnalisées wireless_verse_grip[] par défaut lorsque vous activez cette option , le tableau des styles contient également les variantes personnalisées. Le fichier séparé custom_verse_grip Le tableau n'est affiché que lorsque vous changez de sens explicit_custom = true, auquel cas ce tableau devient réservé à l'utilisation personnalisée (le stylet n'y apparaît jamais).
  4. Les charges utiles à structure personnalisée restent sous forme d'octets d'extension bruts. extended_data/raw_data (par défaut true) conserve le format brut state.extension_data: [...] tableau d'octets pour les entrées de poignées personnalisées — correspondant à l'ancienne forme. Les clients doivent convertir ces octets en champs spécifiques à chaque sous-type (roue/gâchette Ruko, boutons Kingfisher, …) dans leur propre code ; un indicateur avancé dédié extended_data/custom_fields peut générer des champs pré-traduits au sein du service, mais c'est pas Cela fait partie du processus de migration recommandé — consultez la remarque concernant ce paramètre avant de l'activer.

Exemple : système classique (par défaut) vs système sur inscription

Supposons qu'il y ait un stylet (1615) et un Ruko (1419) sont reliés.

{
"wireless_verse_grip": [
{
"device_id": "1615",
"config": { "type": "wireless_verse_grip", "…": "…" },
"state": {
"buttons": { "a": false, "b": false, "c": false },
"hall": 16,
"orientation": { "x": 0, "y": 0, "z": 0, "w": 1 }
}
},
{
"device_id": "1419",
"config": { "type": "ruko", "…": "…" },
"state": {
"buttons": { "up": false, "down": false, "left": false, "right": false },
"trigger": 7,
"wheel": 4,
"hall": 16,
"orientation": { "x": 0, "y": 0, "z": 0, "w": 1 }
}
}
],
"custom_verse_grip": [
{
"device_id": "1419",
"config": { "type": "custom_verse_grip", "…": "…" },
"state": {
"buttons": { "a": false, "b": false, "c": false },
"hall": 16,
"orientation": { "x": 0, "y": 0, "z": 0, "w": 1 },
"extension_data": [0, 6, 1, 183, 5, 6, 7, 8, 9, 10, 11, 12]
}
}
]
}

Principales différences lorsque vous vous inscrivez :

AspectAncien (version 3.5 par défaut)Inscription (legacy_mode = false)
config.type pour les lignes personnalisées sous wireless_verse_gripnom du sous-type (par exemple "ruko")famille d'origine "custom_verse_grip"
config.sub_typeabsentactuellement — "stylus" / "prototype" / "ruko" / "kingfisher"
custom_verse_grip tableau émistoujours (lorsqu'une poignée personnalisée est connectée)uniquement lorsque explicit_custom = true
Schéma d'état avec prise personnaliséebrut extension_data octets + a/b/c boutonsmême format brut extension_data octets par défaut ; raw_data peut être désactivé, et custom_fields il s'agit d'un système d'adhésion volontaire avancé — voir ci-dessous
Stylet en dessous custom_verse_gripjamaisjamais

Adapter votre analyseur syntaxique

Une fois que vous vous êtes inscrit, considérez config.sub_type en tant que identifiant matériel et config.type en tant que panier familial. Les clients qui se connectaient auparavant via config.type == "ruko" devrait se déclencher config.sub_type == "ruko":

- const isRuko = entry.config.type === "ruko";
+ const isRuko = entry.config.sub_type === "ruko";

Pour les analyseurs syntaxiques qui doivent prendre en charge à la fois les versions de service antérieures à la version 3.5 (ou les services 3.5 encore en mode hérité) et les services 3.5 en mode opt-in dans le même fichier binaire, cochez l'une ou l'autre des cases suivantes :

const subtype = entry.config.sub_type ?? entry.config.type;
const isRuko = subtype === "ruko";

Tout client qui, auparavant, comptait sur traduit champs par sous-type au sein d'une entrée Ruko ou Kingfisher (buttons.{up,down,left,right}, trigger, wheel, buttons.{a..f}, …) devraient désormais traduire le format brut state.extension_data[] octets de son côté. Le service conserve la traduction existante en service derrière le extended_data/custom_fields drapeau, mais ce drapeau est destiné uniquement à des clients internes très spécifiques et la traduction en cours d'exécution devrait être supprimée du service dans une prochaine version — intégrez le décodeur d'octets côté client dès le départ pour éviter une nouvelle migration ultérieure.

Maintien de l'ancien système (aucune action requise)

Le mode par défaut dans la version 3.5 est le mode hérité. Si vous disposez d'un client figé que vous ne pouvez pas mettre à jour, ou si vous n'avez tout simplement pas encore besoin de la nouvelle structure, ne faites rien : la mise à niveau vers la version 3.5 n'aura aucune incidence sur votre charge utile.

Le mode Legacy est une solution transitoire

legacy_mode = true est la valeur par défaut dans la version 3.5 afin de laisser le temps Haply internes Haply (y compris le Hub) et aux intégrations propriétaires de migrer. Il s'agit n'est pas obsolète aujourd'hui, mais le réglage par défaut devrait revenir à false dans une prochaine version mineure, et ce paramètre devrait être supprimé avant la mise à jour majeure vers la version 4.0. Prévoyez de migrer dès que cela vous convient — n’ attendez pas qu’une date butoir vous y oblige.

Matrice complète des boutons

Les quatre boutons se trouvent sous serialization/wireless_verse_grip/ et peut être activé ou désactivé à l'exécution via l'API HTTP des paramètres.

Bouton : legacy_mode

  • Type: bool
  • Par défaut: true (3,5 avec le mode hérité activé)

Quand true, la charge utile correspond à l'intégralité de la structure antérieure à la version 3.5, octet par octet, et les autres paramètres ne produisent aucun effet. Lorsque false, la nouvelle forme est active et les trois boutons situés en dessous prennent effet. Voir S'inscrire.

Bouton : explicit_custom

  • Type: bool
  • Par défaut: false
  • Nécessite legacy_mode = false pour avoir un effet.

Détermine si les poignées personnalisées disposent de leur propre tableau dédié.

  • false (par défaut) — les douanes partagent le wireless_verse_grip[] tableau à côté des entrées au stylet ; pas de fichier séparé custom_verse_grip le tableau est émis.
  • true — les droits de douane sont également perçus dans le cadre d'un système spécifique custom_verse_grip[] tableau (et continuent d'apparaître sous wireless_verse_grip[] (aussi).

Le précédent merged_in_wireless en inversant ce paramètre : la valeur par défaut était true (douanes reproduites dans wireless_verse_grip) et a dû être réglé sur false pour obtenir une distinction claire. La nouvelle dénomination est positive — explicit_custom = true se lit comme suit : « émettre explicitement les propriétés sous leur propre tableau » — et le réglage par défaut a été inversé, de sorte que le mode « opt-in » par défaut génère un seul tableau unifié wireless_verse_grip[] tableau, réduisant ainsi le coût de la sérialisation à chaque tick.

Bouton : extended_data/raw_data

  • Type: bool
  • Par défaut: true
  • Nécessite legacy_mode = false pour avoir un effet.

Quand true (par défaut), les entrées « custom-grip » incluent le format brut state.extension_data: [...] tableau d'octets — la structure stable pour les désérialiseurs basés sur la réflexion, comme ceux de Unity JsonUtility et pour les clients utilisant un protocole binaire personnalisé via le canal d'extension. Lorsque false, le tableau d'octets est omis. Indépendamment de custom_fields; consultez le tableau ci-dessous pour découvrir les quatre combinaisons.

Opération vide pour le sous-type de stylet standard (sans canal d'extension).

Bouton : extended_data/custom_fields

  • Type: bool
  • Par défaut: false
  • Nécessite legacy_mode = false pour avoir un effet.
Avancé — ne fait pas partie de la migration recommandée

custom_fields est conservée pour une poignée de clients internes spécifiques qui continuent de s'appuyer sur ce service pour convertir les octets bruts de l'extension en champs spécifiques au sous-type. Il est prévu de transférer la conversion en cours de traitement hors service dans une prochaine version, les nouvelles intégrations devraient donc pas activez cet indicateur. Conserver custom_fields = false (par défaut) et effectuer la conversion des octets en champs côté client.

Quand true, les entrées de type « custom-grip » héritent du schéma traduit par sous-type — buttons.{up,down,left,right} + trigger + wheel pour Ruko ; buttons.{a..f} + trigger pour Kingfisher. Quand false (par défaut), uniquement le générique buttons.{a,b,c} sont présents et l'état spécifique au sous-type doit être déduit à partir de state.extension_data[]. Indépendamment de raw_data.

Opération vide pour le sous-type « plain stylus » et pour le sous-type « prototype » — le prototype ne dispose pas de schéma traduit et revient toujours à extension_data octets (si raw_data = true) ou en texte brut a/b/c boutons uniquement (si raw_data = false).

Matrice combinée (mode « opt-in »)

Avec legacy_mode = false:

explicit_customraw_datacustom_fieldswireless_verse_grip[] contientcustom_verse_grip[] contient
false (par défaut)true (par défaut)false (par défaut)stylus (simple) + données brutes (octets bruts)(non émis)
falsefalsetruestylet (standard) + personnalisations (traduites)(non émis)
falsetruetruestylus (brut) + données personnalisées (octets bruts + traduits)(non émis)
truetruefalsestylus (simple) + données brutes (octets bruts)données brutes (octets bruts)
truefalsetruestylet (standard) + personnalisations (traduites)douanes (traduit)
truetruetruestylus (version standard) + douanes (version brute + traduite)douanes (original + traduction)

(Lignes contenant raw_data = false et custom_fields = false sont autorisées mais n'émettent que le message générique a/b/c boutons — qui ne servent généralement à rien.)

Sous-type de prototype

Le sous-type de poignée personnalisée « prototype » est considéré comme une poignée personnalisée aux fins du routage — il apparaît sous wireless_verse_grip[], ainsi que sous custom_verse_grip[] quand explicit_custom = true. Étant donné qu'il n'existe pas de schéma traduit pour le prototype, custom_fields n'a aucun effet sur les entrées de prototype ; leur état provient entièrement de extension_data octets (lorsque raw_data = true) ou pas du tout (lorsque raw_data = false).

En mode « opt-in », les entrées de prototype sont signalées config.sub_type = "prototype" — une valeur d'énumération spécifique, distincte de "stylus". Au point 3.4, les deux sous-types sont sérialisés sous la forme "wireless_verse_grip"; 3.5 Le mode « opt-in » attribue à chacun sa propre valeur. Le mode « legacy » n'émet pas sub_type pas du tout.


Référence