Skip to content

Commit fa635b1

Browse files
author
qinanhong
committedDec 21, 2018
commit
0 parents  commit fa635b1

25 files changed

+3482
-0
lines changed
 

‎Drones.pro

+46
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
#-------------------------------------------------
2+
#
3+
# Project created by QtCreator 2016-06-24T09:26:30
4+
#
5+
#-------------------------------------------------
6+
7+
QT += core \
8+
gui \
9+
charts \
10+
sql \
11+
12+
!MobileBuild {4
13+
QT += \
14+
printsupport \
15+
}
16+
17+
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
18+
19+
TARGET = Drones
20+
TEMPLATE = app
21+
22+
SOURCES += main.cpp\
23+
mainwindow.cpp \
24+
LogDisplay/LogWidget.cpp \
25+
LogDisplay/Callout.cpp \
26+
QuadApplication.cpp \
27+
LogDisplay/chartView.cpp \
28+
LogDisplay/LogAnalysis.cpp
29+
30+
31+
HEADERS += mainwindow.h \
32+
LogDisplay/basic_types.h \
33+
LogDisplay/messages.h \
34+
LogDisplay/sdfiles.h \
35+
LogDisplay/LogAnalysis.h \
36+
LogDisplay/chartView.h \
37+
LogDisplay/LogWidget.h \
38+
LogDisplay/Callout.h \
39+
QuadApplication.h
40+
41+
FORMS += mainwindow.ui \
42+
LogWidget.ui
43+
44+
UI_DIR += E:/baseModule-12.21
45+
46+

‎Drones.pro.user

+318
Large diffs are not rendered by default.

‎Log.TXT

21.6 KB
Binary file not shown.

‎LogDisplay/Callout.cpp

+114
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
#include "Callout.h"
2+
#include <QtGui/QPainter>
3+
#include <QtGui/QFontMetrics>
4+
#include <QtWidgets/QGraphicsSceneMouseEvent>
5+
#include <QtGui/QMouseEvent>
6+
#include <QtCharts/QChart>
7+
8+
Callout::Callout(QChart *chart)
9+
: QGraphicsItem(chart),
10+
_chart(chart)
11+
{
12+
13+
}
14+
15+
QRectF Callout::boundingRect() const
16+
{
17+
QPointF anchor = mapFromParent(_chart->mapToPosition(_anchor));
18+
QRectF rect;
19+
rect.setLeft(qMin(_rect.left(), anchor.x()));
20+
rect.setRight(qMax(_rect.right(), anchor.x()));
21+
rect.setTop(qMin(_rect.top(), anchor.y()));
22+
rect.setBottom(qMax(_rect.bottom(), anchor.y()));
23+
return rect;
24+
}
25+
26+
void Callout::mouseMoveEvent(QGraphicsSceneMouseEvent* event)
27+
{
28+
event->setAccepted(true);
29+
/* if (event->buttons() & Qt::LeftButton){
30+
setPos(mapToParent(event->pos() - event->buttonDownPos(Qt::LeftButton)));
31+
event->setAccepted(true);
32+
} else {
33+
event->setAccepted(false);
34+
}
35+
*/
36+
}
37+
38+
void Callout::mousePressEvent(QGraphicsSceneMouseEvent *event)
39+
{
40+
event->setAccepted(true);
41+
}
42+
43+
void Callout::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
44+
{
45+
Q_UNUSED(option)
46+
Q_UNUSED(widget)
47+
QPainterPath path;
48+
path.addRoundedRect(_rect, 5, 5);
49+
50+
QPointF anchor = mapFromParent(_chart->mapToPosition(_anchor));
51+
52+
//qDebug()<<"anchor"<<anchor;
53+
54+
if (!_rect.contains(anchor)) {
55+
QPointF point1, point2;
56+
57+
// establish the position of the anchor point in relation to _rect
58+
bool above = anchor.y() <= _rect.top();
59+
bool aboveCenter = anchor.y() > _rect.top() && anchor.y() <= _rect.center().y();
60+
bool belowCenter = anchor.y() > _rect.center().y() && anchor.y() <= _rect.bottom();
61+
bool below = anchor.y() > _rect.bottom();
62+
63+
bool onLeft = anchor.x() <= _rect.left();
64+
bool leftOfCenter = anchor.x() > _rect.left() && anchor.x() <= _rect.center().x();
65+
bool rightOfCenter = anchor.x() > _rect.center().x() && anchor.x() <= _rect.right();
66+
bool onRight = anchor.x() > _rect.right();
67+
68+
// get the nearest _rect corner.
69+
qreal x = (onRight + rightOfCenter) * _rect.width();
70+
qreal y = (below + belowCenter) * _rect.height();
71+
bool cornerCase = (above && onLeft) || (above && onRight) || (below && onLeft) || (below && onRight);
72+
bool vertical = qAbs(anchor.x() - x) > qAbs(anchor.y() - y);
73+
74+
qreal x1 = x + leftOfCenter * 10 - rightOfCenter * 20 + cornerCase * !vertical * (onLeft * 10 - onRight * 20);
75+
qreal y1 = y + aboveCenter * 10 - belowCenter * 20 + cornerCase * vertical * (above * 10 - below * 20);;
76+
point1.setX(x1);
77+
point1.setY(y1);
78+
79+
qreal x2 = x + leftOfCenter * 20 - rightOfCenter * 10 + cornerCase * !vertical * (onLeft * 20 - onRight * 10);;
80+
qreal y2 = y + aboveCenter * 20 - belowCenter * 10 + cornerCase * vertical * (above * 20 - below * 10);;
81+
point2.setX(x2);
82+
point2.setY(y2);
83+
84+
path.moveTo(point1);
85+
path.lineTo(anchor);
86+
path.lineTo(point2);
87+
path = path.simplified();
88+
}
89+
90+
painter->setBrush(QColor(255, 255, 255));
91+
painter->drawPath(path);
92+
painter->drawText(_textRect, _text);
93+
}
94+
95+
void Callout::setText(const QString &text)
96+
{
97+
_text = text;
98+
}
99+
100+
void Callout::setAnchor(QPointF point)
101+
{
102+
_anchor = point;
103+
QFontMetrics metrics(_font);
104+
_textRect = metrics.boundingRect(QRect(0, 0, 150, 150), Qt::AlignLeft, _text);
105+
_textRect.translate(5, 5);
106+
prepareGeometryChange();
107+
_rect = _textRect.adjusted(-5, -5, 5, 5);
108+
}
109+
110+
void Callout::updateGeometry()
111+
{
112+
prepareGeometryChange();
113+
setPos(_chart->mapToPosition(_anchor) + QPoint(10, -50));
114+
}

‎LogDisplay/Callout.h

+45
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
#ifndef CALLOUT_H
2+
#define CALLOUT_H
3+
4+
/**
5+
* Tooltip box, display data of point when mouse is hovering on the line series
6+
**/
7+
#include <QGraphicsItem>
8+
#include <QtCharts>
9+
#include <QtCharts/QChartGlobal>
10+
#include <QtWidgets/QGraphicsItem>
11+
#include <QtGui/QFont>
12+
13+
using namespace QtCharts;
14+
15+
QT_BEGIN_NAMESPACE
16+
class QGraphicsSceneMouseEvent;
17+
QT_END_NAMESPACE
18+
19+
QT_CHARTS_USE_NAMESPACE
20+
21+
class Callout : public QGraphicsItem
22+
{
23+
public:
24+
Callout(QChart* chart);
25+
void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);
26+
void setText(const QString &text);
27+
void setAnchor(QPointF point);
28+
void updateGeometry();
29+
30+
protected:
31+
QRectF boundingRect() const;
32+
void mouseMoveEvent(QGraphicsSceneMouseEvent* event);
33+
void mousePressEvent(QGraphicsSceneMouseEvent *event);
34+
35+
private:
36+
QChart* _chart;
37+
QString _text;
38+
39+
QRectF _textRect;
40+
QRectF _rect;
41+
QPointF _anchor;
42+
QFont _font;
43+
};
44+
45+
#endif // CALLOUT_H

‎LogDisplay/LogAnalysis.cpp

