diff --git a/cfg/ObstacleDetectionNormals.cfg b/cfg/ObstacleDetectionNormals.cfg
index 9dade53ba091c164eac7c5c9ffaa9d64dcb9512d..c9c10542f9785ef5e2b1102b72b0ba8f8cf9a0bd 100755
--- a/cfg/ObstacleDetectionNormals.cfg
+++ b/cfg/ObstacleDetectionNormals.cfg
@@ -37,11 +37,11 @@ from dynamic_reconfigure.parameter_generator_catkin import *
 
 gen = ParameterGenerator()
 
-#       Name                       Type       Reconfiguration level            Description                       Default   Min   Max
-#gen.add("velocity_scale_factor",  double_t,  0,                               "Maximum velocity scale factor",  0.5,      0.0,  1.0)
-gen.add(       "filter_min_dist",  double_t,  0,                                      "Min distance threshold",  0.3,        0,  100)
-gen.add(        "normal_KSearch",     int_t,  0,                     "No of neighbors to estimate the surface",  100,       10,  200)
-gen.add(              "normal_x",  double_t,  0, 														  	 "Accepted Normal X component",    1,       )
-gen.add(              "normal_y",  double_t,  0, 															   "Accepted Normal Y component", -0.2,       )
-gen.add(              "normal_z",  double_t,  0, 															   "Accepted Normal Z component",    1,       )
+#       Name                       Type       Reconfiguration level  Description                       Default   Min   Max
+#gen.add("velocity_scale_factor",  double_t,  0,                     "Maximum velocity scale factor",  0.5,      0.0,  1.0)
+gen.add("filter_min_dist",         double_t,  0,                     "Min distance threshold",         0.3,        0,  100)
+gen.add("normal_KSearch",          int_t,     0,                     "No of neighbors to estimate the surface",100,10, 200)
+gen.add("normal_x",                double_t,  0,                     "Accepted Normal X component",    1,)
+gen.add("normal_y",                double_t,  0,                     "Accepted Normal Y component",    -0.2,)
+gen.add("normal_z",                double_t,  0,                     "Accepted Normal Z component",    1,)
 exit(gen.generate(PACKAGE, "ObstacleDetectionNormalsAlgorithm", "ObstacleDetectionNormals"))
diff --git a/config/default_config.yaml b/config/default_config.yaml
new file mode 100755
index 0000000000000000000000000000000000000000..1c13d880ebd6a334ff48f005ecf4b7a2c101730a
--- /dev/null
+++ b/config/default_config.yaml
@@ -0,0 +1,5 @@
+filter_min_dist: 0.3
+normal_KSearchi: 30
+normal_x: 1.001
+normal_y: 1.001
+normal_z: 0.95
diff --git a/include/obstacle_detection_normals_alg.h b/include/obstacle_detection_normals_alg.h
index 7d87c54b10d9525065d3345d60faa27953ae715c..b06d03cebcd9a145d8ea0679528b5075dff790bb 100644
--- a/include/obstacle_detection_normals_alg.h
+++ b/include/obstacle_detection_normals_alg.h
@@ -28,7 +28,6 @@
 #include <iri_nav_obstacle_detection_normals/ObstacleDetectionNormalsConfig.h>
 #include "mutex.h"
 
-
 #include <pcl/point_types.h>
 #include <pcl/io/pcd_io.h>
 #include <pcl/features/normal_3d.h>
@@ -38,10 +37,7 @@
 
 #include <boost/make_shared.hpp>
 
-using namespace pcl;
-using namespace std;
-
-typedef KdTree<PointXYZ>::Ptr KdTreePtr;
+typedef pcl::KdTree<pcl::PointXYZ>::Ptr KdTreePtr;
 
 //include obstacle_detection_normals_alg main library
 
@@ -61,17 +57,8 @@ class ObstacleDetectionNormalsAlgorithm
     */
     CMutex alg_mutex_;
 
-    // private attributes and methods
-    int KSearch;
-    float normal_z,normal_y,normal_x,min_dist;
-
     KdTreePtr tree;
     
