Service Inverse de Haply
Le service inverseHaply est un composant fondamental qui intègre les dispositifs tactiles de Haply avec des applications interactives, fonctionnant comme un service Windows en arrière-plan pour permettre des interactions en temps réel. Ses fonctionnalités sont les suivantes
- Découverte et gestion des appareils : Identifie et configure automatiquement les appareils Haply connectés.
- Gestion de la propriété : Gère l'accès aux appareils à travers plusieurs applications, garantissant ainsi un fonctionnement sans heurts.
- Flux d'état en temps réel : Fournit des mises à jour sur les états de l'appareil à haute fréquence pour un contrôle précis.
- Traitement des commandes : Exécute les commandes de force ou de position avec une grande fidélité, améliorant ainsi le retour d'information haptique.
- Fonctionnement en arrière-plan : S'exécute en arrière-plan et maintient l'appareil en état de marche sans intervention de l'utilisateur.
Exécuter, arrêter, redémarrer
Sous Windows :
- Ouvrir le Services l'application de bureau : Appuyez sur
Windows
+R
pour ouvrir le Exécuter Dans la boîte de dialogue, entrezservices.msc
puis appuyez surEnter
ou sélectionnerOK
.
Sur Ubuntu :
- Démarrage
systemctl start haply-inverse-service.service
- Arrêter
systemctl stop haply-inverse-service.service
- Activer
systemctl enable haply-inverse-service.service
- Désactiver
systemctl disable haply-inverse-service.service
Dossiers importants
Sous Windows :
- Les fichiers de configuration sont situés dans : %PROGRAMDATA%\N-Haply\NInverse\N*-config.json
- Les fichiers journaux sont situés dans : %PROGRAMDATA%\N-Haply\NInverse\N*-log.log
Sur Ubuntu :
- Les fichiers de configuration sont situés dans : /etc/haply-inverse-service/*-config.json
- Les fichiers journaux sont situés dans : /var/log/haply-inverse-service/*-log.log
Sur OSX :
- Les fichiers de configuration sont situés dans : $TMPDIR/Haply/Inverse/*-config.json
- Les fichiers journaux sont situés dans : $TMPDIR/Haply/Inverse/*-log.log
Versions du format JSON
Le service prend actuellement en charge deux types de services différents JSON
formats : 3.0
et 3.1
. Les deux versions sont disponibles simultanément, ce qui garantit la compatibilité ascendante. Si vous utilisez la version 3.0
dans vos simulations, aucune modification n'est nécessaire - le système continuera à fonctionner comme avant.
Cependant, nous vous encourageons à mettre à jour le format 3.1.x
afin de profiter de ses améliorations et de ses performances accrues pour l'intégration des moteurs de jeu.
Détails clés
-
3.0
Version- Entièrement documenté dans le
3.0.x
pages de documentation. HTTP
accessible par défaut sur http://localhost:10000/3.0.Websockets
accessible par défaut sur port10000
.
- Entièrement documenté dans le
-
3.1
Version- Entièrement documenté dans le
3.1.x
pages de documentation. HTTP
accessible par défaut sur http://localhost:10000/3.1.Websockets
accessible par défaut sur port10001
.- Amélioration des fonctionnalités et intégration plus rapide avec les moteurs de jeu.
- Entièrement documenté dans le
N'hésitez pas à passer à la version 3.1
à votre convenance pour tirer parti de ses avantages sans perturber vos flux de travail existants.
Interfaces
Les interfaces HTTP et Websocket utilisent toutes deux la fonction JSON
des charges utiles formatées.
Lors de la lecture de la position de l'effecteur, vous devez envoyer une valeur de force à l'appareil (même si les valeurs de force sont toutes nulles).
HTTP
Par défaut, le service HTTP démarre sur : http://localhost:10000
. Note : le port peut être modifié dans la configuration.
Tableau de bord
Le tableau de bord est disponible à l'adresse suivante http://localhost:10000
Version
Méthode : GET
URL : http://localhost:10000/3.1/version
Exemple de réponse :
{
"build_time": "2024-08-07T16:01:53Z",
"git_branch": "main",
"git_describe": "3.0.0-2-gce34c39e",
"git_hash": "ce34c39e",
"git_tag": "3.0.0",
"project_name": "haply-inverse-service",
"project_version": "3.0.0.0"
}
Dispositifs
Méthode : GET
URL : http://localhost:10000/3.1/devices
Exemple de réponse :
{
"inverse3": [
{
"device_id": "04BA",
"config": {
"type": "inverse3",
"device_info": {
"firmware_version": 1,
"hardware_version": 7,
"id": "04BA",
"model": 4,
"uuid": ""
},
"port": "COM13",
"extended_device_id": "2D35F80DD9005F599B68F49944CB04BA",
"extended_firmware_version": "8C20FDC8010AA1E15AA133CDA2534874",
"gravity_compensation": {
"enabled": true,
"scaling_factor": 1
},
"handedness": "right",
"torque_scaling": {
"enabled": true
}
},
"state": {
"angular_position": {
"a0": -69.31704,
"a1": 137.62952,
"a2": 19.832787
},
"angular_velocity": {
"a0": 0,
"a1": 0,
"a2": 0
},
"body_orientation": {
"x": -0.01940918,
"y": 0.7026367,
"z": 0.00048828125,
"w": 0.7113037
},
"cursor_position": {
"x": 0.07842738,
"y": -0.14836666,
"z": 0.14297646
},
"cursor_velocity": {
"x": -0.011969013,
"y": 0.0012009288,
"z": -0.043197
},
"mode": "idle"
},
"status": {
"calibrated": false,
"in_use": false,
"power_supply": true,
"ready": true,
"started": true
}
}
],
"verse_grip": [
{
"device_id": "61548",
"config": {
"port": "COM3",
"type": "verse_grip"
},
"state": {
"button": false,
"hall": 0,
"orientation": {
"x": -0.5019531,
"y": 0.8632202,
"z": -0.048095703,
"w": -0.022338867
}
},
"status": {
"error": 0,
"ready": true
}
}
],
"wireless_verse_grip": [
{
"device_id": "0",
"config": {
"port": "COM6",
"type": "wireless_verse_grip"
},
"state": {
"battery_level": 0.42000008,
"buttons": {
"a": false,
"b": false,
"c": false
},
"hall": 16,
"orientation": {
"x": -0.019866943,
"y": -0.017486572,
"z": 0.05508423,
"w": -0.9963989
}
},
"status": {
"ready": true
}
}
]
}
Échelle des forces
Méthode : POST
URL : http://localhost:10000/3.1/force_scale
Exemple de corps :
{
"force_scale": 0.5
}
Exemple de réponse :
{
"ok": true
}
Compensation de la gravité
Méthode : POST
URL : http://localhost:10000/3.1/gravity_compensation
Exemple de corps :
{
"device_id": "049D",
"enable": true,
"gravity_scaling_factor": 0.8
}
Exemple de réponse :
{
"ok": true
}
Mise à l'échelle du couple
Méthode : POST
URL : http://localhost:10000/3.1/torque_scaling
Exemple de corps :
{
"device_id": "049D",
"enable": true
}
Exemple de réponse :
{
"ok": true
}
Manipulation de l'appareil
Méthode : POST
URL : http://localhost:10000/3.1/device_handedness
Exemple de corps :
{
"device_id": "049D",
"handedness": "right"
}
Exemple de réponse :
{
"ok": true
}
Sauvegarder la configuration
Ne fonctionne qu'avec les appareils Inverse3 . Attention : Évitez de sauvegarder la configuration trop souvent, car le nombre de sauvegardes pouvant être appliquées à un appareil donné est limité.
Méthode : POST
URL : http://localhost:10000/3.1/save_configuration
Exemple de corps :
{
"device_id": "049D"
}
Exemple de réponse :
{
"ok": true
}
Activation série
Active ou désactive toute la communication série. Lorsque la communication série est désactivée, il est impossible d'envoyer des commandes aux appareils.
Méthode : POST
URL : http://localhost:10000/3.1/serial_enable
Exemple de corps :
{
"enable": true
}
Exemple de réponse :
{
"ok": true
}
Grip Vertical Stopper
Activer ou désactiver la fonction expérimentale d'arrêt vertical de la poignée. Cette fonction vérifie l'orientation du VerseGrip sans fil pour détecter si le VerseGrip est tombé. Lorsqu'elle se déclenche, elle place le Inverse3 en contrôle de position dans sa position actuelle afin que l'effecteur ne tombe pas. Elle est désactivée automatiquement lorsque le VerseGrip est ramassé à nouveau.
En tant que fonction expérimentale, elle est désactivée par défaut et doit être explicitement activée pour être activée.
Méthode : POST
URL : http://localhost:10000/3.1/experimental/features/grip_dropped_simulation_stopper
Exemple de corps :
{
"enable": true,
"hall_effect_threshold": 17
}
Exemple de réponse :
{
"ok": true
}
Websocket
L'URL par défaut est ws://localhost:10001
. Note : le port peut être modifié dans la configuration.
Message initial
Le service envoie un message contenant la liste complète des appareils lorsqu'un websocket est connecté. Le message initial contient les éléments suivants JSON
format :
{
"inverse3": [
{
"device_id": "04BA",
"config": {
"type": "inverse3",
"device_info": {
"firmware_version": 1,
"hardware_version": 7,
"id": "04BA",
"model": 4,
"uuid": ""
},
"port": "COM13",
"extended_device_id": "2D35F80DD9005F599B68F49944CB04BA",
"extended_firmware_version": "8C20FDC8010AA1E15AA133CDA2534874",
"gravity_compensation": {
"enabled": true,
"scaling_factor": 1
},
"handedness": "right",
"torque_scaling": {
"enabled": true
}
},
"state": {
"angular_position": {
"a0": -69.31704,
"a1": 137.62952,
"a2": 19.832787
},
"angular_velocity": {
"a0": 0,
"a1": 0,
"a2": 0
},
"body_orientation": {
"x": -0.01940918,
"y": 0.7026367,
"z": 0.00048828125,
"w": 0.7113037
},
"cursor_position": {
"x": 0.07842738,
"y": -0.14836666,
"z": 0.14297646
},
"cursor_velocity": {
"x": -0.011969013,
"y": 0.0012009288,
"z": -0.043197
},
"mode": "idle"
},
"status": {
"calibrated": false,
"in_use": false,
"power_supply": true,
"ready": true,
"started": true
}
}
],
"verse_grip": [
{
"device_id": "61548",
"config": {
"port": "COM3",
"type": "verse_grip"
},
"state": {
"button": false,
"hall": 0,
"orientation": {
"x": -0.5019531,
"y": 0.8632202,
"z": -0.048095703,
"w": -0.022338867
}
},
"status": {
"error": 0,
"ready": true
}
}
],
"wireless_verse_grip": [
{
"device_id": "0",
"config": {
"port": "COM6",
"type": "wireless_verse_grip"
},
"state": {
"battery_level": 0.42000008,
"buttons": {
"a": false,
"b": false,
"c": false
},
"hall": 16,
"orientation": {
"x": -0.019866943,
"y": -0.017486572,
"z": 0.05508423,
"w": -0.9963989
}
},
"status": {
"ready": true
}
}
]
}
Message de mise à jour de l'état
Le service envoie un message de mise à jour de l'état contenant l'état de tous les dispositifs pour chaque message de commande reçu.
Si vous souhaitez connaître l'état de la machine, vous devez lui envoyer un message au préalable, tel qu'une valeur de force (même si les valeurs sont des zéros). Ceci est particulièrement important si l'on utilise nos appareils comme dispositif d'entrée, par exemple en suivant la position et en n'appliquant pas de force. Le message de mise à jour de l'état a les caractéristiques suivantes JSON
format :
{
"inverse3": [
{
"device_id": "04BA",
"state": {
"angular_position": {
"a0": -69.31704,
"a1": 137.62952,
"a2": 19.832787
},
"angular_velocity": {
"a0": 0,
"a1": 0,
"a2": 0
},
"body_orientation": {
"x": -0.01940918,
"y": 0.7026367,
"z": 0.00048828125,
"w": 0.7113037
},
"cursor_position": {
"x": 0.07842738,
"y": -0.14836666,
"z": 0.14297646
},
"cursor_velocity": {
"x": -0.011969013,
"y": 0.0012009288,
"z": -0.043197
},
"mode": "idle"
},
"status": {
"calibrated": false,
"in_use": false,
"power_supply": true,
"ready": true,
"started": true
}
}
],
"verse_grip": [
{
"device_id": "61548",
"state": {
"button": false,
"hall": 0,
"orientation": {
"x": -0.5019531,
"y": 0.8632202,
"z": -0.048095703,
"w": -0.022338867
}
},
"status": {
"error": 0,
"ready": true
}
}
],
"wireless_verse_grip": [
{
"device_id": "0",
"state": {
"battery_level": 0.42000008,
"buttons": {
"a": false,
"b": false,
"c": false
},
"hall": 16,
"orientation": {
"x": -0.019866943,
"y": -0.017486572,
"z": 0.05508423,
"w": -0.9963989
}
},
"status": {
"ready": true
}
}
]
}
Message de commande
Pour envoyer des commandes au inverse3
le client doit envoyer un message de commande. Voici un exemple :
{
"inverse3": [
{
"device_id": "049D",
"commands": {
"set_cursor_force": {
"values": {
"x": 1.0,
"y": 2.0,
"z": 3.0
}
}
}
}
],
"verse_grip": [],
"wireless_verse_grip": []
}
Il est également possible d'envoyer des commandes à plusieurs appareils dans un seul message. en voici un exemple :
{
"inverse3": [
{
"device_id": "049D",
"commands": {
"set_cursor_force": {
"values": {
"x": 1.0,
"y": 2.0,
"z": 3.0
}
}
}
},
{
"device_id": "049E",
"commands": {
"set_cursor_force": {
"values": {
"x": 1.0,
"y": 2.0,
"z": 3.0
}
}
}
}
],
"verse_grip": [],
"wireless_verse_grip": []
}
Les commandes suivantes sont actuellement disponibles sur le site inverse3
:
Définir la position du curseur
{
"inverse3": [
{
"device_id": "049D",
"commands": {
"set_cursor_position": {
"values": {
"x": 1.0,
"y": 2.0,
"z": 3.0
}
}
}
}
],
"verse_grip": [],
"wireless_verse_grip": []
}
Définir la force du curseur
{
"inverse3": [
{
"device_id": "049D",
"commands": {
"set_cursor_force": {
"values": {
"x": 1.0,
"y": 2.0,
"z": 3.0
}
}
}
}
],
"verse_grip": [],
"wireless_verse_grip": []
}
Définir la position angulaire
{
"inverse3": [
{
"device_id": "049D",
"commands": {
"set_cursor_force": {
"values": {
"x": 1.0,
"y": 2.0,
"z": 3.0
}
}
}
}
],
"verse_grip": [],
"wireless_verse_grip": []
}
Réglage du couple angulaire
{
"inverse3": [
{
"device_id": "049D",
"commands": {
"set_angular_torque": {
"values": {
"a0": 1.0,
"a1": 2.0,
"a2": 3.0
}
}
}
}
],
"verse_grip": [],
"wireless_verse_grip": []
}
Commandes de sondage
probe_cursor_position
, probe_angular_position
pour le site inverse3, et probe_orientation
pour le vers
grips all ne contient aucune donnée de commande.
{
"inverse3": [
{
"device_id": "049D",
"commands": {
"probe_cursor_position": {},
"probe_angular_position": {}
}
}
],
"verse_grip": [
{
"device_id": "049D",
"commands": {
"probe_orientation": {}
}
}
],
"wireless_verse_grip": [
{
"device_id": "049D",
"commands": {
"probe_orientation": {}
}
}
]
}