+366
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,366 @@
1+
#include "LogAnalysis.h"
2+
//#include "dataconnection.h"
3+
4+
#include <QFile>
5+
#include <QFileDialog>
6+
#include <QSqlError>
7+
#include <QDebug>
8+
#include <QSqlQuery>
9+
#include <QMessageBox>
10+
11+
LogAnalysis::LogAnalysis(QWidget *parent) :
12+
QWidget(parent)
13+
{
14+
_creatConnection();
15+
}
16+
17+
bool LogAnalysis::_creatConnection()
18+
{
19+
db = QSqlDatabase::addDatabase("QSQLITE");
20+
db.setDatabaseName("LogData.db");
21+
22+
if(!db.open()) {
23+
qDebug()<<db.lastError();
24+
qFatal("Fail to connect");
25+
return false;
26+
}
27+
28+
//db.transaction();
29+
30+
//create database table
31+
QSqlQuery query(db);
32+
33+
query.exec("create table Mode (timestamp int primary key,"
34+
"mode int)");
35+
36+
query.exec("create table FlightStatus (timestamp int primary key,"
37+
"flightStatus int)");
38+
39+
query.exec("create table Baro (timestamp int primary key,"
40+
"temperature float,"
41+
"altitude float)");
42+
43+
query.exec("create table IMU (timestamp int primary key,"
44+
"acc_x float,"
45+
"acc_y float,"
46+
"acc_z float,"
47+
"gyro_x float,"
48+
"gyro_y float,"
49+
"gyro_z float,"
50+
"mag_x float,"
51+
"mag_y float,"
52+
"mag_z float)");
53+
54+
query.exec("create table GPS (timestamp int primary key,"
55+
"lat int,"
56+
"lon int,"
57+
"azm float,"
58+
"vel float,"
59+
"alt float,"
60+
"sat int,"
61+
"date int,"
62+
"time int)");
63+
64+
query.exec("create table RC (timestamp int primary key,"
65+
"ch1 float,"
66+
"ch2 float,"
67+
"ch3 float,"
68+
"ch4 float,"
69+
"ch5 float,"
70+
"ch6 float,"
71+
"ch7 float,"
72+
"ch8 float,"
73+
"ch9 float,"
74+
"ch10 float,"
75+
"ch11 float,"
76+
"ch12 float,"
77+
"ch13 float,"
78+
"ch14 float,"
79+
"ch15 float,"
80+
"ch16 float)");
81+
82+
query.exec("create table Battery_Info (timestamp int primary key,"
83+
"voltage float,"
84+
"battery_remaining float)");
85+
86+
/*query.exec("create table Attitude_Setpoint (timestamp int primary key,"
87+
"thrust float,"
88+
"yaw_ff float)");
89+
*/
90+
91+
query.exec("create table Attitude (timestamp int primary key,"
92+
"rate_x float,"
93+
"rate_y float,"
94+
"rate_z float,"
95+
"euler_R float,"
96+
"euler_P float,"
97+
"euler_Y float)");
98+
99+
query.exec("create table Manual_Setpoint (timestamp int primary key,"
100+
"throttle float,"
101+
"euler_R float,"
102+
"euler_P float,"
103+
"euler_Y float)");
104+
105+
query.exec("create table PosCtrl_Setpoint (timestamp int primary key,"
106+
"position_setpoint_x float,"
107+
"position_setpoint_y float,"
108+
"position_setpoint_z float,"
109+
"vel_ff_x float,"
110+
"vel_ff_y float,"
111+
"vel_ff_z float,"
112+
"acc_ff_x float,"
113+
"acc_ff_y float,"
114+
"acc_ff_z float,"
115+
"yaw_setpoint float)");
116+
117+
query.exec("create table AltCtrl_Setpoint (timestamp int primary key,"
118+
"pos_sp_z float,"
119+
"vel_ff_z float,"
120+
"euler_R float,"
121+
"euler_P float,"
122+
"euler_Y float)");
123+
124+
query.exec("create table Position (timestamp int primary key,"
125+
"pos_x float,"
126+
"pos_y float,"
127+
"pos_z float,"
128+
"vel_x float,"
129+
"vel_y float,"
130+
"vel_z float,"
131+
"acc_x float,"
132+
"acc_y float,"
133+
"acc_z float)");
134+
135+
return true;
136+
}
137+
138+
void LogAnalysis::logReadAndStore()
139+
{
140+
/**/
141+
db.transaction();
142+
143+
QStringList tables = db.tables();
144+
QSqlQuery query(db);
145+
for(int i = 0;i<tables.count();i++) {
146+
QString truncateString = QString("truncate table %1").arg(tables.at(i));
147+
//qDebug()<<truncateString;
148+
query.exec(truncateString);
149+
}
150+
151+
QString fileName = QFileDialog::getOpenFileName(this,"Open File",".\\","texFile(*.txt *.bin)");
152+
QFile file(fileName);
153+
154+
if(fileName.isNull()) {
155+
QMessageBox::information(this,"Document","No document selected.",QMessageBox::Ok | QMessageBox::Cancel);
156+
emit openFileStatusChanged(false);
157+
}
158+
else {
159+
emit openFileStatusChanged(true);
160+
QByteArray b;
161+
QList<QByteArray> arrayList;
162+
if(!file.open(QIODevice::ReadOnly)) {
163+
qDebug()<<"can't open";
164+
return;
165+
}
166+
else {
167+
// 用"\r\n"即0d0a分行,每一行存储一个数据结构,见sdfiles.h
168+
b = file.readAll();
169+
QByteArray turn("\r\n",2);
170+
int len = turn.length();
171+
int start = 0;
172+
int end = b.indexOf(turn,start);
173+
while(end != -1) {
174+
arrayList<<b.mid(start,(end-start));
175+
start = end + len;
176+
end = b.indexOf(turn,start);
177+
}
178+
qDebug()<<arrayList.count();
179+
}
180+
181+
for(int i = 0;i<arrayList.size();i++) {
182+
//读取每一行的数据
183+
const char* logData = arrayList.at(i).data();
184+
//第一个字节为message_id
185+
// qDebug()<<QString::number(*logData);
186+
//QSqlQuery query(db);
187+
188+
switch(*logData) {
189+
case 0:
190+
{
191+
mode_log_t* mode_log = (mode_log_t*)logData;
192+
mode_t mode =mode_log->mode_log_s;
193+
QString queryString = QString("insert into Mode values(%1,%2)").arg(mode_log->timestamp).arg(mode);
194+
query.exec(queryString);
195+
196+
//mode_log_t* mode_log = (mode_log_t*)logData;
197+
//qDebug()<<"mode"<<mode_log->mode_log_s;
198+
}
199+
break;
200+
201+
//0x01,flight status
202+
case 1:
203+
{
204+
status_log_t* status_log = (status_log_t*)logData;
205+
statusFlight_t status = status_log->status_log_s;
206+
QString queryString = QString("insert into FlightStatus values(%1,%2)").arg(status_log->timestamp).arg(status);
207+
query.exec(queryString);
208+
209+
//qDebug()<<"status"<<status_log->status_log_s;
210+
}
211+
break;
212+
213+
//0x10, baro
214+
case 16:
215+
{
216+
baro_log_t* baro_log = (baro_log_t*)logData;
217+
baro_t* baro = (baro_t*)&(baro_log->baro_log_s);
218+
219+
QString queryString = QString("insert into Baro values(%1,%2,%3)").arg(baro->timestamp).arg(baro->temp).arg(baro->alt);
220+
query.exec(queryString);
221+
}
222+
break;
223+
224+
225+
//0x11,imu
226+
case 17:
227+
{
228+
imu_log_t* imu_log = (imu_log_t*)logData;
229+
//qDebug()<<"message_id"<<imu_log->message_id;
230+
marg_t* marg = (marg_t*)&(imu_log->marg_log_s);
231+
//qDebug()<<"x"<<marg->acc.x<<"y"<<marg->acc.y<<"z"<<marg->acc.z;
232+
QString queryString = QString("insert into IMU values(%1,%2,%3,%4,%5,%6,%7,%8,%9,%10)").arg(marg->timestamp)
233+
.arg(marg->acc.x).arg(marg->acc.y).arg(marg->acc.z)
234+
.arg(marg->gyr.x).arg(marg->gyr.y).arg(marg->gyr.z)
235+
.arg(marg->mag.x).arg(marg->mag.y).arg(marg->mag.z);
236+
query.exec(queryString);
237+
}
238+
break;
239+
240+
//0x12,gps
241+
case 18:
242+
{
243+
gps_log_t* gps_log = (gps_log_t*)logData;
244+
//qDebug()<<"message_id"<<QString::number(gps_log->message_id);
245+
gpsRaw_t* gps = (gpsRaw_t*)&(gps_log->gpsRaw_log_s);
246+
qDebug()<<"gps date time"<<gps->date<<gps->time;
247+
QString queryString = QString("insert into GPS values(%1,%2,%3,%4,%5,%6,%7,%8,%9)").arg(gps->timestamp)
248+
.arg(gps->lat).arg(gps->lon).arg(gps->azm).arg(gps->vel).arg(gps->alt).arg(gps->sat).arg(gps->date).arg(gps->time);
249+
query.exec(queryString);
250+
}
251+
break;
252+
253+
//0x13, rc
254+
case 19:
255+
{
256+
rc_log_t* rc_log = (rc_log_t*)logData;
257+
rc_t* rc = (rc_t*)&(rc_log->rc_log_s);
258+
//qDebug()<<"channel 3"<<rc->channels[2];
259+
query.prepare("insert into RC values(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)");
260+
query.bindValue(0,rc->timestamp);
261+
for(int i =1;i<17;i++) {
262+
query.bindValue(i,rc->channels[i-1]);
263+
}
264+
query.exec();
265+
}
266+
break;
267+
268+
//0x14, power
269+
case 20:
270+
{
271+
bat_log_t* bat_log = (bat_log_t*)logData;
272+
battery_t* battery = (battery_t*)&(bat_log->bat_log_s);
273+
QString queryString = QString("insert into Battery_Info values(%1,%2,%3)").arg(battery->timestamp).arg(battery->voltage).arg(battery->battery_remaining);
274+
qDebug()<<"bat query"<<query.exec(queryString);
275+
276+
//qDebug()<<"voltage: "<<battery->voltage<<"battery_remaining: "<<battery->battery_remaining;
277+
}
278+
break;
279+
280+
//0x20, attsp
281+
/* case 32:
282+
{
283+
attsp_log_t* attsp_log = (attsp_log_t*)logData;
284+
attsp_t* attsp = (attsp_t*)&(attsp_log->attsp_log_s);
285+
QString queryString = QString("insert into Attitude_Setpoint values(%1,%2,%3)").arg(attsp->timestamp)
286+
.arg(attsp->thrust).arg(attsp->yaw_ff);
287+
query.exec(queryString);
288+
}
289+
break;
290+
*/
291+
292+
//0x21, att
293+
case 33:
294+
{
295+
att_log_t* att_log = (att_log_t*)logData;
296+
att_t* att = (att_t*)&(att_log->att_log_s);
297+
QString queryString = QString("insert into Attitude values(%1,%2,%3,%4,%5,%6,%7)").arg(att->timestamp)
298+
.arg(att->rate.x).arg(att->rate.y).arg(att->rate.z).arg(att->Euler.R).arg(att->Euler.P).arg(att->Euler.Y);
299+
query.exec(queryString);
300+
}
301+
break;
302+
303+
//0x22, output
304+
case 34:
305+
{
306+
output_t* output = (output_t*)logData;
307+
qDebug()<<"thrust"<<output->thrust;
308+
}
309+
break;
310+
311+
//0x23, mansp
312+
case 35:
313+
{
314+
mansp_log_t* mansp_log = (mansp_log_t*)logData;
315+
manCtrlsp_t* manCtrlsp = (manCtrlsp_t*)&(mansp_log->mansp_log_s);
316+
QString queryString = QString("insert into Manual_Setpoint values(%1,%2,%3,%4)")
317+
.arg(manCtrlsp->throttle).arg(manCtrlsp->euler.R).arg(manCtrlsp->euler.P).arg(manCtrlsp->euler.Y);
318+
query.exec(queryString);
319+
}
320+
break;
321+
322+
//0x24, altsp
323+
case 36:
324+
{
325+
altsp_log_t* altsp_log = (altsp_log_t*)logData;
326+
altCtrlsp_t* altCtrlsp = (altCtrlsp_t*)&(altsp_log->altsp_log_s);
327+
QString queryString = QString("insert into AltCtrl_Setpoint values(%1,%2,%3,%4,%5)")
328+
.arg(altCtrlsp->pos_sp_z).arg(altCtrlsp->euler.R).arg(altCtrlsp->euler.P).arg(altCtrlsp->euler.Y);
329+
query.exec(queryString);
330+
}
331+
break;
332+
333+
//0x25, possp
334+
case 37:
335+
{
336+
possp_log_t* possp_log = (possp_log_t*)logData;
337+
posCtrlsp_t* posCtrlsp = (posCtrlsp_t*)&(possp_log->possp_log_s);
338+
QString queryString = QString("insert into PosCtrl_Setpoint values(%1,%2,%3,%4,%5,%6,%7,%8,%9,%10,%11)")
339+
.arg(posCtrlsp->timestamp).arg(posCtrlsp->pos_sp.x).arg(posCtrlsp->pos_sp.y).arg(posCtrlsp->pos_sp.z)
340+
.arg(posCtrlsp->vel_ff.x).arg(posCtrlsp->vel_ff.y).arg(posCtrlsp->vel_ff.z)
341+
.arg(posCtrlsp->acc_ff.x).arg(posCtrlsp->acc_ff.y).arg(posCtrlsp->acc_ff.z)
342+
.arg(posCtrlsp->yaw_sp);
343+
query.exec(queryString);
344+
}
345+
break;
346+
347+
//0x26, pos
348+
case 38:
349+
{
350+
pos_log_t* pos_log = (pos_log_t*)logData;
351+
pos_t* pos = (pos_t*)&(pos_log->pos_log_s);
352+
QString queryString = QString("insert into Position values(%1,%2,%3,%4,%5,%6,%7,%8,%9,%10)")
353+
.arg(pos->timestamp).arg(pos->pos.x).arg(pos->pos.y).arg(pos->pos.z)
354+
.arg(pos->vel.x).arg(pos->vel.y).arg(pos->vel.z)
355+
.arg(pos->acc.x).arg(pos->acc.y).arg(pos->acc.z);
356+
query.exec(queryString);
357+
}
358+
break;
359+
360+
default:
361+
break;
362+
}
363+
}
364+
db.commit();
365+
}
366+
}

