J'aimais les jeux de course et jouais à Gran Turismo 5/6, mais après avoir déménagé à Assetto Corsa, j'ai réalisé que je ne courais pas très bien. Plus précisément, la situation est que le véhicule AI (Force = 100%) est séparé de près de 4 secondes par tour (lors de l'utilisation du circuit de Catalunya / TOYOTA GT86, manette de jeu). En GT6, j'ai obtenu tout l'or avec une assistance OFF autre que ABS = 1 / TCS = 1, donc je pensais que je n'étais pas si mal ...
Afin d'analyser pourquoi il y a une telle différence, j'ai également étudié l'outil de visualisation, acquis les données de fonctionnement de mon jeu et de mon jeu AI avec Python, et je les ai visualisés avec Plotly.
À propos, il existe un outil appelé Motec i2 Pro pour l'acquisition et la visualisation de données. Cette fois, j'étudie également des outils de visualisation, donc je n'utiliserai pas Motec.
Assetto Corsa dispose d'un mécanisme appelé «application en jeu» qui permet aux utilisateurs de développer indépendamment des applications qui affichent des données de conduite sur l'écran de jeu en utilisant le langage Python. Des API d'acquisition de données de conduite et des API à afficher à l'écran sont préparées.
Sur la base de ces informations de référence, j'ai réalisé un programme pour acquérir les informations suivantes.
--Nombre de tours
ACTelemetry.py
class ACTelemetry:
(Abréviation)
def logging(self):
if self.outputFile == None:
return
lapCount = ac.getCarState(self.carId, acsys.CS.LapCount) + 1
lapTime = ac.getCarState( self.carId, acsys.CS.LapTime)
speed = ac.getCarState(self.carId, acsys.CS.SpeedKMH)
throttle = ac.getCarState(self.carId, acsys.CS.Gas)
brake = ac.getCarState(self.carId, acsys.CS.Brake)
gear = ac.getCarState(self.carId, acsys.CS.Gear)
rpm = ac.getCarState(self.carId, acsys.CS.RPM)
distance = ac.getCarState(self.carId, acsys.CS.NormalizedSplinePosition)
steer = ac.getCarState(self.carId, acsys.CS.Steer)
(x, y, z) = ac.getCarState(self.carId, acsys.CS.WorldPosition)
self.outputFile.write('{}\t{:.3f}\t{:.4f}\t{:.2f}\t{:.3f}\t{:.3f}\t{}\t{:.0f}\t{:.1f}\t{:.2f}\t{:.2f}\t{:.2f}\n'.format(\
lapCount, lapTime/1000, distance, speed, throttle, brake,
gear, rpm, steer, x, y, z))
(Abréviation)
def acUpdate(deltaT):
global telemetryInstance
telemetryInstance.logging()
Je n'entrerai pas dans les détails du code, mais le mécanisme d'application du jeu exécute ʻacUpdate (deltaT) chaque fois qu'un graphique est mis à jour (60 fois par seconde dans mon environnement). L'acquisition des données et la sortie des fichiers sont effectuées dans ʻACTelemetry.logging ()
appelé depuis ʻacUpdate (deltaT)`.
Pour activer cette application en jeu, procédez comme suit:
L'interface utilisateur suivante sera affichée. Cliquez sur le bouton "Suivant" pour sélectionner le véhicule pour lequel les données seront acquises, et cliquez sur le bouton "Démarrer" pour démarrer l'acquisition du journal.
En conséquence, les données suivantes peuvent être obtenues. J'aimerais obtenir et comparer ces données pour mon jeu et celui de l'IA.
logger_20190817_1257.log
Course : ks_barcelona
Layout : layout_gp
Car Id : 0
Driver : abe.masanori
Driver : ks_toyota_gt86
lapCount lapTime distance speed throttle brake gear RPM steer x y z
1 151.829 0.9399 115.7 1.00 0.00 4 6425 33 490.4 -14.6 -436.3
1 151.846 0.9400 115.8 1.00 0.00 4 6425 33 490.5 -14.6 -435.7
1 151.862 0.9401 115.8 1.00 0.00 4 6421 33 490.5 -14.7 -435.2
1 151.879 0.9402 116.0 1.00 0.00 4 6425 33 490.6 -14.7 -434.7
Cette fois, j'aimerais visualiser les données en utilisant la bibliothèque Javascript de Plotly. Le fichier délimité par des tabulations ci-dessus avec en-tête peut être traité tel quel, mais c'est un peu gênant, alors ajoutez à l'avance le traitement et la mise en forme suivants.
--Supprimer l'en-tête (5 premières lignes d'informations et lignes d'article) --Supprimer les lignes de données autres que le tour concerné --Supprimer les 5 premières lignes et les 5 dernières lignes des données du tour correspondant (pour supprimer les données étranges qui se produisent avant et après le départ / objectif)
Le fichier ressemblera à celui ci-dessous.
my_data_before.js
my_data = [
[2, 0.125, 0.0017, 155.96, 1.000, 0.000, 5, 6672, 0.0, 365.52, -18.43, -187.32],
[2, 0.142, 0.0019, 155.96, 1.000, 0.000, 5, 6672, 0.0, 365.13, -18.43, -186.72],
[2, 0.158, 0.0020, 156.11, 1.000, 0.000, 5, 6674, 0.0, 364.73, -18.43, -186.11],
[2, 0.175, 0.0022, 156.11, 1.000, 0.000, 5, 6676, 0.0, 364.34, -18.44, -185.51],
(Ce qui suit est omis)
Je voudrais faire la visualisation suivante en utilisant Plotly. Vous pouvez en fait le déplacer depuis (here. Il est un peu lourd, mais le GIF animé est [ici](https: // abe-masanori. github.io/AC_analysis/data_viz/ui.gif))
Normalement, ce type de données affiche l'axe horizontal = temps et l'axe vertical = métriques, mais si vous faites cela cette fois, il sera difficile de comparer vos propres données avec les données AI (CPU), donc l'axe horizontal commencera au début. Utilisez les valeurs numériques (0,0: début à 1,0: objectif) qui représentent la distance de.
Commencez par créer un fichier HTML de base.
--Charger la bibliothèque de Plotly.
div
avec Plotly, ajoutez ʻid au
div` dans l'affichage du graphique.viz_before.html
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<title>moi même(Avant amélioration)Et comparaison de données AI</title>
<script src='https://cdn.plot.ly/plotly-latest.min.js'></script>
<style>
html,
body {
margin: 0;
padding: 0;
height: 100%;
display: flex;
}
</style>
</head>
<body>
<div>
<div id="div-speed"></div>
<div id="div-throttle"></div>
<div id="div-brake"></div>
<div id="div-gear"></div>
<div id="div-rpm"></div>
<div id="div-steer"></div>
</div>
<div id="div-position"></div>
</body>
<script src="data/my_data_before.js"></script>
<script src="data/cpu_data.js"></script>
<script src="my_viz.js"></script>
</html>
Étant donné que les graphiques pour la vitesse, l'ouverture de l'accélérateur / frein, le rapport, la vitesse du moteur et l'angle de braquage sont presque les mêmes, un graphique linéaire est transmis avec vos propres données, les données AI (CPU), la position de création du graphique et le titre de l'axe vertical comme arguments. Créez une fonction qui crée.
my_viz.js
function plot_speed(my_x, my_y, cpu_x, cpu_y, divId, title_y){
var data_me = {
x: my_x,
y: my_y,
mode: 'lines',
name: 'me'
};
var data_cpu = {
x: cpu_x,
y: cpu_y,
mode: 'lines',
name: 'cpu'
};
var layout = {
autosize: false,
yaxis: {title: title_y},
width: 600,
height: 250,
margin: {l: 70, r: 70, b: 25, t: 25}
};
Plotly.newPlot(divId, [data_me, data_cpu], layout);
}
my_data_distance = Array.from(my_data, x => x[2]);
cpu_data_distance = Array.from(cpu_data, x => x[2]);
my_data_speed = Array.from(my_data, x => x[3]);
cpu_data_speed = Array.from(cpu_data, x => x[3]);
plot_speed(
my_data_distance, my_data_speed, cpu_data_distance, cpu_data_speed,
'div-speed', 'la vitesse(km/h)'
);
(Ce qui suit est omis)
C'est un peu ennuyeux de ne pas pouvoir passer le tableau bidimensionnel tel quel.
Cela crée également une fonction de création de graphique.
Plotly.react ()
au lieu de la fonction Plotly.newPlot ()
(de newPlot ()
selon la référence Plotly. Il semble que react ()
soit "beaucoup plus efficace", mais je ne suis pas surpris que seul react ()
soit utilisé ...)range: [600, -600]
est spécifiée et le haut et le bas sont inversés. ʻAutorange: 'inversé'` peut également être inversé, mais lors de la réduction des données, la plage de l'axe change et le rapport hauteur / largeur change, donc une valeur fixe est spécifiée.my_viz.js
function plot_position(min_distance, max_distance) {
my_x = Array.from(my_data.filter(v => (min_distance < v[2]) && (v[2] < max_distance)), x => x[9]);
my_z = Array.from(my_data.filter(v => (min_distance < v[2]) && (v[2] < max_distance)), x => x[11]);
my_pos = {
x: my_x,
y: my_z,
mode: 'scatter',
mode: 'line',
};
var layout = {
xaxis: {autorange: false, range: [-600, 600]},
yaxis: {autorange: false, range: [600, -600]},
autosize: false,
width: 300,
height: 300,
margin: {l: 50, r: 50, b: 50, t: 50, pad: 10},
showlegend: false,
images: [{
source: 'pos_base.png',
xref: 'x',
yref: 'y',
x: 500,
y: 600,
xanchor: 'right',
yanchor: 'bottom',
sizex: 1000,
sizey: 1200,
sizing: 'stretch',
opacity: 0.4,
layer: 'below'
}]
};
Plotly.react('div-position', [my_pos], layout);
}
Si vous sélectionnez une plage sur l'axe horizontal (Zoom) dans le graphique de vitesse, l'événement sera déclenché et le résultat sera reflété dans d'autres graphiques.
--Dans Plotly, le contenu de l'événement Zoom qui se produit lorsque vous sélectionnez une plage en faisant glisser et en déposant la souris est différent du contenu de l'événement Zoom qui se produit lorsque vous annulez le Zoom en double-cliquant sur le graphique, donc traiter avec ʻif..else ..` Diviser.
Plotly.relayout ()
.
--Pour le graphe de position, il est nécessaire d'affiner les données d'affichage, donc recréez le graphe (exécutez la fonction plot_position ()
créée ci-dessus).my_viz.js
document.querySelector('#div-speed').on(
'plotly_relayout',
function(eventdata) {
if(eventdata['xaxis.autorange']) {
x_start = 0.0;
x_end = 1.0;
option = {'xaxis.autorange': true};
} else {
x_start = eventdata['xaxis.range[0]'];
x_end = eventdata['xaxis.range[1]'];
option = {'xaxis.range': [x_start, x_end]}
}
Plotly.relayout('div-throttle', option);
Plotly.relayout('div-brake', option);
Plotly.relayout('div-gear', option);
Plotly.relayout('div-rpm', option);
Plotly.relayout('div-steer', option);
plot_position(x_start, x_end);
}
);
Vous pouvez maintenant analyser avec le flux suivant.
(Double-cliquez sur le graphique de vitesse pour annuler le zoom)
Eh bien, je n'avais pas besoin d'aller aussi loin pour voir pourquoi c'était lent, c'était juste que l'angle de braquage était trop grand. C'est simple une fois que la cause est connue, mais GT5 / 6 a une limite supérieure sur l'angle de braquage (il semble changer dynamiquement), il semble donc que la situation n'était pas si mauvaise.
En jouant avec la conscience que la cause était trop de pilotage, j'ai pu réduire la différence avec l'IA (CPU) de 4 secondes à 1 seconde ou moins. Cependant, lorsque je vérifie à nouveau les données, il semble que la direction est encore trop brusque et que le virage est raide, donc je dois encore m'améliorer.
[Comparaison des données entre moi-même (après amélioration) et AI](http: // localhost: 8000 / viz_after.html)
Cette fois, en visualisant les données, j'ai essayé les outils suivants autres que Plotly, alors donnez-moi une petite impression.
En résumé, Plotly est très bon.
Recommended Posts