21.6.4.1 오도메트리(Odom) 토픽 기반 픽셀(Pixel) 스케일링 변환 연산 방정식

21.6.4.1 오도메트리(Odom) 토픽 기반 픽셀(Pixel) 스케일링 변환 연산 방정식

Zenoh 망을 타고 무사히 클라이언트를 강타한 로봇 스웜들의 데이터 트래픽이 Zustand 를 거쳐 DOM 메모리 안착까지 안정을 찾았다 (21.6.1장 ~ 21.6.3장).
이제 마지막 관문이다. 백엔드에서 날아온 데이터는 “로봇이 공장 중심점 기준 X: 45.2m, Y: -12.4m 지점에 위치함” 이라는 물리적 미터(Meter) 단위 좌표계다.
그러나 관제탑 화면을 띄운 대형 모니터 안의 세상은 “모니터 좌측 상단 모서리를 기준으로 우측으로 800px, 아래로 400px” 인 차가운 브라우저 픽셀(Pixel) 좌표계로 작동한다.

이 이질적인 두 우주(현실 좌표계와 화면 좌표계)를 억지로 욱여넣으려다 로봇의 움직임이 왜곡되거나 모니터 밖으로 튕겨 나가는 참사를 막기 위해, 시스템 아키텍트는 철저한 비례식의 철퇴를 갈겨야 한다.
본 절에서는 무한한 현실 공장의 평면을 정해진 CSS 해상도 크기 안으로 단 한 치의 오차도 없이 욱여넣고 정렬시키는 오도메트리(Odometry) 스케일링 변환 방정식 런북을 갈파한다.

1. 좌표 역전의 함정: Y축 하강(Downwards)의 저주

개발자들을 가장 먼저 미치게 하는 것은 현실 세계 수학과 브라우저 DOM 렌더링 엔진의 Y축 관점 차이다.

  • 로보틱스 오도메트리 공간: 직교 좌표계(Cartesian). 원점(0,0)에서 Y축의 +값이 위로 상승한다 (North = +Y).
  • 브라우저 스크린 공간: 좌상단이 원점(0,0). Y축의 +값이 아래쪽으로 하강한다 (South = +Y).

로봇이 현실에서 앞으로 전진(+Y)하고 있다고 해서 좌표를 브라우저에 그대로 top: 45px 꽂아 넣으면 화면 속 로봇 아이콘은 바닥을 향해 거꾸로 질주(후진)하는 기괴한 백워드 파동을 일으킨다.
모든 렌더링 직전엔 Y축 역전(Inversion) 수술이 선행되어야 한다.

2. 바운딩 박스(Bounding Box)와 리니어 스케일(Linear Scale) 락온

공장의 크기가 가로 100m, 세로 50m (Bounding Box)라 치자.
그리고 관리자의 프론트엔드 모니터 맵 영역은 가로 1000px, 세로 500px (Map Viewport) 이다.

아키텍트는 백엔드에서 좌표(odom)가 하나 들어올 때마다 이를 픽셀 돔의 점(Position px)으로 치환하는 무자비한 비율(Scale) 클램프 공식을 React 컴포넌트 한가운데 박아넣는다.

// [절대 불변의 현실-모니터 우주 변환 방정식 런북]

// 1. 공장 현실의 극단 크기 (Domain)
const FACTORY_MIN_X = -50; // 미터(m)
const FACTORY_MAX_X = 50;
const FACTORY_MIN_Y = -25; 
const FACTORY_MAX_Y = 25;

// 2. 화면의 극단 크기 (Range)
const MAP_WIDTH_PX = 1000;
const MAP_HEIGHT_PX = 500;

function odomToPixel(odomX, odomY) {
    // 3. X축 비례 스케일링 (현실 미터를 비율(0~1)로 바꾸고 픽셀을 곱해 투영한다)
    const scaleX = (odomX - FACTORY_MIN_X) / (FACTORY_MAX_X - FACTORY_MIN_X);
    const pixelX = scaleX * MAP_WIDTH_PX;
    
    // 4. [치명주의!] Y축 비례 스케일링 및 축 역전 타격!
    const scaleY = (odomY - FACTORY_MIN_Y) / (FACTORY_MAX_Y - FACTORY_MIN_Y);
    // 도출된 비율(scaleY)을 위에서부터 내려찍는 게 아니라 바닥에서 빼버려서(1 - scale) 위아래를 뒤집어버린다!
    const pixelY = (1 - scaleY) * MAP_HEIGHT_PX;
    
    return { x: pixelX, y: pixelY };
}

3. 중앙 정렬의 통치력 (Center Offset Origin)

만일 로봇 오도메트리의 (0,0) 기준점이 공장의 한가운데(Center)라면 어떻게 해야 하는가?
위 방정식에 입각하여 odomX=0, odomY=0 을 찔러 넣었을 때, 픽셀의 값은 정확하게 화면의 한가운데 픽셀인 (500px, 250px) 로 수학적으로 완전하게 도출(Offset Origin Mapping)되어야 한다.

이렇게 클라이언트의 뷰 컴포넌트에 DOM Translation Layer (변환 렌즈) 를 철퇴로 내리꽂음으로써,
백엔드의 로봇들(C++ ROS 데몬)은 자신이 화면 안에 어떻게 그려질지 따위의 쓰레기 같은 디자인 고민(Pixel Math)을 단 1% 도 하지 않은 채 순수한 “미터 계(Meter)” 만을 Zenoh 에 뿜어댈 수 있다.
물리 세계의 본질적 좌표만을 이송시키고, 관찰자(Browser) 단에 이르러서야 오도메트리 렌즈를 달아 스크린의 감각계로 꺾어 쏴버리는 투영 분리술. 데이터 계층과 뷰(View) 계층의 완벽한 디커플링(Decoupling)을 증명하는 프론트엔드 연산 철학의 집대성이다.