‎LogDisplay/LogAnalysis.h

+31
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
#ifndef LOGANALYSIS_H
2+
#define LOGANALYSIS_H
3+
4+
/** Parse log file, and store log data in database
5+
**/
6+
#include <QWidget>
7+
#include <QMap>
8+
#include <QSqlDatabase>
9+
#include "basic_types.h"
10+
#include "messages.h"
11+
#include "sdfiles.h"
12+
13+
class LogAnalysis : public QWidget
14+
{
15+
Q_OBJECT
16+
public:
17+
LogAnalysis(QWidget *parent);
18+
/// load log file, parse and store log data
19+
void logReadAndStore();
20+
21+
signals:
22+
void openFileStatusChanged(bool opened);
23+
24+
private:
25+
/// create database and tables of each kind of log data
26+
bool _creatConnection();
27+
28+
QSqlDatabase db;
29+
};
30+
31+
#endif // LOGANALYSIS_H

‎LogDisplay/LogWidget.cpp

+233
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,233 @@
1+
#include "LogWidget.h"
2+
#include "ui_LogWidget.h"
3+
4+
#include <QtCharts/QLineSeries>
5+
#include <QtCharts/QChartView>
6+
#include <QtCharts/QChart>
7+
#include <QtCharts/QValueAxis>
8+
#include <QVXYModelMapper>
9+
10+
#include <QSqlQuery>
11+
#include <QDebug>
12+
#include <QMessageBox>
13+
14+
using namespace QtCharts;
15+
16+
LogWidget::LogWidget(QWidget *parent) :
17+
QWidget(parent),
18+
ui(new Ui::LogWidget),
19+
_chartView(NULL),
20+
model(NULL),
21+
_tooltip(0),
22+
_coordX(0),
23+
_coordY(0),
24+
_chart(NULL)
25+
{
26+
ui->setupUi(this);
27+
_init();
28+
}
29+
30+
void LogWidget::_init()
31+
{
32+
ui->treeWidget->setStyleSheet("QTreeWidget::item:selected {"
33+
" border: 1px solid #567dbc;"
34+
" background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #6ea1f1, stop: 1 #567dbc);}");
35+
36+
ui->treeWidget->setEnabled(false);
37+
connect(ui->treeWidget,&QTreeWidget::itemClicked,this,&LogWidget::plotData);
38+
39+
_logAnalysis = new LogAnalysis(this);
40+
connect(_logAnalysis,&LogAnalysis::openFileStatusChanged,this,&LogWidget::_openFileStatusChanged);
41+
}
42+
43+
LogWidget::~LogWidget()
44+
{
45+
delete ui;
46+
}
47+
48+
void LogWidget::on_pushButton_OpenLogFile_clicked()
49+
{
50+
ui->treeWidget->setEnabled(false);
51+
_clear();
52+
_logAnalysis->logReadAndStore();
53+
//ui->treeWidget->setEnabled(true);
54+
}
55+
56+
void LogWidget::_openFileStatusChanged(bool opened)
57+
{
58+
//qDebug()<<"_openFileStatusChanged "<<opened;
59+
if(opened) {
60+
ui->pushButton_Clear->setEnabled(true);
61+
ui->treeWidget->setEnabled(true);
62+
}
63+
}
64+
65+
void LogWidget::plotData(QTreeWidgetItem* item, int column)
66+
{
67+
//qDebug()<<"LogWidget:plotData";
68+
if(item ==NULL) {
69+
return;
70+
}
71+
72+
QStringList filePath;
73+
74+
if(!_item2FilepathMap.contains(item)) {
75+
76+
QTreeWidgetItem* itemFile = item;
77+
78+
//get full path of item
79+
while(itemFile != NULL) {
80+
filePath<<itemFile->text(column);
81+
itemFile = itemFile->parent();
82+
}
83+
if(!filePath.isEmpty()) {
84+
_item2FilepathMap.insert(item,filePath);
85+
}
86+
}
87+
88+
if(ui->treeWidget->selectedItems().count() > 2) {
89+
item->setSelected(false);
90+
//QMessageBox::warning(this,"Parameter Selection","You can only select less than 2 params",QMessageBox::Ok);
91+
return;
92+
}
93+
94+
QList<QTreeWidgetItem*> selectedItems = ui->treeWidget->selectedItems();
95+
QStringList columns;
96+
if(!selectedItems.isEmpty()) {
97+
ui->tableView->setVisible(true);
98+
ui->scrollArea_LogDisplay->setVisible(true);
99+
100+
for(int i = 0;i<selectedItems.count();i++) {
101+
QTreeWidgetItem* item = selectedItems.at(i);
102+
filePath = _item2FilepathMap.value(item);
103+
104+
if(!filePath.isEmpty()) {
105+
QString cellName;
106+
QString tableName = filePath.last();
107+
if(filePath.size()>=2) {
108+
for(int i = filePath.size() - 2; i>=0; i--) {
109+
cellName += filePath.at(i);
110+
if(i!=0) {
111+
cellName += '_';
112+
}
113+
}
114+
}
115+
else {
116+
cellName = tableName;
117+
}
118+
//qDebug()<<"tablename"<<tableName<<"cellname"<<cellName;
119+
columns<<tableName<<cellName;
120+
}
121+
}
122+
123+
model = new QSqlQueryModel(ui->tableView);
124+
QSqlQuery query;
125+
QString queryString;
126+
127+
//more than 1 parameter to display
128+
if(columns.count()>2) {
129+
//2 params have the same timestamp
130+
if(columns.at(0) == columns.at(2)) {
131+
queryString = QString("select %1.timestamp,%1.%2,%1.timestamp,%1.%3 from %1").arg(columns.at(0)).arg(columns.at(1)).arg(columns.at(3));
132+
}
133+
//2 params have different timestamps
134+
else {
135+
queryString = QString("select %1.timestamp,%1.%2,%3.timestamp,%3.%4 from %1,%3").arg(columns.at(0)).arg(columns.at(1)).arg(columns.at(2)).arg(columns.at(3));
136+
}
137+
}
138+
else {
139+
queryString = QString("select %1.timestamp,%1.%2 from %1").arg(columns.at(0)).arg(columns.at(1));
140+
}
141+
query.exec(queryString);
142+
143+
model->setQuery(queryString);
144+
ui->tableView->setModel(model);
145+
146+
_chart = new QChart();
147+
_chart->setTitle("Log Data");
148+
_chart->setAnimationOptions(QChart::AllAnimations);
149+
_chart->setAcceptHoverEvents(true);
150+
151+
//series1
152+
QLineSeries * series = new QLineSeries();
153+
series->setName(columns.at(1));
154+
155+
QVXYModelMapper* mapper = new QVXYModelMapper(this);
156+
mapper->setXColumn(0);
157+
mapper->setYColumn(1);
158+
mapper->setSeries(series);
159+
mapper->setModel(model);
160+
_chart->addSeries(series);
161+
//connect(series,SIGNAL(hovered(QPointF,bool)),this,SLOT(tooltip(QPointF,bool)));
162+
163+
//series2
164+
if(columns.count() > 2) {
165+
series = new QLineSeries();
166+
series->setName(columns.at(3));
167+
168+
mapper = new QVXYModelMapper(this);
169+
mapper->setXColumn(2);
170+
mapper->setYColumn(3);
171+
mapper->setSeries(series);
172+
mapper->setModel(model);
173+
_chart->addSeries(series);
174+
connect(series,SIGNAL(hovered(QPointF,bool)),this,SLOT(tooltip(QPointF,bool)));
175+
}
176+
177+
178+
_chart->createDefaultAxes();
179+
_chart->setAcceptHoverEvents(true);
180+
181+
_coordX = new QGraphicsSimpleTextItem("X: ",_chart);
182+
_coordX->setPos(_chart->size().width()/2 - 50, _chart->size().height());
183+
184+
_chartView = new chartView(_chart,this);
185+
186+
ui->scrollArea_LogDisplay->setWidget(_chartView);
187+
}
188+
else {
189+
//qDebug()<<"No item selected";
190+
_chartView = NULL;
191+
ui->scrollArea_LogDisplay->setVisible(false);
192+
ui->tableView->setVisible(false);
193+
}
194+
}
195+
196+
void LogWidget::tooltip(QPointF point, bool state)
197+
{
198+
qDebug()<<point<<state;
199+
if (_tooltip == 0) {
200+
//qDebug()<<"_tooltip == 0";
201+
_tooltip = new Callout(_chart);
202+
}
203+
204+
if (state) {
205+
_tooltip->setText(QString("X: %1 \nY: %2 ").arg(point.x()).arg(point.y()));
206+
_tooltip->setAnchor(point);
207+
_tooltip->setZValue(11);
208+
_tooltip->updateGeometry();
209+
_tooltip->show();
210+
211+
} else {
212+
_tooltip->hide();
213+
}
214+
}
215+
216+
void LogWidget::on_pushButton_Clear_clicked()
217+
{
218+
ui->treeWidget->clearSelection();
219+
_clear();
220+
}
221+
222+
void LogWidget::_clear()
223+
{
224+
if(model) {
225+
model->clear();
226+
if(_chart) {
227+
_chart->removeAllSeries();
228+
}
229+
ui->tableView->setModel(model);
230+
}
231+
}
232+
233+

