diff --git a/CMakeLists.txt b/CMakeLists.txt
index 926896be739aa4dd14a226a1e37a3985819f43f6..9bb3939bbdb57c22676e1de090256e30b34cbc54 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -1,10 +1,12 @@
 cmake_minimum_required(VERSION 2.8.3)
 project(iri_base_driver)
 
+set(CMAKE_BUILD_TYPE "DEBUG")
+
 ## Find catkin macros and libraries
 ## if COMPONENTS list like find_package(catkin REQUIRED COMPONENTS xyz)
 ## is used, also find other catkin packages
-find_package(catkin REQUIRED)
+find_package(catkin REQUIRED COMPONENTS roscpp dynamic_reconfigure message_generation)
 
 ## System dependencies are found with CMake's conventions
 # find_package(Boost REQUIRED COMPONENTS system)
@@ -39,11 +41,10 @@ find_package(catkin REQUIRED)
 ##   * add every package in MSG_DEP_SET to generate_messages(DEPENDENCIES ...)
 
 ## Generate messages in the 'msg' folder
-# add_message_files(
-#   FILES
-#   Message1.msg
-#   Message2.msg
-# )
+add_message_files(
+  FILES
+  SensorLevels.msg
+)
 
 ## Generate services in the 'srv' folder
 # add_service_files(
@@ -60,10 +61,10 @@ find_package(catkin REQUIRED)
 # )
 
 ## Generate added messages and services with any dependencies listed here
-# generate_messages(
-#   DEPENDENCIES
-#   std_msgs  # Or other packages containing msgs
-# )
+generate_messages(
+  DEPENDENCIES
+  std_msgs  # Or other packages containing msgs
+)
 
 ###################################
 ## catkin specific configuration ##
@@ -77,7 +78,7 @@ find_package(catkin REQUIRED)
 catkin_package(
   INCLUDE_DIRS include
   LIBRARIES ${PROJECT_NAME}
-  CATKIN_DEPENDS roscpp driver_base dynamic_reconfigure
+  CATKIN_DEPENDS roscpp dynamic_reconfigure message_runtime
 #  DEPENDS system_lib
 )
 
