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

Last change on this file was 444, checked in by Sanahuja Guillaume, 15 months 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.