feat: add planning visualization contracts
This commit is contained in:
@@ -0,0 +1,147 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
|
||||
namespace TrajectoryPlanningVisualization;
|
||||
|
||||
public sealed class VisualizationPoint
|
||||
{
|
||||
public VisualizationPoint(double x, double y)
|
||||
{
|
||||
VisualizationContract.RequireFinite(x, nameof(x));
|
||||
VisualizationContract.RequireFinite(y, nameof(y));
|
||||
X = x;
|
||||
Y = y;
|
||||
}
|
||||
|
||||
public double X { get; }
|
||||
public double Y { get; }
|
||||
}
|
||||
|
||||
public sealed class VisualizationPose
|
||||
{
|
||||
public VisualizationPose(double x, double y, double headingRadians)
|
||||
{
|
||||
VisualizationContract.RequireFinite(x, nameof(x));
|
||||
VisualizationContract.RequireFinite(y, nameof(y));
|
||||
VisualizationContract.RequireFinite(headingRadians, nameof(headingRadians));
|
||||
X = x;
|
||||
Y = y;
|
||||
HeadingRadians = headingRadians;
|
||||
}
|
||||
|
||||
public double X { get; }
|
||||
public double Y { get; }
|
||||
public double HeadingRadians { get; }
|
||||
}
|
||||
|
||||
public sealed class VisualizationBounds
|
||||
{
|
||||
public VisualizationBounds(double xMin, double xMax, double yMin, double yMax)
|
||||
{
|
||||
VisualizationContract.RequireFinite(xMin, nameof(xMin));
|
||||
VisualizationContract.RequireFinite(xMax, nameof(xMax));
|
||||
VisualizationContract.RequireFinite(yMin, nameof(yMin));
|
||||
VisualizationContract.RequireFinite(yMax, nameof(yMax));
|
||||
if (xMax < xMin || yMax < yMin)
|
||||
{
|
||||
throw new ArgumentOutOfRangeException(nameof(xMax), "Bounds maxima must not precede minima.");
|
||||
}
|
||||
|
||||
XMin = xMin;
|
||||
XMax = xMax;
|
||||
YMin = yMin;
|
||||
YMax = yMax;
|
||||
}
|
||||
|
||||
public double XMin { get; }
|
||||
public double XMax { get; }
|
||||
public double YMin { get; }
|
||||
public double YMax { get; }
|
||||
}
|
||||
|
||||
public sealed class VisualizationValue
|
||||
{
|
||||
public VisualizationValue(string chineseName, string rawName, string value, string unit, string severity)
|
||||
{
|
||||
ChineseName = VisualizationContract.RequireText(chineseName, nameof(chineseName));
|
||||
RawName = VisualizationContract.RequireText(rawName, nameof(rawName));
|
||||
Value = VisualizationContract.RequireText(value, nameof(value));
|
||||
Unit = VisualizationContract.RequireText(unit, nameof(unit));
|
||||
if (severity != "normal" && severity != "notice" && severity != "failure")
|
||||
{
|
||||
throw new ArgumentOutOfRangeException(nameof(severity), "Severity must be normal, notice, or failure.");
|
||||
}
|
||||
|
||||
Severity = severity;
|
||||
}
|
||||
|
||||
public string ChineseName { get; }
|
||||
public string RawName { get; }
|
||||
public string Value { get; }
|
||||
public string Unit { get; }
|
||||
public string Severity { get; }
|
||||
}
|
||||
|
||||
public sealed class VisualizationConfigurationGroup
|
||||
{
|
||||
public VisualizationConfigurationGroup(string chineseTitle, IReadOnlyList<VisualizationValue> entries)
|
||||
{
|
||||
ChineseTitle = VisualizationContract.RequireText(chineseTitle, nameof(chineseTitle));
|
||||
Entries = VisualizationContract.Copy(entries, nameof(entries));
|
||||
}
|
||||
|
||||
public string ChineseTitle { get; }
|
||||
public IReadOnlyList<VisualizationValue> Entries { get; }
|
||||
}
|
||||
|
||||
internal static class VisualizationContract
|
||||
{
|
||||
public static string RequireText(string value, string parameterName)
|
||||
{
|
||||
if (value == null)
|
||||
{
|
||||
throw new ArgumentNullException(parameterName);
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
public static void RequireFinite(double value, string parameterName)
|
||||
{
|
||||
if (double.IsNaN(value) || double.IsInfinity(value))
|
||||
{
|
||||
throw new ArgumentOutOfRangeException(parameterName, "Value must be finite.");
|
||||
}
|
||||
}
|
||||
|
||||
public static void RequireFinite(double? value, string parameterName)
|
||||
{
|
||||
if (value.HasValue)
|
||||
{
|
||||
RequireFinite(value.Value, parameterName);
|
||||
}
|
||||
}
|
||||
|
||||
public static IReadOnlyList<T> Copy<T>(IReadOnlyList<T> values, string parameterName)
|
||||
{
|
||||
if (values == null)
|
||||
{
|
||||
throw new ArgumentNullException(parameterName);
|
||||
}
|
||||
|
||||
var copy = new List<T>(values.Count);
|
||||
for (var index = 0; index < values.Count; index++)
|
||||
{
|
||||
T value = values[index];
|
||||
if (value is null)
|
||||
{
|
||||
throw new ArgumentException("Collections cannot contain null elements.", parameterName);
|
||||
}
|
||||
|
||||
copy.Add(value);
|
||||
}
|
||||
|
||||
return new ReadOnlyCollection<T>(copy);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user