ROS 2 카메라 영상만 받아서는 픽셀을 3D로 바꿀 수 없는 이유: CameraInfo·intrinsics·distortion·optical frame 계약

현재 G1 URDF에는 머리 쪽 카메라를 뜻하는 d435_link가 있습니다. torso_link에 고정 조인트로 연결되어 있고, 로봇 설정에도 d435_rgbd가 센서 목록에 들어 있습니다. 양팔 VLA 데이터 계약을 열어 보면 head_rgb, left_wrist_rgb, right_wrist_rgb라는 세 개의 영상 배열도 요구합니다.

여기까지만 보면 카메라가 보는 물체를 G1 좌표계로 옮길 준비가 된 것처럼 보입니다. 하지만 픽셀 (u, v) 하나를 집어서 “물체가 pelvis 기준으로 이 위치에 있다”고 말하려는 순간 정보가 끊깁니다. 현재 계약에는 초점거리와 주점, 렌즈 왜곡, raw·rectified 구분, optical frame, 보정 해상도와 버전이 없습니다. RGB 배열은 색을 보존하지만 그 픽셀이 공간의 어느 방향을 보는지는 보존하지 않습니다.

앞선 글에서 여러 센서 메시지를 같은 관측으로 묶는 시간 계약과, 측정 시각의 좌표 변환을 찾는 tf2 계약을 정리했습니다. 이번 글은 그 사이에 남은 카메라 기하를 다룹니다. 핵심 질문은 간단합니다. 영상의 한 점이 3D 광선이 되고, 깊이와 결합해 로봇 좌표의 점이 되기까지 어떤 증거가 필요할까요?

raw 픽셀이 CameraInfo의 왜곡·내부 파라미터와 rectification을 거쳐 optical frame의 광선이 되고, 깊이와 영상 취득 시각의 tf2 변환을 결합해 G1 pelvis 좌표의 3D 점이 되는 과정
픽셀은 3D 점이 아닙니다. CameraInfo가 방향을, 유효한 깊이가 거리를, 영상 취득 시각의 tf2가 로봇 좌표계에서의 위치를 결정합니다.

현재 저장소가 증명하는 것은 카메라 마운트와 RGB 그릇까지입니다

g1_29dof.urdfd435_jointtorso_link에서 d435_link로 가는 고정 변환을 정의합니다. 자산 안에서 카메라가 몸통 어디에 달리는지를 나타내는 nominal mount입니다. g1_bimanual_vla_v0 schema는 세 RGB stream을 (T, H, W, 3)uint8 배열로 저장하도록 정합니다. 변환기는 이 배열을 head·left wrist·right wrist image field로 옮깁니다.

반면 저장소에서 runtime sensor_msgs/msg/CameraInfo publisher, image_geometry::PinholeCameraModel, camera calibration YAML, calibration hash, camera_optical_frame은 찾지 못했습니다. 검증 스크립트의 84×84 영상도 실제 D435 출력 해상도를 측정한 값이 아니라 CPU-only schema fixture입니다. 따라서 현재 방어 가능한 문장은 “G1 자산에 카메라 마운트와 RGB 데이터 자리가 있다”까지입니다. “보정된 카메라로 3D 위치를 계산했다”는 문장은 아직 근거가 없습니다.

항목 현재 근거 아직 없는 증거
카메라 장착 위치 URDF의 torso_link → d435_link fixed joint 실물 장착 오차를 반영한 extrinsic calibration과 optical frame 검증
영상 데이터 자리 head·left wrist·right wrist RGB 배열과 converter 각 영상의 source stamp, frame ID, raw·rectified 상태
내부 보정 구현 근거 없음 K/D/R/P, distortion model, calibration resolution·ROI·binning
3D 투영 구현 근거 없음 pixel→ray, valid depth, optical→pelvis transform의 round-trip 시험

픽셀 좌표는 배열의 주소이지 공간의 방향이 아닙니다

영상에서 (u, v)는 왼쪽 위를 원점으로 하는 열과 행의 위치입니다. 이것만으로 알 수 있는 것은 “이 색이 배열의 어디에 저장되었는가”뿐입니다. 같은 640×480 영상이라도 렌즈의 화각이 다르면 동일한 (500, 240) 픽셀이 가리키는 방향은 달라집니다. 영상을 crop하거나 resize해도 픽셀 번호와 광선의 관계가 바뀝니다.

