#### NOTE
This is a **Hugging Face dataset**. For large datasets, ensure `huggingface_hub>=1.1.3` to avoid rate limits. Learn more in the <a href="https://docs.voxel51.com/integrations/huggingface.html#loading-datasets-from-the-hub" target="_blank">Hugging Face integration docs</a>.

<a href="https://huggingface.co/datasets/Voxel51/Elevator-LIO-FiftyOne" target="_blank">![Hugging Face](https://img.shields.io/badge/%F0%9F%A4%97%20Hugging%20Face-Dataset-yellow)</a>

# Dataset Card for Elevator-LIO (FiftyOne Multimodal)

![preview](https://huggingface.co/datasets/Voxel51/Elevator-LIO-FiftyOne/resolve/main/elevator_lio.gif)

A FiftyOne multimodal dataset of 22 MCAP episodes derived from the Elevator-LIO Dataset
(arXiv 2605.24495). Each episode is a synchronized recording of Livox MID-360 LiDAR point
clouds, IMU data, and (in two sequences) camera imagery captured during multi-floor building
navigation including 79 elevator rides across office, dormitory, campus, and mall environments.

Converted from ROS 1 bags to MCAP format for direct use in FiftyOne’s MCAP viewer, with
Livox CustomMsg transcoded to foxglove.PointCloud (10 Hz), IMU at 200 Hz, and calibrated
static LiDAR-to-IMU transforms embedded in every episode.

## Installation

```bash
pip install -U fiftyone
```

## Usage

```python
import fiftyone as fo
import fiftyone.utils.huggingface as fouh

dataset = fouh.load_from_hub(
    "Voxel51/Elevator-LIO-FiftyOne",
    name="elevator-lio",
    persistent=True,
)

session = fo.launch_app(dataset)
```

## Dataset Details

### Dataset Description

- **Curated by:** Yifan Zhang, Yudong Huang, Yuchong Zhang, Changze Li, Haoran Liu, Ming Yang, Tong Qin (Shanghai Jiao Tong University); FiftyOne packaging by Harpreet Sahota
- **Funded by:** [More Information Needed]
- **Shared by:** Harpreet Sahota (@DataScienceHarp)
- **Language(s):** English
- **License:** CC BY 4.0

### Dataset Sources

- **Repository:** https://github.com/xiaofan4122/Elevator-LIO
- **Paper:** https://arxiv.org/abs/2605.24495
- **Demo:** https://xiaofan4122.github.io/Elevator_LIO_Page/

## Uses

### Direct Use

Benchmarking LiDAR-inertial odometry (LIO) systems on elevator and multi-floor navigation scenarios, where the standard assumption of an inertial reference frame breaks down. Standard LIO systems attribute elevator-induced IMU acceleration to robot ego-motion, causing localization to collapse. Use this dataset to:

- Scrub through elevator transition events in the FiftyOne MCAP viewer (3D point cloud, IMU Plot, elevator flag channel)
- Compare localization behavior at elevator entry and exit across 79 rides
- Evaluate vertical drift suppression algorithms on sequences with known floor-return ground truth
- Develop and test non-inertial state estimation methods in diverse indoor environments (office, dormitory, campus, mall)

### Out-of-Scope Use

This dataset does not contain ground-truth trajectory files or pose annotations. It is not suitable as a direct supervised learning dataset for pose regression. The two community-contributed sequences (horizontal LiDAR mount) have different sensor geometry than the 20 official sequences and require `elevator.strong_prior_enable: true` in the Elevator-LIO YAML configuration.

## Dataset Structure

### Topology

Flat multimodal dataset: **22 samples**, one per recorded episode. `media_type = multimodal`. Each sample’s `filepath` points to a `.mcap` file containing all synchronized sensor streams for that episode.

No train/val/test splits. Episodes are differentiated by the `scene_type` field and can be filtered with `dataset.match(F("scene_type") == "office")`.

### Episodes

| Category   |   Count | Sequences            |
|------------|---------|----------------------|
| Office     |      10 | Office1–10           |
| Campus     |       4 | Campus1–4            |
| Dormitory  |       4 | Dormitory1–4         |
| Mall       |       2 | Mall1–2              |
| Community  |       2 | @_2floors, @_3floors |

Total recording time: **75.4 minutes** (95.6 s min – 705.7 s max per episode).

### Sample fields

| Field               | FiftyOne type   | Description                                                                          |
|---------------------|-----------------|--------------------------------------------------------------------------------------|
| `filepath`          | `StringField`   | Absolute path to `.mcap` episode file                                                |
| `sequence`          | `StringField`   | Sequence name matching the original bag (e.g. `"Office1"`, `"Campus3"`)              |
| `scene_type`        | `StringField`   | Environment category: `"office"`, `"campus"`, `"dormitory"`, `"mall"`, `"community"` |
| `has_camera`        | `BooleanField`  | `True` for Mall2 and Office3 — the only episodes with a camera stream                |
| `has_elevator_flag` | `BooleanField`  | `True` when `/LIO/set_elevator_flag` events are present in the MCAP                  |
| `is_community`      | `BooleanField`  | `True` for community-contributed sequences (non-author data)                         |
| `note`              | `StringField`   | Usage notes (e.g. horizontal LiDAR mount warning for community sequences)            |
| `lidar_msgs`        | `IntField`      | Number of `foxglove.PointCloud` messages (10 Hz, 5-scan accumulation)                |
| `imu_msgs`          | `IntField`      | Number of IMU JSON messages (~200 Hz)                                                |
| `camera_msgs`       | `IntField`      | Number of camera image messages (0 for non-camera episodes)                          |
| `duration_s`        | `FloatField`    | Episode duration in seconds                                                          |
| `has_pointcloud`    | `BooleanField`  | Capability flag: episode contains LiDAR data                                         |
| `has_imu`           | `BooleanField`  | Capability flag: episode contains IMU data                                           |
| `has_image`         | `BooleanField`  | Capability flag: episode contains camera images                                      |

### MCAP channels (inside each episode)

Every `.mcap` file contains the following channels, viewable in FiftyOne’s MCAP tile viewer:

| Topic                          | Schema                       | Tile         | Rate     | Notes                                                                                                     |
|--------------------------------|------------------------------|--------------|----------|-----------------------------------------------------------------------------------------------------------|
| `/livox/lidar`                 | `foxglove.PointCloud`        | 3D           | 10 Hz    | XYZI float32; 5 consecutive Livox CustomMsg packets merged per message for full scene coverage            |
| `/livox/imu`                   | `elevator_lio_imu` (JSON)    | Plot         | ~200 Hz  | Fields: `ax/ay/az` (linear accel), `gx/gy/gz` (angular vel), `qx/qy/qz/qw` (orientation)                  |
| `/LIO/set_elevator_flag`       | `elevator_flag` (JSON)       | Message/Plot | event    | Boolean `active` field; present in subset of sequences                                                    |
| `/tf_static`                   | `foxglove.FrameTransform`    | —            | static   | LiDAR → IMU transform from `calibration_offsets.yaml`; no timestamp field → static store for full episode |
| `/camera/image_raw/compressed` | `foxglove.CompressedImage`   | Image        | variable | JPEG; **Mall2 and Office3 only**                                                                          |
| `/camera/calibration`          | `foxglove.CameraCalibration` | 3D (frustum) | static   | From `calibration_offsets.yaml` K matrix and `plumb_bob` distortion; **Mall2 and Office3 only**           |

### Coordinate frame

Points are in the `lidar` sensor frame (Z-up, X-forward, Y-negated from ROS convention for correct top-down display in the foxglove 3D viewer). The static `/tf_static` transform places the `lidar` frame as a child of the `imu` frame. No odometry or world-frame trajectory is included — each scan is local to the sensor.

### Conversion decisions

- **Livox CustomMsg → foxglove.PointCloud**: The Livox MID-360 uses a proprietary non-repetitive scan pattern. Each 20 ms accumulation window covers a different scene sector. Five consecutive packets (100 ms window) are merged into one MCAP message to provide full scene coverage at 10 Hz and eliminate per-scan flicker in the viewer.
- **IMU as JSON channel**: `foxglove.Imu` is absent from foxglove-sdk 0.26.0; a declared JSON schema (`elevator_lio_imu`) is used instead so the Plot tile can chart individual numeric fields.
- **Camera topic rename**: `/camera/image/compressed` is renamed to `/camera/image_raw/compressed` to satisfy the foxglove image calibration gate (topic last segment must contain `image` + `raw`/`rect`/`rectified`).
- **NaN/Inf filtering**: Invalid Livox returns (NaN/Inf float32 values) and zero-return points (range < 0.1 m) are discarded before packing each PointCloud message.
- **Community bags**: The two `@` sequences use a horizontal LiDAR mount with different sensor geometry. `calibration_offsets.yaml` from the official sequences does not apply; the static transform defaults to the same calibration but these sequences require `elevator.strong_prior_enable: true` when run through Elevator-LIO.

### Sensor calibration (from `calibration_offsets.yaml`)

| Parameter                       | Value                                      |
|---------------------------------|--------------------------------------------|
| `imu_R_lidar`                   | Identity (LiDAR and IMU frames co-aligned) |
| `imu_t_lidar`                   | `[-0.011, -0.023, 0.044]` m                |
| Camera K (fx, fy)               | 1344.65, 1341.78                           |
| Camera principal point (cx, cy) | 801.83, 617.84                             |
| Distortion model                | `plumb_bob` (k1, k2, p1, p2, k3)           |

## Dataset Creation

### Curation Rationale

Standard LiDAR-inertial odometry systems assume the sensor platform operates in an inertial reference frame. When a robot rides an elevator, the elevator cabin imposes a non-inertial motion: the IMU captures elevator-induced acceleration superimposed on robot ego-motion, while the LiDAR observes only the cabin interior. These two signals become physically inconsistent, causing conventional LIO pipelines to diverge or collapse. No prior public dataset specifically targeted this failure mode. The authors collected 20 sequences containing 79 elevator rides to enable development and evaluation of LIO systems for multi-floor indoor navigation.

### Source Data

#### Data Collection and Processing

Data was collected handheld across four building types in Shanghai: office buildings, dormitories, university campus, and a shopping mall. The sensor suite — Livox MID-360 LiDAR with built-in IMU and an optional synchronized industrial camera — was mounted on a Jetson Orin Nano compute unit and carried through elevator rides, lobby traversals, and floor-level exploration. Sequences range from single-floor corridors to large-scale cross-floor mapping with long vertical travel (up to 705 seconds per episode).

Two additional sequences were contributed by community member @ ( ID 9556244270), covering 2-floor and 3-floor elevator rides with a horizontally mounted LiDAR.

#### Who are the source data producers?

Yifan Zhang, Yudong Huang, Yuchong Zhang, Changze Li, Haoran Liu, Ming Yang, and Tong Qin at Shanghai Jiao Tong University (SJTU), Shanghai, China. Community contributions by @.

### Annotations

#### Annotation process

No manual annotations. The `/LIO/set_elevator_flag` boolean topic, present in a subset of sequences, was set programmatically by the Elevator-LIO algorithm’s elevator mode detector during data collection. No ground-truth trajectory or pose annotations are distributed; localization accuracy in the paper was evaluated by measuring terminal height error on return-to-start sequences.

#### Who are the annotators?

The elevator flag signal was generated by the Elevator-LIO algorithm during recording. No human annotators.

#### Personal and Sensitive Information

Data was collected in public and semi-public building environments. No face or personal data was intentionally captured. The camera is present in only 2 of 22 sequences (Mall2 and Office3); all other sequences are LiDAR+IMU only with no imaging capability.

## Citation

**BibTeX:**

```bibtex
@article{zhang2026elevatorlio,
  title={Elevator-LIO: Robust LiDAR-Inertial Odometry for Multi-Floor Navigation under Elevator-Induced Non-Inertial Motion},
  author={Zhang, Yifan and Huang, Yudong and Zhang, Yuchong and Li, Changze and Liu, Haoran and Yang, Ming and Qin, Tong},
  journal={arXiv preprint arXiv:2605.24495},
  year={2026}
}
```

**APA:**

Zhang, Y., Huang, Y., Zhang, Y., Li, C., Liu, H., Yang, M., & Qin, T. (2026). Elevator-LIO: Robust LiDAR-Inertial Odometry for Multi-Floor Navigation under Elevator-Induced Non-Inertial Motion. *arXiv preprint arXiv:2605.24495*.

## More Information

- Original ROS 1 bag dataset: https://huggingface.co/datasets/xiaofan0100/Elevator-LIO-Dataset
- Elevator-LIO source code: https://github.com/xiaofan4122/Elevator-LIO
- Project page: https://xiaofan4122.github.io/Elevator_LIO_Page/
- FiftyOne MCAP viewer documentation: https://docs.voxel51.com/user_guide/app.html

## Dataset Card Authors

Harpreet Sahota

## Dataset Card Contact

[@DataScienceHarp](https://x.com/DataScienceHarp)