‎LogDisplay/LogWidget.h

+63
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
#ifndef LOGWIDGET_H
2+
#define LOGWIDGET_H
3+
4+
/** Load and parse log file, if you select parameters,it will plot for you
5+
**/
6+
#include <QWidget>
7+
#include "LogAnalysis.h"
8+
#include "chartView.h"
9+
#include <QTreeWidget>
10+
#include <QPair>
11+
#include <QMap>
12+
#include <QGraphicsSimpleTextItem>
13+
#include <QSqlQueryModel>
14+
#include "Callout.h"
15+
16+
namespace Ui {
17+
class LogWidget;
18+
}
19+
20+
class LogWidget : public QWidget
21+
{
22+
Q_OBJECT
23+
24+
public:
25+
explicit LogWidget(QWidget *parent = 0);
26+
~LogWidget();
27+
28+
private slots:
29+
/// load log file, parse and store log data
30+
void on_pushButton_OpenLogFile_clicked();
31+
/// plot the selected data
32+
void plotData(QTreeWidgetItem* item, int column);
33+
//void keepCallout();
34+
/// called when mouse is hovering on line series to show data of point
35+
void tooltip(QPointF point, bool state);
36+
void _openFileStatusChanged(bool opened);
37+
38+
void on_pushButton_Clear_clicked();
39+
40+
protected:
41+
//void mouseMoveEvent(QMouseEvent* event);
42+
43+
private:
44+
void _init(); /// initialize widget
45+
void _clear(); /// clear table and chart
46+
47+
Ui::LogWidget *ui;
48+
49+
LogAnalysis* _logAnalysis; /// object to parse and store log data
50+
QSqlQueryModel *model;
51+
52+
chartView* _chartView; /// chart view
53+
QChart* _chart;
54+
QGraphicsSimpleTextItem *_coordX;
55+
QGraphicsSimpleTextItem *_coordY;
56+
Callout *_tooltip; /// tooltip box displaying data of point
57+
58+
///key: QTreeWidgetItem
59+
/// value: filePath
60+
QMap<QTreeWidgetItem*,QStringList> _item2FilepathMap;
61+
};
62+
63+
#endif // LOGWIDGET_H

‎LogDisplay/README.md

