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

Last change on this file since 416 was 269, checked in by Sanahuja Guillaume, 6 years ago

flairgcs:
speed up processing time when receiving datas from uav
triger watchdog while receiving datas from uav
(avoids connection lost in uav)

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, int 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,
151 bool big_endian) {
152 plot->setEnabled(IsEnabled());
153 if (IsEnabled() == false || RefreshRate_ms() != period)
154 return;
155
156 for (uint32_t i = 0; i < nb_samples; i++) {
157 if (data_type == "float") {
158 uint32_t data_raw;
159 float *data = (float *)&data_raw;
160
161 memcpy((void *)&data_raw, *buf, sizeof(uint32_t));
162 *buf += sizeof(uint32_t);
163 if (big_endian == true)
164 data_raw = qFromBigEndian(data_raw);
165 SetTriangle(i, *data);
166 } else if (data_type == "int8_t") {
167 int8_t data;
168 memcpy((void *)&data, *buf, sizeof(data));
169 *buf += sizeof(data);
170 SetTriangle(i, data);
171 } else if (data_type == "int16_t") {
172 int16_t data;
173 memcpy((void *)&data, *buf, sizeof(data));
174 *buf += sizeof(data);
175 if (big_endian == true)
176 data = qFromBigEndian(data);
177 SetTriangle(i, data);
178 } else {
179 fprintf(stderr,"RangeFinderPlot::BufEvent unknown type %s\n",
180 data_type.toLocal8Bit().constData());
181 }
182 }
183
184 plot->replot();
185}
186
187void RangeFinderPlot::addTriangle(float angle_min, float angle_max) {
188 QwtPlotShapeItem *item = new QwtPlotShapeItem();
189
190 item->setRenderHint(QwtPlotItem::RenderAntialiased, true);
191 item->attach(plot);
192 triangles.append(item);
193}
194
195void RangeFinderPlot::SetTriangle(uint32_t id, float length) {
196 QPainterPath path;
197 QPolygonF triangle;
198 float angle_min =
199 start_angle + id * (end_angle - start_angle + 1) / nb_samples;
200 float angle_max =
201 start_angle + (id + 1) * (end_angle - start_angle + 1) / nb_samples;
202
203 if (invert_axis) {
204 angle_min = 90 - angle_min;
205 angle_max = 90 - angle_max;
206 }
207
208 triangle += QPointF(0, 0);
209 triangle += QPointF(length * cos(angle_min * M_PI / 180.),
210 length * sin(angle_min * M_PI / 180.));
211 triangle += QPointF(length * cos(angle_max * M_PI / 180.),
212 length * sin(angle_max * M_PI / 180.));
213
214 path.addPolygon(triangle);
215
216 path.closeSubpath();
217 triangles.at(id)->setShape(path);
218
219 QColor fillColor = "SandyBrown";
220 fillColor.setAlpha(200);
221
222 QPen pen(QColor("SandyBrown"), 1);
223 pen.setJoinStyle(Qt::MiterJoin);
224 triangles.at(id)->setPen(pen);
225 triangles.at(id)->setBrush(fillColor);
226}
227
228// context menu
229void RangeFinderPlot::mousePressEvent(QMouseEvent *event) {
230 if (event->button() == Qt::RightButton) {
231 QMenu *menu = new QMenu("nom", plot);
232 // ajout des actions
233 QAction *a, *z;
234
235 a = menu->addAction("reset y zoom");
236
237 appendmenu(menu);
238 z = execmenu(plot, menu, event->globalPos());
239 delete menu;
240
241 if (z == a) {
242 // zoom to original size
243 if (!invert_axis) {
244 plot->setAxisScale(QwtPlot::yLeft, ymin_orig, ymax_orig);
245 } else {
246 plot->setAxisScale(QwtPlot::yLeft, xmin_orig, xmax_orig);
247 }
248 plot->replot();
249 }
250 }
251}
Note: See TracBrowser for help on using the repository browser.