@@ -89,12 +90,14 @@ catkin_package(
 ## Your package locations should be listed before other locations
 # include_directories(include)
 INCLUDE_DIRECTORIES(include)
+include_directories(${catkin_INCLUDE_DIRS})
 
 ## Declare a cpp library
 # add_library(foo
 #   src/${PROJECT_NAME}/foo.cpp
 # )
 add_library(${PROJECT_NAME} src/iri_base_driver.cpp)
+target_link_libraries(${PROJECT_NAME} ${catkin_LIBRARIES})
 
 ## Declare a cpp executable
 # add_executable(foo_node src/foo_node.cpp)
@@ -102,6 +105,7 @@ add_library(${PROJECT_NAME} src/iri_base_driver.cpp)
 ## Add cmake target dependencies of the executable/library
 ## as an example, message headers may need to be generated before nodes
 # add_dependencies(foo_node foo_generate_messages_cpp)
+add_dependencies(${PROJECT_NAME} ${${PROJECT_NAME}_EXPORTED_TARGETS})
 
 ## Specify libraries to link a library or executable target against
 # target_link_libraries(foo_node
diff --git a/include/iri_base_driver/iri_base_driver.h b/include/iri_base_driver/iri_base_driver.h
index 90d5cac9a19a3240932fe71af64f580ee45f14d1..137b8053093ba6b669915dbe5cc96f0ec6f73597 100644
--- a/include/iri_base_driver/iri_base_driver.h
+++ b/include/iri_base_driver/iri_base_driver.h
@@ -20,12 +20,16 @@
 #define _IRI_BASE_DRIVER_H
 
 // ros base driver class
-#include "driver_base/driver.h"
 #include "ros/ros.h"
 
+// boost libraries
+#include <boost/function.hpp>
+
 namespace iri_base_driver
 {
 
+typedef enum {CLOSED=0,OPENED=1,RUNNING=2} state_t;
+
 /**
  * \brief IRI ROS Base Driver Class
  *
@@ -48,16 +52,10 @@ namespace iri_base_driver
  * through ROS topics by using those scripts. The scripts can be downloaded 
  * from the iri_stack SVN.
  */
-class IriBaseDriver : public driver_base::Driver
+class IriBaseDriver
 {
-  protected:
-   /**
-    * \brief driver unique identifier
-    *
-    * This value is used to identify each driver. Must be set before changing
-    * the driver_base::state=run. Use the abstract function setDriverId().
-    */
-    std::string driver_id_;
+  private:
+    state_t current_state_;
 
     /**
      * \brief  variable to handle the mutual exclusion mechanism
@@ -69,6 +67,23 @@ class IriBaseDriver : public driver_base::Driver
      */
     pthread_mutex_t access_;
 
+    pthread_mutex_t internal_access_;
+
+    boost::function< void() > postOpenHook;
+
+    boost::function< void() > preCloseHook;
+
+   /**
+    * \brief driver unique identifier
+    *
+    * This value is used to identify each driver. Must be set before changing
+    * the driver_base::state=run. Use the abstract function setDriverId().
+    */
+    std::string driver_id_;
+
+    std::string last_message;
+
+  protected:
    /**
     * \brief Set Driver Id
     *
@@ -80,9 +95,6 @@ class IriBaseDriver : public driver_base::Driver
     */
     void setDriverId(const std::string & id);
 
-//     typedef boost::function< void() > hookFunction;
-    hookFunction preCloseHook;
-
   public:
    /**
     * \brief Constructor
@@ -115,42 +127,6 @@ class IriBaseDriver : public driver_base::Driver
     */
     bool try_enter(void);
 
-   /**
-    * \brief Generic Open Driver
-    *
-    * Currently only changes the ROS driver state to open and calls the abstract 
-    * function openDriver(). Common actions required for opening any kind of 
-    * drivers should be added here.
-    */
-    void doOpen(void);
-
-   /**
-    * \brief Generic Close Driver
-    *
-    * Currently only changes the ROS driver state to close and calls the abstract
-    * function closeDriver(). Common actions required for opening any kind of 
-    * drivers should be added here.
-    */
-    void doClose(void);
-
-   /**
-    * \brief Generic Start Driver
-    *
-    * Currently only changes the ROS driver state to start and calls the abstract
-    * function startDriver().Common actions required for opening any kind of 
-    * drivers should be added here.
-    */
-    void doStart(void);
-
-   /**
-    * \brief Generic Stop Driver
-    *
-    * Currently only changes the ROS driver state to stop and calls the abstract 
-    * function stopDriver(). Common actions required for opening any kind of 
-    * drivers should be added here.
-    */
-    void doStop(void);
-
    /**
     * \brief Get Driver Id
     *
@@ -162,6 +138,22 @@ class IriBaseDriver : public driver_base::Driver
     */
     std::string getID(void);
 
+    bool goState(state_t target_state);
+
+    state_t getState(void);
+
+    std::string getStateName(void);
+
+    std::string getStatusMessage(void);
+
+    bool isRunning(void);
+
+    bool isOpened(void);
+
+    bool isClosed(void);
+
+    bool isStopped(void);
+
    /**
     * \brief User Open Driver
     *
@@ -204,8 +196,9 @@ class IriBaseDriver : public driver_base::Driver
     */
     virtual bool stopDriver(void) = 0;
     
-    
-    void setPreCloseHook(hookFunction f);
+    void setPostOpenHook(boost::function< void() > function);
+
+    void setPreCloseHook(boost::function< void() > function);
 
    /**
     * \brief Destructor
diff --git a/include/iri_base_driver/iri_base_driver_node.h b/include/iri_base_driver/iri_base_driver_node.h
index cdbee840ac9b6f4debd347d564575d98843f0b4a..00b21355a9e31577782c3ef6ee29cd9d615df54b 100644
--- a/include/iri_base_driver/iri_base_driver_node.h
+++ b/include/iri_base_driver/iri_base_driver_node.h
@@ -19,19 +19,50 @@
 #ifndef _IRI_BASE_DRIVER_NODE_H
 #define _IRI_BASE_DRIVER_NODE_H
 
-// ros base driver node, diagnostics, and iri_ros driver
-#include <driver_base/driver_node.h>
+#include <ros/ros.h>
+#include <signal.h>
+
+// boost thread includes for ROS::spin thread
+#include <boost/thread.hpp>
+#include <boost/bind.hpp>
+
+// dynamic reconfigure server include
+#include <dynamic_reconfigure/server.h>
+#include <iri_base_driver/SensorLevels.h>
+
+// diagnostic updater include
 #include <diagnostic_updater/diagnostic_updater.h>
-#include "iri_base_driver.h"
+
+#include "iri_base_driver/iri_base_driver.h"
 
 namespace iri_base_driver
 {
+/**
+ * \brief Abstract Class for Ctrl+C management
+ *
+ */
+class AbstractDriverNode
+{
+  protected:
+
+    static void hupCalled(int sig)
+    {
+      ROS_WARN("Unexpected SIGHUP caught. Ignoring it.");
+    }
+};
+
+ /**
+  * \brief default main thread frequency
+  * 
+  * This constant determines the default frequency of the mainThread() in HZ.
+  * All nodes will loop at this rate if loop_rate_ variable is not modified.
+  */
+  static const double DEFAULT_RATE = 10.0; //[Hz]
 
 /**
  * \brief IRI ROS Base Node Class
  *
- * This class inherits from the ROS class driver_base::DriverNode<TemplateDriver> 
- * to provide an execution thread to the driver object. The TemplateDriver object
+ * This class provides the base class for any ROS driver. The Driver object
  * must be an implementation of the IriBaseDriver class. The inherit template
  * design form allows complete access to the driver object while manteining 
  * flexibility to instantiate any object inherit from IriBaseDriver.
@@ -58,55 +89,36 @@ namespace iri_base_driver
  * from the iri_stack SVN.
  */
 template <class Driver>
-class IriBaseNodeDriver : public driver_base::DriverNode<Driver>
+class IriBaseNodeDriver : public AbstractDriverNode
 {
-  protected:
-    /**
-     * \brief Thread information structure
-     *
-     * This structure hold system level information of the thread and it is 
-     * initialized when the thread is first created. This information can not 
-     * be modified at any time and it is not accessible from outside the class.
-     *
-     */
-    pthread_t thread;
-
-   /**
-    * \brief main node post open hook
-    *
-    * This function sets the common parameters for all drivers which might be
-    * tuned for the ROS dynamic reconfigure application.
-    */
-    void postOpenHook(void);
-
-   /**
-    * \brief node implementation post open hook
-    * 
-    * Abstrac function called by postOpenHook() that adds the specific driver
-    * node parameters to the dynamic reconfigure application.
-    */
-    virtual void postNodeOpenHook(void) = 0;
-
+  public:
    /**
-    * \brief main node pre close hook
+    * \brief config object
     *
+    * All template driver class will need a Config variable to allow ROS
+    * dynamic reconfigure. This config class will contain all driver
+    * parameters which may be modified once the driver node is launched.
     */
-    void preCloseHook(void);
+    typedef typename Driver::Config Config;
 
+  private:
    /**
-    * \brief node implementation pre close hook
+    * \brief ros spin thread
     * 
+    * This boost thread object will manage the ros::spin function. It is 
+    * instantiated and launched in the spin class method.
     */
-    virtual void preNodeCloseHook(void);
+    boost::shared_ptr<boost::thread> spin_thread_;
 
-   /**
-    * \brief public node handle communication object
-    *
-    * This node handle is going to be used to create topics and services within
-    * the node namespace. Additional node handles can be instantatied if 
-    * additional namespaces are needed.
-    */
-    ros::NodeHandle public_node_handle_;
+    /**
+     * \brief Thread information structure
+     *
+     * This structure hold system level information of the thread and it is 
+     * initialized when the thread is first created. This information can not 
+     * be modified at any time and it is not accessible from outside the class.
+     *
+     */
+    pthread_t main_thread;
 
    /**
     * \brief main thread loop rate
@@ -119,31 +131,38 @@ class IriBaseNodeDriver : public driver_base::DriverNode<Driver>
     ros::Rate loop_rate_;
 
    /**
-    * \brief default main thread frequency
+    * \brief 
     * 
-    * This constant determines the default frequency of the mainThread() in HZ.
-    * All nodes will loop at this rate if loop_rate_ variable is not modified.
     */
-    static const unsigned int DEFAULT_RATE = 10; //[Hz]
+    diagnostic_updater::FunctionDiagnosticTask driver_status_standard_diagnostic_;
 
-  public:
    /**
-    * \brief constructor
+    * \brief main node post open hook
     *
-    * This constructor creates and initializes the main thread of the class. It 
-    * also sets the driver_base::postOpenHook thread. NodeHandle and loop_rate_
-    * variables are also initialized.
+    * This function sets the common parameters for all drivers which might be
+    * tuned for the ROS dynamic reconfigure application.
+    */
+    void postOpenHook(void);
+
+   /**
+    * \brief main node pre close hook
     *
-    * \param nh a reference to the node handle object to manage all ROS topics.
     */
-    IriBaseNodeDriver(ros::NodeHandle& nh);
+    void preCloseHook(void);
 
    /**
-    * \brief destructor
+    * \brief dynamic reconfigure server callback
+    * 
+    * This method is called whenever a new configuration is received through
+    * the dynamic reconfigure. The derivated generic driver class must 
+    * implement it.
     *
-    * This destructor closes the driver object and kills the main thread.
+    * \param config an object with new configuration from all algorithm 
+    *               parameters defined in the config file.
+    * \param level  integer referring the level in which the configuration
+    *               has been changed.
     */
-    ~IriBaseNodeDriver();
+    void reconfigureCallback(Config &config, uint32_t level);
 
    /**
     * \brief main node add diagnostics
@@ -153,70 +172,91 @@ class IriBaseNodeDriver : public driver_base::DriverNode<Driver>
     */
     void addDiagnostics(void);
 
+  protected:
    /**
-    * \brief open status driver main node tests
+    * \brief template driver class
     *
-    * In this function tests checking driver's functionallity in driver_base
-    * status=open can be added.
+    * This template class refers to an implementation of an specific driver
+    * interface. Will be used in the derivate class to define the common 
+    * behaviour for all the different implementations from the same driver.
     */
-    void addOpenedTests(void);
+    Driver driver_;
 
    /**
-    * \brief stop status driver main node tests
+    * \brief public node handle communication object
     *
-    * In this function tests checking driver's functionallity in driver_base
-    * status=stop can be added.
+    * This node handle is going to be used to create topics and services within
+    * the node namespace. Additional node handles can be instantatied if 
+    * additional namespaces are needed.
     */
-    void addStoppedTests(void);
+    ros::NodeHandle public_node_handle_;
 
    /**
-    * \brief run status driver main node tests
+    * \brief private node handle object
     *
-    * In this function tests checking driver's functionallity in driver_base
-    * status=run can be added.
+    * This private node handle will be used to define algorithm parameters into
+    * the ROS parametre server. For communication pruposes please use the 
+    * previously defined node_handle_ object.
     */
-    void addRunningTests(void);
+    ros::NodeHandle private_node_handle_;
 
    /**
-    * \brief main node dynamic reconfigure
-    *
+    * \brief dynamic reconfigure server
     * 
-    * \param level integer
+    * The dynamic reconfigure server is in charge to retrieve the parameters
+    * defined in the config cfg file through the reconfigureCallback.
     */
-    void reconfigureHook(int level);
+    dynamic_reconfigure::Server<Config> dsrv_;
 
-  protected:
    /**
-    * \brief node add diagnostics
-    *
-    * In this abstract function additional ROS diagnostics applied to the 
-    * specific node may be added.
+    * \brief diagnostic updater
+    * 
+    * The diagnostic updater allows definition of custom diagnostics. 
+    * 
     */
-    virtual void addNodeDiagnostics(void) = 0;
+    diagnostic_updater::Updater diagnostic_;
 
    /**
-    * \brief open status driver specific node tests
-    *
-    * In this abstract function tests checking driver's functionallity in 
-    * driver_base status=open can be added.
+    * \brief 
+    * 
     */
-    virtual void addNodeOpenedTests(void) = 0;
+    void statusDiagnostic(diagnostic_updater::DiagnosticStatusWrapper& stat);
 
    /**
-    * \brief stop status driver specific node tests
+    * \brief node implementation post open hook
+    * 
+    * Abstrac function called by postOpenHook() that adds the specific driver
+    * node parameters to the dynamic reconfigure application.
+    */
+    virtual void postNodeOpenHook(void) = 0;
+
+   /**
+    * \brief node implementation pre close hook
+    * 
+    */
+    virtual void preNodeCloseHook(void);
+
+   /**
+    * \brief dynamic reconfigure server callback
+    * 
+    * This method is called whenever a new configuration is received through
+    * the dynamic reconfigure. The derivated generic driver class must 
+    * implement it.
     *
-    * In this abstract function tests checking driver's functionallity in 
-    * driver_base status=stop can be added.
+    * \param config an object with new configuration from all algorithm 
+    *               parameters defined in the config file.
+    * \param level  integer referring the level in which the configuration
+    *               has been changed.
     */
-    virtual void addNodeStoppedTests(void) = 0;
+    virtual void node_config_update(Config &config, uint32_t level);
 
    /**
-    * \brief run status driver specific node tests
+    * \brief node add diagnostics
     *
-    * In this abstract function tests checking driver's functionallity in
-    * driver_base status=run can be added.
+    * In this abstract function additional ROS diagnostics applied to the 
+    * specific node may be added.
     */
-    virtual void addNodeRunningTests(void) = 0;
+    virtual void addNodeDiagnostics(void) = 0;
 
    /**
     * \brief main node thread
@@ -242,27 +282,61 @@ class IriBaseNodeDriver : public driver_base::DriverNode<Driver>
     virtual void mainNodeThread(void) = 0;
 
    /**
-    * \brief specific node dynamic reconfigure
+    * \brief 
+    * 
+    */
+    void setRate(double rate_hz);
+
+   /**
+    * \brief 
+    * 
+    */
+    double getRate(void);
+
+  public:
+
+   /**
+    * \brief constructor
+    *
+    * This constructor creates and initializes the main thread of the class. It 
+    * also sets the driver_base::postOpenHook thread. NodeHandle and loop_rate_
+    * variables are also initialized.
     *
-    * This function is called reconfigureHook()
+    */
+    IriBaseNodeDriver(ros::NodeHandle &nh);
+
+   /**
+    * \brief spin
     * 
-    * \param level integer
+    * This method is meant to spin the node to update all ROS features. It also
+    * launches de main thread. Once the object is instantiated, it will not 
+    * start iterating until this method is called.
+    */
+    int spin(void);
+
+   /**
+    * \brief destructor
+    *
+    * This destructor closes the driver object and kills the main thread.
     */
-    virtual void reconfigureNodeHook(int level) = 0;
+    ~IriBaseNodeDriver();
 };
 
 template <class Driver>
 IriBaseNodeDriver<Driver>::IriBaseNodeDriver(ros::NodeHandle &nh) : 
-  driver_base::DriverNode<Driver>(nh), 
-  public_node_handle_(ros::this_node::getName()),
-  loop_rate_(DEFAULT_RATE)
+  public_node_handle_(nh),
+  loop_rate_(DEFAULT_RATE),
+  diagnostic_(),
+  dsrv_(private_node_handle_),
+  private_node_handle_("~"),
+  driver_status_standard_diagnostic_("Driver Status", boost::bind(&IriBaseNodeDriver::statusDiagnostic, this, _1))
 {
   ROS_DEBUG("IriBaseNodeDriver::Constructor");
   this->driver_.setPostOpenHook(boost::bind(&IriBaseNodeDriver::postOpenHook, this));
-  this->driver_.setPreCloseHook(boost::bind(&IriBaseNodeDriver::preNodeCloseHook, this));
+  this->driver_.setPreCloseHook(boost::bind(&IriBaseNodeDriver::preCloseHook, this));
 
   // create the status thread
-  pthread_create(&this->thread,NULL,this->mainThread,this);
+  pthread_create(&this->main_thread,NULL,this->mainThread,this);
   
   // initialize class attributes
 }
@@ -276,20 +350,26 @@ void *IriBaseNodeDriver<Driver>::mainThread(void *param)
 
   while(ros::ok())
   {
-//     std::cout << __LINE__ << ": driver state=" << iriNode->driver_.getStateName() << std::endl;
     if(iriNode->driver_.isRunning())
-    {
       iriNode->mainNodeThread();
-
-//       ros::spinOnce();
-    }
     iriNode->loop_rate_.sleep();
-
   }
 
   pthread_exit(NULL);
 }
 
+template <class Driver>
+void IriBaseNodeDriver<Driver>::setRate(double rate_hz)
+{
+  this->loop_rate_=rate_hz;
+}
+
+template <class Driver>
+double IriBaseNodeDriver<Driver>::getRate(void)
+{
+  return this->loop_rate_;
+}
+
 template <class Driver>
 void IriBaseNodeDriver<Driver>::postOpenHook(void)
 {
@@ -298,54 +378,136 @@ void IriBaseNodeDriver<Driver>::postOpenHook(void)
   //set hardware id with driver id
   this->diagnostic_.setHardwareID(this->driver_.getID());
 
-  postNodeOpenHook();
+  /* call the inherited class post open function */
+  this->postNodeOpenHook();
 }
 
 template <class Driver>
 void IriBaseNodeDriver<Driver>::preCloseHook(void)
 {
-  ROS_INFO("IriBaseNodeDriver::preCloseHook");
-  preNodeCloseHook();
+  ROS_DEBUG("IriBaseNodeDriver::preCloseHook");
+  /* call the inherited class pre close function */
+  this->preNodeCloseHook();
 }
 
 template <class Driver>
 void IriBaseNodeDriver<Driver>::preNodeCloseHook(void)
 {
+
 }
-    
+
 template <class Driver>
-void IriBaseNodeDriver<Driver>::addDiagnostics(void)
+void IriBaseNodeDriver<Driver>::node_config_update(Config &config, uint32_t level)
 {
-  ROS_DEBUG("IriBaseNodeDriver::addDiagnostics");
-  addNodeDiagnostics();
+
 }
 
 template <class Driver>
-void IriBaseNodeDriver<Driver>::addOpenedTests(void)
+void IriBaseNodeDriver<Driver>::statusDiagnostic(diagnostic_updater::DiagnosticStatusWrapper& stat)
 {
-  ROS_DEBUG("IriBaseNodeDriver::addOpenedTests");
-  addNodeOpenedTests();
+  if (driver_.isRunning())
+    stat.summary(0, "OK");
+  else
+    stat.summary(2, "not running");
+
+  stat.add("Driver state:", this->driver_.getStateName());
+  stat.add("Latest status message:", this->driver_.getStatusMessage());
 }
 
 template <class Driver>
-void IriBaseNodeDriver<Driver>::addStoppedTests(void)
+void IriBaseNodeDriver<Driver>::addDiagnostics(void)
 {
-  ROS_DEBUG("IriBaseNodeDriver::addStoppedTests");
-  addNodeStoppedTests();
+  ROS_DEBUG("IriBaseNodeDriver::addDiagnostics");
+  this->diagnostic_.add(this->driver_status_standard_diagnostic_);
+
+  /* add the inherited class diagnostics */
+  this->addNodeDiagnostics();
 }
 
 template <class Driver>
-void IriBaseNodeDriver<Driver>::addRunningTests(void)
+void IriBaseNodeDriver<Driver>::reconfigureCallback(Config &config, uint32_t level)
 {
-  ROS_DEBUG("IriBaseNodeDriver::addRunningTests");
-  addNodeRunningTests();
+  iri_base_driver::state_t original_state;
+
+  /// @todo Move this into the Driver class?
+  ROS_DEBUG("IriBaseNodeDriver::reconfigureCallback");
+
+  original_state=this->driver_.getState();
+  /* go to the desired state for the update */
+  switch(level)
+  {
+    case iri_base_driver::SensorLevels::RECONFIGURE_STOP: 
+      this->driver_.goState(iri_base_driver::OPENED);
+      break;
+    case iri_base_driver::SensorLevels::RECONFIGURE_CLOSE:
+      this->driver_.goState(iri_base_driver::CLOSED);
+      break;
+    case iri_base_driver::SensorLevels::RECONFIGURE_RUNNING:
+      this->driver_.goState(iri_base_driver::RUNNING);
+      break;
+  }
+
+  /* update the driver */
+  this->driver_.config_update(config, level);
+  /* update the node */
+  this->node_config_update(config, level);
+
+  /* return to the previous state */
+  this->driver_.goState(original_state);
 }
 
 template <class Driver>
-void IriBaseNodeDriver<Driver>::reconfigureHook(int level)
+int IriBaseNodeDriver<Driver>::spin(void)
 {
-  ROS_DEBUG("IriBaseNodeDriver::reconfigureHook");
-  reconfigureNodeHook(level);
+  ROS_DEBUG("IriBaseNodeDriver::spin");
+
+  // initialize diagnostics
+  this->addDiagnostics();
+
+  // launch ros spin in different thread
+  this->spin_thread_.reset(new boost::thread(boost::bind(&ros::spin)));
+  assert(spin_thread_);
+
+  // initial call of the reconfigure callback function
+//  this->reconfigureCallback(this->driver_.config_,iri_base_driver::SensorLevels::RECONFIGURE_CLOSE);
+  // assign callback to dynamic reconfigure server
+  this->dsrv_.setCallback(boost::bind(&IriBaseNodeDriver<Driver>::reconfigureCallback, this, _1, _2));
+
+  // create the status thread
+  pthread_create(&this->main_thread,NULL,this->mainThread,this);
+
+  // try to go to the running state
+  this->driver_.goState(iri_base_driver::RUNNING);
+
+  while(ros::ok())
+  {
+    if (!this->driver_.isRunning())
+    {
+      ros::WallDuration(1).sleep();
+      this->driver_.goState(iri_base_driver::CLOSED);
+      this->driver_.goState(iri_base_driver::RUNNING);
+    }
+    // update diagnostics
+    this->diagnostic_.update();
+
+    ros::WallDuration(0.1).sleep();
+  }
+
+  // try to go to the closed state
+  this->driver_.goState(iri_base_driver::CLOSED);
+
+  // stop ros
+  ros::shutdown();
+
+  if (this->spin_thread_ && !this->spin_thread_->timed_join((boost::posix_time::milliseconds) 2000))
+  {
+    ROS_ERROR("ROS thread did not die after two seconds. Pretending that it did. This is probably a bad sign.");
+  }
+
+  // kill ros spin thread
+  this->spin_thread_.reset();
+
+  return 0;
 }
 
 template <class Driver>
@@ -354,12 +516,43 @@ IriBaseNodeDriver<Driver>::~IriBaseNodeDriver()
   ROS_DEBUG("IriBaseNodeDriver::Destrcutor");
   //try access to driver to assert it is
   //unlock before its destruction
-  this->driver_.try_enter();
-  this->driver_.unlock();
   
-  this->driver_.close();
-  pthread_cancel(this->thread);
-  pthread_join(this->thread,NULL);
+  this->driver_.goState(iri_base_driver::CLOSED);
+  pthread_cancel(this->main_thread);
+  pthread_join(this->main_thread,NULL);
+}
+
+/**
+ * \brief base main
+ *
+ * This main is common for all the driver nodes. The DriverType class
+ * refers to an specific implementation derived from a generic driver.
+ * 
+ * First, ros::init is called providing the node name. Ctrl+C control is 
+ * activated for sercure and safe exit. Finally, a DriverType object is
+ * defined and launched to spin for endless loop execution.
+ * 
+ * \param argc integer with number of input parameters
+ * \param argv array with all input strings
+ * \param node_name name of the node
+ */
+template <class DriverType>
+int main(int argc, char **argv, std::string node_name)
+{
+  ROS_DEBUG("IriBaseDriver::%s Launched", node_name.c_str());
+
+  // ROS initialization
+  ros::init(argc, argv, node_name);
+
+  // allow Ctrl+C management
+  signal(SIGHUP, &AbstractDriverNode::hupCalled);
+
+  // define and launch generic algorithm implementation object
+  ros::NodeHandle nh;
+  DriverType driver(nh);
+  driver.spin();
+
+  return 0;
 }
 
 }
