Files
fori_zltech_motor_test/QnA/a1.md
T
Dongubak 2f21d86193 Add ZLAC8015D driver docs, IMU integration plan, and reference resources
Documents the ZLAC8015D V4 dual-channel driver (hardware spec, RS485
Modbus register map, 4WD skid-steer system architecture, the
xbox_motor_control.cpp control loop, and error/troubleshooting) under
doc/, plus a phased plan for adding IMU-based heading/slip feedback
(doc/06) informed by Clearpath Husky's sensor fusion stack and
skid-steer ICR literature. QnA/ records the Q&A that refined that plan.
Also adds the underlying manual PDFs and reference links under
resource/ that the docs cite.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-16 00:17:24 +09:00

13 KiB
Raw Blame History

A (q1.md에 대한 답변)

doc/06-imu-integration-plan.md에 대한 4가지 질문에 순서대로 답한다. 결론을 먼저 요약하면: 개루프(조이스틱)와 폐루프(IMU 트림)는 상충하지 않으며 실무에서도 계층 구조로 함께 쓰인다. ICR은 실제로 동적이며 9축 IMU로 온라인 추정이 가능하다. 헤딩 홀드는 상대 헤딩 기준 + 최소한의 필터링으로 충분하다. HWT905는 RS485/Modbus를 지원해 기존 통신 스택 재사용이 가능하다.


Q1. 조이스틱 폐루프 제어가 실무에서 실제로 쓰이는가?

결론: 쓰인다. 다만 사용자가 걱정하는 "조이스틱 값이 바뀌면 폐루프 계산을 처음부터 다시 해야 한다"는 문제는 애초에 발생하지 않는다. 그 걱정 자체가 폐루프 제어에 대한 흔한 오해를 짚고 있어서, 왜 문제가 안 되는지부터 설명한다.

왜 "재계산 문제"가 없는가

폐루프 제어의 기본 형태는 다음과 같다.

e(t) = r(t)  y(t)     // r(t): 기준값(레퍼런스), y(t): 센서 측정값
u(t) = Controller(e(t))  // 그 순간의 오차만 보고 그 순간의 보정량을 계산

여기서 r(t)(조이스틱이 매 순간 주는 목표값)가 틱마다 바뀌는 것은 폐루프 제어의 정상적인 동작 방식이지, 예외 상황이 아니다. 제어기는 "이전 계산이 끝날 때까지 기다렸다가 다음 값을 반영"하는 게 아니라, 매 사이클(본 프로젝트는 100Hz=10ms)마다 그 순간의 r(t)y(t)만으로 그 순간의 보정량 하나를 계산한다. 지금 이미 코드에 있는 jerkLimitedStep()도 정확히 이 구조다 — target_*(조이스틱에서 매 틱 갱신되는 레퍼런스)가 바뀌어도 다음 틱에서 그냥 새 target_* 기준으로 다시 한 스텝 계산할 뿐, "이전 목표를 향한 계산이 안 끝났으니 못 바꾼다"는 일이 없다. 헤딩 홀드도 동일한 구조로 넣을 수 있다.

이미 이 프로젝트에도 폐루프가 존재한다

"조이스틱 제어 = 개루프"라는 인식은 절반만 맞다. 계층을 나눠보면:

계층 신호 흐름 개/폐루프
상위 (조이스틱 → 목표 RPM) ly/lx/rx → 스키드 스티어 킨매틱스 → target_fl/fr/rl/rr 개루프 (피드포워드)
중위 (목표 RPM → 지령 RPM) 저크 제한 S-curve (jerkLimitedStep) 개루프 프로파일 생성 (폐루프 아님, 단 매 틱 최신 목표 반영)
하위 (지령 RPM → 실제 RPM) 드라이버 내장 Velocity Loop (0x203C/0x203D/0x203E L, 0x206C/0x206D/0x206E R — Kp/Ki/Kf) 이미 폐루프. 부하가 걸려도 드라이버가 실제 RPM을 지령 RPM에 맞추려 함

