Nos 3 étudiants de B3 développement et M1 développement poursuivent leur projet <IA/> RACING. Pour rappel, ce projet pédagogique consister à créer une IA capable de réaliser le meilleur chrono sur un circuit grâce à une voiture autonome.
Rappels sur le framework et l'utilisation des parts
Nous avions évoqué plus tôt, le framework Donkey Car dans ce projet. Nos étudiants ont ainsi pu assister à une réunion d’informations afin de mieux appréhender le concept de “parts” qui permettent d’accélérer la vitesse de la boucle principale.
Pour rappel, le framework Donkey Car est composé de deux dossiers principaux :
- Le dossier Donkey Car, tiré du Git et où est regroupé l’ensemble du framework. Ce dossier comprend le fichier principal vehicle.py ainsi que les différentes “parts” ajoutés grâce au manage.py.
- Le dossier cars contenant les instances de voiture ainsi que les fichiers de configuration et le fichier manage.py. Ce dernier, sert de lanceur indépendant pour chaque voiture. Il instancie ainsi le fichier vehicle.py. Ce dossier dispose également de deux fichiers de configuration : config.py qui est le fichier de base, et myconfig.py qui est le fichier de configuration spécifique à la voiture qui est développée.
- De manière synchrone, c’est-à-dire que chaque part s’exécute l’une après l’autre et en résulte un temps d’exécution et donc une fréquence. Celui-ci ne doit pas descendre sous les 10Hz.
- Via l’utilisation de threaded parts, c’est-à-dire, une part indépendante qui s’exécute sans impacter la boucle principale et donc sa vitesse d’exécution.
Développer la part d'information et en mesurer son temps d'exécution
Cette part sert à remonter la fréquence d’exécution de l’ensemble des parts. Elle peut également servir à termes, à remonter tout type d’informations (accélération, direction en cours…).
Développer la part information de manière synchrone
Cette part test_information.py, comme toutes les parts, est composée d’une classe, ici :
class TestInformation(object) et de deux fonctions : def __init__(self) servant à initialiser nos variables, ici, self.care_frequency = 0 et self.last_calc_time = time.time(); et def run(self) pour exécuter ce que l’on souhaite.
Afin que cette part soit prise en compte, il faut l’ajouter au fichier manage.py ou complete.py (si vous souhaitez impacter toutes vos voitures) et l’importer de cette manière au fichier :
from donkeycar.parts.test_information import TestInformation
V.add(TestInformation())
Pour mesurer son temps d’exécution, il faut importer la librairie time et implémenter dans la fonction run() :
self.car_frequency = 1/(time.time()-self.last_calc_time)
self.last_calc-time = time.time()
Puis, pour l’afficher à l’écran : print(” Frequency : ” + str(self.car_frequency) + “Hz”)
Cependant, l’utilisation de cette part rallonge en moyenne de 2.28ms l’exécution de l’ensemble de la boucle. Pour optimiser cela, il faut utiliser une threaded part.
Transformer notre part en threaded part
Afin de transformer notre part synchrone en threaded part, plusieurs modifications sont à réaliser :
- Dans le fichier manage.py, il faut ajouter “threaded = True” à
from donkeycar.parts.test_information import TestInformation
V.add(TestInformation(), threaded=True) - Dans le fichier test_information.py, il faut rajouter la fonction update et modifier son code de la façon suivante.
def __init__(self) :
self.on = True // variable qui sert à indiquer à la fonction update le démarrage de la part
self.care_frequency = 0
self.last_calc_time = time.time()
self.on = False
while self.on : // Tant que la boucle est en cours, les actions ci-dessous s’effectuent
time.sleep(5) // Afin que cette fonction ne s’exécute que toutes les 5 secondes pour ne pas polluer l’écran
self.last_calc-time = time.time()
Par Léna Queguiner
Chargée de communication