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

Last change on this file since 10 was 10, checked in by Sanahuja Guillaume, 5 years ago

lic

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