Jeu Setup Architecture Expérimentation
Constante FRAME_SKIP GAME_SPEED NUM_INSTANCE MOVE_BALL BALL_SPEED AFFICHE_SCREEN SIMULATION_PER_STATS ResX & ResY REPLAY_FOLDER LIM_X LIM_Y LIM_Z PITCH_LIM YAW_LIM ROLL_LIM BLUE_TEAM ORANGE_TEAM ActionParser Initialisation Espace des actions Génération de la table de recherche Analyse des actions Environnement Observer Reward Fonction de récompense par évènement GoalScoredReward BoostDifferenceReward BallTouchReward DemoReward KickoffReward FirstTouchReward SaveReward Fonction de récompense par tick DistancePlayerBallReward DistanceBallGoalReward FacingBallReward AlignBallGoalReward ClosestToBallReward TouchedLastReward BehindBallReward VelocityPlayerBallReward VelocityReward BoostAmountReward ForwardVelocityReward VelocityBallOwnGoalReward VelocityBallOpponentGoalReward Pénalités AirPenalityReward DontTouchPenalityReward DontGoalPenalityReward BehindTheBallPenalityReward State BetterRandom TrainingStateSetter DefaultStateClose RandomState InvertedState DefaultStateCloseOrange RandomStateOrange InvertedStateOrange LineState Alea Attaque Defense AirBallAD DefenseRapide Mur ChaosState ReplayState Callback CustomTerminal CustomPolicy lectureGraph log_rew stats_bot

Architecture du projet

Constante.py🡇

Ce fichier contient l'ensemble des constantes qui sont utilisés par la suite dans le code, nous allons vous les décrire une par une en spécifiant leur utilité.

FRAME_SKIP

Permet de définir à quelle fréquence on avance d'un 'time step'. Si le 'Frame skip' vaut 8, cela signifie qu'à chaque 8 frames, on avance d'un 'time step'. Avancer d'un 'time step' implique de demander un nouvel input au bot.

GAME_SPEED [0 ; 100]

Vous permet de définir à quelle vitesse vous souhaitez que votre jeu s'accélère, la valeur 1 désigne la vitesse par défaut du jeu.

NUM_INSTANCE [1 ; 8]

Vous permet d'ouvrir plus d'une instance de rocket league pour obtenir une simulation plus rapide (exemple: 4 ouvrira 4 fois rocket league). Assurez-vous d'avoir la puissance machine requise pour ouvrir un tel nombre d'instance.

MOVE_BALL [False ; True]

Il existe un grand nombre d'états initiaux (state) disponible. Dans la plupart de ces derniers, la balle apparait sans vitesse initiale. Il vous suffit de passer cette constante à True afin que la balle bénéficie d'une vitesse et d'une direction aléatoire au début de la plupart des états initiaux proposés. Si vous souhaitez intégrer cette fonctionnalité dans votre propre state, il vous suffira d'ajouter la ligne suivante:

if MOVE_BALL : movement_ball(state_wrapper.ball)

BALL_SPEED [0 ; ?]

Permet de fixer une vitesse maximum à la balle lors des états initiaux énoncé ci-dessus.

AFFICHE_SCREEN [False ; True]

Lancer des simulations permet de récupérer des statistiques, vous avez la possibilité d'observer ces statistiques en tant réel. L'inconvénient est que cela engendre une ouverture et fermeture de fenêtres en continu ce qui peut être dérangeant si vous faites une activité à côté. Si vous souhaitez tout de même observer ces statistiques tout en conservant cette constante à False, il vous suffit de taper cette commande dans le terminal:

python .\lectureGraph.py

SIMULATION_PER_STATS [1 ; ?]

Nous avons évoqué précédement la possibilité de récupérer des statistiques pendant la simulation. Il faut savoir qu'une simulation se compose de multiples sous-simulations, les statistiques sont établis toutes les x sous-simulations. Cette constante vous permet de définir le nombre de sous-simulations minimum requises avant de récupérer les statistiques et les stocker dans le fichier 'stats_bot.txt' .