이 관계를 가장 단순하게 표현하는 것이 pinhole camera model입니다. rectified 이미지에서 초점거리를 f_x, f_y, 주점을 c_x, c_y라고 하면 픽셀은 대략 다음 방향의 광선으로 바뀝니다.

x = (u - cx) / fx
y = (v - cy) / fy
ray_camera = [x, y, 1]

여기서 f_x가 클수록 같은 픽셀 이동이 더 작은 각도 변화를 뜻합니다. c_x, c_y는 광축이 영상 평면과 만나는 주점입니다. 그래서 해상도만 같다고 같은 camera model이 되지 않습니다. 픽셀을 ray로 만드는 데 필요한 네 값과, 그 값이 어느 처리 단계의 영상에 적용되는지를 함께 알아야 합니다.

K는 raw 이미지의 내부 파라미터입니다

ROS 2의 공식 CameraInfo 메시지 정의K를 raw, 즉 왜곡이 남아 있는 이미지의 3×3 intrinsic matrix로 정의합니다.

K = [ fx  0  cx
       0  fy  cy
       0   0   1 ]

K는 카메라가 로봇 어디에 달렸는지를 말하지 않습니다. 카메라 내부에서 3D 방향과 raw pixel이 어떻게 대응하는지만 말합니다. 반대로 URDF의 fixed joint는 카메라 링크와 torso 사이의 외부 변환을 말할 뿐, f_xc_x를 알려 주지 않습니다. 둘 중 하나만 있어서는 pixel을 robot-frame point로 만들 수 없습니다.

D는 숫자 배열이 아니라 distortion model과 한 쌍입니다

실제 렌즈에서는 영상 가장자리의 직선이 휘고, 이상적인 pinhole projection과 raw pixel 사이에 차이가 생깁니다. CameraInfo는 이 차이를 distortion_model 문자열과 D 계수 배열로 표현합니다. 예를 들어 메시지 정의가 설명하는 plumb_bob 모델은 (k1, k2, t1, t2, k3) 순서를 사용합니다.

문제는 계수 다섯 개만 저장해서는 해석이 완성되지 않는다는 점입니다. 다른 distortion model에서는 계수의 수와 의미가 달라질 수 있습니다. 모델 이름이 없거나 순서를 잘못 읽으면 보정 코드는 실행되면서도 픽셀을 틀린 방향으로 밉니다. 중앙에서는 오차가 작아 보여도 영상 가장자리에서 크게 벌어질 수 있으므로, 임의의 중심점 한 개로 보정 성공을 판단해서도 안 됩니다.

R과 P는 rectified 이미지의 좌표계를 만듭니다

R은 stereo camera의 두 영상 평면을 정렬하기 위한 rectification rotation이고, P는 처리된 rectified image에 3D 점을 투영하는 3×4 projection matrix입니다. P의 왼쪽 3×3에는 rectified 영상용 f'_x, f'_y, c'_x, c'_y가 들어가며, stereo의 두 번째 카메라는 네 번째 열에 baseline과 관련된 항을 가질 수 있습니다.

여기서 흔한 실수는 raw pixel에 rectified P를 쓰거나, rectified pixel에 raw K를 바로 쓰는 것입니다. 두 조합 모두 숫자 shape는 맞아서 오류가 나지 않습니다. 대신 물체가 영상 중심에서 멀어질수록 조용히 틀린 광선을 만듭니다. 입력 topic이 image_raw인지 image_rect_color인지, detection 좌표가 어느 영상에서 나왔는지를 observation과 함께 보존해야 하는 이유입니다.

입력 영상 필요한 처리 투영에 쓰는 기준 피해야 할 조합
raw/distorted D + K로 undistort 또는 rectify rectified pixel로 바꾼 뒤 camera model 사용 raw pixel을 곧바로 P에 넣기
rectified mono 이미 보정된 pixel인지 provenance 확인 P 기반 projectPixelTo3dRay() 같은 pixel에 distortion을 다시 적용하기
rectified stereo 좌·우 CameraInfo와 baseline semantics 확인 각 카메라의 P, disparity/depth 계약 왼쪽 P를 오른쪽 영상에 재사용하기

image_geometry를 쓰는 이유는 행렬 곱을 감추기 위해서만이 아닙니다

