Files
ParkingRobot/MultiWheelC.Tests/FleetKinematicsTests.cs
T

140 lines
4.2 KiB
C#

using System;
using System.Collections.Generic;
using MyParking.Shared;
namespace MultiWheelC.Tests
{
internal static class FleetKinematicsTests
{
private const double Tolerance = 1e-9;
public static void Run()
{
var layout = CreateTailToTailLayout();
VerifyTranslation(layout);
VerifyRotationAroundFleetCenter(layout);
VerifyRotationAroundFirstVehicle(layout);
VerifyStop(layout);
Console.WriteLine(
"FleetKinematics刚体速度分配测试通过。共4个场景。");
}
private static FleetLayout CreateTailToTailLayout()
{
return new FleetLayout(
new[]
{
new VehicleLayout(
1,
new Pose2D(1.0, 0.0, 0.0)),
new VehicleLayout(
2,
new Pose2D(-1.0, 0.0, Math.PI))
});
}
private static void VerifyTranslation(FleetLayout layout)
{
var commands = FleetKinematics.Decompose(
layout,
new FleetMotionCommand(
Point2D.Zero,
new Twist2D(0.4, 0.0, 0.0)));
AssertTwist(Find(commands, 1), 0.4, 0.0, 0.0);
AssertTwist(Find(commands, 2), -0.4, 0.0, 0.0);
}
private static void VerifyRotationAroundFleetCenter(
FleetLayout layout)
{
var commands = FleetKinematics.Decompose(
layout,
FleetMotionCommand.RotateAround(
Point2D.Zero,
0.2));
AssertTwist(Find(commands, 1), 0.0, 0.2, 0.2);
AssertTwist(Find(commands, 2), 0.0, 0.2, 0.2);
}
private static void VerifyRotationAroundFirstVehicle(
FleetLayout layout)
{
var commands = FleetKinematics.Decompose(
layout,
FleetMotionCommand.RotateAround(
new Point2D(1.0, 0.0),
0.2));
AssertTwist(Find(commands, 1), 0.0, 0.0, 0.2);
AssertTwist(Find(commands, 2), 0.0, 0.4, 0.2);
}
private static void VerifyStop(FleetLayout layout)
{
var commands = FleetKinematics.Decompose(
layout,
FleetMotionCommand.Stop());
AssertTwist(Find(commands, 1), 0.0, 0.0, 0.0);
AssertTwist(Find(commands, 2), 0.0, 0.0, 0.0);
}
private static FleetMemberCommand Find(
IReadOnlyList<FleetMemberCommand> commands,
int vehicleId)
{
for (var index = 0; index < commands.Count; index++)
{
if (commands[index].VehicleId == vehicleId)
{
return commands[index];
}
}
throw new InvalidOperationException(
$"没有找到车辆{vehicleId}的分配命令。");
}
private static void AssertTwist(
FleetMemberCommand command,
double expectedVx,
double expectedVy,
double expectedOmega)
{
AssertNear(
command.TwistInVehicleBody.VxMetersPerSecond,
expectedVx,
command.VehicleId,
"Vx");
AssertNear(
command.TwistInVehicleBody.VyMetersPerSecond,
expectedVy,
command.VehicleId,
"Vy");
AssertNear(
command.TwistInVehicleBody.OmegaRadiansPerSecond,
expectedOmega,
command.VehicleId,
"Omega");
}
private static void AssertNear(
double actual,
double expected,
int vehicleId,
string valueName)
{
if (Math.Abs(actual - expected) > Tolerance)
{
throw new InvalidOperationException(
$"车辆{vehicleId}的{valueName}错误:" +
$"actual={actual:F9}, expected={expected:F9}。");
}
}
}
}