-    // pcl::PointCloud<pcl::PointXYZ> cloud;
-    // pcl::PointCloud<pcl::PointXYZRGBNormal> cloud_out;
-    // pcl::PointCloud<pcl::PointXYZRGBNormal> cloud_obs;  
-
-
   public:
    /**
     * \brief define config type
@@ -151,10 +138,9 @@ class ObstacleDetectionNormalsAlgorithm
     //  const pcl::PointCloud<pcl::PointXYZ>& cloud, 
     //  pcl::PointCloud<pcl::PointXYZRGBNormal>& cloud_out, pcl::PointCloud<pcl::PointXYZRGBNormal>& cloud_obs);   
 
-    void cloud_all(int KSearch, float normal_z, 
-     float normal_y, float normal_x, float min_dist, 
-     const pcl::PointCloud<pcl::PointXYZ>& cloud, 
-     pcl::PointCloud<pcl::PointXYZRGBNormal>::Ptr& cloud_out, pcl::PointCloud<pcl::PointXYZRGBNormal>::Ptr& cloud_obs); 
+    void cloud_all(const pcl::PointCloud<pcl::PointXYZ>& cloud, 
+                   pcl::PointCloud<pcl::PointXYZRGBNormal>::Ptr& cloud_out, 
+                   pcl::PointCloud<pcl::PointXYZRGBNormal>::Ptr& cloud_obs); 
 
 };
 
diff --git a/include/obstacle_detection_normals_alg_node.h b/include/obstacle_detection_normals_alg_node.h
index ca13439978356f3d9335044586329d6de4e7bc8b..f121236f5d5b599e5cd3d64fa5f91fe23dc5d9ae 100644
--- a/include/obstacle_detection_normals_alg_node.h
+++ b/include/obstacle_detection_normals_alg_node.h
@@ -54,10 +54,6 @@ using namespace std;
 class ObstacleDetectionNormalsAlgNode : public algorithm_base::IriBaseAlgorithm<ObstacleDetectionNormalsAlgorithm>
 {
   private:
-
-    int KSearch;
-    float normal_z,normal_y,normal_x,min_dist;
-
     // [publisher attributes]
     ros::Publisher obstacles_publisher_;
     ros::Publisher all_rg_publisher_;
@@ -65,8 +61,6 @@ class ObstacleDetectionNormalsAlgNode : public algorithm_base::IriBaseAlgorithm<
     sensor_msgs::PointCloud obstaclespc_msg_;
     sensor_msgs::PointCloud2 all_rg_msg_;
 
-    
-
     // [subscriber attributes]
     ros::Subscriber input_subscriber_;
     void input_callback(const sensor_msgs::PointCloud2::ConstPtr& msg);
diff --git a/launch/node.launch b/launch/node.launch
new file mode 100644
index 0000000000000000000000000000000000000000..bc6ab27b34615632ca9e863e23c6c3da02ff9d4c
--- /dev/null
+++ b/launch/node.launch
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<launch>
+
+  <arg name="ns" default="ana"/>
+  <arg name="node_name" default="obstacle_detection_normals"/>
+  <arg name="config_file" default="$(find iri_nav_obstacle_detection_normals)/config/default_config.yaml"/>
+  <arg name="output" default="screen"/>
+  <arg name="launch_prefix" default=""/>
+  <arg name="cloud_in" default="~pointcloud_in"/>
+
+  <group ns="$(arg ns)">
+
+    <node pkg ="iri_nav_obstacle_detection_normals"
+          type="iri_nav_obstacle_detection_normals"
+          name="$(arg node_name)"
+          output="$(arg output)"
+          launch-prefix="$(arg launch_prefix)">
+      <remap from="~input" to="$(arg cloud_in)"/>
+      <rosparam file="$(arg config_file)" command="load"/>
+    </node>
+
+  </group>
+
+</launch>
diff --git a/launch/nodelet.launch b/launch/nodelet.launch
new file mode 100644
index 0000000000000000000000000000000000000000..6ab197c82095a97b88e5d32c924ec37f16da5240
--- /dev/null
+++ b/launch/nodelet.launch
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<launch>
+
+  <arg name="ns" default="ana"/>
+  <arg name="node_name" default="average_point_cloud"/>
+  <arg name="camera_nodelet_manager" default="camera_nodelet_manager"/>
+  <arg name="config_file" default="$(find iri_nav_average_point_cloud)/config/default_config.yaml"/>
+  <arg name="output" default="screen"/>
+  <arg name="launch_prefix" default=""/>
+  <arg name="cloud_in" default="~pointcloud_in"/>
+
+  <group ns="$(arg ns)">
+
+    <node name="$(arg node_name)"
+          pkg="nodelet"
+          type="nodelet"
+          args="load iri_nav_average_point_cloud/AveragePointcloudAlgNodelet $(arg camera_nodelet_manager)"
+          output="$(arg output)">
+      <remap from="~input" to="$(arg cloud_in)"/>
+      <rosparam file="$(arg config_file)" command="load"/>
+    </node>
+
+  </group>
+
+</launch>
diff --git a/src/obstacle_detection_normals_alg.cpp b/src/obstacle_detection_normals_alg.cpp
index 8ac78fcfe338f0b0f35f8b59389c0587db148017..0cd5795656e2b793582e479959f8278d40c8f52d 100644
--- a/src/obstacle_detection_normals_alg.cpp
+++ b/src/obstacle_detection_normals_alg.cpp
@@ -26,85 +26,36 @@ the KSearch nearest neighbors. After that, it checks that each normal is inside
 some thresholds to determine if it is a passable point or an obstacle. If some point
 is nearer than a minimum distance, it is marked in a diferent color.
 */
