diff --git a/src/examples/CMakeLists.txt b/src/examples/CMakeLists.txt
index 7c7a623a5c89b351b26641a8735ecac9c62509bd..861dcf413618d6b16ad6029eea721b404f5ecd33 100644
--- a/src/examples/CMakeLists.txt
+++ b/src/examples/CMakeLists.txt
@@ -1,3 +1,5 @@
+# Matrix product test
+#ADD_EXECUTABLE(test_matrix_prod test_matrix_prod.cpp)
 
 # ProcessorMotion classes test
 ADD_EXECUTABLE(test_motion test_motion.cpp)
diff --git a/src/examples/test_matrix_prod.cpp b/src/examples/test_matrix_prod.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..bd6ffddb6585f80c37b0d3a2e028492311ee2937
--- /dev/null
+++ b/src/examples/test_matrix_prod.cpp
@@ -0,0 +1,156 @@
+/**
+ * \file test_matrix_prod.cpp
+ *
+ *  Created on: May 26, 2016
+ *      \author: jsola
+ */
+
+#include "eigen3/Eigen/Dense"
+
+//std includes
+#include <ctime>
+#include <iostream>
+#include <iomanip>
+
+#define DECLARE_MATRICES(s) \
+        Matrix<double, s, s, RowMajor> R1, R2, Ro; \
+        Matrix<double, s, s, ColMajor> C1, C2, Co;
+
+#define INIT_MATRICES(s) \
+        R1.setRandom(s, s);\
+        R2.setRandom(s, s);\
+        C1.setRandom(s, s);\
+        C2.setRandom(s, s);\
+        Ro.setRandom(s, s);\
+        Co.setRandom(s, s);
+
+
+#define LOOP_MATRIX(N,Mo,M1,M2) \
+        for (int i = 0; i < N; i++) \
+        { \
+            Mo = M1 * M2; \
+            M1(2,2) = Mo(2,2); \
+        }
+
+#define EVALUATE_MATRIX(N,Mo,M1,M2) \
+        t0 = clock(); \
+        LOOP_MATRIX(N,Mo,M1,M2) \
+        t1 = clock(); \
+        std::cout << std::setw(15) << Mo(2,2) << "\t";
+
+#define EVALUATE_ALL \
+        EVALUATE_MATRIX(N, Ro, R1, R2)\
+        std::cout << "Time Ro = R * R: " << (long double)(t1 - t0) * 1e9 / CLOCKS_PER_SEC / N << "ns" << std::endl;\
+        EVALUATE_MATRIX(N, Ro, R1, C2)\
+        std::cout << "Time Ro = R * C: " << (long double)(t1 - t0) * 1e9 / CLOCKS_PER_SEC / N << "ns" << std::endl;\
+        EVALUATE_MATRIX(N, Ro, C1, R2)\
+        std::cout << "Time Ro = C * R: " << (long double)(t1 - t0) * 1e9 / CLOCKS_PER_SEC / N << "ns" << std::endl;\
+        EVALUATE_MATRIX(N, Ro, C1, C2)\
+        std::cout << "Time Ro = C * C: " << (long double)(t1 - t0) * 1e9 / CLOCKS_PER_SEC / N << "ns" << std::endl;\
+        EVALUATE_MATRIX(N, Co, R1, R2)\
+        std::cout << "Time Co = R * R: " << (long double)(t1 - t0) * 1e9 / CLOCKS_PER_SEC / N << "ns" << std::endl;\
+        EVALUATE_MATRIX(N, Co, R1, C2)\
+        std::cout << "Time Co = R * C: " << (long double)(t1 - t0) * 1e9 / CLOCKS_PER_SEC / N << "ns" << std::endl;\
+        EVALUATE_MATRIX(N, Co, C1, R2)\
+        std::cout << "Time Co = C * R: " << (long double)(t1 - t0) * 1e9 / CLOCKS_PER_SEC / N << "ns" << std::endl;\
+        EVALUATE_MATRIX(N, Co, C1, C2)\
+        std::cout << "Time Co = C * C: " << (long double)(t1 - t0) * 1e9 / CLOCKS_PER_SEC / N \
+        << "ns <-- this is the Eigen default!" << std::endl;
+
+
+
+/**
+ * We multiply matrices and see how long it takes.
+ * We compare different combinations of row-major and column-major to see which one is the fastest.
+ * We can select the matrix size.
+ */
+int main()
+{
+    using namespace Eigen;
+
+    int N = 100000;
+    const int S = 6;
+    Matrix<double, 16, S - 3 + 1> results;
+    clock_t t0, t1;
+
+    // All dynamic sizes
+    {
+        Matrix<double, Dynamic, Dynamic, RowMajor> R1, R2, Ro;
+        Matrix<double, Dynamic, Dynamic, ColMajor> C1, C2, Co;
+
+        for (int s = 3; s <= S; s++)
+        {
+            std::cout << "Timings for dynamic matrix product. R: row major matrix. C: column major matrix. " << s << "x"
+                    << s << " matrices." << std::endl;
+
+            INIT_MATRICES(s)
+            EVALUATE_ALL
+
+        }
+    }
+    // Statics, one by one
+    {
+        const int s = 3;
+        std::cout << "Timings for static matrix product. R: row major matrix. C: column major matrix. " << s << "x" << s
+                << " matrices." << std::endl;
+
+        DECLARE_MATRICES(s)
+        INIT_MATRICES(s)
+        EVALUATE_ALL
+    }
+    {
+        const int s = 4;
+        std::cout << "Timings for static matrix product. R: row major matrix. C: column major matrix. " << s << "x" << s
+                << " matrices." << std::endl;
+
+        DECLARE_MATRICES(s)
+        INIT_MATRICES(s)
+        EVALUATE_ALL
+    }
+    {
+        const int s = 5;
+        std::cout << "Timings for static matrix product. R: row major matrix. C: column major matrix. " << s << "x" << s
+                << " matrices." << std::endl;
+
+        DECLARE_MATRICES(s)
+        INIT_MATRICES(s)
+        EVALUATE_ALL
+    }
+    {
+        const int s = 6;
+        std::cout << "Timings for static matrix product. R: row major matrix. C: column major matrix. " << s << "x" << s
+                << " matrices." << std::endl;
+
+        DECLARE_MATRICES(s)
+        INIT_MATRICES(s)
+        EVALUATE_ALL
+    }
+
+    std::cout << "Test q and R rotations" << std::endl;
+    Eigen::Quaterniond q(Eigen::Vector4d::Random().normalized());
+    Eigen::Matrix3d R = q.matrix();
+    Eigen::Vector3d v; v << 1,2,3; double vn = v.norm();
+
+    N *= 100;
+
+    t0 = clock();
+    for (int i = 0; i < N; i++)
+    {
+        v = R * v;
+    }
+    t1 = clock();
+    std::cout << "Time w = R * v: " << (double)(t1 - t0) * 1e9 / CLOCKS_PER_SEC / N << "ns" << std::endl;
+    std::cout << "v norm change: " << 10*logl((long double)v.norm()/(long double)vn) << " dB" << std::endl;
+
+    v << 1,2,3;
+    t0 = clock();
+    for (int i = 0; i < N; i++)
+    {
+        v = q * v;
+    }
+    t1 = clock();
+    std::cout << "Time w = q * v: " << (double)(t1 - t0) * 1e9 / CLOCKS_PER_SEC / N << "ns" << std::endl;
+    std::cout << "v norm change: " << 10*logl((long double)v.norm()/(long double)vn) << " dB" << std::endl;
+    return 0;
+}
+
diff --git a/src/examples/test_wolf_factories.cpp b/src/examples/test_wolf_factories.cpp
index 95631ee150b9b84994a65378ee862b3b65382fdb..193ba291790f133b32c3d6febe2ab8d27332fbbe 100644
--- a/src/examples/test_wolf_factories.cpp
+++ b/src/examples/test_wolf_factories.cpp
@@ -15,6 +15,7 @@
 #include "../processor_odom_3D.h"
 #include "../processor_imu.h"
 #include "../processor_gps.h"