diff --git a/msg/SensorLevels.msg b/msg/SensorLevels.msg
new file mode 100644
index 0000000000000000000000000000000000000000..5502f4c46535b006c19364d7de99f0293f55b6c9
--- /dev/null
+++ b/msg/SensorLevels.msg
@@ -0,0 +1,4 @@
+byte RECONFIGURE_CLOSE = 3  # Parameters that need a sensor to be stopped completely when changed
+byte RECONFIGURE_STOP = 1  # Parameters that need a sensor to stop streaming when changed
+byte RECONFIGURE_RUNNING = 0 # Parameters that can be changed while a sensor is streaming
+
diff --git a/package.xml b/package.xml
index 4b3baf87c2c552fde5cc19c1731a24b11b34f344..44cb7490c36ef296085ed28883401cddab1e4b47 100644
--- a/package.xml
+++ b/package.xml
@@ -34,14 +34,14 @@
   <!-- Examples: -->
   <!-- Use build_depend for packages you need at compile time: -->
   <build_depend>roscpp</build_depend>
-  <build_depend>driver_base</build_depend>
   <build_depend>dynamic_reconfigure</build_depend>
+  <build_depend>message_generation</build_depend>
   <!-- Use buildtool_depend for build tool packages: -->
   <!--   <buildtool_depend>catkin</buildtool_depend> -->
   <!-- Use run_depend for packages you need at runtime: -->
   <run_depend>roscpp</run_depend>