ResX & ResY

Permet de définir la taille des fenêtres Rocket League pendant la simulation.
Il est possible d'optimiser légèrement la simulation en réduisant la taille des fenêtres Rocket League. Il faut savoir qu'il est possible de diminuer la taille de la fenêtre à 0x0.

REPLAY_FOLDER

Chemin relatif vers le dossier contenant les données sur les replays. Ce chemin est utilisé par le state setter ReplayState.

LIM_X

Coordonnée X maximum correspondant au mur du terrain auquel on soustrait le rayon de la balle.

LIM_Y

Coordonnée Y maximum correspondant au mur du terrain auquel on soustrait le rayon de la balle.

LIM_Z

Coordonnée Z maximum correspondant au plafond du terrain auquel on soustrait le rayon de la balle.

PITCH_LIM

Valeur de rotation maximum sur l'axe x et y (horizontal).

YAW_LIM = np.pi

Valeur de rotation maximum sur l'axe z (vertical).

ROLL_LIM = np.pi

Valeur de tonneau maximum

BLUE_TEAM

ID de l'équipe Bleu

ORANGE_TEAM

ID de l'équipe Orange

Action.py🡇

Un ActionParser est composant responsable de traduire les indices d'actions en actions concrètes adaptées à l'environnement. Il définit comment l'espace des actions est représenté et comment les actions sont traduites des indices à leurs valeurs correspondantes.

Initialisation

Lors de son initialisation, ZeerLookupAction définit des intervalles prédéfinis ou des valeurs discrètes pour chaque dimension d'action. Cela signifie qu'il détermine à l'avance les différentes valeurs que chaque action peut prendre, comme la vitesse, la direction, etc.

Espace des actions

ZeerLookupAction fournit une méthode pour obtenir la représentation de l'espace des actions. Dans ce cas, il s'agit d'un espace discret dont la taille est égale au nombre d'entrées dans la table de recherche.

Génération de la table de recherche

Cette implémentation crée une table de recherche qui associe des indices d'actions à des valeurs d'actions concrètes en fonction des intervalles ou des valeurs discrètes définies précédemment. Cette table couvre à la fois les actions au sol et en vol.

Analyse des actions

ZeerLookupAction est capable de traduire les indices d'actions en valeurs d'actions concrètes en utilisant la table de recherche générée.

Environnement

Utilisation dans l'environnement : Ce composant peut être utilisé dans un environnement de simulation de Rocket League pour permettre à un agent d'interagir avec le jeu en fournissant des actions compréhensibles par le moteur de jeu.

Observer.py🡇

L'observateur est un objet permettant de visualiser l’environnement dans son état actuel, dans le cas de Rocket League, une observation de l’agent se base sur sa position et sa vitesse sur le terrain, les positions et vitesses des autres joueurs ainsi que la position et la vitesse du ballon.

Reward.py🡇

Ce fichier contient l'ensemble des fonctions de récompenses dont le rôle est de donner des points ou à l'inverse des pénalités selon le comportement de l'agent. Nous allons vous présentez l'ensemble des fonctions de récompenses que nous avons pu utiliser jusqu'à présent.
Nous allons vous présenter deux types de fonctions de récompenses, celles qui sont appelées lors d'un évènement précis, et celles qui sont appelées à chaque tick du jeu.

Fonction de récompense par évènement

GoalScoredReward

L'agent est gratifié s'il marque un but. Dans certaines situations initiales, on donne à la balle une vitesse et une direction aléatoire ce qui peut conduire à des simulations où la balle rentre directement dans les cages sans avoir été touché. Ce problème est réglé avec la variable globale 'TOUCH_VERIF', qui vérifie que la balle a été touché au moins une fois par un des deux agents.

BoostDifferenceReward

L'agent est récompensé lorsqu'il accumule et dépense du boost.

BallTouchReward

L'agent est récompensé lorsqu'il touche la balle.

DemoReward