+43
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
## Log Display
2+
3+
Display log data of flight.
4+
5+
开发环境: Qt 5.8.0 MSVC2013版本。
6+
7+
Qt库:QSqlite进行数据库操作,QtCharts(Qt5.7版本后加入Qt模块)进行绘图
8+
9+
### 运行效果图
10+
11+
![log1]()
12+
13+
### 程序结构
14+
15+
Log相关的程序都在/LogDisplay/中
16+
17+
- LogWidget:log数据显示的主页面,选择并导入log文件,在页面上选择log数据项进行绘图显示
18+
19+
- LogAnalysis:解析log文件,将log数据存储在数据库表中
20+
21+
- chartView:继承自QChartView,可自定义鼠标、键盘事件
22+
23+
- Callout:tooltip框,鼠标悬浮在chart中的线上时,显示当前点的数据
24+
25+
- 其他:log数据是二进制,按头文件中定义的结构存储。读取log文件时要按照这些头文件(basic_types.h, sdfiles.h,message.h)定义的结构进行解析
26+
27+
### 程序流程
28+
29+
1. LogWidget中选择并打开log文件
30+
2. LogAnalysis解析log文件,将log数据分类存储在数据库对应的表中
31+
3. 在LogWidget左侧的QTreeWidget中选择item,就会查询数据库对应表中的数据,在TableView中显示数据,并在chartView中绘图显示
32+
33+
#### tips
34+
35+
SQLite数据库本质上来讲就是一个磁盘上的文件,所以一切的数据库操作其实都会转化为对文件的操作,在向数据库写入大量log数据时,频繁的文件操作会极大地影响数据库存取的速度。
36+
37+
于是我们通过事务来提高数据库的读写速度。事务的基本原理是:数据库管理系统会把要执行的sql语句存储到内存当中,commit()的时候一次性全部执行所有内存中的数据库。
38+
39+
```c++
40+
db.transaction(); // 开始启动事务
41+
... // 执行数据库操作
42+
db.commit() // 提交事务
43+
```

‎LogDisplay/basic_types.h

+114
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
#ifndef BASIC_TYPES_H
2+
#define BASIC_TYPES_H
3+
#pragma anon_unions
4+
#include <stdint.h>
5+
#include <stdbool.h>
6+
typedef struct vec2i16_s {
7+
// uint32_t timestamp;
8+
union {
9+
struct {
10+
int16_t x;
11+
int16_t y;
12+
};
13+
int16_t v[2];
14+
};
15+
}vec2i16_t;
16+
typedef struct vec2f_s {
17+
// uint32_t timestamp;
18+
union {
19+
struct {
20+
float x;
21+
float y;
22+
};
23+
float v[2];
24+
};
25+
}vec2f_t;
26+
/* x,y,z vector */
27+
///////////////////////hyl//////////////////////////
28+
typedef struct vec3f_imu_cali_s {
29+
union {
30+
struct {
31+
float x;
32+
float y;
33+
float z;
34+
};
35+
uint8_t v[12];
36+
};
37+
}vec3f_imu_cali_t;
38+
39+
typedef struct _magresult {
40+
double x0;
41+
double y0;
42+
double z0;
43+
double A;
44+
double B;
45+
double R;
46+
}magresult;
47+
48+
typedef struct vec3f_mag_cali_s {
49+
union{
50+
magresult mag_res;
51+
uint8_t mag_calib_array[48];
52+
};
53+
}vec3f_mag_cali_t;
54+
typedef struct vec3f_acc_cali_s {
55+
union{
56+
magresult acc_res;
57+
uint8_t acc_calib_array[48];
58+
};
59+
}vec3f_acc_cali_t;
60+
///////////////////////hyl//////////////////////////
61+
//typedef struct vec3i16_s {
62+
//// uint32_t timestamp;
63+
// union {
64+
// struct {
65+
// int16_t x;
66+
// int16_t y;
67+
// int16_t z;
68+
// };
69+
// int16_t v[3];
70+
// };
71+
//}vec3i16_t;
72+
typedef struct vec3f_s {
73+
// uint32_t timestamp; // Timestamp when the data was computed
74+
union {
75+
struct {
76+
float R;
77+
float P;
78+
float Y;
79+
};
80+
struct {
81+
float x;
82+
float y;
83+
float z;
84+
};
85+
float v[3];
86+
};
87+
}vec3f_t;
88+
89+
typedef struct quaternion_s {
90+
// uint32_t timestamp;
91+
union {
92+
struct {
93+
float q0;
94+
float q1;
95+
float q2;
96+
float q3;
97+
};
98+
struct {
99+
float x;
100+
float y;
101+
float z;
102+
float w;
103+
};
104+
float q[4];
105+
};
106+
} quaternion_t;
107+
108+
typedef struct rotation_s {
109+
// uint32_t timestamp; // Timestamp when the data was computed
110+
float R[3][3];
111+
} rotation_t;
112+
113+
114+
#endif

‎LogDisplay/chartView.cpp

+64
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
#include "chartView.h"
2+
3+
chartView::chartView(QChart *chart, QWidget *parent)
4+
:QChartView(chart,parent)
5+
{
6+
// 启用“方框选中区域进行放大显示”的功能
7+
setRubberBand(QChartView::RectangleRubberBand);
8+
9+
}
10+
11+
void chartView::mousePressEvent(QMouseEvent *event)
12+
{
13+
QChartView::mousePressEvent(event);
14+
}
15+
16+
void chartView::mouseMoveEvent(QMouseEvent *event)
17+
{
18+
QChartView::mouseMoveEvent(event);
19+
}
20+
21+
void chartView::mouseReleaseEvent(QMouseEvent *event)
22+
{
23+
QChartView::mouseReleaseEvent(event);
24+
}
25+
26+
/// overwrite wheel event
27+
void chartView::wheelEvent(QWheelEvent* event)
28+
{
29+
if(event->delta() > 0) {
30+
chart()->scroll(0,10);
31+
}
32+
else {
33+
chart()->scroll(0,-10);
34+
}
35+
}
36+
37+
/// overwrite key press event
38+
void chartView::keyPressEvent(QKeyEvent *event)
39+
{
40+
switch (event->key()) {
41+
case Qt::Key_Plus:
42+
chart()->zoomIn();
43+
break;
44+
case Qt::Key_Minus:
45+
chart()->zoomOut();
46+
break;
47+
case Qt::Key_Left:
48+
chart()->scroll(-10,0);
49+
break;
50+
case Qt::Key_Right:
51+
chart()->scroll(10,0);
52+
break;
53+
case Qt::Key_Up:
54+
chart()->scroll(0,10);
55+
break;
56+
case Qt::Key_Down:
57+
chart()->scroll(0,-10);
58+
break;
59+
default:
60+
QGraphicsView::keyPressEvent(event);
61+
break;
62+
}
63+
64+
}

‎LogDisplay/chartView.h

+26
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
#ifndef CHARTVIEW_H
2+
#define CHARTVIEW_H
3+
4+
/**
5+
* Overwrite mouse event and keyboard event
6+
**/
7+
#include <QChartView>
8+
//#include <QRubberBand>
9+
10+
using namespace QtCharts;
11+
12+
class chartView : public QChartView
13+
{
14+
Q_OBJECT
15+
public:
16+
chartView(QChart *chart, QWidget *parent = 0);
17+
18+
protected:
19+
void mousePressEvent(QMouseEvent *event);
20+
void mouseMoveEvent(QMouseEvent *event);
21+
void mouseReleaseEvent(QMouseEvent *event);
22+
void wheelEvent(QWheelEvent* event);
23+
void keyPressEvent(QKeyEvent *event);
24+
};
25+
26+
#endif // CHARTVIEW_H

‎LogDisplay/messages.h