-  <run_depend>driver_base</run_depend>
   <run_depend>dynamic_reconfigure</run_depend>
+  <run_depend>message_runtime</run_depend>
   <!-- Use test_depend for packages you need only for testing: -->
   <!--   <test_depend>gtest</test_depend> -->
   <buildtool_depend>catkin</buildtool_depend>
diff --git a/src/iri_base_driver.cpp b/src/iri_base_driver.cpp
index 984f667e0f70e6cb852336486b0f0c4cb1933d31..99ff593e7966e256ecbe5a5c10067c3351a9ea59 100644
--- a/src/iri_base_driver.cpp
+++ b/src/iri_base_driver.cpp
@@ -3,9 +3,13 @@
 namespace iri_base_driver
 {
 
-IriBaseDriver::IriBaseDriver() : driver_id_("none")
+IriBaseDriver::IriBaseDriver()
 {
+  this->current_state_=iri_base_driver::CLOSED;
+  this->driver_id_="none";
+  this->last_message="not operational yet";
   pthread_mutex_init(&this->access_,NULL);
+  pthread_mutex_init(&this->internal_access_,NULL);
 }
 
 void IriBaseDriver::lock(void)
@@ -31,40 +35,221 @@ void IriBaseDriver::setDriverId(const std::string & id)
   driver_id_ = id;
 }
 
