これまでのGT7データ解析の取り組みをおさらい
GitHubにあるGT7Dashboardを使用して、グランツーリスモ7の走行データ(テレメトリーデータ)を取得する方法を紹介しました。さらに保存したデータを解析するC#クラスを作成しました。
関連ページのリンク
- GT7 Dashboardでテレメトリーデータを取得
- GT7DashboardのJSONデータをC#で解析してみた
- 自作ソフトでGT7Dashboardの色々なデータをトレースした←この記事
- GT7DashBoardのデータで車両解析する
これまでは速度のデータしか表示していませんでしたが、他のデータを表示してみたいと思います。
鈴鹿サーキット × FT-1 VGT Gr.3
鈴鹿サーキット × GT-RニスモGT3
鈴鹿サーキット × RC F GT3
一部ソースコードの紹介
データの読み込み、表示クラスとチャート表示フォームクラスを紹介します。
アプリケーションの構成
メインクラスで表示するデータを選択してからフォームクラスインスタンスを作成、表示します。その後、データ読み込み、表示クラスでjsonデータをロードします。データロード時にフォームクラスのインスタンスにデータ参照を追加することでデータを表示できます。チャート表示フォームクラスにはデータ表示の時間軸を設定するメソッド"SetDispArea"があるので、タイマー等で表示範囲を変更することでデータをトレースできます。
速度データの読み込み、表示クラス
一例として速度データのクラスを紹介しますが、他のデータでも基本的なつくりは同じです。
using JsonTool;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Windows.Forms.DataVisualization.Charting;
namespace GT7DashboardDataAnalyzer
{
public class VehicleSpeedGraph
{
public VehicleSpeedGraph(Chart chart)
{
chart.ChartAreas.Clear();
chart.Series.Clear();
chart.Legends.Clear();
chart.Dock = DockStyle.Fill;//フォームいっぱいに表示
chart.ChartAreas.Add(new ChartArea("chartArea"));//グラフエリア
}
public bool AddData(GT7DashboardData gt7DashboardData, Chart chart)
{
bool result = false;
//凡例を作成
//chart.Legends.Add(new Legend(gt7DashboardData.Title));//凡例
//データ系列を作成
Series series = new Series();
//折れ線グラフを選択
series.ChartType = SeriesChartType.Line;
for (int i = 0; i < gt7DashboardData.DataTime.Count(); i++)
{
series.Points.AddXY(gt7DashboardData.DataTime[i], gt7DashboardData.DataSpeed[i]);
}
chart.Series.Add(series);
return result;
}
}
}
チャート表示フォームクラス
一例として2つのチャートを表示するクラスです。
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Windows.Forms;
using System.Windows.Forms.DataVisualization.Charting;
using JsonTool;
namespace GT7DashboardDataAnalyzer
{
public partial class ChartForm2 : Form
{
private List<Chart> charts;
private List<ChartDataType> chartTypes { get; set; }
private readonly int CHART_COUNT;
private double dispAreaTn1 { get; set; }
private double dispAreaTn2 { get; set; }
private StripLine stripLine { get; set; }
private VehicleSpeedGraph vehicleSpeedGraph { get; set; }
private RpmGraph rpmGraph { get; set; }
private ThrottleGraph throttleGraph { get; set; }
private BrakingGraph brakingGraph { get; set; }
private GearGraph gearGraph { get; set; }
private TiresGraph tiresGraph { get; set; }
private BoostGraph boostGraph { get; set; }
public enum ChartDataType
{
Throttle,
Braking,
Speed,
Rpm,
Gear,
Tires,
Position,
Boost,
RotationYaw,
AbsoluteYawRatePerSecond
}
public ChartForm2(List<ChartDataType> types)
{
InitializeComponent();
CHART_COUNT = 2;
//InitChartDataType = new ChartDataType[CHART_COUNT];
//InitChartDataType[0] = ChartDataType.Speed;
//InitChartDataType[1] = ChartDataType.Rpm;
chartTypes = types;
if(types.Count() == CHART_COUNT)
{
charts = new List<Chart>();
charts.Add(chart1);
charts.Add(chart2);
}
}
private void ChartForm2_Load(object sender, EventArgs e)
{
for(int i = 0; i < CHART_COUNT; i++)
{
//this.Text = Enum.GetName(typeof(ChartDataType), chartTypes[i]);
switch (chartTypes[i])
{
case ChartDataType.Throttle:
InitThrottleData(i);
break;
case ChartDataType.Braking:
InitBrakingData(i);
break;
case ChartDataType.Speed:
InitSpeedData(i);
break;
case ChartDataType.Rpm:
InitRpmData(i);
break;
case ChartDataType.Gear:
InitGearData(i);
break;
case ChartDataType.Tires:
InitTiresData(i);
break;
case ChartDataType.Position:
InitPositionData(i);
break;
case ChartDataType.Boost:
InitBoostData(i);
break;
case ChartDataType.RotationYaw:
InitRotationYawData(i);
break;
case ChartDataType.AbsoluteYawRatePerSecond:
InitAbsoluteYawRatePerSecond(i);
break;
default:
break;
}
}
}
private void InitThrottleData(int chartNum)
{
throttleGraph = new ThrottleGraph(charts[chartNum]);
SetChartAxisXTitle(chartNum, 0, "Time[s]");
SetChartAxisYTitle(chartNum, 0, "Throttle[%]");
InitStripLine(chartNum);
}
private void InitBrakingData(int chartNum)
{
brakingGraph = new BrakingGraph(charts[chartNum]);
SetChartAxisXTitle(chartNum, 0, "Time[s]");
SetChartAxisYTitle(chartNum, 0, "Braking[%]");
InitStripLine(chartNum);
}
private void InitSpeedData(int chartNum)
{
vehicleSpeedGraph = new VehicleSpeedGraph(charts[chartNum]);
SetChartAxisXTitle(chartNum, 0, "Time[s]");
SetChartAxisYTitle(chartNum, 0, "Speed[km/h]");
InitStripLine(chartNum);
}
private void InitRpmData(int chartNum)
{
rpmGraph = new RpmGraph(charts[chartNum]);
SetChartAxisXTitle(chartNum, 0, "Time[s]");
SetChartAxisYTitle(chartNum, 0, "rpm");
InitStripLine(chartNum);
}
private void InitGearData(int chartNum)
{
gearGraph = new GearGraph(charts[chartNum]);
SetChartAxisXTitle(chartNum, 0, "Time[s]");
SetChartAxisYTitle(chartNum, 0, "Gear");
InitStripLine(chartNum);
}
private void InitTiresData(int chartNum)
{
tiresGraph = new TiresGraph(charts[chartNum]);
SetChartAxisXTitle(chartNum, 0, "Time[s]");
SetChartAxisYTitle(chartNum, 0, "Tires");
InitStripLine(chartNum);
}
private void InitPositionData(int chartNum)
{
}
private void InitBoostData(int chartNum)
{
boostGraph = new BoostGraph(charts[chartNum]);
SetChartAxisXTitle(chartNum, 0, "Time[s]");
SetChartAxisYTitle(chartNum, 0, "Boost");
InitStripLine(chartNum);
}
private void InitRotationYawData(int chartNum)
{
}
private void InitAbsoluteYawRatePerSecond(int chartNum)
{
}
private void InitStripLine(int chartNum)
{
stripLine = new StripLine
{
Text = $"time",
TextAlignment = StringAlignment.Near, // テキストの水平位置(Near:左, Center:中央, Far:右)
TextLineAlignment = StringAlignment.Far, // テキストの垂直位置(Near:下, Center:中央, Far:上)
Interval = 0, // 線分の表示間隔 値を設定すると指定した間隔で表示される。
//IntervalOffset = offset, // 線分の表示オフセット
BorderWidth = 1,
BorderDashStyle = ChartDashStyle.DashDot,
BorderColor = Color.Red,
};
charts[chartNum].ChartAreas[0].AxisX.StripLines.Add(stripLine);
}
public void AddData(GT7DashboardData data)
{
if(chartTypes.Count() == charts.Count())
{
int chartNum = 0;
foreach (var chart in charts)
{
switch (chartTypes[chartNum])
{
case ChartDataType.Throttle:
throttleGraph.AddData(data, charts[chartNum]);
break;
case ChartDataType.Braking:
brakingGraph.AddData(data, charts[chartNum]);
break;
case ChartDataType.Speed:
vehicleSpeedGraph.AddData(data, charts[chartNum]);
break;
case ChartDataType.Rpm:
rpmGraph.AddData(data, charts[chartNum]);
break;
case ChartDataType.Gear:
gearGraph.AddData(data, charts[chartNum]);
break;
case ChartDataType.Tires:
tiresGraph.AddData(data, charts[chartNum]);
break;
case ChartDataType.Boost:
boostGraph.AddData(data, charts[chartNum]);
break;
}
chartNum++;
}
}
}
private void SetChartAxisXTitle(int chartNum, int areaNum, string title)
{
charts[chartNum].ChartAreas[areaNum].AxisX.Title = title;
}
private void SetChartAxisYTitle(int chartNum, int areaNum, string title)
{
charts[chartNum].ChartAreas[areaNum].AxisY.Title = title;
}
public void SetChartAreas(int areaNum)
{
foreach (var chart in charts)
{
// 表示範囲の設定
chart.ChartAreas[areaNum].AxisX.Minimum = Math.Round(dispAreaTn1, 1);
chart.ChartAreas[areaNum].AxisX.Maximum = Math.Round(dispAreaTn2, 1);
//ストリップラインの更新
chart.ChartAreas[0].AxisX.StripLines.Clear();
stripLine.IntervalOffset = (dispAreaTn1 + dispAreaTn2) / 2;
chart.ChartAreas[0].AxisX.StripLines.Add(stripLine);
}
}
public void SetChartAreas(object obj)
{
SetChartAreas((int)obj);
}
public void ChartAxisXInit(int areaNum, double x1, double x2)
{
foreach (var chart in charts)
{
chart.ChartAreas[areaNum].InnerPlotPosition.Auto = false;
chart.ChartAreas[areaNum].InnerPlotPosition.X = 8.0f;
chart.ChartAreas[areaNum].InnerPlotPosition.Y = 4.0f;
chart.ChartAreas[areaNum].InnerPlotPosition.Width = 84.0f;
chart.ChartAreas[areaNum].InnerPlotPosition.Height = 84.0f;
double axisXInterval = (x2 - x1) / 10;
chart.ChartAreas[areaNum].AxisX.Interval = axisXInterval;
}
}
public void SetDispArea(double dispSpan)
{
dispAreaTn1 = -dispSpan / 2;
dispAreaTn2 = dispSpan / 2;
}
public void SetDispArea(double t1, double t2)
{
dispAreaTn1 = t1;
dispAreaTn2 = t2;
}
}
}



