···803803804804Les premiers essais affichent un facteur temps-réel#footnote[Appelé RTF @rtf (Real-Time Factor). Un RTF de 100% signifie que la simulation s'éxécute à vitesse réelle, un RTF inférieur à 1 signifie que la simulation est plus lente que la vitesse simulée] autour des 10 à 15%.
805805806806-En utilisant le _profiler_ de Gazebo @gzprof, on peut capturer des intervalles de temps et les annoter, pour identifier ce qui ralenti les cycles de simulation:
806806+#grid(
807807+ columns: 2,
808808+ gutter: 2em,
809809+ [
810810+ En utilisant le _profiler_ de Gazebo @gzprof, on peut capturer des intervalles de temps et les annoter, pour identifier ce qui ralenti les cycles de simulation.
811811+ ],
812812+ [
813813+ ```cpp
814814+ GZ_PROFILE_BEGIN("Label");
815815+ ...
816816+ GZ_PROFILE_END();
817817+ ```
807818808808-```cpp
809809-GZ_PROFILE_BEGIN("Label");
810810-...
811811-GZ_PROFILE_END();
812812-```
819819+ ]
820820+)
813821814814-Crée un segment nommé "Label" dans le diagramme du profiler.
815815-816816-On peut créer plusieurs segments en parallèle quand le programme possède plusieurs threads:
817817-818818-```cpp
819819-GZ_PROFILE_THREAD_NAME("Nom du thread");
820820-```
821821-822822-On obtient ce diagramme après l'éxécution du programme
822822+// On peut créer plusieurs segments en parallèle quand le programme possède plusieurs threads:
823823+//
824824+// ```cpp
825825+// GZ_PROFILE_THREAD_NAME("Nom du thread");
826826+// ```
823827824828#figure(
825829 caption: [Profiling d'une simulation avec _gz-unitree_],
···844848 )
845849)
846850847847-Quelques mesures ont été tentées pour améliorer le RTF:
851851+852852+Plus de la moitié du temps de calcul du plugin provient de l'envoi de l'état du robot sur le canal DDS `rt/lowstate`.
853853+854854+Notons également que, même si ce cyle-là a duré 0.267 ms, la durée d'un cycle est assez variable, certains atteignent 0.8 ms.
855855+856856+#image("./profiler-two-ticks.png")
857857+858858+Quelques mesures ont été tentées pour réduire le temps nécéssaire à l'envoi d'un message DDS:
848859849860/ Restreindre DDS à `localhost`: Il est possible que DDS envoie les messages en mode "broadcast", c'est-à-dire à
861861+/ Déplacer dans un autre thread: C'est ce qui a motivé la désynchronisation du thread "LowStateWriter" (cf @send-lowstate)
862862+/ Ajuster la fréquence d'envoi: Une fois `LowStateWriter` déplacé dans un thread indépendant, on peut ajuster la fréquence d'envoi, le thread étant récurrant#footnote[Créé avec `CreateRecurrentThreadEx`]
850863864864+Ainsi que d'autres optimisations, qui ne sont pas en rapport avec cette phase d'un cycle: par exemple, la mise en cache de joints à l'initialisation du plugin, pour éviter de devoir appeler `model.JointByName` dans une _hot loop_#footnote[Boucle (`for` ou `while`) dont le corps est exécuté un très grand nombre de fois, et dont la rapidité est importante].
865865+866866+867867+Après optimisations, on arrive à atteindre un RTF aux alentours des 30%. Des recherches supplémentaires sont nécéssaires pour atteindre un RTF raisonnable.
851868852869== Enregistrement de vidéos <video>
853870