347 lines
10 KiB
C++
347 lines
10 KiB
C++
#include "rm_graph_widget.h"
|
|
|
|
//#include "../module/qcustomplot.h"
|
|
#include "../data/rm_video_item_2ch.h"
|
|
#include "../data/rm_sensordata.h"
|
|
#include "../core/rm_player.h"
|
|
#include <QStyleOption>
|
|
#include <QPaintEvent>
|
|
|
|
#include <math.h>
|
|
#include "../core/rm_player.h"
|
|
#include "fm_colors.h"
|
|
|
|
// http://qcustomplot.com/index.php/tutorials/userinteractions
|
|
|
|
//const double minRange = -4.0;
|
|
//const double maxRange = 4.0;
|
|
//const double miniumRange = 0.5;
|
|
//const double initialRange = 2.0; // 초기 시작
|
|
|
|
//const int plot_icon_width = 13;
|
|
|
|
|
|
RMGraphWidget::RMGraphWidget(QWidget *parent,QList<int> scales) : QWidget(parent)
|
|
{
|
|
currentData = NULL;
|
|
_scales = scales;
|
|
_currentScale = 4;
|
|
_cursorX = -1;
|
|
|
|
//setObjectName("graph_widget");
|
|
|
|
connect(RMPlayer::instance(),SIGNAL(positionChanged(qint64,qint64)),SLOT(onPositionChanged(qint64,qint64)));
|
|
connect(RMPlayer::instance(),SIGNAL(playEvent(PLAY_EVENT,RMVideoItem*)),SLOT(onPlayEvent(PLAY_EVENT,RMVideoItem*)));
|
|
labelX = NULL;
|
|
labelY = NULL;
|
|
labelZ = NULL;
|
|
|
|
#if (USE_TRIGGER)
|
|
eTrigger = QPixmap(":/image/icon_plot_e.png");
|
|
mTrigger = QPixmap(":/image/icon_plot_m.png");
|
|
#endif // USE_TRIGGER
|
|
}
|
|
#if (MODEL_STANDARD)
|
|
void RMGraphWidget::onZoomOut()
|
|
{
|
|
if (_scales.isEmpty() ||_scales.last() == _currentScale) {
|
|
return;
|
|
}
|
|
int index = _scales.indexOf(_currentScale) + 1;
|
|
_currentScale = _scales[index];
|
|
_updatePolygon();
|
|
|
|
qInfo() << _currentScale << __FUNCTION__;
|
|
// 1(first) 일 경우
|
|
emit zoomChange(true,_currentScale != _scales.last());
|
|
}
|
|
void RMGraphWidget::onZoomIn()
|
|
{
|
|
// 스케일을 늘린다-> 실제 scale 값은 축소
|
|
if (_scales.isEmpty() ||_scales.first() == _currentScale) {
|
|
return;
|
|
}
|
|
int index = _scales.indexOf(_currentScale) - 1;
|
|
_currentScale = _scales[index];
|
|
_updatePolygon();
|
|
qInfo() << _currentScale << __FUNCTION__;
|
|
emit zoomChange(_scales.first() != _currentScale,true);
|
|
}
|
|
#endif
|
|
float RMGraphWidget::_transform(float value, float height)
|
|
{
|
|
#if (RM_MODEL == RM_MODEL_TYPE_NX_DRW22 || \
|
|
RM_MODEL == RM_MODEL_TYPE_BV2000 || \
|
|
RM_MODEL == RM_MODEL_TYPE_XLDR_88 || \
|
|
RM_MODEL == RM_MODEL_TYPE_KEIYO1 || \
|
|
RM_MODEL == RM_MODEL_TYPE_MBJ5010 || \
|
|
RM_MODEL == RM_MODEL_TYPE_FC_DR232W || \
|
|
RM_MODEL == RM_MODEL_TYPE_MH9000 || \
|
|
RM_MODEL_EMT_KR || \
|
|
RM_MODEL == RM_MODEL_TYPE_TBD360)
|
|
// 0~
|
|
#if (RM_MODEL == RM_MODEL_TYPE_XLDR_88 )
|
|
const float scale = (float)4.0 / _currentScale;
|
|
const float oldRange = 8.0;// -1.0 ~ 1.0
|
|
const float oldMin = -4.0;
|
|
#elif (RM_MODEL_EMT_KR)
|
|
const float scale = (float)8.0 / _currentScale;
|
|
const float oldRange = 4.0;// -1.0 ~ 1.0
|
|
const float oldMin = -2.0;
|
|
#else
|
|
const float scale = (float)4.0 / _currentScale;
|
|
const float oldRange = 4.0;// -1.0 ~ 1.0
|
|
const float oldMin = -2.0;
|
|
#endif
|
|
|
|
const float newMax = height * scale;
|
|
const float newMin = height - (scale * height);
|
|
const float newRange = newMax - newMin;
|
|
|
|
const float nv = ((((value - (oldMin)) * newRange) / oldRange) + newMin);
|
|
// NewValue = (((OldValue - OldMin) * NewRange) / OldRange) + NewMin
|
|
#elif (RM_MODEL == RM_MODEL_TYPE_ADT_CAPS)
|
|
const float scale = (float)4.0 / _currentScale * 2.0;
|
|
const float oldRange = 1.0;// -1.0 ~ 1.0
|
|
const float oldMin = 0.0;
|
|
|
|
const float newMax = height * scale;
|
|
const float newMin = 10;//height - (scale * height);
|
|
const float newRange = newMax - newMin;
|
|
|
|
const float nv = ((((value - (oldMin)) * newRange) / oldRange) + newMin);
|
|
#else
|
|
//#pragma warning (GRAPH SCALE NOT FIEXED)
|
|
const float nv = 0;
|
|
#endif
|
|
return height - nv;
|
|
}
|
|
|
|
void RMGraphWidget::_updatePolygon()
|
|
{
|
|
if(currentData == NULL) {
|
|
update();
|
|
return;
|
|
}
|
|
_polygonX.clear();
|
|
_polygonY.clear();
|
|
_polygonZ.clear();
|
|
|
|
double w = size().width();
|
|
double h = size().height();
|
|
|
|
//qInfo() << "Height:" << h;
|
|
// const double hh = h / 2.0;
|
|
|
|
uint32_t count = currentData->getSensorCount(); // X축 레인지 설정
|
|
#if (RM_MODEL_EMT_KR)
|
|
const NMEA_INFO* sensorValues = currentData->getSensor();
|
|
const float xOffset = w / (double)count;
|
|
for (uint32_t i=0; i<count; ++i)
|
|
{
|
|
float xy = _transform(sensorValues[i].x,h);
|
|
float yy = _transform(sensorValues[i].y,h);
|
|
float zy = _transform(sensorValues[i].z,h);
|
|
|
|
_polygonX.push_back(QPointF(xOffset * (double)i,xy));
|
|
_polygonY.push_back(QPointF(xOffset * (double)i,yy));
|
|
_polygonZ.push_back(QPointF(xOffset * (double)i,zy));
|
|
}
|
|
#else // RM_MODEL_EMT_KR
|
|
const float* sensorValues = currentData->getSensor();
|
|
const float xOffset = w / (double)count;
|
|
for (uint32_t i=0; i<count; ++i)
|
|
{
|
|
// 0 = h / 2.0;
|
|
|
|
float xy = _transform(sensorValues[(i * NUM_SENSOR_DATA) + 0],h);
|
|
float yy = _transform(sensorValues[(i * NUM_SENSOR_DATA) + 1],h);
|
|
float zy = _transform(sensorValues[(i * NUM_SENSOR_DATA) + 2],h);
|
|
|
|
_polygonX.push_back(QPointF(xOffset * (double)i,xy));
|
|
_polygonY.push_back(QPointF(xOffset * (double)i,yy));
|
|
_polygonZ.push_back(QPointF(xOffset * (double)i,zy));
|
|
}
|
|
#endif // RM_MODEL_EMT_KR
|
|
update();
|
|
}
|
|
void RMGraphWidget::redraw()
|
|
{
|
|
_updatePolygon();
|
|
}
|
|
void RMGraphWidget::onPlayEvent(PLAY_EVENT event,RMVideoItem* item)
|
|
{
|
|
if(event == PLAY_DID_LOADED)
|
|
{
|
|
_cursorX = -1;
|
|
if(item != NULL) {
|
|
currentData = item->getSensorData();
|
|
}
|
|
_updatePolygon();
|
|
_itemDurationMSec = (double)item->durationInMSecs();
|
|
}
|
|
else if(event == PLAY_DID_CLEARED)
|
|
{
|
|
_cursorX = -1;
|
|
currentData= NULL;
|
|
_polygonX.clear();
|
|
_polygonY.clear();
|
|
_polygonZ.clear();
|
|
update();
|
|
if(labelX != NULL) {
|
|
labelX->setText(" 0.00");
|
|
labelY->setText(" 0.00");
|
|
labelZ->setText(" 0.00");
|
|
}
|
|
}
|
|
|
|
}
|
|
void RMGraphWidget::setLabels(QLabel*x,QLabel*y,QLabel*z)
|
|
{
|
|
labelX = x;
|
|
labelY = y;
|
|
labelZ = z;
|
|
}
|
|
|
|
void RMGraphWidget::onPositionChanged(qint64 position,qint64 duration)
|
|
{
|
|
if(currentData == NULL) {
|
|
return;
|
|
}
|
|
|
|
double pos = (double)MIN(position,duration);
|
|
double du = ((double)(duration));
|
|
|
|
// 센서 값과 유사하게 표시하기위해 보정
|
|
//const double tolerance = 50.0;
|
|
|
|
// 실제 시간과 seek duration 보정
|
|
//double pos2 = (pos + tolerance) * (_itemDurationMSec / du);
|
|
double pos2 = pos;
|
|
|
|
int cursor = (int)(pos2 / du * ((double)size().width()));
|
|
if(_cursorX != cursor) {
|
|
_cursorX = cursor;
|
|
update();
|
|
}
|
|
|
|
if(labelX != NULL) {
|
|
unsigned int offset = (unsigned int)(((double)pos2) / ((double)du) * ((double)currentData->getSensorCount()) );
|
|
|
|
if(offset < currentData->getSensorCount())
|
|
{
|
|
#if (RM_MODEL_EMT_KR)
|
|
const NMEA_INFO* sensorValues = currentData->getSensor();
|
|
const float x = sensorValues[offset].x;
|
|
const float y = sensorValues[offset].y;
|
|
const float z = sensorValues[offset].z;
|
|
#else // RM_MODEL_EMT_KR
|
|
const float* sensorValues = currentData->getSensor();
|
|
const float x = sensorValues[(offset * NUM_SENSOR_DATA) + 0];
|
|
const float y = sensorValues[(offset * NUM_SENSOR_DATA) + 1];
|
|
const float z = sensorValues[(offset * NUM_SENSOR_DATA) + 2];
|
|
#endif // RM_MODEL_EMT_KR
|
|
if(labelX != NULL)
|
|
{
|
|
labelX->setText(QString().sprintf("% .2f",x));
|
|
}
|
|
if(labelY != NULL)
|
|
{
|
|
labelY->setText(QString().sprintf("% .2f",y));
|
|
}
|
|
if(labelZ != NULL)
|
|
{
|
|
labelZ->setText(QString().sprintf("% .2f",z));
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
}
|
|
// subclassing 할 경우 무조건 구현해야함.
|
|
void RMGraphWidget::paintEvent(QPaintEvent *pe)
|
|
{
|
|
Q_UNUSED(pe);
|
|
QPainter painter(this);
|
|
|
|
//painter.setRenderHint(QPainter::Antialiasing);
|
|
|
|
// Round Box
|
|
QPainterPath path;
|
|
path.addRoundedRect(rect(), 3, 3);
|
|
painter.fillPath(path, QColor(FM_GRAPH_BACK_COLOR)); // QColor("#595959")
|
|
|
|
int xmargin = 3;
|
|
int ymargin = 8;
|
|
QRect r = rect();
|
|
r.adjust(xmargin,ymargin,-xmargin,-ymargin);
|
|
|
|
painter.setPen(QPen(QColor(FM_GRAPH_LINE_COLOR),1, Qt::SolidLine));
|
|
// outer line
|
|
painter.drawRect(r);
|
|
|
|
// h-center line
|
|
//painter.drawLine(r.left(),r.center().y(),r.right(),r.center().y());
|
|
|
|
//int yCount = _scales.length();
|
|
// 1,2,4
|
|
int h = (r.height()/2)/_currentScale;
|
|
int count = r.height() / h;
|
|
for(int i=1;i<count;i++) {
|
|
int y = r.top() + (h * i);
|
|
painter.drawLine(r.left(),y,r.right(),y);
|
|
}
|
|
|
|
// v-center line
|
|
int x = r.center().x();
|
|
painter.drawLine(x,r.top(),x,r.bottom());
|
|
x = r.left() + r.width()/4;
|
|
painter.drawLine(x,r.top(),x,r.bottom());
|
|
x = r.left() + r.width()/4*3;
|
|
painter.drawLine(x,r.top(),x,r.bottom());
|
|
|
|
|
|
if (_polygonX.count() > 0)
|
|
{
|
|
// "#c6f606"
|
|
QPen xPen(FM_QCOLOR(FM_SENSOR_COLOR_X), 1, Qt::SolidLine);
|
|
painter.setPen(xPen);
|
|
painter.drawPolyline(_polygonX);
|
|
|
|
QPen yPen(FM_QCOLOR(FM_SENSOR_COLOR_Y), 1, Qt::SolidLine);
|
|
painter.setPen(yPen);
|
|
painter.drawPolyline(_polygonY);
|
|
|
|
QPen zPen(FM_QCOLOR(FM_SENSOR_COLOR_Z), 1, Qt::SolidLine);
|
|
painter.setPen(zPen);
|
|
painter.drawPolyline(_polygonZ);
|
|
|
|
|
|
}
|
|
|
|
if(_cursorX >= 0){
|
|
QPen cursorPen(QColor(0xFFFFFF), 1, Qt::SolidLine); // QColor("#FFFFFF")
|
|
painter.setPen(cursorPen);
|
|
painter.drawLine(_cursorX,0,_cursorX,size().height());
|
|
}
|
|
#if (USE_TRIGGER)
|
|
if(currentData!= NULL) {
|
|
if(currentData->triggerE >= 0.0f) {
|
|
QSize ss = rect().size();
|
|
int x = (int)(((float)ss.width()) * currentData->triggerE) - (eTrigger.size().width() / 2);
|
|
int y = ss.height() - eTrigger.size().height();
|
|
painter.drawPixmap(x, y, eTrigger);
|
|
}
|
|
if(currentData->triggerM >= 0.0f) {
|
|
QSize ss = rect().size();
|
|
int x = (int)(((float)ss.width()) * currentData->triggerM) - (mTrigger.size().width() / 2);
|
|
int y = ss.height() - eTrigger.size().height();
|
|
painter.drawPixmap(x, y, mTrigger);
|
|
}
|
|
}
|
|
#endif // #if (USE_TRIGGER)
|
|
painter.end();
|
|
|
|
}
|
|
|