ROS의 image_geometry::PinholeCameraModelfromCameraInfo()로 모델을 만들고, rectifyPoint(), projectPixelTo3dRay(), project3dToPixel() 같은 연산을 제공합니다. 중요한 점은 이 API가 raw와 rectified 좌표를 함수 이름에서 구분하고, 최신 CameraInfo의 binning과 ROI가 반영된 현재 K/P도 관리한다는 것입니다.

직접 (u-cx)/fx를 계산하는 식은 synthetic pinhole test와 원리 설명에는 유용합니다. 그러나 runtime에서 distortion, ROI, stereo projection이 들어오면 손으로 만든 일부 수식이 메시지 semantics와 어긋나기 쉽습니다. 따라서 구현은 공식 camera model을 사용하고, 별도의 시험에서는 알려진 3D 점을 project3dToPixel()로 투영한 뒤 다시 ray로 복원하는 round-trip을 두는 편이 낫습니다.

광선만으로는 거리를 알 수 없습니다

RGB 영상의 한 픽셀과 CameraInfo를 결합하면 optical frame에서의 방향은 얻을 수 있습니다. 하지만 그 방향 위 어디에 물체가 있는지는 알 수 없습니다. [x, y, 1][2x, 2y, 2]는 같은 픽셀로 투영되기 때문입니다. metric 3D point를 만들려면 depth, stereo disparity, 알려진 평면과의 교차, object geometry 같은 추가 제약이 필요합니다.

정렬된 depth에서 optical-axis depth Z가 유효하다고 가정하면 rectified pixel은 다음 점으로 확장할 수 있습니다.

X = (u - cx) * Z / fx
Y = (v - cy) * Z / fy
point_optical = [X, Y, Z]

하지만 여기에도 계약이 붙습니다. depth의 단위가 meter인지 millimeter인지, 0·NaN·Inf가 어떤 invalid 값을 뜻하는지, depth image가 color image에 registered되어 있는지 확인해야 합니다. RGB pixel에 다른 optical frame의 depth를 같은 index로 붙이면 선명한 영상과 정상적인 depth 값으로도 틀린 3D 점이 나옵니다.

해상도·resize·crop은 보정값의 의미를 바꿉니다

카메라 보정은 특정 sensor resolution에서 수행됩니다. 공식 CameraInfowidthheight는 보정에 사용한 해상도를 나타내며, binning과 ROI는 실제로 캡처한 영역을 나타냅니다. 같은 보정 파일을 불러왔더라도 runtime 영상의 해상도와 crop이 다르면 현재 pixel과 원래 K의 대응이 달라집니다.

예를 들어 640×480 영상을 가로와 세로 모두 절반으로 resize했다면 이상적인 단순 scale에서는 f_x, f_y, c_x, c_y도 절반 scale에 맞춰야 합니다. 중앙 320×320을 crop했다면 주점은 crop origin만큼 이동합니다. aspect ratio를 바꾸어 찌그러뜨리면 x와 y scale도 달라집니다. detector나 VLA 입력을 위해 만든 84×84 배열에 원본 CameraInfo를 그대로 붙일 수 없는 이유입니다.

영상 연산 기하에 생기는 변화 보존해야 할 정보
균일 resize focal length와 principal point가 같은 비율로 scale 원본·출력 크기와 scale
비균일 resize x·y 축의 scale이 달라짐 s_x, s_y와 변환된 intrinsics
crop / ROI 출력 원점과 principal point가 이동 full-resolution 좌표의 ROI origin·size
binning 여러 sensor pixel이 한 output pixel이 됨 binning_x/y
letterbox scale 뒤 padding offset이 추가됨 scale·padding·model input 좌표와 sensor 좌표의 역변환

Image와 CameraInfo는 같은 영상 취득 사건을 가리켜야 합니다

공식 Image 메시지 정의는 header timestamp를 영상 취득 시각으로, frame ID를 카메라 optical frame으로 두라고 명시합니다. 연결된 CameraInfo의 frame ID와 충돌하면 동작은 undefined입니다. 즉 topic 이름이 같은 namespace에 있다는 사실만으로 짝이 완성되지 않습니다.

실제 observation에는 Image와 CameraInfo의 source stamp, frame ID, resolution, calibration identity를 함께 묶어야 합니다. CameraInfo가 보정 이후 고정값처럼 반복 발행되더라도 어느 calibration epoch를 적용했는지 추적해야 합니다. self-calibration이나 resolution 변경으로 모델이 바뀌는 순간, 이전 이미지와 새 CameraInfo가 잠깐 섞일 수 있기 때문입니다.

