컨트롤러 자이로 센서 매핑 QA: 축 반전·축 교환·단위 변환 오류를 기기별로 검증하는 방법

컨트롤러 자이로 입력의 축 반전, 축 교환, 라디안·도 단위 변환 오류를 기기별 테스트 매트릭스와 자동 검증 절차로 찾아 수정하는 센서 매핑 QA 가이드입니다.

✓ 복사 완료!
챕터자동화 테스트 & 회귀 검증
난이도중급
상태● 검토 완료
대상 엔진
Engine Agnostic
최종 업데이트
컨트롤러 자이로 센서 매핑 QA: 축 반전·축 교환·단위 변환 오류를 기기별로 검증하는 방법

핵심 요약

컨트롤러 자이로 입력 오류는 센서 고장보다 좌표계 정의, 축 순서, 부호, 단위 변환이 플랫폼 어댑터마다 달라서 발생하는 경우가 많습니다. 원시 입력을 공통 좌표계로 정규화한 뒤 기기별 기준 동작과 회귀 테스트를 자동화하면 축 반전·축 교환·라디안/도 단위 오류를 빠르게 분리할 수 있습니다.

핵심 검증식은 다음과 같습니다.

y=S⋅P⋅R⋅(x−b)y = S · P · R · (x - b)

여기서 x는 원시 자이로 값, b는 바이어스, R은 센서 좌표계 회전, P는 축 교환과 부호 반전, S는 단위 스케일, y는 게임이 사용하는 공통 좌표계 입력입니다.

왜 컨트롤러 자이로 입력은 기기마다 다르게 움직이는가?

자이로 입력은 단순히 x, y, z 값을 읽어 카메라에 전달하는 기능이 아닙니다. 다음 네 가지 정의가 모두 맞아야 같은 물리 동작이 같은 게임 동작으로 변환됩니다.

검증 항목의미대표적인 오류
축 방향어느 방향을 양수로 볼지오른쪽 회전이 왼쪽 회전으로 처리됨
축 순서센서의 X·Y·Z가 게임의 어느 축에 대응하는지Yaw와 Roll이 서로 바뀜
좌표계센서·화면·월드 좌표계의 관계화면 방향이나 손잡이 방향에 따라 회전이 달라짐
단위값의 물리적 크기라디안/초를 도/초로 잘못 해석해 감도가 약하거나 과도함

예를 들어 플랫폼 API가 각속도를 rad/s로 제공하는데 게임 코드가 이를 deg/s로 가정하면 스케일 차이는 다음과 같습니다.

ωdeg/s=ωrad/s×180÷πω_{deg/s} = ω_{rad/s} × 180 ÷ π

이 변환을 두 번 적용하면 감도가 약 57.3배 커지고 변환을 빠뜨리면 약 57.3배 작아집니다. 축 반전과 축 교환은 화면을 보며 감으로 고치기 쉽지만 단위 오류는 임계값, 감도, 필터와 섞여 늦게 발견되므로 별도의 수치 검증이 필요합니다.

기기별 센서 매핑 QA를 어떻게 설계할까?

먼저 기기명을 기준으로 테스트하지 말고 입력 경로를 기준으로 분류합니다. 같은 컨트롤러라도 USB, Bluetooth, 운영체제 드라이버, 엔진 백엔드에 따라 값의 부호와 축 배열이 달라질 수 있습니다.

그룹기록해야 할 정보QA 목적
컨트롤러제조사, 모델, 펌웨어하드웨어별 센서 정의 확인
연결 경로USB, Bluetooth, 무선 리시버드라이버별 매핑 차이 확인
플랫폼Windows, Android, iOS, 콘솔운영체제 좌표계와 API 차이 확인
엔진 백엔드Unity Input System, Unreal Enhanced Input 등엔진 어댑터의 재매핑 여부 확인
빌드브랜치, 커밋, 입력 설정 버전패치 전후 회귀 비교
샘플 주기폴링 주기, 프레임 주기, 센서 주기필터와 적분 오차 확인

테스트 로그에는 최소한 다음 값을 함께 남깁니다.

  • 원시 x, y, z
  • 타임스탬프와 샘플 간격
  • 바이어스 보정 후 값
  • 축 교환·반전 이후 값
  • 단위 변환 이후 값
  • 최종 카메라 또는 조준 입력
  • 기기 식별자와 연결 경로

이렇게 계층별 값을 보관하면 최종 화면만 보고 원인을 추측하지 않아도 됩니다. raw는 정상인데 mapped만 틀리면 매핑 문제이고 mapped까지 정상인데 카메라가 과도하게 움직이면 감도나 적분 단계의 문제일 가능성이 큽니다.

축 반전과 축 교환 오류는 어떻게 구분하는가?

