Camera IMU Coordinate Frames

Table of contents

  1. Overview
  2. SNAV IMU Position Relative to Robot
  3. SNAV IMU Rotation Relative to Robot
  4. VIO IMU Position and Orientation Relative to Robot

Overview

On VOXL, there are two MPU-9250 IMUs. Designated IMU0 (Primary) and IMU1 (auxiliary). The SNAV parameters listed in this page are relative to IMU0. Their positions on the Voxl-Core board are as follows:

voxl-core-imu-locations

SNAV IMU Position Relative to Robot

In SNAV, the position of the IMU relative to the center of the drone/robot is set in /usr/lib/rfsa/adsp/snav_params.xml Note that this file is probably a simlink to another settings file and that these snav xml settings files often include other xml files.

For example, the base snav install has /usr/lib/rfsa/adsp/snav_params.xml link to /usr/lib/rfsa/adsp/200qc_runtime_params.xml which includes /usr/lib/rfsa/adsp/imu_offset.xml containing:

Position of IMU1 in red VOXL Tray for dragonfly quadcopter as distance from dragonfly center of mass to IMU1 in drone coordinate frame.

<SnavParameters>
  <orientation_params>
    <param name="vehicle_center_to_imu_x" value="0.050"/>
    <param name="vehicle_center_to_imu_y" value="0.0152"/>
    <param name="vehicle_center_to_imu_z" value="-0.023"/>
  </orientation_params>
</SnavParameters>

These distances are in meters along the vehicle coordinate frame which matches the ROS convention with X forward from center, Y to the left from center, and Z up vertically from center. The measurements are to IMU0 not IMU1.

For Voxl-Cam, the IMU1 position is roughly:

<SnavParameters>
  <orientation_params>
    <!-- in VOXLCAM, center is centroid of VOXL PCB. -0.001, -0.344, 0.0155
    is to IMU1 in corner of VOXL by camera ports -->
    <param name="vehicle_center_to_imu_x" value="-0.001"/>
    <param name="vehicle_center_to_imu_y" value="-0.0344"/>
    <param name="vehicle_center_to_imu_z" value="0.0155"/>
  </orientation_params>
</SnavParameters>

SNAV IMU Rotation Relative to Robot

Orientation params also includes the rotation matrix from IMU to body coordinates. By default this is in /usr/lib/rfsa/adsp/eagle.xml which is included by /usr/lib/rfsa/adsp/200qc_runtime_params.xml

Rotation matrix for Voxl-Core in red tray:

<SnavParameters>
  <orientation_params>
    <param name="imu_R00" value="0.0"/>
    <param name="imu_R01" value="1.0"/>
    <param name="imu_R02" value="0.0"/>
    <param name="imu_R10" value="-1.0"/>
    <param name="imu_R11" value="0.0"/>
    <param name="imu_R12" value="0.0"/>
    <param name="imu_R20" value="0.0"/>
    <param name="imu_R21" value="0.0"/>
    <param name="imu_R22" value="1.0"/>

Rotation matrix for Voxl-Cam:

<SnavParameters>
  <orientation_params>
    <param name="imu_R00" value="0.0"/>
    <param name="imu_R01" value="0.0"/>
    <param name="imu_R02" value="-1.0"/>
    <param name="imu_R10" value="0.0"/>
    <param name="imu_R11" value="-1.0"/>
    <param name="imu_R12" value="0.0"/>
    <param name="imu_R20" value="-1.0"/>
    <param name="imu_R21" value="0.0"/>
    <param name="imu_R22" value="0.0"/>

VIO IMU Position and Orientation Relative to Robot

More critically is the position and orientation of the tracking camera relative to the IMU as this must be very accurate for Visual Odometry to function. This is defined in /etc/snav/mount.snav_dft_vio_app.xml Note that these values are in the original coordinate frame of IMU1, not the robot itself.

Translation and rotation between IMU1 and tracking camera for Voxl-Core in Red Tray:

  <SnavMountDownward>
    <!-- mvVISLAM params -->
    <!-- These are for 8096 boards -->

    <!-- Vector from the origin of the IMU1 frame to the origin of the camera
         frame represented in the IMU frame -->
    <param name="mv_vislam_tbc_1" value="0.0152"/>
    <param name="mv_vislam_tbc_2" value="0.0021"/>
    <param name="mv_vislam_tbc_3" value="0.0095"/>

    <!-- Axis-angle representation of the rotation of the camera frame relative
         to the IMU1 frame  -->
    <param name="mv_vislam_ombc_1" value="-2.3561945f"/>
    <param name="mv_vislam_ombc_2" value="0.0f"/>
    <param name="mv_vislam_ombc_3" value="0.0f"/>

IMU1 to tracking camera for Voxl-Cam with right-side-up tracking

  <SnavMountDownward>
    <!-- Vector from the origin of the IMU frame to the origin of the camera
         frame represented in the IMU frame -->
    <param name="mv_vislam_tbc_1" value="0.02715"/>
    <param name="mv_vislam_tbc_2" value="-0.0344"/>
    <param name="mv_vislam_tbc_3" value="0.0088"/>
    <!-- Axis-angle representation of the rotation of the camera frame relative
         to the IMU1 frame  -->
    <param name="mv_vislam_ombc_1" value="1.7599884"/>
    <param name="mv_vislam_ombc_2" value="1.7599884f"/>
    <param name="mv_vislam_ombc_3" value="0.7290111f"/>

IMU1 to tracking camera for Voxl-Cam with upside-down tracking

  <SnavMountDownward>
    <!-- Vector from the origin of the IMU frame to the origin of the camera
         frame represented in the IMU frame -->
    <param name="mv_vislam_tbc_1" value="0.02715"/>
    <param name="mv_vislam_tbc_2" value="-0.0344"/>
    <param name="mv_vislam_tbc_3" value="0.0088"/>

    <!-- Axis-angle representation of the rotation of the camera frame relative
         to the IMU frame  -->
    <param name="mv_vislam_ombc_1" value="-1.7599884"/>
    <param name="mv_vislam_ombc_2" value="1.7599884f"/>
    <param name="mv_vislam_ombc_3" value="-0.7290111f"/>

The translation is straightforward if you reference the IMU’s coordinate frame diagram above and translate from there to the camera. Note that the camera’s coordinate frame also matches ROS and open-cv’s conventions with Z pointing out the optical axis, X to the right, and Y down. The 3 rotation numbers are in axis-angle representation (reference) where the magnitude of the given vector is the rotation in radians.

If you are generating this rotation yourself for a custom application, it may be easiest to construct a rotation matrix or Euler angles and convert with a tool like this: https://www.andre-gaschler.com/rotationconverter