Index: trunk/lib/FlairFilter/CMakeLists.txt
===================================================================
--- trunk/lib/FlairFilter/CMakeLists.txt	(revision 7)
+++ trunk/lib/FlairFilter/CMakeLists.txt	(revision 7)
@@ -0,0 +1,45 @@
+PROJECT(FlairFilter)
+cmake_minimum_required(VERSION 2.8)
+include($ENV{FLAIR_ROOT}/flair-dev/cmake-modules/GlobalCmakeFlair.cmake)
+
+find_package(LibXml2 REQUIRED)
+
+execute_process(COMMAND ${CMAKE_C_COMPILER} -dumpversion
+                OUTPUT_VARIABLE GCC_VERSION)
+
+if (GCC_VERSION VERSION_GREATER 4.3 OR GCC_VERSION VERSION_EQUAL 4.3)
+	if (GCC_VERSION VERSION_GREATER 4.7 OR GCC_VERSION VERSION_EQUAL 4.7)
+		ADD_DEFINITIONS("-std=c++11")
+	else()
+		ADD_DEFINITIONS("-std=c++0x")
+	endif()
+else()
+	message(STATUS "GCC version < 4.3, c+11 is not supported!")
+endif()
+
+INCLUDE_DIRECTORIES(
+	${LIBXML2_INCLUDE_DIR}
+	${CMAKE_CURRENT_SOURCE_DIR}/../FlairCore/src
+	${CMAKE_CURRENT_SOURCE_DIR}/../FlairSensorActuator/src
+	${CMAKE_CURRENT_SOURCE_DIR}/src/unexported
+	${CMAKE_CURRENT_SOURCE_DIR}/src/
+	${CMAKE_SYSROOT}/usr/include/opencv
+	${CMAKE_SYSROOT}/usr/include/iir
+)
+
+FILE(GLOB SRC_FILES "${CMAKE_CURRENT_SOURCE_DIR}/src/*.cpp")
+
+ADD_LIBRARY(${PROJECT_NAME}
+	${SRC_FILES}
+)
+
+INSTALL(TARGETS ${PROJECT_NAME}
+	LIBRARY DESTINATION $ENV{FLAIR_ROOT}/flair-bin/lib/${ARCH_DIR}
+	ARCHIVE DESTINATION $ENV{FLAIR_ROOT}/flair-bin/lib/${ARCH_DIR}
+)
+
+#copie des entetes
+FILE(GLOB HEADER_FILES "${CMAKE_CURRENT_SOURCE_DIR}/src/*.h")
+INSTALL(FILES ${HEADER_FILES} DESTINATION $ENV{FLAIR_ROOT}/flair-dev/include/${PROJECT_NAME})
+
+SET(LIBRARY_OUTPUT_PATH ${PROJECT_BINARY_DIR}/bin)
Index: trunk/lib/FlairFilter/src/Ahrs.cpp
===================================================================
--- trunk/lib/FlairFilter/src/Ahrs.cpp	(revision 7)
+++ trunk/lib/FlairFilter/src/Ahrs.cpp	(revision 7)
@@ -0,0 +1,90 @@
+//  created:    2014/01/14
+//  filename:   Ahrs.cpp
+//
+//  author:     Guillaume Sanahuja
+//              Copyright Heudiasyc UMR UTC/CNRS 7253
+//
+//  version:    $Id: $
+//
+//  purpose:    Virtual class for AHRS
+//
+//
+/*********************************************************************/
+
+#include "Ahrs.h"
+#include "Ahrs_impl.h"
+#include <Imu.h>
+#include <DataPlot1D.h>
+#include <AhrsData.h>
+
+using std::string;
+using namespace flair::core;
+using namespace flair::gui;
+using namespace flair::sensor;
+
+namespace flair { namespace filter {
+
+Ahrs::Ahrs(const Imu* parent,string name) : IODevice(parent,name) {
+    pimpl_=new Ahrs_impl(this);
+    AddDataToLog(pimpl_->ahrsData);
+}
+
+Ahrs::~Ahrs() {
+    delete pimpl_;
+}
+
+const Imu *Ahrs::GetImu(void) const {
+    return (Imu*)Parent();
+}
+
+const AhrsData *Ahrs::GetDatas(void) const {
+    return pimpl_->ahrsData;
+}
+
+void Ahrs::GetDatas(core::AhrsData **ahrsData) const {
+    *ahrsData=pimpl_->ahrsData;
+}
+
+void Ahrs::LockUserInterface(void) const {
+    //((Imu*)Parent())->LockUserInterface();
+}
+
+void Ahrs::UnlockUserInterface(void) const {
+    //((Imu*)Parent())->UnlockUserInterface();
+}
+
+void Ahrs::UseDefaultPlot(void) {
+    pimpl_->UseDefaultPlot();
+    ((Imu*)Parent())->UseDefaultPlot();
+}
+
+void Ahrs::AddPlot(const AhrsData *ahrsData,DataPlot::Color_t color) {
+    pimpl_->AddPlot(ahrsData,color);
+}
+
+DataPlot1D *Ahrs::RollPlot(void) const {
+    return pimpl_->rollPlot;
+}
+
+DataPlot1D *Ahrs::PitchPlot(void) const {
+    return pimpl_->pitchPlot;
+}
+
+DataPlot1D *Ahrs::YawPlot(void) const {
+    return pimpl_->yawPlot;
+}
+
+DataPlot1D *Ahrs::WXPlot(void) const {
+    return pimpl_->wXPlot;
+}
+
+DataPlot1D *Ahrs::WYPlot(void) const {
+    return pimpl_->wYPlot;
+}
+
+DataPlot1D *Ahrs::WZPlot(void) const {
+    return pimpl_->wZPlot;
+}
+
+} // end namespace filter
+} // end namespace flair
Index: trunk/lib/FlairFilter/src/Ahrs.h
===================================================================
--- trunk/lib/FlairFilter/src/Ahrs.h	(revision 7)
+++ trunk/lib/FlairFilter/src/Ahrs.h	(revision 7)
@@ -0,0 +1,181 @@
+/*!
+ * \file Ahrs.h
+ * \brief Abstract class for AHRS
+ * \author Guillaume Sanahuja, Copyright Heudiasyc UMR UTC/CNRS 7253
+ * \date 2014/01/14
+ * \version 4.0
+ */
+
+#ifndef AHRS_H
+#define AHRS_H
+
+#include <IODevice.h>
+#include <DataPlot.h>
+
+namespace flair {
+    namespace core {
+        class Euler;
+        class Vector3D;
+        class ImuData;
+        class Quaternion;
+        class AhrsData;
+    }
+    namespace gui {
+        class Tab;
+        class DataPlot1D;
+    }
+    namespace sensor {
+        class Imu;
+    }
+}
+
+class Ahrs_impl;
+
+namespace flair { namespace filter {
+    /*! \class Ahrs
+    *
+    * \brief Abstract class for AHRS
+    *
+    * Use this class to define a custom AHRS. This class is child
+    * of an Imu class, which will provide measurements. \n
+    *
+    */
+    class Ahrs : public core::IODevice {
+        public:
+            /*!
+            * \brief Constructor
+            *
+            * Construct an Ahrs.
+            *
+            * \param parent parent
+            * \param name name
+            */
+            Ahrs(const sensor::Imu* parent,std::string name);
+
+            /*!
+            * \brief Destructor
+            *
+            */
+            ~Ahrs();
+
+            /*!
+            * \brief Get parent Imu
+            *
+            * This function is identical to (Imu*)Parent()
+            */
+            const sensor::Imu *GetImu(void) const;
+
+            /*!
+            * \brief Get ahrs datas
+            *
+            * \return AhrsData
+            */
+            const core::AhrsData *GetDatas(void) const;
+
+            /*!
+            * \brief Lock the graphical user interface
+            *
+            * When locked, parameters cannot be modified.
+            *
+            */
+            void LockUserInterface(void) const;
+
+            /*!
+            * \brief Unlock the graphical user interface
+            *
+            */
+            void UnlockUserInterface(void) const;
+
+            /*!
+            * \brief Use default plot
+            *
+            * Plot the datas defined in imudata,
+            * and datas defined in Imu::imudata.
+            *
+            */
+            void UseDefaultPlot(void);
+
+            /*!
+            * \brief Add plot
+            *
+            * Add plot of an AhrsData to the default plot
+            *
+            * \param ahrsData ahrs datas to plot
+            * \param color color to use
+            */
+            void AddPlot(const core::AhrsData *ahrsData,gui::DataPlot::Color_t color);
+
+            /*!
+            * \brief Roll plot
+            *
+            * Use this plot to add own curves.
+            *
+            * \return plot
+            *
+            */
+            gui::DataPlot1D *RollPlot(void)const ;
+
+            /*!
+            * \brief Pitch plot
+            *
+            * Use this plot to add own curves.
+            *
+            * \return plot
+            *
+            */
+            gui::DataPlot1D *PitchPlot(void) const;
+
+            /*!
+            * \brief Yaw plot
+            *
+            * Use this plot to add own curves.
+            *
+            * \return plot
+            *
+            */
+            gui::DataPlot1D *YawPlot(void) const;
+
+            /*!
+            * \brief Rotation speed around x axis plot
+            *
+            * Use this plot to add own curves.
+            *
+            * \return plot
+            *
+            */
+            gui::DataPlot1D *WXPlot(void) const;
+
+            /*!
+            * \brief Rotation speed around y axis plot
+            *
+            * Use this plot to add own curves.
+            *
+            * \return plot
+            *
+            */
+            gui::DataPlot1D *WYPlot(void) const;
+
+            /*!
+            * \brief Rotation speed around z axis plot
+            *
+            * Use this plot to add own curves.
+            *
+            * \return plot
+            *
+            */
+            gui::DataPlot1D *WZPlot(void) const;
+
+        protected:
+            /*!
+            * \brief Get ahrs datas
+            *
+            * \param ahrsData ahrs datas
+            */
+            void GetDatas(core::AhrsData **ahrsData) const;
+
+        private:
+            class Ahrs_impl *pimpl_;
+    };
+} // end namespace filter
+} // end namespace flair
+#endif // AHRS_H
Index: trunk/lib/FlairFilter/src/Ahrs_impl.cpp
===================================================================
--- trunk/lib/FlairFilter/src/Ahrs_impl.cpp	(revision 7)
+++ trunk/lib/FlairFilter/src/Ahrs_impl.cpp	(revision 7)
@@ -0,0 +1,95 @@
+//  created:    2014/01/14
+//  filename:   Ahrs_impl.cpp
+//
+//  author:     Guillaume Sanahuja
+//              Copyright Heudiasyc UMR UTC/CNRS 7253
+//
+//  version:    $Id: $
+//
+//  purpose:    Virtual class for Ahrs_impl
+//
+//
+/*********************************************************************/
+
+#include "Ahrs_impl.h"
+#include "Ahrs.h"
+#include <Imu.h>
+#include <Tab.h>
+#include <TabWidget.h>
+#include <DataPlot1D.h>
+#include <AhrsData.h>
+
+using std::string;
+using namespace flair::core;
+using namespace flair::gui;
+using namespace flair::filter;
+using namespace flair::sensor;
+
+Ahrs_impl::Ahrs_impl(Ahrs* inSelf): self(inSelf) {
+    rollPlot=NULL;
+    pitchPlot=NULL;
+    yawPlot=NULL;
+    wXPlot=NULL;
+    wYPlot=NULL;
+    wZPlot=NULL;
+    q0Plot=NULL;
+    q1Plot=NULL;
+    q2Plot=NULL;
+    q3Plot=NULL;
+
+    eulerTab=NULL;
+    quaternionTab=NULL;
+
+    ahrsData=new AhrsData(self);
+}
+
+Ahrs_impl::~Ahrs_impl() {
+}
+
+void Ahrs_impl::UseDefaultPlot(void) {
+
+    eulerTab=new Tab(((Imu*)(self->Parent()))->tab,"AHRS");
+    rollPlot=new DataPlot1D(eulerTab->NewRow(),"roll",-30,30);
+    rollPlot->AddCurve(ahrsData->Element(AhrsData::RollDeg));
+    pitchPlot=new DataPlot1D(eulerTab->LastRowLastCol(),"pitch",-30,30);
+    pitchPlot->AddCurve(ahrsData->Element(AhrsData::PitchDeg));
+    yawPlot=new DataPlot1D(eulerTab->LastRowLastCol(),"yaw",-180,180);
+    yawPlot->AddCurve(ahrsData->Element(AhrsData::YawDeg));
+
+    wXPlot=new DataPlot1D(eulerTab->NewRow(),"w_x",-200,200);
+    wXPlot->AddCurve(ahrsData->Element(AhrsData::WxDeg));
+    wYPlot=new DataPlot1D(eulerTab->LastRowLastCol(),"w_y",-200,200);
+    wYPlot->AddCurve(ahrsData->Element(AhrsData::WyDeg));
+    wZPlot=new DataPlot1D(eulerTab->LastRowLastCol(),"w_z",-200,200);
+    wZPlot->AddCurve(ahrsData->Element(AhrsData::WzDeg));
+
+    quaternionTab=new Tab(((Imu*)(self->Parent()))->tab,"Quaternion");
+    q0Plot=new DataPlot1D(quaternionTab->NewRow(),"q0",-1,1);
+    q0Plot->AddCurve(ahrsData->Element(AhrsData::Q0));
+    q1Plot=new DataPlot1D(quaternionTab->NewRow(),"q1",-1,1);
+    q1Plot->AddCurve(ahrsData->Element(AhrsData::Q1));
+    q2Plot=new DataPlot1D(quaternionTab->LastRowLastCol(),"q2",-1,1);
+    q2Plot->AddCurve(ahrsData->Element(AhrsData::Q2));
+    q3Plot=new DataPlot1D(quaternionTab->LastRowLastCol(),"q3",-1,1);
+    q3Plot->AddCurve(ahrsData->Element(AhrsData::Q3));
+
+}
+
+void Ahrs_impl::AddPlot(const AhrsData *ahrsData,DataPlot::Color_t color) {
+    if(rollPlot!=NULL) {
+        rollPlot->AddCurve(ahrsData->Element(AhrsData::RollDeg),color);
+        pitchPlot->AddCurve(ahrsData->Element(AhrsData::PitchDeg),color);
+        yawPlot->AddCurve(ahrsData->Element(AhrsData::YawDeg),color);
+    }
+    if(wXPlot!=NULL) {
+        wXPlot->AddCurve(ahrsData->Element(AhrsData::WxDeg),color);
+        wYPlot->AddCurve(ahrsData->Element(AhrsData::WyDeg),color);
+        wZPlot->AddCurve(ahrsData->Element(AhrsData::WzDeg),color);
+    }
+    if(quaternionTab!=NULL) {
+        q0Plot->AddCurve(ahrsData->Element(AhrsData::Q0),color);
+        q1Plot->AddCurve(ahrsData->Element(AhrsData::Q1),color);
+        q2Plot->AddCurve(ahrsData->Element(AhrsData::Q2),color);
+        q3Plot->AddCurve(ahrsData->Element(AhrsData::Q3),color);
+    }
+}
Index: trunk/lib/FlairFilter/src/ButterworthLowPass.cpp
===================================================================
--- trunk/lib/FlairFilter/src/ButterworthLowPass.cpp	(revision 7)
+++ trunk/lib/FlairFilter/src/ButterworthLowPass.cpp	(revision 7)
@@ -0,0 +1,64 @@
+//  created:    2013/12/10
+//  filename:   ButterworthLowPass.cpp
+//
+//  author:     Guillaume Sanahuja
+//              Copyright Heudiasyc UMR UTC/CNRS 7253
+//
+//  version:    $Id: $
+//
+//  purpose:    Class defining a Butterworth low pass filter
+//
+//
+/*********************************************************************/
+
+#include "ButterworthLowPass.h"
+#include "ButterworthLowPass_impl.h"
+#include <cvmatrix.h>
+#include <Layout.h>
+#include <LayoutPosition.h>
+
+using std::string;
+using namespace flair::core;
+using namespace flair::gui;
+
+namespace flair
+{
+namespace filter
+{
+
+ButterworthLowPass::ButterworthLowPass(const IODevice* parent,const LayoutPosition* position,string name,int order): IODevice(parent,name)
+{
+    pimpl_=new ButterworthLowPass_impl(this,position,name,order);
+    AddDataToLog(pimpl_->output);
+}
+
+ButterworthLowPass::ButterworthLowPass(const gui::LayoutPosition* position,string name,int order): IODevice(position->getLayout(),name)
+{
+    pimpl_=new ButterworthLowPass_impl(this,position,name,order);
+    AddDataToLog(pimpl_->output);
+}
+
+
+ButterworthLowPass::~ButterworthLowPass()
+{
+    delete pimpl_;
+}
+
+cvmatrix *ButterworthLowPass::Matrix(void) const
+{
+    return pimpl_->output;
+}
+
+float ButterworthLowPass::Output(void) const
+{
+   return pimpl_->output->Value(0,0);
+}
+
+void ButterworthLowPass::UpdateFrom(const io_data *data)
+{
+    pimpl_->UpdateFrom(data);
+    ProcessUpdate(pimpl_->output);
+}
+
+} // end namespace filter
+} // end namespace flair
Index: trunk/lib/FlairFilter/src/ButterworthLowPass.h
===================================================================
--- trunk/lib/FlairFilter/src/ButterworthLowPass.h	(revision 7)
+++ trunk/lib/FlairFilter/src/ButterworthLowPass.h	(revision 7)
@@ -0,0 +1,103 @@
+/*!
+ * \file ButterworthLowPass.h
+ * \brief Class defining a Butterworth low pass filter
+ * \author Guillaume Sanahuja, Copyright Heudiasyc UMR UTC/CNRS 7253
+ * \date 2013/12/10
+ * \version 4.0
+ */
+
+#ifndef BUTTERWORTHLOWPASS_H
+#define BUTTERWORTHLOWPASS_H
+
+#include <IODevice.h>
+
+namespace flair
+{
+    namespace core
+    {
+        class cvmatrix;
+    }
+    namespace gui
+    {
+        class LayoutPosition;
+    }
+}
+
+class ButterworthLowPass_impl;
+
+namespace flair
+{
+namespace filter
+{
+    /*! \class ButterworthLowPass
+    *
+    * \brief Class defining a Butterworth low pass filter
+    */
+    class ButterworthLowPass : public core::IODevice
+    {
+        public:
+            /*!
+            * \brief Constructor
+            *
+            * Construct a ButterworthLowPass at position. \n
+            * After calling this function, position will be deleted as it is no longer usefull. \n
+            * The filter is automatically updated when parent's
+            * IODevice::ProcessUpdate is called.
+            *
+            * \param parent parent
+            * \param position position to display settings
+            * \param name name
+            * \param order order of the filter
+            */
+            ButterworthLowPass(const IODevice* parent,const gui::LayoutPosition* position,std::string name,int order);
+
+            /*!
+            * \brief Constructor
+            *
+            * Construct a ButterworthLowPass at position. \n
+            * The ButterworthLowPass will automatically be child of position->getLayout() Layout. After calling this function,
+            * position will be deleted as it is no longer usefull. \n
+            * The filter is updated manually with UpdateFrom method. \n
+            *
+            * \param position position to display settings
+            * \param name name
+            * \param order order of the filter
+            */
+            ButterworthLowPass(const gui::LayoutPosition* position,std::string name,int order);
+
+            /*!
+            * \brief Destructor
+            *
+            */
+            ~ButterworthLowPass();
+
+            /*!
+            * \brief Output value
+            *
+            * \return filtered output
+            */
+            float Output(void) const;
+
+            /*!
+            * \brief Output matrix
+            *
+            * \return filtered output
+            */
+            core::cvmatrix* Matrix(void)const ;
+
+            /*!
+            * \brief Update using provided datas
+            *
+            * Reimplemented from IODevice.
+            *
+            * \param data data from the parent to process
+            */
+            void UpdateFrom(const core::io_data *data);
+
+        private:
+
+            class ButterworthLowPass_impl* pimpl_;
+    };
+} // end namespace filter
+} // end namespace flair
+#endif // BUTTERWORTHLOWPASS_H
Index: trunk/lib/FlairFilter/src/ButterworthLowPass_impl.cpp
===================================================================
--- trunk/lib/FlairFilter/src/ButterworthLowPass_impl.cpp	(revision 7)
+++ trunk/lib/FlairFilter/src/ButterworthLowPass_impl.cpp	(revision 7)
@@ -0,0 +1,96 @@
+//  created:    2013/12/10
+//  filename:   ButterworthLowPass_impl.cpp
+//
+//  author:     Guillaume Sanahuja
+//              Copyright Heudiasyc UMR UTC/CNRS 7253
+//
+//  version:    $Id: $
+//
+//  purpose:    objet permettant le calcul d'un filtre passe bas de Butterworth
+//
+//
+/*********************************************************************/
+
+#include "ButterworthLowPass_impl.h"
+#include "ButterworthLowPass.h"
+#include <cvmatrix.h>
+#include <Layout.h>
+#include <GroupBox.h>
+#include <SpinBox.h>
+#include <DoubleSpinBox.h>
+
+using std::string;
+using namespace flair::core;
+using namespace flair::gui;
+using namespace flair::filter;
+
+ButterworthLowPass_impl::ButterworthLowPass_impl(ButterworthLowPass* self,const LayoutPosition* position,string name,int order)
+{
+    //init UI
+    GroupBox* reglages_groupbox=new GroupBox(position,name);
+        T=new DoubleSpinBox(reglages_groupbox->NewRow(),"period, 0 for auto"," s",0,10,0.01);
+        cutoff=new DoubleSpinBox(reglages_groupbox->NewRow(),"cutoff frequency"," Hz",0,10000,0.1,2,1);
+
+    cvmatrix_descriptor* desc=new cvmatrix_descriptor(1,1);
+    desc->SetElementName(0,0,"output");
+    output=new cvmatrix(self,desc,floatType,name);
+
+    output->SetValue(0,0,0);
+
+	f= new PoleFilter(order);
+
+    if(T->Value()!=0) f->setup(1./T->Value(), cutoff->Value());
+	f->reset();
+
+	first_update=true;
+}
+
+ButterworthLowPass_impl::~ButterworthLowPass_impl()
+{
+    delete f;
+}
+
+void ButterworthLowPass_impl::UpdateFrom(const io_data *data)
+{
+    float result;
+    cvmatrix *input=(cvmatrix*)data;
+
+    if(T->ValueChanged() || cutoff->ValueChanged())
+    {
+        if(T->Value()!=0)
+        {
+            f->setup (1./T->Value(), cutoff->Value());
+        }
+        else
+        {
+            first_update=true;
+        }
+    }
+
+    //on prend une fois pour toute les mutex et on fait des accès directs
+    output->GetMutex();
+    input->GetMutex();
+
+    if(T->Value()==0)
+    {
+        float delta_t=(float)(data->DataTime()-previous_time)/1000000000.;
+        f->setup (1./delta_t, cutoff->Value());
+    }
+
+    if(first_update==true)
+    {
+        first_update=false;
+    }
+    else
+    {
+        result = f->filter(input->ValueNoMutex(0,0));
+        output->SetValueNoMutex(0,0,result);
+    }
+
+    input->ReleaseMutex();
+    output->ReleaseMutex();
+
+    output->SetDataTime(data->DataTime());
+    previous_time=data->DataTime();
+}
+
Index: trunk/lib/FlairFilter/src/ControlLaw.cpp
===================================================================
--- trunk/lib/FlairFilter/src/ControlLaw.cpp	(revision 7)
+++ trunk/lib/FlairFilter/src/ControlLaw.cpp	(revision 7)
@@ -0,0 +1,64 @@
+//  created:    2014/04/30
+//  filename:   ControlLaw.cpp
+//
+//  author:     Guillaume Sanahuja
+//              Copyright Heudiasyc UMR UTC/CNRS 7253
+//
+//  version:    $Id: $
+//
+//  purpose:    Base class for control law
+//
+//
+/*********************************************************************/
+
+#include "ControlLaw.h"
+#include <cvmatrix.h>
+#include <cvmatrix_descriptor.h>
+#include <DataPlot1D.h>
+#include <sstream>
+
+using std::string;
+using namespace flair::core;
+using namespace flair::gui;
+
+namespace flair {
+namespace filter {
+
+ControlLaw::ControlLaw(const Object* parent,string name,uint32_t nb_out) : IODevice(parent,name) {
+    if(nb_out==1) {
+        output=new cvmatrix(this,nb_out,1,floatType,name);
+    } else {
+        cvmatrix_descriptor* desc=new cvmatrix_descriptor(nb_out,1);
+        for(int i=0;i<nb_out;i++) {
+            std::stringstream ss;
+            ss << i;
+            desc->SetElementName(i,0,ss.str());
+        }
+        output=new cvmatrix(this,desc,floatType,name);
+    }
+
+    input=NULL;
+    AddDataToLog(output);
+}
+
+ControlLaw::~ControlLaw(void) {
+
+}
+
+void ControlLaw::Update(Time time) {
+    input->SetDataTime(time);
+    UpdateFrom(input);
+}
+
+float ControlLaw::Output(uint32_t index) const {
+    return output->Value(index,0);
+}
+
+void ControlLaw::UseDefaultPlot(const LayoutPosition* position) {
+    if(output->Rows()!=1) Warn("Output size is different from 1. Plotting only Output(1,1).\n");
+
+    DataPlot1D *plot=new DataPlot1D(position,ObjectName(),-1,1);
+    plot->AddCurve(output->Element(0));
+}
+} // end namespace filter
+} // end namespace flair
Index: trunk/lib/FlairFilter/src/ControlLaw.h
===================================================================
--- trunk/lib/FlairFilter/src/ControlLaw.h	(revision 7)
+++ trunk/lib/FlairFilter/src/ControlLaw.h	(revision 7)
@@ -0,0 +1,118 @@
+/*!
+ * \file ControlLaw.h
+ * \brief Base class for control law
+ * \author Guillaume Sanahuja, Copyright Heudiasyc UMR UTC/CNRS 7253
+ * \date 2014/04/30
+ * \version 4.0
+ */
+
+#ifndef CONTROLLAW_H
+#define CONTROLLAW_H
+
+#include <IODevice.h>
+
+namespace flair {
+    namespace gui {
+        class LayoutPosition;
+    }
+    namespace core {
+        class cvmatrix;
+    }
+}
+
+namespace flair { namespace filter {
+    /*! \class ControlLaw
+    *
+    * \brief Base class for control law
+    * input must be created by reimplemented class.\n
+    * output is created by this class, it is of size (nb_out,1) and type float.\n
+    * see constructor for nb_out
+    */
+    class ControlLaw : public core::IODevice {
+        public:
+            /*!
+            * \brief Constructor
+            *
+            * Construct a ControlLaw
+            *
+            * \param parent parent
+            * \param name name
+            * \param nb_out number of output
+            */
+            ControlLaw(const core::Object* parent,std::string name,uint32_t nb_out=1);
+
+            /*!
+            * \brief Destructor
+            *
+            */
+            ~ControlLaw();
+
+            /*!
+            * \brief Output value
+            *
+            * \param index output index, between 0 and nb_out-1
+            *
+            * \return output value
+            */
+            float Output(uint32_t index=0) const;
+
+            /*!
+            * \brief Use default plot
+            *
+            * Plot the output value at given position. \n
+            * Only Output(1,1) is plotted. \n
+            * In case of a mutliple output ControlLaw, this function should be reimplemented. \n
+            * After calling this function, position will be deleted as it is no longer usefull. \n
+            *
+            * \param position position to display plot
+            */
+            virtual void UseDefaultPlot(const gui::LayoutPosition* position);
+
+            /*!
+            * \brief Update using provided datas
+            *
+            * Reimplemented class must fill input matrix before calling this.
+            *
+            * \param time time of the update
+            */
+            void Update(core::Time time);
+
+            /*!
+            * \brief Reset the internal state of the control law
+            *
+            * Doesn't do anything by default
+            *
+            */
+            virtual void Reset() {};
+
+        protected:
+            /*!
+            * \brief input matrix
+            *
+            * This matrix must be created by the reimplemented class.
+            *
+            */
+            core::cvmatrix *input;
+
+            /*!
+            * \brief output matrix
+            *
+            * This matrix is created by this class. Its size is (nb_out,1) and its type
+            * is io_data::Float.
+            *
+            */
+            core::cvmatrix *output;
+
+        private:
+            /*!
+            * \brief Update using provided datas
+            *
+            * Reimplemented from IODevice.
+            *
+            * \param data data from the parent to process
+            */
+            virtual void UpdateFrom(const core::io_data *data)=0;
+    };
+} // end namespace filter
+} // end namespace flair
+#endif // CONTROLLAW_H
Index: trunk/lib/FlairFilter/src/EulerDerivative.cpp
===================================================================
--- trunk/lib/FlairFilter/src/EulerDerivative.cpp	(revision 7)
+++ trunk/lib/FlairFilter/src/EulerDerivative.cpp	(revision 7)
@@ -0,0 +1,56 @@
+//  created:    2011/05/01
+//  filename:   EulerDerivative.cpp
+//
+//  author:     Guillaume Sanahuja
+//              Copyright Heudiasyc UMR UTC/CNRS 7253
+//
+//  version:    $Id: $
+//
+//  purpose:    Class defining an euler derivative
+//
+//
+/*********************************************************************/
+
+#include "EulerDerivative.h"
+#include "EulerDerivative_impl.h"
+#include <cvmatrix.h>
+#include <LayoutPosition.h>
+
+using std::string;
+using namespace flair::core;
+using namespace flair::gui;
+
+namespace flair
+{
+namespace filter
+{
+
+EulerDerivative::EulerDerivative(const IODevice* parent,const LayoutPosition* position,string name,const cvmatrix* init_value) : IODevice(parent,name)
+{
+    pimpl_=new EulerDerivative_impl(this,position,name,init_value);
+    AddDataToLog(pimpl_->output);
+}
+
+EulerDerivative::~EulerDerivative()
+{
+    delete pimpl_;
+}
+
+cvmatrix* EulerDerivative::Matrix(void) const
+{
+    return pimpl_->output;
+}
+
+float EulerDerivative::Output(int row,int col) const
+{
+    return pimpl_->output->Value(row,col);
+}
+
+void EulerDerivative::UpdateFrom(const io_data *data)
+{
+    pimpl_->UpdateFrom(data);
+    ProcessUpdate(pimpl_->output);
+}
+
+} // end namespace filter
+} // end namespace flair
Index: trunk/lib/FlairFilter/src/EulerDerivative.h
===================================================================
--- trunk/lib/FlairFilter/src/EulerDerivative.h	(revision 7)
+++ trunk/lib/FlairFilter/src/EulerDerivative.h	(revision 7)
@@ -0,0 +1,96 @@
+/*!
+ * \file EulerDerivative.h
+ * \brief Class defining an euler derivative
+ * \author Guillaume Sanahuja, Copyright Heudiasyc UMR UTC/CNRS 7253
+ * \date 2011/05/01
+ * \version 4.0
+ */
+
+#ifndef EULERDERIVATIVE_H
+#define EULERDERIVATIVE_H
+
+#include <IODevice.h>
+
+namespace flair
+{
+    namespace core
+    {
+        class cvmatrix;
+    }
+    namespace gui
+    {
+        class LayoutPosition;
+    }
+}
+
+class EulerDerivative_impl;
+
+namespace flair
+{
+namespace filter
+{
+    /*! \class EulerDerivative
+    *
+    * \brief Class defining an euler derivative
+    */
+
+    class EulerDerivative : public core::IODevice
+    {
+        public:
+            /*!
+            * \brief Constructor
+            *
+            * Construct an EulerDerivative at given position. \n
+            * After calling this function, position will be deleted as it is no longer usefull. \n
+            * The filter is automatically updated when parent's
+            * IODevice::ProcessUpdate is called. \n
+            * The optional init_value parameters allow to specify
+            * the size of the input datas and its inital values.
+            * If unspecified, a 1*1 size is used, and values are
+            * initialized with 0.
+            *
+            * \param parent parent
+            * \param position position to display settings
+            * \param name name
+            * \param init_value initial value
+            */
+            EulerDerivative(const core::IODevice* parent,const gui::LayoutPosition* position,std::string name,const core::cvmatrix* init_value=NULL);
+
+            /*!
+            * \brief Destructor
+            *
+            */
+            ~EulerDerivative();
+
+            /*!
+            * \brief Output value
+            *
+            * \param row row element
+            * \param col column element
+            *
+            * \return element value
+            */
+            float Output(int row, int col) const;
+
+            /*!
+            * \brief Output matrix
+            *
+            * \return filtered output
+            */
+            core::cvmatrix *Matrix(void) const;
+
+        private:
+            /*!
+            * \brief Update using provided datas
+            *
+            * Reimplemented from IODevice.
+            *
+            * \param data data from the parent to process
+            */
+            void UpdateFrom(const core::io_data *data);
+
+            class EulerDerivative_impl* pimpl_;
+    };
+} // end namespace filter
+} // end namespace flair
+#endif // EULERDERIVATIVE_H
Index: trunk/lib/FlairFilter/src/EulerDerivative_impl.cpp
===================================================================
--- trunk/lib/FlairFilter/src/EulerDerivative_impl.cpp	(revision 7)
+++ trunk/lib/FlairFilter/src/EulerDerivative_impl.cpp	(revision 7)
@@ -0,0 +1,114 @@
+//  created:    2011/05/01
+//  filename:   EulerDerivative.cpp
+//
+//  author:     Guillaume Sanahuja
+//              Copyright Heudiasyc UMR UTC/CNRS 7253
+//
+//  version:    $Id: $
+//
+//  purpose:    objet permettant le calcul d'une derivee d'Euler
+//
+//
+/*********************************************************************/
+
+#include "EulerDerivative.h"
+#include "EulerDerivative_impl.h"
+#include <cvmatrix.h>
+#include <Layout.h>
+#include <GroupBox.h>
+#include <DoubleSpinBox.h>
+
+using std::string;
+using namespace flair::core;
+using namespace flair::gui;
+using namespace flair::filter;
+
+EulerDerivative_impl::EulerDerivative_impl(EulerDerivative* self,const LayoutPosition* position,string name,const cvmatrix* init_value)
+{
+    first_update=true;
+
+    if(init_value!=NULL)
+    {
+        prev_value=(cvmatrix*)init_value;
+    }
+    else
+    {
+        //if NULL, assume dimension 1, and init=0
+        cvmatrix_descriptor* desc=new cvmatrix_descriptor(1,1);
+        desc->SetElementName(0,0,"output");
+        prev_value=new cvmatrix(self,desc,floatType,name);
+        prev_value->SetValue(0,0,0);
+    }
+
+    //init UI
+    GroupBox* reglages_groupbox=new GroupBox(position,name);
+        T=new DoubleSpinBox(reglages_groupbox->NewRow(),"period, 0 for auto:"," s",0,1,0.01);
+
+    //init output matrix of same size as init
+    cvmatrix_descriptor* desc=new cvmatrix_descriptor(prev_value->Rows(),prev_value->Cols());
+
+    for(int i=0;i<prev_value->Rows();i++)
+    {
+        for(int j=0;j<prev_value->Cols();j++)
+        {
+            desc->SetElementName(i,j,prev_value->Name(i,j));
+        }
+    }
+
+    output=new cvmatrix(self,desc,prev_value->GetDataType().GetElementDataType(),name);
+}
+
+EulerDerivative_impl::~EulerDerivative_impl()
+{
+
+}
+
+void EulerDerivative_impl::UpdateFrom(const io_data *data)
+{
+    float delta_t;
+    cvmatrix *input=(cvmatrix*)data;
+
+    //on prend une fois pour toute les mutex et on fait des accès directs
+    output->GetMutex();
+    input->GetMutex();
+
+    if(first_update==true)
+    {
+        for(int i=0;i<input->Rows();i++)
+        {
+            for(int j=0;j<input->Cols();j++)
+            {
+                output->SetValueNoMutex(i,j,prev_value->ValueNoMutex(i,j));
+                prev_value->SetValueNoMutex(i,j,input->ValueNoMutex(i,j));
+            }
+        }
+        first_update=false;
+    }
+    else
+    {
+        if(T->Value()==0)
+        {
+            delta_t=(float)(data->DataTime()-previous_time)/1000000000.;
+        }
+        else
+        {
+            delta_t=T->Value();
+        }
+
+        for(int i=0;i<input->Rows();i++)
+        {
+            for(int j=0;j<input->Cols();j++)
+            {
+                output->SetValueNoMutex(i,j,(input->ValueNoMutex(i,j)-prev_value->ValueNoMutex(i,j))/delta_t);
+                prev_value->SetValueNoMutex(i,j,input->ValueNoMutex(i,j));
+            }
+        }
+    }
+
+    input->ReleaseMutex();
+    output->ReleaseMutex();
+
+    output->SetDataTime(data->DataTime());
+    previous_time=data->DataTime();
+}
+
Index: trunk/lib/FlairFilter/src/Gx3_25_ahrs.cpp
===================================================================
--- trunk/lib/FlairFilter/src/Gx3_25_ahrs.cpp	(revision 7)
+++ trunk/lib/FlairFilter/src/Gx3_25_ahrs.cpp	(revision 7)
@@ -0,0 +1,51 @@
+//  created:    2013/01/16
+//  filename:   Gx3_25_ahrs.cpp
+//
+//  author:     Guillaume Sanahuja
+//              Copyright Heudiasyc UMR UTC/CNRS 7253
+//
+//  version:    $Id: $
+//
+//  purpose:    class for 3dmgx3-25 ahrs
+//
+//
+/*********************************************************************/
+
+#include "Gx3_25_ahrs.h"
+#include <FrameworkManager.h>
+#include <AhrsData.h>
+
+using std::string;
+using namespace flair::core;
+using namespace flair::sensor;
+
+namespace flair { namespace filter {
+
+Gx3_25_ahrs::Gx3_25_ahrs(const FrameworkManager* parent,string name,SerialPort *serialport,Gx3_25_imu::Command_t command,uint8_t priority) : Ahrs(new Gx3_25_imu(parent,name,serialport,command,priority),name) {
+}
+
+Gx3_25_ahrs::~Gx3_25_ahrs() {
+}
+
+void Gx3_25_ahrs::Start(void) {
+    ((Gx3_25_imu*)GetImu())->Start();
+}
+
+//datas from Gx3_25_imu are AhrsData!
+void Gx3_25_ahrs::UpdateFrom(const io_data *data) {
+    AhrsData *input=(AhrsData*)data;
+    AhrsData *output;
+    GetDatas(&output);
+
+    Quaternion quaternion;
+    Vector3D filteredAngRates;
+    input->GetQuaternionAndAngularRates(quaternion,filteredAngRates);
+    output->SetQuaternionAndAngularRates(quaternion,filteredAngRates);
+    output->SetDataTime(input->DataTime());
+
+    ProcessUpdate(output);
+}
+
+} // end namespace filter
+} // end namespace flair
+
Index: trunk/lib/FlairFilter/src/Gx3_25_ahrs.h
===================================================================
--- trunk/lib/FlairFilter/src/Gx3_25_ahrs.h	(revision 7)
+++ trunk/lib/FlairFilter/src/Gx3_25_ahrs.h	(revision 7)
@@ -0,0 +1,65 @@
+/*!
+ * \file Gx3_25_ahrs.h
+ * \brief Class for 3dmgx3-25 ahrs
+ * \author Guillaume Sanahuja, Copyright Heudiasyc UMR UTC/CNRS 7253
+ * \date 2013/01/16
+ * \version 4.0
+ */
+
+#ifndef GX3_25_AHRS_H
+#define GX3_25_AHRS_H
+
+#include <Ahrs.h>
+#include <Gx3_25_imu.h>
+
+namespace flair
+{
+namespace filter
+{
+    /*! \class Gx3_25_ahrs
+    *
+    * \brief Class for 3dmgx3-25 ahrs
+    *
+    * This class constructs a Gx3_25_imu as Imu of this Ahrs.
+    */
+    class Gx3_25_ahrs : public Ahrs
+    {
+        public:
+            /*!
+            * \brief Constructor
+            *
+            * Construct an Ahrs for 3dmgx3-25
+            *
+            * \param parent parent
+            * \param name name
+            * \param serialport Imu SerialPort
+            * \param command command for the Gx3_25_imu continuous mode
+            * \param priority priority of the Gx3_25_imu Thread
+            */
+            Gx3_25_ahrs(const core::FrameworkManager* parent,std::string name,core::SerialPort *serialport,sensor::Gx3_25_imu::Command_t command,uint8_t priority);
+
+            /*!
+            * \brief Destructor
+            *
+            */
+            ~Gx3_25_ahrs();
+
+            /*!
+            * \brief Start Gx3_25_imu Thread
+            *
+            */
+            void Start(void);
+
+        private:
+            /*!
+            * \brief Update using provided datas
+            *
+            * Reimplemented from IODevice.
+            *
+            * \param data data from the parent to process
+            */
+            void UpdateFrom(const core::io_data *data);
+    };
+} // end namespace filter
+} // end namespace flair
+#endif // GX3_25_AHRS_H
Index: trunk/lib/FlairFilter/src/JoyReference.cpp
===================================================================
--- trunk/lib/FlairFilter/src/JoyReference.cpp	(revision 7)
+++ trunk/lib/FlairFilter/src/JoyReference.cpp	(revision 7)
@@ -0,0 +1,116 @@
+//  created:    2012/08/29
+//  filename:   JoyReference.cpp
+//
+//  author:     Guillaume Sanahuja
+//              Copyright Heudiasyc UMR UTC/CNRS 7253
+//
+//  version:    $Id: $
+//
+//  purpose:    generation de consignes a partir joystick
+//
+//
+/*********************************************************************/
+
+#include "JoyReference.h"
+#include "JoyReference_impl.h"
+#include <Layout.h>
+#include <LayoutPosition.h>
+#include <cvmatrix.h>
+#include <AhrsData.h>
+#include <Euler.h>
+#include <Quaternion.h>
+
+using std::string;
+using namespace flair::core;
+using namespace flair::gui;
+
+namespace flair { namespace filter {
+
+JoyReference::JoyReference(const LayoutPosition* position,string name) : IODevice(position->getLayout(),name) {
+    pimpl_=new JoyReference_impl(this,position,name);
+    AddDataToLog(pimpl_->output);
+    AddDataToLog(pimpl_->ahrsData);
+}
+
+JoyReference::~JoyReference(void) {
+    delete pimpl_;
+}
+
+AhrsData* JoyReference::GetReferenceOrientation(void) const{
+    return pimpl_->ahrsData;
+}
+
+void JoyReference::SetRollAxis(float value) {
+    pimpl_->SetRollAxis(value);
+}
+
+void JoyReference::SetPitchAxis(float value) {
+    pimpl_->SetPitchAxis(value);
+}
+
+void JoyReference::SetYawAxis(float value) {
+    pimpl_->SetYawAxis(value);
+}
+
+void JoyReference::SetAltitudeAxis(float value) {
+    pimpl_->SetAltitudeAxis(value);
+}
+
+void JoyReference::RollTrimUp(void) {
+    pimpl_->RollTrimUp();
+}
+
+void JoyReference::RollTrimDown(void) {
+    pimpl_->RollTrimDown();
+}
+
+void JoyReference::PitchTrimUp(void) {
+    pimpl_->PitchTrimUp();
+}
+
+void JoyReference::PitchTrimDown(void) {
+    pimpl_->PitchTrimDown();
+}
+
+void JoyReference::SetYawRef(float value) {
+    pimpl_->SetYawRef(value);
+}
+
+void JoyReference::SetYawRef(core::Quaternion const &value) {
+    Euler euler;
+    value.ToEuler(euler);
+    pimpl_->SetYawRef(euler.yaw);
+}
+void JoyReference::SetZRef(float value) {
+    pimpl_->SetZRef(value);
+}
+
+float JoyReference::ZRef(void) const {
+    return pimpl_->ZRef();
+}
+
+float JoyReference::DzRef(void) const {
+    return pimpl_->dZRef();
+}
+
+float JoyReference::RollTrim(void) const {
+    return pimpl_->RollTrim();
+}
+
+float JoyReference::PitchTrim(void) const {
+    return pimpl_->PitchTrim();
+}
+
+void JoyReference::Update(Time time) {
+    pimpl_->Update(time);
+    ProcessUpdate(pimpl_->output);
+}
+
+void JoyReference::UpdateFrom(const io_data *data) {
+    pimpl_->UpdateFrom(data);
+    ProcessUpdate(pimpl_->output);
+}
+
+} // end namespace sensor
+} // end namespace flair
+
Index: trunk/lib/FlairFilter/src/JoyReference.h
===================================================================
--- trunk/lib/FlairFilter/src/JoyReference.h	(revision 7)
+++ trunk/lib/FlairFilter/src/JoyReference.h	(revision 7)
@@ -0,0 +1,200 @@
+/*!
+ * \file JoyReference.h
+ * \brief Class creating references from a joystick
+ * \author Guillaume Sanahuja, Copyright Heudiasyc UMR UTC/CNRS 7253
+ * \date 2012/08/29
+ * \version 4.0
+ */
+
+#ifndef JOYREFERENCE_H
+#define JOYREFERENCE_H
+
+#include <IODevice.h>
+#include <stdint.h>
+
+namespace flair
+{
+    namespace core {
+        class Quaternion;
+        class AhrsData;
+    }
+    namespace gui {
+        class LayoutPosition;
+    }
+}
+
+class JoyReference_impl;
+
+namespace flair { namespace filter {
+    /*! \class JoyReference
+    *
+    * \brief Class creating references from a joystick
+    */
+    class JoyReference : public core::IODevice
+    {
+        public:
+            /*!
+            * \brief Constructor
+            *
+            * Construct a JoyReference at given position. \n
+            * The JoyReference will automatically be child of position->getLayout() Layout. After calling this function,
+            * position will be deleted as it is no longer usefull. \n
+            * JoyReference compute reference in quaternion, wz, altitude and altitude speed.
+            *
+            * \param position position
+            * \param name name
+            */
+            JoyReference(const gui::LayoutPosition* position,std::string name);
+
+            /*!
+            * \brief Destructor
+            *
+            */
+            ~JoyReference();
+
+            /*!
+            * \brief Set roll axis value
+            *
+            * \param value value
+            */
+            void SetRollAxis(float value);
+
+            /*!
+            * \brief Set pitch axis value
+            *
+            * \param value value
+            */
+            void SetPitchAxis(float value);
+
+            /*!
+            * \brief Set yaw axis value
+            *
+            * \param value value
+            */
+            void SetYawAxis(float value);
+
+            /*!
+            * \brief Set thrust axis value
+            *
+            * \param value value
+            */
+            void SetAltitudeAxis(float value);
+
+            /*!
+            * \brief Get orientation reference
+            *
+            * \return reference
+            */
+            core::AhrsData* GetReferenceOrientation(void) const;
+
+            /*!
+            * \brief Get z reference
+            *
+            * \return reference
+            */
+            float ZRef(void) const;
+
+            /*!
+            * \brief Get z derivative reference
+            *
+            * \return reference
+            */
+            float DzRef(void) const;
+
+            /*!
+            * \brief Get roll trim
+            *
+            * \return trim value
+            */
+            float RollTrim(void) const;
+
+            /*!
+            * \brief Get pitch trim
+            *
+            * \return trim value
+            */
+            float PitchTrim(void) const;
+
+            /*!
+            * \brief Set yaw reference
+            *
+            * Yaw part of the output quaternion is obtained by integrating the wz desired angular speed.\n
+            * This method reset the yaw.
+            *
+            * \param value value
+            */
+            void SetYawRef(float value);
+
+            /*!
+            * \brief Set yaw reference
+            *
+            * Yaw part of the output quaternion is obtained by integrating the wz desired angular speed.\n
+            * This method reset the yaw.
+            *
+            * \param value value, only the yaw part of the quaternion is used
+            */
+            void SetYawRef(core::Quaternion const &value);
+
+            /*!
+            * \brief Set z reference
+            *
+            * Altitude of the output is obtained by integrating the vz desired altitude speed.\n
+            * This method reset z.
+            *
+            * \param value value
+            */
+            void SetZRef(float value);
+
+            /*!
+            * \brief Trim up roll
+            *
+            * Roll trim value is increased by one
+            */
+            void RollTrimUp(void);
+
+            /*!
+            * \brief Trim down roll
+            *
+            * Roll trim value is decreased by one
+            */
+            void RollTrimDown(void);
+
+            /*!
+            * \brief Trim up pitch
+            *
+            * Pitch trim value is increased by one
+            */
+            void PitchTrimUp(void);
+
+            /*!
+            * \brief Trim down pitch
+            *
+            * Pitch trim value is decreased by one
+            */
+            void PitchTrimDown(void);
+
+            /*!
+            * \brief Update references
+            *
+            * Calls UpdateFrom with values entered manually.
+            *
+            * \param time time
+            */
+            void Update(core::Time time);
+
+        private:
+            /*!
+            * \brief Update using provided datas
+            *
+            * Reimplemented from IODevice.
+            *
+            * \param data data from the parent to process
+            */
+            void UpdateFrom(const core::io_data *data);
+
+            class JoyReference_impl* pimpl_;
+    };
+} // end namespace sensor
+} // end namespace flair
+
+#endif // JOYREFERENCE_H
Index: trunk/lib/FlairFilter/src/JoyReference_impl.cpp
===================================================================
--- trunk/lib/FlairFilter/src/JoyReference_impl.cpp	(revision 7)
+++ trunk/lib/FlairFilter/src/JoyReference_impl.cpp	(revision 7)
@@ -0,0 +1,198 @@
+//  created:    2012/08/29
+//  filename:   JoyReference_impl.cpp
+//
+//  author:     Guillaume Sanahuja
+//              Copyright Heudiasyc UMR UTC/CNRS 7253
+//
+//  version:    $Id: $
+//
+//  purpose:    generation de consignes a partir joystick
+//
+//
+/*********************************************************************/
+
+#include "JoyReference_impl.h"
+#include "JoyReference.h"
+#include <AhrsData.h>
+#include <Euler.h>
+#include <cvmatrix.h>
+#include <Layout.h>
+#include <GroupBox.h>
+#include <DoubleSpinBox.h>
+#include <SpinBox.h>
+#include <Label.h>
+#include <PushButton.h>
+#include <math.h>
+
+using std::string;
+using namespace flair::core;
+using namespace flair::gui;
+using namespace flair::filter;
+
+JoyReference_impl::JoyReference_impl(JoyReference *inSelf,const LayoutPosition* position,string name): self(inSelf) {
+
+    ahrsData= new AhrsData(self);
+	input=new cvmatrix(self,4,1,floatType,name);
+
+	cvmatrix_descriptor* desc=new cvmatrix_descriptor(4,1);
+	desc->SetElementName(0,0,"z");;
+	desc->SetElementName(1,0,"dz");
+    desc->SetElementName(2,0,"trim_roll");
+    desc->SetElementName(3,0,"trim_pitch");
+    output=new cvmatrix(self,desc,floatType,name);
+
+	reglages_groupbox=new GroupBox(position,name);
+    deb_roll=new DoubleSpinBox(reglages_groupbox->NewRow(),"debattement roll"," deg",-45,45,1,0);
+    deb_pitch=new DoubleSpinBox(reglages_groupbox->LastRowLastCol(),"debattement pitch"," deg",-45,45,1,0);
+    deb_wz=new DoubleSpinBox(reglages_groupbox->NewRow(),"debattement wz"," deg/s",-180,180,1,0);
+    deb_dz=new DoubleSpinBox(reglages_groupbox->LastRowLastCol(),"debattement dz"," m/s",-2,2,0.1,1);
+    trim=new DoubleSpinBox(reglages_groupbox->NewRow(),"trim",-1,1,0.01);
+    label_roll=new Label(reglages_groupbox->NewRow(),"trim roll");
+    button_roll=new PushButton(reglages_groupbox->LastRowLastCol(),"reset roll trim");
+    label_pitch=new Label(reglages_groupbox->NewRow(),"trim pitch");
+    button_pitch=new PushButton(reglages_groupbox->LastRowLastCol(),"reset pitch trim");
+
+    z_ref=0;
+    previous_time=0;
+    trim_roll=0;
+    trim_pitch=0;
+
+    label_roll->SetText("trim roll: %.2f",trim_roll);
+    label_pitch->SetText("trim pitch: %.2f",trim_pitch);
+}
+
+JoyReference_impl::~JoyReference_impl(void) {
+}
+
+void JoyReference_impl::SetRollAxis(float value) {
+    input->SetValue(0,0,value);
+}
+
+void JoyReference_impl::SetPitchAxis(float value) {
+    input->SetValue(1,0,value);
+}
+
+void JoyReference_impl::SetYawAxis(float value) {
+    input->SetValue(2,0,value);
+}
+
+void JoyReference_impl::SetAltitudeAxis(float value) {
+    input->SetValue(3,0,value);
+}
+
+void JoyReference_impl::RollTrimUp(void) {
+    trim_roll+=trim->Value();
+    output->SetValue(2,0,trim_roll);
+    label_roll->SetText("trim roll: %.2f",trim_roll);
+}
+
+void JoyReference_impl::RollTrimDown(void) {
+    trim_roll-=trim->Value();
+    output->SetValue(2,0,trim_roll);
+    label_roll->SetText("trim roll: %.2f",trim_roll);
+}
+
+void JoyReference_impl::PitchTrimUp(void) {
+    trim_pitch+=trim->Value();
+    output->SetValue(3,0,trim_pitch);
+    label_pitch->SetText("trim pitch: %.2f",trim_pitch);
+}
+
+void JoyReference_impl::PitchTrimDown(void) {
+    trim_pitch-=trim->Value();
+    output->SetValue(3,0,trim_pitch);
+    label_pitch->SetText("trim pitch: %.2f",trim_pitch);
+}
+
+void JoyReference_impl::SetYawRef(float value) {
+    Euler ref(0,0,value);
+    input->GetMutex();
+    ref.ToQuaternion(q_z);
+    input->ReleaseMutex();
+
+    Update(GetTime());
+}
+
+void JoyReference_impl::SetZRef(float value) {
+    z_ref=value;
+    output->SetValue(0,0,z_ref);
+}
+
+float JoyReference_impl::ZRef(void) const {
+    return output->Value(0,0);
+}
+
+float JoyReference_impl::dZRef(void) const {
+   return output->Value(1,0);
+}
+
+float JoyReference_impl::RollTrim(void) const {
+    return trim_roll;
+}
+
+float JoyReference_impl::PitchTrim(void) const {
+    return trim_pitch;
+}
+
+void JoyReference_impl::Update(Time time) {
+    input->SetDataTime(time);
+    UpdateFrom(input);
+}
+
+void JoyReference_impl::UpdateFrom(const io_data *data) {
+    cvmatrix *input=(cvmatrix*)data;
+
+    if(previous_time==0) previous_time=data->DataTime();//pour la premiere iteration
+    float delta_t=(float)(data->DataTime()-previous_time)/1000000000.;
+    previous_time=data->DataTime();
+
+    if(button_roll->Clicked()==true) {
+        trim_roll=0;
+        output->SetValue(2,0,0);
+        label_roll->SetText("trim roll: %.2f",trim_roll);
+    }
+    if(button_pitch->Clicked()==true) {
+        trim_pitch=0;
+        output->SetValue(3,0,0);
+        label_pitch->SetText("trim pitch: %.2f",trim_pitch);
+    }
+
+    //les box sont en degrés
+    input->GetMutex();
+
+    Vector3D theta_xy(-Euler::ToRadian(input->ValueNoMutex(0,0)*deb_roll->Value()),
+                      -Euler::ToRadian(input->ValueNoMutex(1,0)*deb_pitch->Value()),
+                      0);
+    Vector3D e_bar=theta_xy;
+    e_bar.Normalize();
+    Quaternion q_xy(cos(theta_xy.GetNorm()/2.0f),
+                    e_bar.x*sin(theta_xy.GetNorm()/2.0f),
+                    e_bar.y*sin(theta_xy.GetNorm()/2.0f),
+                    0);
+    q_xy.Normalize();
+
+    float wz_ref=Euler::ToRadian(input->ValueNoMutex(2,0)*deb_wz->Value());
+	Quaternion w_zd(1,0,0,wz_ref*delta_t/2);
+	w_zd.Normalize();
+	q_z = q_z*w_zd;
+	q_z.Normalize();
+
+	Quaternion q_ref = q_z*q_xy;
+	q_ref.Normalize();
+
+    z_ref+=input->ValueNoMutex(3,0)*deb_dz->Value()*delta_t;
+    float dz_ref=input->ValueNoMutex(3,0)*deb_dz->Value();
+
+    input->ReleaseMutex();
+
+    ahrsData->SetQuaternionAndAngularRates(q_ref,Vector3D(0,0,wz_ref));
+
+    //ouput quaternion for control law
+    output->GetMutex();
+    output->SetValueNoMutex(0,0,z_ref);
+    output->SetValueNoMutex(1,0,dz_ref);
+    output->ReleaseMutex();
+
+    output->SetDataTime(data->DataTime());
+}
+
Index: trunk/lib/FlairFilter/src/LowPassFilter.cpp
===================================================================
--- trunk/lib/FlairFilter/src/LowPassFilter.cpp	(revision 7)
+++ trunk/lib/FlairFilter/src/LowPassFilter.cpp	(revision 7)
@@ -0,0 +1,56 @@
+//  created:    2011/05/01
+//  filename:   LowPassFilter.cpp
+//
+//  author:     Guillaume Sanahuja
+//              Copyright Heudiasyc UMR UTC/CNRS 7253
+//
+//  version:    $Id: $
+//
+//  purpose:    Class defining a first order low pass filter
+//
+//
+/*********************************************************************/
+
+#include "LowPassFilter.h"
+#include "LowPassFilter_impl.h"
+#include <cvmatrix.h>
+#include <LayoutPosition.h>
+
+using std::string;
+using namespace flair::core;
+using namespace flair::gui;
+
+namespace flair
+{
+namespace filter
+{
+
+LowPassFilter::LowPassFilter(const IODevice* parent,const LayoutPosition* position,string name,const cvmatrix* init_value) : IODevice(parent,name)
+{
+    pimpl_=new LowPassFilter_impl(this,position,name,init_value);
+    AddDataToLog(pimpl_->output);
+}
+
+LowPassFilter::~LowPassFilter()
+{
+    delete pimpl_;
+}
+
+cvmatrix *LowPassFilter::Matrix(void) const
+{
+    return pimpl_->output;
+}
+
+float LowPassFilter::Output(int row,int col) const
+{
+   return pimpl_->output->Value(row,col);
+}
+
+void LowPassFilter::UpdateFrom(const io_data *data)
+{
+    pimpl_->UpdateFrom(data);
+    ProcessUpdate(pimpl_->output);
+}
+
+} // end namespace filter
+} // end namespace flair
Index: trunk/lib/FlairFilter/src/LowPassFilter.h
===================================================================
--- trunk/lib/FlairFilter/src/LowPassFilter.h	(revision 7)
+++ trunk/lib/FlairFilter/src/LowPassFilter.h	(revision 7)
@@ -0,0 +1,96 @@
+/*!
+ * \file LowPassFilter.h
+ * \brief Class defining a first order low pass filter
+ * \author Guillaume Sanahuja, Copyright Heudiasyc UMR UTC/CNRS 7253
+ * \date 2011/05/01
+ * \version 4.0
+ */
+
+#ifndef LOWPASSFILTER_FILTER_H
+#define LOWPASSFILTER_FILTER_H
+
+#include <IODevice.h>
+
+namespace flair
+{
+    namespace core
+    {
+        class cvmatrix;
+    }
+    namespace gui
+    {
+        class Layout;
+        class LayoutPosition;
+    }
+}
+
+class LowPassFilter_impl;
+
+namespace flair
+{
+namespace filter
+{
+    /*! \class LowPassFilter
+    *
+    * \brief Class defining a first order low pass filter
+    */
+    class LowPassFilter : public core::IODevice
+    {
+        public:
+            /*!
+            * \brief Constructor
+            *
+            * Construct a LowPassFilter at position. \n
+            * After calling this function, position will be deleted as it is no longer usefull. \n
+            * The filter is automatically updated when parent's
+            * IODevice::ProcessUpdate is called. \n
+            * The optional init_value parameters allow to specify
+            * the size of the input datas and its inital values.
+            * If unspecified, a 1*1 size is used, and values are
+            * initialized with 0.
+            *
+            * \param parent parent
+            * \param position position to display settings
+            * \param name name
+            * \param init_value initial value
+            */
+            LowPassFilter(const core::IODevice* parent,const gui::LayoutPosition* position,std::string name,const core::cvmatrix* init_value=NULL);
+
+            /*!
+            * \brief Destructor
+            *
+            */
+            ~LowPassFilter();
+
+            /*!
+            * \brief Output value
+            *
+            * \param row row element
+            * \param col column element
+            *
+            * \return element value
+            */
+            float Output(int row, int col) const;
+
+            /*!
+            * \brief Output matrix
+            *
+            * \return filtered output
+            */
+            core::cvmatrix* Matrix(void) const;
+
+        private:
+            /*!
+            * \brief Update using provided datas
+            *
+            * Reimplemented from IODevice.
+            *
+            * \param data data from the parent to process
+            */
+            void UpdateFrom(const core::io_data *data);
+
+            class LowPassFilter_impl* pimpl_;
+    };
+} // end namespace filter
+} // end namespace flair
+#endif // LOWPASSFILTER_FILTER_H
Index: trunk/lib/FlairFilter/src/LowPassFilter_impl.cpp
===================================================================
--- trunk/lib/FlairFilter/src/LowPassFilter_impl.cpp	(revision 7)
+++ trunk/lib/FlairFilter/src/LowPassFilter_impl.cpp	(revision 7)
@@ -0,0 +1,127 @@
+//  created:    2011/05/01
+//  filename:   LowPassFilter_impl.cpp
+//
+//  author:     Guillaume Sanahuja
+//              Copyright Heudiasyc UMR UTC/CNRS 7253
+//
+//  version:    $Id: $
+//
+//  purpose:    objet permettant le calcul d'un filtre passe bas
+//
+//
+/*********************************************************************/
+
+#include "LowPassFilter_impl.h"
+#include "LowPassFilter.h"
+#include <cvmatrix.h>
+#include <Layout.h>
+#include <GroupBox.h>
+#include <SpinBox.h>
+#include <DoubleSpinBox.h>
+
+#define PI ((float)3.14159265358979323846)
+
+using std::string;
+using namespace flair::core;
+using namespace flair::gui;
+using namespace flair::filter;
+
+LowPassFilter_impl::LowPassFilter_impl(const LowPassFilter* self,const LayoutPosition* position,string name,const cvmatrix* init_value)
+{
+    first_update=true;
+
+    if(init_value!=NULL)
+    {
+        prev_value=(cvmatrix*)init_value;
+    }
+    else
+    {
+        //if NULL, assume dimension 1, and init=0
+        cvmatrix_descriptor* desc=new cvmatrix_descriptor(1,1);
+        desc->SetElementName(0,0,"output");
+        prev_value=new cvmatrix(self,desc,floatType,name);
+        prev_value->SetValue(0,0,0);
+    }
+
+    //init UI
+    GroupBox* reglages_groupbox=new GroupBox(position,name);
+        T=new DoubleSpinBox(reglages_groupbox->NewRow(),"period, 0 for auto"," s",0,10,0.01);
+        freq=new DoubleSpinBox(reglages_groupbox->NewRow(),"cutoff frequency"," Hz",0,10000,0.1,2,1);
+
+
+    //init output matrix of same size as init
+    cvmatrix_descriptor* desc=new cvmatrix_descriptor(prev_value->Rows(),prev_value->Cols());
+
+    for(int i=0;i<prev_value->Rows();i++)
+    {
+        for(int j=0;j<prev_value->Cols();j++)
+        {
+            desc->SetElementName(i,j,prev_value->Name(i,j));
+        }
+    }
+
+    output=new cvmatrix(self,desc,prev_value->GetDataType().GetElementDataType(),name);
+
+    output->SetValue(0,0,0);
+}
+
+LowPassFilter_impl::~LowPassFilter_impl()
+{
+}
+
+void LowPassFilter_impl::UpdateFrom(const io_data *data)
+{
+    float delta_t;
+    float result;
+    cvmatrix *input=(cvmatrix*)data;
+
+    //on prend une fois pour toute les mutex et on fait des accès directs
+    output->GetMutex();
+    input->GetMutex();
+
+    if(first_update==true)
+    {
+        for(int i=0;i<input->Rows();i++)
+        {
+            for(int j=0;j<input->Cols();j++)
+            {
+                output->SetValueNoMutex(i,j,prev_value->ValueNoMutex(i,j));
+                prev_value->SetValueNoMutex(i,j,input->ValueNoMutex(i,j));
+            }
+        }
+        first_update=false;
+    }
+    else
+    {
+        if(T->Value()==0)
+        {
+            delta_t=(float)(data->DataTime()-previous_time)/1000000000.;
+        }
+        else
+        {
+            delta_t=T->Value();
+        }
+        for(int i=0;i<input->Rows();i++)
+        {
+            for(int j=0;j<input->Cols();j++)
+            {
+
+                if(freq->Value()!=0)
+                {
+                    output->SetValueNoMutex(i,j,(1-2*PI*freq->Value()*delta_t)*prev_value->ValueNoMutex(i,j)+2*PI*freq->Value()*delta_t*input->ValueNoMutex(i,j));
+                }
+                else
+                {
+                    output->SetValueNoMutex(i,j,input->ValueNoMutex(i,j));
+                }
+                prev_value->SetValueNoMutex(i,j,output->ValueNoMutex(i,j));
+            }
+        }
+    }
+    input->ReleaseMutex();
+    output->ReleaseMutex();
+
+    output->SetDataTime(data->DataTime());
+    previous_time=data->DataTime();
+}
+
Index: trunk/lib/FlairFilter/src/NestedSat.cpp
===================================================================
--- trunk/lib/FlairFilter/src/NestedSat.cpp	(revision 7)
+++ trunk/lib/FlairFilter/src/NestedSat.cpp	(revision 7)
@@ -0,0 +1,59 @@
+//  created:    2013/04/15
+//  filename:   NestedSat.cpp
+//
+//  author:     Guillaume Sanahuja
+//              Copyright Heudiasyc UMR UTC/CNRS 7253
+//
+//  version:    $Id: $
+//
+//  purpose:    Class defining a PID with saturations
+//
+//
+/*********************************************************************/
+
+#include "NestedSat.h"
+#include "NestedSat_impl.h"
+#include <cvmatrix.h>
+#include <Layout.h>
+#include <LayoutPosition.h>
+#include <Euler.h>
+
+using std::string;
+using namespace flair::core;
+using namespace flair::gui;
+
+namespace flair
+{
+namespace filter
+{
+
+NestedSat::NestedSat(const LayoutPosition* position,string name) : ControlLaw(position->getLayout(),name)
+{
+    pimpl_=new NestedSat_impl(this,position,name);
+}
+
+NestedSat::~NestedSat(void)
+{
+    delete pimpl_;
+}
+
+void NestedSat::UpdateFrom(const io_data *data)
+{
+    pimpl_->UpdateFrom(data);
+    ProcessUpdate(output);
+}
+
+void NestedSat::SetValues(float p_ref,float p,float d)
+{
+    input->SetValue(0,0,p_ref);
+    input->SetValue(1,0,p);
+    input->SetValue(2,0,d);
+}
+//TODO: add a combobox to choose between rad and deg
+void NestedSat::ConvertSatFromDegToRad(void)
+{
+    pimpl_->k=Euler::ToRadian(1);
+}
+
+} // end namespace filter
+} // end namespace flair
Index: trunk/lib/FlairFilter/src/NestedSat.h
===================================================================
--- trunk/lib/FlairFilter/src/NestedSat.h	(revision 7)
+++ trunk/lib/FlairFilter/src/NestedSat.h	(revision 7)
@@ -0,0 +1,98 @@
+/*!
+ * \file NestedSat.h
+ * \brief  Class defining a PID with saturations
+ * \author Guillaume Sanahuja, Copyright Heudiasyc UMR UTC/CNRS 7253
+ * \date 2013/04/15
+ * \version 4.0
+ */
+
+#ifndef NESTEDSAT_H
+#define NESTEDSAT_H
+
+#include <ControlLaw.h>
+
+namespace flair
+{
+    namespace gui
+    {
+        class Layout;
+        class LayoutPosition;
+    }
+}
+
+class NestedSat_impl;
+
+namespace flair
+{
+namespace filter
+{
+    /*! \class NestedSat
+    *
+    * \brief  Class defining a PID with saturations
+    *
+    * The output of this control law is calculated
+    * as follows: \n
+    * p_ref=Sat(p_ref,k*sat_ref) \n
+    * d_ref=Sat[(p_ref-p)*kp,k*sat_dref] \n
+    * law=Sat[(d-d_ref)*kd,sat_u] \n
+    * where p, p_ref and d are input values (see SetValues()), \n
+    * where sat_ref, sat_dref and sat_u are settings availables on the ground station, \n
+    * where k is a conversion factor (see ConvertSatFromDegToRad()).
+    */
+    class NestedSat : public ControlLaw
+    {
+        friend class ::NestedSat_impl;
+
+        public:
+            /*!
+            * \brief Constructor
+            *
+            * Construct a NestedSat at given place position. \n
+            * The NestedSat will automatically be child of position->getLayout() Layout. After calling this function,
+            * position will be deleted as it is no longer usefull. \n
+            *
+            * \param position position to display settings
+            * \param name name
+            */
+            NestedSat(const gui::LayoutPosition* position,std::string name);
+
+            /*!
+            * \brief Destructor
+            *
+            */
+            ~NestedSat();
+
+            /*!
+            * \brief Set input values
+            *
+            * \param p_ref proportional reference
+            * \param p proportional value
+            * \param d derivative value
+            */
+            void SetValues(float p_ref,float p,float d);
+
+            /*!
+            * \brief Convert saturation parameters in radians
+            *
+            * If this function is called, saturation parameters
+            * on the ground station will be interpreted as degrees. \n
+            * Thus, an internal conversion from degrees to radians will
+            * be done (k=PI/180).
+            */
+            void ConvertSatFromDegToRad(void);
+
+        private:
+            /*!
+            * \brief Update using provided datas
+            *
+            * Reimplemented from IODevice.
+            *
+            * \param data data from the parent to process
+            */
+            void UpdateFrom(const core::io_data *data);
+
+            NestedSat_impl* pimpl_;
+    };
+} // end namespace filter
+} // end namespace flair
+#endif // NESTEDSAT_H
Index: trunk/lib/FlairFilter/src/NestedSat_impl.cpp
===================================================================
--- trunk/lib/FlairFilter/src/NestedSat_impl.cpp	(revision 7)
+++ trunk/lib/FlairFilter/src/NestedSat_impl.cpp	(revision 7)
@@ -0,0 +1,70 @@
+//  created:    2013/04/15
+//  filename:   NestedSat_impl.cpp
+//
+//  author:     Guillaume Sanahuja
+//              Copyright Heudiasyc UMR UTC/CNRS 7253
+//
+//  version:    $Id: $
+//
+//  purpose:    objet permettant le calcul d'un Pid avec saturations
+//
+//
+/*********************************************************************/
+
+#include "NestedSat_impl.h"
+#include "NestedSat.h"
+#include <cvmatrix.h>
+#include <Layout.h>
+#include <GroupBox.h>
+#include <DoubleSpinBox.h>
+
+using std::string;
+using namespace flair::core;
+using namespace flair::gui;
+using namespace flair::filter;
+
+NestedSat_impl::NestedSat_impl(NestedSat* self,const LayoutPosition* position,string name)
+{
+    this->self=self;
+	k=1;
+
+    //init matrix
+    self->input=new cvmatrix(self,3,1,floatType,name);
+
+    GroupBox* reglages_groupbox=new GroupBox(position,name);
+            sat=new DoubleSpinBox(reglages_groupbox->NewRow(),"sat ref:",0,9000000,1);
+            kp=new DoubleSpinBox(reglages_groupbox->NewRow(),"kp:",0,9000000,1);
+            dsat=new DoubleSpinBox(reglages_groupbox->NewRow(),"sat dref:",0,9000000,1);
+            kd=new DoubleSpinBox(reglages_groupbox->NewRow(),"kd:",0,9000000,0.1);
+            usat=new DoubleSpinBox(reglages_groupbox->NewRow(),"sat u:",0,1,.1);
+}
+
+NestedSat_impl::~NestedSat_impl(void)
+{
+}
+
+void NestedSat_impl::UpdateFrom(const io_data *data)
+{
+    float cons,dcons,law;
+    cvmatrix *input=(cvmatrix*)data;
+
+    input->GetMutex();
+
+    cons=Sat(input->ValueNoMutex(0,0),k*sat->Value());
+    dcons=(cons-input->ValueNoMutex(1,0))*kp->Value();
+    dcons=Sat(dcons,k*dsat->Value());
+    law=(input->ValueNoMutex(2,0)-dcons)*kd->Value();
+    law=Sat(law,usat->Value());
+
+    input->ReleaseMutex();
+
+    self->output->SetValue(0,0,law);
+    self->output->SetDataTime(data->DataTime());
+}
+
+float NestedSat_impl::Sat(float value,float borne)
+{
+    if(value<-borne) return -borne;
+    if(value>borne) return borne;
+    return value;
+}
Index: trunk/lib/FlairFilter/src/Pid.cpp
===================================================================
--- trunk/lib/FlairFilter/src/Pid.cpp	(revision 7)
+++ trunk/lib/FlairFilter/src/Pid.cpp	(revision 7)
@@ -0,0 +1,55 @@
+//  created:    2011/05/01
+//  filename:   Pid.cpp
+//
+//  author:     Guillaume Sanahuja
+//              Copyright Heudiasyc UMR UTC/CNRS 7253
+//
+//  version:    $Id: $
+//
+//  purpose:    Class defining a PID
+//
+//
+/*********************************************************************/
+
+#include "Pid.h"
+#include "Pid_impl.h"
+#include <cvmatrix.h>
+#include <Layout.h>
+#include <LayoutPosition.h>
+
+using std::string;
+using namespace flair::core;
+using namespace flair::gui;
+
+namespace flair { namespace filter {
+
+Pid::Pid(const LayoutPosition* position,string name) : ControlLaw(position->getLayout(),name) {
+    pimpl_=new Pid_impl(this,position,name);
+}
+
+Pid::~Pid(void) {
+    delete pimpl_;
+}
+
+void Pid::UseDefaultPlot(const gui::LayoutPosition* position) {
+    pimpl_->UseDefaultPlot(position);
+}
+
+void Pid::Reset(void) {
+    pimpl_->i=0;
+    pimpl_->first_update=true;
+}
+
+void Pid::UpdateFrom(const io_data *data) {
+    pimpl_->UpdateFrom(data);
+    ProcessUpdate(output);
+}
+
+void Pid::SetValues(float p,float d) {
+    input->SetValue(0,0,p);
+    input->SetValue(1,0,d);
+}
+
+
+} // end namespace filter
+} // end namespace flair
Index: trunk/lib/FlairFilter/src/Pid.h
===================================================================
--- trunk/lib/FlairFilter/src/Pid.h	(revision 7)
+++ trunk/lib/FlairFilter/src/Pid.h	(revision 7)
@@ -0,0 +1,96 @@
+/*!
+ * \file Pid.h
+ * \brief Class defining a PID
+ * \author Guillaume Sanahuja, Copyright Heudiasyc UMR UTC/CNRS 7253
+ * \date 2011/05/01
+ * \version 4.0
+ */
+
+#ifndef PID_H
+#define PID_H
+
+#include <ControlLaw.h>
+
+namespace flair
+{
+    namespace gui
+    {
+        class LayoutPosition;
+    }
+}
+
+class Pid_impl;
+
+namespace flair
+{
+namespace filter
+{
+    /*! \class Pid
+    *
+    * \brief Class defining a PID
+    */
+    class Pid : public ControlLaw
+    {
+        friend class ::Pid_impl;
+
+        public:
+            /*!
+            * \brief Constructor
+            *
+            * Construct a PID at given position. \n
+            * The PID will automatically be child of position->getLayout() Layout. After calling this function,
+            * position will be deleted as it is no longer usefull. \n
+            *
+            * \param position position to display settings
+            * \param name name
+            */
+            Pid(const gui::LayoutPosition* position,std::string name);
+
+            /*!
+            * \brief Destructor
+            *
+            */
+            ~Pid();
+
+            /*!
+            * \brief Reset integral
+            *
+            */
+            void Reset(void);
+
+            /*!
+            * \brief Set input values
+            *
+            * \param p proportional value
+            * \param d derivative value
+            */
+            void SetValues(float p,float d);
+
+            /*!
+            * \brief Use default plot
+            *
+            * Plot the output values at position. \n
+            * Plot consists of 4 curves: proportional part,
+            * derivative part, integral part and
+            * the sum of the three. \n
+            * After calling this function, position will be deleted as it is no longer usefull. \n
+            *
+            * \param position position to display plot
+            */
+            void UseDefaultPlot(const gui::LayoutPosition* position);
+
+        private:
+            /*!
+            * \brief Update using provided datas
+            *
+            * Reimplemented from IODevice.
+            *
+            * \param data data from the parent to process
+            */
+            void UpdateFrom(const core::io_data *data);
+
+            Pid_impl* pimpl_;
+    };
+} // end namespace filter
+} // end namespace flair
+#endif // PID_H
Index: trunk/lib/FlairFilter/src/PidThrust.cpp
===================================================================
--- trunk/lib/FlairFilter/src/PidThrust.cpp	(revision 7)
+++ trunk/lib/FlairFilter/src/PidThrust.cpp	(revision 7)
@@ -0,0 +1,110 @@
+//  created:    2014/11/07
+//  filename:   PidThrust.cpp
+//
+//  author:     Guillaume Sanahuja
+//              Copyright Heudiasyc UMR UTC/CNRS 7253
+//
+//  version:    $Id: $
+//
+//  purpose:    Class defining a PidThrust
+//
+//
+/*********************************************************************/
+
+#include "PidThrust.h"
+#include "PidThrust_impl.h"
+#include <cvmatrix.h>
+#include <Layout.h>
+#include <LayoutPosition.h>
+#include <DoubleSpinBox.h>
+
+using std::string;
+using namespace flair::core;
+using namespace flair::gui;
+
+namespace flair
+{
+namespace filter
+{
+
+PidThrust::PidThrust(const LayoutPosition* position,string name) : ControlLaw(position->getLayout(),name)
+{
+    pimpl_=new PidThrust_impl(this,position,name);
+}
+
+PidThrust::~PidThrust(void)
+{
+    delete pimpl_;
+}
+
+void PidThrust::UseDefaultPlot(const flair::gui::LayoutPosition* position)
+{
+    pimpl_->UseDefaultPlot(position);
+}
+
+void PidThrust::Reset(void) {
+    pimpl_->i=0;
+    pimpl_->offset_g=0;
+}
+
+void PidThrust::ResetI(void)
+{
+    pimpl_->i=0;
+}
+
+float PidThrust::GetOffset(void) {
+    return pimpl_->offset_g;
+}
+
+void PidThrust::UpdateFrom(const io_data *data)
+{
+    pimpl_->UpdateFrom(data);
+    ProcessUpdate(output);
+}
+
+void PidThrust::SetValues(float p,float d)
+{
+    input->SetValue(0,0,p);
+    input->SetValue(1,0,d);
+}
+
+void PidThrust::ResetOffset(void)
+{
+    pimpl_->offset_g=0;
+}
+
+void PidThrust::SetOffset(void)
+{
+    pimpl_->offset_g=pimpl_->offset->Value();
+}
+
+bool PidThrust::OffsetStepUp(void)
+{
+    pimpl_->offset_g+=pimpl_->pas_offset->Value();
+    if(pimpl_->offset_g>1)
+    {
+        pimpl_->offset_g=1;
+        return false;
+    }
+    else
+    {
+        return true;
+    }
+}
+
+bool PidThrust::OffsetStepDown(void)
+{
+    pimpl_->offset_g-=pimpl_->pas_offset->Value();
+    if(pimpl_->offset_g<pimpl_->offset->Value())
+    {
+        pimpl_->offset_g=pimpl_->offset->Value();
+        return false;
+    }
+    else
+    {
+        return true;
+    }
+}
+
+} // end namespace filter
+} // end namespace flair
Index: trunk/lib/FlairFilter/src/PidThrust.h
===================================================================
--- trunk/lib/FlairFilter/src/PidThrust.h	(revision 7)
+++ trunk/lib/FlairFilter/src/PidThrust.h	(revision 7)
@@ -0,0 +1,136 @@
+/*!
+ * \file PidThrust.h
+ * \brief Class defining a Pid for Thrust
+ * \author Guillaume Sanahuja, Copyright Heudiasyc UMR UTC/CNRS 7253
+ * \date 2014/11/07
+ * \version 4.0
+ */
+
+#ifndef PIDTHRUST_H
+#define PIDTHRUST_H
+
+#include <ControlLaw.h>
+
+namespace flair
+{
+    namespace gui
+    {
+        class LayoutPosition;
+    }
+}
+
+class PidThrust_impl;
+
+namespace flair
+{
+namespace filter
+{
+    /*! \class PidThrust
+    *
+    * \brief Class defining a Pid for Thrust.\n
+    * This Pid as an extra offset for compensating gravity.
+    */
+    class PidThrust : public ControlLaw
+    {
+        friend class ::PidThrust_impl;
+
+        public:
+            /*!
+            * \brief Constructor
+            *
+            * Construct a PidThrust at given position
+            * The PidThrust will automatically be child of position->getLayout() Layout. After calling this function,
+            * position will be deleted as it is no longer usefull. \n
+            *
+            * \param position position to display settings
+            * \param name name
+            */
+            PidThrust(const gui::LayoutPosition* position,std::string name);
+
+            /*!
+            * \brief Destructor
+            *
+            */
+            ~PidThrust();
+
+            /*!
+            * \brief Reset integral and offset to 0
+            *
+            */
+            void Reset(void);
+
+            /*!
+            * \brief Reset integral to 0
+            *
+            */
+            void ResetI(void);
+
+            /*!
+            * \brief Reset offset to 0
+            *
+            */
+            void ResetOffset(void);
+
+            /*!
+            * \brief Set offset to specified value in ground station
+            *
+            */
+            void SetOffset(void);
+
+            /*!
+            * \brief Get offset
+            *
+            * \return current offset
+            */
+            float GetOffset(void);
+
+            /*!
+            * \brief Step up the offset according to specified value in ground station
+            *
+            * \return false if offset is at its maximum (1) value, true otherwise
+            */
+            bool OffsetStepUp(void);
+
+            /*!
+            * \brief Step down the offset according to specified value in ground station
+            *
+            * \return false if offset is at its minimum (specified in ground station) value, true otherwise
+            */
+            bool OffsetStepDown(void);
+
+            /*!
+            * \brief Set input values
+            *
+            * \param p proportional value
+            * \param d derivative value
+            */
+            void SetValues(float p,float d);
+
+            /*!
+            * \brief Use default plot
+            *
+            * Plot the output values at position. \n
+            * Plot consists of 4 curves: proportional part,
+            * derivative part, integral part and
+            * the sum of the three. \n
+            * After calling this function, position will be deleted as it is no longer usefull. \n
+            *
+            * \param position position to display plot
+            */
+            void UseDefaultPlot(const gui::LayoutPosition* position);
+
+        private:
+            /*!
+            * \brief Update using provided datas
+            *
+            * Reimplemented from IODevice.
+            *
+            * \param data data from the parent to process
+            */
+            void UpdateFrom(const core::io_data *data);
+
+            PidThrust_impl* pimpl_;
+    };
+} // end namespace filter
+} // end namespace flair
+#endif // PIDTHRUST_H
Index: trunk/lib/FlairFilter/src/PidThrust_impl.cpp
===================================================================
--- trunk/lib/FlairFilter/src/PidThrust_impl.cpp	(revision 7)
+++ trunk/lib/FlairFilter/src/PidThrust_impl.cpp	(revision 7)
@@ -0,0 +1,113 @@
+//  created:    2014/11/07
+//  filename:   PidThrust_impl.cpp
+//
+//  author:     Guillaume Sanahuja
+//              Copyright Heudiasyc UMR UTC/CNRS 7253
+//
+//  version:    $Id: $
+//
+//  purpose:    Class defining a PID
+//
+//
+/*********************************************************************/
+#include "PidThrust_impl.h"
+#include "PidThrust.h"
+#include <cvmatrix.h>
+#include <Layout.h>
+#include <GroupBox.h>
+#include <DoubleSpinBox.h>
+#include <DataPlot1D.h>
+
+using std::string;
+using namespace flair::core;
+using namespace flair::gui;
+using namespace flair::filter;
+
+PidThrust_impl::PidThrust_impl(PidThrust* self,const LayoutPosition* position,string name) {
+    i=0;
+    offset_g=0;
+	first_update=true;
+	this->self=self;
+
+    //init matrix
+    self->input=new cvmatrix(self,2,1,floatType,name);
+
+    cvmatrix_descriptor* desc=new cvmatrix_descriptor(5,1);
+    desc->SetElementName(0,0,"p");
+	desc->SetElementName(1,0,"i");
+	desc->SetElementName(2,0,"d");
+	desc->SetElementName(3,0,"p+i+d");
+	desc->SetElementName(4,0,"p+i+d+offset");
+    state=new cvmatrix(self,desc,floatType,name);
+
+    GroupBox* reglages_groupbox=new GroupBox(position,name);
+            T=new DoubleSpinBox(reglages_groupbox->NewRow(),"period, 0 for auto"," s",0,1,0.01);
+            kp=new DoubleSpinBox(reglages_groupbox->NewRow(),"kp:",0,90000000,0.01);
+            ki=new DoubleSpinBox(reglages_groupbox->NewRow(),"ki:",0,90000000,0.01);
+            sati=new DoubleSpinBox(reglages_groupbox->LastRowLastCol(),"sat i:",0,1,0.01);
+            kd=new DoubleSpinBox(reglages_groupbox->NewRow(),"kd:",0,90000000,0.01);
+            offset=new DoubleSpinBox(reglages_groupbox->LastRowLastCol(),"offset g:",0,1,0.01);
+            sat=new DoubleSpinBox(reglages_groupbox->NewRow(),"sat:",0,1,0.1);
+            pas_offset=new DoubleSpinBox(reglages_groupbox->LastRowLastCol(),"offset step:",0,1,.0001,4);
+}
+
+PidThrust_impl::~PidThrust_impl(void) {
+}
+
+void PidThrust_impl::UseDefaultPlot(const LayoutPosition* position)
+{
+    DataPlot1D *plot=new DataPlot1D(position,self->ObjectName(),-1,1);
+            plot->AddCurve(state->Element(0));
+            plot->AddCurve(state->Element(1),DataPlot::Green);
+            plot->AddCurve(state->Element(2),DataPlot::Blue);
+            plot->AddCurve(state->Element(3),DataPlot::Black);
+            plot->AddCurve(state->Element(4),DataPlot::Yellow);
+}
+
+void PidThrust_impl::UpdateFrom(const io_data *data)
+{
+    float p,d,total;
+    float delta_t;
+    cvmatrix *input=(cvmatrix*)data;
+
+    if(T->Value()==0)
+    {
+        delta_t=(float)(data->DataTime()-previous_time)/1000000000.;
+    }
+    else
+    {
+        delta_t=T->Value();
+    }
+    if(first_update==true)
+    {
+        delta_t=0;
+        first_update=false;
+    }
+
+    input->GetMutex();
+    p=kp->Value()*input->ValueNoMutex(0,0);
+    i+=ki->Value()*input->ValueNoMutex(0,0)*delta_t;
+    if(i>sati->Value()) i=sati->Value();
+    if(i<-sati->Value()) i=-sati->Value();
+    d=kd->Value()*input->ValueNoMutex(1,0);
+    input->ReleaseMutex();
+
+    total=p+i+d;
+    if(total>sat->Value()) total=sat->Value();
+    if(total<-sat->Value()) total=-sat->Value();
+
+    state->GetMutex();
+    state->SetValueNoMutex(0,0,p);
+    state->SetValueNoMutex(1,0,i);
+    state->SetValueNoMutex(2,0,d);
+    state->SetValueNoMutex(3,0,total);
+    state->SetValueNoMutex(4,0,total-offset_g*offset_g);
+    state->ReleaseMutex();
+
+    //-offset_g, car on met -u_z dans le multiplex
+    //a revoir!
+    self->output->SetValue(0,0,total-offset_g*offset_g);
+    self->output->SetDataTime(data->DataTime());
+
+    previous_time=data->DataTime();
+}
Index: trunk/lib/FlairFilter/src/Pid_impl.cpp
===================================================================
--- trunk/lib/FlairFilter/src/Pid_impl.cpp	(revision 7)
+++ trunk/lib/FlairFilter/src/Pid_impl.cpp	(revision 7)
@@ -0,0 +1,99 @@
+//  created:    2011/05/01
+//  filename:   Pid_impl.cpp
+//
+//  author:     Guillaume Sanahuja
+//              Copyright Heudiasyc UMR UTC/CNRS 7253
+//
+//  version:    $Id: $
+//
+//  purpose:    Class defining a PID
+//
+//
+/*********************************************************************/
+#include "Pid_impl.h"
+#include "Pid.h"
+#include <cvmatrix.h>
+#include <Layout.h>
+#include <GroupBox.h>
+#include <DoubleSpinBox.h>
+#include <DataPlot1D.h>
+
+using std::string;
+using namespace flair::core;
+using namespace flair::gui;
+using namespace flair::filter;
+
+Pid_impl::Pid_impl(Pid* self,const LayoutPosition* position,string name) {
+    i=0;
+    first_update=true;
+    this->self=self;
+
+    //init matrix
+    self->input=new cvmatrix(self,2,1,floatType,name);
+
+    cvmatrix_descriptor* desc=new cvmatrix_descriptor(4,1);
+    desc->SetElementName(0,0,"p");
+    desc->SetElementName(1,0,"i");
+    desc->SetElementName(2,0,"d");
+    desc->SetElementName(3,0,"p+i+d");
+    state=new cvmatrix(self,desc,floatType,name);
+
+    GroupBox* reglages_groupbox=new GroupBox(position,name);
+    T=new DoubleSpinBox(reglages_groupbox->NewRow(),"period, 0 for auto"," s",0,1,0.01);
+    kp=new DoubleSpinBox(reglages_groupbox->NewRow(),"kp:",0,90000000,0.01,3);
+    ki=new DoubleSpinBox(reglages_groupbox->NewRow(),"ki:",0,90000000,0.01,3);
+    sati=new DoubleSpinBox(reglages_groupbox->LastRowLastCol(),"sat i:",0,1,0.01);
+    kd=new DoubleSpinBox(reglages_groupbox->NewRow(),"kd:",0,90000000,0.01,3);
+    sat=new DoubleSpinBox(reglages_groupbox->NewRow(),"sat:",0,1,0.1);
+}
+
+Pid_impl::~Pid_impl(void) {
+}
+
+void Pid_impl::UseDefaultPlot(const LayoutPosition* position) {
+    DataPlot1D *plot=new DataPlot1D(position,self->ObjectName(),-1,1);
+    plot->AddCurve(state->Element(0));
+    plot->AddCurve(state->Element(1),DataPlot::Green);
+    plot->AddCurve(state->Element(2),DataPlot::Blue);
+    plot->AddCurve(state->Element(3),DataPlot::Black);
+}
+
+void Pid_impl::UpdateFrom(const io_data *data) {
+    float p,d,total;
+    float delta_t;
+    cvmatrix *input=(cvmatrix*)data;
+
+    if(T->Value()==0) {
+        delta_t=(float)(data->DataTime()-previous_time)/1000000000.;
+    } else {
+        delta_t=T->Value();
+    }
+    if(first_update==true) {
+        delta_t=0;
+        first_update=false;
+    }
+
+    input->GetMutex();
+    p=kp->Value()*input->ValueNoMutex(0,0);
+    i+=ki->Value()*input->ValueNoMutex(0,0)*delta_t;
+    if(i>sati->Value()) i=sati->Value();
+    if(i<-sati->Value()) i=-sati->Value();
+    d=kd->Value()*input->ValueNoMutex(1,0);
+    input->ReleaseMutex();
+
+    total=p+i+d;
+    if(total>sat->Value()) total=sat->Value();
+    if(total<-sat->Value()) total=-sat->Value();
+
+    state->GetMutex();
+    state->SetValueNoMutex(0,0,p);
+    state->SetValueNoMutex(1,0,i);
+    state->SetValueNoMutex(2,0,d);
+    state->SetValueNoMutex(3,0,total);
+    state->ReleaseMutex();
+
+    self->output->SetValue(0,0,total);
+    self->output->SetDataTime(data->DataTime());
+
+    previous_time=data->DataTime();
+}
Index: trunk/lib/FlairFilter/src/SimuAhrs.cpp
===================================================================
--- trunk/lib/FlairFilter/src/SimuAhrs.cpp	(revision 7)
+++ trunk/lib/FlairFilter/src/SimuAhrs.cpp	(revision 7)
@@ -0,0 +1,50 @@
+//  created:    2014/02/07
+//  filename:   SimuAhrs.cpp
+//
+//  author:     Guillaume Sanahuja
+//              Copyright Heudiasyc UMR UTC/CNRS 7253
+//
+//  version:    $Id: $
+//
+//  purpose:    Class for a simulation ahrs
+//
+//
+/*********************************************************************/
+
+#include "SimuAhrs.h"
+#include "SimuImu.h"
+#include <FrameworkManager.h>
+#include <AhrsData.h>
+
+using std::string;
+using namespace flair::core;
+using namespace flair::sensor;
+
+namespace flair { namespace filter {
+
+SimuAhrs::SimuAhrs(const FrameworkManager* parent,string name,uint32_t dev_id,uint8_t priority) :Ahrs(new SimuImu(parent,name,dev_id,priority),name) {
+}
+
+SimuAhrs::~SimuAhrs() {}
+
+void SimuAhrs::Start(void) {
+    ((SimuImu*)GetImu())->Start();
+}
+
+//datas from SimuImu are AhrsData!
+void SimuAhrs::UpdateFrom(const io_data *data) {
+    AhrsData *input=(AhrsData*)data;
+    AhrsData *output;
+    GetDatas(&output);
+
+    Quaternion quaternion;
+    Vector3D filteredAngRates;
+    input->GetQuaternionAndAngularRates(quaternion,filteredAngRates);
+    output->SetQuaternionAndAngularRates(quaternion,filteredAngRates);
+    output->SetDataTime(input->DataTime());
+
+    ProcessUpdate(output);
+}
+
+} // end namespace filter
+} // end namespace flair
Index: trunk/lib/FlairFilter/src/SimuAhrs.h
===================================================================
--- trunk/lib/FlairFilter/src/SimuAhrs.h	(revision 7)
+++ trunk/lib/FlairFilter/src/SimuAhrs.h	(revision 7)
@@ -0,0 +1,64 @@
+/*!
+ * \file SimuAhrs.h
+ * \brief Class for a simulation Ahrs
+ * \author Guillaume Sanahuja, Copyright Heudiasyc UMR UTC/CNRS 7253
+ * \date 2014/02/07
+ * \version 4.0
+ */
+
+#ifndef SIMUAHRS_H
+#define SIMUAHRS_H
+
+#include <Ahrs.h>
+#include <stdint.h>
+
+namespace flair
+{
+namespace filter
+{
+    /*! \class SimuAhrs
+    *
+    * \brief Class for a simulation Ahrs
+    *
+    * This class constructs a SimuImu as Imu of this Ahrs.
+    */
+    class SimuAhrs : public filter::Ahrs
+    {
+        public:
+            /*!
+            * \brief Constructor
+            *
+            * Construct a simulation Ahrs.
+            *
+            * \param parent parent
+            * \param name name
+            * \param dev_id number id of the simulated Ahrs
+            * \param priority priority of the SimuImu Thread
+            */
+            SimuAhrs(const core::FrameworkManager* parent,std::string name,uint32_t dev_id,uint8_t priority);
+
+            /*!
+            * \brief Destructor
+            *
+            */
+            ~SimuAhrs();
+
+             /*!
+            * \brief Start SimuImu Thread
+            *
+            */
+            void Start(void);
+
+        private:
+            /*!
+            * \brief Update using provided datas
+            *
+            * Reimplemented from IODevice.
+            *
+            * \param data data from the parent to process
+            */
+            void UpdateFrom(const core::io_data *data);
+    };
+} // end namespace filter
+} // end namespace flair
+#endif // SIMUAHRS_H
Index: trunk/lib/FlairFilter/src/TrajectoryGenerator1D.cpp
===================================================================
--- trunk/lib/FlairFilter/src/TrajectoryGenerator1D.cpp	(revision 7)
+++ trunk/lib/FlairFilter/src/TrajectoryGenerator1D.cpp	(revision 7)
@@ -0,0 +1,90 @@
+//  created:    2011/05/01
+//  filename:   TrajectoryGenerator1D.cpp
+//
+//  author:     Guillaume Sanahuja
+//              Copyright Heudiasyc UMR UTC/CNRS 7253
+//
+//  version:    $Id: $
+//
+//  purpose:    Class generating a trajectory in 1D
+//
+//
+/*********************************************************************/
+
+#include "TrajectoryGenerator1D.h"
+#include "TrajectoryGenerator1D_impl.h"
+#include <cvmatrix.h>
+#include <Layout.h>
+#include <LayoutPosition.h>
+
+using std::string;
+using namespace flair::core;
+using namespace flair::gui;
+
+namespace flair { namespace filter {
+
+TrajectoryGenerator1D::TrajectoryGenerator1D(const LayoutPosition* position,string name,string unit) : IODevice(position->getLayout(),name) {
+    pimpl_=new TrajectoryGenerator1D_impl(this,position,name,unit);
+    AddDataToLog(pimpl_->output);
+}
+
+TrajectoryGenerator1D::~TrajectoryGenerator1D() {
+    delete pimpl_;
+}
+
+cvmatrix *TrajectoryGenerator1D::Matrix(void) const {
+    return pimpl_->output;
+}
+
+void TrajectoryGenerator1D::StartTraj(float start_pos,float end_pos) {
+    pimpl_->StartTraj(start_pos,end_pos);
+}
+
+//revoir l'interet du stop?
+void TrajectoryGenerator1D::StopTraj(void) {
+    pimpl_->StopTraj();
+}
+
+bool TrajectoryGenerator1D::IsRunning(void) const {
+    if(pimpl_->is_started==true) {
+        if(pimpl_->is_finished==true) {
+            return false;
+        } else {
+            return true;
+        }
+    } else {
+        return false;
+    }
+}
+
+float TrajectoryGenerator1D::Position(void) const {
+    return pimpl_->output->Value(0,0);
+}
+
+void TrajectoryGenerator1D::Reset(void) {
+    if(IsRunning()==false) {
+        pimpl_->Reset();
+    } else {
+        Err("impossible while running\n");
+    }
+}
+
+void TrajectoryGenerator1D::SetPositionOffset(float value) {
+    pimpl_->pos_off=value;
+}
+
+float TrajectoryGenerator1D::Speed(void) const {
+    return pimpl_->output->Value(1,0);
+}
+
+void TrajectoryGenerator1D::SetSpeedOffset(float value) {
+    pimpl_->vel_off=value;
+}
+
+void TrajectoryGenerator1D::Update(Time time) {
+    pimpl_->Update(time);
+    ProcessUpdate(pimpl_->output);
+}
+
+} // end namespace filter
+} // end namespace flair
Index: trunk/lib/FlairFilter/src/TrajectoryGenerator1D.h
===================================================================
--- trunk/lib/FlairFilter/src/TrajectoryGenerator1D.h	(revision 7)
+++ trunk/lib/FlairFilter/src/TrajectoryGenerator1D.h	(revision 7)
@@ -0,0 +1,153 @@
+/*!
+ * \file TrajectoryGenerator1D.h
+ * \brief Class generating a trajectory in 1D
+ * \author Guillaume Sanahuja, Copyright Heudiasyc UMR UTC/CNRS 7253
+ * \date 2011/05/01
+ * \version 4.0
+ */
+
+#ifndef TRAJECTORYGENERATOR1D_H
+#define TRAJECTORYGENERATOR1D_H
+
+#include <IODevice.h>
+
+namespace flair
+{
+    namespace core
+    {
+        class cvmatrix;
+    }
+    namespace gui
+    {
+        class LayoutPosition;
+    }
+}
+
+class TrajectoryGenerator1D_impl;
+
+namespace flair
+{
+namespace filter
+{
+    /*! \class TrajectoryGenerator1D
+    *
+    * \brief Class generating a trajectory in 1D
+    *
+    * This class generates position and velocity references, given
+    * an absolute maximum velocity and an absolute acceleration. \n
+    * When trajectory is started (see StartTraj()), position and velocity will increase
+    * at the given acceleration. If the maximum velocity is reached,
+    * velocity will not increase anymore. Then, velocity will decrease according
+    * to the given acceleration until velocity is null and final position is reached. \n
+    * Manual inputs can be introduced using SetPositionOffset() and SetSpeedOffset().
+    *
+    */
+    class TrajectoryGenerator1D : public core::IODevice
+    {
+        public:
+            /*!
+            * \brief Constructor
+            *
+            * Construct a TrajectoryGenerator1D at given position. \n
+            * The TrajectoryGenerator1D will automatically be child of position->getLayout() Layout. After calling this function,
+            * position will be deleted as it is no longer usefull. \n
+            *
+            * \param position position to display settings
+            * \param name name
+            * \param unit unit of the position (for exemple m, deg, etc). Its only used for display on ground station.
+            */
+            TrajectoryGenerator1D(const gui::LayoutPosition* position,std::string name,std::string unit="");
+
+            /*!
+            * \brief Destructor
+            *
+            */
+            ~TrajectoryGenerator1D();
+
+            /*!
+            * \brief Start trajectory
+            *
+            * \param start_pos start position
+            * \param end_pos end position
+            */
+            void StartTraj(float start_pos,float end_pos);
+
+            /*!
+            * \brief Stop trajectory
+            *
+            */
+            void StopTraj(void);
+
+            /*!
+            * \brief Reset
+            *
+            * Reset all outputs to 0. This can be done only when IsRunning()==false.
+            *
+            */
+            void Reset(void);
+
+            /*!
+            * \brief Is trajectory running?
+            *
+            * \return true if trajectory is running
+            */
+            bool IsRunning(void) const;
+
+            /*!
+            * \brief Set position offset
+            *
+            * \param value position offset
+            */
+            void SetPositionOffset(float value);
+
+            /*!
+            * \brief Set speed offset
+            *
+            * \param value speed offset
+            */
+            void SetSpeedOffset(float value);
+
+            /*!
+            * \brief Update using provided datas
+            *
+            * Uses values specified by StartTraj(),
+            * SetPositionOffset() and SetSpeedOffset().
+            *
+            * \param time time of the update
+            */
+            void Update(core::Time time);
+
+            /*!
+            * \brief Position
+            *
+            */
+            float Position(void) const;
+
+            /*!
+            * \brief Speed
+            *
+            */
+            float Speed(void) const;
+
+            /*!
+            * \brief Output matrix
+            *
+            * \return matrix
+            */
+            core::cvmatrix *Matrix(void) const;
+
+        private:
+            /*!
+            * \brief Update using provided datas
+            *
+            * Reimplemented from IODevice. Nothing to do in this IODevice.
+            *
+            * \param data data from the parent to process
+            */
+            void UpdateFrom(const core::io_data *data){};
+
+            TrajectoryGenerator1D_impl* pimpl_;
+    };
+} // end namespace filter
+} // end namespace flair
+#endif // TRAJECTORYGENERATOR1D_H
Index: trunk/lib/FlairFilter/src/TrajectoryGenerator1D_impl.cpp
===================================================================
--- trunk/lib/FlairFilter/src/TrajectoryGenerator1D_impl.cpp	(revision 7)
+++ trunk/lib/FlairFilter/src/TrajectoryGenerator1D_impl.cpp	(revision 7)
@@ -0,0 +1,142 @@
+//  created:    2011/05/01
+//  filename:   TrajectoryGenerator1D_impl.cpp
+//
+//  author:     Guillaume Sanahuja
+//              Copyright Heudiasyc UMR UTC/CNRS 7253
+//
+//  version:    $Id: $
+//
+//  purpose:    Class generating a trajectory in 1D
+//
+//
+/*********************************************************************/
+
+#include "TrajectoryGenerator1D.h"
+#include "TrajectoryGenerator1D_impl.h"
+#include <cvmatrix.h>
+#include <Layout.h>
+#include <GroupBox.h>
+#include <DoubleSpinBox.h>
+#include <cmath>
+
+using std::string;
+using namespace flair::core;
+using namespace flair::gui;
+using namespace flair::filter;
+
+TrajectoryGenerator1D_impl::TrajectoryGenerator1D_impl(TrajectoryGenerator1D* self,const LayoutPosition* position,string name,string unit) {
+    first_update=true;
+    is_started=false;
+
+    //init UI
+    GroupBox* reglages_groupbox=new GroupBox(position,name);
+    T=new DoubleSpinBox(reglages_groupbox->NewRow(),"period, 0 for auto:"," s",0,1,0.01);
+    if(unit=="") {
+        max_veloctity=new DoubleSpinBox(reglages_groupbox->LastRowLastCol(),"velocity max (absolute):",0.,200000,1);
+    } else {
+        max_veloctity=new DoubleSpinBox(reglages_groupbox->LastRowLastCol(),"velocity max (absolute):"," "+ unit+"/s",0.,200000,1);
+    }
+    if(unit=="") {
+        acceleration=new DoubleSpinBox(reglages_groupbox->LastRowLastCol(),"acceleration (absolute):",0.,10,1,3);
+    } else {
+        acceleration=new DoubleSpinBox(reglages_groupbox->LastRowLastCol(),"acceleration (absolute):"," "+unit +"/s²",0.,200000,1);
+    }
+
+    Reset();
+
+    //init matrix
+    cvmatrix_descriptor* desc=new cvmatrix_descriptor(2,1);
+    desc->SetElementName(0,0,"pos");
+    desc->SetElementName(1,0,"vel");
+    output=new cvmatrix(self,desc,floatType,name);
+
+    output->SetValue(0,0,pos);
+    output->SetValue(1,0,v);
+}
+
+TrajectoryGenerator1D_impl::~TrajectoryGenerator1D_impl() {
+}
+
+void TrajectoryGenerator1D_impl::Reset(void) {
+    pos=0;
+    v=0;
+    pos_off=0;
+    vel_off=0;
+}
+
+void TrajectoryGenerator1D_impl::StartTraj(float start_pos,float end_pos) {
+    is_started=true;
+    is_finished=false;
+    first_update=true;
+
+    //configure trajectory
+    end_position=end_pos;
+    pos=start_pos;
+    acc=acceleration->Value();
+    v=0;
+    if(end_position<start_pos) {
+        acc=-acc;
+        //max_veloctity=-max_veloctity;
+    }
+}
+
+//revoir l'interet du stop?
+void TrajectoryGenerator1D_impl::StopTraj(void) {
+    is_started=false;
+    v=0;
+    //output->SetValue(1,0,v);
+}
+
+void TrajectoryGenerator1D_impl::Update(Time time) {
+    float delta_t;
+
+    if(T->Value()==0) {
+        if(first_update==true) {
+            first_update=false;
+            previous_time=time;
+            output->GetMutex();
+            output->SetValueNoMutex(0,0,pos+pos_off);
+            output->SetValueNoMutex(1,0,v+vel_off);
+            output->ReleaseMutex();
+
+            output->SetDataTime(time);
+            return;
+        } else {
+            delta_t=(float)(time-previous_time)/1000000000.;
+        }
+    } else {
+        delta_t=T->Value();
+    }
+    previous_time=time;
+
+
+    if(is_started==true) {
+        if(is_finished==false) {
+            v+=acc*delta_t;
+            if(fabs(v)>fabs(max_veloctity->Value())) {
+                if(v>0)
+                    v=max_veloctity->Value();
+                else
+                    v=-max_veloctity->Value();
+            }
+            pos+=v*delta_t;
+            if(end_position-v*v/(2*acc)<=pos && v>=0) acc=-acc;
+            if(end_position-v*v/(2*acc)>=pos && v<0) acc=-acc;
+            if(pos>=end_position && v>=0) is_finished=true;
+            if(pos<=end_position && v<0) is_finished=true;
+        }
+        //else
+        if(is_finished==true) {
+            v=0;
+            pos=end_position;
+        }
+    }
+
+    //on prend une fois pour toute les mutex et on fait des accès directs
+    output->GetMutex();
+    output->SetValueNoMutex(0,0,pos+pos_off);
+    output->SetValueNoMutex(1,0,v+vel_off);
+    output->ReleaseMutex();
+
+    output->SetDataTime(time);
+}
Index: trunk/lib/FlairFilter/src/TrajectoryGenerator2DCircle.cpp
===================================================================
--- trunk/lib/FlairFilter/src/TrajectoryGenerator2DCircle.cpp	(revision 7)
+++ trunk/lib/FlairFilter/src/TrajectoryGenerator2DCircle.cpp	(revision 7)
@@ -0,0 +1,96 @@
+//  created:    2013/04/08
+//  filename:   TrajectoryGenerator2DCircle.cpp
+//
+//  author:     Guillaume Sanahuja
+//              Copyright Heudiasyc UMR UTC/CNRS 7253
+//
+//  version:    $Id: $
+//
+//  purpose:    Class generating a circle trajectory in 2D
+//
+//
+/*********************************************************************/
+
+#include "TrajectoryGenerator2DCircle.h"
+#include "TrajectoryGenerator2DCircle_impl.h"
+#include <cvmatrix.h>
+#include <Layout.h>
+#include <LayoutPosition.h>
+#include <Vector2D.h>
+
+using std::string;
+using namespace flair::core;
+using namespace flair::gui;
+
+namespace flair
+{
+namespace filter
+{
+
+TrajectoryGenerator2DCircle::TrajectoryGenerator2DCircle(const LayoutPosition* position,string name) : IODevice(position->getLayout(),name)
+{
+    pimpl_=new TrajectoryGenerator2DCircle_impl(this,position,name);
+    AddDataToLog(pimpl_->output);
+}
+
+
+TrajectoryGenerator2DCircle::~TrajectoryGenerator2DCircle()
+{
+    delete pimpl_;
+}
+
+bool TrajectoryGenerator2DCircle::IsRunning(void) const
+{
+    return pimpl_->is_running;
+}
+
+cvmatrix *TrajectoryGenerator2DCircle::Matrix(void) const
+{
+    return pimpl_->output;
+}
+
+void TrajectoryGenerator2DCircle::StartTraj(const Vector2D &start_pos,float nb_lap)
+{
+    pimpl_->StartTraj(start_pos,nb_lap);
+}
+
+void TrajectoryGenerator2DCircle::FinishTraj(void)
+{
+    pimpl_->FinishTraj();
+}
+
+void TrajectoryGenerator2DCircle::StopTraj(void)
+{
+    pimpl_->is_running=false;
+}
+
+void TrajectoryGenerator2DCircle::GetPosition(Vector2D &point) const
+{
+    point.x=pimpl_->output->Value(0,0);
+    point.y=pimpl_->output->Value(0,1);
+}
+
+void TrajectoryGenerator2DCircle::SetCenter(const Vector2D &value)
+{
+    pimpl_->pos_off=value;
+}
+
+void TrajectoryGenerator2DCircle::GetSpeed(Vector2D &point) const
+{
+    point.x=pimpl_->output->Value(1,0);
+    point.y=pimpl_->output->Value(1,1);
+}
+
+void TrajectoryGenerator2DCircle::SetCenterSpeed(const Vector2D &value)
+{
+    pimpl_->vel_off=value;
+}
+
+void TrajectoryGenerator2DCircle::Update(Time time)
+{
+    pimpl_->Update(time);
+    ProcessUpdate(pimpl_->output);
+}
+
+} // end namespace filter
+} // end namespace flair
Index: trunk/lib/FlairFilter/src/TrajectoryGenerator2DCircle.h
===================================================================
--- trunk/lib/FlairFilter/src/TrajectoryGenerator2DCircle.h	(revision 7)
+++ trunk/lib/FlairFilter/src/TrajectoryGenerator2DCircle.h	(revision 7)
@@ -0,0 +1,156 @@
+/*!
+ * \file TrajectoryGenerator2DCircle.h
+ * \brief Class generating a circle trajectory in 2D
+ * \author Guillaume Sanahuja, Copyright Heudiasyc UMR UTC/CNRS 7253
+ * \date 2013/04/08
+ * \version 4.0
+ */
+
+#ifndef TRAJECTORYGENERATOR2DCIRCLE_H
+#define TRAJECTORYGENERATOR2DCIRCLE_H
+
+#include <IODevice.h>
+
+namespace flair
+{
+    namespace core
+    {
+        class cvmatrix;
+        class Vector2D;
+    }
+    namespace gui
+    {
+        class LayoutPosition;
+    }
+}
+
+class TrajectoryGenerator2DCircle_impl;
+
+namespace flair
+{
+namespace filter
+{
+    /*! \class TrajectoryGenerator2DCircle
+    *
+    * \brief Class generating a circle trajectory in 2D
+    *
+    * This class generates position and velocity references, given
+    * a maximum velocity and an absolute acceleration, for a circle. \n
+    * When trajectory is started (StartTraj), position and velocity will increase
+    * at the given acceleration untill maximum velocity is reached. \n
+    * When trajectory is asked to be finished (see FinishTraj()), position
+    * and velocity will decrease at the given acceleration untill null velocity is reached. \n
+    * Position and velocity of the center of the circle can be manually changed
+    * through SetCenter() and SetCenterSpeed().
+    */
+    class TrajectoryGenerator2DCircle : public core::IODevice
+    {
+        public:
+            /*!
+            * \brief Constructor
+            *
+            * Construct a TrajectoryGenerator2DCircle at position. \n
+            * The TrajectoryGenerator2DCircle will automatically be child of position->getLayout() Layout. After calling this function,
+            * position will be deleted as it is no longer usefull. \n
+            *
+            * \param position position to display settings
+            * \param name name
+            */
+            TrajectoryGenerator2DCircle(const gui::LayoutPosition* position,std::string name);
+
+            /*!
+            * \brief Destructor
+            *
+            */
+            ~TrajectoryGenerator2DCircle();
+
+            /*!
+            * \brief Start trajectory
+            *
+            * \param start_pos start position
+            * \param nb_lap number of laps, -1 for infinite
+            */
+            void StartTraj(const core::Vector2D &start_pos,float nb_lap=-1);
+
+            /*!
+            * \brief Stop trajectory
+            *
+            * Stop abruptly the trajectory.
+            */
+            void StopTraj(void);
+
+            /*!
+            * \brief Finish trajectory
+            *
+            * Finish smoothly the trajectory.
+            */
+            void FinishTraj(void);
+
+            /*!
+            * \brief Set center position
+            *
+            * \param value center position
+            */
+            void SetCenter(const core::Vector2D &value);
+
+            /*!
+            * \brief Set center speed
+            *
+            * \param value center speed
+            */
+            void SetCenterSpeed(const core::Vector2D &value);
+
+            /*!
+            * \brief Update using provided datas
+            *
+            * Uses values specified by StartTraj(),
+            * SetCenter() and SetCenterSpeed().
+            *
+            * \param time time of the update
+            */
+            void Update(core::Time time);
+
+            /*!
+            * \brief Position
+            *
+            * \param point returned position
+            */
+            void GetPosition(core::Vector2D &point) const;
+
+            /*!
+            * \brief Speed
+            *
+            * \param point returned speed
+            */
+            void GetSpeed(core::Vector2D &point) const;
+
+            /*!
+            * \brief Output matrix
+            *
+            * \return matrix
+            */
+            core::cvmatrix *Matrix(void) const;
+
+            /*!
+            * \brief Is trajectory running?
+            *
+            * \return true if trajectory is running
+            */
+            bool IsRunning(void) const;
+
+        private:
+            /*!
+            * \brief Update using provided datas
+            *
+            * Reimplemented from IODevice. Nothing to do in this IODevice.
+            *
+            * \param data data from the parent to process
+            */
+            void UpdateFrom(const core::io_data *data){};
+
+            TrajectoryGenerator2DCircle_impl* pimpl_;
+
+    };
+} // end namespace filter
+} // end namespace flair
+#endif // TRAJECTORYGENERATOR2DCIRCLE_H
Index: trunk/lib/FlairFilter/src/TrajectoryGenerator2DCircle_impl.cpp
===================================================================
--- trunk/lib/FlairFilter/src/TrajectoryGenerator2DCircle_impl.cpp	(revision 7)
+++ trunk/lib/FlairFilter/src/TrajectoryGenerator2DCircle_impl.cpp	(revision 7)
@@ -0,0 +1,151 @@
+//  created:    2013/04/08
+//  filename:   TrajectoryGenerator2DCircle_impl.cpp
+//
+//  author:     Guillaume Sanahuja
+//              Copyright Heudiasyc UMR UTC/CNRS 7253
+//
+//  version:    $Id: $
+//
+//  purpose:    objet permettant la generation d'une trajectoire cercle
+//
+//
+/*********************************************************************/
+
+#include "TrajectoryGenerator2DCircle_impl.h"
+#include "TrajectoryGenerator2DCircle.h"
+#include <cvmatrix.h>
+#include <Layout.h>
+#include <GroupBox.h>
+#include <DoubleSpinBox.h>
+#include <cmath>
+
+#define PI ((float)3.14159265358979323846)
+
+using std::string;
+using namespace flair::core;
+using namespace flair::gui;
+using namespace flair::filter;
+
+TrajectoryGenerator2DCircle_impl::TrajectoryGenerator2DCircle_impl(TrajectoryGenerator2DCircle* self,const LayoutPosition* position,string name) {
+    first_update=true;
+    is_running=false;
+    is_finishing=false;
+
+    //init UI
+   GroupBox* reglages_groupbox=new GroupBox(position,name);
+        T=new DoubleSpinBox(reglages_groupbox->NewRow(),"period, 0 for auto"," s",0,1,0.01);
+        rayon=new DoubleSpinBox(reglages_groupbox->LastRowLastCol(),"R"," m",0,1000,.1);
+        veloctity=new DoubleSpinBox(reglages_groupbox->LastRowLastCol(),"velocity"," m/s",-10,10,1);
+        acceleration=new DoubleSpinBox(reglages_groupbox->LastRowLastCol(),"acceleration (absolute)"," m/s²",0,10,.1);
+
+    //init matrix
+    cvmatrix_descriptor* desc=new cvmatrix_descriptor(2,2);
+    desc->SetElementName(0,0,"pos.x");
+    desc->SetElementName(0,1,"pos.y");
+    desc->SetElementName(1,0,"vel.x");
+    desc->SetElementName(1,1,"vel.y");
+    output=new cvmatrix(self,desc,floatType,name);
+
+    output->SetValue(0,0,0);
+    output->SetValue(0,1,0);
+    output->SetValue(1,0,0);
+    output->SetValue(1,1,0);
+}
+
+
+TrajectoryGenerator2DCircle_impl::~TrajectoryGenerator2DCircle_impl() {
+    delete output;
+}
+
+void TrajectoryGenerator2DCircle_impl::StartTraj(const Vector2D &start_pos,float nb_lap) {
+    is_running=true;
+    first_update=true;
+    is_finishing=false;
+    this->nb_lap=nb_lap;
+
+    //configure trajectory
+    angle_off=atan2(start_pos.y-pos_off.y,start_pos.x-pos_off.x);
+    CurrentTime=0;
+}
+
+void TrajectoryGenerator2DCircle_impl::FinishTraj(void) {
+    if(!is_finishing) {
+        is_finishing=true;
+        FinishTime=CurrentTime;
+    }
+}
+
+void TrajectoryGenerator2DCircle_impl::Update(Time time) {
+    float delta_t;
+    float theta;
+    float V=veloctity->Value();
+    float A=acceleration->Value();
+    float R=rayon->Value();
+    Vector2D v;
+
+    if(V<0) A=-A;
+
+    if(T->Value()==0) {
+        if(first_update) {
+            first_update=false;
+            previous_time=time;
+            return;
+        } else {
+            delta_t=(float)(time-previous_time)/1000000000.;
+        }
+    } else {
+        delta_t=T->Value();
+    }
+    previous_time=time;
+    CurrentTime+=delta_t;
+
+    if(is_finishing && CurrentTime>FinishTime+V/A) is_running=false;
+
+    if(is_running) {
+        if(R==0) {
+            pos.x=0;
+            pos.y=0;
+            v.x=0;
+            v.y=0;
+        } else {
+            if(CurrentTime<V/A) {
+                theta=angle_off+A/2*CurrentTime*CurrentTime/R;
+                pos.x=R*cos(theta);
+                pos.y=R*sin(theta);
+                v.x=-A*CurrentTime*sin(theta);
+                v.y=A*CurrentTime*cos(theta);
+            } else {
+                if(!is_finishing) {
+                    theta=angle_off+V*V/(2*A*R)+(CurrentTime-V/A)*V/R;
+                    pos.x=R*cos(theta);
+                    pos.y=R*sin(theta);
+                    v.x=-V*sin(theta);
+                    v.y=V*cos(theta);
+                } else {
+                    theta=angle_off+V*V/(2*A*R)+(FinishTime-V/A)*V/R-A/2*(FinishTime-CurrentTime)*(FinishTime-CurrentTime)/R+V*(CurrentTime-FinishTime)/R;
+                    pos.x=R*cos(theta);
+                    pos.y=R*sin(theta);
+                    v.x=-(V+A*(FinishTime-CurrentTime))*sin(theta);
+                    v.y=(V+A*(FinishTime-CurrentTime))*cos(theta);
+                }
+            }
+        }
+
+        if(theta-angle_off>=nb_lap*2*PI-(-A/2*(V/A)*(V/A)/R+V*(V/A)/R) && nb_lap>0) {
+            FinishTraj();
+        }
+    } else {
+        v.x=0;
+        v.y=0;
+    }
+
+    //on prend une fois pour toute les mutex et on fait des accès directs
+    output->GetMutex();
+    output->SetValueNoMutex(0,0,pos.x+pos_off.x);
+    output->SetValueNoMutex(0,1,pos.y+pos_off.y);
+    output->SetValueNoMutex(1,0,v.x+vel_off.x);
+    output->SetValueNoMutex(1,1,v.y+vel_off.y);
+    output->ReleaseMutex();
+
+    output->SetDataTime(time);
+}
Index: trunk/lib/FlairFilter/src/UavMultiplex.cpp
===================================================================
--- trunk/lib/FlairFilter/src/UavMultiplex.cpp	(revision 7)
+++ trunk/lib/FlairFilter/src/UavMultiplex.cpp	(revision 7)
@@ -0,0 +1,112 @@
+//  created:    2014/04/11
+//  filename:   UavMultiplex.cpp
+//
+//  author:     Guillaume Sanahuja
+//              Copyright Heudiasyc UMR UTC/CNRS 7253
+//
+//  version:    $Id: $
+//
+//  purpose:    Class defining uav multiplexing
+//
+//
+/*********************************************************************/
+
+#include "UavMultiplex.h"
+#include "UavMultiplex_impl.h"
+#include <cvmatrix.h>
+#include <FrameworkManager.h>
+#include <Tab.h>
+#include <GridLayout.h>
+
+using std::string;
+using namespace flair::core;
+using namespace flair::gui;
+
+namespace flair
+{
+namespace filter
+{
+
+UavMultiplex::UavMultiplex(const core::FrameworkManager* parent,std::string name) : IODevice(parent,name)
+{
+    pimpl_=new UavMultiplex_impl(parent,this,name);
+}
+
+UavMultiplex::~UavMultiplex(void)
+{
+    delete pimpl_;
+}
+
+void UavMultiplex::Update(core::Time time)
+{
+    pimpl_->input->SetDataTime(time);
+    UpdateFrom(pimpl_->input);
+}
+
+void UavMultiplex::SetMultiplexComboBox(string name,int index)
+{
+    pimpl_->SetMultiplexComboBox(name,index);
+}
+
+int UavMultiplex::MultiplexValue(int index) const
+{
+    return pimpl_->MultiplexValue(index);
+}
+
+TabWidget* UavMultiplex::GetTabWidget(void) const
+{
+    return pimpl_->tabwidget;
+}
+
+Layout* UavMultiplex::GetLayout(void) const
+{
+    return pimpl_->setup_tab;
+}
+
+void UavMultiplex::LockUserInterface(void) const
+{
+    pimpl_->setup_tab->setEnabled(false);
+}
+
+void UavMultiplex::UnlockUserInterface(void) const
+{
+    pimpl_->setup_tab->setEnabled(true);
+}
+
+void UavMultiplex::SetRoll(float value)
+{
+    pimpl_->input->SetValue(0,0,value);
+}
+
+void UavMultiplex::SetPitch(float value)
+{
+    pimpl_->input->SetValue(1,0,value);
+}
+
+void UavMultiplex::SetYaw(float value)
+{
+    pimpl_->input->SetValue(2,0,value);
+}
+
+void UavMultiplex::SetThrust(float value)
+{
+    pimpl_->input->SetValue(3,0,value);
+}
+
+void UavMultiplex::SetRollTrim(float value)
+{
+    pimpl_->input->SetValue(4,0,value);
+}
+
+void UavMultiplex::SetPitchTrim(float value)
+{
+    pimpl_->input->SetValue(5,0,value);
+}
+
+void UavMultiplex::SetYawTrim(float value)
+{
+    pimpl_->input->SetValue(6,0,value);
+}
+
+} // end namespace filter
+} // end namespace flair
Index: trunk/lib/FlairFilter/src/UavMultiplex.h
===================================================================
--- trunk/lib/FlairFilter/src/UavMultiplex.h	(revision 7)
+++ trunk/lib/FlairFilter/src/UavMultiplex.h	(revision 7)
@@ -0,0 +1,220 @@
+/*!
+ * \file UavMultiplex.h
+ * \brief Class defining uav multiplexing
+ * \author Guillaume Sanahuja, Copyright Heudiasyc UMR UTC/CNRS 7253
+ * \date 2014/04/11
+ * \version 4.0
+ */
+
+#ifndef UAVMULTIPLEX_H
+#define UAVMULTIPLEX_H
+
+#include <IODevice.h>
+#include <stdint.h>
+
+namespace flair
+{
+    namespace core
+    {
+        class FrameworkManager;
+        class io_data;
+    }
+    namespace gui
+    {
+        class TabWidget;
+        class Layout;
+    }
+}
+
+class UavMultiplex_impl;
+
+namespace flair
+{
+namespace filter
+{
+    /*! \class UavMultiplex
+    *
+    * \brief Class defining uav multiplexing
+    */
+    class UavMultiplex : public core::IODevice
+    {
+        public:
+            /*!
+            * \brief Constructor
+            *
+            * Construct a uav multiplexing
+            *
+            * \param parent parent
+            * \param name name
+            */
+            UavMultiplex(const core::FrameworkManager* parent,std::string name);
+
+            /*!
+            * \brief Destructor
+            *
+            */
+            ~UavMultiplex();
+
+            /*!
+            * \brief Set roll torque
+            *
+            * roll torque is placed in input(0,0)
+            *
+            * \param value value between -1 and 1
+            */
+            void SetRoll(float value);
+
+            /*!
+            * \brief Set pitch torque
+            *
+            * pitch torque is placed in input(1,0)
+            *
+            * \param value value between -1 and 1
+            */
+            void SetPitch(float value);
+
+            /*!
+            * \brief Set yaw torque
+            *
+            * yaw torque is placed in input(2,0)
+            *
+            * \param value value between -1 and 1
+            */
+            void SetYaw(float value);
+
+            /*!
+            * \brief Set thrust
+            *
+            * thrust is placed in input(3,0)
+            *
+            * \param value value between 0 and 1
+            */
+            void SetThrust(float value);
+
+            /*!
+            * \brief Set roll trim
+            *
+            * trim is placed in input(4,0)
+            *
+            * \param value value
+            */
+            void SetRollTrim(float value);
+
+            /*!
+            * \brief Set pitch trim
+            *
+            * trim is placed in input(5,0)
+            *
+            * \param value value
+            */
+            void SetPitchTrim(float value);
+
+            /*!
+            * \brief Set yaw trim
+            *
+            * trim is placed in input(6,0)
+            *
+            * \param value value
+            */
+            void SetYawTrim(float value);
+
+            /*!
+            * \brief Update using provided datas
+            *
+            * Uses values specified by Set*().
+            *
+            * \param time time of the update
+            */
+            void Update(core::Time time);
+
+            /*!
+            * \brief Lock user interface
+            *
+            * User interface will be grayed out.\n
+            * Use it do disallow changes when flying.
+            *
+            */
+            void LockUserInterface(void) const;
+
+            /*!
+            * \brief Unlock user interface
+            *
+            * User interface will be enabled.\n
+            *
+            */
+            void UnlockUserInterface(void) const;
+
+            /*!
+            * \brief Layout
+            *
+            * Layout to place custom widgets.\n
+            *
+            * \return the layout
+            */
+            gui::Layout* GetLayout(void) const;
+
+            /*!
+            * \brief Use default plot
+            *
+            * Derived class can implement this function do draw default plot.
+            *
+            */
+            virtual void UseDefaultPlot(void){};
+
+            /*!
+            * \brief Motors count
+            *
+            * This function must be reimplemented, in order to get the number of motors.
+            *
+            * \return motors count
+            */
+            virtual uint8_t MotorsCount(void) const=0;
+
+            /*!
+            * \brief Multiplex value
+            *
+            * Get the mutliplexed value of a motor, if SetMultiplexComboBox() was used.\n
+            *
+            * \param index index of the motor, from 0 to MotorsCount()
+            * \return multiplexed index of the motor
+            */
+            int MultiplexValue(int index) const;
+
+            /*!
+            * \brief Get TabWidget
+            *
+            * Usefull to add tabs.\n
+            *
+            * \return the TabWidget
+            */
+            gui::TabWidget* GetTabWidget(void) const;
+
+        protected:
+            /*!
+            * \brief Set multiplex ComboBox
+            *
+            * Draws a ComboBox to define motor multiplexing. \n
+            * This is used to change the order of the output motors.
+            *
+            * \param name description of the motor (ex front left)
+            * \param index index of the motor, from 0 to MotorsCount()
+            */
+            void SetMultiplexComboBox(std::string name,int index);
+
+        private:
+            /*!
+            * \brief Update using provided datas
+            *
+            * This function is automatically called by ProcessUpdate()
+            * of the Object::Parent's if its Object::ObjectType is "IODevice". \n
+            * This function must be reimplemented, in order to process the data from the parent.
+            *
+            * \param data data from the parent to process
+            */
+            virtual void UpdateFrom(const core::io_data *data)=0;
+
+            UavMultiplex_impl *pimpl_;
+    };
+} // end namespace filter
+} // end namespace flair
+#endif // UAVMULTIPLEX_H
Index: trunk/lib/FlairFilter/src/UavMultiplex_impl.cpp
===================================================================
--- trunk/lib/FlairFilter/src/UavMultiplex_impl.cpp	(revision 7)
+++ trunk/lib/FlairFilter/src/UavMultiplex_impl.cpp	(revision 7)
@@ -0,0 +1,90 @@
+//  created:    2014/04/11
+//  filename:   UavMultiplex_impl.cpp
+//
+//  author:     Guillaume Sanahuja
+//              Copyright Heudiasyc UMR UTC/CNRS 7253
+//
+//  version:    $Id: $
+//
+//  purpose:    Class defining uav multiplexing
+//
+//
+/*********************************************************************/
+
+#include "UavMultiplex_impl.h"
+#include "UavMultiplex.h"
+#include <cvmatrix.h>
+#include <FrameworkManager.h>
+#include <TabWidget.h>
+#include <Tab.h>
+#include <GridLayout.h>
+#include <ComboBox.h>
+#include <GroupBox.h>
+#include <sstream>
+
+using std::string;
+using std::ostringstream;
+using namespace flair::core;
+using namespace flair::gui;
+using namespace flair::filter;
+
+UavMultiplex_impl::UavMultiplex_impl(const FrameworkManager* parent,UavMultiplex* self,std::string name) {
+    input=new cvmatrix(self,7,1,floatType);
+    multiplexcombobox=NULL;
+    this->self=self;
+
+    //station sol
+    main_tab=new Tab(parent->GetTabWidget(),name);
+    tabwidget=new TabWidget(main_tab->NewRow(),"UavMultiplex");
+	setup_tab=new Tab(tabwidget,"Setup");
+}
+
+UavMultiplex_impl::~UavMultiplex_impl(void)
+{
+    delete main_tab;
+    if(multiplexcombobox!=NULL) free(multiplexcombobox);
+}
+
+void UavMultiplex_impl::SetMultiplexComboBox(string name,int index)
+{
+    //we do not know motorcount at constructor time, so allocation is done here
+    if(multiplexcombobox==NULL)
+    {
+        multiplexcombobox=(ComboBox**)malloc(self->MotorsCount()*sizeof(ComboBox*));
+        for(int i=0;i<self->MotorsCount();i++) multiplexcombobox[i]=NULL;
+        groupbox=new GroupBox(setup_tab->NewRow(),"motor attribution");
+    }
+    if(index>self->MotorsCount())
+    {
+        self->Err("index out of bound %i/%i\n",index,self->MotorsCount());
+        return;
+    }
+    if(multiplexcombobox[index]!=NULL)
+    {
+        self->Err("index already setup\n");
+        return;
+    }
+
+    multiplexcombobox[index]=new ComboBox(groupbox->At(index/4,index%4),name);
+
+    for(int i=0;i<self->MotorsCount();i++)
+    {
+        ostringstream oss;
+        oss << i;
+        multiplexcombobox[index]->AddItem(oss.str());
+    }
+}
+
+int UavMultiplex_impl::MultiplexValue(int index) const
+{
+    if(multiplexcombobox[index]!=NULL)
+    {
+        return multiplexcombobox[index]->CurrentIndex();
+    }
+    else
+    {
+        self->Err("multiplex not setup for motor %i\n",index);
+        return 0;
+    }
+
+}
Index: trunk/lib/FlairFilter/src/X4X8Multiplex.cpp
===================================================================
--- trunk/lib/FlairFilter/src/X4X8Multiplex.cpp	(revision 7)
+++ trunk/lib/FlairFilter/src/X4X8Multiplex.cpp	(revision 7)
@@ -0,0 +1,72 @@
+//  created:    2014/04/10
+//  filename:   X4X8Multiplex.cpp
+//
+//  author:     Guillaume Sanahuja
+//              Copyright Heudiasyc UMR UTC/CNRS 7253
+//
+//  version:    $Id: $
+//
+//  purpose:    Class defining X4 and X8 multiplexing
+//
+//
+/*********************************************************************/
+
+#include "X4X8Multiplex.h"
+#include "X4X8Multiplex_impl.h"
+
+using std::string;
+using namespace flair::core;
+using namespace flair::gui;
+
+namespace flair
+{
+namespace filter
+{
+
+X4X8Multiplex::X4X8Multiplex(const FrameworkManager* parent,std::string name,UavType_t type) : UavMultiplex(parent,name)
+{
+    int nb_mot;
+
+    switch(type)
+    {
+        case X4:
+            nb_mot=4;
+            break;
+        case X8:
+            nb_mot=8;
+            break;
+        default:
+            Err("uav type not supported\n");
+            break;
+    }
+
+    pimpl_=new X4X8Multiplex_impl(this,nb_mot);
+
+    for(int i=0;i<nb_mot;i++)
+    {
+        SetMultiplexComboBox(pimpl_->MotorName(i),i);
+    }
+}
+
+X4X8Multiplex::~X4X8Multiplex(void)
+{
+    delete pimpl_;
+}
+
+uint8_t X4X8Multiplex::MotorsCount(void) const
+{
+    return pimpl_->nb_mot;
+}
+
+void X4X8Multiplex::UseDefaultPlot(void)
+{
+    pimpl_->UseDefaultPlot();
+}
+
+void X4X8Multiplex::UpdateFrom(const io_data *data)
+{
+    pimpl_->UpdateFrom(data);
+}
+
+} // end namespace filter
+} // end namespace flair
Index: trunk/lib/FlairFilter/src/X4X8Multiplex.h
===================================================================
--- trunk/lib/FlairFilter/src/X4X8Multiplex.h	(revision 7)
+++ trunk/lib/FlairFilter/src/X4X8Multiplex.h	(revision 7)
@@ -0,0 +1,104 @@
+/*!
+ * \file X4X8Multiplex.h
+ * \brief Class defining X4 and X8 multiplexing
+ * \author Guillaume Sanahuja, Copyright Heudiasyc UMR UTC/CNRS 7253
+ * \date 2014/04/10
+ * \version 4.0
+ */
+
+#ifndef X4X8MULTIPLEX_H
+#define X4X8MULTIPLEX_H
+
+#include <UavMultiplex.h>
+
+class X4X8Multiplex_impl;
+
+namespace flair
+{
+namespace filter
+{
+    /*! \class X4X8Multiplex
+    *
+    * \brief Class defining X4 and X8 multiplexing
+    *
+    * The output order of the motors can be changed through ground station.
+    */
+    class X4X8Multiplex : public UavMultiplex
+    {
+        friend class ::X4X8Multiplex_impl;
+
+        public:
+             /*!
+            \enum UavType_t
+            \brief type of UAV
+            */
+            typedef enum {
+                X4,/*!< 4 motors: front left, front right, rear left, rear right */
+                X8/*!< 8 motors: top front left, top front right, top rear left, top rear right, bottom front left, bottom front right, bottom rear left, bottom rear right */
+                } UavType_t;
+
+            /*!
+            \enum MotorNames_t
+            \brief Motor names
+            */
+            typedef enum {
+                TopFrontLeft=0,/*!< Top front left, X4 or X8 */
+                TopFrontRight=1,/*!< Top front right, X4 or X8 */
+                TopRearLeft=2,/*!< Top rear left, X4 or X8 */
+                TopRearRight=3,/*!< Top rear right, X4 or X8 */
+                BottomFrontLeft=4,/*!< Bottom front left, X8 */
+                BottomFrontRight=5,/*!< Bottom front right, X8 */
+                BottomRearLeft=6,/*!< Bottom rear left, X8 */
+                BottomRearRight=7,/*!< Bottom rear right, X8 */
+                } MotorNames_t;
+
+            /*!
+            * \brief Constructor
+            *
+            * Construct a X4 and X8 multiplexing
+            *
+            * \param parent parent
+            * \param name name
+            * \param type type
+            */
+            X4X8Multiplex(const core::FrameworkManager* parent,std::string name,UavType_t type);
+
+            /*!
+            * \brief Destructor
+            *
+            */
+            ~X4X8Multiplex();
+
+            /*!
+            * \brief Use default plot
+            *
+            * Plot the output values.
+            *
+            */
+            void UseDefaultPlot(void);
+
+            /*!
+            * \brief Motors count
+            *
+            * Reimplemented from UavMultiplex.
+            *
+            * \return motors count
+            */
+            uint8_t MotorsCount(void) const;
+
+        private:
+            /*!
+            * \brief Update using provided datas
+            *
+            * Reimplemented from IODevice.
+            *
+            * \param data data from the parent to process
+            */
+            void UpdateFrom(const core::io_data *data);
+
+            X4X8Multiplex_impl *pimpl_;
+
+    };
+} // end namespace filter
+} // end namespace flair
+#endif // X4X8MULTIPLEX_H
Index: trunk/lib/FlairFilter/src/X4X8Multiplex_impl.cpp
===================================================================
--- trunk/lib/FlairFilter/src/X4X8Multiplex_impl.cpp	(revision 7)
+++ trunk/lib/FlairFilter/src/X4X8Multiplex_impl.cpp	(revision 7)
@@ -0,0 +1,227 @@
+//  created:    2014/04/10
+//  filename:   X4X8Multiplex_impl.cpp
+//
+//  author:     Guillaume Sanahuja
+//              Copyright Heudiasyc UMR UTC/CNRS 7253
+//
+//  version:    $Id: $
+//
+//  purpose:    Class defining X4 and X8 multiplexing
+//
+//
+/*********************************************************************/
+
+#include "X4X8Multiplex_impl.h"
+#include "X4X8Multiplex.h"
+#include <cvmatrix.h>
+#include <Tab.h>
+#include <GridLayout.h>
+#include <GroupBox.h>
+#include <ComboBox.h>
+#include <DataPlot1D.h>
+#include <math.h>
+
+#define MAX_MOTORS 8
+
+using std::string;
+using namespace flair::core;
+using namespace flair::gui;
+using namespace flair::filter;
+
+X4X8Multiplex_impl::X4X8Multiplex_impl(flair::filter::X4X8Multiplex* self,int nb_mot)
+{
+    this->nb_mot=nb_mot;
+    this->self=self;
+
+    if(nb_mot==4)
+    {
+        GroupBox *groupbox=new GroupBox(self->GetLayout()->NewRow(),"x4 multiplex");
+        pas=new ComboBox(groupbox->NewRow(),"front left blade pitch:");
+    }
+    else
+    {
+        GroupBox *groupbox=new GroupBox(self->GetLayout()->NewRow(),"x8 multiplex");
+        pas=new ComboBox(groupbox->NewRow(),"top front left blade pitch:");
+    }
+    pas->AddItem("normal");
+    pas->AddItem("inverted");
+
+    cvmatrix_descriptor* desc=new cvmatrix_descriptor(nb_mot,1);
+    for(int i=0;i<nb_mot;i++)
+    {
+        desc->SetElementName(i,0,MotorName(i));
+    }
+
+    output=new cvmatrix(self,desc,floatType);
+
+    self->AddDataToLog(output);
+}
+
+X4X8Multiplex_impl::~X4X8Multiplex_impl(void)
+{
+}
+
+void X4X8Multiplex_impl::UseDefaultPlot(void)
+{
+    Tab *plot_tab=new Tab(self->GetTabWidget(),"Values");
+    plots[0]=new DataPlot1D(plot_tab->NewRow(),"front left",0,1);
+    plots[1]=new DataPlot1D(plot_tab->LastRowLastCol(),"front right",0,1);
+    plots[2]=new DataPlot1D(plot_tab->NewRow(),"rear left",0,1);
+    plots[3]=new DataPlot1D(plot_tab->LastRowLastCol(),"rear right",0,1);
+
+    for(int i=0;i<4;i++) plots[i]->AddCurve(output->Element(i));
+
+    if(nb_mot==8)
+    {
+        for(int i=0;i<4;i++) plots[i]->AddCurve(output->Element(i+4),DataPlot::Blue);
+    }
+}
+
+void X4X8Multiplex_impl::UpdateFrom(const io_data *data)
+{
+    float u_roll,u_pitch,u_yaw,u_thrust;
+    float trim_roll,trim_pitch,trim_yaw;
+    float value[MAX_MOTORS];
+
+    cvmatrix* input=(cvmatrix*)data;
+
+    //on prend une fois pour toute le mutex et on fait des accès directs
+    input->GetMutex();
+
+    u_roll=input->ValueNoMutex(0,0);
+    u_pitch=input->ValueNoMutex(1,0);
+    u_yaw=input->ValueNoMutex(2,0);
+    u_thrust=input->ValueNoMutex(3,0);
+    trim_roll=input->ValueNoMutex(4,0);
+    trim_pitch=input->ValueNoMutex(5,0);
+    trim_yaw=input->ValueNoMutex(6,0);
+
+    input->ReleaseMutex();
+
+    if(pas->CurrentIndex()==1)
+    {
+        trim_yaw=-trim_yaw;
+        u_yaw=-u_yaw;
+    }
+
+if(nb_mot==2)
+{
+    //(top) front left
+    value[self->MultiplexValue(X4X8Multiplex::TopFrontLeft)]=Set(trim_pitch+trim_roll+trim_yaw,
+                 u_thrust+u_pitch+u_roll+u_yaw);
+
+    //(top) front right
+    value[self->MultiplexValue(X4X8Multiplex::TopFrontRight)]=Set(trim_pitch-trim_roll-trim_yaw,
+                 u_thrust+u_pitch-u_roll-u_yaw);
+}
+    if(nb_mot==4 || nb_mot==8)
+    {
+        //(top) front left
+        value[self->MultiplexValue(X4X8Multiplex::TopFrontLeft)]=Set(trim_pitch+trim_roll+trim_yaw,
+                     u_thrust+u_pitch+u_roll+u_yaw);
+
+        //(top) front right
+        value[self->MultiplexValue(X4X8Multiplex::TopFrontRight)]=Set(trim_pitch-trim_roll-trim_yaw,
+                     u_thrust+u_pitch-u_roll-u_yaw);
+
+        //(top) rear left
+        value[self->MultiplexValue(X4X8Multiplex::TopRearLeft)]=Set(-trim_pitch+trim_roll-trim_yaw,
+                     u_thrust-u_pitch+u_roll-u_yaw);
+
+        //(top) rear right
+        value[self->MultiplexValue(X4X8Multiplex::TopRearRight)]=Set(-trim_pitch-trim_roll+trim_yaw,
+                     u_thrust-u_pitch-u_roll+u_yaw);
+    }
+
+    if(nb_mot==8)
+    {
+        //bottom front left
+        value[self->MultiplexValue(X4X8Multiplex::BottomFrontLeft)]=Set(trim_pitch+trim_roll-trim_yaw,
+                     u_thrust+u_pitch+u_roll-u_yaw);
+
+        //bottom front right
+        value[self->MultiplexValue(X4X8Multiplex::BottomFrontRight)]=Set(trim_pitch-trim_roll+trim_yaw,
+                     u_thrust+u_pitch-u_roll+u_yaw);
+
+        //bottom rear left
+        value[self->MultiplexValue(X4X8Multiplex::BottomRearLeft)]=Set(-trim_pitch+trim_roll+trim_yaw,
+                     u_thrust-u_pitch+u_roll+u_yaw);
+
+        //bottom rear right
+        value[self->MultiplexValue(X4X8Multiplex::BottomRearRight)]=Set(-trim_pitch-trim_roll-trim_yaw,
+                     u_thrust-u_pitch-u_roll-u_yaw);
+
+    }
+
+    //on prend une fois pour toute le mutex et on fait des accès directs
+    output->GetMutex();
+    for(int i=0;i<nb_mot;i++) output->SetValueNoMutex(i,0,value[i]);
+    output->ReleaseMutex();
+
+    output->SetDataTime(data->DataTime());
+
+    self->ProcessUpdate(output);
+}
+
+float X4X8Multiplex_impl::Set(float trim,float u)
+{
+    float value=trim;
+
+    if(u>0)
+    {
+        value+=sqrtf(u);
+    }
+
+    return value;
+}
+
+string X4X8Multiplex_impl::MotorName(int index)
+{
+    switch(nb_mot)
+    {
+        case 4:
+        {
+            switch(index)
+            {
+                case 0:
+                    return "front left";
+                case 1:
+                    return "front rigth";
+                case 2:
+                    return "rear left";
+                case 3:
+                    return "rear rigth";
+                default:
+                    return "unammed motor";
+            }
+        }
+        case 8:
+        {
+            switch(index)
+            {
+                case 0:
+                    return "top front left";
+                case 1:
+                    return "top front rigth";
+                case 2:
+                    return "top rear left";
+                case 3:
+                    return "top rear rigth";
+                case 4:
+                    return "bottom front left";
+                case 5:
+                    return "bottom front rigth";
+                case 6:
+                    return "bottom rear left";
+                case 7:
+                    return "bottom rear rigth";
+                default:
+                    return "unammed motor";
+            }
+        }
+        default:
+        {
+            return "unammed motor";
+        }
+    }
+}
Index: trunk/lib/FlairFilter/src/groups.dox
===================================================================
--- trunk/lib/FlairFilter/src/groups.dox	(revision 7)
+++ trunk/lib/FlairFilter/src/groups.dox	(revision 7)
@@ -0,0 +1,4 @@
+/*! \namespace framework::filter
+ * 
+ * \brief Filter classes
+ */
Index: trunk/lib/FlairFilter/src/unexported/Ahrs_impl.h
===================================================================
--- trunk/lib/FlairFilter/src/unexported/Ahrs_impl.h	(revision 7)
+++ trunk/lib/FlairFilter/src/unexported/Ahrs_impl.h	(revision 7)
@@ -0,0 +1,50 @@
+/*!
+ * \file Ahrs_impl.h
+ * \brief Virtual class for Ahrs_impl
+ * \author Guillaume Sanahuja, Copyright Heudiasyc UMR UTC/CNRS 7253
+ * \date 2014/01/14
+ * \version 4.0
+ */
+
+#ifndef AHRS_IMPL_H
+#define AHRS_IMPL_H
+
+#include <DataPlot.h>
+
+namespace flair {
+    namespace core {
+        class AhrsData;
+    }
+    namespace gui {
+        class Tab;
+        class DataPlot1D;
+    }
+    namespace filter {
+        class Ahrs;
+    }
+}
+
+/*! \class Ahrs_impl
+* \brief Abstract class for Ahrs_impl
+*
+* Use this class to define a custom Ahrs_impl. \n
+*
+*/
+
+class Ahrs_impl {
+    public:
+        Ahrs_impl(flair::filter::Ahrs* self);
+        ~Ahrs_impl();
+        void UseDefaultPlot(void);
+        void AddPlot(const flair::core::AhrsData *ahrsData,flair::gui::DataPlot::Color_t color);
+        flair::gui::DataPlot1D *rollPlot,*pitchPlot,*yawPlot;
+        flair::gui::DataPlot1D *wXPlot,*wYPlot,*wZPlot;
+        flair::gui::DataPlot1D *q0Plot,*q1Plot,*q2Plot,*q3Plot;
+        flair::core::AhrsData *ahrsData;
+
+    private:
+        flair::gui::Tab *eulerTab,*quaternionTab;
+        flair::filter::Ahrs* self;
+};
+
+#endif // AHRS_IMPL_H
Index: trunk/lib/FlairFilter/src/unexported/ButterworthLowPass_impl.h
===================================================================
--- trunk/lib/FlairFilter/src/unexported/ButterworthLowPass_impl.h	(revision 7)
+++ trunk/lib/FlairFilter/src/unexported/ButterworthLowPass_impl.h	(revision 7)
@@ -0,0 +1,151 @@
+/*!
+ * \file ButterworthLowPass_impl.h
+ * \brief Classe permettant le calcul d'un filtre passe bas de Butterworth
+ * \author Guillaume Sanahuja, Copyright Heudiasyc UMR UTC/CNRS 7253
+ * \date 2011/05/01
+ * \version 4.0
+ */
+
+#ifndef BUTTERWORTHLOWPASS_H_IMPL_H
+#define BUTTERWORTHLOWPASS_H_IMPL_H
+
+#include <IODevice.h>
+#include <Butterworth.h>
+
+namespace flair
+{
+    namespace core
+    {
+        class cvmatrix;
+    }
+    namespace gui
+    {
+        class LayoutPosition;
+        class SpinBox;
+        class DoubleSpinBox;
+    }
+    namespace filter
+    {
+        class ButterworthLowPass;
+    }
+}
+
+// Storage for Layout
+//de-templatized for pimpl idom
+//comes from iir from Bernd Porr
+class LayoutStorage
+{
+    public:
+        LayoutStorage(int MaxPoles)
+        {
+            this->MaxPoles=MaxPoles;
+            m_pairs=(Iir::PoleZeroPair*)malloc((MaxPoles+1)/2*sizeof(Iir::PoleZeroPair));
+        }
+        ~LayoutStorage()
+        {
+            free(m_pairs);
+        }
+        operator Iir::LayoutBase ()
+        {
+            return Iir::LayoutBase (MaxPoles, m_pairs);
+        }
+
+    private:
+        Iir::PoleZeroPair *m_pairs;
+        int MaxPoles;
+};
+
+// Storage for Cascade
+//de-templatized for pimpl idom
+//comes from iir from Bernd Porr
+class CascadeStages
+{
+    public:
+        CascadeStages(int MaxStages)
+        {
+            this->MaxStages=MaxStages;
+            m_stages=(Iir::Cascade::Stage*)malloc(MaxStages*sizeof(Iir::Cascade::Stage));
+            m_states=(Iir::DirectFormII*)malloc(MaxStages*sizeof(Iir::DirectFormII));
+        }
+        ~CascadeStages()
+        {
+            free(m_stages);
+            free(m_states);
+        }
+        void reset ()
+        {
+            Iir::DirectFormII* state = m_states;
+            for (int i = MaxStages; --i >= 0; ++state)
+            state->reset();
+        }
+
+        template <typename Sample>
+        inline Sample filter(const Sample in)
+        {
+            double out = in;
+            Iir::DirectFormII* state = m_states;
+            Iir::Biquad const* stage = m_stages;
+            for (int i = MaxStages; --i >= 0; ++state, ++stage)
+            out = state->process1 (out, *stage);
+            return static_cast<Sample> (out);
+        }
+
+        Iir::Cascade::Storage getCascadeStorage()
+        {
+            return Iir::Cascade::Storage (MaxStages, m_stages);
+        }
+
+    private:
+        int MaxStages;
+        Iir::Cascade::Stage *m_stages;
+        Iir::DirectFormII *m_states;
+};
+
+//de-templatized for pimpl idom
+//comes from iir from Bernd Porr
+class PoleFilter : Iir::Butterworth::LowPassBase,public CascadeStages
+{
+    public:
+        PoleFilter (int MaxPoles):CascadeStages((MaxPoles + 1) / 2)
+        {
+            this->MaxPoles=MaxPoles;
+            m_analogStorage=new LayoutStorage(MaxPoles);
+            m_digitalStorage=new LayoutStorage(MaxPoles);
+            // This glues together the factored base classes
+            // with the templatized storage classes.
+            Iir::Butterworth::LowPassBase::setCascadeStorage (this->getCascadeStorage());
+            Iir::Butterworth::LowPassBase::setPrototypeStorage (*m_analogStorage,*m_digitalStorage);
+        }
+        ~PoleFilter()
+        {
+            delete m_analogStorage;
+            delete m_digitalStorage;
+        }
+        void setup (double sampleRate,double cutoffFrequency)
+        {
+            Iir::Butterworth::LowPassBase::setup (MaxPoles, sampleRate,cutoffFrequency);
+        }
+
+    private:
+        int MaxPoles;
+        LayoutStorage* m_analogStorage;
+        LayoutStorage* m_digitalStorage;
+};
+
+
+class ButterworthLowPass_impl
+{
+    public:
+        ButterworthLowPass_impl(flair::filter::ButterworthLowPass* self,const flair::gui::LayoutPosition* position,std::string name,int order);
+        ~ButterworthLowPass_impl();
+        void UpdateFrom(const flair::core::io_data *data);
+        flair::core::cvmatrix *output;
+
+    private:
+        flair::gui::DoubleSpinBox *cutoff,*T;
+        PoleFilter* f;
+        bool first_update;
+        flair::core::Time previous_time;
+};
+
+#endif // BUTTERWORTHLOWPASS_H_IMPL_H
Index: trunk/lib/FlairFilter/src/unexported/EulerDerivative_impl.h
===================================================================
--- trunk/lib/FlairFilter/src/unexported/EulerDerivative_impl.h	(revision 7)
+++ trunk/lib/FlairFilter/src/unexported/EulerDerivative_impl.h	(revision 7)
@@ -0,0 +1,51 @@
+/*!
+ * \file EulerDerivative.h
+ * \brief Classe permettant le calcul d'une derivee d'Euler
+ * \author Guillaume Sanahuja, Copyright Heudiasyc UMR UTC/CNRS 7253
+ * \date 2011/05/01
+ * \version 4.0
+ */
+
+#ifndef EULERDERIVATIVE_IMPL_H
+#define EULERDERIVATIVE_IMPL_H
+
+#include <IODevice.h>
+
+namespace flair
+{
+    namespace core
+    {
+        class cvmatrix;
+    }
+    namespace gui
+    {
+        class LayoutPosition;
+        class DoubleSpinBox;
+    }
+    namespace filter
+    {
+        class EulerDerivative;
+    }
+}
+
+/*! \class EulerDerivative
+* \brief Classe permettant le calcul d'une derivee d'Euler
+*/
+
+class EulerDerivative_impl
+{
+    public:
+        EulerDerivative_impl(flair::filter::EulerDerivative* self,const flair::gui::LayoutPosition* position,std::string name,const flair::core::cvmatrix* init_value=NULL);
+        ~EulerDerivative_impl();
+        void UpdateFrom(const flair::core::io_data *data);
+        flair::core::cvmatrix *output;
+
+    private:
+        flair::gui::DoubleSpinBox* T;
+        flair::core::Time previous_time;
+        bool first_update;
+        flair::core::cvmatrix* prev_value;
+
+};
+
+#endif // EULERDERIVATIVE_IMPL_H
Index: trunk/lib/FlairFilter/src/unexported/JoyReference_impl.h
===================================================================
--- trunk/lib/FlairFilter/src/unexported/JoyReference_impl.h	(revision 7)
+++ trunk/lib/FlairFilter/src/unexported/JoyReference_impl.h	(revision 7)
@@ -0,0 +1,81 @@
+//  created:    2012/08/29
+//  filename:   JoyReference_impl.h
+//
+//  author:     Guillaume Sanahuja
+//              Copyright Heudiasyc UMR UTC/CNRS 7253
+//
+//  version:    $Id: $
+//
+//  purpose:    generation de consignes a partir joystick
+//
+//
+/*********************************************************************/
+
+#ifndef JOYREFERENCE_IMPL_H
+#define JOYREFERENCE_IMPL_H
+
+#include <stdint.h>
+#include <Object.h>
+#include <Quaternion.h>
+
+namespace flair {
+    namespace core {
+        class cvmatrix;
+        class io_data;
+        class AhrsData;
+    }
+    namespace gui {
+        class LayoutPosition;
+        class GroupBox;
+        class DoubleSpinBox;
+        class SpinBox;
+        class Label;
+        class PushButton;
+    }
+    namespace filter {
+        class JoyReference;
+    }
+}
+
+class JoyReference_impl {
+
+    public:
+        JoyReference_impl(flair::filter::JoyReference *self,const flair::gui::LayoutPosition* position,std::string name);
+        ~JoyReference_impl();
+        void SetRollAxis(float value);
+        void SetPitchAxis(float value);
+        void SetYawAxis(float value);
+        void SetAltitudeAxis(float value);
+        float ZRef(void) const;
+        float dZRef(void) const;
+        float RollTrim(void) const;
+        float PitchTrim(void) const;
+        void SetYawRef(float value);
+        void SetZRef(float value);
+        void RollTrimUp(void);
+        void RollTrimDown(void);
+        void PitchTrimUp(void);
+        void PitchTrimDown(void);
+        void Update(flair::core::Time time);
+        void UpdateFrom(const flair::core::io_data *data);
+        flair::core::cvmatrix *output;
+        flair::core::AhrsData *ahrsData;
+
+    private:
+        flair::core::cvmatrix *input;
+
+        flair::gui::GroupBox *reglages_groupbox;
+        flair::gui::DoubleSpinBox *deb_roll,*deb_pitch,*deb_wz,*deb_dz;
+        flair::gui::DoubleSpinBox *trim;
+        flair::gui::Label *label_roll,*label_pitch;
+        flair::gui::PushButton *button_roll,*button_pitch;
+
+        float z_ref;
+        flair::core::Quaternion q_z=flair::core::Quaternion(1,0,0,0);
+        float trim_roll,trim_pitch;
+        flair::core::Time previous_time;
+
+        flair::filter::JoyReference *self;
+};
+
+#endif // JOYREFERENCE_IMPL_H
Index: trunk/lib/FlairFilter/src/unexported/LowPassFilter_impl.h
===================================================================
--- trunk/lib/FlairFilter/src/unexported/LowPassFilter_impl.h	(revision 7)
+++ trunk/lib/FlairFilter/src/unexported/LowPassFilter_impl.h	(revision 7)
@@ -0,0 +1,48 @@
+/*!
+ * \file LowPassFilter_impl.h
+ * \brief Classe permettant le calcul d'un filtre passe bas
+ * \author Guillaume Sanahuja, Copyright Heudiasyc UMR UTC/CNRS 7253
+ * \date 2011/05/01
+ * \version 4.0
+ */
+
+#ifndef LOWPASSFILTER_FILTER_IMPL_H
+#define LOWPASSFILTER_FILTER_IMPL_H
+
+#include <IODevice.h>
+
+namespace flair
+{
+    namespace core
+    {
+        class cvmatrix;
+    }
+    namespace gui
+    {
+        class LayoutPosition;
+        class SpinBox;
+        class DoubleSpinBox;
+    }
+    namespace filter
+    {
+        class LowPassFilter;
+    }
+}
+
+class LowPassFilter_impl
+{
+
+    public:
+        LowPassFilter_impl(const flair::filter::LowPassFilter* self,const flair::gui::LayoutPosition* position,std::string name,const flair::core::cvmatrix* init_value=NULL);
+        ~LowPassFilter_impl();
+        void UpdateFrom(const flair::core::io_data *data);
+        flair::core::cvmatrix *output;
+
+    private:
+        flair::core::Time previous_time;
+        bool first_update;
+        flair::core::cvmatrix* prev_value;
+        flair::gui::DoubleSpinBox *freq,*T;
+};
+
+#endif // LOWPASSFILTER_FILTER_IMPL_H
Index: trunk/lib/FlairFilter/src/unexported/NestedSat_impl.h
===================================================================
--- trunk/lib/FlairFilter/src/unexported/NestedSat_impl.h	(revision 7)
+++ trunk/lib/FlairFilter/src/unexported/NestedSat_impl.h	(revision 7)
@@ -0,0 +1,56 @@
+/*!
+ * \file NestedSat.h
+ * \brief Classe permettant le calcul d'un Pid avec saturations
+ * \author Guillaume Sanahuja, Copyright Heudiasyc UMR UTC/CNRS 7253
+ * \date 2013/04/15
+ * \version 4.0
+ */
+
+#ifndef NESTEDSAT_IMPL_H
+#define NESTEDSAT_IMPL_H
+
+#include <Object.h>
+
+namespace flair
+{
+    namespace core
+    {
+        class cvmatrix;
+        class io_data;
+    }
+    namespace gui
+    {
+        class Layout;
+        class LayoutPosition;
+        class DoubleSpinBox;
+        class DataPlot1D;
+    }
+    namespace filter
+    {
+        class NestedSat;
+    }
+}
+
+/*! \class NestedSat
+* \brief Classe permettant le calcul d'un Pid avec saturations
+*/
+class NestedSat_impl
+{
+    public:
+        NestedSat_impl(flair::filter::NestedSat* self,const flair::gui::LayoutPosition* position,std::string name);
+        ~NestedSat_impl();
+        float Value(void);
+        void UseDefaultPlot(const flair::gui::Layout* layout,int row,int col);
+        void UpdateFrom(const flair::core::io_data *data);
+        void ConvertSatFromDegToRad(void);
+        float k;
+
+    private:
+        flair::filter::NestedSat* self;
+        flair::gui::DoubleSpinBox *kp,*kd,*sat,*dsat,*usat;
+        flair::gui::DataPlot1D *plot;
+        float Sat(float value,float borne);
+};
+
+
+#endif // NESTEDSAT_IMPL_H
Index: trunk/lib/FlairFilter/src/unexported/PidThrust_impl.h
===================================================================
--- trunk/lib/FlairFilter/src/unexported/PidThrust_impl.h	(revision 7)
+++ trunk/lib/FlairFilter/src/unexported/PidThrust_impl.h	(revision 7)
@@ -0,0 +1,57 @@
+/*!
+ * \file PidThrust_impl.h
+ * \brief Classe permettant le calcul d'un Pid
+ * \author Guillaume Sanahuja, Copyright Heudiasyc UMR UTC/CNRS 7253
+ * \date 2014/11/07
+ * \version 4.0
+ */
+
+#ifndef PIDTHRUST_IMPL_H
+#define PIDTHRUST_IMPL_H
+
+#include <Object.h>
+
+namespace flair
+{
+    namespace core
+    {
+        class cvmatrix;
+        class io_data;
+    }
+    namespace gui
+    {
+        class LayoutPosition;
+        class DoubleSpinBox;
+    }
+    namespace filter
+    {
+        class PidThrust;
+    }
+}
+
+/*! \class PidThrust_impl
+* \brief Class defining a PID
+*/
+
+class PidThrust_impl
+{
+    public:
+        PidThrust_impl(flair::filter::PidThrust* self,const flair::gui::LayoutPosition* position,std::string name);
+        ~PidThrust_impl();
+        void UseDefaultPlot(const flair::gui::LayoutPosition* position);
+        void UpdateFrom(const flair::core::io_data *data);
+        float i,offset_g;
+        flair::gui::DoubleSpinBox *offset,*pas_offset;
+
+    private:
+        flair::filter::PidThrust* self;
+        flair::core::Time previous_time;
+        bool first_update;
+
+        //matrix
+        flair::core::cvmatrix *state;
+
+        flair::gui::DoubleSpinBox *T,*kp,*ki,*kd,*sat,*sati;
+};
+
+#endif // PIDTHRUST_IMPL_H
Index: trunk/lib/FlairFilter/src/unexported/Pid_impl.h
===================================================================
--- trunk/lib/FlairFilter/src/unexported/Pid_impl.h	(revision 7)
+++ trunk/lib/FlairFilter/src/unexported/Pid_impl.h	(revision 7)
@@ -0,0 +1,56 @@
+/*!
+ * \file Pid_impl.h
+ * \brief Classe permettant le calcul d'un Pid
+ * \author Guillaume Sanahuja, Copyright Heudiasyc UMR UTC/CNRS 7253
+ * \date 2011/05/01
+ * \version 4.0
+ */
+
+#ifndef PID_IMPL_H
+#define PID_IMPL_H
+
+#include <Object.h>
+
+namespace flair
+{
+    namespace core
+    {
+        class cvmatrix;
+        class io_data;
+    }
+    namespace gui
+    {
+        class LayoutPosition;
+        class DoubleSpinBox;
+    }
+    namespace filter
+    {
+        class Pid;
+    }
+}
+
+/*! \class Pid_impl
+* \brief Class defining a PID
+*/
+
+class Pid_impl
+{
+    public:
+        Pid_impl(flair::filter::Pid* self,const flair::gui::LayoutPosition* position,std::string name);
+        ~Pid_impl();
+        void UseDefaultPlot(const flair::gui::LayoutPosition* position);
+        void UpdateFrom(const flair::core::io_data *data);
+        float i;
+        bool first_update;
+
+    private:
+        flair::filter::Pid* self;
+        flair::core::Time previous_time;
+
+        //matrix
+        flair::core::cvmatrix *state;
+
+        flair::gui::DoubleSpinBox *T,*kp,*ki,*kd,*sat,*sati;
+};
+
+#endif // PID_IMPL_H
Index: trunk/lib/FlairFilter/src/unexported/TrajectoryGenerator1D_impl.h
===================================================================
--- trunk/lib/FlairFilter/src/unexported/TrajectoryGenerator1D_impl.h	(revision 7)
+++ trunk/lib/FlairFilter/src/unexported/TrajectoryGenerator1D_impl.h	(revision 7)
@@ -0,0 +1,50 @@
+/*!
+ * \file TrajectoryGenerator1D_impl.h
+ * \brief Class generating a trajectory in 1D
+ * \author Guillaume Sanahuja, Copyright Heudiasyc UMR UTC/CNRS 7253
+ * \date 2011/05/01
+ * \version 4.0
+ */
+
+#ifndef TRAJECTORYGENERATOR1D_IMPL_H
+#define TRAJECTORYGENERATOR1D_IMPL_H
+
+namespace flair
+{
+    namespace core
+    {
+        class cvmatrix;
+    }
+    namespace gui
+    {
+        class LayoutPosition;
+        class DoubleSpinBox;
+    }
+}
+
+/*! \class TrajectoryGenerator1D_impl
+* \brief Class generating a trajectory in 1D
+*/
+class TrajectoryGenerator1D_impl
+{
+
+    public:
+        TrajectoryGenerator1D_impl(flair::filter::TrajectoryGenerator1D* self,const flair::gui::LayoutPosition* position,std::string name,std::string unit);
+        ~TrajectoryGenerator1D_impl();
+        void Update(flair::core::Time time);
+        void StartTraj(float start_pos,float end_pos);
+        void StopTraj(void);
+        void Reset(void);
+        flair::core::cvmatrix *output;
+        float pos_off,vel_off;
+        bool is_finished,is_started;
+
+    private:
+        float end_position;
+        float pos,v,acc;
+        flair::core::Time previous_time;
+        bool first_update;
+        flair::gui::DoubleSpinBox *T,*max_veloctity,*acceleration;
+};
+
+#endif // TRAJECTORYGENERATOR1D_IMPL_H
Index: trunk/lib/FlairFilter/src/unexported/TrajectoryGenerator2DCircle_impl.h
===================================================================
--- trunk/lib/FlairFilter/src/unexported/TrajectoryGenerator2DCircle_impl.h	(revision 7)
+++ trunk/lib/FlairFilter/src/unexported/TrajectoryGenerator2DCircle_impl.h	(revision 7)
@@ -0,0 +1,61 @@
+/*!
+ * \file TrajectoryGenerator2DCircle_impl.h
+ * \brief Class generating a circle trajectory in 2D
+ * \author Guillaume Sanahuja, Copyright Heudiasyc UMR UTC/CNRS 7253
+ * \date 2013/04/08
+ * \version 4.0
+ */
+
+#ifndef TRAJECTORYGENERATOR2DCIRCLE_IMPL_H
+#define TRAJECTORYGENERATOR2DCIRCLE_IMPL_H
+
+#include <Object.h>
+#include <Vector2D.h>
+
+namespace flair
+{
+    namespace core
+    {
+        class cvmatrix;
+        class io_data;
+    }
+    namespace gui
+    {
+        class LayoutPosition;
+        class DoubleSpinBox;
+    }
+    namespace filter
+    {
+        class TrajectoryGenerator2DCircle;
+    }
+}
+
+
+/*! \class TrajectoryGenerator2DCircle_impl
+* \brief Class generating a circle trajectory in 2D
+*/
+
+class TrajectoryGenerator2DCircle_impl
+{
+
+    public:
+        TrajectoryGenerator2DCircle_impl(flair::filter::TrajectoryGenerator2DCircle* self,const flair::gui::LayoutPosition* position,std::string name);
+        ~TrajectoryGenerator2DCircle_impl();
+        void Update(flair::core::Time time);
+        void StartTraj(const flair::core::Vector2D &start_pos,float nb_lap);
+        void FinishTraj(void);
+        bool is_running;
+        flair::core::cvmatrix *output;
+        flair::core::Vector2D pos_off,vel_off;
+
+    private:
+        flair::core::Time previous_time;
+        float CurrentTime,FinishTime;
+        bool first_update,is_finishing;
+        flair::core::Vector2D pos;
+        float angle_off;
+        flair::gui::DoubleSpinBox *T,*veloctity,*acceleration,*rayon;
+        float nb_lap;
+};
+
+#endif // TRAJECTORYGENERATOR2DCIRCLE_IMPL_H
Index: trunk/lib/FlairFilter/src/unexported/UavMultiplex_impl.h
===================================================================
--- trunk/lib/FlairFilter/src/unexported/UavMultiplex_impl.h	(revision 7)
+++ trunk/lib/FlairFilter/src/unexported/UavMultiplex_impl.h	(revision 7)
@@ -0,0 +1,75 @@
+/*!
+ * \file UavMultiplex_impl.h
+ * \brief Class defining uav multiplexing
+ * \author Guillaume Sanahuja, Copyright Heudiasyc UMR UTC/CNRS 7253
+ * \date 2014/04/11
+ * \version 4.0
+ */
+
+#ifndef UAVMULTIPLEX_IMPL_H
+#define UAVMULTIPLEX_IMPL_H
+
+#include <stdint.h>
+#include <string>
+
+namespace flair
+{
+    namespace core
+    {
+        class FrameworkManager;
+        class cvmatrix;
+        class io_data;
+    }
+    namespace gui
+    {
+        class Tab;
+        class ComboBox;
+        class GroupBox;
+        class TabWidget;
+    }
+    namespace filter
+    {
+        class UavMultiplex;
+    }
+}
+
+
+/*! \class UavMultiplex_impl
+*
+* \brief Class defining uav multiplexing
+*/
+class UavMultiplex_impl
+{
+    public:
+
+        /*!
+        * \brief Constructor
+        *
+        * Construct a uav multiplexing
+        *
+        * \param parent parent
+        * \param name name
+        */
+        UavMultiplex_impl(const flair::core::FrameworkManager* parent,flair::filter::UavMultiplex* self,std::string name);
+
+        /*!
+        * \brief Destructor
+        *
+        */
+        ~UavMultiplex_impl();
+
+        flair::core::cvmatrix *input;
+        void SetMultiplexComboBox(std::string name,int index);
+        int MultiplexValue(int index) const;
+
+        flair::gui::TabWidget* tabwidget;
+        flair::gui::Tab *setup_tab;
+
+    private:
+        flair::gui::Tab *main_tab;
+        flair::gui::ComboBox **multiplexcombobox;
+        flair::gui::GroupBox *groupbox;
+        flair::filter::UavMultiplex* self;
+};
+
+#endif // UAVMULTIPLEX_IMPL_H
Index: trunk/lib/FlairFilter/src/unexported/X4X8Multiplex_impl.h
===================================================================
--- trunk/lib/FlairFilter/src/unexported/X4X8Multiplex_impl.h	(revision 7)
+++ trunk/lib/FlairFilter/src/unexported/X4X8Multiplex_impl.h	(revision 7)
@@ -0,0 +1,55 @@
+/*!
+ * \file X4X8Multiplex_impl.h
+ * \brief Class defining X4 and X8 multiplexing
+ * \author Guillaume Sanahuja, Copyright Heudiasyc UMR UTC/CNRS 7253
+ * \date 2014/04/10
+ * \version 4.0
+ */
+
+#ifndef X4X8MULTIPLEX_IMPL_H
+#define X4X8MULTIPLEX_IMPL_H
+
+#include <string>
+
+namespace flair
+{
+    namespace core
+    {
+        class cvmatrix;
+        class io_data;
+    }
+    namespace gui
+    {
+        class DataPlot1D;
+        class ComboBox;
+    }
+    namespace filter
+    {
+        class X4X8Multiplex;
+    }
+}
+
+
+/*! \class X4X8Multiplex_impl
+*
+* \brief Class defining X4 and X8 multiplexing
+*/
+class X4X8Multiplex_impl
+{
+    public:
+        X4X8Multiplex_impl(flair::filter::X4X8Multiplex* self,int nb_mot);
+        ~X4X8Multiplex_impl();
+        void UseDefaultPlot(void);
+        void UpdateFrom(const flair::core::io_data *data);
+        int nb_mot;
+        std::string MotorName(int index);
+
+    private:
+        flair::core::cvmatrix *output;
+        flair::gui::ComboBox *pas;
+        flair::gui::DataPlot1D *plots[4];
+        flair::filter::X4X8Multiplex* self;
+        float Set(float trim,float u);
+};
+
+#endif // X4X8MULTIPLEX_IMPL_H
Index: trunk/lib/FlairMeta/CMakeLists.txt
===================================================================
--- trunk/lib/FlairMeta/CMakeLists.txt	(revision 7)
+++ trunk/lib/FlairMeta/CMakeLists.txt	(revision 7)
@@ -0,0 +1,45 @@
+PROJECT(FlairMeta)
+cmake_minimum_required(VERSION 2.8)
+include($ENV{FLAIR_ROOT}/flair-dev/cmake-modules/GlobalCmakeFlair.cmake)
+
+find_package(LibXml2 REQUIRED)
+
+execute_process(COMMAND ${CMAKE_C_COMPILER} -dumpversion
+                OUTPUT_VARIABLE GCC_VERSION)
+
+if (GCC_VERSION VERSION_GREATER 4.3 OR GCC_VERSION VERSION_EQUAL 4.3)
+	if (GCC_VERSION VERSION_GREATER 4.7 OR GCC_VERSION VERSION_EQUAL 4.7)
+		ADD_DEFINITIONS("-std=c++11")
+	else()
+		ADD_DEFINITIONS("-std=c++0x")
+	endif()
+else()
+	message(STATUS "GCC version < 4.3, c+11 is not supported!")
+endif()
+
+INCLUDE_DIRECTORIES(
+	${LIBXML2_INCLUDE_DIR}
+	${CMAKE_CURRENT_SOURCE_DIR}/../FlairCore/src
+	${CMAKE_CURRENT_SOURCE_DIR}/../FlairSensorActuator/src
+	${CMAKE_CURRENT_SOURCE_DIR}/../FlairFilter/src
+	${CMAKE_CURRENT_SOURCE_DIR}/src/unexported
+	${CMAKE_CURRENT_SOURCE_DIR}/src/
+	${CMAKE_SYSROOT}/usr/include/opencv
+)
+
+FILE(GLOB SRC_FILES "${CMAKE_CURRENT_SOURCE_DIR}/src/*.cpp")
+
+ADD_LIBRARY(${PROJECT_NAME}
+	${SRC_FILES}
+)
+
+INSTALL(TARGETS ${PROJECT_NAME}
+	LIBRARY DESTINATION $ENV{FLAIR_ROOT}/flair-bin/lib/${ARCH_DIR}
+	ARCHIVE DESTINATION $ENV{FLAIR_ROOT}/flair-bin/lib/${ARCH_DIR}
+)
+
+#copie des entetes
+FILE(GLOB HEADER_FILES "${CMAKE_CURRENT_SOURCE_DIR}/src/*.h")
+INSTALL(FILES ${HEADER_FILES} DESTINATION $ENV{FLAIR_ROOT}/flair-dev/include/${PROJECT_NAME})
+
+SET(LIBRARY_OUTPUT_PATH ${PROJECT_BINARY_DIR}/bin)
Index: trunk/lib/FlairMeta/src/HdsX8.cpp
===================================================================
--- trunk/lib/FlairMeta/src/HdsX8.cpp	(revision 7)
+++ trunk/lib/FlairMeta/src/HdsX8.cpp	(revision 7)
@@ -0,0 +1,67 @@
+//  created:    2015/02/08
+//  filename:   HdsX8.cpp
+//
+//  author:     Guillaume Sanahuja
+//              Copyright Heudiasyc UMR UTC/CNRS 7253
+//
+//  version:    $Id: $
+//
+//  purpose:    Class defining an HDS X8 uav
+//
+//
+/*********************************************************************/
+
+#include "HdsX8.h"
+#include <FrameworkManager.h>
+#include <RTDM_I2cPort.h>
+#include <RTDM_SerialPort.h>
+#include <Srf08.h>
+#include <Gx3_25_ahrs.h>
+#include <BlCtrlV2.h>
+#include <X4X8Multiplex.h>
+#include <Ps3Eye.h>
+
+using std::string;
+using namespace flair::core;
+using namespace flair::sensor;
+using namespace flair::filter;
+using namespace flair::actuator;
+
+namespace flair { namespace meta {
+
+HdsX8::HdsX8(FrameworkManager* parent,string uav_name,filter::UavMultiplex *multiplex) : Uav(parent,uav_name,multiplex) {
+    RTDM_I2cPort* i2cport=new RTDM_I2cPort(parent,"rtdm_i2c","rti2c3");
+    RTDM_SerialPort* imu_port=new RTDM_SerialPort(parent,"imu_port","rtser1");
+
+    if(multiplex==NULL) SetMultiplex(new X4X8Multiplex(parent,"motors",X4X8Multiplex::X8));
+
+    SetBldc(new BlCtrlV2(GetUavMultiplex(),GetUavMultiplex()->GetLayout(),"motors",GetUavMultiplex()->MotorsCount(),i2cport));
+    SetUsRangeFinder(new Srf08(parent,"SRF08",i2cport,0x70,60));
+    SetAhrs(new Gx3_25_ahrs(parent,"imu",imu_port,Gx3_25_imu::EulerAnglesAndAngularRates,70));
+    SetBatteryMonitor(((BlCtrlV2*)GetBldc())->GetBatteryMonitor());
+
+/*
+        if(VRPNType==Auto || VRPNType==AutoSerialPort)
+        {
+            RTDM_SerialPort* vrpn_port=new RTDM_SerialPort(parent,"vrpn_port","rtser3");
+
+            vrpnclient=new VrpnClient(parent,"vrpn",vrpn_port,10000,80);
+            uav_vrpn=new MetaVrpnObject(vrpnclient,uav_name,VRPNSerialObjectId);
+        }
+*/
+    SetVerticalCamera(new Ps3Eye(parent,"camv",0,50));
+}
+
+HdsX8::~HdsX8() {
+
+}
+
+void HdsX8::StartSensors(void) {
+    ((Gx3_25_ahrs*)GetAhrs())->Start();
+    ((Srf08*)GetUsRangeFinder())->Start();
+    ((Ps3Eye *)GetVerticalCamera())->Start();
+    Uav::StartSensors();
+}
+
+} // end namespace meta
+} // end namespace flair
Index: trunk/lib/FlairMeta/src/HdsX8.h
===================================================================
--- trunk/lib/FlairMeta/src/HdsX8.h	(revision 7)
+++ trunk/lib/FlairMeta/src/HdsX8.h	(revision 7)
@@ -0,0 +1,33 @@
+/*!
+ * \file HdsX8.h
+ * \brief Class defining an ardrone2 uav
+ * \author Guillaume Sanahuja, Copyright Heudiasyc UMR UTC/CNRS 7253
+ * \date 2016/02/08
+ * \version 4.0
+ */
+
+#ifndef HDSX8_H
+#define HDSX8_H
+
+#include "Uav.h"
+
+namespace flair
+{
+namespace meta
+{
+    /*! \class HdsX8
+    *
+    * \brief Class defining an ardrone2 uav
+    */
+    class HdsX8 : public Uav {
+        public:
+            HdsX8(core::FrameworkManager* parent,std::string uav_name,filter::UavMultiplex *multiplex=NULL);
+            ~HdsX8();
+            void StartSensors(void);
+
+        private:
+
+    };
+} // end namespace meta
+} // end namespace flair
+#endif // HDSX8_H
Index: trunk/lib/FlairMeta/src/MetaDualShock3.cpp
===================================================================
--- trunk/lib/FlairMeta/src/MetaDualShock3.cpp	(revision 7)
+++ trunk/lib/FlairMeta/src/MetaDualShock3.cpp	(revision 7)
@@ -0,0 +1,95 @@
+//  created:    2014/01/14
+//  filename:   MetaDualShock3.cpp
+//
+//  author:     Guillaume Sanahuja
+//              Copyright Heudiasyc UMR UTC/CNRS 7253
+//
+//  version:    $Id: $
+//
+//  purpose:    objet integrant la manette DualShock3 et les consignes joystick
+//
+//
+/*********************************************************************/
+
+#include "MetaDualShock3.h"
+#include "MetaDualShock3_impl.h"
+#include "JoyReference.h"
+#include <Tab.h>
+#include <FrameworkManager.h>
+#include <cvmatrix.h>
+#include <Ahrs.h>
+#include <AhrsData.h>
+#include <DataPlot1D.h>
+
+using std::string;
+using namespace flair::core;
+using namespace flair::filter;
+using namespace flair::gui;
+
+namespace flair { namespace meta {
+
+MetaDualShock3::MetaDualShock3(FrameworkManager* parent,string name,uint16_t port,uint8_t priority) : TargetEthController(parent,name,port,priority) {
+    pimpl_=new MetaDualShock3_impl(this,name);
+    parent->AddDeviceToLog(pimpl_->joy_ref);
+    Start();
+}
+
+MetaDualShock3::~MetaDualShock3() {
+    delete pimpl_;
+}
+
+AhrsData* MetaDualShock3::GetReferenceOrientation(void) const {
+    return pimpl_->joy_ref->GetReferenceOrientation();
+}
+
+void MetaDualShock3::ErrorNotify(void) {
+    TargetEthController::FlashLed(4,10,0);
+    TargetEthController::Rumble(0xff,20,0,0);
+}
+
+void MetaDualShock3::Rumble(uint8_t left_force,uint8_t left_timeout,uint8_t right_force,uint8_t right_timeout) {
+    TargetEthController::Rumble(left_force,left_timeout,right_force,right_timeout);
+}
+
+void MetaDualShock3::SetLedON(unsigned int ledId) {
+    TargetEthController::SetLedOn(ledId);
+}
+
+void MetaDualShock3::SetLedOFF(unsigned int ledId) {
+    TargetEthController::SetLedOff(ledId);
+}
+
+void MetaDualShock3::FlashLed(unsigned int ledId,uint8_t on_timeout,uint8_t off_timeout) {
+    TargetEthController::FlashLed(ledId,on_timeout,off_timeout);
+}
+
+float MetaDualShock3::ZRef(void) const {
+    return pimpl_->joy_ref->ZRef();
+}
+
+float MetaDualShock3::DzRef(void) const {
+    return pimpl_->joy_ref->DzRef();
+}
+
+void MetaDualShock3::SetYawRef(float value) {
+    pimpl_->joy_ref->SetYawRef(value);
+}
+
+void MetaDualShock3::SetYawRef(Quaternion const &value) {
+    pimpl_->joy_ref->SetYawRef(value);
+}
+
+void MetaDualShock3::SetZRef(float value) {
+    pimpl_->joy_ref->SetZRef(value);
+}
+
+float MetaDualShock3::RollTrim(void) const {
+    return pimpl_->joy_ref->RollTrim();
+}
+
+float MetaDualShock3::PitchTrim(void) const {
+    return pimpl_->joy_ref->PitchTrim();
+}
+
+} // end namespace meta
+} // end namespace flair
Index: trunk/lib/FlairMeta/src/MetaDualShock3.h
===================================================================
--- trunk/lib/FlairMeta/src/MetaDualShock3.h	(revision 7)
+++ trunk/lib/FlairMeta/src/MetaDualShock3.h	(revision 7)
@@ -0,0 +1,67 @@
+/*!
+ * \file MetaDualShock3.h
+ * \brief Classe intégrant la manette DualShock3 et les consignes joystick
+ * \author Guillaume Sanahuja, Copyright Heudiasyc UMR UTC/CNRS 7253
+ * \date 2014/01/14
+ * \version 3.4
+ */
+
+#ifndef METADUALSHOCK3_H
+#define METADUALSHOCK3_H
+
+#include <TargetEthController.h>
+
+namespace flair {
+    namespace core {
+        class AhrsData;
+        class Quaternion;
+    }
+    namespace filter {
+        class Ahrs;
+    }
+}
+
+class MetaDualShock3_impl;
+
+namespace flair {
+namespace meta {
+
+    /*! \class MetaDualShock3
+    *
+    * \brief Classe intégrant la manette MetaDualShock3
+    */
+    class MetaDualShock3 : public sensor::TargetEthController {
+        friend class ::MetaDualShock3_impl;
+
+        public:
+            MetaDualShock3(core::FrameworkManager* parent,std::string name,uint16_t port,uint8_t priority);
+            ~MetaDualShock3();
+            core::AhrsData* GetReferenceOrientation(void) const;
+            float ZRef(void) const;
+            float DzRef(void) const;
+            void SetYawRef(float value);
+            /*!
+            * \brief Set yaw reference
+            *
+            * Yaw part of the output quaternion is obtained by integrating the wz desired angular speed.\n
+            * This method reset the yaw.
+            *
+            * \param value value, only the yaw part of the quaternion is used
+            */
+            void SetYawRef(core::Quaternion const &value);
+            void SetZRef(float value);
+            float RollTrim(void) const;
+            float PitchTrim(void) const;
+            void ErrorNotify(void);
+            void Rumble(uint8_t left_force,uint8_t left_timeout=20,uint8_t right_force=0,uint8_t right_timeout=0);
+            void SetLedON(unsigned int ledId);
+            void SetLedOFF(unsigned int ledId);
+            void FlashLed(unsigned int ledId,uint8_t on_timeout,uint8_t off_timeout);
+
+        private:
+            class MetaDualShock3_impl* pimpl_;
+
+    };
+} // end namespace meta
+} // end namespace flair
+#endif // METADUALSHOCK3_H
Index: trunk/lib/FlairMeta/src/MetaDualShock3_impl.cpp
===================================================================
--- trunk/lib/FlairMeta/src/MetaDualShock3_impl.cpp	(revision 7)
+++ trunk/lib/FlairMeta/src/MetaDualShock3_impl.cpp	(revision 7)
@@ -0,0 +1,109 @@
+//  created:    2014/01/14
+//  filename:   MetaDualShock3_impl.cpp
+//
+//  author:     Guillaume Sanahuja
+//              Copyright Heudiasyc UMR UTC/CNRS 7253
+//
+//  version:    $Id: $
+//
+//  purpose:    objet integrant la manette DualShock3 et les consignes joystick
+//
+//
+/*********************************************************************/
+
+#include "MetaDualShock3_impl.h"
+#include "MetaDualShock3.h"
+#include <JoyReference.h>
+#include <Tab.h>
+#include <cvmatrix.h>
+#include <FrameworkManager.h>
+
+using std::string;
+using namespace flair::core;
+using namespace flair::gui;
+using namespace flair::filter;
+using namespace flair::meta;
+
+MetaDualShock3_impl::MetaDualShock3_impl(MetaDualShock3* self,string name): IODevice((IODevice*)self,name) {
+    joy_ref=new JoyReference(self->GetTab()->NewRow(),"consignes joy");
+    this->self=self;
+    joy_init=false;
+    wasRollTrimUpButtonPressed=false;
+    wasRollTrimDownButtonPressed=false;
+    wasPitchTrimUpButtonPressed=false;
+    wasPitchTrimDownButtonPressed=false;
+}
+
+MetaDualShock3_impl::~MetaDualShock3_impl() {
+
+}
+
+//receives updates from the controler
+void MetaDualShock3_impl::UpdateFrom(const io_data *data) {
+    cvmatrix *input=(cvmatrix*)data;
+
+    //on prend une fois pour toute le mutex et on fait des accès directs
+    input->GetMutex();
+
+    //up
+    if(self->IsButtonPressed(12)) {
+        if(!wasPitchTrimDownButtonPressed) {
+            joy_ref->PitchTrimDown();
+            wasPitchTrimDownButtonPressed=true;
+        }
+    } else {
+        wasPitchTrimDownButtonPressed=false;
+    }
+
+    //down
+    if(self->IsButtonPressed(13)) {
+        if(!wasPitchTrimUpButtonPressed) {
+            joy_ref->PitchTrimUp();
+            wasPitchTrimUpButtonPressed=true;
+        }
+    } else {
+        wasPitchTrimUpButtonPressed=false;
+    }
+
+    //right
+    if(self->IsButtonPressed(15)) {
+        if(!wasRollTrimUpButtonPressed) {
+            joy_ref->RollTrimUp();
+            wasRollTrimUpButtonPressed=true;
+        }
+    } else {
+        wasRollTrimUpButtonPressed=false;
+    }
+
+    //left
+    if(self->IsButtonPressed(14)) {
+        if(!wasRollTrimDownButtonPressed) {
+            joy_ref->RollTrimDown();
+            wasRollTrimDownButtonPressed=true;
+        }
+    } else {
+        wasRollTrimDownButtonPressed=false;
+    }
+
+    if(!getFrameworkManager()->ConnectionLost()) {
+        input->GetMutex();
+        joy_ref->SetRollAxis(input->ValueNoMutex(0,0));
+        joy_ref->SetPitchAxis(input->ValueNoMutex(1,0));
+        joy_ref->SetYawAxis(input->ValueNoMutex(2,0));
+        joy_ref->SetAltitudeAxis(input->ValueNoMutex(3,0));
+        input->ReleaseMutex();
+    } else {
+        joy_ref->SetRollAxis(0);
+        joy_ref->SetPitchAxis(0);
+        joy_ref->SetYawAxis(0);
+        joy_ref->SetAltitudeAxis(0);
+    }
+    input->ReleaseMutex();
+
+    joy_ref->Update(data->DataTime());
+
+    if(!joy_init) {
+        self->TargetEthController::FlashLed(1,10,10);
+        joy_init=true;
+    }
+}
Index: trunk/lib/FlairMeta/src/MetaUsRangeFinder.cpp
===================================================================
--- trunk/lib/FlairMeta/src/MetaUsRangeFinder.cpp	(revision 7)
+++ trunk/lib/FlairMeta/src/MetaUsRangeFinder.cpp	(revision 7)
@@ -0,0 +1,75 @@
+//  created:    2013/04/08
+//  filename:   MetaUsRangeFinder.cpp
+//
+//  author:     Guillaume Sanahuja
+//              Copyright Heudiasyc UMR UTC/CNRS 7253
+//
+//  version:    $Id: $
+//
+//  purpose:    objet integrant une dérivée
+//              d'euler, un passe bas et un generateur de consigne
+//              -> adapté pour un capteur d'altitude
+//
+//
+/*********************************************************************/
+
+#include "MetaUsRangeFinder.h"
+#include "UsRangeFinder.h"
+#include <LowPassFilter.h>
+#include <ButterworthLowPass.h>
+#include <Layout.h>
+#include <DataPlot1D.h>
+#include <Tab.h>
+#include <EulerDerivative.h>
+#include <GroupBox.h>
+#include <cvmatrix.h>
+
+using std::string;
+using namespace flair::core;
+using namespace flair::gui;
+using namespace flair::filter;
+using namespace flair::sensor;
+
+namespace flair { namespace meta
+{
+
+MetaUsRangeFinder::MetaUsRangeFinder(UsRangeFinder* us): Object(us,us->ObjectName()) {
+    this->us=us;
+    pbas_z=new ButterworthLowPass(us,us->GetLayout()->NewRow(),"Passe bas",3);
+    vz_euler=new EulerDerivative(pbas_z,us->GetLayout()->NewRow(),"Vz");
+    pbas_vz=new ButterworthLowPass(vz_euler,us->GetLayout()->NewRow(),"Passe bas v",3);
+
+}
+
+MetaUsRangeFinder::~MetaUsRangeFinder() {
+
+}
+
+void MetaUsRangeFinder::UseDefaultPlot(void) {
+    us->UseDefaultPlot();
+
+    us->GetPlot()->AddCurve(pbas_z->Matrix()->Element(0),DataPlot::Blue);
+
+    vz_plot=new DataPlot1D(us->GetPlotTab()->LastRowLastCol(),"vz",-2,2);
+    vz_plot->AddCurve(vz_euler->Matrix()->Element(0));
+    vz_plot->AddCurve(pbas_vz->Matrix()->Element(0),DataPlot::Blue);
+}
+
+gui::DataPlot1D *MetaUsRangeFinder::GetZPlot() {
+    return us->GetPlot();
+}
+
+gui::DataPlot1D *MetaUsRangeFinder::GetVzPlot() {
+    return vz_plot;
+}
+
+float MetaUsRangeFinder::z(void) const {
+    return pbas_z->Output();
+}
+
+float MetaUsRangeFinder::Vz(void) const {
+    return pbas_vz->Output();
+}
+
+} // end namespace sensor
+} // end namespace framewor
Index: trunk/lib/FlairMeta/src/MetaUsRangeFinder.h
===================================================================
--- trunk/lib/FlairMeta/src/MetaUsRangeFinder.h	(revision 7)
+++ trunk/lib/FlairMeta/src/MetaUsRangeFinder.h	(revision 7)
@@ -0,0 +1,56 @@
+/*!
+ * \file MetaUsRangeFinder.h
+ * \brief Classe haut niveau pour capteur à ultra son
+ * \author Guillaume Sanahuja, Copyright Heudiasyc UMR UTC/CNRS 7253
+ * \date 2013/04/08
+ * \version 3.4
+ */
+
+#ifndef METAUSRANGEFINDER_H
+#define METAUSRANGEFINDER_H
+
+#include <Object.h>
+
+namespace flair {
+    namespace filter {
+        class ButterworthLowPass;
+        class EulerDerivative;
+    }
+    namespace sensor {
+        class UsRangeFinder;
+    }
+    namespace gui {
+        class DataPlot1D;
+    }
+}
+
+namespace flair
+{
+namespace meta
+{
+    /*! \class MetaUsRangeFinder
+    *
+    * \brief Classe haut niveau pour capteur à ultra son
+    *
+    * Contient une dérivée d'euler et un passe bas.
+    * Cette classe est adaptée pour un capteur d'altitude.
+    */
+    class MetaUsRangeFinder: public core::Object {
+        public:
+            MetaUsRangeFinder(sensor::UsRangeFinder* us);
+            ~MetaUsRangeFinder();
+            void UseDefaultPlot(void);
+            float z(void) const;
+            float Vz(void) const;
+            gui::DataPlot1D *GetZPlot();
+            gui::DataPlot1D *GetVzPlot();
+
+        private:
+            sensor::UsRangeFinder* us;
+            filter::ButterworthLowPass *pbas_z,*pbas_vz;
+            filter::EulerDerivative *vz_euler;
+            gui::DataPlot1D* vz_plot;
+    };
+} // end namespace meta
+} // end namespace flair
+#endif // METAUSRANGEFINDER_H
Index: trunk/lib/FlairMeta/src/MetaVrpnObject.cpp
===================================================================
--- trunk/lib/FlairMeta/src/MetaVrpnObject.cpp	(revision 7)
+++ trunk/lib/FlairMeta/src/MetaVrpnObject.cpp	(revision 7)
@@ -0,0 +1,112 @@
+//  created:    2013/04/08
+//  filename:   MetaVrpnObject.cpp
+//
+//  author:     Guillaume Sanahuja
+//              Copyright Heudiasyc UMR UTC/CNRS 7253
+//
+//  version:    $Id: $
+//
+//  purpose:    objet integrant objet vrpn et une dérivée
+//              d'euler
+//
+//
+/*********************************************************************/
+
+#include "MetaVrpnObject.h"
+#include "VrpnClient.h"
+#include <EulerDerivative.h>
+#include <LowPassFilter.h>
+#include <IODevice.h>
+#include <GridLayout.h>
+#include <DataPlot1D.h>
+#include <DataPlot2D.h>
+#include <Tab.h>
+#include <TabWidget.h>
+#include <cvmatrix.h>
+#include <Vector3D.h>
+
+using std::string;
+using namespace flair::core;
+using namespace flair::gui;
+using namespace flair::sensor;
+using namespace flair::filter;
+
+namespace flair { namespace meta {
+
+MetaVrpnObject::MetaVrpnObject(const VrpnClient *parent,string name): VrpnObject(parent,name,parent->GetTabWidget())
+{
+    ConstructorCommon(parent,name);
+}
+
+MetaVrpnObject::MetaVrpnObject(const VrpnClient *parent,std::string name,uint8_t id): VrpnObject(parent,name,id,parent->GetTabWidget())
+{
+    ConstructorCommon(parent,name);
+}
+
+void MetaVrpnObject::ConstructorCommon(const VrpnClient *parent,string name) {
+    cvmatrix_descriptor* desc=new cvmatrix_descriptor(6,1);
+    for(int i=0;i<6;i++) {
+        desc->SetElementName(i,0,Output()->Name(i,0));
+    }
+    cvmatrix* prev_value=new cvmatrix(this,desc,elementDataType,name);
+    for(int i=0;i<6;i++) {
+        prev_value->SetValue(i,0,0);
+    }
+
+    pbas=new LowPassFilter(this,parent->GetLayout()->NewRow(),name + " Passe bas",prev_value);
+
+    desc=new cvmatrix_descriptor(6,1);
+    for(int i=0;i<6;i++) {
+        desc->SetElementName(i,0,"d" + Output()->Name(i,0));
+    }
+    prev_value=new cvmatrix(this,desc,elementDataType,name);
+    for(int i=0;i<6;i++) {
+        prev_value->SetValue(i,0,0);
+    }
+
+    euler=new EulerDerivative(pbas,parent->GetLayout()->NewRow(),name + "_euler",prev_value);
+
+    vx_opti_plot=new DataPlot1D(GetPlotTab()->NewRow(),"vx",-3,3);
+    vx_opti_plot->AddCurve(euler->Matrix()->Element(3));
+    vy_opti_plot=new DataPlot1D(GetPlotTab()->LastRowLastCol(),"vy",-3,3);
+    vy_opti_plot->AddCurve(euler->Matrix()->Element(4));
+    vz_opti_plot=new DataPlot1D(GetPlotTab()->LastRowLastCol(),"vz",-2,2);
+    vz_opti_plot->AddCurve(euler->Matrix()->Element(5));
+
+    plot_tab=new Tab(parent->GetTabWidget(),"Mesures (xy) "+ name);
+    xy_plot=new DataPlot2D(plot_tab->NewRow(),"xy","y",-5,5,"x",-5,5);
+        xy_plot->AddCurve(Output()->Element(4,0),Output()->Element(3,0));
+}
+
+MetaVrpnObject::~MetaVrpnObject() {
+    delete plot_tab;
+}
+
+DataPlot1D* MetaVrpnObject::VxPlot(void) const
+{
+    return vx_opti_plot;
+}
+
+DataPlot1D* MetaVrpnObject::VyPlot(void) const
+{
+    return vy_opti_plot;
+}
+
+DataPlot1D* MetaVrpnObject::VzPlot(void) const
+{
+    return vz_opti_plot;
+}
+
+DataPlot2D* MetaVrpnObject::XyPlot(void) const {
+    return xy_plot;
+}
+
+void MetaVrpnObject::GetSpeed(Vector3D &speed) const
+{
+    speed.x=euler->Output(3,0);
+    speed.y=euler->Output(4,0);
+    speed.z=euler->Output(5,0);
+}
+
+} // end namespace sensor
+} // end namespace framewor
Index: trunk/lib/FlairMeta/src/MetaVrpnObject.h
===================================================================
--- trunk/lib/FlairMeta/src/MetaVrpnObject.h	(revision 7)
+++ trunk/lib/FlairMeta/src/MetaVrpnObject.h	(revision 7)
@@ -0,0 +1,73 @@
+/*!
+ * \file MetaVrpnObject.h
+ * \brief Classe haut niveau intégrant un objet VRPN
+ * \author Guillaume Sanahuja, Copyright Heudiasyc UMR UTC/CNRS 7253
+ * \date 2013/04/08
+ * \version 3.4
+ */
+
+#ifndef METAVRPNOBJECT_H
+#define METAVRPNOBJECT_H
+
+#include <VrpnObject.h>
+#include "io_data.h"
+
+namespace flair
+{
+    namespace core
+    {
+        class Vector3D;
+        class FloatType;
+    }
+    namespace gui
+    {
+        class DataPlot1D;
+        class DataPlot2D;
+        class Tab;
+    }
+    namespace filter
+    {
+        class EulerDerivative;
+        class LowPassFilter;
+    }
+    namespace sensor
+    {
+        class VrpnClient;
+    }
+}
+
+namespace flair
+{
+namespace meta
+{
+
+    /*! \class MetaVrpnObject
+    *
+    * \brief Classe haut niveau intégrant un objet VRPN
+    *
+    * Contient un objet VRPN et une dérivée, d'euler.
+    */
+    class MetaVrpnObject: public sensor::VrpnObject {
+        public:
+            MetaVrpnObject(const sensor::VrpnClient *parent,std::string name);
+            MetaVrpnObject(const sensor::VrpnClient *parent,std::string name,uint8_t id);
+            ~MetaVrpnObject();
+            gui::DataPlot1D* VxPlot(void) const;//1,0
+            gui::DataPlot1D* VyPlot(void) const;//1,1
+            gui::DataPlot1D* VzPlot(void) const;//1,2
+            gui::DataPlot2D* XyPlot(void) const;
+            void GetSpeed(core::Vector3D &speed) const;
+
+        private:
+            void ConstructorCommon(const sensor::VrpnClient *parent,std::string name);
+            filter::LowPassFilter *pbas;
+            filter::EulerDerivative *euler;
+            gui::DataPlot2D *xy_plot;
+            gui::DataPlot1D *vx_opti_plot,*vy_opti_plot,*vz_opti_plot;
+            gui::Tab* plot_tab;
+            core::FloatType elementDataType;
+
+    };
+} // end namespace meta
+} // end namespace flair
+#endif // METAVRPNOBJECT_H
Index: trunk/lib/FlairMeta/src/SimuX4.cpp
===================================================================
--- trunk/lib/FlairMeta/src/SimuX4.cpp	(revision 7)
+++ trunk/lib/FlairMeta/src/SimuX4.cpp	(revision 7)
@@ -0,0 +1,63 @@
+//  created:    2016/02/08
+//  filename:   SimuX4.cpp
+//
+//  author:     Guillaume Sanahuja
+//              Copyright Heudiasyc UMR UTC/CNRS 7253
+//
+//  version:    $Id: $
+//
+//  purpose:    Class defining a simultation x4 uav
+//
+//
+/*********************************************************************/
+
+#include "SimuX4.h"
+#include <FrameworkManager.h>
+#include <X4X8Multiplex.h>
+#include <SimuImu.h>
+#include <SimuAhrs.h>
+#include <SimuBldc.h>
+#include <SimuUs.h>
+#include <SimuCamera.h>
+#include <BatteryMonitor.h>
+#include <Tab.h>
+
+using std::string;
+using namespace flair::core;
+using namespace flair::gui;
+using namespace flair::sensor;
+using namespace flair::filter;
+using namespace flair::actuator;
+
+namespace flair { namespace meta {
+
+SimuX4::SimuX4(FrameworkManager* parent,string uav_name,int simu_id,filter::UavMultiplex *multiplex) : Uav(parent,uav_name,multiplex) {
+
+    if(multiplex==NULL) SetMultiplex(new X4X8Multiplex(parent,"motors",X4X8Multiplex::X4));
+
+    SetBldc(new SimuBldc(GetUavMultiplex(),GetUavMultiplex()->GetLayout(),"motors",GetUavMultiplex()->MotorsCount(),simu_id));
+    SetUsRangeFinder(new SimuUs(parent,"us",simu_id,60));
+    SetAhrs(new SimuAhrs(parent,"imu",simu_id,70));
+    Tab* bat_tab=new Tab(parent->GetTabWidget(),"battery");
+    SetBatteryMonitor(new BatteryMonitor(bat_tab->NewRow(),"battery"));
+    GetBatteryMonitor()->SetBatteryValue(12);
+    SetVerticalCamera(new SimuCamera(parent, "simu_cam_v", 320, 240, 3, simu_id, 10));
+}
+
+SimuX4::~SimuX4() {
+
+}
+
+void SimuX4::StartSensors(void) {
+    ((SimuAhrs*)GetAhrs())->Start();
+    ((SimuUs*)GetUsRangeFinder())->Start();
+    ((SimuCamera *)GetVerticalCamera())->Start();
+    Uav::StartSensors();
+}
+
+void SimuX4::SetupVRPNAutoIP(string name) {
+    SetupVRPN("127.0.0.1:3883",name);
+}
+
+} // end namespace meta
+} // end namespace flair
Index: trunk/lib/FlairMeta/src/SimuX4.h
===================================================================
--- trunk/lib/FlairMeta/src/SimuX4.h	(revision 7)
+++ trunk/lib/FlairMeta/src/SimuX4.h	(revision 7)
@@ -0,0 +1,33 @@
+/*!
+ * \file SimuX4.h
+ * \brief Class defining a simultation x4 uav
+ * \author Guillaume Sanahuja, Copyright Heudiasyc UMR UTC/CNRS 7253
+ * \date 2016/02/08
+ * \version 4.0
+ */
+
+#ifndef SIMUX4_H
+#define SIMUX4_H
+
+#include "Uav.h"
+
+namespace flair
+{
+namespace meta
+{
+    /*! \class SimuX4
+    *
+    * \brief Class defining a simultation x4 uav
+    */
+    class SimuX4 : public Uav {
+        public:
+            //simu_id: 0 if simulating only one UAV
+            //>0 otherwise
+            SimuX4(core::FrameworkManager* parent,std::string uav_name,int simu_id=0,filter::UavMultiplex *multiplex=NULL);
+            ~SimuX4();
+            void StartSensors(void);
+            void SetupVRPNAutoIP(std::string name);
+    };
+} // end namespace meta
+} // end namespace flair
+#endif // SIMUX4_H
Index: trunk/lib/FlairMeta/src/SimuX8.cpp
===================================================================
--- trunk/lib/FlairMeta/src/SimuX8.cpp	(revision 7)
+++ trunk/lib/FlairMeta/src/SimuX8.cpp	(revision 7)
@@ -0,0 +1,63 @@
+//  created:    2016/02/08
+//  filename:   SimuX8.cpp
+//
+//  author:     Guillaume Sanahuja
+//              Copyright Heudiasyc UMR UTC/CNRS 7253
+//
+//  version:    $Id: $
+//
+//  purpose:    Class defining a simultation x4 uav
+//
+//
+/*********************************************************************/
+
+#include "SimuX8.h"
+#include <FrameworkManager.h>
+#include <X4X8Multiplex.h>
+#include <SimuImu.h>
+#include <SimuAhrs.h>
+#include <SimuBldc.h>
+#include <SimuUs.h>
+#include <SimuCamera.h>
+#include <BatteryMonitor.h>
+#include <Tab.h>
+
+using std::string;
+using namespace flair::core;
+using namespace flair::gui;
+using namespace flair::sensor;
+using namespace flair::filter;
+using namespace flair::actuator;
+
+namespace flair { namespace meta {
+
+SimuX8::SimuX8(FrameworkManager* parent,string uav_name,int simu_id,filter::UavMultiplex *multiplex) : Uav(parent,uav_name,multiplex) {
+
+    if(multiplex==NULL) SetMultiplex(new X4X8Multiplex(parent,"motors",X4X8Multiplex::X8));
+
+    SetBldc(new SimuBldc(GetUavMultiplex(),GetUavMultiplex()->GetLayout(),"motors",GetUavMultiplex()->MotorsCount(),simu_id));
+    SetUsRangeFinder(new SimuUs(parent,"us",simu_id,60));
+    SetAhrs(new SimuAhrs(parent,"imu",simu_id,70));
+    Tab* bat_tab=new Tab(parent->GetTabWidget(),"battery");
+    SetBatteryMonitor(new BatteryMonitor(bat_tab->NewRow(),"battery"));
+    GetBatteryMonitor()->SetBatteryValue(12);
+    SetVerticalCamera(new SimuCamera(parent, "simu_cam_v", 320, 240, 3, simu_id, 10));
+}
+
+SimuX8::~SimuX8() {
+
+}
+
+void SimuX8::StartSensors(void) {
+    ((SimuAhrs*)GetAhrs())->Start();
+    ((SimuUs*)GetUsRangeFinder())->Start();
+    ((SimuCamera *)GetVerticalCamera())->Start();
+    Uav::StartSensors();
+}
+
+void SimuX8::SetupVRPNAutoIP(string name) {
+    SetupVRPN("127.0.0.1:3883",name);
+}
+
+} // end namespace meta
+} // end namespace flair
Index: trunk/lib/FlairMeta/src/SimuX8.h
===================================================================
--- trunk/lib/FlairMeta/src/SimuX8.h	(revision 7)
+++ trunk/lib/FlairMeta/src/SimuX8.h	(revision 7)
@@ -0,0 +1,33 @@
+/*!
+ * \file SimuX8.h
+ * \brief Class defining a simultation x8 uav
+ * \author Guillaume Sanahuja, Copyright Heudiasyc UMR UTC/CNRS 7253
+ * \date 2016/02/08
+ * \version 4.0
+ */
+
+#ifndef SIMUX8_H
+#define SIMUX8_H
+
+#include "Uav.h"
+
+namespace flair
+{
+namespace meta
+{
+    /*! \class SimuX8
+    *
+    * \brief Class defining a simultation x8 uav
+    */
+    class SimuX8 : public Uav {
+        public:
+            //simu_id: 0 if simulating only one UAV
+            //>0 otherwise
+            SimuX8(core::FrameworkManager* parent,std::string uav_name,int simu_id=0,filter::UavMultiplex *multiplex=NULL);
+            ~SimuX8();
+            void StartSensors(void);
+            void SetupVRPNAutoIP(std::string name);
+    };
+} // end namespace meta
+} // end namespace flair
+#endif // SIMUX8_H
Index: trunk/lib/FlairMeta/src/Uav.cpp
===================================================================
--- trunk/lib/FlairMeta/src/Uav.cpp	(revision 7)
+++ trunk/lib/FlairMeta/src/Uav.cpp	(revision 7)
@@ -0,0 +1,185 @@
+//  created:    2014/06/10
+//  filename:   Uav.cpp
+//
+//  author:     Guillaume Sanahuja
+//              Copyright Heudiasyc UMR UTC/CNRS 7253
+//
+//  version:    $Id: $
+//
+//  purpose:    Base class to construct sensors/actuators depending on uav type
+//
+//
+/*********************************************************************/
+
+#include "Uav.h"
+#include <FrameworkManager.h>
+#include <Tab.h>
+#include <GridLayout.h>
+#include <DataPlot1D.h>
+#include <VrpnClient.h>
+#include <Ahrs.h>
+#include <Imu.h>
+#include <UavMultiplex.h>
+#include <UsRangeFinder.h>
+#include <Bldc.h>
+#include <cvmatrix.h>
+#include "MetaUsRangeFinder.h"
+#include "MetaVrpnObject.h"
+
+using std::string;
+using namespace flair::core;
+using namespace flair::gui;
+using namespace flair::filter;
+using namespace flair::sensor;
+using namespace flair::actuator;
+
+namespace flair { namespace meta {
+
+Uav::Uav(FrameworkManager* parent,string name,UavMultiplex *multiplex): Object(parent,name) {
+    vrpnclient=NULL;
+    uav_vrpn=NULL;
+    verticalCamera=NULL;
+    this->multiplex=multiplex;
+}
+
+Uav::~Uav() {
+}
+
+void Uav::SetUsRangeFinder(const UsRangeFinder *inUs) {
+    us=(UsRangeFinder*)inUs;
+    meta_us=new MetaUsRangeFinder(us);
+    getFrameworkManager()->AddDeviceToLog(us);
+}
+
+void Uav::SetAhrs(const Ahrs *inAhrs) {
+    ahrs=(Ahrs*)inAhrs;
+    imu=(Imu*)ahrs->GetImu();
+    getFrameworkManager()->AddDeviceToLog(imu);
+}
+
+void Uav::SetBldc(const Bldc* inBldc) {
+    bldc=(Bldc*)inBldc;
+}
+
+void Uav::SetBatteryMonitor(const BatteryMonitor* inBattery) {
+    battery=(BatteryMonitor*)inBattery;
+}
+
+void Uav::SetMultiplex(const UavMultiplex *inMultiplex) {
+    multiplex=(UavMultiplex*)inMultiplex;
+    getFrameworkManager()->AddDeviceToLog(multiplex);
+}
+
+void Uav::SetVerticalCamera(const Camera* inVerticalCamera) {
+    verticalCamera=(Camera*)inVerticalCamera;
+}
+/*
+void Uav::SetupVRPNSerial(SerialPort *vrpn_port,string name,int VRPNSerialObjectId) {
+    vrpnclient=new VrpnClient(getFrameworkManager(),"vrpn",vrpn_port,10000,80);
+    uav_vrpn=new MetaVrpnObject(vrpnclient,name,VRPNSerialObjectId);
+
+    getFrameworkManager()->AddDeviceToLog(uav_vrpn);
+}
+*/
+void Uav::SetupVRPNAutoIP(string name) {
+    SetupVRPN("192.168.147.197:3883",name);
+}
+
+void Uav::SetupVRPN(string optitrack_address,string name) {
+    vrpnclient=new VrpnClient(getFrameworkManager(),"vrpn",optitrack_address,10000,80);
+    uav_vrpn=new MetaVrpnObject(vrpnclient,name);
+
+    getFrameworkManager()->AddDeviceToLog(uav_vrpn);
+
+    GetAhrs()->YawPlot()->AddCurve(uav_vrpn->State()->Element(2),DataPlot::Green);
+    //GetAhrs()->RollPlot()->AddCurve(uav_vrpn->State()->Element(0),DataPlot::Green);
+    //GetAhrs()->PitchPlot()->AddCurve(uav_vrpn->State()->Element(1),DataPlot::Green);
+}
+
+void Uav::StartSensors(void)  {
+    if(vrpnclient!=NULL) {
+        vrpnclient->Start();
+    }
+}
+void Uav::UseDefaultPlot(void) {
+    multiplex->UseDefaultPlot();
+
+    if(bldc->HasSpeedMeasurement()) {
+        Tab* plot_tab=new Tab(multiplex->GetTabWidget(),"Speeds");
+        DataPlot1D* plots[4];
+        plots[0]=new DataPlot1D(plot_tab->NewRow(),"front left",0,7000);
+        plots[1]=new DataPlot1D(plot_tab->LastRowLastCol(),"front right",0,7000);
+        plots[2]=new DataPlot1D(plot_tab->NewRow(),"rear left",0,7000);
+        plots[3]=new DataPlot1D(plot_tab->LastRowLastCol(),"rear right",0,7000);
+
+        if(bldc->MotorsCount()==8) {
+            for(int i=0;i<4;i++) plots[i]->AddCurve(bldc->Output()->Element(multiplex->MultiplexValue(i),0),DataPlot::Red,"top");
+            for(int i=0;i<4;i++) plots[i]->AddCurve(bldc->Output()->Element(multiplex->MultiplexValue(i+4),0),DataPlot::Blue,"bottom");
+        } else {
+            for(int i=0;i<4;i++) plots[i]->AddCurve(bldc->Output()->Element(multiplex->MultiplexValue(i),0));
+        }
+    }
+
+    if(bldc->HasCurrentMeasurement()) {
+        Tab* plot_tab=new Tab(multiplex->GetTabWidget(),"Currents");
+        DataPlot1D* plots[4];
+        plots[0]=new DataPlot1D(plot_tab->NewRow(),"front left",0,10);
+        plots[1]=new DataPlot1D(plot_tab->LastRowLastCol(),"front right",0,10);
+        plots[2]=new DataPlot1D(plot_tab->NewRow(),"rear left",0,10);
+        plots[3]=new DataPlot1D(plot_tab->LastRowLastCol(),"rear right",0,10);
+
+        if(bldc->MotorsCount()==8) {
+            for(int i=0;i<4;i++) plots[i]->AddCurve(bldc->Output()->Element(multiplex->MultiplexValue(i),1),DataPlot::Red,"top");
+            for(int i=0;i<4;i++) plots[i]->AddCurve(bldc->Output()->Element(multiplex->MultiplexValue(i+4),1),DataPlot::Blue,"bottom");
+        } else {
+            for(int i=0;i<4;i++) plots[i]->AddCurve(bldc->Output()->Element(multiplex->MultiplexValue(i),1));
+        }
+    }
+
+    meta_us->UseDefaultPlot();
+    ahrs->UseDefaultPlot();
+}
+
+UavMultiplex* Uav::GetUavMultiplex(void) const {
+    return multiplex;
+}
+
+Bldc* Uav::GetBldc(void) const {
+    return bldc;
+}
+
+Ahrs* Uav::GetAhrs(void) const {
+    return ahrs;
+}
+
+Imu* Uav::GetImu(void) const {
+    return imu;
+}
+
+MetaUsRangeFinder* Uav::GetMetaUsRangeFinder(void) const {
+    return meta_us;
+}
+
+UsRangeFinder* Uav::GetUsRangeFinder(void) const {
+    return us;
+}
+
+BatteryMonitor* Uav::GetBatteryMonitor(void) const {
+    return battery;
+}
+
+VrpnClient* Uav::GetVrpnClient(void) const {
+    if(vrpnclient==NULL) Err("vrpn is not setup, call SetupVRPN before\n");
+    return vrpnclient;
+}
+
+MetaVrpnObject* Uav::GetVrpnObject(void) const {
+    return uav_vrpn;
+}
+
+Camera* Uav::GetVerticalCamera(void) const {
+    return verticalCamera;
+}
+
+} // end namespace meta
+} // end namespace flair
Index: trunk/lib/FlairMeta/src/Uav.h
===================================================================
--- trunk/lib/FlairMeta/src/Uav.h	(revision 7)
+++ trunk/lib/FlairMeta/src/Uav.h	(revision 7)
@@ -0,0 +1,97 @@
+/*!
+ * \file Uav.h
+ * \brief Base class to construct sensors/actuators depending on uav type
+ * \author Guillaume Sanahuja, Copyright Heudiasyc UMR UTC/CNRS 7253
+ * \date 2014/01/22
+ * \version 3.4
+ */
+
+#ifndef HDSUAV_H
+#define HDSUAV_H
+
+#include <Object.h>
+
+namespace flair {
+    namespace core {
+        class FrameworkManager;
+    }
+    namespace filter {
+        class Ahrs;
+        class UavMultiplex;
+    }
+    namespace actuator {
+        class Bldc;
+    }
+    namespace sensor {
+        class UsRangeFinder;
+        class BatteryMonitor;
+        class VrpnClient;
+        class Imu;
+        class Camera;
+    }
+}
+
+namespace flair {
+namespace meta {
+    class MetaUsRangeFinder;
+    class MetaVrpnObject;
+
+    /*! \class Uav
+    *
+    * \brief Base class to construct sensors/actuators depending on uav type
+    */
+    class Uav: public core::Object {
+        public:
+        /*
+            typedef enum {
+                None,
+                Auto,//rt serial if hds x4 ou x8, auto ip sinon
+                AutoIP,
+                UserDefinedIP,
+                AutoSerialPort,
+                } VRPNType_t;
+*/
+            //uav_name: for optitrack
+            Uav(core::FrameworkManager* parent,std::string name,filter::UavMultiplex *multiplex=NULL);
+            ~Uav();
+            void SetupVRPN(std::string optitrack_address,std::string name);
+            //vrpn serial: broken, need to add serial port in uav specific code
+            //void SetupVRPNSerial(core::SerialPort *vrpn_port,std::string name,int VRPNSerialObjectId);
+            virtual void SetupVRPNAutoIP(std::string name);
+
+            virtual void StartSensors(void);
+            void UseDefaultPlot(void);
+            actuator::Bldc* GetBldc(void) const;
+            filter::UavMultiplex* GetUavMultiplex(void) const;
+            sensor::Imu* GetImu(void) const;
+            filter::Ahrs* GetAhrs(void) const;
+            MetaUsRangeFinder* GetMetaUsRangeFinder(void) const;
+            sensor::UsRangeFinder* GetUsRangeFinder(void) const;
+            sensor::BatteryMonitor* GetBatteryMonitor(void) const;
+            sensor::VrpnClient* GetVrpnClient(void) const;
+            meta::MetaVrpnObject* GetVrpnObject(void) const;
+            sensor::Camera* GetVerticalCamera(void) const;
+
+        protected:
+            void SetBldc(const actuator::Bldc *bldc);
+            void SetMultiplex(const filter::UavMultiplex *multiplex);
+            void SetAhrs(const filter::Ahrs *ahrs);
+            void SetUsRangeFinder(const sensor::UsRangeFinder *us);
+            void SetBatteryMonitor(const sensor::BatteryMonitor *battery);
+            void SetVerticalCamera(const sensor::Camera *verticalCamera);
+
+        private:
+            sensor::Imu* imu;
+            filter::Ahrs* ahrs;
+            actuator::Bldc* bldc;
+            filter::UavMultiplex *multiplex;
+            sensor::UsRangeFinder* us;
+            MetaUsRangeFinder* meta_us;
+            sensor::VrpnClient *vrpnclient;
+            MetaVrpnObject* uav_vrpn;
+            sensor::BatteryMonitor* battery;
+            sensor::Camera* verticalCamera;
+    };
+} // end namespace meta
+} // end namespace flair
+#endif // HDSUAV_H
Index: trunk/lib/FlairMeta/src/UavFactory.cpp
===================================================================
--- trunk/lib/FlairMeta/src/UavFactory.cpp	(revision 7)
+++ trunk/lib/FlairMeta/src/UavFactory.cpp	(revision 7)
@@ -0,0 +1,56 @@
+//  created:    2016/02/05
+//  filename:   UavFactory.cpp
+//
+//  author:     Guillaume Sanahuja
+//              Copyright Heudiasyc UMR UTC/CNRS 7253
+//
+//  version:    $Id: $
+//
+//  purpose:   construct a Uav based on the type name
+//
+//
+/*********************************************************************/
+
+#include "UavFactory.h"
+#include "FrameworkManager.h"
+//#include "ArDrone2.h"
+#include "SimuX4.h"
+#include "SimuX8.h"
+#include "HdsX8.h"
+#include "XAir.h"
+
+using namespace std;
+using namespace flair::core;
+using namespace flair::filter;
+using namespace flair::meta;
+
+Uav* CreateUav(FrameworkManager* parent,string uav_name,string uav_type,UavMultiplex *multiplex) {
+    /*if(uav_type=="ardrone2") {
+        return new ArDrone2(parent,uav_name,multiplex);
+    } else */if(uav_type=="hds_x4") {
+        parent->Err("UAV type %s not yet implemented\n",uav_type.c_str());
+        return NULL;
+    } else if(uav_type=="hds_x8") {
+        return new HdsX8(parent,uav_name,multiplex);
+    } else if(uav_type=="xair") {
+        return new XAir(parent,uav_name,multiplex);
+    } else if(uav_type=="hds_xufo") {
+        parent->Err("UAV type %s not yet implemented\n",uav_type.c_str());
+        return NULL;
+    } else if(uav_type.compare(0,7,"x4_simu")==0) {
+        int simu_id=0;
+        if(uav_type.size()>7) {
+            simu_id=atoi(uav_type.substr (7,uav_type.size()-7).c_str());
+        }
+        return new SimuX4(parent,uav_name,simu_id,multiplex);
+    } else if(uav_type.compare(0,7,"x8_simu") == 0) {
+        int simu_id=0;
+        if(uav_type.size()>7) {
+            simu_id=atoi(uav_type.substr (7,uav_type.size()-7).c_str());
+        }
+        return new SimuX8(parent,uav_name,simu_id,multiplex);
+    } else {
+        parent->Err("UAV type %s unknown\n",uav_type.c_str());
+        return NULL;
+    }
+}
Index: trunk/lib/FlairMeta/src/UavFactory.h
===================================================================
--- trunk/lib/FlairMeta/src/UavFactory.h	(revision 7)
+++ trunk/lib/FlairMeta/src/UavFactory.h	(revision 7)
@@ -0,0 +1,21 @@
+//  created:    2016/02/05
+//  filename:   UavFactory.cpp
+//
+//  author:     Guillaume Sanahuja
+//              Copyright Heudiasyc UMR UTC/CNRS 7253
+//
+//  version:    $Id: $
+//
+//  purpose:   construct a Uav based on the type name
+//
+//
+/*********************************************************************/
+
+#ifndef UAVFACTORY
+#define UAVFACTORY
+
+#include <Uav.h>
+
+flair::meta::Uav* CreateUav(flair::core::FrameworkManager* parent,std::string uav_name,std::string uav_type,flair::filter::UavMultiplex *multiplex=NULL);
+
+#endif // UAVFACTORY
Index: trunk/lib/FlairMeta/src/UavStateMachine.cpp
===================================================================
--- trunk/lib/FlairMeta/src/UavStateMachine.cpp	(revision 7)
+++ trunk/lib/FlairMeta/src/UavStateMachine.cpp	(revision 7)
@@ -0,0 +1,644 @@
+//  created:    2014/04/29
+//  filename:   UavStateMachine.cpp
+//
+//  author:     Gildas Bayard, Guillaume Sanahuja
+//              Copyright Heudiasyc UMR UTC/CNRS 7253
+//
+//  version:    $Id: $
+//
+//  purpose:    meta class for UAV
+//
+//
+/*********************************************************************/
+
+#include "UavStateMachine.h"
+#include "Uav.h"
+#include <DataPlot1D.h>
+#include <GridLayout.h>
+#include <Tab.h>
+#include <TabWidget.h>
+#include <PushButton.h>
+#include <SpinBox.h>
+#include <DoubleSpinBox.h>
+#include <X4X8Multiplex.h>
+#include <Bldc.h>
+#include <Ahrs.h>
+#include <MetaUsRangeFinder.h>
+#include <ControlLaw.h>
+#include <Pid.h>
+#include <PidThrust.h>
+#include <NestedSat.h>
+#include <MetaDualShock3.h>
+#include <AhrsData.h>
+#include <BatteryMonitor.h>
+#include <FrameworkManager.h>
+#include <Vector3D.h>
+#include <Vector2D.h>
+#include <cvmatrix.h>
+#include <stdio.h>
+#include <TrajectoryGenerator1D.h>
+
+using namespace std;
+using namespace flair::core;
+using namespace flair::gui;
+using namespace flair::sensor;
+using namespace flair::actuator;
+using namespace flair::filter;
+using namespace flair::meta;
+
+UavStateMachine::UavStateMachine(Uav* inUav,uint16_t ds3Port):
+        Thread(getFrameworkManager(),"UavStateMachine",50),
+        uav(inUav),failSafeMode(true),flagConnectionLost(false),flagBatteryLow(false),flagZTrajectoryFinished(false) {
+    altitudeState=AltitudeState_t::Stopped;
+    uav->UseDefaultPlot();
+
+    Tab *uavTab=new Tab(getFrameworkManager()->GetTabWidget(),"uav",0);
+    buttonslayout=new GridLayout(uavTab->NewRow(),"buttons");
+    button_kill=new PushButton(buttonslayout->NewRow(),"kill");
+    button_start_log=new PushButton(buttonslayout->NewRow(),"start_log");
+    button_stop_log=new PushButton(buttonslayout->LastRowLastCol(),"stop_log");
+    button_take_off=new PushButton(buttonslayout->NewRow(),"take_off");
+    button_land=new PushButton(buttonslayout->LastRowLastCol(),"land");
+
+    Tab *lawTab=new Tab(getFrameworkManager()->GetTabWidget(),"control laws");
+    TabWidget *tabWidget=new TabWidget(lawTab->NewRow(),"laws");
+    setupLawTab=new Tab(tabWidget,"Setup");
+    graphLawTab=new Tab(tabWidget,"Graphes");
+
+    uRoll=new NestedSat(setupLawTab->At(0,0),"u_roll");
+    uRoll->ConvertSatFromDegToRad();
+    uRoll->UseDefaultPlot(graphLawTab->NewRow());
+
+    uPitch=new NestedSat(setupLawTab->At(0,1),"u_pitch");
+    uPitch->ConvertSatFromDegToRad();
+    uPitch->UseDefaultPlot(graphLawTab->LastRowLastCol());
+
+    uYaw=new Pid(setupLawTab->At(0,2),"u_yaw");
+    uYaw->UseDefaultPlot(graphLawTab->LastRowLastCol());
+
+    uZ=new PidThrust(setupLawTab->At(1,2),"u_z");
+    uZ->UseDefaultPlot(graphLawTab->LastRowLastCol());
+
+    getFrameworkManager()->AddDeviceToLog(uZ);
+    uZ->AddDeviceToLog(uRoll);
+    uZ->AddDeviceToLog(uPitch);
+    uZ->AddDeviceToLog(uYaw);
+
+    joy=new MetaDualShock3(getFrameworkManager(),"dualshock3",ds3Port,30);
+    uav->GetAhrs()->AddPlot(joy->GetReferenceOrientation(),DataPlot::Blue);
+
+    altitudeMode=AltitudeMode_t::Manual;
+    orientationMode=OrientationMode_t::Manual;
+    thrustMode=ThrustMode_t::Default;
+    torqueMode=TorqueMode_t::Default;
+
+    GroupBox* reglagesGroupbox=new GroupBox(uavTab->NewRow(),"takeoff/landing");
+    desiredTakeoffAltitude=new DoubleSpinBox(reglagesGroupbox->NewRow(),"desired takeoff altitude"," m",0,5,0.1,2,1);
+    desiredLandingAltitude=new DoubleSpinBox(reglagesGroupbox->LastRowLastCol(),"desired landing altitude"," m",0,1,0.1,1);
+    altitudeTrajectory=new TrajectoryGenerator1D(uavTab->NewRow(),"alt cons","m");
+    uav->GetMetaUsRangeFinder()->GetZPlot()->AddCurve(altitudeTrajectory->Matrix()->Element(0),DataPlot::Green);
+    uav->GetMetaUsRangeFinder()->GetVzPlot()->AddCurve(altitudeTrajectory->Matrix()->Element(1),DataPlot::Green);
+}
+
+UavStateMachine::~UavStateMachine() {
+}
+
+void UavStateMachine::AddDeviceToControlLawLog(const IODevice* device) {
+    uZ->AddDeviceToLog(device);
+}
+
+void UavStateMachine::AddDataToControlLawLog(const core::io_data* data) {
+    uZ->AddDataToLog(data);
+}
+
+const TargetController *UavStateMachine::GetJoystick(void) const {
+    return joy;
+}
+
+const Quaternion &UavStateMachine::GetCurrentQuaternion(void) const {
+            return currentQuaternion;
+}
+
+const Vector3D &UavStateMachine::GetCurrentAngularSpeed(void) const {
+    return currentAngularSpeed;
+}
+
+const Uav *UavStateMachine::GetUav(void) const {
+    return uav;
+}
+
+void UavStateMachine::AltitudeValues(float &altitude,float &verticalSpeed) const{
+    FailSafeAltitudeValues(altitude, verticalSpeed);
+}
+
+void UavStateMachine::FailSafeAltitudeValues(float &altitude,float &verticalSpeed) const {
+    altitude=uav->GetMetaUsRangeFinder()->z();
+    verticalSpeed=uav->GetMetaUsRangeFinder()->Vz();
+}
+
+void UavStateMachine::Run() {
+    WarnUponSwitches(true);
+    uav->StartSensors();
+
+    if(getFrameworkManager()->ErrorOccured()==true) {
+        SafeStop();
+    }
+
+    while(!ToBeStopped()) {
+        SecurityCheck();
+
+        //get controller inputs
+        CheckJoystick();
+        CheckPushButton();
+
+        if(IsPeriodSet()) {
+            WaitPeriod();
+        } else {
+            WaitUpdate(uav->GetAhrs());
+        }
+        needToComputeDefaultTorques=true;
+        needToComputeDefaultThrust=true;
+
+        SignalEvent(Event_t::EnteringControlLoop);
+
+        ComputeOrientation();
+        ComputeAltitude();
+
+        //compute thrust and torques to apply
+        ComputeTorques();
+        ComputeThrust();//logs are added to uz, so it must be updated at last
+
+        // Set torques for roll, pitch and yaw angles (value between -1 and 1). Set thrust (value between 0 and 1)
+        uav->GetUavMultiplex()->SetRoll(-currentTorques.roll);
+        uav->GetUavMultiplex()->SetPitch(-currentTorques.pitch);
+        uav->GetUavMultiplex()->SetYaw(-currentTorques.yaw);
+        uav->GetUavMultiplex()->SetThrust(-currentThrust);//on raisonne en negatif sur l'altitude, a revoir avec les equations
+        uav->GetUavMultiplex()->SetRollTrim(joy->RollTrim());
+        uav->GetUavMultiplex()->SetPitchTrim(joy->PitchTrim());
+        uav->GetUavMultiplex()->SetYawTrim(0);
+        uav->GetUavMultiplex()->Update(GetTime());
+    }
+
+    WarnUponSwitches(false);
+}
+
+void UavStateMachine::ComputeOrientation(void) {
+    if (failSafeMode) {
+        GetDefaultOrientation()->GetQuaternionAndAngularRates(currentQuaternion, currentAngularSpeed);
+    } else {
+        GetOrientation()->GetQuaternionAndAngularRates(currentQuaternion, currentAngularSpeed);
+    }
+}
+
+const AhrsData *UavStateMachine::GetOrientation(void) const {
+    return GetDefaultOrientation();
+}
+
+const AhrsData *UavStateMachine::GetDefaultOrientation(void) const {
+    return uav->GetAhrs()->GetDatas();
+}
+
+void UavStateMachine::ComputeAltitude(void) {
+    if (failSafeMode) {
+        FailSafeAltitudeValues(currentAltitude, currentVerticalSpeed);
+    } else {
+        AltitudeValues(currentAltitude,currentVerticalSpeed);
+    }
+}
+
+void UavStateMachine::ComputeReferenceAltitude(float &refAltitude, float &refVerticalVelocity) {
+    if (altitudeMode==AltitudeMode_t::Manual) {
+        GetDefaultReferenceAltitude(refAltitude, refVerticalVelocity);
+    } else {
+        GetReferenceAltitude(refAltitude, refVerticalVelocity);
+    }
+}
+
+void UavStateMachine::GetDefaultReferenceAltitude(float &refAltitude, float &refVerticalVelocity) {
+    float zc,dzc;
+
+    switch(altitudeState) {
+        //initiate a takeoff: increase motor speed in open loop (see ComputeThrust) until we detect a take off of 0.03m (hard coded value) above the ground.
+        case AltitudeState_t::TakingOff: {
+            if(currentAltitude>groundAltitude+0.03) {
+                altitudeTrajectory->StartTraj(currentAltitude,desiredTakeoffAltitude->Value());
+                altitudeState=AltitudeState_t::Stabilized;
+                SignalEvent(Event_t::Stabilized);
+            }
+            break;
+        }
+        //landing, only check if we reach desired landing altitude
+        case AltitudeState_t::StartLanding: {
+            if(altitudeTrajectory->Position()==desiredLandingAltitude->Value()) {
+                //The Uav target altitude has reached its landing value (typically 0)
+                // but the real Uav altitude may not have reach this value yet because of command delay. Moreover, it
+                // may never exactly reach this value if the ground is not perfectly leveled (critical case: there's a
+                // deep and narrow hole right in the sensor line of sight). That's why we have a 2 phases landing strategy.
+                altitudeState=AltitudeState_t::FinishLanding;
+                SignalEvent(Event_t::FinishLanding);
+                joy->SetLedOFF(1);//DualShock3::led1
+            }
+        }
+        //stabilized: check if z trajectory is finished
+        case AltitudeState_t::Stabilized: {
+            if(!altitudeTrajectory->IsRunning() && !flagZTrajectoryFinished) {
+                SignalEvent(Event_t::ZTrajectoryFinished);
+                flagZTrajectoryFinished=true;
+            }
+            if(flagZTrajectoryFinished && desiredTakeoffAltitude->ValueChanged()) {
+                flagZTrajectoryFinished=false;
+                altitudeTrajectory->StartTraj(currentAltitude,desiredTakeoffAltitude->Value());
+                joy->SetZRef(0);
+            }
+        }
+    }
+
+    //Récupère les consignes (du joystick dans l'implémentation par défaut). La consigne joystick est une vitesse ("delta_z", dzc). le zc est calculé par la manette
+    zc=joy->ZRef();//a revoir, la position offset devrait se calculer dans le generator
+    dzc=joy->DzRef();
+
+    //z control law
+    altitudeTrajectory->SetPositionOffset(zc);
+    altitudeTrajectory->SetSpeedOffset(dzc);
+
+    altitudeTrajectory->Update(GetTime());
+    refAltitude=altitudeTrajectory->Position();
+    refVerticalVelocity=altitudeTrajectory->Speed();
+}
+
+void UavStateMachine::GetReferenceAltitude(float &refAltitude, float &refVerticalVelocity) {
+    Thread::Warn("Default GetReferenceAltitude method is not overloaded => switching back to safe mode\n");
+    EnterFailSafeMode();
+};
+
+void UavStateMachine::ComputeThrust(void) {
+    if (altitudeMode==AltitudeMode_t::Manual) {
+        currentThrust=ComputeDefaultThrust();
+    } else {
+        currentThrust=ComputeCustomThrust();
+    }
+}
+
+float UavStateMachine::ComputeDefaultThrust(void) {
+    if(needToComputeDefaultThrust) {
+        //compute desired altitude
+        float refAltitude, refVerticalVelocity;
+        ComputeReferenceAltitude(refAltitude, refVerticalVelocity);
+
+        switch(altitudeState) {
+            case AltitudeState_t::TakingOff: {
+                //The progressive increase in motor speed is used to evaluate the motor speed that compensate the uav weight. This value
+                //will be used as an offset for altitude control afterwards
+                uZ->OffsetStepUp();
+                break;
+            }
+            case AltitudeState_t::StartLanding:
+            case AltitudeState_t::Stabilized: {
+                float p_error=currentAltitude-refAltitude;
+                float d_error=currentVerticalSpeed-refVerticalVelocity;
+                uZ->SetValues(p_error,d_error);
+                break;
+            }
+            //decrease motor speed in open loop until value offset_g , uav should have already landed or be very close to at this point
+            case AltitudeState_t::FinishLanding: {
+                if(uZ->OffsetStepDown()==false) {
+                    StopMotors();
+                }
+                break;
+            }
+        }
+        uZ->Update(GetTime());
+
+        savedDefaultThrust=uZ->Output();
+        needToComputeDefaultThrust=false;
+    }
+
+    return savedDefaultThrust;
+}
+
+float UavStateMachine::ComputeCustomThrust(void) {
+    Thread::Warn("Default GetThrust method is not overloaded => switching back to safe mode\n");
+    EnterFailSafeMode();
+    return ComputeDefaultThrust();
+}
+
+const AhrsData* UavStateMachine::ComputeReferenceOrientation(void) {
+    if(orientationMode==OrientationMode_t::Manual) {
+        return GetDefaultReferenceOrientation();
+    } else {
+        return GetReferenceOrientation();
+    }
+}
+
+const AhrsData* UavStateMachine::GetDefaultReferenceOrientation(void) const {
+    // We directly control yaw, pitch, roll angles
+    return joy->GetReferenceOrientation();
+}
+
+const AhrsData* UavStateMachine::GetReferenceOrientation(void) {
+    Thread::Warn("Default GetReferenceOrientation method is not overloaded => switching back to safe mode\n");
+    EnterFailSafeMode();
+    return GetDefaultReferenceOrientation();
+}
+
+void UavStateMachine::ComputeTorques(void) {
+    if(torqueMode==TorqueMode_t::Default) {
+        ComputeDefaultTorques(currentTorques);
+    } else {
+        ComputeCustomTorques(currentTorques);
+    }
+}
+
+void UavStateMachine::ComputeDefaultTorques(Euler &torques) {
+    if(needToComputeDefaultTorques) {
+        const AhrsData *refOrientation=ComputeReferenceOrientation();
+        Quaternion refQuaternion;
+        Vector3D refAngularRates;
+        refOrientation->GetQuaternionAndAngularRates(refQuaternion,refAngularRates);
+        Euler refAngles=refQuaternion.ToEuler();
+        Euler currentAngles=currentQuaternion.ToEuler();
+
+        uYaw->SetValues(currentAngles.YawDistanceFrom(refAngles.yaw),currentAngularSpeed.z-refAngularRates.z);
+        uYaw->Update(GetTime());
+        torques.yaw=uYaw->Output();
+
+        uPitch->SetValues(refAngles.pitch,currentAngles.pitch,currentAngularSpeed.y);
+        uPitch->Update(GetTime());
+        torques.pitch=uPitch->Output();
+
+        uRoll->SetValues(refAngles.roll,currentAngles.roll,currentAngularSpeed.x);
+        uRoll->Update(GetTime());
+        torques.roll=uRoll->Output();
+
+        savedDefaultTorques=torques;
+        needToComputeDefaultTorques=false;
+    } else {
+        torques=savedDefaultTorques;
+    }
+}
+
+void UavStateMachine::ComputeCustomTorques(Euler &torques) {
+    Thread::Warn("Default ComputeCustomTorques method is not overloaded => switching back to safe mode\n");
+    EnterFailSafeMode();
+    ComputeDefaultTorques(torques);
+}
+
+void UavStateMachine::TakeOff(void) {
+    flagZTrajectoryFinished=false;
+
+    if(altitudeState==AltitudeState_t::Stopped) {// && GetBatteryMonitor()->IsBatteryLow()==false)
+        //The uav always takes off in fail safe mode
+        EnterFailSafeMode();
+        joy->SetLedOFF(4);//DualShock3::led4
+        joy->SetLedOFF(1);//DualShock3::led1
+        joy->Rumble(0x70);
+        joy->SetZRef(0);
+
+        uZ->SetOffset(); // positionne l'offset de compensation de la gravité à sa valeur initiale (station sol)
+
+        uav->GetUavMultiplex()->LockUserInterface();
+        //Active les moteurs. Pouvoir les désactiver permet de pouvoir observer les consignes moteurs
+        // sans les faire tourner effectivement (en déplaçant à la main le drone)
+        uav->GetBldc()->SetEnabled(true);
+        groundAltitude=currentAltitude;
+        altitudeState=AltitudeState_t::TakingOff;
+
+        SignalEvent(Event_t::TakingOff);
+    } else {
+        joy->ErrorNotify();
+    }
+}
+
+void UavStateMachine::Land(void) {
+    if (altitudeMode!=AltitudeMode_t::Manual) {
+        SetAltitudeMode(AltitudeMode_t::Manual);
+    }
+    if(altitudeState==AltitudeState_t::Stabilized) {
+        joy->SetLedOFF(4);//DualShock3::led4
+        joy->Rumble(0x70);
+
+        altitudeTrajectory->StopTraj();
+        joy->SetZRef(0);
+        altitudeTrajectory->StartTraj(currentAltitude,desiredLandingAltitude->Value()); //shouldn't it be groundAltitude?
+        SignalEvent(Event_t::StartLanding);
+        altitudeState=AltitudeState_t::StartLanding;
+    } else {
+        joy->ErrorNotify();
+    }
+}
+
+void UavStateMachine::SignalEvent(Event_t event) {
+    switch(event) {
+    case Event_t::StartLanding:
+        Thread::Info("Altitude: entering 'StartLanding' state\n");
+        break;
+    case Event_t::Stopped:
+        Thread::Info("Altitude: entering 'Stopped' state\n");
+        break;
+    case Event_t::TakingOff:
+        Thread::Info("Altitude: taking off\n");
+        break;
+    case Event_t::Stabilized:
+        Thread::Info("Altitude: entering 'Stabilized' state\n");
+        break;
+    case Event_t::FinishLanding:
+        Thread::Info("Altitude: entering 'FinishLanding' state\n");
+        break;
+    case Event_t::EmergencyStop:
+        Thread::Info("Emergency stop!\n");
+        break;
+    }
+}
+
+void UavStateMachine::EmergencyStop(void) {
+    if(altitudeState!=AltitudeState_t::Stopped) {
+        StopMotors();
+        EnterFailSafeMode();
+        joy->Rumble(0x70);
+        SignalEvent(Event_t::EmergencyStop);
+    }
+}
+
+void UavStateMachine::StopMotors(void)
+{
+    joy->FlashLed(1,10,10);//DualShock3::led1
+    uav->GetBldc()->SetEnabled(false);
+    uav->GetUavMultiplex()->UnlockUserInterface();
+    SignalEvent(Event_t::Stopped);
+    altitudeState=AltitudeState_t::Stopped;
+    uav->GetAhrs()->UnlockUserInterface();
+
+    uZ->SetValues(0,0);
+    uZ->Reset();
+}
+
+GridLayout* UavStateMachine::GetButtonsLayout(void) const {
+    return buttonslayout;
+}
+
+void UavStateMachine::SecurityCheck(void) {
+    MandatorySecurityCheck();
+    ExtraSecurityCheck();
+}
+
+void UavStateMachine::MandatorySecurityCheck(void) {
+    if(getFrameworkManager()->ConnectionLost() && !flagConnectionLost) {
+        flagConnectionLost=true;
+        Thread::Err("Connection lost\n");
+        EnterFailSafeMode();
+        if(altitudeState==AltitudeState_t::Stopped) {
+            SafeStop();
+        } else {
+            Land();
+        }
+    }
+    if((altitudeState==AltitudeState_t::TakingOff || altitudeState==AltitudeState_t::Stabilized) && uav->GetBatteryMonitor()->IsBatteryLow() && !flagBatteryLow) {
+        flagBatteryLow=true;
+        Printf("Battery Low\n");
+        EnterFailSafeMode();
+        Land();
+    }
+}
+
+void UavStateMachine::CheckJoystick(void) {
+    GenericCheckJoystick();
+    ExtraCheckJoystick();
+}
+
+void UavStateMachine::GenericCheckJoystick(void) {
+    static bool isEmergencyStopButtonPressed=false;
+    static bool isTakeOffButtonPressed=false;
+    static bool isSafeModeButtonPressed=false;
+
+   if(joy->IsButtonPressed(1)) { //select
+        if (!isEmergencyStopButtonPressed) {
+            isEmergencyStopButtonPressed=true;
+            Thread::Info("Emergency stop from joystick\n");
+            EmergencyStop();
+        }
+    } else isEmergencyStopButtonPressed=false;
+
+    if(joy->IsButtonPressed(0)) { //start
+        if (!isTakeOffButtonPressed) {
+            isTakeOffButtonPressed=true;
+            switch(altitudeState) {
+                case AltitudeState_t::Stopped:
+                    TakeOff();
+                    break;
+                case AltitudeState_t::Stabilized:
+                    Land();
+                    break;
+                default:
+                    joy->ErrorNotify();
+                    break;
+            }
+        }
+    } else isTakeOffButtonPressed=false;
+
+    //cross
+    //gsanahuj:conflict with Majd programs.
+    //check if l1,l2,r1 and r2 are not pressed
+    //to allow a combination in user program
+    if(joy->IsButtonPressed(5) && !joy->IsButtonPressed(6) && !joy->IsButtonPressed(7) && !joy->IsButtonPressed(9) && !joy->IsButtonPressed(10)) {
+        if (!isSafeModeButtonPressed) {
+            isSafeModeButtonPressed=true;
+            Thread::Info("Entering fail safe mode\n");
+            EnterFailSafeMode();
+        }
+    } else isSafeModeButtonPressed=false;
+}
+
+void UavStateMachine::CheckPushButton(void) {
+    GenericCheckPushButton();
+    ExtraCheckPushButton();
+}
+
+void UavStateMachine::GenericCheckPushButton(void) {
+    if(button_kill->Clicked()==true) SafeStop();
+    if(button_take_off->Clicked()==true) TakeOff();
+    if(button_land->Clicked()==true) Land();
+    if(button_start_log->Clicked()==true) getFrameworkManager()->StartLog();
+    if(button_stop_log->Clicked()==true) getFrameworkManager()->StopLog();
+}
+
+void UavStateMachine::EnterFailSafeMode(void) {
+    SetAltitudeMode(AltitudeMode_t::Manual);
+    SetOrientationMode(OrientationMode_t::Manual);
+    SetThrustMode(ThrustMode_t::Default);
+    SetTorqueMode(TorqueMode_t::Default);
+
+    GetDefaultOrientation()->GetQuaternionAndAngularRates(currentQuaternion, currentAngularSpeed);
+    joy->SetYawRef(currentQuaternion);
+    uYaw->Reset();
+    uPitch->Reset();
+    uRoll->Reset();
+
+    failSafeMode=true;
+    SignalEvent(Event_t::EnteringFailSafeMode);
+}
+
+bool UavStateMachine::ExitFailSafeMode(void) {
+    // only exit fail safe mode if in Stabilized altitude state
+    //gsanahuj: pour la demo inaugurale on ne peut pas etre en failsafe
+    //le ruban perturbe l'us
+    /*
+    if (altitudeState!=AltitudeState_t::Stabilized) {
+        return false;
+    } else*/ {
+        failSafeMode=false;
+        return true;
+    }
+}
+
+bool UavStateMachine::SetTorqueMode(TorqueMode_t const &newTorqueMode) {
+    if ((newTorqueMode==TorqueMode_t::Custom) && (failSafeMode)) {
+        if (!ExitFailSafeMode()) return false;
+    }
+    //When transitionning from Custom to Default torque mode, we should reset the default control laws
+    if ((torqueMode==TorqueMode_t::Custom) && (newTorqueMode==TorqueMode_t::Default)) {
+        uYaw->Reset();
+        uPitch->Reset();
+        uRoll->Reset();
+    }
+    torqueMode=newTorqueMode;
+    return true;
+}
+
+bool UavStateMachine::SetAltitudeMode(AltitudeMode_t const &newAltitudeMode) {
+    if ((newAltitudeMode==AltitudeMode_t::Custom) && (failSafeMode)) {
+        if (!ExitFailSafeMode()) return false;
+    }
+    altitudeMode=newAltitudeMode;
+    GotoAltitude(desiredTakeoffAltitude->Value());
+
+    return true;
+}
+
+bool UavStateMachine::GotoAltitude(float desiredAltitude) {
+    if (altitudeMode!=AltitudeMode_t::Manual) {
+        return false;
+    }
+    altitudeTrajectory->StartTraj(uav->GetMetaUsRangeFinder()->z(),desiredAltitude);
+    return true;
+}
+
+bool UavStateMachine::SetOrientationMode(OrientationMode_t const &newOrientationMode) {
+    if ((newOrientationMode==OrientationMode_t::Custom) && (failSafeMode)) {
+        if (!ExitFailSafeMode()) return false;
+    }
+    //When transitionning from Custom to Manual mode we must reset to yaw reference to the current absolute yaw angle,
+    // overwise the Uav will abruptly change orientation
+    if ((orientationMode==OrientationMode_t::Custom) && (newOrientationMode==OrientationMode_t::Manual)) {
+        joy->SetYawRef(currentQuaternion);
+    }
+    orientationMode=newOrientationMode;
+    return true;
+}
+
+bool UavStateMachine::SetThrustMode(ThrustMode_t const &newThrustMode) {
+    if ((newThrustMode==ThrustMode_t::Custom) && (failSafeMode)) {
+        if (!ExitFailSafeMode()) return false;
+    }
+    thrustMode=newThrustMode;
+    return true;
+}
Index: trunk/lib/FlairMeta/src/UavStateMachine.h
===================================================================
--- trunk/lib/FlairMeta/src/UavStateMachine.h	(revision 7)
+++ trunk/lib/FlairMeta/src/UavStateMachine.h	(revision 7)
@@ -0,0 +1,303 @@
+//  created:    2014/04/29
+//  filename:   UavStateMachine.h
+//
+//  author:     Gildas Bayard, Guillaume Sanahuja
+//              Copyright Heudiasyc UMR UTC/CNRS 7253
+//
+//  version:    $Id: $
+//
+//  purpose:    state machine for UAV
+//
+//
+/*********************************************************************/
+
+#ifndef UAVSTATEMACHINE_H
+#define UAVSTATEMACHINE_H
+
+#include <Thread.h>
+#include <Vector2D.h>
+#include <Vector3D.h>
+#include <Euler.h>
+#include <Quaternion.h>
+
+namespace flair {
+    namespace core {
+        class FrameworkManager;
+        class AhrsData;
+        class io_data;
+    }
+    namespace gui {
+        class PushButton;
+        class GridLayout;
+        class Tab;
+        class DoubleSpinBox;
+    }
+    namespace filter {
+        class ControlLaw;
+        class NestedSat;
+        class Pid;
+        class PidThrust;
+        class TrajectoryGenerator1D;
+    }
+    namespace sensor {
+        class TargetController;
+    }
+    namespace meta {
+        class MetaDualShock3;
+        class Uav;
+    }
+}
+
+namespace flair { namespace meta {
+
+ /*! \class UavStateMachine
+*
+* \brief State machine for UAV
+*
+* thread synchronized with ahrs, unless a period is set with SetPeriodUS or SetPeriodMS
+*/
+
+class UavStateMachine : public core::Thread
+{
+    protected:
+        enum class AltitudeMode_t {
+            Manual,
+            Custom
+        };
+        const AltitudeMode_t &GetAltitudeMode(void) const {
+            return altitudeMode;
+        }
+        bool SetAltitudeMode(const AltitudeMode_t &altitudeMode);
+
+        //uses TrajectoryGenerator1D *altitudeTrajectory to go to desiredAltitude
+        //available in mode AltitudeMode_t::Manual
+        //return true if goto is possible
+        bool GotoAltitude(float desiredAltitude);
+
+        enum class OrientationMode_t {
+            Manual,
+            Custom
+        };
+        const OrientationMode_t &GetOrientationMode(void) const {
+            return orientationMode;
+        }
+        bool SetOrientationMode(const OrientationMode_t &orientationMode);
+
+        enum class ThrustMode_t {
+            Default,
+            Custom
+        };
+        const ThrustMode_t &GetThrustMode() const {
+            return thrustMode;
+        }
+        bool SetThrustMode(const ThrustMode_t &thrustMode);
+
+        enum class TorqueMode_t {
+            Default,
+            Custom
+        };
+        const TorqueMode_t &GetTorqueMode(void) const {
+            return torqueMode;
+        }
+        bool SetTorqueMode(const TorqueMode_t &torqueMode);
+
+        enum class Event_t {
+            EnteringFailSafeMode,
+            EnteringControlLoop,
+            StartLanding,
+            FinishLanding,
+            Stopped,
+            TakingOff,
+            EmergencyStop,
+            Stabilized, //as soon as uav is 3cm far from the ground
+            ZTrajectoryFinished,
+        };
+
+        UavStateMachine(meta::Uav* uav,uint16_t ds3Port=20000);
+        ~UavStateMachine();
+
+        const core::Quaternion &GetCurrentQuaternion(void) const;
+
+        const core::Vector3D &GetCurrentAngularSpeed(void) const;
+
+        const meta::Uav *GetUav(void) const;
+
+        void Land(void);
+        void TakeOff(void);
+        void EmergencyStop(void);
+        //! Used to signal an event
+        /*!
+            \param event the event which occured
+        */
+        virtual void SignalEvent(Event_t event);
+
+        virtual const core::AhrsData *GetOrientation(void) const;
+        const core::AhrsData *GetDefaultOrientation(void) const;
+
+        virtual void AltitudeValues(float &z,float &dz) const;//in uav coordinate!
+        void EnterFailSafeMode(void);
+        bool ExitFailSafeMode(void);
+        void FailSafeAltitudeValues(float &z,float &dz) const;//in uav coordinate!
+
+        gui::GridLayout *GetButtonsLayout(void) const;
+        virtual void ExtraSecurityCheck(void){};
+        virtual void ExtraCheckJoystick(void){};
+        virtual void ExtraCheckPushButton(void){};
+
+        void GetDefaultReferenceAltitude(float &refAltitude, float &refVerticalVelocity);
+        virtual void GetReferenceAltitude(float &refAltitude, float &refVerticalVelocity);
+        //float GetDefaultThrustOffset(void);
+        const core::AhrsData *GetDefaultReferenceOrientation(void) const;
+        virtual const core::AhrsData *GetReferenceOrientation(void);
+
+        /*!
+        * \brief Compute Custom Torques
+        *
+        * Reimplement this method to use TorqueMode_t::Custom. \n
+        * This method is called internally by UavStateMachine, do not call it by yourself. \n
+        * See GetTorques if you need torques values.
+        *
+        * \param torques custom torques
+        */
+        virtual void ComputeCustomTorques(core::Euler &torques);
+
+        /*!
+        * \brief Compute Default Torques
+        *
+        * This method is called internally by UavStateMachine when using TorqueMode_t::Default. \n
+        * Torques are only computed once by loop, other calls to this method will use previously computed torques.
+        *
+        * \param torques default torques
+        */
+        void ComputeDefaultTorques(core::Euler &torques);
+
+        /*!
+        * \brief Get Torques
+        *
+        * \return torques current torques
+        */
+        //const core::Euler &GetTorques() const;
+
+        /*!
+        * \brief Compute Custom Thrust
+        *
+        * Reimplement this method to use ThrustMode_t::Custom. \n
+        * This method is called internally by UavStateMachine, do not call it by yourself. \n
+        * See GetThrust if you need thrust value.
+        *
+        * \return custom Thrust
+        */
+        virtual float ComputeCustomThrust(void);
+
+        /*!
+        * \brief Compute Default Thrust
+        *
+        * This method is called internally by UavStateMachine when using ThrustMode_t::Default. \n
+        * Thrust is only computed once by loop, other calls to this method will use previously computed thrust.
+        *
+        * \return default thrust
+        */
+        float ComputeDefaultThrust(void);
+
+        /*!
+        * \brief Get Thrust
+        *
+        * \return current thrust
+        */
+        //float GetThrust() const;
+
+        /*!
+        * \brief Add an IODevice to the control law logs
+        *
+        * The IODevice will be automatically logged among the Uz logs,
+        * if logging is enabled (see IODevice::SetDataToLog, FrameworkManager::StartLog
+        * and FrameworkManager::AddDeviceToLog). \n
+        *
+        * \param device IODevice to log
+        */
+        void AddDeviceToControlLawLog(const core::IODevice* device);
+
+        /*!
+        * \brief Add an io_data to the control law logs
+        *
+        * The io_data will be automatically logged among the Uz logs,
+        * if logging is enabled (see IODevice::SetDataToLog, FrameworkManager::StartLog
+        * and FrameworkManager::AddDeviceToLog). \n
+        *
+        * \param data io_data to log
+        */
+        void AddDataToControlLawLog(const core::io_data* data);
+
+        const sensor::TargetController *GetJoystick(void) const;
+
+        gui::Tab *setupLawTab,*graphLawTab;
+
+    private:
+        /*!
+        \enum AltitudeState_t
+        \brief States of the altitude state machine
+        */
+        enum class AltitudeState_t {
+            Stopped,        /*!< the uav motors are stopped */
+            TakingOff,      /*!< take off initiated. Motors accelerate progressively until the UAV lift up */
+            Stabilized,     /*!< the uav is actively maintaining its altitude */
+            StartLanding,   /*!< landing initiated. Altitude is required to reach the landing altitude (0 by default) */
+            FinishLanding   /*!< motors are gradually stopped */
+        };
+        AltitudeState_t altitudeState;
+        void ProcessAltitudeFiniteStateMachine();
+        void ComputeReferenceAltitude(float &refAltitude, float &refVerticalVelocity);
+
+
+        float groundAltitude; // effective altitude when the uav leaves the ground
+        float currentAltitude,currentVerticalSpeed;
+
+        bool failSafeMode;
+        void SecurityCheck(void);
+        void MandatorySecurityCheck(void);
+        void CheckJoystick();
+        void GenericCheckJoystick();
+        void CheckPushButton(void);
+        void GenericCheckPushButton(void);
+        void Run(void);
+        void StopMotors(void);
+
+        meta::Uav *uav;
+
+        core::Quaternion currentQuaternion;
+        core::Vector3D currentAngularSpeed;
+
+        const core::AhrsData *ComputeReferenceOrientation(void);
+
+        void ComputeOrientation(void);
+        void ComputeAltitude(void);
+
+        void ComputeTorques(void);
+        core::Euler currentTorques,savedDefaultTorques;
+        bool needToComputeDefaultTorques;
+
+        void ComputeThrust(void);
+        float currentThrust,savedDefaultThrust;
+        bool needToComputeDefaultThrust;
+
+        gui::PushButton *button_kill,*button_take_off,*button_land,*button_start_log,*button_stop_log;
+        gui::GridLayout *buttonslayout;
+        gui::DoubleSpinBox *desiredTakeoffAltitude,*desiredLandingAltitude;
+        AltitudeMode_t altitudeMode;
+        OrientationMode_t orientationMode;
+        ThrustMode_t thrustMode;
+        TorqueMode_t torqueMode;
+        bool flagBatteryLow;
+        bool flagConnectionLost;
+        bool flagZTrajectoryFinished;
+        filter::NestedSat *uRoll,*uPitch;
+        filter::Pid *uYaw;
+        filter::PidThrust *uZ;
+
+        MetaDualShock3 *joy;
+        filter::TrajectoryGenerator1D *altitudeTrajectory;
+};
+
+};
+};
+#endif // UAVSTATEMACHINE_H
Index: trunk/lib/FlairMeta/src/XAir.cpp
===================================================================
--- trunk/lib/FlairMeta/src/XAir.cpp	(revision 7)
+++ trunk/lib/FlairMeta/src/XAir.cpp	(revision 7)
@@ -0,0 +1,72 @@
+//  created:    2015/02/08
+//  filename:   XAir.cpp
+//
+//  author:     Guillaume Sanahuja
+//              Copyright Heudiasyc UMR UTC/CNRS 7253
+//
+//  version:    $Id: $
+//
+//  purpose:    Class defining a Xair uav
+//
+//
+/*********************************************************************/
+
+#include "XAir.h"
+#include <FrameworkManager.h>
+#include <RTDM_I2cPort.h>
+#include <RTDM_SerialPort.h>
+#include <Srf08.h>
+#include <Gx3_25_ahrs.h>
+#include <AfroBldc.h>
+#include <X4X8Multiplex.h>
+#include <Ps3Eye.h>
+#include <BatteryMonitor.h>
+#include <Tab.h>
+
+using std::string;
+using namespace flair::core;
+using namespace flair::gui;
+using namespace flair::sensor;
+using namespace flair::filter;
+using namespace flair::actuator;
+
+namespace flair { namespace meta {
+
+XAir::XAir(FrameworkManager* parent,string uav_name,filter::UavMultiplex *multiplex) : Uav(parent,uav_name,multiplex) {
+    RTDM_I2cPort* i2cport=new RTDM_I2cPort(parent,"rtdm_i2c","rti2c3");
+    RTDM_SerialPort* imu_port=new RTDM_SerialPort(parent,"imu_port","rtser1");
+
+    if(multiplex==NULL) SetMultiplex(new X4X8Multiplex(parent,"motors",X4X8Multiplex::X8));
+
+    SetBldc(new AfroBldc(GetUavMultiplex(),GetUavMultiplex()->GetLayout(),"motors",GetUavMultiplex()->MotorsCount(),i2cport));
+    SetUsRangeFinder(new Srf08(parent,"SRF08",i2cport,0x70,60));
+    SetAhrs(new Gx3_25_ahrs(parent,"imu",imu_port,Gx3_25_imu::EulerAnglesAndAngularRates,70));
+    Tab* bat_tab=new Tab(parent->GetTabWidget(),"battery");
+    SetBatteryMonitor(new BatteryMonitor(bat_tab->NewRow(),"battery"));
+    GetBatteryMonitor()->SetBatteryValue(12);
+
+/*
+        if(VRPNType==Auto || VRPNType==AutoSerialPort)
+        {
+            RTDM_SerialPort* vrpn_port=new RTDM_SerialPort(parent,"vrpn_port","rtser3");
+
+            vrpnclient=new VrpnClient(parent,"vrpn",vrpn_port,10000,80);
+            uav_vrpn=new MetaVrpnObject(vrpnclient,uav_name,VRPNSerialObjectId);
+        }
+*/
+    SetVerticalCamera(new Ps3Eye(parent,"camv",0,50));
+}
+
+XAir::~XAir() {
+
+}
+
+void XAir::StartSensors(void) {
+    ((Gx3_25_ahrs*)GetAhrs())->Start();
+    ((Srf08*)GetUsRangeFinder())->Start();
+    ((Ps3Eye *)GetVerticalCamera())->Start();
+    Uav::StartSensors();
+}
+
+} // end namespace meta
+} // end namespace flair
Index: trunk/lib/FlairMeta/src/XAir.h
===================================================================
--- trunk/lib/FlairMeta/src/XAir.h	(revision 7)
+++ trunk/lib/FlairMeta/src/XAir.h	(revision 7)
@@ -0,0 +1,33 @@
+/*!
+ * \file XAir.h
+ * \brief Class defining a xair uav
+ * \author Guillaume Sanahuja, Copyright Heudiasyc UMR UTC/CNRS 7253
+ * \date 2016/02/08
+ * \version 4.0
+ */
+
+#ifndef XAIR_H
+#define XAIR_H
+
+#include "Uav.h"
+
+namespace flair
+{
+namespace meta
+{
+    /*! \class XAir
+    *
+    * \brief Class defining an ardrone2 uav
+    */
+    class XAir : public Uav {
+        public:
+            XAir(core::FrameworkManager* parent,std::string uav_name,filter::UavMultiplex *multiplex=NULL);
+            ~XAir();
+            void StartSensors(void);
+
+        private:
+
+    };
+} // end namespace meta
+} // end namespace flair
+#endif // XAIR_H
Index: trunk/lib/FlairMeta/src/unexported/MetaDualShock3_impl.h
===================================================================
--- trunk/lib/FlairMeta/src/unexported/MetaDualShock3_impl.h	(revision 7)
+++ trunk/lib/FlairMeta/src/unexported/MetaDualShock3_impl.h	(revision 7)
@@ -0,0 +1,44 @@
+/*!
+ * \file MetaDualShock3_impl.h
+ * \brief Classe intégrant la manette DualShock3 et les consignes joystick
+ * \author Guillaume Sanahuja, Copyright Heudiasyc UMR UTC/CNRS 7253
+ * \date 2014/01/14
+ * \version 3.4
+ */
+
+#ifndef METADUALSHOCK3_IMPL_H
+#define METADUALSHOCK3_IMPL_H
+
+#include <IODevice.h>
+
+namespace flair
+{
+    namespace meta
+    {
+        class MetaDualShock3;
+    }
+    namespace filter
+    {
+        class JoyReference;
+    }
+}
+
+/*! \class MetaDualShock3_impl
+*
+* \brief Classe intégrant la manette DualShock3 et les consignes joystick
+*/
+class MetaDualShock3_impl: public flair::core::IODevice
+{
+    public:
+        MetaDualShock3_impl(flair::meta::MetaDualShock3* self,std::string name);
+        ~MetaDualShock3_impl();
+        flair::filter::JoyReference *joy_ref;
+
+    private:
+        void UpdateFrom(const flair::core::io_data *data);
+        flair::meta::MetaDualShock3* self;
+        bool joy_init;
+        bool wasRollTrimUpButtonPressed,wasRollTrimDownButtonPressed,wasPitchTrimUpButtonPressed,wasPitchTrimDownButtonPressed;
+};
+
+#endif // METADUALSHOCK3_IMPL_H
