source: flair-src/trunk/tools/FlairGCS/src/RangeFinderPlot.cpp

Last change on this file was 444, checked in by Sanahuja Guillaume, 12 days ago

update buffering (gcs part)
seems to work!

File size: 7.2 KB
Line 
1// %flair:license{
2// This file is part of the Flair framework distributed under the
3// CECILL-C License, Version 1.0.
4// %flair:license}
5#include "RangeFinderPlot.h"
6#include "Layout.h"
7#include <stdlib.h>
8#include <qwt_plot_grid.h>
9#include <qwt_plot_magnifier.h>
10#include <qwt_scale_widget.h>
11#include <qwt_plot_panner.h>
12#include <qwt_plot_rescaler.h>
13#include <qwt_plot_shapeitem.h>
14#include <QMouseEvent>
15#include <QMenu>
16#include <QInputDialog>
17#include <qendian.h>
18#include <qmath.h>
19
20RangeFinderPlot::RangeFinderPlot(Layout *parent, int row, int col, QString name,
21                                 QString x_name, QString y_name, float xmin,
22                                 float xmax, float ymin, float ymax,
23                                 float start_angle, float end_angle,
24                                 uint32_t nb_samples, QString data_type,
25                                 bool invert_axis, bool enabled, uint16_t period)
26    : DataRemote(name, "RangeFinderPlot", parent, enabled, period) {
27  invert_axis = true;
28  this->start_angle = start_angle;
29  this->end_angle = end_angle;
30  this->nb_samples = nb_samples;
31  this->data_type = data_type;
32  this->invert_axis = invert_axis;
33
34  if (data_type == "float") {
35    receivesize = nb_samples * sizeof(float);
36  } else if (data_type == "int8_t") {
37    receivesize = nb_samples * sizeof(int8_t);
38  } else if (data_type == "int16_t") {
39    receivesize = nb_samples * sizeof(int16_t);
40  } else {
41    fprintf(stderr,"RangeFinderPlot::RangeFinderPlot unknown type %s\n",
42           data_type.toLocal8Bit().constData());
43  }
44
45  plot = new QwtPlot(NULL);
46  plot->setEnabled(enabled);
47  // plot->setAutoReplot( false );
48
49  parent->addWidget(plot, row, col);
50  visible_widget = plot;
51
52  plot->setTitle(name);
53
54  // grid
55  QwtPlotGrid *grid = new QwtPlotGrid;
56  grid->setPen(QPen(Qt::black, 0, Qt::DotLine));
57  grid->attach(plot);
58
59  plot->updateAxes();
60
61  // zoomer
62  QwtPlotMagnifier *zoomer = new QwtPlotMagnifier(plot->canvas());
63  zoomer->setMouseButton(Qt::RightButton, Qt::ControlModifier);
64
65  // scroller
66  QwtPlotPanner *scroller = new QwtPlotPanner(plot->canvas());
67
68  // Axis
69  if (!invert_axis) {
70    plot->setAxisTitle(QwtPlot::xBottom, x_name);
71    setXAxisScale(xmin, xmax);
72
73    plot->setAxisTitle(QwtPlot::yLeft, y_name);
74    setYAxisScale(ymin, ymax);
75  } else {
76    plot->setAxisTitle(QwtPlot::xBottom, y_name);
77    setXAxisScale(ymin, ymax);
78
79    plot->setAxisTitle(QwtPlot::yLeft, x_name);
80    setYAxisScale(xmin, xmax);
81  }
82
83  QwtPlotRescaler *rescaler = new QwtPlotRescaler(plot->canvas());
84  rescaler->setRescalePolicy(QwtPlotRescaler::Fixed);
85
86  //( void ) new QwtPlotMagnifier( plot->canvas() );
87
88  plot->canvas()->installEventFilter(this);
89
90  for (uint32_t i = 0; i < nb_samples; i++) {
91    addTriangle(start_angle + i * (end_angle - start_angle + 1) / nb_samples,
92                start_angle +
93                    (i + 1) * (end_angle - start_angle + 1) / nb_samples);
94  }
95}
96
97RangeFinderPlot::~RangeFinderPlot() { delete plot; }
98
99void RangeFinderPlot::XmlEvent(QDomElement *dom) { XmlSetup(dom); }
100
101bool RangeFinderPlot::eventFilter(QObject *o, QEvent *e) {
102  if (o == plot->canvas()) {
103    switch (e->type()) {
104    case QEvent::MouseButtonPress: {
105      mousePressEvent((QMouseEvent *)e);
106      break;
107    }
108
109    default:
110      break;
111    }
112  }
113  return plot->eventFilter(o, e);
114}
115
116//
117//  Set a plain canvas frame and align the scales to it
118//
119void RangeFinderPlot::alignScales(void) {
120  // The code below shows how to align the scales to
121  // the canvas frame, but is also a good example demonstrating
122  // why the spreaded API needs polishing.
123  /*
124      plot->canvas()->setFrameStyle(QFrame::Box | QFrame::Plain );
125      plot->canvas()->setLineWidth(1);
126  */
127  for (int i = 0; i < QwtPlot::axisCnt; i++) {
128    QwtScaleWidget *scaleWidget = (QwtScaleWidget *)plot->axisWidget(i);
129    if (scaleWidget)
130      scaleWidget->setMargin(0);
131
132    QwtScaleDraw *scaleDraw = (QwtScaleDraw *)plot->axisScaleDraw(i);
133    if (scaleDraw)
134      scaleDraw->enableComponent(QwtAbstractScaleDraw::Backbone, false);
135  }
136}
137
138void RangeFinderPlot::setXAxisScale(float xmin, float xmax) {
139  xmin_orig = xmin;
140  xmax_orig = xmax;
141  plot->setAxisScale(QwtPlot::xBottom, xmin_orig, xmax_orig);
142}
143
144void RangeFinderPlot::setYAxisScale(float ymin, float ymax) {
145  ymin_orig = ymin;
146  ymax_orig = ymax;
147  plot->setAxisScale(QwtPlot::yLeft, ymin_orig, ymax_orig);
148}
149
150void RangeFinderPlot::BufEvent(char **buf, int *buf_size, uint16_t period,uint16_t nb_buffering,bool big_endian) {
151  plot->setEnabled(IsEnabled());
152 if (IsEnabled() == false || RefreshRate_ms() != period || NbBuffering()!=nb_buffering) return;
153
154  for (uint32_t i = 0; i < nb_samples; i++) {
155    if (data_type == "float") {
156      uint32_t data_raw;
157      float *data = (float *)&data_raw;
158
159      memcpy((void *)&data_raw, *buf, sizeof(uint32_t));
160      *buf += sizeof(uint32_t);
161      if (big_endian == true)
162        data_raw = qFromBigEndian(data_raw);
163      SetTriangle(i, *data);
164    } else if (data_type == "int8_t") {
165      int8_t data;
166      memcpy((void *)&data, *buf, sizeof(data));
167      *buf += sizeof(data);
168      SetTriangle(i, data);
169    } else if (data_type == "int16_t") {
170      int16_t data;
171      memcpy((void *)&data, *buf, sizeof(data));
172      *buf += sizeof(data);
173      if (big_endian == true)
174        data = qFromBigEndian(data);
175      SetTriangle(i, data);
176    } else {
177      fprintf(stderr,"RangeFinderPlot::BufEvent unknown type %s\n",
178             data_type.toLocal8Bit().constData());
179    }
180  }
181
182  plot->replot();
183}
184
185void RangeFinderPlot::addTriangle(float angle_min, float angle_max) {
186  QwtPlotShapeItem *item = new QwtPlotShapeItem();
187
188  item->setRenderHint(QwtPlotItem::RenderAntialiased, true);
189  item->attach(plot);
190  triangles.append(item);
191}
192
193void RangeFinderPlot::SetTriangle(uint32_t id, float length) {
194  QPainterPath path;
195  QPolygonF triangle;
196  float angle_min =
197      start_angle + id * (end_angle - start_angle + 1) / nb_samples;
198  float angle_max =
199      start_angle + (id + 1) * (end_angle - start_angle + 1) / nb_samples;
200
201  if (invert_axis) {
202    angle_min = 90 - angle_min;
203    angle_max = 90 - angle_max;
204  }
205
206  triangle += QPointF(0, 0);
207  triangle += QPointF(length * cos(angle_min * M_PI / 180.),
208                      length * sin(angle_min * M_PI / 180.));
209  triangle += QPointF(length * cos(angle_max * M_PI / 180.),
210                      length * sin(angle_max * M_PI / 180.));
211
212  path.addPolygon(triangle);
213
214  path.closeSubpath();
215  triangles.at(id)->setShape(path);
216
217  QColor fillColor = "SandyBrown";
218  fillColor.setAlpha(200);
219
220  QPen pen(QColor("SandyBrown"), 1);
221  pen.setJoinStyle(Qt::MiterJoin);
222  triangles.at(id)->setPen(pen);
223  triangles.at(id)->setBrush(fillColor);
224}
225
226// context menu
227void RangeFinderPlot::mousePressEvent(QMouseEvent *event) {
228  if (event->button() == Qt::RightButton) {
229    QMenu *menu = new QMenu("nom", plot);
230    // ajout des actions
231    QAction *a, *z;
232
233    a = menu->addAction("reset y zoom");
234
235    appendmenu(menu);
236    z = execmenu(plot, menu, event->globalPos());
237    delete menu;
238
239    if (z == a) {
240      // zoom to original size
241      if (!invert_axis) {
242        plot->setAxisScale(QwtPlot::yLeft, ymin_orig, ymax_orig);
243      } else {
244        plot->setAxisScale(QwtPlot::yLeft, xmin_orig, xmax_orig);
245      }
246      plot->replot();
247    }
248  }
249}
Note: See TracBrowser for help on using the repository browser.