+197
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,197 @@
1+
#ifndef MESSAGES_H
2+
#define MESSAGES_H
3+
#include "basic_types.h"
4+
5+
typedef struct accProcessed_s{
6+
uint32_t timestamp;
7+
vec3f_t mean;
8+
vec3f_t std;
9+
}accProcessed_t;
10+
typedef enum missionVehicle_e{
11+
Normal = 0,
12+
Takeoff,
13+
Land,
14+
Returnhome
15+
}mission_t;
16+
typedef struct margData_s {
17+
uint32_t timestamp;
18+
vec3f_t acc;
19+
vec3f_t gyr;
20+
vec3f_t mag;
21+
bool mag_updated;
22+
} marg_t;
23+
typedef struct calib_s {
24+
vec3f_acc_cali_t acc_bias;//hyl- change vec3i16_t to vec3f_acc_cali_t
25+
vec3f_imu_cali_t gyr_bias;//hyl- change vec3i16_t to vec3f_imu_cali_t
26+
vec3f_mag_cali_t mag_bias;
27+
vec3f_imu_cali_t mag_d_bias;
28+
vec3f_imu_cali_t acc_d_bias;
29+
vec3f_imu_cali_t acc_d_prop;
30+
vec3f_imu_cali_t gyr_tmp_bias;
31+
vec3f_imu_cali_t acc_tmp_bias;
32+
} calib_t;
33+
typedef struct calib_st {
34+
union{
35+
struct{
36+
bool acc_done; //hyl- add
37+
bool gyr_done;
38+
bool mag_done;
39+
// bool rc_done;
40+
};
41+
uint8_t v[3];
42+
};
43+
} calib_status;
44+
typedef struct baro_s {
45+
uint32_t timestamp;
46+
float pressure;
47+
float temp;
48+
float alt;
49+
float offset;
50+
} baro_t;
51+
typedef struct gpsRaw_s {
52+
uint32_t timestamp;
53+
int64_t lat;
54+
int64_t lon;
55+
float azm;
56+
float vel;
57+
bool vel_valid;
58+
float alt;
59+
uint8_t sat;
60+
uint32_t date;
61+
uint32_t time;
62+
float eph;
63+
enum statusGPS_e {
64+
noGPS = 0,
65+
realtimeGPS = 1,
66+
difGPS = 2
67+
}status;
68+
} gpsRaw_t;
69+
typedef struct gpsProcessed_s {
70+
uint32_t timestamp;
71+
vec3f_t pos;
72+
vec3f_t vel;
73+
vec3f_t acc;
74+
} gpsProcessed_t;
75+
typedef struct rc_s {
76+
uint32_t timestamp;
77+
float channels[16];
78+
} rc_t;
79+
typedef struct battery_s {
80+
uint32_t timestamp;
81+
uint16_t voltage;
82+
int8_t battery_remaining; //SK 2017-3-28 11:09:39
83+
} battery_t;//used in queue
84+
typedef struct att_s {
85+
uint32_t timestamp;
86+
vec3f_t Euler;
87+
quaternion_t Q;
88+
rotation_t R;
89+
vec3f_t rate;
90+
} att_t;//used in queue
91+
typedef struct pos_s {
92+
uint32_t timestamp;
93+
vec3f_t pos;
94+
vec3f_t vel;
95+
vec3f_t acc;
96+
bool xy_valid;
97+
float yaw_bias;
98+
} pos_t;//used in queue
99+
typedef struct attsp_s {
100+
uint32_t timestamp;
101+
rotation_t R;
102+
float thrust;
103+
float yaw_ff;
104+
} attsp_t;//used in queue
105+
typedef struct possp_s {
106+
uint32_t timestamp;
107+
vec3f_t pos_sp;
108+
vec3f_t vel_ff;
109+
vec3f_t acc_ff;
110+
float yaw_sp;
111+
}posCtrlsp_t;//used in queue
112+
typedef struct altCtrlsp_s {
113+
uint32_t timestamp;
114+
float pos_sp_z;
115+
float vel_ff_z;
116+
vec3f_t euler;
117+
} altCtrlsp_t;//used in queue
118+
typedef struct manuelCtrlsp_s {
119+
uint32_t timestamp;
120+
float throttle;
121+
vec3f_t euler;
122+
} manCtrlsp_t;//used in queue
123+
typedef struct output_s {
124+
uint32_t timestamp;
125+
vec3f_t moment;
126+
float thrust;
127+
} output_t;//used in queue
128+
typedef struct motors_s {
129+
float thrust[8];
130+
} motors_t;//used in queue
131+
typedef struct msg_magcalib{ //SK 2017-3-28 11:09:21
132+
union{
133+
struct{
134+
char data_1[5];
135+
int num;
136+
};
137+
char textt[7]; //SK 2017-3-30 14:35:53
138+
};
139+
} msg_magcalib_t;
140+
141+
142+
typedef enum modeVehicle_e {
143+
modeCal = 0,
144+
modeRate,
145+
modeMan,
146+
modeAlt,
147+
modePos,
148+
modeTrj
149+
} mode_t;
150+
typedef enum statusLock_e {
151+
motorLocked = 0,
152+
motorUnlocking,
153+
motorUnlocked,
154+
} statusLock_t;
155+
typedef enum statusFlight_e {
156+
statusLanded = 0,
157+
statusInitiating,
158+
statusTakingoff,
159+
statusLanding,
160+
statusFlying,
161+
statusHovering,
162+
stautsFreefall,
163+
stautsUpsidedown,
164+
stautsTumble
165+
} statusFlight_t;
166+
typedef enum statusGS_e {
167+
gs_normal = 0,
168+
169+
} statusGS_t;
170+
typedef enum statusRC_e {
171+
rc_normal = 0,
172+
} statusRC_t;
173+
//typedef enum msg_log_type {
174+
// LOG_MODE=0,
175+
// LOG_STATUS,
176+
//
177+
// LOG_IMU,
178+
// LOG_BARO,
179+
// LOG_GPS,
180+
// LOG_RC,
181+
//
182+
// LOG_ATTSP,
183+
// LOG_ATT,
184+
// LOG_FORCE,
185+
// LOG_MAN_POSSP,
186+
// LOG_ALT_POSSP,
187+
// LOG_POS_POSSP,
188+
// LOG_POS,
189+
// LOG_POWER
190+
//} msg_log_type_t;
191+
extern mode_t g_mode;
192+
extern statusLock_t g_statusLock;
193+
extern statusFlight_t g_statusFlight;
194+
extern statusRC_t g_statusRC;
195+
extern statusGS_t g_statusGS;
196+
//extern msg_log_type_t msg_log_type;
197+
#endif

‎LogDisplay/sdfiles.h

+119
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,119 @@
1+
#ifndef __SDFILES_H__
2+
#define __SDFILES_H__
3+
4+
5+
//#include "stm32f4xx.h"
6+
//#include "ff.h"
7+
//#include "fatfs.h"
8+
#include "messages.h"
9+
10+
//typedef struct _sensor_combined_s
11+
//{
12+
// union{
13+
// struct {
14+
// char message_id;
15+
// marg_t marg_log_s;
16+
// };
17+
// char marg_sens_log[40];
18+
// };
19+
//}sensor_combined_t;
20+
21+
typedef struct _mode_log_s
22+
{
23+
char message_id;
24+
uint32_t timestamp;
25+
mode_t mode_log_s;
26+
}mode_log_t;
27+
28+
typedef struct _status_log_s
29+
{
30+
char message_id;
31+
uint32_t timestamp;
32+
statusFlight_t status_log_s;
33+
}status_log_t;
34+
35+
typedef struct _imu_log_s
36+
{
37+
char message_id;
38+
marg_t marg_log_s;
39+
}imu_log_t;
40+
41+
typedef struct _baro_log_s
42+
{
43+
char message_id;
44+
baro_t baro_log_s;
45+
}baro_log_t;
46+
47+
typedef struct _gps_log_s
48+
{
49+
char message_id;
50+
gpsRaw_t gpsRaw_log_s;
51+
}gps_log_t;
52+
53+
typedef struct _rc_log_s
54+
{
55+
char message_id;
56+
rc_t rc_log_s;
57+
}rc_log_t;
58+
59+
//typedef struct _attsp_log_s
60+
//{
61+
// char message_id;
62+
// attsp_t attsp_log_s;
63+
//}attsp_log_t;
64+
65+
typedef struct _att_log_s
66+
{
67+
char message_id;
68+
att_t att_log_s;
69+
}att_log_t;
70+
71+
typedef struct _output_log_s
72+
{
73+
char message_id;
74+
output_t output_log_s;
75+
}output_log_t;
76+
77+
typedef struct _mansp_log_s
78+
{
79+
char message_id;
80+
manCtrlsp_t mansp_log_s;
81+
}mansp_log_t;
82+
83+
typedef struct _altsp_log_s
84+
{
85+
char message_id;
86+
altCtrlsp_t altsp_log_s;
87+
}altsp_log_t;
88+
89+
typedef struct _possp_log_s
90+
{
91+
char message_id;
92+
posCtrlsp_t possp_log_s;
93+
}possp_log_t;
94+
95+
typedef struct _pos_log_s
96+
{
97+
char message_id;
98+
pos_t pos_log_s;
99+
}pos_log_t;
100+
101+
typedef struct _bat_log_s
102+
{
103+
char message_id;
104+
battery_t bat_log_s;
105+
}bat_log_t;
106+
107+
108+
//extern FIL sd_file;
109+
//extern char file_newline[2];
110+
//extern uint32_t byte_writtened;
111+
//extern FRESULT f_res;
112+
113+
void sd_file_init(void);
114+
void vLogTask(void *pvParameters);
115+
116+
117+
#endif
118+
119+

