uvt 0.1.1

Utilities for interacting with Uncrewed Vehicle Trajectory (UVT) files.
Documentation
# uvt

[![On crates.io](https://img.shields.io/crates/v/uvt.svg)](https://crates.io/crates/uvt)
[![On docs.rs](https://docs.rs/uvt/badge.svg)](https://docs.rs/uvt)

This crate provides utilities for reading and writing files in the _Uncrewed Vehicle Trajectory_ (UVT) format.
The UVT format is an extension of the LTR file format introduced in [_Kilometer-Scale Autonomous Navigation in Subarctic Forests: Challenges and Lessons Learned_](https://doi.org/10.55417/fr.2022050).

A UVT file contains:

- a LiDAR map of the environment, stored in the [`VTK` format]https://vtk.org.
- A trajectory recorded by an uncrewed vehicle.

An example UVT file is available on [Zenodo](https://doi.org/10.5281/zenodo.16928365).

## Features

This crate:

- Parses `.uvt` files into Rust data structures.
- Exports trajectories and maps back into  `.uvt` files
- Generate UVT files directly from rosbags:
  - ROS (1) (`.bag`)
  - ROS 2 (`.mcap`)

---

## Usage

To use this library simply add the crate name to your `Cargo.toml` file:

```rust
[dependencies]
uvt = "0.1"
```

## Examples

### Import / Export

This crate allows to read, parse, and write uncrewed vehicle trajectories saved in the `UVT` format.

```rs
use std::io;
use uvt::{self, pose};

fn main() -> Result<(), io::Error> {
    // Open a UVT file
    let my_uvt = uvt::Uvt::read_file("example.uvt")?;

    // Retrieve map and trajectory
    let uvt_map = my_uvt.map.clone();
    let uvt_trajectory = my_uvt.trajectory.clone();

    // Retrieve all positions from the trajectory
    let positions: Vec<pose::Point> = uvt_trajectory
        .iter()
        .map(|pose| pose.pose.position)
        .collect();

    // Retrieve all orientations from the trajectory
    let orientations: Vec<pose::Quaternion> = uvt_trajectory
        .iter()
        .map(|pose| pose.pose.orientation)
        .collect();

    // Save my_uvt to a new file
    my_uvt.write_file("my_uvt.uvt")?;

    Ok(())
}
```

### Generation from rosbags

You can also generate a UVT file from rosbags, be it in ROS (1) (`.bag`) or in ROS 2 (`.mcap`).
Your rosbag must contain:

- a **map** topic with `sensor_msgs/PointCloud2` messages
- a **trajectory** topic with `nav_msgs/Odometry` messages.

```rust
use std::io;
use uvt;

fn main() -> Result<(), io::Error> {
    let map_topic = "/map";
    let traj_topic = "/odom";

    // Create a UVT file from a ROS 1 bag file
    let bag_uvt = uvt::Uvt::read_rosbag("example.bag", map_topic, traj_topic)?;
    bag_uvt.write_file("bag.uvt")?;

    // Create a UVT file from a ROS 2 MCAP file
    let mcap_uvt = uvt::Uvt::read_mcap("example.mcap", map_topic, traj_topic)?;
    mcap_uvt.write_file("mcap.uvt")?;

    Ok(())
}
```

## Citation

If you use the code or data in an academic context, please cite the following work:

```bibtex
@article{Baril2022,
  title = {Kilometer-Scale Autonomous Navigation in Subarctic Forests: Challenges and Lessons Learned},
  volume = {2},
  ISSN = {2771-3989},
  url = {http://dx.doi.org/10.55417/fr.2022050},
  DOI = {10.55417/fr.2022050},
  journal = {Field Robotics},
  publisher = {Institute of Electrical and Electronics Engineers (IEEE)},
  author = {Baril,  Dominic and Desch\^enes,  Simon-Pierre and Gamache,  Olivier and Vaidis,  Maxime and LaRocque,  Damien and Laconte,  Johann and Kubelka,  Vladimír and Giguère,  Philippe and Pomerleau,  Fran\c{c}ois},
  year = {2022},
  month = jul,
  pages = {1628–1660}
}
```

## License

Licensed under either of

 * Apache License, Version 2.0
   ([LICENSE-APACHE]LICENSE-APACHE or <http://www.apache.org/licenses/LICENSE-2.0>)
 * MIT license
   ([LICENSE-MIT]LICENSE-MIT or <http://opensource.org/licenses/MIT>)

at your option.

## Contribution

Unless you explicitly state otherwise, any contribution intentionally submitted
for inclusion in the work by you, as defined in the Apache-2.0 license, shall be
dual licensed as above, without any additional terms or conditions.