diff --git a/src/lidar_obstacle_detector_alg_node.cpp b/src/lidar_obstacle_detector_alg_node.cpp
index 8069d8f0ca072af8cc13b834d59febe9503e16b0..e07fa8abf71b17662e3ed2442606397cc0d94d43 100644
--- a/src/lidar_obstacle_detector_alg_node.cpp
+++ b/src/lidar_obstacle_detector_alg_node.cpp
@@ -3,6 +3,8 @@
 #include <math.h>
 #include <opencv2/imgproc.hpp>
 
+#include <algorithm>
+
 LidarObstacleDetectorAlgNode::LidarObstacleDetectorAlgNode(const ros::NodeHandle &nh) :
   algorithm_base::IriBaseAlgorithm<LidarObstacleDetectorAlgorithm>(nh),
   input(new pcl::PointCloud<pcl::PointXYZ>()),
@@ -19,9 +21,6 @@ LidarObstacleDetectorAlgNode::LidarObstacleDetectorAlgNode(const ros::NodeHandle
   this->pointcloud_in_subscriber_ = this->public_node_handle_.subscribe("pointcloud_in", 1, &LidarObstacleDetectorAlgNode::pointcloud_in_callback, this);
   pthread_mutex_init(&this->pointcloud_in_mutex_,NULL);
 
-  this->scan_out_LaserScan_msg_.angle_min=-3.14159;
-  this->scan_out_LaserScan_msg_.angle_max=3.14159;
-  
   this->new_point_cloud=false;
   // [init services]
   
@@ -97,14 +96,17 @@ double LidarObstacleDetectorAlgNode::get_max_inclination(double current_angle,pc
 
 void LidarObstacleDetectorAlgNode::mainNodeThread(void)
 {
-  static bool first=true,success;
+  static bool success;
   static std::vector<float> farthest_ranges,virtual_ranges;
   static double farthest_range,virtual_range;
   static double new_x,new_y;
   static unsigned int prev_col,next_col,prev_ring;
-  static double current_angle;
   static unsigned int last_valid_ring,last_valid_col;
   static int top,left,bottom,right;
+  static double start_angle=0.0,old_start_angle=0.0,start_angle_inc=0.0;
+  double angle=0.0,old_angle=0.0,angle_inc=0.0;
+  double current_angle;
+  unsigned int max_col;
   // current ring points
   static pcl::PointXYZ prev_ring_point,next_ring_point,point;
   static double prev_ring_range,next_ring_range,range;
@@ -157,35 +159,55 @@ void LidarObstacleDetectorAlgNode::mainNodeThread(void)
     }
     else
     {
-      if(first)
+      point=this->transformed_input->at(0,0);
+      if(!isnan(point.x) && !isnan(point.y) && !isnan(point.z))
       {
-        first=false;
-        this->inc_image.create(this->config_.max_ring,this->transformed_input->height,CV_8UC1);
-        this->label_image.create(this->config_.max_ring,this->transformed_input->height,CV_32SC1);
+        old_start_angle=start_angle;
+        start_angle=atan2(point.y,point.x);
+        start_angle_inc=start_angle-old_start_angle;
+        if(start_angle_inc>3.14159)
+          start_angle_inc-=2.0*3.14159;
       }
+      else
+        start_angle+=start_angle_inc;
+      current_angle=start_angle;
+      // initialize sensor messages
+      this->scan_out_LaserScan_msg_.header=this->input_header;
+      this->scan_out_LaserScan_msg_.angle_min=-3.14159;
+      this->scan_out_LaserScan_msg_.angle_max=3.14159;
+      this->scan_out_LaserScan_msg_.angle_increment=(2.0*3.14159-start_angle_inc)/this->transformed_input->height;
+      this->scan_out_LaserScan_msg_.ranges.clear();
+      this->scan_out_LaserScan_msg_.range_min=this->config_.min_range;
+      this->scan_out_LaserScan_msg_.range_max=this->config_.max_range;
+      max_col=(unsigned int)((2.0*3.14159)/this->scan_out_LaserScan_msg_.angle_increment);
+      if(max_col>this->transformed_input->height)
+        max_col=this->transformed_input->height;
+
+      this->inc_image.create(this->config_.max_ring,max_col,CV_8UC1);
+      this->label_image.create(this->config_.max_ring,max_col,CV_32SC1);
       this->lidar_data.clear();
-      this->lidar_data.resize(this->transformed_input->height*this->config_.max_ring);    
+      this->lidar_data.resize(max_col*this->config_.max_ring);    
       // mark all point as not initialized yet
-      for(unsigned int i=0;i<this->transformed_input->height*this->config_.max_ring;i++)
+      for(unsigned int i=0;i<max_col*this->config_.max_ring;i++)
       {
         this->lidar_data[i].init=false;
         this->lidar_data[i].valid=false;
       }
       farthest_ranges.clear();
-      farthest_ranges.resize(this->transformed_input->height,0);
+      farthest_ranges.resize(max_col,0);
       virtual_ranges.clear();
-      virtual_ranges.resize(this->transformed_input->height,this->config_.max_range);
-      for(unsigned int col=0;col<this->transformed_input->height;col++)
+      virtual_ranges.resize(max_col,this->config_.max_range);
+
+      for(unsigned int col=0;col<max_col;col++)
       {
         if(col==0)
-          prev_col=this->transformed_input->height-1;
+          prev_col=max_col-1;
         else
           prev_col=col-1;
-        if(col==this->transformed_input->height-1)
+        if(col==max_col-1)
           next_col=0;
         else
           next_col=col+1;
-        current_angle=col*(360.0/this->transformed_input->height);
         // robot position
         prev_ring_point.x=0.0;
         prev_ring_point.y=0.0;
@@ -194,6 +216,18 @@ void LidarObstacleDetectorAlgNode::mainNodeThread(void)
         prev_ring=-1;
         prev_ring_point_valid=true;
 
+        point=this->transformed_input->at(0,col);
+        if(!isnan(point.x) && !isnan(point.y) && !isnan(point.z))
+        {
+          old_angle=angle;
+          angle=atan2(point.y,point.x);
+          if((angle-old_angle)>3.14159)
+            angle_inc+=(angle-old_angle)-2.0*3.14159;
+          else if((angle-old_angle)<-3.14159)
+            angle_inc+=(angle-old_angle)+2.0*3.14159;
+          else
+            angle_inc+=angle-old_angle;
+        }
         for(unsigned int ring=0;ring<this->config_.max_ring-1;ring++)
         {
           // current point
@@ -263,6 +297,7 @@ void LidarObstacleDetectorAlgNode::mainNodeThread(void)
           prev_ring++;
           prev_ring_point_valid=point_valid;
         }
+        current_angle+=(2.0*3.14159)/max_col;
       }
 
       if(this->config_.virtual_enable)
@@ -275,7 +310,7 @@ void LidarObstacleDetectorAlgNode::mainNodeThread(void)
         cv::inRange(this->inc_image,cv::Scalar(131),cv::Scalar(255),positive_slope);
         cv::morphologyEx(positive_slope,positive_slope,cv::MORPH_OPEN,cv::getStructuringElement(cv::MORPH_RECT,cv::Size(3,3)));
       }
-      for(unsigned int col=0;col<this->transformed_input->height;col++)
+      for(unsigned int col=0;col<max_col;col++)
       {
         if(this->config_.farthest_enable)
         {
@@ -318,16 +353,10 @@ void LidarObstacleDetectorAlgNode::mainNodeThread(void)
         } 
       }
 
-      // initialize sensor messages
-      this->scan_out_LaserScan_msg_.header=this->input_header;
-      this->scan_out_LaserScan_msg_.angle_increment=(3.14159*2.0)/this->transformed_input->height;
-      this->scan_out_LaserScan_msg_.ranges.clear();
-      this->scan_out_LaserScan_msg_.range_min=this->config_.min_range;
-      this->scan_out_LaserScan_msg_.range_max=this->config_.max_range;
       if(this->config_.farthest_enable)
         this->scan_out_LaserScan_msg_.ranges=farthest_ranges;
       else
-        this->scan_out_LaserScan_msg_.ranges.resize(this->transformed_input->height,this->config_.max_range);
+        this->scan_out_LaserScan_msg_.ranges.resize(max_col,this->config_.max_range);
       if(this->config_.virtual_enable)
       {
         for(unsigned int i=0;i<this->scan_out_LaserScan_msg_.ranges.size();i++)
@@ -337,7 +366,7 @@ void LidarObstacleDetectorAlgNode::mainNodeThread(void)
         }
       }
       cv::inRange(this->inc_image,cv::Scalar(128+((unsigned char)(this->config_.max_inc*180.0/3.14159))),cv::Scalar(255),threshold);
-      cv::morphologyEx(threshold,threshold,cv::MORPH_CLOSE,cv::getStructuringElement(cv::MORPH_RECT,cv::Size(3,3)));
+      cv::morphologyEx(threshold,threshold,cv::MORPH_CLOSE,cv::getStructuringElement(cv::MORPH_RECT,cv::Size(11,3)));
       cv::connectedComponentsWithStats(threshold,this->label_image,stats_image,centroid_image,8);
       for(int i=1;i<stats_image.rows;i++)
       {
@@ -365,6 +394,22 @@ void LidarObstacleDetectorAlgNode::mainNodeThread(void)
         if(this->scan_out_LaserScan_msg_.ranges[i]>this->config_.max_range)
           this->scan_out_LaserScan_msg_.ranges[i]=this->config_.max_range;
       }
+      if(angle_inc<0.0)
+      {
+        this->scan_out_LaserScan_msg_.angle_min=0.0;
+        this->scan_out_LaserScan_msg_.angle_max=2.0*3.14159;
+        std::vector<float> ranges=this->scan_out_LaserScan_msg_.ranges;
+        this->scan_out_LaserScan_msg_.ranges.clear();
+        this->scan_out_LaserScan_msg_.ranges.resize(max_col);
+        unsigned int num_swap_samples=((start_angle+3.14159)/this->scan_out_LaserScan_msg_.angle_increment);
+        for(unsigned int i=0;i<ranges.size();i++)
+        {
+          if(i<=num_swap_samples)
+            this->scan_out_LaserScan_msg_.ranges[i]=ranges[num_swap_samples-i];
+          else
+            this->scan_out_LaserScan_msg_.ranges[i]=ranges[max_col-i+num_swap_samples];
+        }
+      }
       if(this->config_.debug && this->obstacles_img_publisher_.getNumSubscribers()>0)
       {
         this->cv_image_=cv_bridge::CvImage(this->input_header, sensor_msgs::image_encodings::MONO8,positive_slope);