‎LogWidget.ui

+742
Large diffs are not rendered by default.

‎QuadApplication.cpp

+40
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
#include "QuadApplication.h"
2+
#include <QDebug>
3+
4+
QuadApplication* QuadApplication::_app = NULL;
5+
6+
QuadApplication::QuadApplication(int &argc, char* argv[])
7+
:QApplication(argc,argv)
8+
, _mainwindow(NULL)
9+
{
10+
11+
Q_ASSERT(_app == NULL);
12+
_app = this;
13+
14+
setApplicationName("LogDisplay");
15+
}
16+
17+
QuadApplication::~QuadApplication()
18+
{
19+
20+
}
21+
22+
bool QuadApplication::_initForNormalAppBoot(void)
23+
{
24+
connect(this,&QuadApplication::lastWindowClosed,this,&QuadApplication::quit);
25+
MainWindow* mainWindow = MainWindow::_create();
26+
Q_CHECK_PTR(mainWindow);
27+
_mainwindow = mainWindow->instance();
28+
return true;
29+
}
30+
31+
void QuadApplication::showMessage(QString message)
32+
{
33+
//qDebug()<<message;
34+
}
35+
36+
QuadApplication* qgcApp()
37+
{
38+
Q_ASSERT(QuadApplication::_app);
39+
return QuadApplication::_app;
40+
}

‎QuadApplication.h

+26
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
#ifndef QUADAPPLICATION_H
2+
#define QUADAPPLICATION_H
3+
4+
#include <QApplication>
5+
#include "mainwindow.h"
6+
//class MainWindow;
7+
8+
class QuadApplication : public QApplication
9+
{
10+
11+
public:
12+
QuadApplication(int &argc, char* argv[]);
13+
~QuadApplication();
14+
15+
static QuadApplication* _app;
16+
bool _initForNormalAppBoot(void);
17+
18+
MainWindow* mainWindow(void) {return _mainwindow;}
19+
void showMessage(QString message);
20+
21+
private:
22+
MainWindow* _mainwindow;
23+
};
24+
25+
QuadApplication* qgcApp();
26+
#endif // QUADAPPLICATION_H

‎images/log1.PNG

42 KB
Loading

‎main.cpp

+63
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
2+
#include "mainwindow.h"
3+
#include "QuadApplication.h"
4+
#include <QTextStream>
5+
#include <QMutex>
6+
#include <QFile>
7+
#include <stdio.h>
8+
#include <stdlib.h>
9+
10+
QMutex mutex;
11+
12+
void logMsgOutput(QtMsgType type,const QMessageLogContext &context, const QString &msg)
13+
{
14+
Q_UNUSED(context)
15+
16+
mutex.lock();
17+
QString text;
18+
switch(type) {
19+
case QtDebugMsg:
20+
text =QString("Debug");
21+
break;
22+
case QtWarningMsg:
23+
text = QString("Warning");
24+
break;
25+
case QtCriticalMsg:
26+
text = QString("Critical");
27+
break;
28+
case QtFatalMsg:
29+
text = QString("Fatal");
30+
}
31+
//QString currentDateTime = QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss");
32+
/*QString message = QString(" %1 : File: %2 Line: %3 Function: %4 %5").arg(text).arg(QString(context.file)).arg(QString::number(context.line))
33+
.arg(QString(context.function)).arg(msg);*/
34+
QString message = QString(" %1 : %2").arg(text).arg(msg);
35+
36+
QFile file("log.txt");
37+
if(file.open(QIODevice::WriteOnly|QIODevice::Append)) {
38+
QTextStream text(&file);
39+
// text<<currentDateTime;
40+
text<<message<<"\r\n";
41+
file.flush();
42+
file.close();
43+
}
44+
mutex.unlock();
45+
}
46+
47+
int main(int argc, char *argv[])
48+
{
49+
qInstallMessageHandler(logMsgOutput);
50+
QuadApplication *a = new QuadApplication(argc, argv);
51+
52+
Q_CHECK_PTR(a);
53+
int exitcode = 0;
54+
{
55+
if(!a->_initForNormalAppBoot()) {
56+
return -1;
57+
}
58+
exitcode = a->exec();
59+
}
60+
delete a;
61+
62+
return exitcode;
63+
}

‎mainwindow.cpp

+45
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
#include "mainwindow.h"
2+
#include "ui_mainwindow.h"
3+
4+
#include <QtDebug>
5+
#include <QtCore>
6+
#include <QMessageBox>
7+
#include <QCloseEvent>
8+
#include <QLayout>
9+
#include <QFile>
10+
11+
static MainWindow* _instance = NULL;
12+
13+
MainWindow* MainWindow::_create()
14+
{
15+
Q_ASSERT(_instance == NULL);
16+
_instance = new MainWindow();
17+
Q_ASSERT(_instance);
18+
return _instance;
19+
}
20+
21+
MainWindow::MainWindow(QWidget *parent) :
22+
QMainWindow(parent),
23+
ui(new Ui::MainWindow)
24+
{
25+
ui->setupUi(this);
26+
setFixedSize(960,600);
27+
this->setStyleSheet("QPushButton {background: #cfe2f3}"
28+
"QPushButton:pressed {background: 6699cc}");
29+
30+
c_palette.setColor(QPalette::WindowText,Qt::black);
31+
w_palette.setColor(QPalette::WindowText,Qt::red);
32+
33+
show();
34+
}
35+
36+
MainWindow* MainWindow::instance(void)
37+
{
38+
return _instance;
39+
}
40+
41+
MainWindow::~MainWindow()
42+
{
43+
_instance = NULL;
44+
delete ui;
45+
}

‎mainwindow.h

+27
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
#ifndef MAINWINDOW_H
2+
#define MAINWINDOW_H
3+
4+
#include <QMainWindow>
5+
6+
namespace Ui {
7+
class MainWindow;
8+
}
9+
10+
class MainWindow : public QMainWindow
11+
{
12+
Q_OBJECT
13+
14+
public:
15+
explicit MainWindow(QWidget *parent = 0);
16+
static MainWindow* _create();
17+
~MainWindow();
18+
19+
MainWindow* instance(void);
20+
21+
private:
22+
Ui::MainWindow *ui;
23+
QPalette w_palette; //warning
24+
QPalette c_palette; //common
25+
};
26+
27+
#endif // MAINWINDOW_H

‎mainwindow.ui