축 반전은 같은 축의 부호가 반대로 적용되는 문제입니다. 축 교환은 값 자체는 정상 방향이지만 서로 다른 축에 들어가는 문제입니다.

축 반전 테스트

컨트롤러를 평평하게 고정한 상태에서 한 축만 회전시킵니다. 예를 들어 양의 Yaw를 기준 동작으로 정의했다면 다음 조건을 확인합니다.

  1. 기준 동작을 5회 반복합니다.
  2. 각 반복에서 300~800ms 동안 일정한 방향으로 회전합니다.
  3. 해당 축의 평균값이 예상 부호인지 확인합니다.
  4. 다른 두 축의 평균 절댓값이 허용 오차 이내인지 확인합니다.
  5. 반대 방향 회전에서 부호가 대칭적으로 바뀌는지 확인합니다.

판정 예시는 다음과 같습니다.

동작기대값실패 시 의심 항목
오른쪽 Yawmapped.y > 0Yaw 부호 반전
왼쪽 Yawmapped.y < 0부호 처리 또는 데드존 오류
위쪽 Pitchmapped.x > 0Pitch 부호 반전
아래쪽 Pitchmapped.x < 0화면 좌표계 반전

축 교환 테스트

축 교환은 한 번에 한 축만 자극하는 단축 동작으로 확인하는 것이 가장 명확합니다. raw.x만 크게 변하는 동작을 만들었는데 mapped.y가 변한다면 매핑 행렬 또는 축 이름 정의가 잘못된 것입니다.

권장 테스트 케이스는 다음과 같습니다.

테스트 ID물리 동작원시 입력 조건최종 입력 기대값
GYR-X-01X축 회전abs(raw.x)가 최대게임 X축만 유의미하게 변화
GYR-Y-01Y축 회전abs(raw.y)가 최대게임 Y축만 유의미하게 변화
GYR-Z-01Z축 회전abs(raw.z)가 최대게임 Z축만 유의미하게 변화
GYR-C-01복합 회전두 축 이상 동시 변화각 축이 독립적으로 보존됨

각 축의 교차 누설도 측정합니다.

Leakagei=maxj≠i(∣yj∣)÷∣yi∣Leakage_i = max_{j ≠ i}(|y_j|) ÷ |y_i|

Leakage 값이 기기별 기준을 초과하면 축 교환뿐 아니라 센서 고정 상태, 손떨림, 필터 지연, 컨트롤러의 물리적 축 비직교성도 함께 확인해야 합니다. 실제 하드웨어에서는 완벽한 0이 나오지 않으므로 프로젝트에 맞는 허용 오차를 명시해야 합니다.

단위 변환 오류를 어떻게 검증할까?

단위 테스트와 실기 테스트를 분리합니다. 단위 테스트는 변환 함수가 맞는지 검증하고 실기 테스트는 플랫폼 API가 실제로 어떤 단위를 반환하는지 검증합니다.

변환 함수 단위 테스트

예를 들어 내부 표준을 deg/s로 정했다면 변환 경계를 한 곳으로 제한합니다.

public enum GyroUnit
{
    RadiansPerSecond,
    DegreesPerSecond
}

public static float ToDegreesPerSecond(float value, GyroUnit sourceUnit)
{
    return sourceUnit == GyroUnit.RadiansPerSecond
        ? value * 180.0f / MathF.PI
        : value;
}

테스트 입력에는 대표적인 기준값을 사용합니다.

입력입력 단위기대 출력
0rad/s0 deg/s
πrad/s180 deg/s
-π/2rad/s-90 deg/s
90deg/s90 deg/s

실제 코드에서는 변환 함수가 여러 어댑터에서 중복 호출되지 않는지도 확인해야 합니다. 플랫폼 어댑터에서 이미 도 단위로 바꾼 값을 공통 입력 계층에서 다시 라디안으로 간주하면 정상적인 회전 방향 테스트를 통과하고도 감도 테스트에서 실패할 수 있습니다.

물리 속도 기반 실기 테스트

자이로 값을 시간에 대해 적분해 각도를 계산할 때는 샘플 간격을 반드시 사용합니다.

θt=θt−1+ωt×Δtθ_t = θ_{t-1} + ω_t × Δt

프레임 시간이 변하는 상황에서 Δt를 생략하면 고주사율 기기와 저주사율 기기에서 회전량이 달라집니다. 다음 조건으로 검증합니다.

  1. 동일한 컨트롤러를 서로 다른 프레임 제한에서 실행합니다.
  2. 같은 시간 동안 같은 방향으로 회전합니다.
  3. 최종 적분 각도와 평균 각속도를 각각 비교합니다.
  4. 프레임 제한에 따라 결과가 크게 달라지면 시간 보정 누락을 의심합니다.
  5. 샘플 주기와 렌더 프레임 주기가 다르면 보간 또는 누적 정책을 기록합니다.

