# Use of external trajectory, LAS export, batch mode

**URL:** https://discourse.paraview.org/t/use-of-external-trajectory-las-export-batch-mode/17167
**Category:** LidarView, Lidar, and SLAM
**Created:** [September 8, 2025, 7:12am UTC](https://discourse.paraview.org/t/use-of-external-trajectory-las-export-batch-mode/17167 "2025-09-08T07:12:10Z")
**Posts on this page:** 8
**Page:** 1

<div class="post-metadata">

### Author: ![Toby](https://discourse.paraview.org/letter_avatar_proxy/v4/letter/t/7993a0/32.png) [@Toby](https://discourse.paraview.org/u/Toby)
#### Post date: [September 8, 2025, 7:12am UTC](https://discourse.paraview.org/t/use-of-external-trajectory-las-export-batch-mode/17167/1 "2025-09-08T07:12:10Z")

</div>

Hi,

I’ve been doing some testing with SLAM inside LidarView, using data acquired with a Hesai Pandar XT32 and a GNSS/INS positioning unit (IMU) from which we can obtain a post-processed tightly-coupled trajectory. First of all I want to say that I’m extremely impressed with the results in a lidar-only test case, as the registering of overlapping drivelines is practically seamless and even longer stretches of straight road with little geometry cause little XY deviation.

I have however run into some issues that I would like to ask help with:

1. I have so far been unable to integrate the postprocessed GNSS/INS trajectory. I have converted the trajectory to a csv that looks like this:

```auto
Time,X,Y,Z,Rz,Ry,Rx
1744611187.003185,180220.72746252423,448140.8107820237,23.98793640492724,3.092427497477753,-0.0251676478137583,-0.0131597825600371
1744611187.008185,180220.7273933219,448140.8108929326,23.987936405969265,3.09244495075656,-0.0251676478137583,-0.0131772358525572
1744611187.013185,180220.72746196107,448140.8108932798,23.98793640573993,3.092444950770452,-0.0251676478137583,-0.0131772358525572

```

I’ve also created the calibration matrix file. Adding the trajectory as described on the LidarView SLAM manual page does appear to work and only generates a warning stating that the caibration matrix has been read. But when I then do the SLAM processing, it does not seem like the trajectory gets used and all output remains close to the origin. I also tried just setting an initial pose XYZ that is close to the starting position in our national grid, but once again the resulting point cloud stays close to 0/0/0.

Would it be possible to get a slightly more detailed description of how to integrate an external trajectory? What is the exact file format required? Should the calibration file contain the position/orientation of the lidar scanner in the IMU body frame, or the IMU position/orientation in the scanner frame? What are then the required settings and processing steps to get an improved trajectory and point cloud in the IMU trajectory’s coordinate system?

1. There are some issued with the LAS export. The timestamp is not written to a point’s timestamp field, but added as an extra custom field. There also seems to be a precision issue (the Hesai uses Unix timestamps) that causes timestamps in large discrete steps instead of the desired millisecond precision. The “write timestemps as file-series” option also generates multiple file with mostly identical content, possibly because of this precision issue. Inside LidarView, the timestamps seem to be OK.

2. Is it possible to do SLAM processing in batch? The bin folder contains an lvbatch.exe and an lvpython.exe, but no information on how to use these.

I’ve been using a recent nightly build (5.1.0-33-gb21aecfa) as this appeared to resolve the issue with importing Hesai calibration files, as described in another topics.

Any help would be greatly appreciated!

Toby

---

<div class="post-metadata">

### Author: ![Timothee\_Couble](https://discourse.paraview.org/user_avatar/discourse.paraview.org/timothee_couble/32/9790_2.png) [@Timothee\_Couble](https://discourse.paraview.org/u/Timothee_Couble)
#### Post date: [September 8, 2025, 3:08pm UTC](https://discourse.paraview.org/t/use-of-external-trajectory-las-export-batch-mode/17167/2 "2025-09-08T15:08:30Z")

</div>

Hi @Toby,

Please note that I’m not the SLAM expert (she is currently in vacation), so I will share my understanding, but I could be mistaken on some points.

> [@Toby](#):
>
> Would it be possible to get a slightly more detailed description of how to integrate an external trajectory? What is the exact file format required? Should the calibration file contain the position/orientation of the lidar scanner in the IMU body frame, or the IMU position/orientation in the scanner frame? What are then the required settings and processing steps to get an improved trajectory and point cloud in the IMU trajectory’s coordinate system?

It seems that the header for the XYZRPY format is `Time, X, Y, Z, Rx(Roll), Ry(Pitch), Rz(Yaw)` (from [here](https://gitlab.kitware.com/keu-computervision/slam/-/blob/6dd01ca134d72b194783b9df57614a6842a7f8ac/paraview_wrapping/Plugin/vtkLidarSlam/vtkSlam.cxx#L1225)), you can add in the same file the IMU data with the columns `acc_x, acc_y, acc_z, w_x, w_y, w_z`.  
I think the calibration file should contains the position/orientation of the lidar scanner in the IMU body frame, and then the `calibration_external_sensor.mat` next to it would convert it back to the lidar frame.  
To convert the local trajectory to gnss coordinates you can use the `Align to external sensor reference` button (I think it should be click after the SLAM process is complete, as doing so earlier could introduce numerical inaccuracies)

> [@Toby](#):
>
> There are some issued with the LAS export. The timestamp is not written to a point’s timestamp field, but added as an extra custom field. There also seems to be a precision issue (the Hesai uses Unix timestamps) that causes timestamps in large discrete steps instead of the desired millisecond precision.

Yes looking a the LAS specs / writter code, I see what you mean. I wil try to fix that this week. (Note that I don’t think you need to use the `write timestemps as file-series` option as it used to write multiple las files, one for each frame of the lidar)

> [@Toby](#):
>
> Is it possible to do SLAM processing in batch? The bin folder contains an lvbatch.exe and an lvpython.exe, but no information on how to use these.

What do you mean exactly? Could you provide more detail on what you are trying to acheive?

Note that we currenlty works on improving the integration of external sensor in LidarView and add a better user experience of manipulating them / loading them in the SLAM. So If you have any suggestion they are welcome!

Hope this helps!  
Timothée

---

<div class="post-metadata">

### Author: ![Toby](https://discourse.paraview.org/letter_avatar_proxy/v4/letter/t/7993a0/32.png) [@Toby](https://discourse.paraview.org/u/Toby)
#### Post date: [September 8, 2025, 3:47pm UTC](https://discourse.paraview.org/t/use-of-external-trajectory-las-export-batch-mode/17167/3 "2025-09-08T15:47:55Z")

</div>

Hi Timothée,

Thanks for your reply! I’ve modified the trajectory file format and I see that the point cloud is indeed relocated after clicking Align to external sensor reference and then re-running through all frames. I’ll try out a few options for the calibration matrix.

Regarding the batch processing, ideally it would be possible to run the processing from the command line in a non-interactive way to allow for automation. It also looks like (at least in the test that I did) processing becomes slow with large input files.

Toby

---

<div class="post-metadata">

### Author: ![Toby](https://discourse.paraview.org/letter_avatar_proxy/v4/letter/t/7993a0/32.png) [@Toby](https://discourse.paraview.org/u/Toby)
#### Post date: [September 9, 2025, 3:07pm UTC](https://discourse.paraview.org/t/use-of-external-trajectory-las-export-batch-mode/17167/4 "2025-09-09T15:07:28Z")

</div>

I’ve done some further testing. I’ve found one way to generate results that appear to use the GNSS/INS trajectory and provide output in the trajectory coordinate system. I’ve directly applied the LiDAR lever arm and orientation during PCAP import. It is a bit unclear here whether the transformation from base to lidar frame or lidar to base frame is required, but it seems to be lidar to base frame. The coordinate system definition is also not entirely clear. The trajectory appears to be left-handed with x=forward (roll axis), y=right (pitch axis) and z=up (yaw-axis). But both the display in LidarView and how the rotation angles affect the lidar frames imply a right-handed system with x=left (pitch axis), y=forward (roll axis), and z=up (yaw axis).

After instantiating a SLAM filter I have added the trajectory through the external sensor dialog, using the identity matrix as calibration matrix (as lidar to base frame transformation has already been dealt with) and `External OR motion extrapolation` as Ego-Motion mode.

If I then click `Align to external sensor reference` and run through all frames, the external trajectory appears to be taken into account. I’m still seeing differences in height.

Some things that I noticed:

1. I tried to run SLAM first without the external trajectory, then loading it and clicking `Align to external sensor reference`. This does not appear to do anything.
2. Likewise for the `Calibrate` button under `External sensors`. It is suggested that this should be able to compute the calibration if both a SLAM trajectory and an external trajectory are present, but nothing seems to happen.
3. The documentation states that it is also possible to use an external trajectory (GNSS only or with orientations) for Pose graph optimization. I’ve tried, but clicking `Optimize graph` does not appear to do anything.

---

<div class="post-metadata">

### Author: ![Toby](https://discourse.paraview.org/letter_avatar_proxy/v4/letter/t/7993a0/32.png) [@Toby](https://discourse.paraview.org/u/Toby)
#### Post date: [October 6, 2025, 9:53am UTC](https://discourse.paraview.org/t/use-of-external-trajectory-las-export-batch-mode/17167/5 "2025-10-06T09:53:27Z")

</div>

Hi,

Is the SLAM expert back from vacation? If yes, could she take a look at my questions? This would be much appreciated. Thanks!

Toby

---

<div class="post-metadata">

### Author: ![Tong\_Fu](https://discourse.paraview.org/user_avatar/discourse.paraview.org/tong_fu/32/13154_2.png) [@Tong\_Fu](https://discourse.paraview.org/u/Tong_Fu)
#### Post date: [October 9, 2025, 3:19pm UTC](https://discourse.paraview.org/t/use-of-external-trajectory-las-export-batch-mode/17167/6 "2025-10-09T15:19:39Z")

</div>

**Hi Toby,**

Sorry for the delayed reply.

When you have an external trajectory — whether from an IMU, INS, or another LiDAR SLAM — you can use it to assist SLAM in several ways:

1. **Use external poses for ego-motion estimation.**  
Based on the current timestamps, SLAM will find the synchronized pose by interpolating the external trajectory. To enable this, set the _Ego-Motion mode_ to **“External”** or **“External OR motion extrapolation.”**

2. **Use external poses in local optimization.**  
SLAM estimates the pose by optimizing the distance between the features in the current frame and the map. If an external trajectory is available, it can also be included in this optimization.  
To enable it, set _Pose weight_ to a non-zero value to indicate how much you trust the external poses.

3. **Use external poses for undistortion.**  
External poses can be used to undistort frames, especially when the external sensor (e.g., an IMU) has a higher frequency than the LiDAR. To enable this, set the _Undistortion mode_ to **“External.”**

4. **Use external poses in pose graph optimization.**  
To do so, you can then click **“Optimize graph”** whenever needed.

SLAM uses the right-handed coordinate convention with **x → roll** , **y → pitch** , and **z → yaw**.  
`BaseToLidar` is set to identity by default, meaning the SLAM odometry is represented in the LiDAR frame. The external poses used in SLAM should be aligned with the **ENU** (East–North–Up) coordinate system.

In my experience, the **x, y, z** coordinates from an INS are often in the **ENU** frame (east → x, north → y, up → z), while the **roll, pitch, yaw** from an IMU are aligned with the **NED** frame (north → x, east → y, down → z).  
Additionally, the yaw value provided by the INS often represents a _heading_ — an absolute angle (0° → north, 90° → east, etc.).

> “I tried to run SLAM first without the external trajectory, then loading it and clicking _Align to external sensor reference_. This does not appear to do anything.”

That’s the recommended way to align the SLAM trajectory with the external poses. We prefer to let SLAM work locally first and then apply the GPS offset afterward.  
I haven’t been able to reproduce this behavior — if you can share part of your **pcap** and **INS trajectory** , I can take a closer look.

> “Likewise for the _Calibrate_ button under _External sensors_. It is suggested that this should be able to compute the calibration if both a SLAM trajectory and an external trajectory are present, but nothing seems to happen.”

The **Calibrate** button computes the INS calibration. The calibration matrix is stored in memory and does not affect visualization directly.  
However, accurate calibration is important — otherwise, using the INS can actually degrade SLAM results.  
Calibration precision depends on the trajectory quality. You should select a portion of the SLAM trajectory with sufficient rotation and non-planar motion so that the optimizer has enough information to estimate the 6-DOF transformation.

Do you work in a Windows or Linux environment?  
It would be helpful to check the SLAM log. If you’re on Linux, you can set the verbosity level to **3** for more detailed output. The log can provide more information about why the pose graph optimization didn’t work, show the estimated calibration, and include other useful details.

Best regards,

Tong

---

<div class="post-metadata">

### Author: ![Toby](https://discourse.paraview.org/letter_avatar_proxy/v4/letter/t/7993a0/32.png) [@Toby](https://discourse.paraview.org/u/Toby)
#### Post date: [October 13, 2025, 10:28am UTC](https://discourse.paraview.org/t/use-of-external-trajectory-las-export-batch-mode/17167/7 "2025-10-13T10:28:29Z")

</div>

Hi Tong,

Thanks for getting back to me!

> [@](#):
>
> 1. **Use external poses for ego-motion estimation.**  
> Based on the current timestamps, SLAM will find the synchronized pose by interpolating the external trajectory. To enable this, set the _Ego-Motion mode_ to **“External”** or **“External OR motion extrapolation.”**

Which other settings/actions are required for this? If I use _Align to external sensor reference_ on the first frame everything is shifted to the proper position, but I’m unsure whether the external trajectory is used in any other way.

> [@](#):
>
> 1. **Use external poses in local optimization.**  
> SLAM estimates the pose by optimizing the distance between the features in the current frame and the map. If an external trajectory is available, it can also be included in this optimization.  
> To enable it, set _Pose weight_ to a non-zero value to indicate how much you trust the external poses.

I assume this also requires the _Ego-Motion mode_ set to **“External”** or **“External OR motion extrapolation.”**? Or does this need different settings/actions? I’ve experimented with different pose weights, and with larger weights the trajectory is indeed somewhere between the SLAM-only and the IMU-only trajectory.

> [@](#):
>
> 1. **Use external poses for undistortion.**  
> External poses can be used to undistort frames, especially when the external sensor (e.g., an IMU) has a higher frequency than the LiDAR. To enable this, set the _Undistortion mode_ to **“External.”**

I’ve briefly tried this, but it makes processing extremely slow (with a 200 Hz trajectory).

> [@](#):
>
> 1. **Use external poses in pose graph optimization.**  
> To do so, you can then click **“Optimize graph”** whenever needed.

I’ve now been able to get this to work, by first clicking _Apply_. I haven’t taken a good look at the results yet.

Concerning the coordinate system, I’ve made sure that the coordinates and angles of my IMU trajectory match those in an exported lidar-only trajectory, so I think that those are correct

> [@](#):
>
> > “I tried to run SLAM first without the external trajectory, then loading it and clicking _Align to external sensor reference_. This does not appear to do anything.”

I’ve now been able to get this to work, but I don’t fully understand how the offset is computed. Is the offset only computed for the selected frame and applied to the entire trajectory, or are multiple offsets computed and applied to the trajectory?

> [@](#):
>
> The **Calibrate** button computes the INS calibration. The calibration matrix is stored in memory and does not affect visualization directly.

I’ve found the calibration results in the program output.

> [@](#):
>
> Do you work in a Windows or Linux environment?  
> It would be helpful to check the SLAM log. If you’re on Linux, you can set the verbosity level to **3** for more detailed output. The log can provide more information about why the pose graph optimization didn’t work, show the estimated calibration, and include other useful details.

Originally Windows, but I’ve now done some testing with the latest nightly build under Linux as well.  
Do you mean the verbosity level as given to LidarView binary (_-v 3_) or the verbosity level under \*General Parameters" in the LidarView GUI?

I can share the dataset with you privately, as it is not a public dataset. I would be interested in the processing steps that you would recommend to get the best results. I’m also still interested in a batch processing mode, if that is possible.

Best regards,

Toby

---

<div class="post-metadata">

### Author: ![Tong\_Fu](https://discourse.paraview.org/user_avatar/discourse.paraview.org/tong_fu/32/13154_2.png) [@Tong\_Fu](https://discourse.paraview.org/u/Tong_Fu)
#### Post date: [October 21, 2025, 12:02pm UTC](https://discourse.paraview.org/t/use-of-external-trajectory-las-export-batch-mode/17167/8 "2025-10-21T12:02:13Z")

</div>

Hi Toby,

Thank you for your detailed testing and for sharing the data.  
Here is my answers:

### Ego-Motion Mode

Setting the _Ego-Motion mode_ to “External” or “External OR motion extrapolation” only affects how the SLAM pipeline initializes the relative transform between frames (i.e., it provides a pose prior for ICP).  
It doesn’t automatically enable other uses of the external trajectory (e.g., local optimization or undistortion). Each of these is configured separately.

### Local Optimization (Pose Weight)

You’re correct — the _Pose weight_ parameter controls how much the local optimization trusts the external trajectory.  
You don’t need to set the Ego-Motion mode to External for this to take effect, the two steps are independent.  
A higher pose weight means the optimization will lean more toward the external poses (as you observed).

### Undistortion with External Poses

Yes, setting Undistortion mode to External uses the external trajectory to compensate motion distortion.  
However, the process currently becomes slow due to a multithreading issue — we’re aware of this and plan to improve it. If you want to test this feature, you can set the num of thread to 1 for now.

### Align to External Sensor Reference

This function computes an offset between the SLAM pose and the corresponding external pose at (or near) the selected frame.  
The offset is computed once and applied globally to the trajectory.  
If the SLAM trajectory has drifted, you may see good alignment for the current frame but some residual offset for earlier parts of the trajectory.

### Logs and Verbosity

To view detailed logs, you can simply adjust the verbosity level under General Parameters → Verbosity level in the GUI.  
By the way, after changing parameters, you should always need to click **Apply** for it to take effect.

### Workflow

Your testing setup looks good. Just make sure the INS/LiDAR calibration is accurate before using external pose constraints — otherwise, the pose graph optimization may introduce additional noise.  
Here’s a quick summary of what I did with your dataset:

- load the external trajectory in SLAM and run SLAM with “indoor - hesai xt32 - vehicle” preset
- (optional) If the environment is chanlleging (e.g featureless area such as tunnels or open fields) for SLAM, you can set “ego motion mode” as external and increase pose weight.
- opitmize graph
- align to external sensor reference
- (optional) Apply “Aggregate points from trajectory” to obtain dense map

Regarding batch processing mode, we already have some experience about this subject. Please feel free to contact us ([gatien.ferret@kitware.com](mailto:gatien.ferret@kitware.com) or [tong.fu@kitware.com](mailto:tong.fu@kitware.com)) if you’d like more detailed support

Best,  
Tong