즉 지금도 "조이스틱 값 → 목표 속도"까지는 개루프지만, "목표 속도 → 실제 바퀴 속도"는 이미 드라이버가 폐루프로 하고 있다. IMU 헤딩 홀드(계획서 Phase 3)는 이 구조에 한 계층을 더 얹는 것뿐이다: "조향 입력이 중립일 때, 목표 요레이트(=0)와 실측 요레이트(IMU)의 오차를 보고 좌/우 목표 RPM에 작은 트림을 더한다." 조이스틱이 다시 움직이면(조향 입력 재개) 그 즉시 헤딩 락을 풀고 트림을 0으로 되돌리면 되므로, "조이스틱 값 변경 시 재계산" 문제는 설계상 발생하지 않는다.

실무 사례 (동일 패턴)

  • 자동차 ESC/TCS(전자식 주행안정장치): 운전자의 스티어링·가속페달이 항상 최우선 레퍼런스지만, 요레이트 센서가 실측한 값이 스티어링 각도로부터 기대되는 값과 어긋나면 개별 바퀴 브레이크/토크를 트림한다. 운전자가 스티어링을 계속 바꿔도 문제없이 동작 — 매 사이클 그 순간의 편차만 본다.
  • 쿼드콥터: 스틱은 각속도/자세에 대한 레퍼런스이고, 내부 자세제어 루프가 IMU로 안정화한다. 스틱을 중립으로 놓으면 자세/포지션 홀드로 전환되어 바람 등 외란을 자동 보정 — Phase 3와 정확히 동일한 "중립 시에만 홀드" 패턴.
  • 선박 오토파일럿: 조타핸들이 중립일 때만 자이로컴퍼스 기준 헤딩홀드가 개입하고, 조타를 움직이면 즉시 새 헤딩으로 재설정된다.

요약: 실무의 표준 패턴은 "조이스틱 = 상위 레퍼런스(운전자 의도, 매 틱 갱신 가능) + 하위 폐루프(그 레퍼런스를 추종·안정화)"의 계층 구조다. 계획서 Phase 3가 제안하는 헤딩 홀드도 이 패턴을 그대로 따른다.


Q2. ICR이 동적이라면, IMU로 이를 감지해 더 고차원의 제어가 가능한가?

결론: 가능하다. 그리고 지적한 대로 현재 로직은 "동적으로 변하는 현상을 정적 스칼라로 땜빵"한 것이 맞다.

현재 로직이 "땜빵"인 이유 (재확인)

k_skid, effective_w는 로봇 형상(트랙폭, 축거)만으로 계산된 기하학적 근사치이고, spin_arc_bias=0.12는 실측 없이 경험으로 넣은 상수다. 이 값들은 지면 마찰계수, 무게중심, 경사, 타이어 트레드 마모, 속도에 따라 실제로는 계속 바뀌는 "유효 ICR"을 대표할 수 없다 — 특정 노면/속도 조건에서 튜닝된 값일 뿐이다.

9축 IMU가 추가하는 정보 차원

IMU 축 얻는 정보 현재(전류+엔코더)로는 불가능한 이유
자이로 요레이트 로봇이 실제로 얼마나 회전하고 있는가 (슬립 무관) 전류는 부하/토크 정보, 엔코더는 개별 바퀴 회전량 정보일 뿐 — 차체가 실제로 얼마나 돌았는지는 아무도 안 알려준다
가속도계 (중력보정 후) 급조향/급가감속 시 차체가 실제로 그만큼 가속했는가 저크 리미터가 만드는 "기대 가속도"와 비교해 "명령은 갔는데 차체가 안 따라옴" 상태(전신 슬립)를 검출 가능
Roll/Pitch(경사각) 현재 지형이 경사면인지 경사에서는 좌우 바퀴 접지압이 비대칭이 되어 ICR이 더 크게 틀어짐 — 지금은 이 정보 자체가 전무
지자기 절대 방위 참조 (제한적) 다만 차체가 모터/드라이버/배터리 등 금속 덩어리라 지자기 왜곡이 클 가능성이 높음 — 절대 헤딩보다는 참고용으로만 신중히 사용 권장

