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.
3.0 La prise en charge de la version de l'API sera abandonnée pour les 4.0.
-
3.0API- Entièrement documenté dans le
3.0.xpages de documentation. HTTPsur http://localhost:10000/3.0/.Websocketsau port10000.
- Entièrement documenté dans le
-
3.xAPI- Entièrement documenté dans le
3.xpages de documentation. HTTPsur http://localhost:10001/.Websocketsau port10001.- Des fonctionnalités améliorées et une intégration plus rapide avec les moteurs de jeu.
- Entièrement documenté dans le
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ète | Remplacement |
|---|---|
POST /force_scale | POST /settings/devices/force_scale |
POST /gravity_compensation | POST /{type}/{id}/config/gravity_compensation |
POST /torque_scaling | POST /{type}/{id}/config/torque_scaling |
POST /device_handedness | POST /{type}/{id}/config/handedness |
POST /serial_enable | POST /settings/system/serial_enable |
POST /experimental/features/grip_dropped_simulation_stopper | POST /settings/features/grip_hook/enabled |
POST /experimental/features/screensaver_enable | POST /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_origin → inverse3[*].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_origin | Nouveau préréglage |
|---|---|
device_base | arm_front (ou defaults) |
workspace_center | arm_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_basis → session.configure.basis
// Old — deprecated
{ "session": { "set_basis": { "basis": { "permutation": "X-ZY" } } } }
// New — canonical
{ "session": { "configure": { "basis": { "permutation": "XZ-Y" } } } }
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.
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 :
- HTTP (en exécution)
- Fichier de configuration (persistant)
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.
Ajouter la clé à haply-inverse-service-config.json:
{
"serialization/wireless_verse_grip/legacy_mode": false
}
Emplacements des fichiers de configuration (l'un des suivants) :
| Plateforme | Chemin |
|---|---|
| Windows | C:\ProgramData\Haply\Inverse\haply-inverse-service-config.json |
| macOS | /Library/Application Support/Haply/Inverse/haply-inverse-service-config.json |
| Linux | /etc/haply-inverse-service/haply-inverse-service-config.json |
Redémarrez le service (ou le Haply ) pour que la modification prenne effet.
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 :
config.typeest 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).config.sub_typeest 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 lewireless_verse_grip::subtypeénumération directement, distincte deconfig.type'sdevice_typeenum. 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 émettresub_type.- 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_gripLe tableau n'est affiché que lorsque vous changez de sensexplicit_custom = true, auquel cas ce tableau devient réservé à l'utilisation personnalisée (le stylet n'y apparaît jamais). - Les charges utiles à structure personnalisée restent sous forme d'octets d'extension bruts.
extended_data/raw_data(par défauttrue) conserve le format brutstate.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_fieldspeut 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.
- Ancien (version 3.5 par défaut)
- Activation (legacy_mode = false, paramètres par défaut)
{
"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]
}
}
]
}
{
"wireless_verse_grip": [
{
"device_id": "1615",
"config": { "type": "wireless_verse_grip", "sub_type": "stylus", "…": "…" },
"state": {
"buttons": { "a": false, "b": false, "c": false },
"hall": 16,
"orientation": { "x": 0, "y": 0, "z": 0, "w": 1 }
}
},
{
"device_id": "1419",
"config": { "type": "custom_verse_grip", "sub_type": "ruko", "…": "…" },
"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]
}
}
]
}
Dans cet exemple, les trois autres boutons sont réglés sur leurs valeurs par défaut
(explicit_custom = false, raw_data = true, custom_fields = false),
de sorte que les douanes partagent le wireless_verse_grip tableau, le séparé
custom_verse_grip Le tableau n'est pas émis, et l'entrée ruko contient les
données brutes extension_data tableau d'octets que le client doit traduire localement.
Principales différences lorsque vous vous inscrivez :
| Aspect | Ancien (version 3.5 par défaut) | Inscription (legacy_mode = false) |
|---|---|---|
config.type pour les lignes personnalisées sous wireless_verse_grip | nom du sous-type (par exemple "ruko") | famille d'origine "custom_verse_grip" |
config.sub_type | absent | actuellement — "stylus" / "prototype" / "ruko" / "kingfisher" |
custom_verse_grip tableau émis | toujours (lorsqu'une poignée personnalisée est connectée) | uniquement lorsque explicit_custom = true |
| Schéma d'état avec prise personnalisée | brut extension_data octets + a/b/c boutons | mê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_grip | jamais | jamais |
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.
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 = falsepour 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 lewireless_verse_grip[]tableau à côté des entrées au stylet ; pas de fichier séparécustom_verse_griple tableau est émis.true— les droits de douane sont également perçus dans le cadre d'un système spécifiquecustom_verse_grip[]tableau (et continuent d'apparaître souswireless_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 = falsepour 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 = falsepour avoir un effet.
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_custom | raw_data | custom_fields | wireless_verse_grip[] contient | custom_verse_grip[] contient |
|---|---|---|---|---|
false (par défaut) | true (par défaut) | false (par défaut) | stylus (simple) + données brutes (octets bruts) | (non émis) |
false | false | true | stylet (standard) + personnalisations (traduites) | (non émis) |
false | true | true | stylus (brut) + données personnalisées (octets bruts + traduits) | (non émis) |
true | true | false | stylus (simple) + données brutes (octets bruts) | données brutes (octets bruts) |
true | false | true | stylet (standard) + personnalisations (traduites) | douanes (traduit) |
true | true | true | stylus (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
- Référence des paramètres — les quatre
serialization/wireless_verse_grip/*clés. - Protocole WebSocket — aperçu complet et structure des trames de streaming.
- Référence AsyncAPI — schéma lisible par machine pour toutes les charges utiles de la version 3.1.
- Référence de l'API HTTP — Swagger UI pour les routes HTTP actuelles et leurs équivalents remplaçant les points de terminaison obsolètes énumérés ci-dessus.