Ich liebte Rennspiele und spielte Gran Turismo 5/6, aber nachdem ich zu Assetto Corsa gewechselt war, stellte ich fest, dass ich nicht sehr gut lief. Insbesondere besteht die Situation darin, dass das KI-Fahrzeug (Stärke = 100%) durch fast 4 Sekunden pro Runde voneinander getrennt ist (bei Verwendung der Catalunya-Rennstrecke / TOYOTA GT86, Gamepad). In GT6 habe ich alles Gold mit Assist AUS außer ABS = 1 / TCS = 1 bekommen, also dachte ich, ich wäre nicht so schlecht ...
Um zu analysieren, warum es einen solchen Unterschied gibt, habe ich auch das Visualisierungstool studiert, die laufenden Daten meines Spiels und des KI-Spiels mit Python erfasst und mit Plotly visualisiert.
Übrigens gibt es ein Tool namens Motec i2 Pro zur Datenerfassung und -visualisierung. Dieses Mal untersuche ich auch Visualisierungstools, sodass ich Motec nicht verwenden werde.
Assetto Corsa verfügt über einen Mechanismus namens "In-Game-App", mit dem Benutzer unabhängig voneinander Anwendungen entwickeln können, die Fahrdaten in Python-Sprache auf dem Spielbildschirm anzeigen. APIs zur Erfassung von Fahrdaten und APIs zur Anzeige auf dem Bildschirm werden vorbereitet.
Basierend auf diesen Referenzinformationen habe ich ein Programm erstellt, um die folgenden Informationen zu erhalten.
ACTelemetry.py
class ACTelemetry:
(Abkürzung)
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))
(Abkürzung)
def acUpdate(deltaT):
global telemetryInstance
telemetryInstance.logging()
Ich werde nicht auf die Details des Codes eingehen, aber der App-Mechanismus im Spiel führt jedes Mal, wenn eine Grafik aktualisiert wird, "acUpdate (deltaT)" aus (60 Mal pro Sekunde in meiner Umgebung). Datenerfassung und Dateiausgabe werden in "ACTelemetry.logging ()" ausgeführt, das von "acUpdate (deltaT)" aufgerufen wird.
Gehen Sie wie folgt vor, um diese In-Game-App zu aktivieren:
Die folgende Benutzeroberfläche wird angezeigt. Klicken Sie auf die Schaltfläche "Weiter", um das Fahrzeug auszuwählen, für das Daten erfasst werden sollen, und klicken Sie auf die Schaltfläche "Start", um die Protokollerfassung zu starten.
Als Ergebnis können die folgenden Daten erhalten werden. Ich möchte diese Daten sowohl für mein Spiel als auch für mein KI-Spiel abrufen und vergleichen.
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
Dieses Mal möchte ich die Daten mithilfe der Javascript-Bibliothek von Plotly visualisieren. Die obige tabulatorgetrennte Datei mit Header kann so behandelt werden, wie sie ist, ist jedoch etwas problematisch. Fügen Sie daher im Voraus die folgende Verarbeitung und Formgebung hinzu.
Die Datei sieht wie folgt aus.
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],
(Folgendes wird weggelassen)
Ich möchte das folgende Viz mit Plotly machen. Sie können es tatsächlich von (hier verschieben. Es ist etwas schwer, aber das animierte GIF ist [hier](https: // abe-masanori). github.io/AC_analysis/data_viz/ui.gif))
--Für Geschwindigkeit, Gas- / Bremsöffnung, Gang, Motordrehzahl und Lenkwinkel zeigen Sie Ihre eigenen und AI (CPU) -Daten auf der linken Seite des Liniendiagramms mit dem Abstand vom Start als horizontaler Achse an.
Diese Art von Daten zeigt normalerweise die horizontale Achse = Zeit und die vertikale Achse = Metriken an. Wenn Sie dies jedoch diesmal tun, ist es schwierig, Ihre eigenen Daten mit AI-Daten (CPU-Daten) zu vergleichen, sodass die horizontale Achse von vorne beginnt. Verwenden Sie die numerischen Werte (0.0: Start bis 1.0: Ziel), die die Entfernung von darstellen.
Erstellen Sie zunächst eine Basis-HTML-Datei.
--Lade die Bibliothek von Plotly.
viz_before.html
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<title>mich selber(Vor der Verbesserung)Und AI-Datenvergleich</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>
Da die Diagramme für Geschwindigkeit, Gas- / Bremsöffnung, Gang, Motordrehzahl und Lenkwinkel nahezu identisch sind, wird ein Liniendiagramm mit Ihren eigenen Daten, AI-Daten (CPU), der Position zur Erstellung des Diagramms und dem Titel der vertikalen Achse als Argumente übergeben. Erstellen Sie eine Funktion, die erstellt.
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', 'Geschwindigkeit(km/h)'
);
(Folgendes wird weggelassen)
Es ist ein wenig ärgerlich, das zweidimensionale Array nicht so passieren zu können, wie es ist.
Dadurch wird auch eine Diagrammerstellungsfunktion erstellt.
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);
}
Wenn Sie im Geschwindigkeitsdiagramm einen Bereich auf der horizontalen Achse (Zoom) auswählen, wird das Ereignis ausgelöst und das Ergebnis in anderen Diagrammen wiedergegeben.
plot_position ()
aus).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);
}
);
Jetzt können Sie mit folgendem Ablauf analysieren.
(Doppelklicken Sie auf das Geschwindigkeitsdiagramm, um den Zoom abzubrechen.)
Nun, ich musste nicht so weit gehen, um zu sehen, warum es langsam war, es war nur so, dass der Lenkwinkel zu groß war. Sobald die Ursache bekannt ist, ist es einfach, aber der GT5 / 6 hat eine Obergrenze für den Lenkwinkel (er scheint sich dynamisch zu ändern), sodass die Situation anscheinend nicht so schlecht war.
Indem ich mit dem Bewusstsein spielte, dass die Ursache zu viel Lenkung war, konnte ich den Unterschied mit AI (CPU) von 4 Sekunden auf 1 Sekunde oder weniger reduzieren. Wenn ich die Daten jedoch erneut überprüfe, scheint die Lenkung immer noch zu scharf und der Weg zum Abbiegen steil zu sein, sodass ich mich noch verbessern muss.
[Vergleich der Daten zwischen mir (nach Verbesserung) und AI](http: // localhost: 8000 / viz_after.html)
Dieses Mal habe ich bei der Visualisierung der Daten die folgenden Tools außer Plotly ausprobiert. Bitte geben Sie mir einen kleinen Eindruck.
Zusammenfassend ist Plotly sehr gut.
Recommended Posts