"정적 캘리브레이션"보다 한 단계 더 — 온라인 ICR 추정

계획서 Phase 5(§6.4)는 원래 "몇 차례 실측 후 한 번 피팅해서 상수를 교체"하는 정적 캘리브레이션으로 설계했다. 하지만 지적한 대로 ICR이 지형에 따라 계속 바뀐다면, 매 틱

effective_ICR_gain = 실측_요레이트(IMU) / 지령_차동속도

를 계속 갱신하는 온라인 추정(Pentzer 2014가 제안한 방식)이 이론적으로는 더 맞는 방향이다. 다만 이건 Phase 5를 정적 캘리브레이션 → 상시 온라인 추정으로 확장하는 것이므로, 구현 난이도와 실외 검증 부담이 커진다. 이번 답변을 반영해 계획서 §6.4 Phase 5에 "1차: 정적 캘리브레이션으로 먼저 검증 → 2차: 온라인 추정으로 확장 가능"이라는 단계를 추가해 두었다(아래 "계획서 반영" 참고).

우선순위: 조이스틱 제어가 먼저라는 원칙과의 정합성

이 답변에서 제안하는 내용은 계획서의 Phase 순서를 바꾸지 않는다. Phase 1~2(§6.4)는 IMU 값을 "관측/로깅"만 할 뿐 제어에 전혀 개입하지 않으므로, 조이스틱 제어 자체의 완성도에는 영향을 주지 않는다. ICR 온라인 추정 같은 고차원 활용은 Phase 5 이후, 즉 조이스틱 경로가 충분히 검증된 다음에야 의미가 있는 단계로 이미 순서가 잡혀 있다.


Q3. 헤딩 기준을 IMU로 얻어 직진 편향 보정이 가능한가? 필터는?

결론: 맞다. 그리고 이 용도에서는 "정밀한 절대 헤딩"이 아니라 "짧은 구간 동안의 상대 헤딩"만 있으면 되기 때문에, 필터링 요구 수준이 생각보다 무겁지 않다.

왜 절대 헤딩이 필요 없는가

Phase 3(§6.4)의 헤딩 홀드는 "조향 입력이 중립인 동안 로봇이 옆으로 틀어지지 않게" 하는 용도다. 조향 입력이 다시 들어오면(사용자가 스틱을 움직이면) 헤딩 락을 풀고, 다시 중립이 되는 시점에 **그 순간의 방향을 새 기준으로 재설정(reset)**하면 된다. 즉 각 "직진 구간"은 보통 수 초~수십 초 단위이므로, 자이로 바이어스 드리프트가 누적될 시간 자체가 짧아 실사용상 큰 문제가 되지 않는다. (장기 절대 헤딩이 필요해지는 건 계획서 Phase 6의 자율주행/맵핑 단계부터다.)

그래도 필요한 최소한의 처리

  1. 정적 바이어스 캘리브레이션: 전원 인가 직후 정지 상태에서 수 초간 자이로 값을 평균 내 영점(zero-rate offset)을 구해 빼준다. 이거 없이는 정지 중에도 헤딩이 서서히 흘러간다.
  2. 노이즈 필터링: 실외 오프로드 특성상 진동이 크다. 저역통과 또는 이동평균 정도로 고주파 진동 성분을 제거해야 트림 제어기가 노이즈에 반응해 떨지 않는다.
  3. HWT905류 온보드 AHRS 모듈을 쓰면 위 부담이 상당 부분 줄어든다: 이 모듈은 가속도+자이로 +지자기를 내부적으로 칼만필터 등으로 융합해 이미 안정화된 roll/pitch/yaw를 직접 출력한다. 순수 MEMS 칩(raw 자이로 값만 주는 IC)을 쓰는 것보다 애플리케이션 쪽 필터링 구현 부담이 훨씬 적다 — Q4에서 이어서 설명.