앞서 다룬 message_filters는 image·depth·robot state처럼 서로 다른 stream의 stamp를 어떤 정책으로 묶을지 소유합니다. 이번 카메라 계약은 그 묶음 안의 image와 CameraInfo가 같은 기하를 공유하는지 검사합니다. 둘은 같은 문제가 아닙니다.

optical frame은 일반 body frame과 축 방향이 다릅니다

REP 103의 일반 body frame은 x forward, y left, z up입니다. 카메라의 _optical suffix frame은 z forward, x right, y down을 사용합니다. 영상의 오른쪽으로 갈수록 x가 증가하고 아래로 갈수록 y가 증가하는 pixel convention과 맞추기 위한 축입니다.

따라서 URDF에 d435_link가 있다는 사실만으로 그 링크를 CameraInfo의 frame ID로 사용해도 된다고 결론낼 수 없습니다. d435_link가 일반 body convention을 따르는지, 이미 optical convention인지, 별도의 d435_color_optical_frame이 필요한지를 자산과 runtime TF에서 확인해야 합니다. 축을 한 번 잘못 잡으면 바닥의 물체가 몸통 위쪽이나 뒤쪽으로 투영되는 부호 오류가 생깁니다.

intrinsic과 extrinsic은 서로 대체할 수 없습니다

intrinsic calibration은 pixel과 optical-frame ray의 관계를 정합니다. extrinsic calibration은 optical frame과 torso·pelvis 같은 robot frame의 관계를 정합니다. URDF fixed joint는 후자의 nominal prior가 될 수 있지만 전자의 대체물이 아닙니다. 반대로 완벽한 CameraInfo가 있어도 카메라가 몸에 어떻게 달렸는지 모르면 ray를 pelvis 좌표로 옮길 수 없습니다.

실물에서는 CAD·URDF의 장착 위치와 실제 브래킷 조립 오차가 다를 수 있습니다. 그래서 provenance에 “URDF nominal”인지 “hand–eye calibration 결과”인지 authority를 남겨야 합니다. simulation에서도 sensor prim의 실제 pose와 URDF joint가 같은지 확인하지 않으면, 자산 파일의 숫자만 맞고 렌더링 카메라는 다른 위치에 있을 수 있습니다.

마지막 변환은 영상 취득 시각의 tf2로 해야 합니다

깊이를 결합해 point_optical을 만들었다면 다음 단계는 optical frame에서 pelvis 또는 world frame으로 옮기는 일입니다. G1이 움직이는 동안 카메라 pose도 변하므로 callback이 실행된 현재 시각의 transform이 아니라 영상이 취득된 stamp의 transform을 조회해야 합니다.

point_pelvis(t_image)
  = T_pelvis_optical(t_image) * point_optical

이 부분은 앞선 tf2 글의 책임입니다. 현재 글에서 강조할 경계는 CameraInfo가 optical-frame 내부 기하를, tf2가 frame 사이의 외부 기하와 시간 이력을 소유한다는 점입니다. CameraInfo에 torso pose를 억지로 넣거나, TF만 보고 intrinsic을 추정하는 식으로 두 계층을 섞지 않습니다.

보정 파일에는 값뿐 아니라 identity가 필요합니다

ROS 2의 camera_info_manager는 CameraInfo를 저장·복원하고, camera name과 URL로 보정 데이터를 관리합니다. 문서도 해상도·focus·zoom처럼 보정에 영향을 주는 조건을 camera name에 포함해 파일을 구분할 수 있다고 설명합니다.

프로젝트에서는 URL만 기록하는 것으로 부족합니다. 파일 내용이 교체될 수 있기 때문입니다. 최소한 camera serial 또는 simulation sensor ID, stream profile, calibration file hash, calibration timestamp, distortion model, optical frame, source revision을 immutable bundle로 묶어야 합니다. runtime observation에는 이 bundle의 calibration_id를 붙이고, post-processing이나 dataset converter가 바뀌어도 어느 기하를 썼는지 역추적할 수 있어야 합니다.

제가 추가하려는 CalibratedImageObservation 계약

현재 RGB 배열을 바로 VLA 입력으로 넘기는 대신, projection이 필요한 경로에는 다음과 같은 envelope를 두는 편이 안전합니다. 실제 메시지 타입을 확정한 것이 아니라, 구현 전 누락 필드를 드러내기 위한 초안입니다.

