62 lines
3.0 KiB
C#
62 lines
3.0 KiB
C#
using System;
|
||
using MultiWheelC.TrajectoryPlanning.Utils;
|
||
|
||
namespace MultiWheelC.TrajectoryPlanning.CoarsePath.Search;
|
||
|
||
/// <summary>按位置、航向和进入方向约束判定连续位姿是否可以作为目标候选。</summary>
|
||
public static class GoalToleranceChecker
|
||
{
|
||
/// <summary>
|
||
/// 判断一个位姿是否满足目标容差和进入方向约束。
|
||
/// 参数:pose 与 goal 使用世界 m/rad;configuration 提供位置 m 和航向 rad 容差;direction 为候选末段方向;goalDirection 为目标进入方向约束。
|
||
/// 返回:输入有限、位置距离和最小环形航向误差均不超过容差且方向匹配时为 true;无效输入保守地返回 false。
|
||
/// </summary>
|
||
public static bool IsSatisfied(
|
||
Pose2D pose,
|
||
Pose2D goal,
|
||
HybridAStarConfiguration configuration,
|
||
TravelDirection direction,
|
||
GoalDirectionConstraint goalDirection)
|
||
{
|
||
if (!IsFinitePose(pose) || !IsFinitePose(goal) || configuration == null ||
|
||
!NumericGuard.IsFinite(configuration.GoalPositionToleranceMeters) ||
|
||
!NumericGuard.IsFinite(configuration.GoalHeadingToleranceRadians) ||
|
||
configuration.GoalPositionToleranceMeters < 0d || configuration.GoalHeadingToleranceRadians < 0d ||
|
||
!IsTravelDirection(direction) || !IsGoalDirection(goalDirection))
|
||
return false;
|
||
|
||
if (!MatchesDirection(direction, goalDirection)) return false;
|
||
|
||
double deltaX = pose.X - goal.X;
|
||
double deltaY = pose.Y - goal.Y;
|
||
double positionDistanceMeters = Math.Sqrt(deltaX * deltaX + deltaY * deltaY);
|
||
if (!NumericGuard.IsFinite(positionDistanceMeters) || positionDistanceMeters > configuration.GoalPositionToleranceMeters)
|
||
return false;
|
||
|
||
double headingDifferenceRadians = Math.Abs(AngleMath.ShortestSignedDifference(pose.Heading, goal.Heading));
|
||
return NumericGuard.IsFinite(headingDifferenceRadians) && headingDifferenceRadians <= configuration.GoalHeadingToleranceRadians;
|
||
}
|
||
|
||
private static bool IsFinitePose(Pose2D pose)
|
||
{
|
||
return pose != null && NumericGuard.IsFinite(pose.X) && NumericGuard.IsFinite(pose.Y) && NumericGuard.IsFinite(pose.Heading);
|
||
}
|
||
|
||
private static bool IsTravelDirection(TravelDirection direction)
|
||
{
|
||
return direction == TravelDirection.Forward || direction == TravelDirection.Reverse;
|
||
}
|
||
|
||
private static bool IsGoalDirection(GoalDirectionConstraint direction)
|
||
{
|
||
return direction == GoalDirectionConstraint.Any || direction == GoalDirectionConstraint.Forward || direction == GoalDirectionConstraint.Reverse;
|
||
}
|
||
|
||
private static bool MatchesDirection(TravelDirection direction, GoalDirectionConstraint constraint)
|
||
{
|
||
return constraint == GoalDirectionConstraint.Any ||
|
||
(constraint == GoalDirectionConstraint.Forward && direction == TravelDirection.Forward) ||
|
||
(constraint == GoalDirectionConstraint.Reverse && direction == TravelDirection.Reverse);
|
||
}
|
||
}
|