Index: /trunk/lib/FlairCore/src/RangeFinderPlot.cpp
===================================================================
--- /trunk/lib/FlairCore/src/RangeFinderPlot.cpp	(revision 220)
+++ /trunk/lib/FlairCore/src/RangeFinderPlot.cpp	(revision 221)
@@ -35,5 +35,5 @@
     : SendData(position, name, "RangeFinderPlot", 200) {
   this->datas = datas;
-Warn("RangeFinderPlot::CopyDatas needs to be written\n");
+
   SetSendSize(datas->GetDataType().GetSize());
 
@@ -58,5 +58,5 @@
 
 void RangeFinderPlot::CopyDatas(char *buf) const {
-  //datas->CopyDatas(buf);
+  datas->CopyDatas(buf);
 }
 
Index: /trunk/lib/FlairCore/src/UsSensorPlot.cpp
===================================================================
--- /trunk/lib/FlairCore/src/UsSensorPlot.cpp	(revision 221)
+++ /trunk/lib/FlairCore/src/UsSensorPlot.cpp	(revision 221)
@@ -0,0 +1,70 @@
+// %flair:license{
+// This file is part of the Flair framework distributed under the
+// CECILL-C License, Version 1.0.
+// %flair:license}
+//  created:    2018/02/21
+//  filename:   UsSensorPlot.cpp
+//
+//  author:     Guillaume Sanahuja
+//              Copyright Heudiasyc UMR UTC/CNRS 7253
+//
+//  version:    $Id: $
+//
+//  purpose:    Class displaying a plot for raw us sensor
+//
+//
+/*********************************************************************/
+
+#include "UsSensorPlot.h"
+#include "LayoutPosition.h"
+#include "Matrix.h"
+
+using std::string;
+using namespace flair::core;
+
+namespace flair {
+namespace gui {
+
+UsSensorPlot::UsSensorPlot(const LayoutPosition *position, string name,
+                       string y_name,float ymin, float ymax,const Matrix *datas,const Matrix *peakInfos)
+    : DataPlot(position, name, "UsSensorPlot") {
+  int nbSamples;
+  if(datas->Cols()==1) {
+    nbSamples=datas->Rows();
+  } else if(datas->Rows()==1) {
+    nbSamples=datas->Cols();
+  } else {
+    nbSamples=0;
+    Err("matrix must be 1D\n");
+  }
+  
+  if(peakInfos->Cols()!=4 || peakInfos->Rows()!=1) {
+    Err("peakInfos matrix must be 1*4 (first start,first end, second start,second end)\n");
+  }
+  
+  if(peakInfos->GetDataType().GetElementDataType().GetDescription()!="uint16_t") {
+    Err("peakInfos matrix must be 1of type uint16_t\n");
+  }
+    
+  this->datas = datas;
+  this->peakInfos = peakInfos;
+  
+  SetVolatileXmlProp("ymin", ymin);
+  SetVolatileXmlProp("ymax", ymax);
+  SetVolatileXmlProp("y_name", y_name);
+  SetVolatileXmlProp("samples", nbSamples);
+  SetVolatileXmlProp("type", datas->GetDataType().GetElementDataType().GetDescription());
+  SendXml();
+
+  SetSendSize(datas->GetDataType().GetSize()+peakInfos->GetDataType().GetSize());
+}
+
+UsSensorPlot::~UsSensorPlot() {}
+
+void UsSensorPlot::CopyDatas(char *buf) const {
+  datas->CopyDatas(buf);
+  peakInfos->CopyDatas(buf+datas->GetDataType().GetSize());
+}
+
+} // end namespace gui
+} // end namespace flair
Index: /trunk/lib/FlairCore/src/UsSensorPlot.h
===================================================================
--- /trunk/lib/FlairCore/src/UsSensorPlot.h	(revision 221)
+++ /trunk/lib/FlairCore/src/UsSensorPlot.h	(revision 221)
@@ -0,0 +1,77 @@
+// %flair:license{
+// This file is part of the Flair framework distributed under the
+// CECILL-C License, Version 1.0.
+// %flair:license}
+/*!
+ * \file UsSensorPlot.h
+ * \brief Class displaying a plot for raw us sensor
+ * \author Guillaume Sanahuja, Copyright Heudiasyc UMR UTC/CNRS 7253
+ * \date 2018/02/21
+ * \version 4.0
+ */
+
+#ifndef USSENSORPLOT_H
+#define USSENSORPLOT_H
+
+#include <DataPlot.h>
+#include <stdint.h>
+
+namespace flair {
+namespace core {
+class Matrix;
+}
+}
+
+namespace flair {
+namespace gui {
+
+class LayoutPosition;
+
+/*! \class UsSensorPlot
+*
+* \brief Class displaying a plot for raw us sensor
+*
+*/
+class UsSensorPlot : private DataPlot {
+public:
+  /*!
+  * \brief Constructor
+  *
+  * Construct a plot for raw us sensor at given place position.
+  *
+  * \param position position to display the plot
+  * \param name name
+  * \param y_name name of y axis
+  * \param ymin default ymin of the plot
+  * \param ymax default ymax of the plot
+  * \param datas data matrix, must be 1D
+  * \param peakInfos peak infos, must be 1*4 (first start,first end, second start,second end)
+  */
+  UsSensorPlot(const LayoutPosition *position, std::string name,
+                       std::string y_name,float ymin, float ymax,const core::Matrix *datas,const core::Matrix *peakInfos);
+
+  /*!
+  * \brief Destructor
+  *
+  */
+  ~UsSensorPlot();
+  
+private:
+  /*!
+  * \brief Copy datas to specified buffer
+  *
+  * Reimplemented from SendData.
+  *
+  * \param buf output buffer
+  */
+  void CopyDatas(char *buf) const;
+  
+  const core::Matrix *datas,*peakInfos;
+
+
+};
+
+} // end namespace gui
+} // end namespace flair
+
+#endif // USSENSORPLOT_H
Index: /trunk/lib/FlairSensorActuator/src/SimuUs.cpp
===================================================================
--- /trunk/lib/FlairSensorActuator/src/SimuUs.cpp	(revision 220)
+++ /trunk/lib/FlairSensorActuator/src/SimuUs.cpp	(revision 221)
@@ -32,4 +32,5 @@
 namespace sensor {
 
+//control part
 SimuUs::SimuUs(string name, uint32_t modelId,uint32_t deviceId,
                uint8_t priority)
@@ -43,4 +44,5 @@
 }
 
+//simulation part
 SimuUs::SimuUs(const IODevice *parent, string name,uint32_t modelId,uint32_t deviceId)
     : Thread(parent, name, 0), UsRangeFinder(parent,name) {
Index: /trunk/lib/FlairSensorActuator/src/UsRangeFinder.cpp
===================================================================
--- /trunk/lib/FlairSensorActuator/src/UsRangeFinder.cpp	(revision 220)
+++ /trunk/lib/FlairSensorActuator/src/UsRangeFinder.cpp	(revision 221)
@@ -73,4 +73,6 @@
 Tab *UsRangeFinder::GetPlotTab(void) const { return plot_tab; }
 
+TabWidget *UsRangeFinder::GetTabWidget(void) const { return tab; }
+
 void UsRangeFinder::UseDefaultPlot(void) {
   if (tab == NULL) {
Index: /trunk/lib/FlairSensorActuator/src/UsRangeFinder.h
===================================================================
--- /trunk/lib/FlairSensorActuator/src/UsRangeFinder.h	(revision 220)
+++ /trunk/lib/FlairSensorActuator/src/UsRangeFinder.h	(revision 221)
@@ -105,4 +105,11 @@
   */
   gui::Tab *GetPlotTab(void) const;
+  
+  /*!
+  * \brief Tab widget
+  *
+  * \return tab widget
+  */
+  gui::TabWidget *GetTabWidget(void) const;
 
   /*!
Index: /trunk/tools/FlairGCS/CMakeLists.txt
===================================================================
--- /trunk/tools/FlairGCS/CMakeLists.txt	(revision 220)
+++ /trunk/tools/FlairGCS/CMakeLists.txt	(revision 221)
@@ -23,4 +23,5 @@
 	src/UdtSocket.h
 	src/RangeFinderPlot.h
+    src/UsSensorPlot.h
 	src/DataPlot2D.h
 	src/Picture.h
Index: /trunk/tools/FlairGCS/src/DataPlot2D.cpp
===================================================================
--- /trunk/tools/FlairGCS/src/DataPlot2D.cpp	(revision 220)
+++ /trunk/tools/FlairGCS/src/DataPlot2D.cpp	(revision 221)
@@ -272,5 +272,5 @@
       plot_data(data1, data2, i);
     } else {
-      printf("DataPlot1D::DrawDatas type non connu\n");
+      printf("DataPlot2D::DrawDatas type non connu\n");
     }
   }
Index: /trunk/tools/FlairGCS/src/Layout.cpp
===================================================================
--- /trunk/tools/FlairGCS/src/Layout.cpp	(revision 220)
+++ /trunk/tools/FlairGCS/src/Layout.cpp	(revision 221)
@@ -18,4 +18,5 @@
 #include "DataPlot2D.h"
 #include "RangeFinderPlot.h"
+#include "UsSensorPlot.h"
 #include "Picture.h"
 #include "Map.h"
@@ -180,4 +181,20 @@
     }
   }
+  if (type == "UsSensorPlot") {
+    float ymin = dom.attribute("ymin").toFloat();
+    float ymax = dom.attribute("ymax").toFloat();
+    QString y_name = dom.attribute("y_name");
+    int enabled = dom.attribute("enabled").toInt();
+    int period = dom.attribute("period").toInt();
+    QString type = dom.attribute("type");
+    int samples = dom.attribute("samples").toInt();
+    if (enabled == 1) {
+      widget = new UsSensorPlot(this, row, col, name, y_name,
+                              ymin, ymax, samples,type,true, period);
+    } else {
+      widget = new UsSensorPlot(this, row, col, name,  y_name,
+                              ymin, ymax, samples,type,false, 100);
+    }
+  }
   if (type == "RangeFinderPlot") {
     float xmin = dom.attribute("xmin").toFloat();
Index: /trunk/tools/FlairGCS/src/UsSensorPlot.cpp
===================================================================
--- /trunk/tools/FlairGCS/src/UsSensorPlot.cpp	(revision 221)
+++ /trunk/tools/FlairGCS/src/UsSensorPlot.cpp	(revision 221)
@@ -0,0 +1,254 @@
+// %flair:license{
+// This file is part of the Flair framework distributed under the
+// CECILL-C License, Version 1.0.
+// %flair:license}
+#include "UsSensorPlot.h"
+#include "Layout.h"
+#include <qwt_plot.h>
+#include <qwt_plot_curve.h>
+#include <qwt_plot_grid.h>
+#include <qwt_plot_magnifier.h>
+#include <qwt_plot_canvas.h>
+#include <qwt_scale_widget.h>
+#include <qwt_legend_label.h>
+#include <qwt_legend.h>
+#include <qwt_plot_panner.h>
+#include <qwt_plot_rescaler.h>
+#include <qwt_plot_marker.h>
+#include <QMouseEvent>
+#include <QMenu>
+#include <QInputDialog>
+#include <qendian.h>
+#include <qwt_symbol.h>
+
+UsSensorPlot::UsSensorPlot(Layout *parent, int row, int col, QString plot_name,
+                       QString y_name, float ymin, float ymax, uint32_t nbSamples,QString datasType,bool enabled, int period)
+    : DataRemote(plot_name, "UsSensorPlot", parent, enabled, period) {
+  plot = new QwtPlot(NULL);
+  plot->setEnabled(enabled);
+
+  parent->addWidget(plot, row, col);
+  visible_widget = plot;
+  
+  this->nbSamples=nbSamples;
+  this->datasType=datasType;
+
+#if QT_VERSION >= 0x040000
+#ifdef Q_WS_X11
+  /*
+     Qt::WA_PaintOnScreen is only supported for X11, but leads
+     to substantial bugs with Qt 4.2.x/Windows
+   */
+  plot->canvas()->setAttribute(Qt::WA_PaintOnScreen, true);
+#endif
+#endif
+
+  alignScales();
+
+  // Assign a title
+  plot->setTitle(plot_name);
+
+  // Axis
+  plot->setAxisTitle(QwtPlot::xBottom, "samples");
+  setXAxisScale(0, nbSamples-1);
+
+  plot->setAxisTitle(QwtPlot::yLeft, y_name);
+  setYAxisScale(ymin, ymax);
+
+  //QwtPlotRescaler *rescaler = new QwtPlotRescaler(plot->canvas());
+  //rescaler->setRescalePolicy(QwtPlotRescaler::Fixed); 
+  /*
+ rescaler->setReferenceAxis(QwtPlot::xBottom);
+ rescaler->setAspectRatio(QwtPlot::yLeft, 1.0);*/
+
+  // grid
+  QwtPlotGrid *grid = new QwtPlotGrid;
+  grid->setPen(QPen(Qt::black, 0, Qt::DotLine));
+  grid->attach(plot);
+
+  // zoomer
+  QwtPlotMagnifier *zoomer = new QwtPlotMagnifier(plot->canvas());
+  zoomer->setMouseButton(Qt::RightButton, Qt::ControlModifier);
+
+  // scroller
+  QwtPlotPanner *scroller = new QwtPlotPanner(plot->canvas());
+
+  plot->canvas()->installEventFilter(this);
+  
+  dx = (double *)malloc(nbSamples* sizeof(double));
+  dy = (double *)malloc(nbSamples* sizeof(double));
+  for (int i = 0; i < nbSamples; i++) dx[i] = i;
+  
+  // Insert new curve
+  datas = new QwtPlotCurve();
+  datas->attach(plot);
+  datas->setPen(QPen(QColor(255, 0, 0, 255)));
+
+  datas->setVisible(true);
+
+  // Attach (don't copy) data
+  datas->setRawSamples(dx,dy, nbSamples);
+
+  if (datasType == "float") {
+    receivesize += sizeof(float);
+  } else if (datasType == "int8_t" || datasType == "uint8_t") {
+    receivesize += sizeof(int8_t);
+  } else if (datasType == "int16_t" || datasType == "uint16_t") {
+    receivesize += sizeof(int16_t);
+  } else {
+    printf("UsSensorPlot::unknown type %s\n",
+           datasType.toLocal8Bit().constData());
+  }
+  
+  firstPeakStart = new QwtPlotMarker();
+  QwtSymbol* s=new QwtSymbol( QwtSymbol::Diamond, Qt::blue, Qt::NoPen, QSize( 10, 10 ) );
+  firstPeakStart->setSymbol(s);
+  //firstPeakStart->setValue( QPointF( 1000, 200 ) );
+  //m->setLabel("toto" );
+  firstPeakStart->attach( plot );
+  
+  firstPeakEnd = new QwtPlotMarker();
+  //QwtSymbol* s=new QwtSymbol( QwtSymbol::Diamond, Qt::blue, Qt::NoPen, QSize( 10, 10 ) );
+  firstPeakEnd->setSymbol(s);
+  firstPeakEnd->attach( plot );
+  
+  secondPeakStart = new QwtPlotMarker();
+  secondPeakStart->setSymbol(s);
+  secondPeakStart->attach( plot );
+  
+  secondPeakEnd = new QwtPlotMarker();
+  secondPeakEnd->setSymbol(s);
+  secondPeakEnd->attach( plot );
+}
+
+UsSensorPlot::~UsSensorPlot() {
+  free(dx);
+  free(dy);
+}
+
+void UsSensorPlot::XmlEvent(QDomElement dom) {
+  XmlSetup(dom);
+}
+
+bool UsSensorPlot::eventFilter(QObject *o, QEvent *e) {
+  if (o == plot->canvas()) {
+    switch (e->type()) {
+    case QEvent::MouseButtonPress: {
+      mousePressEvent((QMouseEvent *)e);
+      break;
+    }
+
+    default:
+      break;
+    }
+  }
+  return plot->eventFilter(o, e);
+}
+
+void UsSensorPlot::setXAxisScale(float xmin, float xmax) {
+  xmin_orig = xmin;
+  xmax_orig = xmax;
+  plot->setAxisScale(QwtPlot::xBottom, xmin_orig, xmax_orig);
+}
+
+void UsSensorPlot::setYAxisScale(float ymin, float ymax) {
+  ymin_orig = ymin;
+  ymax_orig = ymax;
+  plot->setAxisScale(QwtPlot::yLeft, ymin_orig, ymax_orig);
+}
+
+//
+//  Set a plain canvas frame and align the scales to it
+//
+void UsSensorPlot::alignScales(void) {
+  // The code below shows how to align the scales to
+  // the canvas frame, but is also a good example demonstrating
+  // why the spreaded API needs polishing.
+  /*
+      plot->canvas()->setFrameStyle(QFrame::Box | QFrame::Plain );
+      plot->canvas()->setLineWidth(1);
+  */
+  for (int i = 0; i < QwtPlot::axisCnt; i++) {
+    QwtScaleWidget *scaleWidget = (QwtScaleWidget *)plot->axisWidget(i);
+    if (scaleWidget)
+      scaleWidget->setMargin(0);
+
+    QwtScaleDraw *scaleDraw = (QwtScaleDraw *)plot->axisScaleDraw(i);
+    if (scaleDraw)
+      scaleDraw->enableComponent(QwtAbstractScaleDraw::Backbone, false);
+  }
+}
+
+void UsSensorPlot::BufEvent(char **buf, int *buf_size, uint16_t period,bool big_endian) {
+  plot->setEnabled(IsEnabled());
+  if (IsEnabled() == false || RefreshRate_ms() != period)
+    return;
+
+  if (datasType == "float") {
+    float *data=(float*)*buf;
+    for (int i = 0; i < nbSamples; i++) {
+      dy[i]=data[i];
+    }
+    *buf += nbSamples*sizeof(float);
+  } else if (datasType == "int8_t") {
+    int8_t *data=(int8_t*)*buf;
+    for (int i = 0; i < nbSamples; i++) {
+      dy[i]=data[i];
+    }
+    *buf += nbSamples*sizeof(int8_t);
+   } else if (datasType == "uint8_t") {
+    uint8_t *data=(uint8_t*)*buf;
+    for (int i = 0; i < nbSamples; i++) {
+      dy[i]=data[i];
+    }
+    *buf += nbSamples*sizeof(uint8_t);
+  } else if (datasType == "int16_t") {
+    int16_t *data=(int16_t*)*buf;
+    for (int i = 0; i < nbSamples; i++) {
+      dy[i]=data[i];
+    }
+    *buf += nbSamples*sizeof(int16_t);
+  } else if (datasType == "uint16_t") {
+    uint16_t *data=(uint16_t*)*buf;
+    for (int i = 0; i < nbSamples; i++) {
+      dy[i]=data[i];
+    }
+    *buf += nbSamples*sizeof(uint16_t);
+  } else {
+    printf("UsSensorPlot::DrawDatas type non connu %s\n",datasType.toLocal8Bit().constData());
+  }
+  uint16_t *data=(uint16_t*)*buf;
+  *buf += 4*sizeof(uint16_t);
+  
+  firstPeakStart->setValue( QPointF( data[0], dy[data[0]] ) );
+  firstPeakEnd->setValue( QPointF( data[1], dy[data[1]] ) );
+  secondPeakStart->setValue( QPointF( data[2], dy[data[2]] ) );
+  secondPeakEnd->setValue( QPointF( data[3], dy[data[3]] ) );
+  
+  plot->replot();
+}
+
+
+// context menu
+void UsSensorPlot::mousePressEvent(QMouseEvent *event) {
+  if (event->button() == Qt::RightButton) {
+
+    QMenu *menu = new QMenu("nom", plot);
+    // ajout des actions
+    QAction *a, *z;
+
+    a = menu->addAction("reset zoom");
+    menu->addSeparator();
+
+
+    appendmenu(menu);
+    z = execmenu(plot, menu, event->globalPos());
+    delete menu;
+
+    if (z == a) {
+      // zoom to original size
+      plot->setAxisScale(QwtPlot::yLeft, ymin_orig, ymax_orig);
+      plot->setAxisScale(QwtPlot::xBottom, xmin_orig, xmax_orig);
+    }
+  }
+}
Index: /trunk/tools/FlairGCS/src/UsSensorPlot.h
===================================================================
--- /trunk/tools/FlairGCS/src/UsSensorPlot.h	(revision 221)
+++ /trunk/tools/FlairGCS/src/UsSensorPlot.h	(revision 221)
@@ -0,0 +1,50 @@
+// %flair:license{
+// This file is part of the Flair framework distributed under the
+// CECILL-C License, Version 1.0.
+// %flair:license}
+#ifndef USSENSORPLOT_H_INCLUDED
+#define USSENSORPLOT_H_INCLUDED
+
+#include "DataRemote.h"
+#include <stdint.h>
+#include <QPen>
+
+class Layout;
+class QwtPlot;
+class QwtPlotCurve;
+class QwtPlotItem;
+class QMouseEvent;
+class QwtPlotMarker;
+
+class UsSensorPlot : public DataRemote {
+  Q_OBJECT
+
+public:
+  UsSensorPlot(Layout *parent, int row, int col, QString plot_name,
+             QString y_name, float ymin,float ymax, uint32_t nbSamples,QString datasType,bool enabled, int period);
+  ~UsSensorPlot();
+
+protected:
+  void mousePressEvent(QMouseEvent *event);
+
+private:
+  QwtPlot *plot;
+  void XmlEvent(QDomElement dom);
+  void alignScales(void);
+  float xmin_orig, xmax_orig, ymin_orig, ymax_orig;
+
+  QwtPlotCurve *datas;
+  QwtPlotMarker *firstPeakStart,*firstPeakEnd,*secondPeakStart,*secondPeakEnd;
+  QString datasType;
+  bool datas_first_update;
+  double *dx;
+  double *dy;
+  uint32_t nbSamples;
+
+  bool eventFilter(QObject *, QEvent *);
+  void setYAxisScale(float ymin, float ymax);
+  void setXAxisScale(float xmin, float xmax);
+  void BufEvent(char **buf, int *buf_size, uint16_t period, bool big_endian);
+};
+
+#endif // USSENSORPLOT_H_INCLUDED
