diff --git a/include/publisher_laser_map.h b/include/publisher_laser_map.h
index 9471795421100679fca08bde46583876776bc6a1..58fd1d79e2d71cacef4240e81c791e24d139e26b 100644
--- a/include/publisher_laser_map.h
+++ b/include/publisher_laser_map.h
@@ -59,6 +59,7 @@ class PublisherLaserMap: public Publisher
     protected:
 
         double update_dist_th_, update_angle_th_;
+        bool recompute_on_frame_removal_;
         SensorBaseConstPtr sensor_;
 
         // OCCUPANCY MAP parameters and auxiliar variables
@@ -79,7 +80,8 @@ class PublisherLaserMap: public Publisher
         int pc_r_, pc_g_, pc_b_;
 
         // std::maps
-        std::map<FrameBaseConstPtr,std::list<ScanData>> scans_;
+        std::map<FrameBaseConstPtr,std::map<CaptureLaser2dConstPtr, ScanData>> scans_;
+        std::set<CaptureLaser2dConstPtr> last_captures_occ_, last_captures_pc_;
         std::map<FrameBaseConstPtr,Eigen::Vector3d> current_trajectory_, last_trajectory_occ_, last_trajectory_pc_;
 
 
@@ -99,6 +101,9 @@ class PublisherLaserMap: public Publisher
                                const std::map<FrameBaseConstPtr,Eigen::Vector3d>& _current_trajectory) const;
         void storeScan(FrameBaseConstPtr frame, CaptureLaser2dConstPtr capture);
 
+        bool renderingOccMap() const;
+        bool renderingPcMap() const;
+
         // occmap
         void resetOccMap();
         bool updateOccMap();
@@ -129,5 +134,17 @@ inline Eigen::Vector2i PublisherLaserMap::vectorToCell(const Eigen::DenseBase<T>
     return cell;
 }
 
+inline bool PublisherLaserMap::renderingOccMap() const
+{
+    return publisher_.getNumSubscribers() == 0;
+}
+
+inline bool PublisherLaserMap::renderingPcMap() const
+{
+    return publisher_pc_.getNumSubscribers() == 0;
+}
+
+
+
 }
 #endif
diff --git a/src/publisher_laser_map.cpp b/src/publisher_laser_map.cpp
index 50c1452996e2ee6e5cc2427d365706cb641faf66..7d384c55d3ece8d9b1c2f073fa25a04fee544deb 100644
--- a/src/publisher_laser_map.cpp
+++ b/src/publisher_laser_map.cpp
@@ -30,6 +30,7 @@
 #include <pcl_ros/transforms.h>
 
 #include <limits>