Q4. IMU 하드웨어: HWT905 확정

WitMotion 공식 자료 기준으로 확인한 HWT905-RS485 스펙 (정식 PDF 매뉴얼은 이미지 기반이라 텍스트 자동 추출이 안 돼, 아래는 제조사 웹페이지 기준 요약이다 — 레지스터 맵 등 세부 사항은 §실행 전 확인 필요 참고):

항목 내용
측정 축 9축 — 가속도 3축 + 자이로 3축 + 지자기 3축, 내장 자세융합 알고리즘으로 roll/pitch/yaw 직접 출력
통신 RS485, Modbus 프로토콜 지원(레지스터 리스트 기반)
보드레이트 기본 9600bps, 2400~921600bps 가변
출력 레이트 최대 200Hz
정확도 제조사 공식 스펙 "0.05°" (동적/정적 조건은 정식 PDF 확보 후 재확인 필요)
케이스 55×36.8×24mm 알루미늄, IP67 방수/방진
케이블 RS485 최대 30m

이 프로젝트에 잘 맞는 이유

  1. RS485 + Modbus 프로토콜xbox_motor_control.cppSerialPort 클래스(Modbus RTU, CRC16, readReg/writeReg/readRegs 패턴)를 상당 부분 재사용할 수 있다. IMU만을 위한 완전히 새로운 통신 스택을 만들 필요가 없다. (단, ZLAC8015D 2대가 이미 쓰고 있는 버스에 같이 물릴지, 별도 물리 포트로 분리할지는 §실행 전 확인 필요에서 결정해야 한다 — 100Hz 루프에서 통신 3개 슬레이브를 한 버스로 돌리면 틱당 통신 시간이 늘어날 수 있다.)
  2. IP67 방수/방진 — 실외 로봇이라는 조건에 부합.
  3. 온보드 AHRS 융합 — Q3에서 설명한 필터링 부담을 하드웨어가 상당 부분 대신 처리해준다. 저가 MEMS 칩 대비 확실한 이점.

실행 전 확인 필요 (아직 확정 못한 것)

이번 조사에서 확보한 HWT905 정식 매뉴얼 PDF는 이미지 스캔본이라 텍스트 추출이 되지 않아, 정확한 레지스터 주소(각속도/각도/가속도/지자기 레지스터, 출력레이트 설정 레지스터, 슬레이브 주소 설정 방법 등)는 이번 문서에 포함하지 못했다. ZLAC8015D 때와 동일한 방식으로 진행하려면:

  1. HWT905 정식 매뉴얼(텍스트 검색 가능한 PDF)을 resource/에 추가.
  2. doc/07-imu-hwt905-spec.md(가칭)로 레지스터 맵을 ZLAC8015D 문서와 동일한 정밀도로 문서화.
  3. 그 다음에야 Phase 1(하드웨어 연동) 코드 작업 착수.

계획서(doc/06-imu-integration-plan.md) 반영 사항

이 답변 내용을 반영해 계획서를 다음과 같이 갱신했다:

  • §6.7 "결정이 필요한 사항" 중 IMU 하드웨어 항목을 HWT905로 확정 표시.
  • Phase 5에 "정적 캘리브레이션 → 온라인 ICR 추정으로 확장 가능" 단계 구분을 추가.
  • Phase 1 앞에 "IMU 정식 매뉴얼 확보 및 레지스터 맵 문서화"를 선행 작업으로 명시.

남은 결정 사항: IMU를 ZLAC8015D와 같은 RS485 버스에 물릴지, 별도 포트로 분리할지 — 이건 실측(버스 하나에 3개 슬레이브 얹었을 때 100Hz 루프의 comm_ms 여유가 있는지) 후 결정하는 것을 제안한다.