언리얼 스플라인 경로 추종 차량이 도로 밖으로 튕길 때, 평면 조향과 이탈 페일세이프 분리
스플라인을 따라가는 자율주행 차량이 커브에서 도로 밖으로 튕겨 나가고, 도로 밑으로 떨어진 뒤에도 자율주행은 정상 주행 중이라고 판단하는 문제를 다룬 기록이다.
결론부터 말하면 조향 계산 자체는 손대지 않고, 도로 이탈을 감지하는 별도 로직을 분리해서 해결했다.
처음 의심한 곳: 조향이 높이를 무시한다
조향 오차 계산이 X-Y 평면만 쓰고 있었다.
const FVector ToLA = (LAPos - VehicleLocation).GetSafeNormal();
Errors.PositionError = FMath::FindDeltaAngleDegrees(
VehicleYaw,
FMath::Atan2(ToLA.Y, ToLA.X) * (180.f / PI));
Z를 무시하니 차가 도로 밑에 있어도 평면 위치만 맞으면 정상으로 본다고 추측했다.
그래서 목표 지점의 Z를 차량 높이에 맞춰 보정하려 했다.
하지만 이 방향은 틀렸다.
핸들의 회전축은 수직(Z축)이고, 그 결과 핸들 각도 변화는 수평(X-Y) 평면에서 일어난다.
즉 조향 계산이 X-Y 평면만 보는 것은 비정상이 아니라 오히려 자연스러운 동작이다.
여기서 Z를 끌어들이면 문제가 아닌 곳을 건드리게 된다.
진짜 원인: 가장 가까운 점은 항상 도로 위에 있다
차량 위치를 도로 위 거리로 변환하는 코드는 이렇다.
const float InputKey = Spline->FindInputKeyClosestToWorldLocation(VehicleLocation);
CurrentDistance = Spline->GetDistanceAlongSplineAtSplineInputKey(InputKey);
이 함수는 차량과 가장 가까운 스플라인 위 점을 찾는다.
문제는 차량이 도로 아래로 30m 떨어져 있어도, 도로 위 모든 점 중에서 가장 가까운 점은 여전히 차량 바로 위의 도로 점이라는 것이다.
그 점의 거리값이 CurrentDistance에 저장되므로, 자율주행 입장에서는 여전히 정상 경로 위에 있다고 인식한다.
차량이 수직으로 얼마나 벗어났는지는 이 방식으로는 알 수 없다.
선택한 방향: 조향은 그대로, 이탈 감지는 별도로
조향 로직은 평면 기준이 맞으므로 건드리지 않고, 도로에서 벗어났는지를 판단하는 페일세이프를 따로 두기로 했다.
핵심은 평면 거리가 아니라 3D 거리로 보는 것이다.
const FVector RoadHere = GetLocationAtDistance(CurrentDistance);
if (FVector::Dist(VehicleLoc, RoadHere) > MaxRoadDeviation)
{
ApplySpeedCommand(0.f, VehicleSpeed);
ApplySteeringCommand(0.f);
return;
}
FVector::Dist는 3D 거리를 재기 때문에 차량이 도로 밑으로 떨어지면 Z 차이가 그대로 거리에 반영된다.
차량 Z가 -3000, 도로 점 Z가 100이면 3D 거리가 임계값을 넘어 페일세이프가 작동한다.
MaxRoadDeviation은 에디터에서 조정할 수 있는 값으로 빼두면 상황에 맞게 튜닝하기 쉽다.
이 프로젝트에서 정리한 원칙은, 정상 동작인 평면 조향을 의심하기보다 "벗어남을 감지하는 책임"을 별도 로직으로 분리하는 쪽이 더 안전하다는 것이다.
정상 경로 추종과 이탈 감지는 보는 기준(평면 vs 3D)이 다르므로, 한 계산에 섞지 않고 나누는 편이 디버깅도 쉬웠다.
'etc' 카테고리의 다른 글
| 언리얼 Chaos Vehicle이 멈추지 않고 후진할 때: bReverseAsBrake와 상태 머신 이해 (0) | 2026.05.16 |
|---|---|
| 언리얼 런타임 SplineMeshComponent 동적 생성: 호출 순서·탄젠트 정규화·핫리로드 함정 (0) | 2026.05.16 |
| 언리얼 자율주행 차량, 곡률 반경으로 안전 속도 계산하기 (V = √(μgR)) (0) | 2026.05.13 |
| 자율주행 차량 조향 가중치를 곡률에 따라 동적 조정하기 (Lerp 활용) (0) | 2026.05.13 |
| 언리얼 벡터로 도로 이탈 거리 구하기, Cross-Track Error 계산 과정 (0) | 2026.05.13 |