센서 매핑 검증 절차를 어떻게 표준화할까?

Step 1. 공통 좌표계와 단위를 문서화한다

게임 내부 표준을 먼저 고정합니다. 예를 들어 다음과 같이 선언할 수 있습니다.

  • 내부 좌표계: 오른손 좌표계
  • Pitch: 게임 X축
  • Yaw: 게임 Y축
  • Roll: 게임 Z축
  • 내부 단위: deg/s
  • 양의 방향: 카메라 기준 오른쪽·위쪽·시계 방향 등 프로젝트 정의에 따름
  • 바이어스 보정: 정지 상태 2초 평균
  • 허용 오차: 축 방향, 스케일, 교차 누설을 각각 별도 정의

중요한 점은 엔진의 Vector3 이름을 물리적 의미와 동일하다고 가정하지 않는 것입니다. Vector3.x가 항상 Pitch를 의미하는 것은 아닙니다.

Step 2. 플랫폼 어댑터에서 원시 입력을 캡처한다

플랫폼별 코드는 다음처럼 공통 인터페이스 뒤에 숨깁니다.

public readonly record struct RawGyroSample(
    double Time,
    float X,
    float Y,
    float Z,
    GyroUnit Unit);

public interface IGyroSource
{
    RawGyroSample Read();
}

어댑터는 축을 임의로 수정하기 전에 원시 축 배열과 단위를 그대로 기록해야 합니다. 그래야 나중에 운영 빌드에서 특정 기기만 매핑이 달라진 이유를 재현할 수 있습니다.

Step 3. 매핑 프로필을 데이터로 분리한다

기기별 예외를 코드의 if 문으로 계속 추가하면 패치 때 누락 가능성이 커집니다. 축 순서와 부호는 프로필로 관리하는 편이 안전합니다.

public readonly record struct AxisMap(int SourceAxis, int Sign);

public readonly record struct GyroMappingProfile(
    AxisMap Pitch,
    AxisMap Yaw,
    AxisMap Roll,
    float UnitScale);

프로필에는 모델명만 저장하지 말고 식별에 사용한 조건도 함께 저장합니다.

필드예시
VendorExampleVendor
Product ID0x1234
ConnectionBluetooth
PlatformAndroid
BackendGamepadBackendA
Firmware range1.2.x
Mapping versiongyro-map-03

Step 4. 기준 동작을 반복 측정하고 자동 판정한다

QA 담당자가 화면을 보며 성공 여부를 누르는 수동 테스트만으로는 축 교환과 단위 오류를 안정적으로 잡기 어렵습니다. 기준 동작별로 입력값을 캡처하고 최소값, 최대값, 평균값, 표준편차를 계산해 자동 판정합니다.

자동 판정 규칙은 다음처럼 구성할 수 있습니다.

  • 예상 축의 신호 대 잡음비가 최소 기준 이상일 것
  • 비예상 축의 교차 누설이 허용 오차 이하일 것
  • 양방향 동작의 평균 크기 비율이 허용 범위 안일 것
  • π rad/s 입력이 180 deg/s로 변환될 것
  • 정지 상태 평균이 바이어스 한계를 넘지 않을 것
  • 샘플 간격 누락으로 프레임 레이트 의존성이 발생하지 않을 것

기기별 테스트 매트릭스는 어떻게 구성하는가?

기기 목록을 늘리는 것보다 위험 조합을 빠짐없이 커버하는 것이 중요합니다. 최소 매트릭스는 다음 축으로 구성합니다.

축권장 값
컨트롤러 모델자사 지원 모델, 대표 서드파티 모델, 신규 인증 모델
연결 방식유선, Bluetooth, 전용 리시버
플랫폼지원 운영체제와 콘솔 타깃
엔진 입력 경로각 플랫폼 백엔드
펌웨어최신 버전, 최소 지원 버전, 변경 이력이 있는 버전
게임 상태메뉴, 일반 플레이, 조준, 일시정지 복귀
성능 조건30·60·120 FPS, 프레임 드롭, CPU 부하

특히 다음 조합은 패치 전후에 반드시 재검증합니다.

  • 신규 컨트롤러 펌웨어와 기존 매핑 프로필
  • 운영체제 업데이트와 입력 API 버전 변경
  • 엔진 버전 업그레이드와 Input System 설정 변경
  • 자이로 감도 옵션과 조준 보정 옵션의 동시 활성화
  • 재연결·절전 복귀 뒤 센서 스트림 재초기화

센서 매핑 QA에서 자주 놓치는 버그는 무엇인가?

정지 상태에서도 값이 계속 누적되는 문제