+#include "../processor_image.h"
 
 #include "../problem.h"
 
@@ -31,14 +32,6 @@ int main(void)
     using namespace std;
 
 
-    cout << "\n====== Registering creators in the Wolf Factories ======" << endl;
-
-    cout << "If you look above, you see the registered creators.\n"
-            "There is only one attempt per class, and it is successful!\n"
-            "We do this by registering in the class\'s .cpp file.\n"
-            "\n"
-            "See [wolf]/src/examples/test_sensor_factory.cpp for the way to add sensors and processors to wolf::Problem." << endl;
-
     /**=============================================================================================
      * Get wolf root directory from the environment variable WOLF_ROOT
      * To make this work, you need to set the environment variable WOLF_ROOT:
@@ -56,6 +49,15 @@ int main(void)
     std::cout << "\nwolf directory for configuration files: " << WOLF_CONFIG << std::endl;
     //==============================================================================================
 
+    cout << "\n====== Registering creators in the Wolf Factories =======" << endl;
+
+    cout << "If you look above, you see the registered creators.\n"
+            "There is only one attempt per class, and it is successful!\n"
+            "We do this by registering in the class\'s .cpp file.\n"
+            "\n"
+            "- See \'" << WOLF_ROOT << "/src/examples/test_wolf_factories.cpp\'\n"
+            "  for the way to install sensors and processors to wolf::Problem." << endl;
+
     // Start creating the problem
 
     Problem problem(FRM_PO_3D);
@@ -64,12 +66,16 @@ int main(void)
     Eigen::VectorXs pq_3d(7), po_2d(3), p_3d(3);
     IntrinsicsOdom2D intr_odom2d;
 
-    cout << "\n================= Intrinsics Factory ===================" << endl;
+    cout << "\n================== Intrinsics Factory ===================" << endl;
 
     // Use params factory for camera intrinsics
     IntrinsicsBase* intr_cam_ptr = IntrinsicsFactory::get().create("CAMERA", WOLF_CONFIG + "/camera.yaml");
+    ProcessorParamsBase* params_ptr = ProcessorParamsFactory::get().create("IMAGE", WOLF_CONFIG + "/processor_image_ORB.yaml");
+
+    cout << "CAMERA with intrinsics      : " << ((IntrinsicsCamera*)intr_cam_ptr)->pinhole_model.transpose() << endl;
+    cout << "Processor IMAGE image width : " << ((ProcessorImageParameters*)params_ptr)->image.width << endl;
 
-    cout << "\n==================== Sensor Factory ====================" << endl;
+    cout << "\n==================== Install Sensors ====================" << endl;
 
     // Install sensors
     problem.installSensor("CAMERA",     "front left camera",    pq_3d,  intr_cam_ptr);
@@ -79,9 +85,7 @@ int main(void)
     problem.installSensor("IMU",        "inertial",             pq_3d);
     problem.installSensor("GPS",        "GPS raw",              p_3d);
     problem.installSensor("ODOM 2D",    "aux odometer",         po_2d,  &intr_odom2d);
-
-    // Full YAML support: Add this sensor and recover a pointer to it
-    SensorBase* sen_ptr = problem.installSensor("CAMERA", "rear camera", pq_3d, WOLF_CONFIG + "/camera.yaml");
+    problem.installSensor("CAMERA", "rear camera", pq_3d, WOLF_ROOT + "/src/examples/camera.yaml");
 
     // print available sensors
     for (auto sen : *(problem.getHardwarePtr()->getSensorListPtr())){
@@ -90,9 +94,8 @@ int main(void)
                 << ": " << setw(8) << sen->getType()
                 << " | name: " << sen->getName() << endl;
     }
-    cout << "\twith intrinsics: " << sen_ptr->getIntrinsicPtr()->getVector().transpose() << endl;
 
-    cout << "\n=================== Processor Factory ===================" << endl;
+    cout << "\n=================== Install Processors ===================" << endl;
 
     // Install processors and bind them to sensors -- by sensor name!
     problem.installProcessor("ODOM 2D", "main odometry",    "main odometer");
diff --git a/src/processor_odom_3D.h b/src/processor_odom_3D.h
index 87f962096afc80bfab44cf309de4e9a9b320a04b..e4b32dd56846702b568efb52ee3032112338e028 100644
--- a/src/processor_odom_3D.h
+++ b/src/processor_odom_3D.h
@@ -156,9 +156,7 @@ inline void ProcessorOdom3D::deltaMinusDelta(const Eigen::VectorXs& _delta1, con
 
 inline Eigen::VectorXs ProcessorOdom3D::deltaZero() const
 {
-    Eigen::VectorXs delta_zero(7);
-    delta_zero << 0, 0, 0, 0, 0, 0, 1;;
-    return delta_zero;
+    return (Eigen::VectorXs(7) << 0,0,0, 0,0,0,1).finished(); // p, q
 }
 
 inline Motion ProcessorOdom3D::interpolate(const Motion& _motion_ref, Motion& _motion, TimeStamp& _ts)
diff --git a/src/sensor_base.h b/src/sensor_base.h
index ba8cf1530644da2b502577062ee02b788a318a5f..0f6fcdf6c855b95ea07328c0cc37aa2648b323c1 100644
--- a/src/sensor_base.h
+++ b/src/sensor_base.h
@@ -58,9 +58,9 @@ class SensorBase : public NodeLinked<HardwareBase, ProcessorBase>
          * \param _tp Type of the sensor  (types defined at wolf.h)
          * \param _p_ptr StateBlock pointer to the sensor position
          * \param _o_ptr StateBlock pointer to the sensor orientation
-         * \param _intr_ptr TODO update documentation
-         * \param _noise_size TODO update documentation
-         * \param _extr_dyn TODO update documentation
+         * \param _intr_ptr StateBlock pointer to the sensor intrinsic params that might be estimated (if unfixed).
+         * \param _noise_size dimension of the noise term
+         * \param _extr_dyn Flag indicating if extrinsics are dynamic (moving) or static (not moving)
          *
          **/
         SensorBase(const SensorType & _tp, StateBlock* _p_ptr, StateBlock* _o_ptr, StateBlock* _intr_ptr, const unsigned int _noise_size, const bool _extr_dyn = false);