-void IriBaseDriver::doOpen(void)
+std::string IriBaseDriver::getID(void)
 {
-  if(openDriver()) this->state_ = OPENED;
+  return this->driver_id_;
 }
 
-void IriBaseDriver::doClose(void)
+bool IriBaseDriver::goState(state_t target_state)
 {
-  this->preCloseHook();
-  if(closeDriver()) this->state_ = CLOSED;
+  std::string transition;
+  bool error=false;
+
+  pthread_mutex_lock(&this->internal_access_);  
+  try{
+    do{
+      switch(this->current_state_)
+      {
+        case iri_base_driver::CLOSED: if(target_state == iri_base_driver::OPENED || target_state == iri_base_driver::RUNNING)
+                     {
+                       transition="open";
+                       ROS_DEBUG("Trying transition open from CLOSED to OPENED.");
+                       if(this->openDriver())
+                       {
+                         this->current_state_=iri_base_driver::OPENED;
+                         this->postOpenHook();
+                         this->last_message="Transition open from CLOSED to OPENED succeeded.";
+                         ROS_DEBUG("%s",this->last_message.c_str());
+                       }
+                       else
+                       {
+                         this->current_state_=iri_base_driver::CLOSED;
+                         this->last_message="Transition open from CLOSED to OPENED failed.";
+                         ROS_DEBUG("%s",this->last_message.c_str());
+                         error=true;
+                       }
+                     }
+                     else
+                     {
+                       this->current_state_=iri_base_driver::CLOSED;
+                       this->last_message="No transition required";
+                       ROS_DEBUG("%s",this->last_message.c_str());
+                     }
+                     break;
+        case iri_base_driver::OPENED: if(target_state == iri_base_driver::CLOSED)
+                     {
+                       transition="close";
+                       ROS_DEBUG("Trying transition close from OPENED to CLOSED.");
+                       this->preCloseHook();
+                       if(this->closeDriver())
+                       {
+                         this->current_state_=iri_base_driver::CLOSED;
+                         this->last_message="Transition close from OPENED to CLOSED succeeded.";
+                         ROS_DEBUG("%s",this->last_message.c_str());
+                       }
+                       else
+                       {
+                         this->current_state_=iri_base_driver::OPENED;
+                         this->last_message="Transition close from OPENED to CLOSED failed.";
+                         ROS_DEBUG("%s",this->last_message.c_str());
+                         error=true;
+                       }
+                     }
+                     else if(target_state == iri_base_driver::RUNNING)
+                     {
+                       transition="start";
+                       ROS_DEBUG("Trying transition start from OPENED to RUNNING.");
+                       if(this->startDriver())
+                       {
+                         this->current_state_=iri_base_driver::RUNNING;
+                         this->last_message="Transition start from OPENED to RUNNING succeeded.";
+                         ROS_DEBUG("%s",this->last_message.c_str());
+                       }
+                       else
+                       {
+                         this->current_state_=iri_base_driver::OPENED;
+                         this->last_message="Transition start from OPENED to RUNNING failed.";
+                         ROS_DEBUG("%s",this->last_message.c_str());
+                         error=true;
+                       }
+                     }
+                     else
+                     {
+                       this->current_state_=iri_base_driver::OPENED;
+                       this->last_message="No transition required";
+                       ROS_DEBUG("%s",this->last_message.c_str());
+                     }
+                     break;
+        case RUNNING: if(target_state == iri_base_driver::OPENED || target_state == iri_base_driver::CLOSED)
+                      {
+                        transition="stop";
+                        ROS_DEBUG("Trying transition stop from RUNNING to OPENED.");
+                        if(this->stopDriver())
+                        {
+                          this->current_state_=iri_base_driver::OPENED;
+                          this->last_message="Transition stop from RUNING to OPENED succeeded.";
+                          ROS_DEBUG("%s",this->last_message.c_str());
+                        }
+                        else
+                        {
+                          this->current_state_=iri_base_driver::RUNNING;
+                          this->last_message="Transition stop from RUNNING to OPENED failed.";
+                          ROS_DEBUG("%s",this->last_message.c_str());
+                          error=true;
+                        }
+                      }
+                      else
+                      {
+                        this->current_state_=iri_base_driver::RUNNING;
+                        this->last_message="No transition required";
+                        ROS_DEBUG("%s",this->last_message.c_str());
+                      }
+                      break;
+      }
+    }while(!error && this->current_state_!=target_state);
+  }catch(...){
+    ROS_WARN("Caught exception in state transition %s\n",transition.c_str());
+    error=true;
+  }
+  pthread_mutex_unlock(&this->internal_access_);  
+
+  return error;
 }
 
