···11#import "@preview/arkheion:0.1.0": arkheion, arkheion-appendices
22+#import "@preview/fletcher:0.5.8": diagram, edge, node
2334#show: arkheion.with(
45 title: "Étude bibliographique I",
···78 ),
89 date: "2 Septembre 2025",
910 abstract: [
1010- Ce stage porte sur l'intégration de Nix et NixOS dans les processus de développement et de déploiement logiciel dans le domaine robotique au sein du LAAS. Nix, le _package manager_, et NixOS, l'OS, sont des technologies permettant une reproductibilité, une qualité importante dans le monde de la recherche.
1111+ Ce stage porte sur l'intégration de Nix et NixOS dans les processus de développement et de déploiement logiciel dans le domaine robotique au sein du LAAS. Nix, le _package manager_, et NixOS, l'OS, sont des technologies permettant une reproductibilité, une qualité importante dans le monde de la recherche.
11121213 J'ai été aussi amenée à travailler sur la création d'un _plugin_ pour Gazebo, un logiciel de simulation robotique, pour l'utiliser avec le _SDK_ d'un robot de Unitree.
1313- ]
1414+ ],
1415)
15161617#outline(
1717- title: [Table des matières]
1818+ title: [Table des matières],
1819)
19202020-= Reproductibilité
2121+= Reproductibilité
21222223== État dans le domaine de la programmation
2324···2829Mais, en contrepartie, on perd une équation qui est fondamentale en mathématiques:
29303031$
3131-forall E, F, forall f: E->F, forall (e_1, e_2) in E^2, e_1 = e_2 => f(e_1) = f(e_2)
3232+ forall E, F, forall f: E->F, forall (e_1, e_2) in E^2, e_1 = e_2 => f(e_1) = f(e_2)
3233$
33343435En programmation, on peut très facilement construire un $f$ qui ne vérifie pas ceci:
···9192 else:
9293 x = 8
9394 return f(x)
9494- ```,
9595+ ```,
9596 ```ocaml
9697 let g x y = f (
9797- if y = 5 then
9898- 6
9999- else
9898+ if y = 5 then
9999+ 6
100100+ else
100101 8
101102 )
102103 ```,
103103- [ *Python* (`if` et `else` sont des instructions) ], [ *OCaml* (`if` et `else` forment une expression) ]
104104+105105+ [ *Python* (`if` et `else` sont des instructions) ], [ *OCaml* (`if` et `else` forment une expression) ],
104106)
105107106108Afin de décrire les dépendances d'un programme, l'environnement de compilation, et les étapes pour le compiler (en somme, afin de définir le $f in "bin"^"src"$), Nix comprend un langage d'expressions @nix-language. Un fichier `.nix` définit une fonction, que Nix sait exécuter pour compiler le code source.
···113115 ```,
114116 ```nix
115117 { a }: a + 3
116116- ```
118118+ ```,
117119)
118120119121Voici un exemple de définition d'un programme, appelée _dérivation_ dans le jargon de Nix:
···163165164166La dérivation ici prend en entrée le code source (`src-odri-masterboard-sdk`), ainsi que des dépendances, que ce soit des fonctions relatives à Nix même (comme `stdenv.mkDerivation`) pour simplifier la définition de dérivation, ou des dépendances au programmes, que ce soit pour sa compilation ou pour son exécution (dans ce dernier cas de figures, les dépendances sont inclues ou reliées au binaire final)
165167166166-== Un ecosystème de dépendances
168168+== Un ecosystème de dépendances
167169168170Afin de conserver la reproductibilité même lorsque l'on dépend de libraries tierces, ces dépendances doivent également avoir une compilation reproductible: on déclare donc des dépendances à des _packages_ Nix, disponibles sur _Nixpkgs_ @nixpkgs.
169171···213215214216== `rt/lowstate`, `rt/lowcmd`
215217216216-Le SDK de Unitree fonctionne via des canaux DDS, une technologie de communication temps-réel bas niveau @dds.
218218+Le SDK de Unitree fonctionne via des canaux DDS, une technologie de communication temps-réel bas niveau @dds.
217219218220Deux de ces canaux donnent accès au contrôle (resp. à l'état) bas-niveau des moteurs (resp. capteurs) du robot: `rt/lowcmd` (resp. `rt/lowstate`).
219221220222Grâce à l'étude des paquets transmis via Wireshark, j'ai pu débugger les communications entre mon plugin, _gz-unitree_, et le SDK.
221223224224+Et au final, mon plugin fonctionne, en simulant un robot H1v2 via ces deux canaux:
225225+226226+#align(center, diagram(
227227+ node((-1, 0))[Unitree SDKv2],
228228+ edge("->", bend: 45deg)[`rt/lowcmd`],
229229+ edge("<-", bend: -45deg)[`rt/lowstate`],
230230+ node((0, 0))[gz-unitree],
231231+ edge("<->")[`::PreUpdate`],
232232+ node((1, 0))[Gazebo],
233233+ edge("--"),
234234+ node((2, 0))[Modèle SDF du robot]
235235+))
236236+222237== Des tests end-to-end automatisés
223238224224-Je souhaitais permettre de tester le code sur simulateur de manière automatique: on push un commit modifiant une politique de contrôle du robot, et, automatiquement, en CI, un test sous simulateur est lancé. On reçoit un artéfact avec une vidéo filmant le test.
239239+Je souhaitais permettre de tester le code sur simulateur de manière automatique: on push un commit modifiant une politique de contrôle du robot, et, automatiquement, en CI, un test sous simulateur est lancé. On reçoit un artéfact avec une vidéo filmant le test.
225240226241Pour faire ceci, il a fallu rendre la fonctionnalité native à Gazebo d'enregistrement vidéo automatisable: elle ne l'est pas nativement, il a donc fallu que je duplique le code du module Gazebo correspondant, afin d'y rajouter de quoi contrôler l'entregistrement vidéo via des _topics_ Gazebo.
227242228228-Il y a aussi un challenge lié au fait que, en CI, il n'y a pas d'interface graphique, ce qui rend le lancement de l'interface graphique de Gazebo impossible. Il faut donc simuler une interface graphique avec _Xvfb_ @xvfb, un serveur X virtuel.
243243+Il y a aussi un challenge lié au fait que, en CI, il n'y a pas d'interface graphique, ce qui rend le lancement de l'interface graphique de Gazebo impossible. Il faut donc simuler une interface graphique avec _XVFB_, un serveur X virtuel @xvfb.
229244230245== Packaging sous Nix
231246