新增倒车以及项目结构优化
This commit is contained in:
@@ -4,6 +4,7 @@ using System.Diagnostics;
|
||||
using ClumsyCore.Interfaces;
|
||||
using ClumsyCore.Pilot;
|
||||
using CommonUsage.Chassis;
|
||||
using MultiWheelC.Control.Abstractions;
|
||||
using MultiWheelC.Control.Allocation;
|
||||
using MultiWheelC.Control.Execution;
|
||||
using MultiWheelC.Control.Lateral;
|
||||
@@ -26,120 +27,120 @@ namespace MultiWheelC
|
||||
public Trajectory2D Trajectory;
|
||||
|
||||
/// <summary>
|
||||
/// 获取或设置本次动作使用的车辆状态源;为空时自动创建Detour状态源。
|
||||
/// 获取或设置本次动作使用的车辆状态源;为空时组合Detour位姿与电机反馈速度。
|
||||
/// </summary>
|
||||
public IVehicleStateProvider StateProvider;
|
||||
|
||||
/// <summary>
|
||||
/// 获取或设置横向控制器创建委托;参数为车辆控制点半径(m),为空时使用配置化Stanley控制器。
|
||||
/// </summary>
|
||||
public Func<double, ILateralController>
|
||||
LateralControllerFactory;
|
||||
|
||||
/// <summary>
|
||||
/// 获取或设置每个有效控制周期结束后的诊断数据观察回调。
|
||||
/// </summary>
|
||||
public Action<ParkingGeometricController> CycleObserver;
|
||||
|
||||
/// <summary>
|
||||
/// Stanley横向误差增益,单位为1/s。
|
||||
/// 获取或设置本次动作的Stanley横向误差增益覆盖值,单位为1/s;为空时读取车辆配置。
|
||||
/// </summary>
|
||||
public double StanleyCrossTrackGainPerSecond = 0.4;
|
||||
public double? StanleyCrossTrackGainPerSecond;
|
||||
|
||||
/// <summary>
|
||||
/// Stanley航向误差增益。
|
||||
/// 获取或设置本次动作的Stanley航向误差增益覆盖值;为空时读取车辆配置。
|
||||
/// </summary>
|
||||
public double StanleyHeadingErrorGain = 1.0;
|
||||
public double? StanleyHeadingErrorGain;
|
||||
|
||||
/// <summary>
|
||||
/// Stanley低速分母保护速度,单位为m/s。
|
||||
/// 获取或设置本次动作的Stanley低速分母保护速度覆盖值,单位为m/s;为空时读取车辆配置。
|
||||
/// </summary>
|
||||
public double StanleyMinimumSpeedMetersPerSecond = 0.15;
|
||||
public double? StanleyMinimumSpeedMetersPerSecond;
|
||||
|
||||
/// <summary>
|
||||
/// 获取或设置Stanley是否优先使用当前状态源提供的实际纵向速度。
|
||||
/// 获取或设置本次动作是否使用实际纵向速度的覆盖值;为空时读取车辆配置。
|
||||
/// </summary>
|
||||
public bool StanleyUsesActualSpeed = true;
|
||||
public bool? StanleyUsesActualSpeed;
|
||||
|
||||
/// <summary>
|
||||
/// Stanley横向误差共同转角分量的最大绝对值,单位为rad。
|
||||
/// 获取或设置本次动作的Stanley横向修正上限覆盖值,单位为rad;为空时读取车辆配置。
|
||||
/// </summary>
|
||||
public double MaximumCrossTrackCorrectionRadians =
|
||||
AngleMath.DegreesToRadians(10.0);
|
||||
public double? MaximumCrossTrackCorrectionRadians;
|
||||
|
||||
/// <summary>
|
||||
/// Stanley航向误差差动转角分量的最大绝对值,单位为rad。
|
||||
/// 获取或设置本次动作的Stanley航向修正上限覆盖值,单位为rad;为空时读取车辆配置。
|
||||
/// </summary>
|
||||
public double MaximumHeadingCorrectionRadians =
|
||||
AngleMath.DegreesToRadians(10.0);
|
||||
public double? MaximumHeadingCorrectionRadians;
|
||||
|
||||
/// <summary>
|
||||
/// 纵向速度外环比例增益。
|
||||
/// 获取或设置本次动作的纵向速度比例增益覆盖值;为空时读取车辆配置。
|
||||
/// </summary>
|
||||
public double LongitudinalKp = 0.5;
|
||||
public double? LongitudinalKp;
|
||||
|
||||
/// <summary>
|
||||
/// 纵向速度外环积分增益,单位为1/s。
|
||||
/// 获取或设置本次动作的纵向速度积分增益覆盖值,单位为1/s;为空时读取车辆配置。
|
||||
/// </summary>
|
||||
public double LongitudinalKiPerSecond;
|
||||
public double? LongitudinalKiPerSecond;
|
||||
|
||||
/// <summary>
|
||||
/// 纵向速度外环微分增益,单位为s。
|
||||
/// 获取或设置本次动作的纵向速度微分增益覆盖值,单位为s;为空时读取车辆配置。
|
||||
/// </summary>
|
||||
public double LongitudinalKdSeconds;
|
||||
public double? LongitudinalKdSeconds;
|
||||
|
||||
/// <summary>
|
||||
/// 纵向积分项允许产生的最大速度修正绝对值,单位为m/s。
|
||||
/// 获取或设置本次动作的纵向积分修正上限覆盖值,单位为m/s;为空时读取车辆配置。
|
||||
/// </summary>
|
||||
public double MaximumIntegralCorrectionMetersPerSecond = 0.05;
|
||||
public double? MaximumIntegralCorrectionMetersPerSecond;
|
||||
|
||||
/// <summary>
|
||||
/// 纵向PID不进行反馈修正的速度误差死区,单位为m/s。
|
||||
/// 获取或设置本次动作的纵向速度误差死区覆盖值,单位为m/s;为空时读取车辆配置。
|
||||
/// </summary>
|
||||
public double LongitudinalSpeedErrorDeadbandMetersPerSecond =
|
||||
0.025;
|
||||
public double? LongitudinalSpeedErrorDeadbandMetersPerSecond;
|
||||
|
||||
/// <summary>
|
||||
/// 底盘纵向命令速度绝对值上限,单位为m/s。
|
||||
/// 获取或设置本次动作的底盘纵向命令速度上限覆盖值,单位为m/s;为空时读取车辆配置。
|
||||
/// </summary>
|
||||
public double MaximumCommandSpeedMetersPerSecond = 0.50;
|
||||
public double? MaximumCommandSpeedMetersPerSecond;
|
||||
|
||||
/// <summary>
|
||||
/// 前后GCP允许的最大转角绝对值,单位为rad。
|
||||
/// 获取或设置本次动作的GCP转角上限覆盖值,单位为rad;为空时读取车辆配置。
|
||||
/// </summary>
|
||||
public double MaximumGcpAngleRadians =
|
||||
AngleMath.DegreesToRadians(45.0);
|
||||
public double? MaximumGcpAngleRadians;
|
||||
|
||||
/// <summary>
|
||||
/// 前后GCP目标转角最大变化率,单位为rad/s。
|
||||
/// 获取或设置本次动作的GCP转角变化率上限覆盖值,单位为rad/s;为空时读取车辆配置。
|
||||
/// </summary>
|
||||
public double MaximumGcpAngleRateRadiansPerSecond =
|
||||
AngleMath.DegreesToRadians(15.0);
|
||||
public double? MaximumGcpAngleRateRadiansPerSecond;
|
||||
|
||||
/// <summary>
|
||||
/// 终点位置和剩余弧长的完成容差,单位为m。
|
||||
/// 获取或设置本次动作的终点距离容差覆盖值,单位为m;为空时读取车辆配置。
|
||||
/// </summary>
|
||||
public double FinishDistanceMeters = 0.03;
|
||||
public double? FinishDistanceMeters;
|
||||
|
||||
/// <summary>
|
||||
/// 终点停稳判定允许的实际线速度,单位为m/s。
|
||||
/// 获取或设置本次动作的终点速度容差覆盖值,单位为m/s;为空时读取车辆配置。
|
||||
/// </summary>
|
||||
public double FinishSpeedMetersPerSecond = 0.02;
|
||||
public double? FinishSpeedMetersPerSecond;
|
||||
|
||||
/// <summary>
|
||||
/// 终点航向完成容差,单位为rad。
|
||||
/// 获取或设置本次动作的终点航向容差覆盖值,单位为rad;为空时读取车辆配置。
|
||||
/// </summary>
|
||||
public double FinishHeadingToleranceRadians =
|
||||
AngleMath.DegreesToRadians(3.0);
|
||||
public double? FinishHeadingToleranceRadians;
|
||||
|
||||
/// <summary>
|
||||
/// 终点减速阶段提前读取参考速度的距离,单位为m。
|
||||
/// 获取或设置本次动作的终点制动预瞄距离覆盖值,单位为m;为空时读取车辆配置。
|
||||
/// </summary>
|
||||
public double TerminalBrakingPreviewMeters = 0.02;
|
||||
public double? TerminalBrakingPreviewMeters;
|
||||
|
||||
/// <summary>
|
||||
/// 车辆允许偏离参考轨迹的最大欧氏距离,单位为m。
|
||||
/// 获取或设置本次动作的最大轨迹偏离距离覆盖值,单位为m;为空时读取车辆配置。
|
||||
/// </summary>
|
||||
public double MaximumDistanceToTrajectoryMeters = 0.30;
|
||||
public double? MaximumDistanceToTrajectoryMeters;
|
||||
|
||||
/// <summary>
|
||||
/// 单次轨迹动作允许的最长执行时间,单位为s。
|
||||
/// 获取或设置本次动作的执行超时覆盖值,单位为s;为空时读取车辆配置。
|
||||
/// </summary>
|
||||
public double ExecutionTimeoutSeconds = 120.0;
|
||||
public double? ExecutionTimeoutSeconds;
|
||||
|
||||
/// <summary>
|
||||
/// 获取本次动作创建的控制器,尚未开始时为空。
|
||||
@@ -147,11 +148,78 @@ namespace MultiWheelC
|
||||
public ParkingGeometricController Controller { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// 创建控制器并持续执行控制周期,直到轨迹完成、失败或动作被取消。
|
||||
/// 等待舵轮稳定回正后创建控制器并持续执行,直到轨迹完成、失败或动作被取消。
|
||||
/// </summary>
|
||||
public override IEnumerable<bool> Get()
|
||||
{
|
||||
ValidateParameters();
|
||||
var config = PilotDefinition.Conf;
|
||||
var stanleyCrossTrackGainPerSecond =
|
||||
StanleyCrossTrackGainPerSecond ??
|
||||
config.ParkingStanleyCrossTrackGain;
|
||||
var stanleyHeadingErrorGain =
|
||||
StanleyHeadingErrorGain ??
|
||||
config.ParkingStanleyHeadingGain;
|
||||
var stanleyMinimumSpeedMetersPerSecond =
|
||||
StanleyMinimumSpeedMetersPerSecond ??
|
||||
config.ParkingStanleyMinimumSpeed;
|
||||
var stanleyUsesActualSpeed =
|
||||
StanleyUsesActualSpeed ??
|
||||
config.ParkingStanleyUseActualSpeed;
|
||||
var maximumCrossTrackCorrectionRadians =
|
||||
MaximumCrossTrackCorrectionRadians ??
|
||||
AngleMath.DegreesToRadians(
|
||||
config.ParkingMaximumCrossTrackCorrectionDegrees);
|
||||
var maximumHeadingCorrectionRadians =
|
||||
MaximumHeadingCorrectionRadians ??
|
||||
AngleMath.DegreesToRadians(
|
||||
config.ParkingMaximumHeadingCorrectionDegrees);
|
||||
var longitudinalKp =
|
||||
LongitudinalKp ??
|
||||
config.ParkingLongitudinalKp;
|
||||
var longitudinalKiPerSecond =
|
||||
LongitudinalKiPerSecond ??
|
||||
config.ParkingLongitudinalKi;
|
||||
var longitudinalKdSeconds =
|
||||
LongitudinalKdSeconds ??
|
||||
config.ParkingLongitudinalKd;
|
||||
var maximumIntegralCorrectionMetersPerSecond =
|
||||
MaximumIntegralCorrectionMetersPerSecond ??
|
||||
config.ParkingMaximumIntegralCorrection;
|
||||
var maximumCommandSpeedMetersPerSecond =
|
||||
MaximumCommandSpeedMetersPerSecond ??
|
||||
config.ParkingMaximumCommandSpeed;
|
||||
var longitudinalSpeedErrorDeadbandMetersPerSecond =
|
||||
LongitudinalSpeedErrorDeadbandMetersPerSecond ??
|
||||
config.ParkingLongitudinalSpeedErrorDeadband;
|
||||
var maximumGcpAngleRadians =
|
||||
MaximumGcpAngleRadians ??
|
||||
AngleMath.DegreesToRadians(
|
||||
config.ParkingMaximumGcpAngleDegrees);
|
||||
var maximumGcpAngleRateRadiansPerSecond =
|
||||
MaximumGcpAngleRateRadiansPerSecond ??
|
||||
AngleMath.DegreesToRadians(
|
||||
config.ParkingMaximumGcpAngleRateDegreesPerSecond);
|
||||
var finishDistanceMeters =
|
||||
FinishDistanceMeters ??
|
||||
config.ParkingFinishDistance;
|
||||
var finishSpeedMetersPerSecond =
|
||||
FinishSpeedMetersPerSecond ??
|
||||
config.ParkingFinishSpeed;
|
||||
var finishHeadingToleranceRadians =
|
||||
FinishHeadingToleranceRadians ??
|
||||
AngleMath.DegreesToRadians(
|
||||
config.ParkingFinishHeadingToleranceDegrees);
|
||||
var terminalBrakingPreviewMeters =
|
||||
TerminalBrakingPreviewMeters ??
|
||||
config.ParkingTerminalBrakingPreview;
|
||||
var maximumDistanceToTrajectoryMeters =
|
||||
MaximumDistanceToTrajectoryMeters ??
|
||||
config.ParkingMaximumDistanceToTrajectory;
|
||||
var executionTimeoutSeconds =
|
||||
ExecutionTimeoutSeconds ??
|
||||
config.ParkingExecutionTimeoutSeconds;
|
||||
|
||||
ValidateParameters(executionTimeoutSeconds);
|
||||
|
||||
var chassis =
|
||||
PilotDefinition.Chassis as MultiWheelChassis;
|
||||
@@ -161,6 +229,24 @@ namespace MultiWheelC
|
||||
"当前底盘不是MultiWheelChassis,无法执行新版轨迹跟踪动作。");
|
||||
}
|
||||
|
||||
var wheelPreparation =
|
||||
new PrepareWheelsForward();
|
||||
foreach (var keepRunning in wheelPreparation.Get())
|
||||
{
|
||||
if (!keepRunning)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
yield return true;
|
||||
}
|
||||
|
||||
if (!wheelPreparation.Completed)
|
||||
{
|
||||
throw new InvalidOperationException(
|
||||
"轨迹跟踪开始前舵轮未能稳定回到车头方向。");
|
||||
}
|
||||
|
||||
var adapter = new MultiWheelChassisAdapter(
|
||||
chassis,
|
||||
PilotDefinition.Self.CarNum);
|
||||
@@ -170,34 +256,44 @@ namespace MultiWheelC
|
||||
|
||||
var stateProvider =
|
||||
StateProvider ??
|
||||
new DetourVehicleStateProvider();
|
||||
ParkingVehicleStateProviderFactory.Create(
|
||||
chassis,
|
||||
config);
|
||||
var controlPointRadiusMeters =
|
||||
chassis.ControlPointRadius / 1000.0;
|
||||
|
||||
var lateralController =
|
||||
new StanleyLateralController(
|
||||
controlPointRadiusMeters,
|
||||
StanleyCrossTrackGainPerSecond,
|
||||
StanleyHeadingErrorGain,
|
||||
StanleyMinimumSpeedMetersPerSecond,
|
||||
StanleyUsesActualSpeed,
|
||||
MaximumCrossTrackCorrectionRadians,
|
||||
MaximumHeadingCorrectionRadians);
|
||||
LateralControllerFactory == null
|
||||
? new StanleyLateralController(
|
||||
controlPointRadiusMeters,
|
||||
stanleyCrossTrackGainPerSecond,
|
||||
stanleyHeadingErrorGain,
|
||||
stanleyMinimumSpeedMetersPerSecond,
|
||||
stanleyUsesActualSpeed,
|
||||
maximumCrossTrackCorrectionRadians,
|
||||
maximumHeadingCorrectionRadians)
|
||||
: LateralControllerFactory(
|
||||
controlPointRadiusMeters);
|
||||
if (lateralController == null)
|
||||
{
|
||||
throw new InvalidOperationException(
|
||||
"横向控制器创建委托不能返回空值。");
|
||||
}
|
||||
var longitudinalController =
|
||||
new PidLongitudinalController(
|
||||
LongitudinalKp,
|
||||
LongitudinalKiPerSecond,
|
||||
LongitudinalKdSeconds,
|
||||
MaximumIntegralCorrectionMetersPerSecond,
|
||||
MaximumCommandSpeedMetersPerSecond,
|
||||
LongitudinalSpeedErrorDeadbandMetersPerSecond);
|
||||
longitudinalKp,
|
||||
longitudinalKiPerSecond,
|
||||
longitudinalKdSeconds,
|
||||
maximumIntegralCorrectionMetersPerSecond,
|
||||
maximumCommandSpeedMetersPerSecond,
|
||||
longitudinalSpeedErrorDeadbandMetersPerSecond);
|
||||
var gcpAllocator =
|
||||
new GcpCommandAllocator(
|
||||
MaximumGcpAngleRadians);
|
||||
maximumGcpAngleRadians);
|
||||
var commandExecutor =
|
||||
new GcpCommandExecutor(
|
||||
adapter,
|
||||
MaximumGcpAngleRateRadiansPerSecond);
|
||||
maximumGcpAngleRateRadiansPerSecond);
|
||||
|
||||
Controller = new ParkingGeometricController(
|
||||
stateProvider,
|
||||
@@ -205,11 +301,11 @@ namespace MultiWheelC
|
||||
longitudinalController,
|
||||
gcpAllocator,
|
||||
commandExecutor,
|
||||
FinishDistanceMeters,
|
||||
FinishSpeedMetersPerSecond,
|
||||
FinishHeadingToleranceRadians,
|
||||
MaximumDistanceToTrajectoryMeters,
|
||||
TerminalBrakingPreviewMeters);
|
||||
finishDistanceMeters,
|
||||
finishSpeedMetersPerSecond,
|
||||
finishHeadingToleranceRadians,
|
||||
maximumDistanceToTrajectoryMeters,
|
||||
terminalBrakingPreviewMeters);
|
||||
|
||||
var clock = Stopwatch.StartNew();
|
||||
var previousCycleSeconds =
|
||||
@@ -221,10 +317,10 @@ namespace MultiWheelC
|
||||
while (true)
|
||||
{
|
||||
if (clock.Elapsed.TotalSeconds >
|
||||
ExecutionTimeoutSeconds)
|
||||
executionTimeoutSeconds)
|
||||
{
|
||||
throw new TimeoutException(
|
||||
$"新版轨迹跟踪超过{ExecutionTimeoutSeconds:F1}s仍未完成。");
|
||||
$"新版轨迹跟踪超过{executionTimeoutSeconds:F1}s仍未完成。");
|
||||
}
|
||||
|
||||
var currentCycleSeconds =
|
||||
@@ -291,7 +387,8 @@ namespace MultiWheelC
|
||||
/// <summary>
|
||||
/// 在接管实际底盘前检查动作自身无法由子控制器检查的参数。
|
||||
/// </summary>
|
||||
private void ValidateParameters()
|
||||
private void ValidateParameters(
|
||||
double executionTimeoutSeconds)
|
||||
{
|
||||
if (Trajectory == null)
|
||||
{
|
||||
@@ -299,9 +396,9 @@ namespace MultiWheelC
|
||||
"新版轨迹跟踪动作没有设置Trajectory。");
|
||||
}
|
||||
|
||||
if (double.IsNaN(ExecutionTimeoutSeconds) ||
|
||||
double.IsInfinity(ExecutionTimeoutSeconds) ||
|
||||
ExecutionTimeoutSeconds <= 0.0)
|
||||
if (double.IsNaN(executionTimeoutSeconds) ||
|
||||
double.IsInfinity(executionTimeoutSeconds) ||
|
||||
executionTimeoutSeconds <= 0.0)
|
||||
{
|
||||
throw new ArgumentOutOfRangeException(
|
||||
nameof(ExecutionTimeoutSeconds),
|
||||
|
||||
Reference in New Issue
Block a user