← BlogAMR 내비게이션 입문· 8/12

RPP 컨트롤러 — Pure Pursuit가 경로를 바퀴 속도로 바꾸는 법 (그리고 0.05에 갇힌 회전 버그)

Regulated Pure Pursuit가 lookahead로 경로를 cmd_vel로 바꾸는 원리와, odom 가속 클램핑이 회전 속도를 0.05 rad/s에 영구히 가둔 실제 디버깅 사례.

약 2분
Nav2controllerRPPpure-pursuitdebugging

RPP 컨트롤러

Planner가 "어디로 갈지" 경로를 그었습니다. 이제 그 경로를 실제 바퀴 속도(cmd_vel) 로 바꿔 따라가야 합니다. 그 일을 하는 게 컨트롤러이고, AMR에서 가장 널리 쓰이는 게 Regulated Pure Pursuit(RPP) 입니다.

당근을 쫓는 토끼 — Pure Pursuit

Pure Pursuit의 직관은 단순합니다. 경로 위 앞쪽 한 점(lookahead point) 을 정하고, 그 점을 향해 부드러운 호를 그리며 따라갑니다. lookahead 거리를 늘리면 완만하게, 줄이면 민첩하게 돕니다.

도식 렌더링 중…

"Regulated"가 붙은 이유는, 곡률이 크거나 장애물이 가까우면 속도를 알아서 줄이는 규제(regulation)가 들어가기 때문입니다. 주요 파라미터:

  • lookahead_dist — 앞을 얼마나 멀리 볼지
  • desired_linear_vel — 목표 직진 속도
  • rotate_to_heading — 제자리 회전으로 방향부터 맞출지

Pure Pursuit의 핵심은 곡률 한 줄입니다.

# lookahead 점을 향한 호(arc)의 곡률 → cmd_vel
def pure_pursuit(lookahead_pt, lookahead_dist, desired_v):
    y = lookahead_pt.y                        # 로봇 좌표계의 횡방향 오차
    curvature = 2 * y / lookahead_dist**2      # 그 점을 지나는 원호
    return desired_v, desired_v * curvature    # (vx, wz)

회전이 0.05 rad/s에 갇혔다 — odom 클램프 버그

여기서 우리가 겪은 까다로운 버그가 있습니다. 로봇이 회전해야 하는데 각속도가 0.05 rad/s에 영구히 갇혀 거의 안 도는 현상이었습니다.

처음엔 velocity_smoother, 바퀴 구동, 콜백 등을 의심했지만 전부 빗나갔습니다. 토픽 사슬 곳곳에 로그를 심어 1회 실행하니(instrument-first) 범인은 RPP 자신이었습니다 — RPP가 odom의 현재 각속도를 읽어 가속을 제한(clamp) 하는데, 물리 시뮬의 odom이 한 틱 지연되면서 "현재 각속도≈0"으로 읽혀, 가속 한계(max_angular_accel)가 너무 낮으면 0.05를 못 벗어나는 악순환에 빠진 것이었습니다.

RPP 각속도 — odom 피드백 클램프 버그. 목표 1.0 rad/s인데 가속한계 1.0(빨강)에선 0.05에 갇히고, 3.2로 올리면(시안) 목표까지 도달한다.RPP 각속도 — odom 피드백 클램프 버그. 목표 1.0 rad/s인데 가속한계 1.0(빨강)에선 0.05에 갇히고, 3.2로 올리면(시안) 목표까지 도달한다.

해결은 가속 한계를 현실적인 값으로 올리는 것이었습니다(max_angular_accel 1.0 → 3.2). 위 차트처럼, 같은 명령인데 한 파라미터로 회전이 살아났습니다.

⚠️ 시뮬 odom 지연을 잊지 말 것 — closed-loop 컨트롤러가 odom 피드백으로 가속을 제한할 때, 시뮬레이션 물리의 한 틱 지연이 실로봇과 다른 거동을 만들 수 있습니다. "코드만 읽고 추측" 대신 토픽 사슬에 로그를 심어 어디서 값이 0.05로 갇히는지 데이터로 확인한 게 해결의 열쇠였습니다.

💡 RPP의 출력은 곧장 바퀴로 가지 않고 velocity_smoother를 거쳐 가감속이 매끄럽게 다듬어집니다. 컨트롤러–smoother–DriveAPI로 이어지는 사슬을 기억해 두면 디버깅이 쉽습니다.

한 줄 정리

📌 RPP는 경로 앞 lookahead 점을 호로 쫓아 cmd_vel을 만드는 컨트롤러다(곡률·장애물에 따라 속도 규제). 시뮬에서 odom 가속 클램프가 회전을 0.05에 가둘 수 있으며, 범인은 추측이 아니라 토픽 사슬 로깅으로 잡았다.