Skip to main content
Version : 3.1.0

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, entrez services.mscpuis appuyez sur Enter ou sélectionner OK.

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 port 10000.
  • 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 port 10001.
    • Amélioration des fonctionnalités et intégration plus rapide avec les moteurs de jeu.

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.

info

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.

avertissement

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": {}
}
}
]
}