Skip to content

Pose Engine output

Pose Engine generates output that can be trusted. Pose Engine does not generate an output when in an unknown state or if a solution can not be accurately determined.

Offline Pose Engine output

Offline pose results (from the remote service or on-prem Docker) can be delivered in an arbitrary format: CSV, standard ROS messages or custom messages in a ROS 1 bag or ROS 2 bag, or some other custom format.

Local map pose

World-from-body rigid transform in the local map frame, plus body-frame velocities.

Fields:

Field Description
time_s Time of validity (seconds)
px_m, py_m, pz_m Position in local map frame (meters)
rx_rad, ry_rad, rz_rad Rotation as so(3) logarithm, see Rotation convention
vx_mps, vy_mps, vz_mps Body-frame linear velocity: +X forward, +Y left, +Z up (m/s)
wx_rps, wy_rps, wz_rps Body-frame angular velocity: roll, pitch, yaw rate (rad/s)

Example CSV:

# world-from-body rigid transform, body-frame velocities
# world frame: local map origin (set at Platform Setup)
# <customer>_<log-id>_<sensor-cf>.local.csv
time_s,               px_m,      py_m,       pz_m,     rx_rad,       ry_rad,       rz_rad,       vx_mps,   vy_mps,    vz_mps,   wx_rps,    wy_rps,    wz_rps
1776371688.261120081, -0.991453, -13.979609, 0.898994, -0.013059700, -0.004910992, -0.945530403, 0.007306, -0.004017, 0.001259, -0.000613, -0.000246, 0.001082

Example ROS2 nav_msgs/Odometry message:

header:
  stamp:
    sec: 1776371688
    nanosec: 261120081
  frame_id: "local_map"
child_frame_id: "base_link"  # matches <sensor-cf>
pose:
  pose:
    position:
      x: -0.991453
      y: -13.979609
      z:  0.898994
    orientation:
      x:  0.000000   # quaternion from rotvec [-0.013059700, -0.004910992, -0.945530403]
      y: -0.006530
      z: -0.471857
      w:  0.881679
  covariance: [...]  
twist:
  twist:
    linear:
      x:  0.007306
      y: -0.004017
      z:  0.001259
    angular:
      x: -0.000613
      y: -0.000246
      z:  0.001082
  covariance: [...]

ECEF pose

World-from-body rigid transform in the ECEF frame. Only generated when GNSS/INS data was present during mapping or is present in the input data.

Fields:

Field Description
time_s Time of validity (seconds)
px_m, py_m, pz_m Position in ECEF frame (meters)
rx_rad, ry_rad, rz_rad Rotation as so(3) logarithm, see Rotation convention

Example CSV:

# world-from-body rigid transform
# world frame: ECEF (only available if GNSS data is provided)
# <customer>_<log-id>_<sensor-cf>.ecef.csv
time_s,               px_m,         py_m,         pz_m,        rx_rad,      ry_rad,      rz_rad
1776371688.261120081, -2687738.311, -4291128.930, 3865469.473, 0.968923418, 0.190917898, -1.392946097

Example ROS2 geometry_msgs/PoseWithCovarianceStamped message:

header:
  stamp:
    sec: 1776371688
    nanosec: 261120081
  frame_id: "ecef"
pose:
  pose:
    position:
      x: -2687738.311
      y: -4291128.930
      z:  3865469.473
    orientation:
      x:  0.435439   # quaternion from rotvec [0.968923418, 0.190917898, -1.392946097]
      y:  0.085769
      z: -0.626385
      w:  0.639310
  covariance: [...]  # 6x6 row-major [x, y, z, rx, ry, rz]

Output format

Delivery format depends on your integration:

  • CSV: typically used for initial evaluation and offline analysis
  • ROS messages: standard nav_msgs/Odometry or custom message types, recorded to a ROS 1 bag or ROS 2 bag
  • Custom formats: output can be serialized to match non-ROS pub/sub architectures or proprietary APIs on request

The CSV examples above use flat column naming that maps directly to the equivalent message fields regardless of delivery format.

Rotation convention

Rotation is stored as the so(3) logarithm (axis-angle vector form). The norm of [rx, ry, rz] is the rotation angle in radians; the unit vector is the rotation axis. Other rotation formats are available upon request.

To recover the rotation matrix from the axis-angle vector:

import numpy as np

def rodrigues(w):
    t = np.linalg.norm(w)
    if t < 1e-9:
        return np.eye(3)
    skew = np.array([[    0, -w[2],  w[1]],
                     [ w[2],     0, -w[0]],
                     [-w[1],  w[0],     0]])
    return np.eye(3) + np.sin(t)/t*skew + (1-np.cos(t))/t**2 * skew@skew

# Equivalent library calls:
#   scipy.spatial.transform.Rotation.from_rotvec(w).as_matrix()
#   kornia.geometry.conversions.angle_axis_to_rotation_matrix(w)
#   pypose.mat_from_rotvec(w)

Applying the rigid transform

To transform a point from the sensor (body) frame to the world frame:

# w = [rx_rad, ry_rad, rz_rad] from a CSV row
# p = [px_m, py_m, pz_m] from a CSV row
R = rodrigues(w)
xyz_world = R @ xyz_body + p

Acausal and causal offline outputs

The remote service and on-prem Docker both support two output modes:

  • Acausal: Pose Engine has access to the full data record. Outputs are at arbitrary timestamps and in an arbitrary coordinate frame. No odometry is generated.
  • Causal (online emulation): Outputs are generated as if Pose Engine were running online, in an arbitrary coordinate frame. Includes odometric pose output.

Online Pose Engine output

Online pose results are standard ROS messages or other message type managed by non-ROS middleware published at configured rates and coordinate frames.

Odometric pose

Property Value
ROS message nav_msgs/Odometry (see example)
Nominal output frequency 100 Hz
Nominal output latency <10 ms
Error behavior Drifts smoothly but without bound from starting pose

Timestamped bounded-error velocity estimates. Integrated into a pose, the output drifts smoothly but without bound from the starting pose, and does not reference the map.

Map-relative pose

Property Value
ROS message geometry_msgs/PoseWithCovarianceStamped (see example)
Nominal output frequency 10 Hz
Nominal output latency <100 ms
Error behavior Bounded error relative to map

Timestamped 6DoF map-from-robot poses with bounded error. Referenced to the local map frame.

ECEF pose

Property Value
ROS message geometry_msgs/PoseWithCovarianceStamped (see example)
Nominal output frequency 10 Hz
Nominal output latency <100 ms
Error behavior Bounded error relative to absolute frame

Timestamped 6DoF ECEF pose. Available only if mapping or localization vehicle has GNSS or INS.