Skip to content

Commit 764295e

Browse files
authored
Document the float32 precision limit on large-coordinate maps (#68) (#92)
Explain why a map kept in absolute MGRS/UTM coordinates fails: it is loaded into pcl::PointXYZI (float32), whose ~24-bit mantissa quantizes positions to 0.25-0.5 m at seven- to eight-digit northings, and RViz (also float32, camera at origin) does not display a cloud millions of metres away -- the symptom in #68. The fix is to localize in a recentered local frame, as the Istanbul and Boreas public setups already do. Adds a precision table and an RViz-not-displayed row to the mismatch table in map_alignment.md, and marks #68 documented in the reliability roadmap.
1 parent d72f73e commit 764295e

2 files changed

Lines changed: 31 additions & 1 deletion

File tree

docs/map_alignment.md

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,35 @@ use a fixed local East-North-Up style frame baked into the map build:
4141
- `/initialpose` must use the **same origin and axis convention** as the map file
4242
- GNSS reference poses in the Istanbul bag are already in that convention
4343

44+
### Very large coordinates and float32 precision (issue #68)
45+
46+
The map is loaded into a `pcl::PointCloud<pcl::PointXYZI>`, whose XYZ are **32-bit
47+
floats**. float32 keeps ~24 bits of mantissa, so the spacing between representable
48+
values (and therefore the position quantization of every map point) grows with the
49+
coordinate magnitude:
50+
51+
| Coordinate magnitude | float32 step (quantization) |
52+
| --- | --- |
53+
| `~66,000` (Istanbul local frame) | `~0.008 m` (fine) |
54+
| `~500,000` (UTM easting) | `~0.03 m` |
55+
| `~4,000,000` (UTM/MGRS northing) | `~0.25 m` |
56+
| `~8,000,000` | `~0.5 m` |
57+
58+
So a map kept in **absolute MGRS/UTM coordinates** (six- to eight-digit northings)
59+
is silently snapped to a 0.25–0.5 m grid the moment it is loaded — registration can
60+
never do better than that floor, and in RViz the cloud looks coarse or, more often,
61+
**does not appear at all**: RViz/Ogre also renders in float32 with the camera at the
62+
origin, so a cloud millions of metres away is beyond the default view and clipping
63+
planes (this is the symptom reported in #68).
64+
65+
**Fix: localize in a recentered frame, not in absolute MGRS/UTM.** Subtract a fixed
66+
origin offset from the map so its coordinates are small (a few km at most), and use
67+
that same offset for `/initialpose`, any GNSS reference poses, and when interpreting
68+
`/pcl_pose`. This is exactly what the public setups already do — the Istanbul map is
69+
a local ENU frame (`x ≈ 66459`), and the Boreas maps are GT-aligned
70+
`*_loc_frame.pcd` rebuilds rather than absolute coordinates. MGRS tiles are **not**
71+
supported directly (see *Supported map inputs* above); convert and recenter first.
72+
4473
### Common mismatch patterns
4574

4675
| Symptom | Likely cause | What to check |
@@ -50,6 +79,7 @@ use a fixed local East-North-Up style frame baked into the map build:
5079
| Offset grows over time | registration drift, not static map misalignment | see `/alignment_status` reject streak |
5180
| `local_map_crop_too_small` | pose seed far outside map bounds | initial pose or map path wrong |
5281
| Map visible, pose never moves | frame id mismatch on `/initialpose` | `header.frame_id` must equal `global_frame_id` |
82+
| Map not displayed in RViz / coarse-looking cloud | absolute MGRS/UTM coordinates exceed float32 precision | recenter the map to a local origin (see *Very large coordinates*, issue #68) |
5383

5484
## Minimum alignment checklist
5585

docs/reliability_roadmap.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ Last triaged: 2026-06-10
2525
| [#27](https://github.com/rsasaki0109/lidar_localization_ros2/issues/27) | use odom TF instead of odom topic | frame / TF | P1 | documented | odom topic vs odom TF clarified; TF-only mode not implemented |
2626
| [#55](https://github.com/rsasaki0109/lidar_localization_ros2/issues/55) | `odom_frame_id_` defined but not used | frame / TF | P2 | open | code audit + doc alignment |
2727
| [#75](https://github.com/rsasaki0109/lidar_localization_ros2/issues/75) | map alignment | map | P1 | documented | see [map_alignment.md](map_alignment.md) |
28-
| [#68](https://github.com/rsasaki0109/lidar_localization_ros2/issues/68) | MGRS map not displayed | map | P2 | open | document supported map formats and frame assumptions |
28+
| [#68](https://github.com/rsasaki0109/lidar_localization_ros2/issues/68) | MGRS map not displayed | map | P2 | documented | float32 precision limit on absolute MGRS/UTM coords; recenter to a local frame ([map_alignment.md](map_alignment.md)) |
2929
| [#48](https://github.com/rsasaki0109/lidar_localization_ros2/issues/48) | map showing alongside live data in rviz | map | P2 | documented | see [troubleshooting.md](troubleshooting.md) map visibility section |
3030
| [#44](https://github.com/rsasaki0109/lidar_localization_ros2/issues/44) | localization pose offset | map | P2 | documented | see [map_alignment.md](map_alignment.md) offset vs drift table |
3131
| [#72](https://github.com/rsasaki0109/lidar_localization_ros2/issues/72) | pose covariance | covariance | P2 | documented | see [pose_covariance.md](pose_covariance.md); no fusion claim yet |

0 commit comments

Comments
 (0)