+#include <set>
 
 namespace wolf
 {
@@ -55,6 +56,7 @@ PublisherLaserMap::PublisherLaserMap(const std::string& _unique_name,
         sensor_ = _problem->findSensor(sensor_name);
         WOLF_WARN_COND(not sensor_, "PublisherLaserMap: Sensor name not found: ", sensor_name);
     }
+    recompute_on_frame_removal_ = getParamWithDefault<bool>     (_server, prefix_ + "/recompute_on_frame_removal", false);
 
     // occmap params
     occ_msg_.header.frame_id    = _server.getParam<std::string> (prefix_ + "/map_frame_id");
@@ -138,8 +140,10 @@ void PublisherLaserMap::publishDerived()
 
 void PublisherLaserMap::updateTrajectory()
 {
-    current_trajectory_.clear();
-    scans_.clear();
+    // store old frames to know which were removed
+    std::set<FrameBaseConstPtr> removed_frames;
+    for (auto frame_pos : current_trajectory_)
+        removed_frames.insert(frame_pos.first);
 
     // copy new trajectory poses and scans
     auto frame_map = problem_->getTrajectory()->getFrameMap();
@@ -148,32 +152,56 @@ void PublisherLaserMap::updateTrajectory()
         if (frame_pair.second->isRemoving())
             continue;
 
-        // insert frame to maps
+        // frame not removed
+        removed_frames.erase(frame_pair.second);
+
+        // insert/modify frame pose
         current_trajectory_[frame_pair.second] = frame_pair.second->getState("PO").vector("PO");
-        scans_[frame_pair.second] = std::list<ScanData>();
 
         // search all CaptureLaser2d
         auto cap_list = frame_pair.second->getCaptureList();
         for (auto cap : cap_list)
         {
             auto cap_laser = std::dynamic_pointer_cast<const CaptureLaser2d>(cap);
-            if (cap_laser and 
-                not cap_laser->isRemoving() and
-                (not sensor_ or cap_laser->getSensor() == sensor_))
+
+            // add scan if...
+            if (// ...not null
+                cap_laser and 
+                // ...not removing
+                not cap_laser->isRemoving() and 
+                // ...from specified sensor (if specified)
+                (not sensor_ or cap_laser->getSensor() == sensor_) and 
+                // ...not stored already
+                (not scans_.count(frame_pair.second) or not scans_.at(frame_pair.second).count(cap_laser))) 
                 storeScan(frame_pair.second, cap_laser);
         }
 
         // remove frames without scans
-        if (scans_.at(frame_pair.second).empty())
+        if (scans_.count(frame_pair.second) and scans_.at(frame_pair.second).empty())
         {
             scans_.erase(frame_pair.second);
             current_trajectory_.erase(frame_pair.second);
         }
     }
+
+    // remove removed frames from scans and trajectory
+    for (auto removed_frm : removed_frames)
+    {
+        current_trajectory_.erase(removed_frm);
+        scans_.erase(removed_frm);
+    }
 }
 
 void PublisherLaserMap::storeScan(FrameBaseConstPtr frame, CaptureLaser2dConstPtr capture)
 {
+    if (not capture or 
+        not capture->getSensor() or 
+        not capture->getSensor()->getP() or
+        not capture->getSensor()->getO() or
+        capture->getSensor()->getP()->getState().size() != 2 or
+        capture->getSensor()->getO()->getState().size() != 1)
+        return;
+
     ScanData scan_data;
     scan_data.capture_ = capture;
     scan_data.params_ = std::static_pointer_cast<const SensorLaser2d>(capture->getSensor())->getScanParams();
@@ -197,13 +225,6 @@ void PublisherLaserMap::storeScan(FrameBaseConstPtr frame, CaptureLaser2dConstPt
     scan_data.local_points_.row(0) = orientations.cos() * ranges_filtered + laser_extrinsics_p(0);
     scan_data.local_points_.row(1) = orientations.sin() * ranges_filtered + laser_extrinsics_p(1);
     
-    // // discard max range (optionally)
-    // if (discard_max_range_)
-    // {
-    //     scan_data.local_points_.row(0) = (ranges < scan_data.params_.range_max_-1e-3).select(scan_data.local_points_.row(0), 0.0);
-    //     scan_data.local_points_.row(1) = (ranges < scan_data.params_.range_max_-1e-3).select(scan_data.local_points_.row(1), 0.0);
-    // }
-
     // local pointcloud
     scan_data.local_pc_ = pcl::PointCloud<pcl::PointXYZRGB>(ranges.size(),
                                                             1,
@@ -220,8 +241,11 @@ void PublisherLaserMap::storeScan(FrameBaseConstPtr frame, CaptureLaser2dConstPt
         }
     }
 
+    // insert scan if not exist
+    if (not scans_.count(frame))
+        scans_[frame] = std::map<CaptureLaser2dConstPtr, ScanData>();
     // store data
-    scans_.at(frame).push_back(scan_data);
+    scans_.at(frame).emplace(capture, scan_data);
 }
 
 bool PublisherLaserMap::trajectoryChanged(const std::map<FrameBaseConstPtr,Eigen::Vector3d>& _last_trajectory,
@@ -233,17 +257,17 @@ bool PublisherLaserMap::trajectoryChanged(const std::map<FrameBaseConstPtr,Eigen
         // any old frame was removed -> recompute
         if (_current_trajectory.count(frame_pos.first) == 0)
         {
-            WOLF_INFO("PublisherLaserMap::trajectoryChanged: Any old frame was removed. Recomputing from scratch");
-            return true;
+            WOLF_INFO_COND(recompute_on_frame_removal_, "PublisherLaserMap::trajectoryChanged: Any old frame was removed. Recomputing from scratch");
+            if (recompute_on_frame_removal_)
+                return true;
+            else
+                continue;
         }
 
         // any old frame moved significantly (angle or position) -> recompute occupancy map
         const Eigen::Vector3d& old_frame_pos = frame_pos.second;
         const Eigen::Vector3d& new_frame_pos = _current_trajectory.at(frame_pos.first);
 
-        //std::cout << "old_frame_pos " << old_frame_pos.transpose() << std::endl;
-        //std::cout << "new_frame_pos " << new_frame_pos.transpose() << std::endl;
-
         if ((old_frame_pos-new_frame_pos).head<2>().norm() > update_dist_th_ or
             std::abs(old_frame_pos(2)-new_frame_pos(2)) > update_angle_th_)
         {
@@ -261,30 +285,39 @@ void PublisherLaserMap::resetOccMap()
     // Reset logodds_grid_
     logodds_array_ = Eigen::Array<double, Eigen::Dynamic, Eigen::Dynamic, Eigen::ColMajor>::Zero(n_cells_(0),n_cells_(1));
 
-    // reset last trajectory poses
+    // reset last trajectory poses and captures
     last_trajectory_occ_.clear();
+    last_captures_occ_.clear();
 }
 
 bool PublisherLaserMap::updateOccMap()
 {
     bool updated = false;
 
-    // Update the map with captures of frames in trajectory_poses_ that are not in last_trajectory_occ_
-    for (auto frame_pose : current_trajectory_)
+    // Update the map with captures in scans_ that are not in last_captures_occ_
+    for (auto scan_pair : scans_)
     {
-        if (last_trajectory_occ_.count(frame_pose.first) == 1)
-            continue;
+        // add frame to last_trajectory_occ_
+        if (not last_trajectory_occ_.count(scan_pair.first))
+        {    
+            WOLF_DEBUG("Frame ", scan_pair.first->id(), " not in last_trajectory_occ_, adding its pose");
 
-        WOLF_DEBUG("Frame ", frame_pose.first->id(), " not in last_trajectory_occ_, adding ", scans_.at(frame_pose.first).size(), " scans to map");
-
-        // add trajectory pose
-        last_trajectory_occ_[frame_pose.first] = frame_pose.second;
-
-        // add all scans of the frame the map
-        for (auto scan_data : scans_.at(frame_pose.first))
-            addScanToOccMap(scan_data, frame_pose.second);
+            last_trajectory_occ_[scan_pair.first] = current_trajectory_.at(scan_pair.first);
+            updated = true;
+        }
 
-        updated = true;
+        // update occmap with new scans
+        for (auto capture_pair : scan_pair.second)
+        {
+            if (last_captures_occ_.count(capture_pair.first))
+                continue;
+            
+            WOLF_DEBUG("Capture ", capture_pair.first->id(), " not in last_captures_occ_, adding it to map");
+
+            last_captures_occ_.insert(capture_pair.first);
+            addScanToOccMap(capture_pair.second, last_trajectory_occ_.at(scan_pair.first));
+            updated = true;
+        }
     }
 
     WOLF_DEBUG("PublisherLaserMap::updateOccMap updated = ", (updated ? "true" : "false"));
@@ -481,28 +514,37 @@ void PublisherLaserMap::resetPcMap()
 
     // reset last trajectory poses
     last_trajectory_pc_.clear();
+    last_captures_pc_.clear();
 }
 
 bool PublisherLaserMap::updatePcMap()
 {
     bool updated = false;
 
-    // Update the map with captures of frames in trajectory_poses_ that are not in last_trajectory_pc_
-    for (auto frame_pose : current_trajectory_)
+    // Update the map with captures in scans_ that are not in last_captures_pc_
+    for (auto scan_pair : scans_)
     {
-        if (last_trajectory_pc_.count(frame_pose.first) == 1)
-            continue;
+        // add frame to last_trajectory_pc_
+        if (not last_trajectory_pc_.count(scan_pair.first))
+        {    
+            WOLF_DEBUG("Frame ", scan_pair.first->id(), " not in last_trajectory_pc_, adding its pose");
 
-        WOLF_DEBUG("Frame ", frame_pose.first->id(), " not in last_trajectory_pc_, adding ", scans_.at(frame_pose.first).size(), " scans to pointcloud");
-
-        // add trajectory pose
-        last_trajectory_pc_[frame_pose.first] = frame_pose.second;
-
-        // add all scans of the frame the map
-        for (auto cap_laser : scans_.at(frame_pose.first))
-            addScanToPcMap(cap_laser, frame_pose.second);
+            last_trajectory_pc_[scan_pair.first] = current_trajectory_.at(scan_pair.first);
+            updated = true;
+        }
 
-        updated = true;
+        // update aggregated pointcloud with new scans
+        for (auto capture_pair : scan_pair.second)
+        {
+            if (last_captures_pc_.count(capture_pair.first))
+                continue;
+            
+            WOLF_DEBUG("Capture ", capture_pair.first->id(), " not in last_captures_pc_, adding it to map");
+
+            last_captures_pc_.insert(capture_pair.first);
+            addScanToPcMap(capture_pair.second, last_trajectory_pc_.at(scan_pair.first));
+            updated = true;
+        }
     }
 
     WOLF_DEBUG("PublisherLaserMap::updatePcMap updated = ", (updated ? "true" : "false"));