+169
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,169 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<ui version="4.0">
3+
<class>MainWindow</class>
4+
<widget class="QMainWindow" name="MainWindow">
5+
<property name="geometry">
6+
<rect>
7+
<x>0</x>
8+
<y>0</y>
9+
<width>1039</width>
10+
<height>720</height>
11+
</rect>
12+
</property>
13+
<property name="windowTitle">
14+
<string>MainWindow</string>
15+
</property>
16+
<widget class="QWidget" name="centralWidget">
17+
<layout class="QGridLayout" name="gridLayout_8">
18+
<item row="0" column="0">
19+
<widget class="QTabWidget" name="tabWidget">
20+
<property name="palette">
21+
<palette>
22+
<active>
23+
<colorrole role="Button">
24+
<brush brushstyle="SolidPattern">
25+
<color alpha="255">
26+
<red>0</red>
27+
<green>170</green>
28+
<blue>0</blue>
29+
</color>
30+
</brush>
31+
</colorrole>
32+
<colorrole role="Base">
33+
<brush brushstyle="SolidPattern">
34+
<color alpha="255">
35+
<red>0</red>
36+
<green>170</green>
37+
<blue>0</blue>
38+
</color>
39+
</brush>
40+
</colorrole>
41+
<colorrole role="Window">
42+
<brush brushstyle="SolidPattern">
43+
<color alpha="255">
44+
<red>0</red>
45+
<green>170</green>
46+
<blue>0</blue>
47+
</color>
48+
</brush>
49+
</colorrole>
50+
</active>
51+
<inactive>
52+
<colorrole role="Button">
53+
<brush brushstyle="SolidPattern">
54+
<color alpha="255">
55+
<red>0</red>
56+
<green>170</green>
57+
<blue>0</blue>
58+
</color>
59+
</brush>
60+
</colorrole>
61+
<colorrole role="Base">
62+
<brush brushstyle="SolidPattern">
63+
<color alpha="255">
64+
<red>0</red>
65+
<green>170</green>
66+
<blue>0</blue>
67+
</color>
68+
</brush>
69+
</colorrole>
70+
<colorrole role="Window">
71+
<brush brushstyle="SolidPattern">
72+
<color alpha="255">
73+
<red>0</red>
74+
<green>170</green>
75+
<blue>0</blue>
76+
</color>
77+
</brush>
78+
</colorrole>
79+
</inactive>
80+
<disabled>
81+
<colorrole role="Button">
82+
<brush brushstyle="SolidPattern">
83+
<color alpha="255">
84+
<red>0</red>
85+
<green>170</green>
86+
<blue>0</blue>
87+
</color>
88+
</brush>
89+
</colorrole>
90+
<colorrole role="Base">
91+
<brush brushstyle="SolidPattern">
92+
<color alpha="255">
93+
<red>0</red>
94+
<green>170</green>
95+
<blue>0</blue>
96+
</color>
97+
</brush>
98+
</colorrole>
99+
<colorrole role="Window">
100+
<brush brushstyle="SolidPattern">
101+
<color alpha="255">
102+
<red>0</red>
103+
<green>170</green>
104+
<blue>0</blue>
105+
</color>
106+
</brush>
107+
</colorrole>
108+
</disabled>
109+
</palette>
110+
</property>
111+
<property name="font">
112+
<font>
113+
<family>微软雅黑</family>
114+
<pointsize>12</pointsize>
115+
</font>
116+
</property>
117+
<property name="styleSheet">
118+
<string notr="true">background-image: url(:/attitude/attitude/background-new.jpg);</string>
119+
</property>
120+
<property name="currentIndex">
121+
<number>0</number>
122+
</property>
123+
<property name="iconSize">
124+
<size>
125+
<width>24</width>
126+
<height>24</height>
127+
</size>
128+
</property>
129+
<property name="movable">
130+
<bool>false</bool>
131+
</property>
132+
<widget class="QWidget" name="log">
133+
<attribute name="title">
134+
<string>log分析</string>
135+
</attribute>
136+
<layout class="QGridLayout" name="gridLayout_2">
137+
<item row="0" column="0">
138+
<widget class="LogWidget" name="widget_Log" native="true"/>
139+
</item>
140+
</layout>
141+
</widget>
142+
</widget>
143+
</item>
144+
</layout>
145+
</widget>
146+
<widget class="QMenuBar" name="menuBar">
147+
<property name="geometry">
148+
<rect>
149+
<x>0</x>
150+
<y>0</y>
151+
<width>1039</width>
152+
<height>23</height>
153+
</rect>
154+
</property>
155+
</widget>
156+
<widget class="QStatusBar" name="statusBar"/>
157+
</widget>
158+
<layoutdefault spacing="6" margin="11"/>
159+
<customwidgets>
160+
<customwidget>
161+
<class>LogWidget</class>
162+
<extends>QWidget</extends>
163+
<header>LogWidget.h</header>
164+
<container>1</container>
165+
</customwidget>
166+
</customwidgets>
167+
<resources/>
168+
<connections/>
169+
</ui>

‎ui_LogWidget.h

+473
Large diffs are not rendered by default.

‎ui_mainwindow.h

+118
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,118 @@
1+
/********************************************************************************
2+
** Form generated from reading UI file 'mainwindow.ui'
3+
**
4+
** Created by: Qt User Interface Compiler version 5.8.0
5+
**
6+
** WARNING! All changes made in this file will be lost when recompiling UI file!
7+
********************************************************************************/
8+
9+
#ifndef UI_MAINWINDOW_H
10+
#define UI_MAINWINDOW_H
11+
12+
#include <QtCore/QVariant>
13+
#include <QtWidgets/QAction>
14+
#include <QtWidgets/QApplication>
15+
#include <QtWidgets/QButtonGroup>
16+
#include <QtWidgets/QGridLayout>
17+
#include <QtWidgets/QHeaderView>
18+
#include <QtWidgets/QMainWindow>
19+
#include <QtWidgets/QMenuBar>
20+
#include <QtWidgets/QStatusBar>
21+
#include <QtWidgets/QTabWidget>
22+
#include <QtWidgets/QWidget>
23+
#include "LogDisplay/LogWidget.h"
24+
25+
QT_BEGIN_NAMESPACE
26+
27+
class Ui_MainWindow
28+
{
29+
public:
30+
QWidget *centralWidget;
31+
QGridLayout *gridLayout_8;
32+
QTabWidget *tabWidget;
33+
QWidget *log;
34+
QGridLayout *gridLayout_2;
35+
LogWidget *widget_Log;
36+
QMenuBar *menuBar;
37+
QStatusBar *statusBar;
38+
39+
void setupUi(QMainWindow *MainWindow)
40+
{
41+
if (MainWindow->objectName().isEmpty())
42+
MainWindow->setObjectName(QStringLiteral("MainWindow"));
43+
MainWindow->resize(1039, 720);
44+
centralWidget = new QWidget(MainWindow);
45+
centralWidget->setObjectName(QStringLiteral("centralWidget"));
46+
gridLayout_8 = new QGridLayout(centralWidget);
47+
gridLayout_8->setSpacing(6);
48+
gridLayout_8->setContentsMargins(11, 11, 11, 11);
49+
gridLayout_8->setObjectName(QStringLiteral("gridLayout_8"));
50+
tabWidget = new QTabWidget(centralWidget);
51+
tabWidget->setObjectName(QStringLiteral("tabWidget"));
52+
QPalette palette;
53+
QBrush brush(QColor(0, 170, 0, 255));
54+
brush.setStyle(Qt::SolidPattern);
55+
palette.setBrush(QPalette::Active, QPalette::Button, brush);
56+
palette.setBrush(QPalette::Active, QPalette::Base, brush);
57+
palette.setBrush(QPalette::Active, QPalette::Window, brush);
58+
palette.setBrush(QPalette::Inactive, QPalette::Button, brush);
59+
palette.setBrush(QPalette::Inactive, QPalette::Base, brush);
60+
palette.setBrush(QPalette::Inactive, QPalette::Window, brush);
61+
palette.setBrush(QPalette::Disabled, QPalette::Button, brush);
62+
palette.setBrush(QPalette::Disabled, QPalette::Base, brush);
63+
palette.setBrush(QPalette::Disabled, QPalette::Window, brush);
64+
tabWidget->setPalette(palette);
65+
QFont font;
66+
font.setFamily(QString::fromUtf8("\345\276\256\350\275\257\351\233\205\351\273\221"));
67+
font.setPointSize(12);
68+
tabWidget->setFont(font);
69+
tabWidget->setStyleSheet(QStringLiteral("background-image: url(:/attitude/attitude/background-new.jpg);"));
70+
tabWidget->setIconSize(QSize(24, 24));
71+
tabWidget->setMovable(false);
72+
log = new QWidget();
73+
log->setObjectName(QStringLiteral("log"));
74+
gridLayout_2 = new QGridLayout(log);
75+
gridLayout_2->setSpacing(6);
76+
gridLayout_2->setContentsMargins(11, 11, 11, 11);
77+
gridLayout_2->setObjectName(QStringLiteral("gridLayout_2"));
78+
widget_Log = new LogWidget(log);
79+
widget_Log->setObjectName(QStringLiteral("widget_Log"));
80+
81+
gridLayout_2->addWidget(widget_Log, 0, 0, 1, 1);
82+
83+
tabWidget->addTab(log, QString());
84+
85+
gridLayout_8->addWidget(tabWidget, 0, 0, 1, 1);
86+
87+
MainWindow->setCentralWidget(centralWidget);
88+
menuBar = new QMenuBar(MainWindow);
89+
menuBar->setObjectName(QStringLiteral("menuBar"));
90+
menuBar->setGeometry(QRect(0, 0, 1039, 23));
91+
MainWindow->setMenuBar(menuBar);
92+
statusBar = new QStatusBar(MainWindow);
93+
statusBar->setObjectName(QStringLiteral("statusBar"));
94+
MainWindow->setStatusBar(statusBar);
95+
96+
retranslateUi(MainWindow);
97+
98+
tabWidget->setCurrentIndex(0);
99+
100+
101+
QMetaObject::connectSlotsByName(MainWindow);
102+
} // setupUi
103+
104+
void retranslateUi(QMainWindow *MainWindow)
105+
{
106+
MainWindow->setWindowTitle(QApplication::translate("MainWindow", "MainWindow", Q_NULLPTR));
107+
tabWidget->setTabText(tabWidget->indexOf(log), QApplication::translate("MainWindow", "log\345\210\206\346\236\220", Q_NULLPTR));
108+
} // retranslateUi
109+
110+
};
111+
112+
namespace Ui {
113+
class MainWindow: public Ui_MainWindow {};
114+
} // namespace Ui
115+
116+
QT_END_NAMESPACE
117+
118+
#endif // UI_MAINWINDOW_H

0 commit comments

Comments
 (0)
Please sign in to comment.