43 lines
2.6 KiB
C#
43 lines
2.6 KiB
C#
using System;
|
|||
|
|
using System.Globalization;
|
||
|
|
using System.Text;
|
||
|
|
|
||
|
|
namespace MultiWheelC.TrajectoryPlanning.PathSmoothing.Output.Visualization;
|
||
|
|
|
||
|
|
/// <summary>把共享图形模型的指标表写为带 BOM 的 UTF-8 CSV。</summary>
|
||
|
|
public sealed class SmoothingCsvWriter
|
||
|
|
{
|
||
|
|
private const string Header = "ScenarioId,Method,Status,PathLengthMeters,MaximumAbsoluteVehicleCurvaturePerMeter,RootMeanSquareVehicleCurvaturePerMeter,TotalAbsoluteCurvatureVariationPerMeter,CurvatureVariationEnergy,MinimumBodyClearanceMeters,MedianElapsedMilliseconds,TimingSampleCount,IsDeterministic";
|
||
|
|
|
||
|
|
public byte[] Write(SmoothingFigureModel model)
|
||
|
|
{
|
||
|
|
if (model == null) throw new ArgumentNullException(nameof(model));
|
||
|
|
var text = new StringBuilder(Header).Append("\r\n");
|
||
|
|
for (int index = 0; index < model.MetricRows.Count; index++)
|
||
|
|
{
|
||
|
|
SmoothingFigureMetricRow row = model.MetricRows[index];
|
||
|
|
PathQualityMetrics metrics = row.Metrics;
|
||
|
|
text.Append(Field(model.ScenarioId)).Append(',').Append(Field(row.Method)).Append(',').Append(Field(row.Status.ToString())).Append(',')
|
||
|
|
.Append(Number(metrics.PathLengthMeters)).Append(',').Append(Number(metrics.MaximumAbsoluteVehicleCurvaturePerMeter)).Append(',')
|
||
|
|
.Append(Number(metrics.RootMeanSquareVehicleCurvaturePerMeter)).Append(',').Append(Number(metrics.TotalAbsoluteCurvatureVariationPerMeter)).Append(',')
|
||
|
|
.Append(Number(metrics.CurvatureVariationEnergy)).Append(',').Append(Number(metrics.MinimumBodyClearanceMeters)).Append(',')
|
||
|
|
.Append(Number(row.Timing == null ? 0d : row.Timing.MedianElapsedMilliseconds)).Append(',')
|
||
|
|
.Append(row.Timing == null ? 0 : row.Timing.MeasuredElapsedMilliseconds.Count).Append(',')
|
||
|
|
.Append(row.Timing != null && row.Timing.IsDeterministic ? "true" : "false").Append("\r\n");
|
||
|
|
}
|
||
|
|
byte[] body = new UTF8Encoding(false).GetBytes(text.ToString());
|
||
|
|
byte[] preamble = new UTF8Encoding(true).GetPreamble();
|
||
|
|
var output = new byte[preamble.Length + body.Length];
|
||
|
|
Buffer.BlockCopy(preamble, 0, output, 0, preamble.Length);
|
||
|
|
Buffer.BlockCopy(body, 0, output, preamble.Length, body.Length);
|
||
|
|
return output;
|
||
|
|
}
|
||
|
|
|
||
|
|
private static string Number(double value) { return value.ToString("0.#################", CultureInfo.InvariantCulture); }
|
||
|
|
private static string Field(string value)
|
||
|
|
{
|
||
|
|
string text = value ?? string.Empty;
|
||
|
|
return text.IndexOfAny(new[] { ',', '\"', '\r', '\n' }) < 0 ? text : "\"" + text.Replace("\"", "\"\"") + "\"";
|
||
|
|
}
|
||
|
|
}
|