-void ObstacleDetectionNormalsAlgorithm::cloud_all(int KSearch, float normal_z,
-     float normal_y, float normal_x, float min_dist,
-     const pcl::PointCloud<pcl::PointXYZ>& cloud,
-     pcl::PointCloud<pcl::PointXYZRGBNormal>::Ptr& cloud_out, pcl::PointCloud<pcl::PointXYZRGBNormal>::Ptr& cloud_obs)
+void ObstacleDetectionNormalsAlgorithm::cloud_all(const pcl::PointCloud<pcl::PointXYZ>& cloud,
+                                                  pcl::PointCloud<pcl::PointXYZRGBNormal>::Ptr& cloud_out, 
+                                                  pcl::PointCloud<pcl::PointXYZRGBNormal>::Ptr& cloud_obs)
 {
+  float e=0.0;
 
-//pcl::PointCloud<pcl::PointXYZ>::Ptr cloud (new pcl::PointCloud<pcl::PointXYZ>);
   // Output datasets
   pcl::PointCloud<pcl::Normal>::Ptr output (new pcl::PointCloud<pcl::Normal>);
 
-// Normal estimation using integral Images /////////////////////////////////////////////
-// NOTE: Point cloud should contain width and height structure
-
-// pcl::IntegralImageNormalEstimation<pcl::PointXYZ, pcl::Normal> n;
-
-// n.setNormalEstimationMethod(n.AVERAGE_3D_GRADIENT);
-// n.setMaxDepthChangeFactor(0.02f);
-// n.setNormalSmoothingSize(10.0f);
-// n.setInputCloud(cloud);
-// n.compute(*output);
-
-// ROS Fuerte version //////////////////////////////////////////////////////////////
-
   // Create the normal estimation class, and pass the input dataset to it
   pcl::NormalEstimation<pcl::PointXYZ, pcl::Normal> n;
-  // [Multi-threat](NOTE: Point cloud should contain width and height structure):
-  // pcl::NormaleEstimationOMP<pcl::PointXYZ, pcl::Normal> n;
-  // n.setNumberOfThreads(8);
-
-  // To work with Pointers ::Ptr ///////////////////////////////////////////////////////////
-  // // Set input cloud
-  // n.setInputCloud (cloud);
-
-  // // Create an empty kdtree representation, and pass it to the normal estimation object.
-  // // Its content will be filled inside the object, based on the given input dataset (as no other search surface is given).
-  // pcl::search::KdTree<pcl::PointXYZ>::Ptr tree (new pcl::search::KdTree<pcl::PointXYZ> ());
-  // n.setSearchMethod (tree);
-
-  // // Use all neighbors in a sphere of radius 3cm
-  // n.setRadiusSearch (KSearch);
-  // // [Multi-threat](NOTE: Point cloud should contain width and height structure) :
-  // // n.setKSearch (KSearch);
-
-  // double secs = ros::Time::now().toSec();
-
-  // // Compute the features
-  // n.compute (*output);
-
-  // pcl::concatenateFields (*cloud, *output, *cloud_out);
-
-  // double secs2 = ros::Time::now().toSec();
-  // double diff = secs2-secs;
-  // ROS_INFO("computation time: %2.2f",diff);
-
-/////////////////////////////////////////////////////////////////////////////////
 
   std::vector<int> indices;
-  indices.resize (cloud.points.size());
-  for (size_t i = 0; i < indices.size (); ++i) { indices[i] = i; }
+  indices.resize(cloud.points.size());
+  for (size_t i = 0; i < indices.size (); ++i) 
+    indices[i] = i;
 
   pcl::search::KdTree<pcl::PointXYZ>::Ptr tree(new pcl::search::KdTree<pcl::PointXYZ>());
 
-
   boost::shared_ptr< vector<int> > indicesptr(new vector<int> (indices));
   // set normal estimation parameters
   n.setIndices(indicesptr);
   n.setSearchMethod(tree);
-  n.setKSearch(KSearch); // Use 10 nearest neighbors to estimate the normals
+  n.setKSearch(this->config_.normal_KSearch);
 
-  //n.setViewPoint (0.26374, 0.0, -0.0485);
   //estimate
   n.setInputCloud(cloud.makeShared());
   n.compute(*output);
 
-  pcl::concatenateFields (cloud, *output, *cloud_out);
-
-
-
-  float e=0.0;
+  pcl::concatenateFields(cloud,*output,*cloud_out);
 
   *cloud_obs=*cloud_out;
 
@@ -112,21 +63,12 @@ void ObstacleDetectionNormalsAlgorithm::cloud_all(int KSearch, float normal_z,
   {
     for (size_t colIndex=0; colIndex<cloud_out->width; ++colIndex, ++pointIndex)
     {
-      //ROS_ERROR_STREAM(cloud_out->points[pointIndex].normal_z);
-      if (cloud_out->points[pointIndex].x > min_dist)
+      if (cloud_out->points[pointIndex].x > this->config_.filter_min_dist)
       {
-				//ROS_INFO_STREAM("z_normal: " << cloud_out->points[pointIndex].normal_z);
-
-        if (abs(cloud_out->points[pointIndex].normal_z) > normal_z &&
-            cloud_out->points[pointIndex].normal_y < normal_y &&
-            cloud_out->points[pointIndex].normal_x < normal_x )
+        if (abs(cloud_out->points[pointIndex].normal_z) > this->config_.normal_z &&
+            cloud_out->points[pointIndex].normal_y < this->config_.normal_y &&
+            cloud_out->points[pointIndex].normal_x < this->config_.normal_x )
         {
-          /*if (pointIndex % 200 == 0)
-          {
-            ROS_INFO_STREAM("x_normal: " << cloud_out->points[pointIndex].normal_x);
-            ROS_INFO_STREAM("y_normal: " << cloud_out->points[pointIndex].normal_y);
-            ROS_INFO_STREAM("z_normal: " << cloud_out->points[pointIndex].normal_z);
-          }*/
           cloud_out->points[pointIndex].r=0;
           cloud_out->points[pointIndex].g=255;
           cloud_out->points[pointIndex].b=0;
@@ -136,13 +78,6 @@ void ObstacleDetectionNormalsAlgorithm::cloud_all(int KSearch, float normal_z,
         }
         else
         {
-          //ROS_ERROR_STREAM("z_normal: " << cloud_out->points[pointIndex].normal_z);
-          /*if (pointIndex % 200 == 0)
-          {
-            ROS_ERROR_STREAM("x_normal: " << cloud_out->points[pointIndex].normal_x);
-            ROS_ERROR_STREAM("y_normal: " << cloud_out->points[pointIndex].normal_y);
-            ROS_ERROR_STREAM("z_normal: " << cloud_out->points[pointIndex].normal_z);
-          }*/
           cloud_out->points[pointIndex].r=255;
           cloud_out->points[pointIndex].g=0;
           cloud_out->points[pointIndex].b=0;
@@ -159,5 +94,4 @@ void ObstacleDetectionNormalsAlgorithm::cloud_all(int KSearch, float normal_z,
     }
   }
   e=(e/float(cloud_out->width*cloud_out->height))*100;
-  //printf("error %f",e);
 }
diff --git a/src/obstacle_detection_normals_alg_node.cpp b/src/obstacle_detection_normals_alg_node.cpp
index da90fc40acd6563774bf9c993bdd3c22cb02009e..dd3f7b6566bb11819df699baa60201b3a780fe78 100644
--- a/src/obstacle_detection_normals_alg_node.cpp
+++ b/src/obstacle_detection_normals_alg_node.cpp
@@ -1,8 +1,7 @@
 #include "obstacle_detection_normals_alg_node.h"
 
 ObstacleDetectionNormalsAlgNode::ObstacleDetectionNormalsAlgNode(void) :
-  algorithm_base::IriBaseAlgorithm<ObstacleDetectionNormalsAlgorithm>(),KSearch(100),normal_z(1),
-  normal_y(-0.2),normal_x(1),min_dist(0.3)
+  algorithm_base::IriBaseAlgorithm<ObstacleDetectionNormalsAlgorithm>()
 {
   //init class attributes if necessary
   //this->loop_rate_ = 2;//in [Hz]
@@ -49,41 +48,21 @@ void ObstacleDetectionNormalsAlgNode::input_callback(const sensor_msgs::PointClo
   // Convert the sensor_msgs/PointCloud2 data to pcl/PointCloud
   pcl::PointCloud<pcl::PointXYZ> cloud;
 
-  // pcl::PointCloud<pcl::PointXYZ> cloud(new pcl::PointCloud<pcl::PointXYZ>());
   pcl::PointCloud<pcl::PointXYZRGBNormal>::Ptr cloud_out(new pcl::PointCloud<pcl::PointXYZRGBNormal>());
   pcl::PointCloud<pcl::PointXYZRGBNormal>::Ptr cloud_obs(new pcl::PointCloud<pcl::PointXYZRGBNormal>());
 
   pcl::fromROSMsg (*msg, cloud);
 
-  // pcl::PointCloud<pcl::PointXYZ> cloud_in;
-  // std::vector<int> indices;
-  // pcl::removeNaNFromPointCloud (cloud, cloud_in, indices);
-  
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-  //use appropiate mutex to shared variables if necessary 
   this->alg_.lock(); 
 
   if (!cloud.empty()){
-    obstacle_detect.cloud_all(KSearch, normal_z, normal_y, normal_x, min_dist, cloud, cloud_out, cloud_obs);
+    obstacle_detect.cloud_all(cloud, cloud_out, cloud_obs);
   }
   //unlock previously blocked shared variables 
   this->alg_.unlock();
 
-//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-
-  // all_rg_msg_.width=msg->width;
-  // all_rg_msg_.height=msg->height;
-  // all_rg_msg_.is_dense=msg->is_dense;
-
-  // obstacles_msg_.header=msg->header;
-  // obstacles_msg_.width=msg->width;
-  // obstacles_msg_.height=msg->height;
-  // obstacles_msg_.is_dense=msg->is_dense;
-
-	pcl::toROSMsg (*cloud_out, all_rg_msg_);
-	pcl::toROSMsg (*cloud_obs, obstacles_msg_);
+  pcl::toROSMsg (*cloud_out, all_rg_msg_);
+  pcl::toROSMsg (*cloud_obs, obstacles_msg_);
 
   sensor_msgs::convertPointCloud2ToPointCloud(obstacles_msg_, obstaclespc_msg_);
   
@@ -91,17 +70,6 @@ void ObstacleDetectionNormalsAlgNode::input_callback(const sensor_msgs::PointClo
 
   this->obstacles_publisher_.publish(this->obstaclespc_msg_);
   this->all_rg_publisher_.publish(this->all_rg_msg_);
-
-  
-  //use appropiate mutex to shared variables if necessary 
-  //this->alg_.lock(); 
-  //this->input_mutex_.enter(); 
-
-  //std::cout << msg->data << std::endl; 
-
-  //unlock previously blocked shared variables 
-  //this->alg_.unlock(); 
-  //this->input_mutex_.exit(); 
 }
 
 /*  [service callbacks] */
@@ -112,13 +80,6 @@ void ObstacleDetectionNormalsAlgNode::input_callback(const sensor_msgs::PointClo
 
 void ObstacleDetectionNormalsAlgNode::node_config_update(Config &config, uint32_t level)
 {
-  this->alg_.lock();
-min_dist=config.filter_min_dist;
-KSearch=config.normal_KSearch;
-normal_z=config.normal_z;
-normal_y=config.normal_y;
-normal_x=config.normal_x;
-  this->alg_.unlock();
 }
 
 void ObstacleDetectionNormalsAlgNode::addNodeDiagnostics(void)