2026-08-05 18:07:01 +08:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
using System;
|
|
|
|
|
|
using System.Collections.Generic;
|
|
|
|
|
|
using ClumsyCore.Pilot;
|
|
|
|
|
|
using CommonUsage.Chassis;
|
|
|
|
|
|
using MyParking.Shared;
|
|
|
|
|
|
|
|
|
|
|
|
namespace MultiWheelC
|
|
|
|
|
|
{
|
2026-08-11 17:06:26 +08:00
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 停车并等待四个舵轮稳定回到车体前向0°。
|
|
|
|
|
|
/// </summary>
|
2026-08-05 18:07:01 +08:00
|
|
|
|
public class PrepareWheelsForward : MovementDefinition
|
|
|
|
|
|
{
|
2026-08-11 17:06:26 +08:00
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 获取或设置本次动作的回正到位容差覆盖值,单位为deg;为空时读取车辆配置。
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
public float? ToleranceDegrees;
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 获取或设置本次动作的稳定确认时间覆盖值,单位为s;为空时读取车辆配置。
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
public float? StableSeconds;
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 获取或设置本次动作的超时覆盖值,单位为s;为空时读取车辆配置,0表示关闭超时。
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
public float? TimeoutSeconds;
|
|
|
|
|
|
|
2026-08-05 18:07:01 +08:00
|
|
|
|
public bool Completed { get; private set; }
|
|
|
|
|
|
|
2026-08-11 17:06:26 +08:00
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 读取一次有效配置并等待全部舵轮在容差内稳定保持车体前向0°。
|
|
|
|
|
|
/// </summary>
|
2026-08-05 18:07:01 +08:00
|
|
|
|
public override IEnumerable<bool> Get()
|
|
|
|
|
|
{
|
2026-08-11 17:06:26 +08:00
|
|
|
|
var config = PilotDefinition.Conf;
|
|
|
|
|
|
var toleranceDegrees =
|
|
|
|
|
|
ToleranceDegrees ??
|
|
|
|
|
|
config.ParkingWheelForwardToleranceDegrees;
|
|
|
|
|
|
var stableSeconds =
|
|
|
|
|
|
StableSeconds ??
|
|
|
|
|
|
config.ParkingWheelForwardStableSeconds;
|
|
|
|
|
|
var timeoutSeconds =
|
|
|
|
|
|
TimeoutSeconds ??
|
|
|
|
|
|
config.ParkingWheelForwardTimeoutSeconds;
|
|
|
|
|
|
|
|
|
|
|
|
NumericGuard.EnsureFiniteNonNegative(
|
|
|
|
|
|
toleranceDegrees,
|
|
|
|
|
|
nameof(ToleranceDegrees));
|
|
|
|
|
|
NumericGuard.EnsureFiniteNonNegative(
|
|
|
|
|
|
stableSeconds,
|
|
|
|
|
|
nameof(StableSeconds));
|
|
|
|
|
|
NumericGuard.EnsureFiniteNonNegative(
|
|
|
|
|
|
timeoutSeconds,
|
|
|
|
|
|
nameof(TimeoutSeconds));
|
|
|
|
|
|
|
2026-08-05 18:07:01 +08:00
|
|
|
|
var chassis =
|
|
|
|
|
|
PilotDefinition.Chassis as MultiWheelChassis;
|
|
|
|
|
|
if (chassis == null)
|
|
|
|
|
|
{
|
|
|
|
|
|
throw new InvalidOperationException(
|
|
|
|
|
|
"当前底盘不是MultiWheelChassis,无法执行舵轮回正。");
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
var adapter = new MultiWheelChassisAdapter(
|
|
|
|
|
|
chassis,
|
|
|
|
|
|
PilotDefinition.Self.CarNum);
|
|
|
|
|
|
adapter.ResetToBodyFrame();
|
|
|
|
|
|
var toleranceRadians =
|
2026-08-11 17:06:26 +08:00
|
|
|
|
AngleMath.DegreesToRadians(toleranceDegrees);
|
2026-08-05 18:07:01 +08:00
|
|
|
|
var startTime = DateTime.UtcNow;
|
|
|
|
|
|
DateTime? alignedSince = null;
|
|
|
|
|
|
|
|
|
|
|
|
Completed = false;
|
|
|
|
|
|
if (!adapter.PrepareParallelDirection(0.0))
|
|
|
|
|
|
{
|
|
|
|
|
|
throw new InvalidOperationException(
|
|
|
|
|
|
"无法将所有舵轮下发到车体前向0°。");
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
try
|
|
|
|
|
|
{
|
|
|
|
|
|
while (true)
|
|
|
|
|
|
{
|
|
|
|
|
|
var aligned =
|
|
|
|
|
|
adapter.AreParallelWheelsAligned(
|
|
|
|
|
|
0.0,
|
|
|
|
|
|
toleranceRadians);
|
|
|
|
|
|
|
|
|
|
|
|
if (aligned)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (!alignedSince.HasValue)
|
|
|
|
|
|
alignedSince = DateTime.UtcNow;
|
|
|
|
|
|
|
|
|
|
|
|
if ((DateTime.UtcNow -
|
|
|
|
|
|
alignedSince.Value).TotalSeconds >=
|
2026-08-11 17:06:26 +08:00
|
|
|
|
stableSeconds)
|
2026-08-05 18:07:01 +08:00
|
|
|
|
{
|
|
|
|
|
|
Completed = true;
|
|
|
|
|
|
yield break;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
alignedSince = null;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-08-11 17:06:26 +08:00
|
|
|
|
if (timeoutSeconds > 0f &&
|
2026-08-05 18:07:01 +08:00
|
|
|
|
(DateTime.UtcNow - startTime).TotalSeconds >
|
2026-08-11 17:06:26 +08:00
|
|
|
|
timeoutSeconds)
|
2026-08-05 18:07:01 +08:00
|
|
|
|
{
|
|
|
|
|
|
throw new TimeoutException(
|
2026-08-11 17:06:26 +08:00
|
|
|
|
$"舵轮回正超过{timeoutSeconds:F1}s," +
|
2026-08-05 18:07:01 +08:00
|
|
|
|
"测试已经取消。");
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
yield return true;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
finally
|
|
|
|
|
|
{
|
|
|
|
|
|
// 只清零驱动速度,保留已经下发的0°舵角。
|
|
|
|
|
|
adapter.StopImmediately();
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|