22
33# Layered Global Map Observations
44
5- This post describes the observation interface for contributing temporary map
6- information to the next generation Open-RMF prototype.
5+ This post describes the implemented observation interface and demos for
6+ contributing temporary map information to the next generation Open-RMF
7+ prototype.
78
89The goal is to let robots and perception systems publish what they currently
910observe without tying them to a specific central map implementation. The first
@@ -19,15 +20,21 @@ observations, can be added later.
1920 same sensor snapshot
2021* Clear-space patches have TTLs, just like obstacle patches
2122* A source can reset its previous observations without using a TTL
22- * Robot-mounted sources can include the robot pose at observation time
23+ * Robot-mounted sources include the observation-frame pose at observation time
24+ * The Rust map server composes a static occupancy grid and active observations
25+ into ` /map `
26+ * The Nav2 demo converts scans from three robots into point regions and displays
27+ the combined map
2328* The observation messages live in ` rmf_layered_map_msgs ` , leaving
2429 ` rmf_prototype_msgs ` unchanged
2530
26- # Observation Topic
31+ # Observation Topics
2732
28- Observation sources publish dynamic map observations on :
33+ The layered map server uses these topics :
2934
35+ * ` /map/static ` - static ` nav_msgs/OccupancyGrid `
3036* ` /map/region_updates ` - [ ` MapRegionUpdate.msg ` ] ( ../rmf_layered_map_msgs/msg/MapRegionUpdate.msg )
37+ * ` /map ` - composed ` nav_msgs/OccupancyGrid `
3138
3239The topic is an event stream. Updates are not latched because expired
3340observations should not be replayed to a restarted map service as if they were
@@ -105,6 +112,47 @@ sensor-local regions with their sensor pose, while synthetic sources whose
105112regions are already global can use the identity pose. The first implementation
106113accepts point and axis-aligned rectangle regions.
107114
115+ # Layered Map Server
116+
117+ ` rmf_layered_map_server ` keeps the static occupancy grid separate from dynamic
118+ observations and publishes their composition on ` /map ` . It validates source
119+ timestamps and frames, ignores updates that are older than the latest accepted
120+ update from the same source, supports source resets, and removes observations
121+ after their TTL expires.
122+
123+ The server applies clear patches before obstacle patches from the same update.
124+ During composition, obstacle observations win over clear observations so
125+ occupied space is not accidentally erased by another active source.
126+
127+ # Three-Robot Nav2 Demo
128+
129+ The launch file starts three stationary robots in different free corners of the
130+ warehouse and spawns one deterministic Gazebo box near each robot. Each
131+ observation node subscribes to its robot's local ` sensor_msgs/LaserScan ` ,
132+ filters invalid or out-of-range returns, and publishes the remaining scan
133+ endpoints as point regions.
134+
135+ Each scan is a replacement snapshot: ` reset_source ` removes the source's
136+ preceding points before the new points are added, and a short TTL removes the
137+ source if it stops publishing. The observation-frame pose is recorded in the
138+ shared ` map ` frame so the map server can transform the scan-local regions before
139+ rasterizing them.
140+
141+ The demo launches Nav2 localization but does not launch Nav2 planning or control
142+ components, RMF planning, or navigation goals. Three robot-local RViz windows
143+ are enabled by default, and another RViz window displays the combined global
144+ ` /map ` .
145+
146+ The scan-to-region conversion is deliberately simple so its information loss
147+ and publication cost are visible. ` beam_stride ` reduces the number of point
148+ regions, ` publish_period_sec ` throttles replacement snapshots, and
149+ ` max_observation_range ` limits represented returns. ` ttl_sec ` controls how
150+ quickly stale snapshots expire. Each publisher logs its number of input beams
151+ and output regions so message density, update rate, and visual fidelity can be
152+ compared. The current demo publishes occupied endpoints only; it does not
153+ convert raycast clearing into free-space regions or compress adjacent points
154+ into larger regions.
155+
108156# Example Flow
109157
110158A local costmap or LiDAR observation node can publish a replacement snapshot by:
@@ -118,22 +166,24 @@ A local costmap or LiDAR observation node can publish a replacement snapshot by:
1181665 . Giving each patch a TTL long enough to survive normal publication jitter but
119167 short enough to decay when the observation is no longer refreshed.
120168
121- The map service should ignore snapshots from a source if their timestamp is
122- older than a newer snapshot that has already been accepted. This prevents a late
123- clear/ reset message from removing obstacle information that came from a newer
169+ The map server ignores snapshots from a source if their timestamp is older than
170+ a newer snapshot that has already been accepted. This prevents a late clear or
171+ reset message from removing obstacle information that came from a newer
124172observation.
125173
126174# Implemented Test Coverage
127175
128- The first server tests cover:
176+ The committed server and demo tests cover:
129177
130178* composing obstacle regions over a static planning grid
131179* point regions with non-zero map origins and non-1.0 resolutions
132180* transforming robot-local regions into the global map frame
133181* out-of-bounds regions, malformed point arrays, and unsupported region types
134- * rejecting updates without a timestamp
182+ * rejecting updates without a timestamp or in a different global frame
135183* pruning expired observations by TTL
136184* clear and obstacle patches in the same update
137185* late older snapshots being ignored
138186* reset updates removing observations from the same source and map
139187* multiple robot sources being stitched into one composed grid
188+ * filtering invalid and out-of-range laser returns
189+ * preserving original beam angles when scan points are sampled
0 commit comments