Implémentation C++ d'un serveur Websocket du protocole Rosbridge.
Il utilise Qt pour l'implémentation Websocket et donc dépend de libqt5websockets5-dev.
Les "compressions" JSON, CBOR et CBOR-RAW sont supportés mais pas la compression PNG.
- compression PNG
- paquets fragmentés
- authentification (
rosauth) - service server
- Autres transports que Websocket (TCP, UDP)
- Mode BSON only
- Regex pour n'autoriser que certains topics et services
En plus des fonctionnalités non implémentées, quelques choix de design diffèrent :
- Le paramètre
typede la requêtecall_serviceest obligatoire. La version Python l'ignore et recherche le type avec l'API rosmaster. - Un watchdog kill le noeud quand la boucle ROS est bloquée pendant plus de 5s
- Supporte la réception de requêtes (appel de service, souscription, publication...) en CBOR. La réponse sera en CBOR seulement si
"compression":"cbor"est présent.
Qt 5.14+ corrige certains bugs dans QWebsocketServer : 5s freeze on client disconnection during frame reception et connection header size too big. La version de Qt fourni par Ubuntu 18.04 et 20.04 n'a pas ces correctifs.
Pour utiliser une version Qt plus récente (par exemple /opt/Qt5.15), il faut set les variables CMake ROSBRIDGE_FORCE_CUSTOM_QT et ROSBRIDGE_FORCE_CUSTOM_QT_DIR.
Les tableaux de int8[] ou uint8[] sont encodés en string codée en base64.
Par exemple le message sensors_msgs/CompressedImage suivant :
m.header...
m.format = "jpeg"
m.data = [0,1,2,3,4,5,6,7,8,9]Sera encodé en :
{
"header": {"seq":123,"stamp":{"secs":123,"nsecs":456},"frame_id":"frame_id"},"format":"jpeg",
"data":"AAECAwQFBgcICQ=="
}Dans l'autre sens, à partir du JSON, les deux formats sont supportés. Tableau de int ou string en base64.
libqt5websockets5-devroscppros_babel_fishrosbridge_cpp_msgsstd_msgs
port(int) : Port de la websocket. La valeur 0 conduit à ce que l'OS donne un port (défaut =9090)service_timeout(double) : Durée du timeout pour les appels de services en secondes (défaut =5.0)pong_timeout_s(double) : Durée de timeout, en secondes, avant que l'on déconnecte le client (défaut =30.0)watchdog_enabled(bool) : Activation du watchdog (défault =true)watchdog_timeout(double) : Timeout du watchdog (défault =5.0)
Le nœud set lui-même le paramètre actual_port, utile dans le cas où port est mis à 0.
Topics hérités du nœud Python :
client_count(std_msgs/Int32) : Nombre de clients connectés, latché et mis à jour à chaque changement du nombre de clients.connected_clients(rosbridge_msgs/ConnectedClients**) : Information sur les clients actuellement connectés, latché et mis à jour à chaque changement du nombre de clients.
Pour tester le fonctionnement avec la boucle d'événements Qt, Qt Test est utilisé.
Mais catkin ne sait utiliser que gtest avec catkin_add_gtest et add_rostest_gtest et donne donc des arguments spécifiques à googletest pour informer du nom du fichier xml de sortie.
Nous modifions donc ces arguments pour les convertir en arguments compris par QTest.
Mais, dans le fichier XML généré par QTest, les testcase n'ont pas de champ time et rosunit (< 1.15.8) gère mal ce cas, ce qui le fait planter et donc échouer les tests.
En attendant d'utiliser une version corrigée de rosunit, il est possible de récupérer la dernière version pour utilisation dans Jenkins :
// Install latest version of rosunit to handle p_rosbridge_server_cpp Qt tests
dir('tmp')
{
sh 'git clone --depth=1 https://github.com/ros/ros'
sh 'cp -r ros/tools/rosunit ../workspace/src'
}