자이로는 정지 중에도 작은 바이어스와 노이즈가 존재합니다. 이를 그대로 적분하면 카메라가 천천히 회전하는 드리프트가 발생합니다. 초기화 시점에 짧은 정지 구간의 평균을 구해 바이어스로 저장하고 필요하면 저주파 보정이나 재보정 절차를 제공합니다.

축 검증은 통과하지만 조준 감도만 다른 문제

축 방향과 교환이 맞더라도 단위 스케일, 감도 배수, 델타타임 적용 위치가 다르면 기기별 체감 감도가 달라집니다. 테스트 리포트에는 raw → normalized → sensitivity → camera delta 단계를 분리해 기록해야 합니다.

화면 방향 변경 뒤 Pitch가 반전되는 문제

모바일 플랫폼이나 휴대형 기기에서는 화면 회전과 센서 좌표계가 연결될 수 있습니다. 화면 방향을 변경한 뒤 같은 물리 동작을 반복해 매핑이 유지되는지 확인합니다. 화면 좌표계 변환과 게임 월드 좌표계 변환을 한 함수에 섞지 않는 것이 좋습니다.

재연결 뒤 이전 프로필이 남는 문제

컨트롤러가 교체되거나 재연결될 때 장치 식별자가 갱신되지 않으면 이전 기기의 매핑 프로필이 계속 적용될 수 있습니다. 연결 이벤트마다 장치 ID, 연결 방식, 매핑 버전을 로그에 남기고 프로필 재선택을 수행해야 합니다.

실패 로그는 어떤 형식으로 남겨야 하는가?

버그 리포트에는 영상만 첨부하지 말고 다음 정보를 포함합니다.

Test: GYR-Y-01
Device: Example Controller A
Connection: Bluetooth
Platform: Android 15
Backend: GamepadBackendA
Firmware: 1.2.4
Mapping: gyro-map-03
Source unit: rad/s
Raw mean: x=0.01, y=3.14, z=-0.02
Mapped mean: pitch=0.01, yaw=-180.0, roll=-0.02
Expected: yaw=+180.0 deg/s
Result: FAIL - sign inversion
Build: 2026.08.29-rc2

이 형식은 축 반전과 단위 변환 오류를 구분하는 데 필요한 정보를 모두 포함합니다. Raw mean이 3.14인데 Mapped mean이 -180이라면 단위 변환은 정상이고 부호가 문제입니다. 반대로 Mapped mean이 -3.14라면 단위 스케일과 부호를 모두 확인해야 합니다.

릴리스 게이트에는 무엇을 포함해야 하는가?

자이로 매핑 변경이 포함된 빌드는 다음 조건을 만족해야 합니다.

  1. 지원 기기별 단축 축 테스트 통과
  2. 양방향 회전의 부호 테스트 통과
  3. 라디안·도 단위 기준값 테스트 통과
  4. 정지 상태 드리프트 테스트 통과
  5. 30·60·120 FPS 비교 통과
  6. 재연결과 절전 복귀 테스트 통과
  7. 이전에 수정한 기기의 회귀 테스트 통과
  8. 매핑 프로필 버전과 빌드 커밋 기록

매핑 데이터만 변경한 패치라도 입력 동작은 게임 플레이에 직접 영향을 주므로 일반 콘텐츠 변경과 분리해 릴리스 노트에 기록하는 것이 좋습니다.

자주 묻는 질문 (FAQ)

자이로 값이 정상인데 카메라 방향만 반대인 이유는 무엇인가요?

센서 원시값이 정상이어도 게임 좌표계의 양의 방향 정의가 반대일 수 있습니다. 원시값, 매핑 후 값, 카메라 델타를 순서대로 비교해 어느 계층에서 부호가 바뀌는지 확인하세요.

축 교환과 축 반전을 한 번에 고쳐도 되나요?

가능하지만 원인 분석이 어려워집니다. 먼저 단축 동작으로 축 순서를 확정한 뒤 부호를 검증하고 마지막에 단위 스케일을 확인하는 순서를 권장합니다.

모든 컨트롤러에 같은 자이로 감도를 적용해도 되나요?

매핑과 단위가 동일하게 정규화된 뒤라면 공통 감도를 적용할 수 있습니다. 정규화 전 원시값에 공통 감도를 적용하면 센서 범위와 API 단위가 다른 기기에서 감도가 달라집니다.

정리

컨트롤러 자이로 입력 QA의 핵심은 화면 결과가 아니라 데이터 변환 경계를 검증하는 것입니다. 기기별 원시 입력을 캡처하고 축 순서, 부호, 좌표계, 단위를 공통 프로필로 정규화한 뒤 기준 동작과 수치 판정을 자동화하면 센서 매핑 오류를 재현 가능한 테스트 케이스로 관리할 수 있습니다.