# SaltyBot Obstacle Memory Map (Issue #453) Persistent spatial memory system for tracking obstacles and hazards detected by LIDAR. Maintains a 2D occupancy grid that accumulates detections over time with temporal decay. ## Features ### 1. Occupancy Grid Map - **Resolution**: 10cm per cell (configurable) - **Grid Size**: 100×100 cells by default (~10×10 meters centered on robot) - **Cell States**: - **Unknown**: Never observed (-1 in OccupancyGrid) - **Free**: Definitely free space (0% occupancy) - **Obstacle**: Detected obstacle (0–100% based on confidence) - **Hazard**: Persistent hazard with 3+ detections (high confidence) ### 2. Hazard Classification - **Detection-based**: 3+ observations of same location = hazard - **Permanent**: Hazards persist even with temporal decay - **Confidence Tracking**: 0.0–1.0 based on detection history - **Quality Metric**: Increases confidence with repeated detections ### 3. Temporal Decay - **Hazard Decay**: 95% per day (30-day half-life) - Decays slowly due to persistence - Never drops below 30% confidence - **Obstacle Decay**: 85% per day (~21-day half-life) - Faster decay than hazards - Reverts to free space when confidence < 20% - **Decay Interval**: Applied every hour ### 4. LIDAR Integration - **Input**: LaserScan on `/scan` (or `/saltybot/scan`) - **Odometry**: Robot position from `/odom` - **Ray Casting**: Marks hit points as obstacles, intermediate points as free - **Range Filtering**: Configurable min/max range (default 0.1–10.0m) ### 5. ROS2 Navigation Integration - **Output**: `/saltybot/obstacle_map` (nav_msgs/OccupancyGrid) - **Format**: Standard OccupancyGrid for Nav2 costmap - **Frequency**: Published at 5 Hz - **Frame**: Map frame compatible with move_base ### 6. Persistence - **Storage**: YAML file at `/home/seb/saltybot-data/obstacle_map.yaml` - **Format**: Grid metadata + cell states with timestamps - **Auto-Save**: Every 5 minutes (configurable) - **Load on Startup**: Restores previous session's map ## Configuration Edit `config/obstacle_memory.yaml`: ```yaml grid_width: 100 grid_height: 100 grid_resolution: 0.1 map_file: "/home/seb/saltybot-data/obstacle_map.yaml" auto_save_interval: 300.0 scan_max_range: 10.0 scan_min_range: 0.1 publish_rate_hz: 5.0 decay_interval_seconds: 3600.0 ``` ## Running ### Launch the obstacle memory node ```bash ros2 launch saltybot_obstacle_memory obstacle_memory.launch.py ``` ### Direct execution ```bash ros2 run saltybot_obstacle_memory obstacle_memory ``` ## Integration Points 1. **Navigation Stack** (Nav2) - Consumes `/saltybot/obstacle_map` in costmap_2d_ros - Influences pathfinding and local costmap 2. **LIDAR Driver** (e.g., saltybot_sensors) - Publishes `/scan` or `/saltybot/scan` - Ray angles, distances, and timestamp 3. **Odometry Provider** (e.g., wheel encoders + IMU) - Publishes `/odom` - Robot pose (x, y, theta) 4. **Dashboard/WebUI** - Subscribes to `/saltybot/obstacle_map` - Displays as overlay on navigation view - Hazard visualization ## Performance - **Memory**: ~100KB per 100×100 grid - **Computation**: O(n) per LIDAR scan (n = number of rays) - **Persistence**: O(width×height) per save (~1ms for 100×100) - **Decay**: O(width×height) per hour (~5ms for 100×100)