Exwayz trajectories as they are output by exwayz_slam.exe, exwayz_loop_closure.exe or exwayz_georef.exe for instance are stored in a .ply
binary format.
Field name | Type | Description |
---|---|---|
x |
double |
X component of the pose’s translation |
y |
double |
Y component of the pose’s translation |
z |
double |
Z component of the pose’s translation |
qx |
double |
X component of the pose’s rotation quaternion |
qy |
double |
Y component of the pose’s rotation quaternion |
qz |
double |
Z component of the pose’s rotation quaternion |
qw |
double |
Omega component of the pose’s rotation quaternion |
timestamp |
double |
Hardware timestamp of the LiDAR frame corresponding to the pose |
indices |
int |
Index of the frame in the dataset |
A trajectory can come with an offset file (when written by exwayz_georef.exe for instance) to avoid storing too big coordinates directly in the .ply
. The offset file
.ply
trajectory.ply
trajectoryIf the two above conditions are matched, when Exwayz executables will receive a .ply
trajectory in input, they will automatically read the .offset
and then get the trajectory in global coordinates
import numpy as np
from plyfile import PlyData
from pyquaternion import Quaternion
def main():
ply_fpath = "2_georef/traj_fusion_gps.ply"
ply = PlyData.read(ply_fpath)
ply_props = [p.name for p in ply['vertex'].properties]
positions = []
rotations = []
timestamps = []
indices = []
for vertex in ply['vertex']:
positions.append( np.array([vertex['x'], vertex['y'], vertex['z']]) )
if 'q_w' in ply_props:
rotations.append( Quaternion(w=vertex['q_w'], x=vertex['q_x'], y=vertex['q_y'], z=vertex['q_z']) )
if 'timestamp' in ply_props:
timestamps.append(vertex['timestamp'])
if 'indices' in ply_props:
indices.append(vertex['indices'])
print("positions:", positions[0:10])
print("rotations:", rotations[0:min(10, len(rotations))])
print("timestamps:", timestamps[0:min(10, len(rotations))])
print("indices:", indices[0:min(10, len(rotations))])
if __name__== "__main__":
main()