← Blog디버깅 전쟁 일지· 7/7

차가 차를 통과한다 — ORCA 회피와 PhysX 충돌을 혼동한 대가

차량끼리 부딪혀도 그냥 통과하고, 장애물도 뚫고 지나갔다. 두 개의 충돌 개념(ORCA 사전 회피 vs PhysX 물리 접촉)을 혼동한 데서 비롯된 버그를 풀어낸 기록.

약 2분
debuggingcollisionPhysXORCAwar-story

차가 차를 통과한다

지상 차량 시뮬레이션에서 이상한 일이 벌어졌습니다. 차량끼리 그냥 통과했습니다. 장애물도 뚫고 지나갔습니다. 분명 충돌 처리가 있는데 왜 물체들이 서로를 유령처럼 지나칠까요?

두 개의 다른 "충돌"

핵심은 — 이 시스템에 충돌이 두 종류라는 걸 혼동한 것이었습니다.

도식 렌더링 중…
  • ORCA(사전 회피) — 다중 에이전트가 서로의 속도를 예측해 미리 비켜 가는 계획 단계. 닿기 전에 피합니다.
  • PhysX(물리 접촉) — 그래도 실제로 닿으면 강체가 튕겨내는 물리 단계.

"충돌이 처리된다"고 믿었지만, ORCA 회피만 보고 PhysX 접촉 충돌체가 실제로 작동하는지는 확인하지 않았던 것입니다. 둘은 완전히 다른 레이어입니다.

통과의 진짜 원인들

파고들자 여러 겹이 나왔습니다.

  • 충돌 지오메트리가 너무 작았다 — 차량 차대의 충돌체(Cube)가 실제 차체보다 작아, 외형은 닿아도 충돌체는 안 닿았습니다.
  • 기본 충돌 반경이 너무 작았다 — 회피용 기본 반경(0.3m)이 차량 크기에 비해 작아, 큰 차들이 서로를 통과.
  • 누적 추적이 없었다 — 충돌이 몇 번 났는지 세지 않으니, 통과가 조용히 넘어갔습니다.

⚠️ "회피되니까 충돌도 되겠지"는 틀린다 — ORCA가 잘 비켜 가는 걸 보고 "충돌 처리 완료"라 믿으면, 정작 회피가 실패해 실제로 닿는 순간 통과가 납니다. 사전 회피(ORCA)와 물리 접촉(PhysX)은 각각 따로 검증해야 합니다.

고침 — 그리고 fail-loud

수정은 여러 곳이었습니다 — 차대 충돌체를 실제 크기로 키우고, 기본 반경을 1.5m로 올리고, 절차적 환경의 장애물에 충돌체를 부여했습니다. 그리고 가장 중요한 한 가지:

💡 충돌 횟수를 세고, 통과를 fail-loud로 — 충돌을 누적 추적하고, 통과(겹침)가 감지되면 조용히 넘기지 말고 단언(assert) 실패로 터뜨리게 했습니다. 그래야 다음에 통과가 생기면 즉시 드러납니다. "통과가 없다"를 믿는 게 아니라 측정하는 것입니다.

한 줄 정리

📌 차량이 서로를 통과한 건, ORCA(사전 회피)와 PhysX(물리 접촉)를 혼동해 후자를 검증 안 한 탓이었다. 충돌체가 차체보다 작고, 기본 반경이 작고, 누적 추적이 없어 통과가 조용히 넘어갔다. 둘은 따로 검증해야 하며, 충돌은 세어서 통과를 fail-loud로 터뜨려야 한다.