Service Inverse de Haply
Le service inverse Haply est un composant fondamental qui intègre les dispositifs tactiles 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%\NHaply\NInverse\N*-config.json
- Les fichiers journaux sont situés dans : %PROGRAMDATA%\NHaply\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
Interfaces
Les interfaces HTTP et Websocket utilisent toutes deux la fonction JSON
des charges utiles formatées.
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.0/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.0/devices
Exemple de réponse :
{
"inverse3": {
"049D": {
"config": {
"device_info": {
"firmware_version": 1,
"hardware_version": 7,
"id": "049D",
"model": 4,
"uuid": "5A9F3AC02E085C078AD6A4A113DE049D"
},
"extended_device_id": "5A9F3AC02E085C078AD6A4A113DE049D",
"extended_firmware_version": "77488E4644CB6057D0920B0B919C8B82",
"gravity_compensation": {
"enabled": true,
"scaling_factor": 0.75
},
"handedness": "left",
"torque_scaling": {
"enabled": true
}
},
"device_id": "049D",
"state": {
"angular_position": {
"a0": 0.0,
"a1": 0.0,
"a2": 0.0
},
"angular_velocity": {
"a0": 0.0,
"a1": 0.0,
"a2": 0.0
},
"body_orientation": {
"w": 1.0,
"x": 0.0,
"y": 0.0,
"z": 0.0
},
"calibrated": false,
"cursor_position": {
"x": 0.0,
"y": 0.0,
"z": 0.0
},
"cursor_velocity": {
"x": 0.0,
"y": 0.0,
"z": 0.0
},
"in_use": false,
"mode": "idle",
"power_supply": false,
"ready": false,
"started": false
},
"status": {
"initialization_received": {
"body_orientation": true,
"device_handedness": true,
"device_info": true,
"extended_device_id": true,
"extended_firmware_version": true,
"gravity_compensation": true,
"torque_scaling": true
},
"port": "COM12"
}
}
},
"verse_grip": {
"61582": {
"button": false,
"device_id": "61582",
"error": 0,
"hall": 0,
"orientation": {
"w": 0.17022705078125,
"x": -0.24114990234375,
"y": -0.95538330078125,
"z": -0.001220703125
}
}
},
"wireless_verse_grip": {
"0": {
"battery_level": 0.6200001239776611,
"buttons": {
"a": false,
"b": false,
"c": false
},
"device_id": "0",
"hall": 15,
"orientation": {
"w": -0.906463623046875,
"x": -0.379058837890625,
"y": -0.111785888671875,
"z": -0.136688232421875
}
}
}
}
Échelle des forces
Méthode : POST
URL : http://localhost:10000/3.0/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.0/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.0/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.0/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.0/save_configuration
Exemple de corps :
{
"device_id": "049D"
}
Exemple de réponse :
{
"ok": true
}
Websocket
L'URL par défaut est ws://localhost:10000
. 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": {
"049D": {
"config": {
"device_info": {
"firmware_version": 1,
"hardware_version": 7,
"id": "049D",
"model": 4,
"uuid": "5A9F3AC02E085C078AD6A4A113DE049D"
},
"extended_device_id": "5A9F3AC02E085C078AD6A4A113DE049D",
"extended_firmware_version": "77488E4644CB6057D0920B0B919C8B82",
"gravity_compensation": {
"enabled": true,
"scaling_factor": 0.75
},
"handedness": "left",
"torque_scaling": {
"enabled": true
}
},
"device_id": "049D",
"state": {
"angular_position": {
"a0": -90.40308380126953,
"a1": 3.390819549560547,
"a2": 0.8826223015785217
},
"angular_velocity": {
"a0": 0,
"a1": 0,
"a2": 0
},
"body_orientation": {
"w": 1,
"x": 0,
"y": 0,
"z": 0
},
"calibrated": false,
"cursor_position": {
"x": -0.022379431873559952,
"y": -0.011212021112442017,
"z": -0.11827600002288818
},
"cursor_velocity": {
"x": 0,
"y": 0,
"z": 0
},
"in_use": false,
"mode": "angle",
"power_supply": true,
"ready": true,
"started": true
},
"status": {
"initialization_received": {
"body_orientation": true,
"device_handedness": true,
"device_info": true,
"extended_device_id": true,
"extended_firmware_version": true,
"gravity_compensation": true,
"torque_scaling": true
},
"port": "COM12"
}
}
},
"verse_grip": {
"61582": {
"button": false,
"device_id": "61582",
"error": 0,
"hall": 0,
"orientation": {
"w": 0.156982421875,
"x": -0.24163818359375,
"y": -0.95751953125,
"z": -0.00079345703125
}
}
},
"wireless_verse_grip": {
"0": {
"battery_level": 0.5999999046325684,
"buttons": {
"a": false,
"b": false,
"c": false
},
"device_id": "0",
"hall": 15,
"orientation": {
"w": -0.91265869140625,
"x": -0.389984130859375,
"y": -0.075103759765625,
"z": -0.07635498046875
}
}
}
}
Message de mise à jour de l'état
Chaque fois que tous des dispositifs disponibles, le service enverra un message de mise à jour de l'état contenant l'état de tous les appareils. Le message de mise à jour de l'état présente les caractéristiques suivantes JSON
format :
{
"inverse3": {
"049D": {
"state": {
"angular_position": {
"a0": 0,
"a1": 0,
"a2": 0
},
"angular_velocity": {
"a0": 0,
"a1": 0,
"a2": 0
},
"body_orientation": {
"w": 1,
"x": 0,
"y": 0,
"z": 0
},
"calibrated": true,
"cursor_position": {
"x": -0.022203030064702034,
"y": -0.027979673817753792,
"z": -0.1170499324798584
},
"cursor_velocity": {
"x": 0,
"y": 0,
"z": 0
},
"in_use": true,
"mode": "position",
"power_supply": false,
"ready": true,
"started": true
}
}
},
"verse_grip": {
"61582": {
"button": false,
"device_id": "61582",
"error": 0,
"hall": 0,
"orientation": {
"w": 0.15423583984375,
"x": -0.24176025390625,
"y": -0.95794677734375,
"z": -0.0015869140625
}
}
},
"wireless_verse_grip": {
"0": {
"battery_level": 0.5999999046325684,
"buttons": {
"a": false,
"b": false,
"c": false
},
"device_id": "0",
"hall": 15,
"orientation": {
"w": -0.3958740234375,
"x": 0.639190673828125,
"y": -0.404388427734375,
"z": -0.51739501953125
}
}
}
}
Message de commande
Pour envoyer des commandes au inverse3
le client doit envoyer un message de commande. Voici un exemple :
{
"inverse3": {
"049D": [
{
"command": "set_cursor_force",
"values": {
"x": 0,
"y": 0,
"z": 0
}
}
]
}
}
Il est également possible d'envoyer des commandes à plusieurs appareils dans un seul message. en voici un exemple :
{
"inverse3": {
"049D": [
{
"command": "set_cursor_force",
"values": {
"x": 0,
"y": 0,
"z": 0
}
}
],
"049E": [
{
"command": "set_cursor_force",
"values": {
"x": 0,
"y": 0,
"z": 0
}
}
]
}
}
Les commandes suivantes sont actuellement disponibles sur le site inverse3
:
Définir la position du curseur
{
"command": "set_cursor_position",
"values": {
"x": 1.0,
"y": 2.0,
"z": 3.0
}
}
Définir la force du curseur
{
"command": "set_cursor_force",
"values": {
"x": 0.5,
"y": 0.5,
"z": 0.5
}
}
Définir la position angulaire
{
"command": "set_angular_position",
"values": {
"a0": 1.0,
"a1": 2.0,
"a2": 3.0
}
}
Réglage du couple angulaire
{
"command": "set_angular_torque",
"values": {
"a0": 0.5,
"a1": 0.5,
"a2": 0.5
}
}