-void IriBaseDriver::doStart(void)
+state_t IriBaseDriver::getState(void)
 {
-  if(startDriver()) this->state_ = RUNNING;
+  return this->current_state_;
 }
 
-void IriBaseDriver::doStop(void)
+std::string IriBaseDriver::getStateName(void)
 {
-  if(stopDriver()) this->state_ = OPENED;
+  switch(this->current_state_)
+  {
+    case iri_base_driver::CLOSED: return std::string("closed");
+    case iri_base_driver::OPENED: return std::string("oepned");
+    case iri_base_driver::RUNNING: return std::string("running");
+  }
 }
 
-std::string IriBaseDriver::getID(void)
+std::string IriBaseDriver::getStatusMessage(void)
+{
+  return this->last_message;
+}
+
+bool IriBaseDriver::isRunning(void)
+{
+  pthread_mutex_lock(&this->internal_access_);  
+  if(this->current_state_ == iri_base_driver::RUNNING)
+  {
+    pthread_mutex_unlock(&this->internal_access_);  
+    return true;
+  }
+  else
+  {
+    pthread_mutex_unlock(&this->internal_access_);  
+    return false;
+  }
+}
+
+bool IriBaseDriver::isOpened(void)
+{
+  pthread_mutex_lock(&this->internal_access_);  
+  if(this->current_state_ == iri_base_driver::OPENED)
+  {
+    pthread_mutex_unlock(&this->internal_access_);  
+    return true;
+  }
+  else
+  {
+    pthread_mutex_unlock(&this->internal_access_);  
+    return false;
+  }
+}
+
+bool IriBaseDriver::isClosed(void)
+{
+  pthread_mutex_lock(&this->internal_access_);  
+  if(this->current_state_ == iri_base_driver::CLOSED)
+  {
+    pthread_mutex_unlock(&this->internal_access_);  
+    return true;
+  }
+  else
+  {
+    pthread_mutex_unlock(&this->internal_access_);  
+    return false;
+  }
+}
+
+bool IriBaseDriver::isStopped(void)
+{
+  pthread_mutex_lock(&this->internal_access_);  
+  if(this->current_state_ == iri_base_driver::OPENED || this->current_state_ == iri_base_driver::CLOSED)
+  {
+    pthread_mutex_unlock(&this->internal_access_);  
+    return true;
+  }
+  else
+  {
+    pthread_mutex_unlock(&this->internal_access_);  
+    return false;
+  }
+}
+
+void IriBaseDriver::setPostOpenHook(boost::function< void() > function)
 {
-  return driver_id_;
+  this->postOpenHook = function;
 }
 
-void IriBaseDriver::setPreCloseHook(hookFunction f)
+void IriBaseDriver::setPreCloseHook(boost::function< void() > function)
 {
-  preCloseHook = f;
+  this->preCloseHook = function;
 }
 
 IriBaseDriver::~IriBaseDriver()
 {
   pthread_mutex_destroy(&this->access_);
+  pthread_mutex_destroy(&this->internal_access_);
 }
 
 }