这个是我实训做的项目,是模拟对无人机姿态的控制,实现对无人机飞行数据的分析,项目主要分为登录窗口,客户端和服务器端
项目主题界面:
需求分析:
1、设计本地登录界面及云端平台界面。
2、根据用户登录信息的不同,选择不同的云端用户级别,具体为user和vip。
3、普通用户只能查看实时数据、自动给出实时建议,超级用户可以查看实时数据、历史数据、统计数据判断是否危险飞行、生成事故报告
4、创建数据库,保存两张表,表1判断云端用户级别及用户登录验证,表2记录一定时间内的飞机姿态数据
5、事故报告以文档(word、pdf)形式生成
功能分析:
1、可以根据用户级别的不同授权不同的内容查看。
2、可以使用模拟终端(滑动按钮)来改变机身角度的值。
3、通过计算机网络将数据进行传输。
4、可以实时改变验证平台上图形的状态。
5、可以实时记录机身角度改变的内容并保存到数据库中
总体设计:
我先从登录界面开始说起吧
登录界面的设计:
登录界面主要分为用户登录和管理员登录,运用了Sqlite轻量级数据库,可实现账号的注册,在普通用户界面加了一个验证码的功能,其实是通过随机数来实现验证,主要的代码如下:
创建数据库和表
//创建数据库
QSqlDatabase db=QSqlDatabase::addDatabase("QSQLITE");
//QSqlDatabase db1=QSqlDatabase::addDatabase("QSQLITE");
//设置数据库名
db.setDatabaseName("pwd.db");
//db1.setDatabaseName("pwd1.db");
//打开数据
if(db.open())
{
qDebug()<<"open database success";
}else
{
qDebug()<<"open database fail";
}
//创建一个存储用户名密码的数据库表
QString tableuser="create table userinfo(username varchar(64),password varchar(64))";
QString tableadmin="create table userinfo1(username1 varchar(64),password1 varchar(64))";
实现注册:
QString username=ui->useredit->text();
QString password=ui->passedit->text();
QString cmd=QString("insert into userinfo values('%1','%2')")
.arg(username).arg(password);
QSqlQuery query;
if(username==NULL||password==NULL)
{
QMessageBox::information(this,"注册提示","用户名或密码不能为空");
}
else if(query.exec(cmd))
{
QMessageBox::information(this,"注册提示","注册成功");
}
服务器的实现:
服务器界面就是一个模拟无人机的圆
这里运用了Qpainter来绘制三角,圆等形状来实现对无人机的模拟,服务器接收来自客户端的消息,来进行角度的改变,接收来自客户端连接的信号:
if(svr->hasPendingConnections()){
socket = svr->nextPendingConnection();
connect(socket,SIGNAL(readyRead()),this,SLOT(slotRecv()));
qDebug() << "有设备连接";
}
接收客户端数据:
QByteArray array = socket->readAll();
QString str = QString::fromUtf8(array);
QString tmp;
int j = 0;
while(j<str.size()){
tmp.clear();
int k = 0;
for(j;j<str.length();j++)
{
if(str[j]>='0'&&str[j]<='9'||str[j]=='-'){
tmp.append(str[j]);
}
if(str[j]==" "){
k++;
if(k == 1){
angle_spin = tmp.toInt();
tmp.clear();
}else if(k==2) {
angle_dir = tmp.toInt();
tmp.clear();
}
}
if(str[j]=="e"){
j++;
angle_pit = tmp.toInt();
break;
}
}
this->setWindowTitle("偏转角:"+QString::number(angle_spin)+"°俯仰角:"+QString::number(angle_dir)+"°方向:"+QString::number(angle_pit)+"°");
update();
}
客户端的实现:
客户端主要通过三个Slider来实现对角度的控制,在tableView控件里来显示历史数据,tableView里还有一个事故,我这里设置的是三个角度大于60度就会报警,一般报警就是事故变为1.0并且图标发生改变:
然后就是散点图的绘制:
chart = new QChart();
chart->setTitle("无人机飞行角度"); //设置表格标题
QScatterSeries *scatterSeries1 = new QScatterSeries(chart);
QScatterSeries *scatterSeries2 = new QScatterSeries(chart);
QScatterSeries *scatterSeries3 = new QScatterSeries(chart);
scatterSeries1->setName("偏航角度");
scatterSeries1->setPointLabelsFormat("@yPoint");
scatterSeries1->setPointLabelsVisible();
scatterSeries1->setMarkerSize(16); // 设置节点大小
scatterSeries2->setName("横滚角度");
scatterSeries2->setPointLabelsFormat("@yPoint");
scatterSeries2->setPointLabelsVisible();
scatterSeries2->setMarkerSize(16);
scatterSeries3->setName("俯视角度");
scatterSeries3->setPointLabelsFormat("@yPoint");
scatterSeries3->setPointLabelsVisible();
scatterSeries3->setMarkerSize(16);
QSqlQuery sql_query;
QString select_sql = "select * from info3";// order by 字段名 +asc 递增方式
if(!sql_query.exec(select_sql))
{
qDebug()<<"错误";
}
else
{
while(sql_query.next())//判断下个查询数据是否可用
{
static int i=1,j=1,k=1;
int a = sql_query.value(0).toDouble();//打印某行第一列
int b = sql_query.value(1).toDouble();
int c=sql_query.value(2).toDouble();
scatterSeries1->append(i,a);
scatterSeries2->append(j,b);
scatterSeries3->append(k,c);
i++;
j++;
k++;
if(i==90){
i=-90;
}
if(j==90){
j=-90;
}
if(k==0){
k=-90;
}
}
}
// 添加节点
// scatterSeries1->append(0,6);
// scatterSeries1->append(1,10);
// scatterSeries1->append(4,12);
// scatterSeries1->append(6,5);
// scatterSeries2->append(0,18);
// scatterSeries2->append(3,13);
// scatterSeries2->append(5,7);
// scatterSeries2->append(6,2);
chart->addSeries(scatterSeries1);
chart->addSeries(scatterSeries2);
chart->addSeries(scatterSeries3);
//设置动画效果
chart->setAnimationOptions(QChart::AllAnimations);
chart->createDefaultAxes();//设置网格线
chart->axes(Qt::Horizontal).first()->setRange(-90,90);// x轴范围
chart->axes(Qt::Vertical).first()->setRange(-90,90);// y轴范围
// Add space to label to add space between labels and axis在标签和轴之间加空格
QValueAxis *axisY = qobject_cast<QValueAxis*>(chart->axes(Qt::Vertical).first());
Q_ASSERT(axisY);
axisY->setLabelFormat("%.1f ");
chart->setTheme(QChart::ChartThemeDark);
QChartView *chartView;
chartView = new QChartView(chart);
zt++;
ui->widget1->insertWidget(0,chartView,0,Qt::Alignment());
if(zt==1){
ui->widget1->removeWidget(chartView);
zt=0;
}
可以实现数据的清空,一旦清空所有数据都会删除,散点图也会清除:
全部重置是对Slider的重置,导出数据是保存历史数据到csv文件:
导出pdf是保存历史数据到pdf中:
保存pdf代码:文章来源:https://www.toymoban.com/news/detail-406630.html
QFile pdfFile("D:\\test1.pdf");//输出文件名
if(!pdfFile.open(QIODevice::WriteOnly))
{
QMessageBox::warning(this,tr("write File"),tr("Cannot open file:\n%1").arg("d:\\test.pdf"));
return;
}
QPdfWriter *pdfWriter = new QPdfWriter(&pdfFile); //实例化QPdfWriter 可以设置PDF文件的一些参数
pdfWriter->setPageSize(QPagedPaintDevice::A4); //设置纸张为A4纸
pdfWriter->setResolution(QPrinter::ScreenResolution); //设置分辨率 屏幕分辨率 打印机分辨率 高分辨率
pdfWriter->setPageMargins(QMarginsF(40, 40, 40, 40)); //设置页边距 顺序是:左上右下
QPainter *pdfPainter = new QPainter(pdfWriter); //qt绘制工具
//设置标题
QTextOption option(Qt::AlignCenter); //标题居中显示
option.setWrapMode(QTextOption::WordWrap); //标题自动换行
// 设置标题字体 需要使用QT的QFont
QFont font;
font.setFamily("Microsoft YaHei"); //设置字体 微软雅黑、宋体之类的
font.setPointSize(22); //设置字体大小
//font.setItalic(true);//斜体
//font.setUnderline(true);//设置下划线
// font.setBold(true); //加粗
pdfPainter->setFont(font);
pdfPainter->drawText(QRect(3000, 0, 2100, 450), QString::QString::fromUtf8("历史数据"), option);//距离左边3000,上面0,标题字宽度2100,标题字高450(如果字显示不全,可以适当调整)
//设置内容
option.setAlignment(Qt::AlignLeft);
font.setPointSize(14); //字体大小14
pdfPainter->setFont(font);
pdfPainter->drawRect(200, 250, 2000, 1);
pdfPainter->drawRect(200, 700, 2000, 4);
pdfPainter->setFont(QFont("NSimSun", 12, QFont::Normal));
pdfPainter->setFont(QFont("NSimSun", 14, QFont::Normal));
option.setAlignment(Qt::AlignLeft);
font.setPointSize(10); //字体大小14
pdfPainter->setFont(font);
pdfPainter->drawText(200, 2000, QString::fromUtf8("偏移角度"));
pdfPainter->drawText(1200, 2000, QString::fromUtf8("横滚角度"));
pdfPainter->drawText(2200, 2000, QString::fromUtf8("俯视角度"));
pdfPainter->drawText(3200, 2000, QString::fromUtf8("事故"));
QString str = "select * from info3";
QSqlQuery query;
query.exec(str);
int i=0;
while(query.next())//依次取出下一行数据
{
i++;
QString x1 = query.value(0).toString();
QString x = query.value(1).toString();
QString y = query.value(2).toString();
QString z = query.value(3).toString();
pdfPainter->drawText(200, 2000+i*200, x1);
pdfPainter->drawText(1200, 2000+i*200, y);
pdfPainter->drawText(2200, 2000+i*200, x);
pdfPainter->drawText(3200, 2000+i*200, z);
if(2000+i*200>12000)
{
i=i-50;
pdfWriter->newPage();
pdfPainter->drawText(200, 2000+i*200, x1);
pdfPainter->drawText(1200, 2000+i*200, y);
pdfPainter->drawText(2200, 2000+i*200, x);
pdfPainter->drawText(3200, 2000+i*200, z);
}
}
delete pdfPainter;
delete pdfWriter;
QDesktopServices::openUrl(QUrl::fromLocalFile("D:\\test1.pdf"));
整体的项目就是这样,最后由衷地感谢我的小组团队,以及实训的所有老师
想要例子的可以私信,添加联系文章来源地址https://www.toymoban.com/news/detail-406630.html
到了这里,关于Qt无人机姿态模拟的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!