L'agent est récompensé lorsqu'il détruit un adversaire (on peut détruire son adversaire lorsqu'on le percute avec une vitesse 'supersonic').

KickoffReward

L'agent est récompensé s'il remporte le kickoff (kickoff=engagement), si la balle est du côté de son adversaire après le kickoff réalisé, alors on considère ce dernier comme remporté.

FirstTouchReward

L'agent est récompensé s'il touche la balle en premier lors du kickoff.

SaveReward

L'agent est récompensé s'il effectue un arrêt.

Fonction de récompense par tick

DistancePlayerBallReward

Plus l'agent est proche de la balle, plus il est récompensé.

DistanceBallGoalReward

Plus la balle est proche du but adverse (sans prendre en compte l'axe z vertical), plus l'agent est récompensé.

FacingBallReward

Si l'agent fait face à la balle, il est récompensé (pour éviter qu'il ne joue en arrière...).

AlignBallGoalReward

Plus l'agent s'aligne par rapport à la balle et le but adverse, plus il gagne de points.

ClosestToBallReward

Si l'agent est plus proche de la balle que son adversaire, alors il gagne des points.

TouchedLastReward

Si l'agent est le dernier à avoir touché la balle, alors il est récompensé.

BehindBallReward

Si l'agent se situe derrière la balle, alors il est récompensé. En effet, il y a peu d'intérêt pour l'agent de se trouver entre la balle et le but adverse.

VelocityPlayerBallReward

Si l'agent se déplace en direction de la balle, alors il est récompensé.

VelocityReward

Plus l'agent se déplace rapidement, plus il est récompensé.

BoostAmountReward

Plus l'agent possède du boost, plus il est récompensé.

ForwardVelocityReward

Si l'agent avance vers l'avant (pénalise la marche arrière) alors il est récompensé.

VelocityBallOwnGoalReward

Plus la vitesse de la balle vers le but orange est élevée, plus l'agent remporte des points.

VelocityBallOpponentGoalReward

Plus la vitesse de la balle vers le but bleu est élevée, plus l'agent remporte des points.

Pénalités

AirPenalityReward (utilisation déconseillée)

Si le joueur part dans les airs à l'aide de son boost ou saut..etc, il est pénalisé.

DontTouchPenalityReward

L'agent subis une pénalité croissante en fonction du temps tant qu'il n'a pas touché au moins une fois la balle.

DontGoalPenalityReward

L'agent subis une pénalité croissante en fonction du temps tant qu'il n'a pas marqué.

BehindTheBallPenalityReward

L'agent subis une pénalité croissante en fonction du temps tant qu'il n'est pas du bon côté de la balle.

State.py🡇

Ce fichier contient l'ensemble des fonctions proposant un état initial pour une simulation. Cela permet d'entrainer l'agent pour certaines situation pré-fabriquée par nous même.

CombinedState

Ce state setter est inspiré de la classe CombinedReward. Il permet de combiner plusieurs autres state setters et de leur attribuer différentes probabilités d'apparition, ainsi que différents poids pour les récompenses. Le fonctionnement est le suivant : en lui fournissant un tuple de tuples, chaque tuple interne contenant une classe StateSetter et un autre tuple. Si ce tuple interne est laissé vide, il conservera les poids par défaut des récompenses. Si vous le remplissez avec autant de valeurs flottantes qu'il y a de récompenses, il remplacera les poids par défaut des récompenses. (si vous mettez 42 comme poids de récompense, il conservera la valeur par défaut)

BetterRandom

Ce state setter est l'un des états utilisés par Necto. Il génère des états de départ aléatoires avec certaines contraintes et distributions :

  • Position de la balle : Sélectionnée de manière aléatoire à l'intérieur des limites du jeu (`LIM_X`, `LIM_Y`) pour les coordonnées x et y, et suit une distribution triangulaire pour la coordonnée z entre `BALL_RADIUS` et `LIM_Z`.
  • Vélocité linéaire de la balle : Génère une vélocité aléatoire avec une chance de 99,9 % d'être inférieure à la vitesse maximale de la balle (`BALL_MAX_SPEED`). Cela se fait en échantillonnant à partir d'une distribution exponentielle pour garantir que la plupart des vélocités sont inférieures à la vitesse maximale.
  • Vélocité angulaire de la balle : Génère de manière aléatoire une vélocité angulaire avec une distribution triangulaire entre 0 et la vélocité angulaire maximale (`CAR_MAX_ANG_VEL`) plus un petit décalage.
  • Position de la voiture : Calcule une position pour chaque voiture en fonction de la position de la balle, en veillant à ce que la voiture soit, en moyenne, à 1 seconde de la balle à la vitesse maximale. Si la position calculée se trouve à l'intérieur des limites du jeu (`LIM_X`, `LIM_Y`) et au-dessus du sol mais toujours proche de la balle, elle utilise cette position. Sinon, elle génère une position totalement aléatoire.
  • Vélocité linéaire de la voiture : Génère une vélocité linéaire aléatoire avec une distribution triangulaire entre 0 et la vitesse maximale de la voiture (`CAR_MAX_SPEED`).
  • Orientation de la voiture (Rotation) : Définit de manière aléatoire le tangage, le lacet et le roulis de la voiture dans des limites spécifiées (`PITCH_LIM`, `YAW_LIM`, `ROLL_LIM`), en suivant des distributions triangulaires.
  • Vélocité angulaire de la voiture : Génère de manière aléatoire une vélocité angulaire avec une distribution triangulaire entre 0 et la vélocité angulaire maximale de la voiture (`CAR_MAX_ANG_VEL`).
  • Boost de la voiture : Attribue une quantité de boost aléatoire entre 0 et 1 à chaque voiture.

TrainingStateSetter

Ce state setter a été trouvé sur le github RL-in-RL et est conçu pour des scénarios d'entraînement où différentes conditions initiales sont nécessaires pour enseigner à l'agent des compétences ou des comportements spécifiques. Il sélectionne de manière aléatoire parmi plusieurs états de spawn prédéfinis pour fournir une variété de scénarios d'entraînement.

DefaultStateClose

Ce state setter est une variation du state setter par défaut où les positions initiales des voitures sont ajustées pour créer des scénarios d'entraînement avec des distances différentes par rapport à la balle au coup d'envoi. Il sélectionne de manière aléatoire un sous-ensemble de positions de coup d'envoi prédéfinies pour les voitures des équipes bleue et orange et ajuste leurs positions en conséquence.

RandomState

Ce state setter distribue aléatoirement la balle sur le terrain tout en maintenant les voitures dans leurs positions de coup d'envoi par défaut.

InvertedState

Il s'agit d'un état de coup d'envoi normal, mais les voitures sont tournées loin de la balle.

DefaultStateCloseOrange

Similaire à DefaultStateClose, mais les voitures oranges sont positionnées du côté bleu, et les voitures bleues sont du côté orange.

RandomStateOrange

Similaire à RandomState, mais les voitures oranges sont positionnées du côté bleu, et les voitures bleues sont du côté orange.

InvertedStateOrange

Similaire à InvertedState, mais les voitures oranges sont positionnées du côté bleu, et les voitures bleues sont du côté orange.

LineState

Positionne la balle au centre du terrain ainsi que les agents dans leur côté respectif. La fonction prends en paramètre un entier qui détermine la largeur sur l'axe Y et donc une zone dans laquelle la balle et les agents peuvent apparaitre.

Alea

Les voitures et le ballon spawn de manière totalement aléatoire sur le terrain avec une rotation et du boost aléatoire. Cette fonction prend deux paramètre, le premier permet d'ajouter ou non une vitesse initiale à la balle, le second prend en considération dans cette vitesse initiale l'axe Z (vertical).

Attaque

Propose une situation d'attaque & de défense pour l'agent.

Defense

Propose une situation de défense et d'attaque pour l'agent.

AirBallAD

La balle spawn en l'air devant les cage avec un agent positionné pour défendre et l'autre pour attaquer. L'idée est de travailler les balles aériennes.

DefenseRapide

Propose une situation d'attaque et de défense rapide pour l'agent (la balle a une direction orienté vers les cages).

Mur

La balle et l'agent spawn sur le mur lattéral du terrain.

ChaosState

La balle et les voitures sont placées aléatoirement sur le sol avec une orientation et une vitesse aléatoire.

ReplayState

Récupère un fichier de replay au hasard dans le dossier indiqué par la constante REPLAY_FOLDER, puis extrait une frame aléatoire de ce replay. Ensuite, positionne les voitures et la balle comme sur cette frame, avec le même niveau de boost et la même vitesse. Les données des replays ont été récupérées et traitées à l'aide du code disponible à cette adresse : https://github.com/xerneas02/RocketleagueReplayToData.

Callback.py🡇

Un objet callBack est utilisé pour effectuer des actions à des moments spécifiques pendant l'entraînement de l'agent. Un callBack est une fonction ou un objet qui est appelé à des points déterminés pendant l'entraînement de l'agent pour effectuer des tâches telles que la sauvegarde de modèles, l'enregistrement de statistiques d'entraînement, la modification dynamique des hyperparamètres, ou toute autre opération personnalisée.

CustomTerminal.py🡇

Les terminal conditions sont des événements qui signalent la fin d'un épisode. Elles doivent implémenter à la fois une méthode de réinitialisation (reset) et une méthode is_terminal.

BallTouchCondition

Cette terminal condition vérifie s'il y a eu un contact avec la balle depuis la dernière réinitialisation. Elle réinitialise son état chaque fois que l'état du jeu est réinitialisé.

NoTouchOrGoalTimeoutCondition

Cette condition terminale agit de manière similaire à la timeout_condition de rlgym.utils.terminal_conditions.common_conditions, mais réinitialise le minuteur de temporisation dès que la balle est touchée pour la première fois ou lorsqu'un but est marqué. Elle est initialisée avec une durée de temporisation spécifiée.

NoTouchFirstTimeoutCondition

Similaire à NoTouchOrGoalTimeoutCondition, cette terminal condition réinitialise le minuteur de temporisation lorsque la balle est touchée pour la première fois. Elle s'initialise avec une durée de temporisation spécifiée.

NoGoalTimeoutCondition

Cette terminal condition réinitialise le minuteur de temporisation lorsqu'un but est marqué. Elle s'initialise avec une durée de temporisation spécifiée et peut être modifiée davantage par un coefficient.

AfterTouchTimeoutCondition

Cette terminal condition démarre un minuteur de temporisation lorsque la balle est touchée pour la première fois par n'importe quel joueur.

CustomPolicy.py🡇

Tout agent en apprentissage par renforcement suit ce que l’on appelle une politique, que l’on peut apparenter comme le cerveau de l’agent. C’est le centre névralgique des décisions qu’un agent puisse prendre. La politique et son optimisation sont donc les éléments centraux de notre projet . L’implémentation d’un agent dépend en grande partie de l’algorithme d’apprentissage par ren- forcement utlisé.
Il existe deux grands types d’algorithmes dans ce domaine : — les méthodes basées on-policy dans lesquelles la collecte des données d’apprentissage est réalisée par l’agent lui-même, ce qui couple les performances de la politique de l’agent avec la diversité des données sur lesquelles il s’entraîne.
— les méthodes basées off-policy qui contrairement aux méthodes on-policy découplent l’ex- ploration de l’environnement et le comportement. Ainsi, nous pouvons disposer de deux politiques, une qui régit le comportement de l’agent.

lectureGraph.py🡇

Ce fichier permet de lire les données stockées dans 'stats_bot.txt' et de les visualiser sous forme de graphe. Penser à utiliser la commande suivante:

python .\lectureGraph.py

log_rew.txt🡇

Ce fichier enregistre l'évolution du gain de récompenses des fonctions de récompenses tout au long de la simulation.

stats_bot.txt🡇

Ce fichier contient les données actuelles (nombre de simulations, nombre de balles touchées, nombre de buts marqués, et % de temps passé du bon côté de la balle). Ces données sont récupérer toutes les 'SIMULATION_PER_STATS' simulations.