CalibratedImageObservation {
  image: {
    source_stamp, clock_id, frame_id,
    width, height, encoding,
    processing: raw | rectified,
    resize_crop_letterbox_transform
  },
  camera_info: {
    stamp, frame_id, width, height,
    distortion_model, D, K, R, P,
    binning_x, binning_y, roi
  },
  calibration: {
    calibration_id, file_hash, sensor_id,
    stream_profile, authority
  },
  depth: {
    optional, stamp, frame_id, unit,
    registered_to, invalid_value_policy
  }
}

여기서 processing과 resize/crop transform은 CameraInfo만으로 알 수 없는 model-input 전처리를 기록합니다. authority는 synthetic nominal, factory calibration, measured calibration처럼 근거 수준을 구분합니다. depth는 RGB와 다른 센서일 수 있으므로 독립 stamp와 frame, registration 대상을 가집니다.

projection callback은 계산보다 먼저 거절 조건을 검사해야 합니다

현재 가장 위험한 구현은 값이 없을 때 대충 identity나 중심 주점을 채우고 계속 계산하는 방식입니다. 결과가 NaN이 아니라 그럴듯한 3D 숫자로 나오기 때문입니다. ROS 메시지 정의는 보정되지 않은 카메라에서 K[0] == 0.0을 uncalibrated 표시로 간주할 수 있다고 명시합니다. 이 경우 projection 경로는 명시적으로 실패해야 합니다.

검사 실패 거절 이유 남길 evidence
K[0] == 0 또는 model 미초기화 보정되지 않은 카메라 camera name·URL·calibration ID
Image와 CameraInfo frame 불일치 공식 semantics가 undefined 두 frame ID와 source stamp
해상도·ROI·전처리 불일치 pixel과 intrinsics의 좌표가 다름 원본·출력 크기, crop·scale·padding
raw/rectified 상태 불명 K/DP 중 선택 불가 입력 topic·processing provenance
distortion model/계수 불일치 undistortion 의미 불명 model 이름과 D 길이
depth invalid 또는 registration 불명 광선을 metric point로 만들 수 없음 depth 값·단위·frame·registered target
tf2 lookup 실패 robot frame으로 옮길 수 없음 source·target frame, image stamp, 오류 종류
calibration epoch 변경 한 observation에 서로 다른 기하 혼합 가능 old/new calibration ID와 경계 stamp

첫 시험은 실제 D435가 아니라 synthetic pinhole camera로 합니다

아직 실제 D435 보정값과 runtime publisher가 없으므로 임의의 숫자를 만들어 “카메라 검증 완료”라고 쓰지 않습니다. 첫 시험은 authority 0인 synthetic pinhole camera와 알려진 3D points로 구성합니다. 렌즈 왜곡이 없는 단순 조건에서 시작해야 수식·축·timestamp 오류를 분리할 수 있습니다.

  1. 정답점을 만듭니다. optical frame의 중심·좌우·상하·영상 가장자리에 대응하는 3D 점을 고정합니다.
  2. project→unproject round-trip을 검사합니다. 3D 점을 pixel로 투영하고 같은 depth로 복원해 허용 오차 안에 들어오는지 봅니다.
  3. raw와 rectified 경로를 분리합니다. synthetic distortion을 넣고 rectify 전후 pixel을 일부러 바꾸어 사용했을 때 gate가 잡는지 확인합니다.
  4. resolution·crop·letterbox fault를 주입합니다. intrinsics를 갱신하지 않은 결과가 통과하지 못하게 합니다.
  5. optical 축 오류를 넣습니다. x-forward body frame을 optical frame으로 가장했을 때 sign·axis assertion이 실패해야 합니다.
  6. CameraInfo를 바꿉니다. 잘못된 K, 다른 distortion model, frame mismatch, calibration epoch 변경을 각각 독립 case로 만듭니다.
  7. tf2 시각을 바꿉니다. 움직이는 torso에서 image stamp 대신 latest transform을 사용하면 정답과 달라지는지 측정합니다.

이 시험에서 “성공”은 화면상 점이 대략 맞아 보이는 것이 아닙니다. 3D round-trip 오차, pixel reprojection 오차, frame과 calibration identity, reject reason이 artifact로 남는 것입니다. synthetic 조건을 통과한 뒤 Isaac Sim camera prim과 ground-truth point를 연결하고, 마지막에 실물 checkerboard·hand–eye calibration으로 authority를 올립니다.