@@ -71,9 +71,9 @@ class SensorBase : public NodeLinked<HardwareBase, ProcessorBase>
          * \param _tp Type of the sensor  (types defined at wolf.h)
          * \param _p_ptr StateBlock pointer to the sensor position
          * \param _o_ptr StateBlock pointer to the sensor orientation
-         * \param _intr_ptr TODO update documentation
-         * \param _noise_std TODO update documentation
-         * \param _extr_dyn TODO update documentation
+         * \param _intr_ptr StateBlock pointer to the sensor intrinsic params that might be estimated (if unfixed).
+         * \param _noise_std standard deviations of the noise term
+         * \param _extr_dyn Flag indicating if extrinsics are dynamic (moving) or static (not moving)
          *
          **/
         SensorBase(const SensorType & _tp, StateBlock* _p_ptr, StateBlock* _o_ptr, StateBlock* _intr_ptr, const Eigen::VectorXs & _noise_std, const bool _extr_dyn = false);
diff --git a/src/sensor_factory.h b/src/sensor_factory.h
index ba4462a50a41229dad311020ca4f3be74b2136fb..71ebf9575b7b089327ac4205019dc8b1d27a89ab 100644
--- a/src/sensor_factory.h
+++ b/src/sensor_factory.h
@@ -44,12 +44,12 @@ namespace wolf
  * Creators must be registered to the factory before they can be invoked for sensor creation.
  *
  * This documentation shows you how to:
- *   - Access the Factory
+ *   - Access the factory
  *   - Register and unregister creators
  *   - Create sensors
  *   - Write a sensor creator for SensorCamera (example).
  *
- * #### Accessing the Factory
+ * #### Accessing the factory
  * The SensorFactory class is a <a href="http://stackoverflow.com/questions/1008019/c-singleton-design-pattern#1008289">singleton</a>: it can only exist once in your application.
  * To obtain an instance of it, use the static method get(),
  *