현재 상태를 증거 수준으로 나누면

상태 현재 근거 아직 말할 수 없는 것
Designed pixel→ray→depth point→measurement-time tf2라는 계약과 fail-closed gate를 정의했습니다. runtime 메시지 구조가 확정됐다고 말할 수 없습니다.
Implemented G1 URDF의 nominal d435_link mount와 RGB HDF5 schema·converter가 있습니다. CameraInfo publisher, optical TF, PinholeCameraModel projection은 없습니다.
Executed 84×84 zero image를 쓰는 CPU-only contract fixture가 있습니다. 실제 D435나 Isaac Sim camera geometry를 실행한 증거가 아닙니다.
Observed 카메라 calibration·projection의 runtime 관측 기록이 없습니다. pixel·depth·robot-frame 오차를 수치로 말할 수 없습니다.
Accepted synthetic round-trip 또는 Isaac ground-truth acceptance 기록이 없습니다. 보정과 투영 경로가 승인됐다고 말할 수 없습니다.
Deployed projection 결과가 actuator authority를 가진 task에 연결되지 않았습니다. G1이 영상의 물체 위치를 사용한다고 말할 수 없습니다.

구현 순서는 CameraInfo publisher보다 소비자 gate부터입니다

다음 구현을 큰 camera node 하나로 시작하면 어떤 누락값을 임시 default로 채웠는지 놓치기 쉽습니다. 먼저 projection 소비자가 요구하는 입력과 거절 조건을 test로 고정하고, producer를 그 계약에 맞추는 순서가 낫습니다.

  1. CalibratedImageObservation의 최소 schema와 calibration ID 계산 규칙을 정합니다.
  2. synthetic CameraInfo fixture와 project→unproject fault suite를 만듭니다.
  3. G1 자산에 일반 camera link와 _optical frame의 축 변환을 명시하고 TF tree를 검사합니다.
  4. Isaac Sim camera의 실제 render resolution·aperture·pose에서 CameraInfo를 생성하는 adapter를 붙입니다.
  5. Image·CameraInfo·depth·robot state를 source stamp 기준으로 묶고 calibration epoch 혼합을 막습니다.
  6. ground-truth 3D marker로 optical·pelvis frame reprojection 오차를 측정합니다.
  7. 그 뒤에 실제 D435 stream profile별 보정 파일과 hand–eye extrinsic을 별도 authority로 등록합니다.

영상이 보인다는 것과 공간을 측정했다는 것은 다릅니다

카메라 화면이 RViz나 Isaac Sim viewport에 정상적으로 보인다고 해서 pixel의 3D 의미가 검증된 것은 아닙니다. RGB 배열은 색과 배열 순서를 담고, CameraInfo는 내부 기하를 담고, depth는 거리를 제공하며, tf2는 측정 시각의 외부 변환을 제공합니다. 어느 하나라도 빠지면 계산은 완성되지 않습니다.

현재 프로젝트에는 G1의 nominal 카메라 mount와 세 RGB stream을 담을 데이터 그릇이 있습니다. 그러나 runtime CameraInfo, optical frame, calibration identity, raw·rectified provenance와 pixel-to-3D 시험은 아직 없습니다. 이 공백을 숨기지 않는 것이 오히려 다음 구현을 짧게 만듭니다.

그래서 바로 다음 목표는 실제 물체 인식을 붙이는 일이 아닙니다. synthetic pinhole camera에서 몇 개의 알려진 3D 점을 투영하고 다시 복원한 뒤, 해상도·왜곡·frame·timestamp를 일부러 틀렸을 때 모두 명시적인 이유로 거절되는지 확인하는 일입니다. 그 작은 gate를 통과해야 비로소 화면 속 한 픽셀이 G1이 사용할 수 있는 공간의 점이 됩니다.


함께 읽기: 로봇 episode의 이미지와 action을 같은 시간축에 묶는 법 · G1 tick과 ROS time을 직접 비교하면 안 되는 이유 · tf2에서 measurement-time transform을 찾는 법 · message_filters의 exact·approximate sync 계약

댓글 달기

이메일 주소는 공개되지 않습니다. 필수 필드는 *로 표시됩니다

위로 스크롤