├── NGroundStation ├── .gitignore ├── GroundStation.pro ├── Headfile.h ├── Resources.qrc ├── calibration.cpp ├── calibration.h ├── calibration.ui ├── flightstate.cpp ├── flightstate.h ├── flightstate.ui ├── form.cpp ├── image │ ├── Logo.png │ ├── QQ.png │ ├── QQGroup.png │ ├── acce.png │ ├── blog.png │ ├── book.png │ ├── calibration.png │ ├── clearshow.png │ ├── clearwave.png │ ├── closecom.png │ ├── debug.png │ ├── default.png │ ├── defaultwave.png │ ├── export.png │ ├── getparam.png │ ├── gyro.png │ ├── help.png │ ├── hor.png │ ├── import.png │ ├── logo.ico │ ├── mag.png │ ├── main.png │ ├── noshow.png │ ├── opencom.png │ ├── quit.png │ ├── remote.png │ ├── send.png │ ├── send │ │ ├── clear.png │ │ ├── send.png │ │ └── zero.png │ ├── senddata.png │ ├── setup.png │ ├── show.png │ ├── stopwave.png │ ├── sw.png │ ├── taobao.png │ ├── tech.png │ ├── tozero.png │ ├── update.png │ ├── usb.png │ ├── wave.png │ ├── web.png │ ├── write.png │ ├── zoomin.png │ ├── zoomout.png │ ├── 无名创新背景图片.jpg │ └── 退出.png ├── logo.ico ├── main.cpp ├── mainwindow.cpp ├── mainwindow.h ├── mainwindow.ui ├── remotectrl.cpp ├── remotectrl.h ├── remotectrl.ui ├── sendandreceive.cpp ├── sendandreceive.h ├── sendandreceive.ui ├── serialportthread.cpp ├── serialportthread.h ├── serialsetup.cpp ├── serialsetup.h ├── serialsetup.ui ├── serialthread.qrc ├── setparameter.cpp ├── setparameter.h ├── setparameter.ui ├── waveshow.cpp ├── waveshow.h └── waveshow.ui ├── images ├── 1586249791769.png ├── NGS.png ├── basic_window.png ├── cal_window.png ├── learn-1586145845974.png ├── learn.png ├── main_window.png ├── noserial.png ├── open_serial-1586076513816.png ├── open_serial.png ├── para_window.png ├── pressed.png ├── public.png ├── remote_window.png ├── serialsetup.png ├── state_window.png ├── wave_import.png └── wave_window.png ├── readme.md └── 无名创新地面站.zip /NGroundStation/.gitignore: -------------------------------------------------------------------------------- 1 | # This file is used to ignore files which are generated 2 | # ---------------------------------------------------------------------------- 3 | 4 | *~ 5 | *.autosave 6 | *.a 7 | *.core 8 | *.moc 9 | *.o 10 | *.obj 11 | *.orig 12 | *.rej 13 | *.so 14 | *.so.* 15 | *_pch.h.cpp 16 | *_resource.rc 17 | *.qm 18 | .#* 19 | *.*# 20 | core 21 | !core/ 22 | tags 23 | .DS_Store 24 | .directory 25 | *.debug 26 | Makefile* 27 | *.prl 28 | *.app 29 | moc_*.cpp 30 | ui_*.h 31 | qrc_*.cpp 32 | Thumbs.db 33 | *.res 34 | *.rc 35 | /.qmake.cache 36 | /.qmake.stash 37 | 38 | # qtcreator generated files 39 | *.pro.user* 40 | 41 | # xemacs temporary files 42 | *.flc 43 | 44 | # Vim temporary files 45 | .*.swp 46 | 47 | # Visual Studio generated files 48 | *.ib_pdb_index 49 | *.idb 50 | *.ilk 51 | *.pdb 52 | *.sln 53 | *.suo 54 | *.vcproj 55 | *vcproj.*.*.user 56 | *.ncb 57 | *.sdf 58 | *.opensdf 59 | *.vcxproj 60 | *vcxproj.* 61 | 62 | # MinGW generated files 63 | *.Debug 64 | *.Release 65 | 66 | # Python byte code 67 | *.pyc 68 | 69 | # Binaries 70 | # -------- 71 | *.dll 72 | *.exe 73 | 74 | -------------------------------------------------------------------------------- /NGroundStation/GroundStation.pro: -------------------------------------------------------------------------------- 1 | QT += core gui 2 | QT += serialport 3 | QT += gui 4 | QT += datavisualization 5 | 6 | 7 | QMAKE_CXXFLAGS += -gstabs+ 8 | UI_DIR=./UI 9 | 10 | RC_ICONS = logo.ico 11 | 12 | DEFINES += QT_DLL QWT_DLL 13 | #LIBS += -L"D:\Qt\Qt5.13.2\5.13.2\mingw73_32\lib" -lqwtd 14 | LIBS += -L"D:\Qt\Qt5.13.2\5.13.2\mingw73_32\lib" -lqwt 15 | INCLUDEPATH += D:\Qt\Qt5.13.2\5.13.2\mingw73_32\include\Qwt 16 | 17 | DEFINES += QT_DLL QUC_DLL 18 | #LIBS += -L$$PWD/sdk/ -lqucd 19 | LIBS += -L$$PWD/sdk/ -lquc 20 | INCLUDEPATH += D:\Qt\Qt5.13.2\5.13.2\mingw73_32\include\Quc 21 | 22 | 23 | #INCLUDEPATH += $$PWD/sdk 24 | #CONFIG(release, debug|release){ 25 | #LIBS += -L$$PWD/sdk/ -lquc 26 | #} else { 27 | #unix {LIBS += -L$$PWD/sdk/ -lquc} 28 | #else {LIBS += -L$$PWD/sdk/ -lqucd} 29 | #} 30 | 31 | 32 | 33 | greaterThan(QT_MAJOR_VERSION, 4): QT += widgets 34 | 35 | 36 | # 一般加上pthread就可以 37 | LIBS += -pthread 38 | # 如果你的QT工程CONFIG中没有配置c++11,最好把下面两行也一并加上吧 39 | QMAKE_CXXFLAGS += -pthread 40 | QMAKE_CXXFLAGS += -std=c++11 41 | 42 | 43 | 44 | CONFIG += c++11 45 | 46 | # The following define makes your compiler emit warnings if you use 47 | # any Qt feature that has been marked deprecated (the exact warnings 48 | # depend on your compiler). Please consult the documentation of the 49 | # deprecated API in order to know how to port your code away from it. 50 | DEFINES += QT_DEPRECATED_WARNINGS 51 | 52 | # You can also make your code fail to compile if it uses deprecated APIs. 53 | # In order to do so, uncomment the following line. 54 | # You can also select to disable deprecated APIs only up to a certain version of Qt. 55 | #DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 56 | 57 | SOURCES += \ 58 | calibration.cpp \ 59 | flightstate.cpp \ 60 | main.cpp \ 61 | mainwindow.cpp \ 62 | remotectrl.cpp \ 63 | sendandreceive.cpp \ 64 | serialportthread.cpp \ 65 | serialsetup.cpp \ 66 | setparameter.cpp \ 67 | waveshow.cpp 68 | 69 | HEADERS += \ 70 | Headfile.h \ 71 | calibration.h \ 72 | flightstate.h \ 73 | mainwindow.h \ 74 | remotectrl.h \ 75 | sendandreceive.h \ 76 | serialportthread.h \ 77 | serialsetup.h \ 78 | setparameter.h \ 79 | waveshow.h 80 | 81 | FORMS += \ 82 | calibration.ui \ 83 | flightstate.ui \ 84 | mainwindow.ui \ 85 | remotectrl.ui \ 86 | sendandreceive.ui \ 87 | serialsetup.ui \ 88 | setparameter.ui \ 89 | waveshow.ui 90 | 91 | # Default rules for deployment. 92 | qnx: target.path = /tmp/$${TARGET}/bin 93 | else: unix:!android: target.path = /opt/$${TARGET}/bin 94 | !isEmpty(target.path): INSTALLS += target 95 | 96 | DISTFILES += \ 97 | image/blog.png \ 98 | image/clearwave.png \ 99 | image/defaultwave.png \ 100 | image/help.png \ 101 | image/stopwave.png 102 | 103 | RESOURCES += \ 104 | Resources.qrc 105 | -------------------------------------------------------------------------------- /NGroundStation/Headfile.h: -------------------------------------------------------------------------------- 1 | #ifndef HEADFILE_H 2 | #define HEADFILE_H 3 | 4 | #define ABS(X) (((X)>0)?(X):-(X)) 5 | #define MAX(a,b) ((a)>(b)?(a):(b)) 6 | #define MIN(a,b) ((a)>(b)?(b):(a)) 7 | 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | 14 | 15 | #include 16 | #include 17 | #include 18 | #include 19 | #include //提供访问串行端口的功能 20 | #include //提供关于现有串行端口的信息。 21 | #include 22 | //#include 23 | #include 24 | #include 25 | #include 26 | #include 27 | 28 | typedef struct{ 29 | int baudrate; 30 | int parity; 31 | int dataBit; 32 | int stopBit; 33 | QString serialname; 34 | }serial_config; 35 | 36 | //#include 37 | #include 38 | #include 39 | #include 40 | #include 41 | #include 42 | #include 43 | #include 44 | #include 45 | #include 46 | #include 47 | #include 48 | #include 49 | #include 50 | #include 51 | 52 | #include "gaugecompass.h" 53 | #include "gaugeplane.h" 54 | #include "gaugespeed.h" 55 | #include "rulerdouble.h" 56 | #include "rulerbar.h" 57 | #include "customrocker.h" 58 | #include "xslider.h" 59 | 60 | 61 | #include "serialsetup.h" 62 | #include "ui_serialsetup.h" 63 | #include "sendandreceive.h" 64 | #include "ui_sendandreceive.h" 65 | #include "waveshow.h" 66 | #include "flightstate.h" 67 | #include "serialportthread.h" 68 | #include "setparameter.h" 69 | #include "remotectrl.h" 70 | #include "calibration.h" 71 | 72 | #endif // HEADFILE_H 73 | -------------------------------------------------------------------------------- /NGroundStation/Resources.qrc: -------------------------------------------------------------------------------- 1 | 2 | 3 | image/clearshow.png 4 | image/closecom.png 5 | image/debug.png 6 | image/Logo.png 7 | image/main.png 8 | image/opencom.png 9 | image/send.png 10 | image/setup.png 11 | image/usb.png 12 | image/wave.png 13 | image/send/send.png 14 | image/send/clear.png 15 | image/send/zero.png 16 | image/default.png 17 | image/getparam.png 18 | image/write.png 19 | image/defaultwave.png 20 | image/stopwave.png 21 | image/clearwave.png 22 | image/senddata.png 23 | image/help.png 24 | image/web.png 25 | image/blog.png 26 | image/QQ.png 27 | image/QQGroup.png 28 | image/taobao.png 29 | image/tech.png 30 | image/zoomin.png 31 | image/zoomout.png 32 | image/tozero.png 33 | image/sw.png 34 | image/noshow.png 35 | image/show.png 36 | image/book.png 37 | image/remote.png 38 | image/calibration.png 39 | image/mag.png 40 | image/acce.png 41 | image/gyro.png 42 | image/hor.png 43 | image/quit.png 44 | image/import.png 45 | image/export.png 46 | image/update.png 47 | 48 | 49 | -------------------------------------------------------------------------------- /NGroundStation/calibration.cpp: -------------------------------------------------------------------------------- 1 | #include "calibration.h" 2 | #include "ui_calibration.h" 3 | #include "Headfile.h" 4 | 5 | 6 | calibration::calibration(QWidget *parent) : 7 | QWidget(parent), 8 | ui(new Ui::calibration) 9 | { 10 | ui->setupUi(this); 11 | this->setWindowTitle("飞控校准"); 12 | setWindowIcon(QIcon(":/image/calibration.png")); //设置主界面LOGO 13 | setWindowFlags(windowFlags()&~Qt::WindowMaximizeButtonHint); // 禁止最大化按钮 14 | setFixedSize(this->width(),this->height()); // 禁止拖动窗口大小 15 | 16 | QPalette palette(this->palette()); 17 | palette.setColor(QPalette::Background, QColor(233,235,254));//QColor(78,168,243) 18 | this->setPalette(palette); 19 | 20 | 21 | timer = new QTimer(this); 22 | connect(timer, SIGNAL(timeout()), this, SLOT(timer_show())); 23 | timer->start(50);//20HZ 24 | 25 | } 26 | 27 | calibration::~calibration() 28 | { 29 | delete ui; 30 | } 31 | 32 | 33 | 34 | //当窗口出发关闭事件后,将信号发射出去 35 | void calibration::closeEvent(QCloseEvent *) 36 | { 37 | emit exitwindows(); 38 | } 39 | 40 | 41 | void calibration::getcheck(uint8_t ch) 42 | { 43 | QDateTime current_date_time = QDateTime::currentDateTime(); 44 | QString current_time = current_date_time.toString("hh:mm:ss.zzz"); 45 | if(ch==0x13) 46 | { 47 | ui->msg->appendPlainText(current_time+"毫秒>飞控传感器数据校准成功"); 48 | } 49 | else if(ch==0x14) 50 | { 51 | ui->msg->appendPlainText(current_time+"毫秒>飞控传感器校准参数获取成功"); 52 | } 53 | ui->msg->moveCursor(QTextCursor::End, QTextCursor::MoveAnchor); 54 | } 55 | 56 | void calibration::on_clear_clicked() 57 | { 58 | ui->msg->clear(); 59 | ui->msg->moveCursor(QTextCursor::End, QTextCursor::MoveAnchor); 60 | } 61 | 62 | 63 | 64 | void calibration::timer_show() 65 | { 66 | ui->gx->setText(QString::number(gyro_x_raw,10,4)); 67 | ui->gy->setText(QString::number(gyro_y_raw,10,4)); 68 | ui->gz->setText(QString::number(gyro_z_raw,10,4)); 69 | ui->ax->setText(QString::number(acce_x_raw,10,4)); 70 | ui->ay->setText(QString::number(acce_y_raw,10,4)); 71 | ui->az->setText(QString::number(acce_z_raw,10,4)); 72 | ui->mx->setText(QString::number(mag_x_raw,10,4)); 73 | ui->my->setText(QString::number(mag_y_raw,10,4)); 74 | ui->mz->setText(QString::number(mag_z_raw,10,4)); 75 | 76 | ui->temp->setText(QString::number(imu_temp,10,2)); 77 | 78 | 79 | ui->gx_offset->setText(QString::number(gyro_x_offset,10,4)); 80 | ui->gy_offset->setText(QString::number(gyro_y_offset,10,4)); 81 | ui->gz_offset->setText(QString::number(gyro_z_offset,10,4)); 82 | ui->ax_offset->setText(QString::number(acce_x_offset,10,4)); 83 | ui->ay_offset->setText(QString::number(acce_y_offset,10,4)); 84 | ui->az_offset->setText(QString::number(acce_z_offset,10,4)); 85 | ui->mx_offset->setText(QString::number(mag_x_offset,10,4)); 86 | ui->my_offset->setText(QString::number(mag_y_offset,10,4)); 87 | ui->mz_offset->setText(QString::number(mag_z_offset,10,4)); 88 | ui->ax_k->setText(QString::number(acce_x_scale,10,4)); 89 | ui->ay_k->setText(QString::number(acce_y_scale,10,4)); 90 | ui->az_k->setText(QString::number(acce_z_scale,10,4)); 91 | 92 | ui->pitch_offset->setText(QString::number(pitch_offset,10,4)); 93 | ui->roll_offset->setText(QString::number(roll_offset,10,4)); 94 | 95 | 96 | if(gyro_auto_cal_flag==0x00) ui->cal_finished->setText("否"); 97 | else ui->cal_finished->setText("是"); 98 | } 99 | 100 | 101 | extern QSerialPort* serialPort; 102 | bool calibration::Send_CAL(uint8_t cal_flag,uint8_t cal_step,uint8_t cal_cmd)//地面站指令发送RC数据 103 | { 104 | uint8_t data_to_send[50]; 105 | uint8_t sum = 0,i=0,cnt=0; 106 | uint16_t _temp; 107 | data_to_send[cnt++]=NCLink_Head1; 108 | data_to_send[cnt++]=NCLink_Head0; 109 | data_to_send[cnt++]=0x0B; 110 | data_to_send[cnt++]=0; 111 | 112 | data_to_send[cnt++]=BYTE0(cal_flag); 113 | data_to_send[cnt++]=BYTE0(cal_step); 114 | data_to_send[cnt++]=BYTE0(cal_cmd); 115 | 116 | 117 | data_to_send[3] = cnt-4; 118 | for(i=0;iwrite((char *)(data_to_send),cnt); 125 | return true; 126 | } 127 | else 128 | { 129 | QDateTime current_date_time = QDateTime::currentDateTime(); 130 | QString current_time = current_date_time.toString("hh:mm:ss.zzz"); 131 | ui->msg->appendPlainText(current_time+"毫秒>串口发送失败,请检查串口配置"); 132 | ui->msg->moveCursor(QTextCursor::End, QTextCursor::MoveAnchor); 133 | return false; 134 | } 135 | } 136 | 137 | 138 | void calibration::on_gyro_cal_start_clicked() 139 | { 140 | if(Send_CAL(0x01,0x00,0x00)==true) 141 | { 142 | QDateTime current_date_time = QDateTime::currentDateTime(); 143 | QString current_time = current_date_time.toString("hh:mm:ss.zzz"); 144 | ui->msg->appendPlainText(current_time+"毫秒>陀螺仪校准指令已发送"); 145 | ui->msg->moveCursor(QTextCursor::End, QTextCursor::MoveAnchor); 146 | } 147 | } 148 | 149 | void calibration::on_acc_cal_start_clicked() 150 | { 151 | if(Send_CAL(0x02,0x00,0x00)==true) 152 | { 153 | QDateTime current_date_time = QDateTime::currentDateTime(); 154 | QString current_time = current_date_time.toString("hh:mm:ss.zzz"); 155 | ui->msg->appendPlainText(current_time+"毫秒>加速度计校准指令已发送"); 156 | ui->msg->moveCursor(QTextCursor::End, QTextCursor::MoveAnchor); 157 | } 158 | } 159 | 160 | void calibration::on_mag_cal_start_clicked() 161 | { 162 | if(Send_CAL(0x03,0x01,0x00)==true) 163 | { 164 | QDateTime current_date_time = QDateTime::currentDateTime(); 165 | QString current_time = current_date_time.toString("hh:mm:ss.zzz"); 166 | ui->msg->appendPlainText(current_time+"毫秒>磁力计校准指令已发送"); 167 | ui->msg->moveCursor(QTextCursor::End, QTextCursor::MoveAnchor); 168 | } 169 | } 170 | 171 | void calibration::on_hor_cal_start_clicked() 172 | { 173 | if(Send_CAL(0x04,0x00,0x00)==true) 174 | { 175 | QDateTime current_date_time = QDateTime::currentDateTime(); 176 | QString current_time = current_date_time.toString("hh:mm:ss.zzz"); 177 | ui->msg->appendPlainText(current_time+"毫秒>机架水平校准指令已发送"); 178 | ui->msg->moveCursor(QTextCursor::End, QTextCursor::MoveAnchor); 179 | } 180 | } 181 | 182 | 183 | 184 | void calibration::on_bt1_acc_cal_clicked() 185 | { 186 | if(Send_CAL(0x00,0x01,0x00)==true) 187 | { 188 | QDateTime current_date_time = QDateTime::currentDateTime(); 189 | QString current_time = current_date_time.toString("hh:mm:ss.zzz"); 190 | ui->msg->appendPlainText(current_time+"毫秒>第1面校准,请将飞机水平放置"); 191 | ui->msg->moveCursor(QTextCursor::End, QTextCursor::MoveAnchor); 192 | } 193 | } 194 | 195 | void calibration::on_bt2_acc_cal_clicked() 196 | { 197 | if(Send_CAL(0x00,0x02,0x00)==true) 198 | { 199 | QDateTime current_date_time = QDateTime::currentDateTime(); 200 | QString current_time = current_date_time.toString("hh:mm:ss.zzz"); 201 | ui->msg->appendPlainText(current_time+"毫秒>第2面校准,请将飞机右侧朝上放置"); 202 | ui->msg->moveCursor(QTextCursor::End, QTextCursor::MoveAnchor); 203 | } 204 | } 205 | 206 | void calibration::on_bt3_acc_cal_clicked() 207 | { 208 | if(Send_CAL(0x00,0x03,0x00)==true) 209 | { 210 | QDateTime current_date_time = QDateTime::currentDateTime(); 211 | QString current_time = current_date_time.toString("hh:mm:ss.zzz"); 212 | ui->msg->appendPlainText(current_time+"毫秒>第3面校准,请将飞机左侧朝上放置"); 213 | ui->msg->moveCursor(QTextCursor::End, QTextCursor::MoveAnchor); 214 | } 215 | } 216 | 217 | void calibration::on_bt4_acc_cal_clicked() 218 | { 219 | if(Send_CAL(0x00,0x04,0x00)==true) 220 | { 221 | QDateTime current_date_time = QDateTime::currentDateTime(); 222 | QString current_time = current_date_time.toString("hh:mm:ss.zzz"); 223 | ui->msg->appendPlainText(current_time+"毫秒>第4面校准,请将飞机机头朝下放置"); 224 | ui->msg->moveCursor(QTextCursor::End, QTextCursor::MoveAnchor); 225 | } 226 | } 227 | 228 | void calibration::on_bt5_acc_cal_clicked() 229 | { 230 | if(Send_CAL(0x00,0x05,0x00)==true) 231 | { 232 | QDateTime current_date_time = QDateTime::currentDateTime(); 233 | QString current_time = current_date_time.toString("hh:mm:ss.zzz"); 234 | ui->msg->appendPlainText(current_time+"毫秒>第5面校准,请将飞机机头朝上放置"); 235 | ui->msg->moveCursor(QTextCursor::End, QTextCursor::MoveAnchor); 236 | } 237 | } 238 | 239 | void calibration::on_bt6_acc_cal_clicked() 240 | { 241 | if(Send_CAL(0x00,0x06,0x00)==true) 242 | { 243 | QDateTime current_date_time = QDateTime::currentDateTime(); 244 | QString current_time = current_date_time.toString("hh:mm:ss.zzz"); 245 | ui->msg->appendPlainText(current_time+"毫秒>第6面校准,请将飞机翻转并水平放置"); 246 | ui->msg->moveCursor(QTextCursor::End, QTextCursor::MoveAnchor); 247 | } 248 | } 249 | 250 | void calibration::on_get_cal_para_clicked() 251 | { 252 | if(Send_CAL(0x00,0x00,0x01)==true) 253 | { 254 | QDateTime current_date_time = QDateTime::currentDateTime(); 255 | QString current_time = current_date_time.toString("hh:mm:ss.zzz"); 256 | ui->msg->appendPlainText(current_time+"毫秒>获取校准参数发送成功"); 257 | ui->msg->moveCursor(QTextCursor::End, QTextCursor::MoveAnchor); 258 | } 259 | } 260 | 261 | 262 | void calibration::on_quit_cal_now_clicked() 263 | { 264 | if(Send_CAL(0x00,0x00,0x00)==true) 265 | { 266 | QDateTime current_date_time = QDateTime::currentDateTime(); 267 | QString current_time = current_date_time.toString("hh:mm:ss.zzz"); 268 | ui->msg->appendPlainText(current_time+"毫秒>提前终止当前校准指令已发送"); 269 | ui->msg->moveCursor(QTextCursor::End, QTextCursor::MoveAnchor); 270 | } 271 | } 272 | -------------------------------------------------------------------------------- /NGroundStation/calibration.h: -------------------------------------------------------------------------------- 1 | #ifndef CALIBRATION_H 2 | #define CALIBRATION_H 3 | 4 | #include 5 | 6 | namespace Ui { 7 | class calibration; 8 | } 9 | 10 | class calibration : public QWidget 11 | { 12 | Q_OBJECT 13 | public: 14 | explicit calibration(QWidget *parent = nullptr); 15 | ~calibration(); 16 | void closeEvent(QCloseEvent *);//重写关闭事件 17 | bool Send_CAL(uint8_t cal_flag,uint8_t cal_step,uint8_t cal_cmd); 18 | 19 | QTimer *timer=nullptr; 20 | private slots: 21 | void on_gyro_cal_start_clicked(); 22 | void on_acc_cal_start_clicked(); 23 | void on_mag_cal_start_clicked(); 24 | void on_hor_cal_start_clicked(); 25 | void on_bt1_acc_cal_clicked(); 26 | void on_bt2_acc_cal_clicked(); 27 | void on_bt3_acc_cal_clicked(); 28 | void on_bt4_acc_cal_clicked(); 29 | void on_bt5_acc_cal_clicked(); 30 | void on_bt6_acc_cal_clicked(); 31 | void on_get_cal_para_clicked(); 32 | void timer_show(); 33 | void getcheck(uint8_t ch); 34 | void on_clear_clicked(); 35 | 36 | void on_quit_cal_now_clicked(); 37 | 38 | private: 39 | Ui::calibration *ui; 40 | signals: 41 | void exitwindows();//新建一个信号槽 42 | }; 43 | 44 | #endif // CALIBRATION_H 45 | -------------------------------------------------------------------------------- /NGroundStation/flightstate.cpp: -------------------------------------------------------------------------------- 1 | #include "Headfile.h" 2 | #include "flightstate.h" 3 | #include "ui_flightstate.h" 4 | 5 | QwtPlotCurve *flightstate_ch[3]; 6 | double flightstate_ch_val[3][flightstate_wave_num_max]; 7 | double flightstate_time[flightstate_wave_num_max]={0}; 8 | bool waveshow_flag=true; 9 | int waveclear_cnt=0; 10 | QTimer *flight_show=nullptr; 11 | flightstate::flightstate(QWidget *parent) : 12 | QWidget(parent), 13 | ui(new Ui::flightstate) 14 | { 15 | ui->setupUi(this); 16 | this->setWindowTitle("飞控状态"); //设置主界面名称 17 | setWindowIcon(QIcon(":/image/Logo.png")); //设置主界面LOGO 18 | //setWindowFlags(windowFlags()&~Qt::WindowMaximizeButtonHint); // 禁止最大化按钮 19 | //setFixedSize(this->width(),this->height()); // 禁止拖动窗口大小 20 | 21 | QPalette palette(this->palette()); 22 | palette.setColor(QPalette::Background, QColor(233,235,254));//QColor(78,168,243) 23 | this->setPalette(palette); 24 | flightstate_ch[0] = new QwtPlotCurve("Pitch"); 25 | flightstate_ch[1] = new QwtPlotCurve("Roll"); 26 | flightstate_ch[2] = new QwtPlotCurve("Yaw"); 27 | 28 | flightstate_ch[0]->setPen(QColor(255,0,0)); //设定前景颜色,就是字体颜色 29 | flightstate_ch[1]->setPen(QColor(0,255,0)); //设定前景颜色,就是字体颜色 30 | flightstate_ch[2]->setPen(QColor(0,0,255)); //设定前景颜色,就是字体颜 31 | 32 | //设置示波器背景网格 33 | QwtPlotGrid *grid = new QwtPlotGrid(); 34 | grid->setPen(Qt::white,1.0,Qt::DashLine ); 35 | grid->enableX(true); 36 | grid->enableXMin(true); 37 | grid->enableY(true); 38 | grid->enableYMin(true); 39 | grid->setMajorPen(Qt::white,1.0,Qt::SolidLine ); 40 | grid->attach(ui->qwtPlot); 41 | 42 | ui->qwtPlot->setAxisScale(QwtPlot::yLeft,-180.0,360.0); 43 | ui->qwtPlot->setAxisScale(QwtPlot::xBottom,0,flightstate_wave_num_max); 44 | ui->qwtPlot->setTitle("姿态角曲线"); 45 | ui->qwtPlot->setAxisTitle(QwtPlot::yLeft,"Degree"); 46 | ui->qwtPlot->setAxisTitle(QwtPlot::xBottom,"Sampling Points"); 47 | 48 | //ui->qwtPlot->insertLegend(new QwtLegend(), QwtPlot::RightLegend);//设置右边标注 49 | QwtLegend *legend = new QwtLegend;//实例化图例 50 | legend->setDefaultItemMode( QwtLegendData::Checkable );//图例可以选择,Checkable 51 | ui->qwtPlot->insertLegend(legend, QwtPlot::RightLegend );//qwtPlot中插入图例 52 | //连接槽,处理选择事件 53 | connect(legend, 54 | SIGNAL(checked(const QVariant &, bool, int)), 55 | SLOT(showItem( const QVariant &, bool)));//点击图例操作 56 | 57 | new QwtPlotMagnifier(ui->qwtPlot->canvas());//使用滚轮放大/缩小 58 | new QwtPlotPanner(ui->qwtPlot->canvas());//使用鼠标左键平移 59 | 60 | /* 61 | //鼠标左键选择区域放大:(右键还原) 62 | QwtPlotZoomer* zoomer = new QwtPlotZoomer( ui->qwtPlot->canvas() ); 63 | zoomer->setRubberBandPen( QColor( Qt::black ) ); 64 | zoomer->setTrackerPen( QColor( Qt::black ) ); 65 | zoomer->setMousePattern(QwtEventPattern::MouseSelect2,Qt::RightButton, Qt::ControlModifier ); 66 | zoomer->setMousePattern(QwtEventPattern::MouseSelect3,Qt::RightButton ); 67 | */ 68 | 69 | 70 | for(uint16_t i=0;istart(50);//20HZ 79 | } 80 | 81 | flightstate::~flightstate() 82 | { 83 | delete ui; 84 | } 85 | 86 | 87 | void flightstate::timer_flight_show() 88 | { 89 | 90 | ui->pitch->setText(QString::number(pitch,10,2)); 91 | ui->roll->setText(QString::number(roll,10,2)); 92 | ui->yaw->setText(QString::number(yaw,10,2)); 93 | 94 | ui->alt->setText(QString::number(alt_pos_fus,10,2)); 95 | ui->vz->setText(QString::number(alt_vel_fus,10,2)); 96 | ui->accelz->setText(QString::number(alt_accel_fus)); 97 | 98 | ui->vbat->setText(QString::number(vbat,10,2)); 99 | ui->imu_temp->setText(QString::number(imu_temp,10,2)); 100 | 101 | if(fly_mode==1) ui->flightmode->setText("姿态"); 102 | else if(fly_mode==2) ui->flightmode->setText("定高"); 103 | 104 | if(armed_flag==0) ui->armed->setText("锁定"); 105 | else if(armed_flag==1) ui->armed->setText("解锁"); 106 | 107 | if(waveshow_flag==true) 108 | { 109 | for(uint16_t i=0;i<3;i++) 110 | flightstate_ch[i]->setSamples(flightstate_time,flightstate_ch_val[i],waveclear_cnt);//更新每个通道数据 111 | for(uint16_t i=0;i<3;i++) 112 | flightstate_ch[i]->attach(ui->qwtPlot);//将通道数据写入qwt 113 | ui->qwtPlot->replot(); 114 | } 115 | 116 | ui->ax->setText(QString::number(ax)); 117 | ui->ay->setText(QString::number(ay)); 118 | ui->az->setText(QString::number(az)); 119 | ui->gx->setText(QString::number(gx)); 120 | ui->gy->setText(QString::number(gy)); 121 | ui->gz->setText(QString::number(gz)); 122 | ui->mx->setText(QString::number(mx)); 123 | ui->my->setText(QString::number(my)); 124 | ui->mz->setText(QString::number(mz)); 125 | 126 | ui->ch0->setText(QString::number(rc[0])); 127 | ui->ch1->setText(QString::number(rc[1])); 128 | ui->ch2->setText(QString::number(rc[2])); 129 | ui->ch3->setText(QString::number(rc[3])); 130 | ui->ch4->setText(QString::number(rc[4])); 131 | ui->ch5->setText(QString::number(rc[5])); 132 | ui->ch6->setText(QString::number(rc[6])); 133 | ui->ch7->setText(QString::number(rc[7])); 134 | 135 | ui->ch0_pro->setValue(rc[0]); // 当前进度 136 | ui->ch1_pro->setValue(rc[1]); // 当前进度 137 | ui->ch2_pro->setValue(rc[2]); // 当前进度 138 | ui->ch3_pro->setValue(rc[3]); // 当前进度 139 | ui->ch4_pro->setValue(rc[4]); // 当前进度 140 | ui->ch5_pro->setValue(rc[5]); // 当前进度 141 | ui->ch6_pro->setValue(rc[6]); // 当前进度 142 | ui->ch7_pro->setValue(rc[7]); // 当前进度 143 | 144 | 145 | ui->baro_alt->setText(QString::number(alt_obs_baro)); 146 | ui->ult_alt->setText(QString::number(alt_obs_ult)); 147 | ui->gps_lng->setText(QString::number(gps_lng,10,6)); 148 | ui->gps_lat->setText(QString::number(gps_lat,10,6)); 149 | ui->gps_alt->setText(QString::number(gps_alt)); 150 | ui->gps_vel_e->setText(QString::number(lng_vel_obs)); 151 | ui->gps_vel_n->setText(QString::number(lat_vel_obs)); 152 | ui->numsv->setText(QString::number(gps_satellite_num)); 153 | 154 | ui->gaugePlane->setDegValue(roll); 155 | ui->gaugePlane->setRollValue(pitch); 156 | ui->gaugeCompass->setValue(360-yaw); 157 | 158 | ui->rulerLine->setValue(yaw); 159 | 160 | ui->rulerBar->setMinValue(alt_pos_fus-50); 161 | ui->rulerBar->setMaxValue(alt_pos_fus+50); 162 | ui->rulerBar->setValue(alt_pos_fus); 163 | 164 | ui->gaugeSpeed->setValue(alt_vel_fus); 165 | 166 | 167 | ui->opt_vel_p->setText(QString::number(opt_vel_p)); 168 | ui->opt_vel_r->setText(QString::number(opt_vel_r)); 169 | } 170 | 171 | void flightstate::on_clearwave_clicked() 172 | { 173 | for(uint16_t i=0;i<3;i++) 174 | { 175 | for(uint16_t j=0;jqwtPlot->infoToItem(itemInfo);//获取曲线 186 | if(plotItem) plotItem->setVisible(on);//根据图例选择状态,设置曲线隐藏还是显示 187 | //ui->qwtPlot->replot(); 188 | 189 | } 190 | 191 | void flightstate::on_defaultwave_clicked() 192 | { 193 | ui->qwtPlot->setAxisScale(QwtPlot::yLeft,-180.0,360.0); 194 | ui->qwtPlot->setAxisScale(QwtPlot::xBottom,0,flightstate_wave_num_max); 195 | //ui->qwtPlot->replot(); 196 | } 197 | 198 | void flightstate::on_stopwave_clicked() 199 | { 200 | if(ui->stopwave->text()=="停止显示") 201 | { 202 | ui->stopwave->setText("开始显示"); 203 | waveshow_flag=false; 204 | } 205 | else 206 | { 207 | ui->stopwave->setText("停止显示"); 208 | waveshow_flag=true; 209 | } 210 | } 211 | 212 | 213 | //当窗口出发关闭事件后,将信号发射出去 214 | void flightstate::closeEvent(QCloseEvent *) 215 | { 216 | emit exitwindows(); 217 | } 218 | -------------------------------------------------------------------------------- /NGroundStation/flightstate.h: -------------------------------------------------------------------------------- 1 | #ifndef FLIGHTSTATE_H 2 | #define FLIGHTSTATE_H 3 | 4 | #include 5 | #include 6 | 7 | 8 | #define flightstate_wave_num_max 200 9 | extern QwtPlotCurve *flightstate_ch[3]; 10 | extern double flightstate_ch_val[3][flightstate_wave_num_max]; 11 | extern double flightstate_time[flightstate_wave_num_max]; 12 | extern int waveclear_cnt; 13 | 14 | namespace Ui { 15 | class flightstate; 16 | } 17 | 18 | class flightstate : public QWidget 19 | { 20 | Q_OBJECT 21 | public: 22 | explicit flightstate(QWidget *parent = nullptr); 23 | ~flightstate(); 24 | //重写关闭事件 25 | void closeEvent(QCloseEvent *); 26 | //private: 27 | Ui::flightstate *ui; 28 | private slots: 29 | void timer_flight_show(); 30 | void on_clearwave_clicked(); 31 | void showItem(const QVariant &itemInfo, bool on); 32 | void on_defaultwave_clicked(); 33 | void on_stopwave_clicked(); 34 | signals: 35 | void exitwindows();//新建一个信号槽 36 | }; 37 | 38 | #endif // FLIGHTSTATE_H 39 | -------------------------------------------------------------------------------- /NGroundStation/form.cpp: -------------------------------------------------------------------------------- 1 | #include "form.h" 2 | #include "ui_form.h" 3 | 4 | Form::Form(QWidget *parent) : 5 | QWidget(parent), 6 | ui(new Ui::Form) 7 | { 8 | ui->setupUi(this); 9 | } 10 | 11 | Form::~Form() 12 | { 13 | delete ui; 14 | } 15 | -------------------------------------------------------------------------------- /NGroundStation/image/Logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wustyuyi/NGroundStation/ddcdffde18b8c035d6bbe78ea84d704106d2d6d6/NGroundStation/image/Logo.png -------------------------------------------------------------------------------- /NGroundStation/image/QQ.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wustyuyi/NGroundStation/ddcdffde18b8c035d6bbe78ea84d704106d2d6d6/NGroundStation/image/QQ.png -------------------------------------------------------------------------------- /NGroundStation/image/QQGroup.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wustyuyi/NGroundStation/ddcdffde18b8c035d6bbe78ea84d704106d2d6d6/NGroundStation/image/QQGroup.png -------------------------------------------------------------------------------- /NGroundStation/image/acce.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wustyuyi/NGroundStation/ddcdffde18b8c035d6bbe78ea84d704106d2d6d6/NGroundStation/image/acce.png -------------------------------------------------------------------------------- /NGroundStation/image/blog.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wustyuyi/NGroundStation/ddcdffde18b8c035d6bbe78ea84d704106d2d6d6/NGroundStation/image/blog.png -------------------------------------------------------------------------------- /NGroundStation/image/book.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wustyuyi/NGroundStation/ddcdffde18b8c035d6bbe78ea84d704106d2d6d6/NGroundStation/image/book.png -------------------------------------------------------------------------------- /NGroundStation/image/calibration.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wustyuyi/NGroundStation/ddcdffde18b8c035d6bbe78ea84d704106d2d6d6/NGroundStation/image/calibration.png -------------------------------------------------------------------------------- /NGroundStation/image/clearshow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wustyuyi/NGroundStation/ddcdffde18b8c035d6bbe78ea84d704106d2d6d6/NGroundStation/image/clearshow.png -------------------------------------------------------------------------------- /NGroundStation/image/clearwave.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wustyuyi/NGroundStation/ddcdffde18b8c035d6bbe78ea84d704106d2d6d6/NGroundStation/image/clearwave.png -------------------------------------------------------------------------------- /NGroundStation/image/closecom.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wustyuyi/NGroundStation/ddcdffde18b8c035d6bbe78ea84d704106d2d6d6/NGroundStation/image/closecom.png -------------------------------------------------------------------------------- /NGroundStation/image/debug.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wustyuyi/NGroundStation/ddcdffde18b8c035d6bbe78ea84d704106d2d6d6/NGroundStation/image/debug.png -------------------------------------------------------------------------------- /NGroundStation/image/default.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wustyuyi/NGroundStation/ddcdffde18b8c035d6bbe78ea84d704106d2d6d6/NGroundStation/image/default.png -------------------------------------------------------------------------------- /NGroundStation/image/defaultwave.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wustyuyi/NGroundStation/ddcdffde18b8c035d6bbe78ea84d704106d2d6d6/NGroundStation/image/defaultwave.png -------------------------------------------------------------------------------- /NGroundStation/image/export.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wustyuyi/NGroundStation/ddcdffde18b8c035d6bbe78ea84d704106d2d6d6/NGroundStation/image/export.png -------------------------------------------------------------------------------- /NGroundStation/image/getparam.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wustyuyi/NGroundStation/ddcdffde18b8c035d6bbe78ea84d704106d2d6d6/NGroundStation/image/getparam.png -------------------------------------------------------------------------------- /NGroundStation/image/gyro.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wustyuyi/NGroundStation/ddcdffde18b8c035d6bbe78ea84d704106d2d6d6/NGroundStation/image/gyro.png -------------------------------------------------------------------------------- /NGroundStation/image/help.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wustyuyi/NGroundStation/ddcdffde18b8c035d6bbe78ea84d704106d2d6d6/NGroundStation/image/help.png -------------------------------------------------------------------------------- /NGroundStation/image/hor.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wustyuyi/NGroundStation/ddcdffde18b8c035d6bbe78ea84d704106d2d6d6/NGroundStation/image/hor.png -------------------------------------------------------------------------------- /NGroundStation/image/import.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wustyuyi/NGroundStation/ddcdffde18b8c035d6bbe78ea84d704106d2d6d6/NGroundStation/image/import.png -------------------------------------------------------------------------------- /NGroundStation/image/logo.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wustyuyi/NGroundStation/ddcdffde18b8c035d6bbe78ea84d704106d2d6d6/NGroundStation/image/logo.ico -------------------------------------------------------------------------------- /NGroundStation/image/mag.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wustyuyi/NGroundStation/ddcdffde18b8c035d6bbe78ea84d704106d2d6d6/NGroundStation/image/mag.png -------------------------------------------------------------------------------- /NGroundStation/image/main.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wustyuyi/NGroundStation/ddcdffde18b8c035d6bbe78ea84d704106d2d6d6/NGroundStation/image/main.png -------------------------------------------------------------------------------- /NGroundStation/image/noshow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wustyuyi/NGroundStation/ddcdffde18b8c035d6bbe78ea84d704106d2d6d6/NGroundStation/image/noshow.png -------------------------------------------------------------------------------- /NGroundStation/image/opencom.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wustyuyi/NGroundStation/ddcdffde18b8c035d6bbe78ea84d704106d2d6d6/NGroundStation/image/opencom.png -------------------------------------------------------------------------------- /NGroundStation/image/quit.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wustyuyi/NGroundStation/ddcdffde18b8c035d6bbe78ea84d704106d2d6d6/NGroundStation/image/quit.png -------------------------------------------------------------------------------- /NGroundStation/image/remote.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wustyuyi/NGroundStation/ddcdffde18b8c035d6bbe78ea84d704106d2d6d6/NGroundStation/image/remote.png -------------------------------------------------------------------------------- /NGroundStation/image/send.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wustyuyi/NGroundStation/ddcdffde18b8c035d6bbe78ea84d704106d2d6d6/NGroundStation/image/send.png -------------------------------------------------------------------------------- /NGroundStation/image/send/clear.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wustyuyi/NGroundStation/ddcdffde18b8c035d6bbe78ea84d704106d2d6d6/NGroundStation/image/send/clear.png -------------------------------------------------------------------------------- /NGroundStation/image/send/send.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wustyuyi/NGroundStation/ddcdffde18b8c035d6bbe78ea84d704106d2d6d6/NGroundStation/image/send/send.png -------------------------------------------------------------------------------- /NGroundStation/image/send/zero.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wustyuyi/NGroundStation/ddcdffde18b8c035d6bbe78ea84d704106d2d6d6/NGroundStation/image/send/zero.png -------------------------------------------------------------------------------- /NGroundStation/image/senddata.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wustyuyi/NGroundStation/ddcdffde18b8c035d6bbe78ea84d704106d2d6d6/NGroundStation/image/senddata.png -------------------------------------------------------------------------------- /NGroundStation/image/setup.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wustyuyi/NGroundStation/ddcdffde18b8c035d6bbe78ea84d704106d2d6d6/NGroundStation/image/setup.png -------------------------------------------------------------------------------- /NGroundStation/image/show.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wustyuyi/NGroundStation/ddcdffde18b8c035d6bbe78ea84d704106d2d6d6/NGroundStation/image/show.png -------------------------------------------------------------------------------- /NGroundStation/image/stopwave.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wustyuyi/NGroundStation/ddcdffde18b8c035d6bbe78ea84d704106d2d6d6/NGroundStation/image/stopwave.png -------------------------------------------------------------------------------- /NGroundStation/image/sw.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wustyuyi/NGroundStation/ddcdffde18b8c035d6bbe78ea84d704106d2d6d6/NGroundStation/image/sw.png -------------------------------------------------------------------------------- /NGroundStation/image/taobao.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wustyuyi/NGroundStation/ddcdffde18b8c035d6bbe78ea84d704106d2d6d6/NGroundStation/image/taobao.png -------------------------------------------------------------------------------- /NGroundStation/image/tech.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wustyuyi/NGroundStation/ddcdffde18b8c035d6bbe78ea84d704106d2d6d6/NGroundStation/image/tech.png -------------------------------------------------------------------------------- /NGroundStation/image/tozero.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wustyuyi/NGroundStation/ddcdffde18b8c035d6bbe78ea84d704106d2d6d6/NGroundStation/image/tozero.png -------------------------------------------------------------------------------- /NGroundStation/image/update.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wustyuyi/NGroundStation/ddcdffde18b8c035d6bbe78ea84d704106d2d6d6/NGroundStation/image/update.png -------------------------------------------------------------------------------- /NGroundStation/image/usb.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wustyuyi/NGroundStation/ddcdffde18b8c035d6bbe78ea84d704106d2d6d6/NGroundStation/image/usb.png -------------------------------------------------------------------------------- /NGroundStation/image/wave.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wustyuyi/NGroundStation/ddcdffde18b8c035d6bbe78ea84d704106d2d6d6/NGroundStation/image/wave.png -------------------------------------------------------------------------------- /NGroundStation/image/web.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wustyuyi/NGroundStation/ddcdffde18b8c035d6bbe78ea84d704106d2d6d6/NGroundStation/image/web.png -------------------------------------------------------------------------------- /NGroundStation/image/write.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wustyuyi/NGroundStation/ddcdffde18b8c035d6bbe78ea84d704106d2d6d6/NGroundStation/image/write.png -------------------------------------------------------------------------------- /NGroundStation/image/zoomin.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wustyuyi/NGroundStation/ddcdffde18b8c035d6bbe78ea84d704106d2d6d6/NGroundStation/image/zoomin.png -------------------------------------------------------------------------------- /NGroundStation/image/zoomout.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wustyuyi/NGroundStation/ddcdffde18b8c035d6bbe78ea84d704106d2d6d6/NGroundStation/image/zoomout.png -------------------------------------------------------------------------------- /NGroundStation/image/无名创新背景图片.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wustyuyi/NGroundStation/ddcdffde18b8c035d6bbe78ea84d704106d2d6d6/NGroundStation/image/无名创新背景图片.jpg -------------------------------------------------------------------------------- /NGroundStation/image/退出.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wustyuyi/NGroundStation/ddcdffde18b8c035d6bbe78ea84d704106d2d6d6/NGroundStation/image/退出.png -------------------------------------------------------------------------------- /NGroundStation/logo.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wustyuyi/NGroundStation/ddcdffde18b8c035d6bbe78ea84d704106d2d6d6/NGroundStation/logo.ico -------------------------------------------------------------------------------- /NGroundStation/main.cpp: -------------------------------------------------------------------------------- 1 | #include "mainwindow.h" 2 | #include 3 | #include 4 | #include 5 | 6 | using namespace QtDataVisualization; 7 | 8 | int main(int argc, char *argv[]) 9 | { 10 | QApplication a(argc, argv); 11 | MainWindow w; 12 | w.show(); 13 | return a.exec(); 14 | } 15 | -------------------------------------------------------------------------------- /NGroundStation/mainwindow.cpp: -------------------------------------------------------------------------------- 1 | #include "mainwindow.h" 2 | #include "ui_mainwindow.h" 3 | #include "Headfile.h" 4 | 5 | sendandreceive *serialsendandreceive; 6 | serialsetup *usbsetup; 7 | waveshow *wave; 8 | flightstate *state; 9 | SetParameter *setpara; 10 | remotectrl *remote; 11 | calibration *cal; 12 | 13 | QString bt_switch_text; 14 | QSerialPort* serialPort=nullptr; 15 | bool serialflag=false; 16 | MainWindow::MainWindow(QWidget *parent) 17 | : QMainWindow(parent) 18 | , ui(new Ui::MainWindow) 19 | { 20 | ui->setupUi(this); 21 | setWindowFlags(windowFlags()&~Qt::WindowMaximizeButtonHint); // 禁止最大化按钮 22 | setFixedSize(this->width(),this->height()); // 禁止拖动窗口大小 23 | 24 | 25 | this->setWindowTitle("无名创新地面站NGS"); //设置主界面名称 26 | setWindowIcon(QIcon(":/image/Logo.png")); //设置主界面LOGO 27 | 28 | QPalette palette(this->palette()); 29 | palette.setColor(QPalette::Background, QColor(233,235,254)); 30 | this->setPalette(palette); 31 | 32 | connect(ui->Frame, SIGNAL(triggered()), this, SLOT(help())); 33 | connect(ui->web, SIGNAL(triggered()), this, SLOT(surfWeb())); 34 | connect(ui->blog, SIGNAL(triggered()), this, SLOT(blog())); 35 | connect(ui->store, SIGNAL(triggered()), this, SLOT(store())); 36 | connect(ui->update, SIGNAL(triggered()), this, SLOT(update())); 37 | } 38 | 39 | MainWindow::~MainWindow() 40 | { 41 | delete ui; 42 | } 43 | 44 | void MainWindow::closeEvent(QCloseEvent *event) 45 | { 46 | //serialsendandreceive->close(); 47 | //usbsetup->close(); 48 | //wave->close(); 49 | //state->close(); 50 | //setpara->close(); 51 | //delete serialsendandreceive; 52 | //delete usbsetup; 53 | //delete wave; 54 | //delete state; 55 | //delete setpara; 56 | } 57 | 58 | void MainWindow::redraw() 59 | { 60 | //if(wave!=nullptr) delete wave; 61 | 62 | this->show(); 63 | } 64 | 65 | 66 | void MainWindow::on_bt_serialsetup_clicked() 67 | { 68 | // //串口设置ui 69 | usbsetup =new serialsetup(); 70 | usbsetup->setWindowFlags(Qt::Window); 71 | usbsetup->setAttribute(Qt::WA_DeleteOnClose); 72 | connect(usbsetup,SIGNAL(exitwindows()),this,SLOT(redraw()));//当点击子界面时,调用主界面的redraw()函数 73 | 74 | usbsetup->serialinit(); 75 | usbsetup->show(); 76 | this->hide(); 77 | } 78 | 79 | 80 | void MainWindow::on_bt_switch_clicked() 81 | { 82 | if(ui->bt_switch->text()=="打开串口") 83 | { 84 | if(serial_init()) 85 | { 86 | ui->bt_switch->setText("关闭串口"); 87 | ui->bt_switch->setIcon(QIcon(":/image/opencom.png")); 88 | serialflag=true; 89 | } 90 | } 91 | else 92 | { 93 | serialPort->close(); 94 | delete serialPort; 95 | ui->bt_switch->setText("打开串口"); 96 | ui->bt_switch->setIcon(QIcon(":/image/closecom.png")); 97 | serialflag=false; 98 | } 99 | } 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | void MainWindow::on_bt_sendandreceive_clicked() 110 | { 111 | 112 | 113 | //基本收发ui 114 | serialsendandreceive=new sendandreceive(); 115 | serialsendandreceive->setAttribute(Qt::WA_DeleteOnClose); 116 | serialsendandreceive->setWindowFlags(Qt::Window); 117 | connect(serialsendandreceive,SIGNAL(exitwindows()),this,SLOT(redraw()));//当点击子界面时,调用主界面的redraw()函数 118 | 119 | connect(serialsendandreceive,SIGNAL(senddata(QString)),this,SLOT(readdata(QString))); 120 | serialsendandreceive->setWindowFlag(Qt::WindowStaysOnTopHint);//窗口置顶 121 | serialsendandreceive->show(); 122 | this->hide(); 123 | } 124 | 125 | 126 | 127 | 128 | 129 | void MainWindow::readdata(QString data) 130 | { 131 | //ui->txtb_message->setText(data); 132 | } 133 | 134 | 135 | QString MainWindow::GetCPUManID() 136 | { 137 | QString cpu_id = ""; 138 | QProcess p(0); 139 | p.start("wmic CPU get ProcessorID"); 140 | p.waitForStarted(); 141 | p.waitForFinished(); 142 | cpu_id = QString::fromLocal8Bit(p.readAllStandardOutput()); 143 | cpu_id = cpu_id.remove("ProcessorId").trimmed(); 144 | //qDebug()<setWindowFlags(Qt::Window); 153 | wave->setAttribute(Qt::WA_DeleteOnClose); 154 | connect(wave,SIGNAL(exitwindows()),this,SLOT(redraw()));//当点击子界面时,调用主界面的redraw()函数 155 | //connect(this,SIGNAL(showwave()),wave,SLOT(showwave())); 156 | //wave->wave_init(); 157 | wave->show(); 158 | this->hide(); 159 | } 160 | 161 | void MainWindow::on_bt_flightstate_clicked() 162 | { 163 | //飞控状态ui 164 | state=new flightstate(); 165 | state->setWindowFlags(Qt::Window); 166 | state->setAttribute(Qt::WA_DeleteOnClose); 167 | connect(state,SIGNAL(exitwindows()),this,SLOT(redraw()));//当点击子界面时,调用主界面的redraw()函数 168 | 169 | state->show(); 170 | this->hide(); 171 | } 172 | 173 | 174 | QString msg_data; 175 | void MainWindow::getthreaddata(QByteArray data) 176 | { 177 | static QByteArray data_temp; 178 | data_temp+=data; 179 | //msg_data=QString(data_temp); 180 | /*********************************************** 181 | QByteArray bufferHex = data.toHex();//转换成hex 182 | bufferHex=bufferHex.toUpper();//转换成大写 183 | data_temp+=bufferHex; 184 | msg_data=QString(data_temp); 185 | for(int i = msg_data.count(); i > 0; i = i-2) 186 | { 187 | msg_data.insert(i," "); 188 | } 189 | ***********************************************/ 190 | if(data_temp.length()>1000) 191 | { 192 | data_temp.clear(); 193 | //ui->txtb_message->clear(); 194 | } 195 | } 196 | 197 | 198 | 199 | 200 | void MainWindow::on_bt_parameter_clicked() 201 | { 202 | //飞控参数ui 203 | setpara=new SetParameter(); 204 | setpara->setWindowFlags(Qt::Window); 205 | setpara->setAttribute(Qt::WA_DeleteOnClose); 206 | connect(setpara,SIGNAL(exitwindows()),this,SLOT(redraw()));//当点击子界面时,调用主界面的redraw()函数 207 | connect(this,SIGNAL(redrawparameter(uint8_t)),setpara,SLOT(setparameter_show(uint8_t))); 208 | connect(this,SIGNAL(sendcheck(uint8_t)),setpara,SLOT(getcheck(uint8_t))); 209 | setpara->show(); 210 | this->hide(); 211 | } 212 | 213 | 214 | 215 | /***********************************************************************************************/ 216 | 217 | bool MainWindow::serial_init() 218 | { 219 | serialPort = new QSerialPort(this);//打开串口 220 | serialPort->setPortName(serialconfig.serialname);//设置串口号 221 | if(serialPort->isOpen())//如果串口已打开,立刻关闭 222 | { 223 | serialPort->close(); 224 | } 225 | 226 | if(!serialPort->open(QIODevice::ReadWrite)) 227 | { 228 | QMessageBox::critical(this,"提示","串口异常,请您先配置串口,再打开串口!!!",QMessageBox::Yes,QMessageBox::Yes); 229 | return false; 230 | } 231 | 232 | serialPort->setBaudRate(serialconfig.baudrate); 233 | switch(serialconfig.parity)//设置数据校验形式 234 | { 235 | case 0: 236 | serialPort->setParity(QSerialPort::NoParity);//无校验 237 | break; 238 | case 1: 239 | serialPort->setParity(QSerialPort::OddParity);//奇校验 240 | break; 241 | case 2: 242 | serialPort->setParity(QSerialPort::EvenParity);//偶校验 243 | break; 244 | default: 245 | serialPort->setParity(QSerialPort::NoParity); 246 | break; 247 | } 248 | 249 | switch(serialconfig.dataBit)//设置数据位 250 | { 251 | case 0: 252 | serialPort->setDataBits(QSerialPort::Data8); 253 | break; 254 | case 1: 255 | serialPort->setDataBits(QSerialPort::Data7); 256 | break; 257 | case 2: 258 | serialPort->setDataBits(QSerialPort::Data6); 259 | break; 260 | case 3: 261 | serialPort->setDataBits(QSerialPort::Data5); 262 | break; 263 | default: 264 | serialPort->setDataBits(QSerialPort::Data8); 265 | break; 266 | } 267 | 268 | switch(serialconfig.stopBit)//设置停止位 269 | { 270 | case 0: 271 | serialPort->setStopBits(QSerialPort::OneStop); 272 | break; 273 | case 1: 274 | serialPort->setStopBits(QSerialPort::OneAndHalfStop); 275 | break; 276 | case 2: 277 | serialPort->setStopBits(QSerialPort::TwoStop); 278 | break; 279 | default: 280 | serialPort->setStopBits(QSerialPort::OneStop); 281 | break; 282 | } 283 | serialPort->setFlowControl(QSerialPort::NoFlowControl); //无流控 284 | serialPort->setReadBufferSize(BufferSizeMax); //数据缓冲区长度65536*2 285 | //int a=(int)QThread::currentThreadId(); 286 | //QString LogInfo=QString::number(a,10); 287 | //qDebug() << "thread初始化 " <<"threadID : "<write("无名创新"); 289 | //connect(serialPort,SIGNAL(readyRead()),this,SLOT(NCLinkDataGet()),Qt::DirectConnection);//有数据就读 290 | connect(serialPort,SIGNAL(readyRead()),this,SLOT(NCLinkDataGet()));//有数据就读 291 | return true; 292 | } 293 | 294 | 295 | union 296 | { 297 | unsigned char floatByte[4]; 298 | float floatValue; 299 | }FloatUnion; 300 | 301 | 302 | void MainWindow::Float2Byte(float *FloatValue, unsigned char *Byte, unsigned char Subscript) 303 | { 304 | FloatUnion.floatValue = (float)2; 305 | 306 | if(FloatUnion.floatByte[0] == 0) 307 | {//小端模式 308 | FloatUnion.floatValue = *FloatValue; 309 | 310 | Byte[Subscript] = FloatUnion.floatByte[0]; 311 | Byte[Subscript + 1] = FloatUnion.floatByte[1]; 312 | Byte[Subscript + 2] = FloatUnion.floatByte[2]; 313 | Byte[Subscript + 3] = FloatUnion.floatByte[3]; 314 | } 315 | else 316 | {//大端模式 317 | FloatUnion.floatValue = *FloatValue; 318 | 319 | Byte[Subscript] = FloatUnion.floatByte[3]; 320 | Byte[Subscript + 1] = FloatUnion.floatByte[2]; 321 | Byte[Subscript + 2] = FloatUnion.floatByte[1]; 322 | Byte[Subscript + 3] = FloatUnion.floatByte[0]; 323 | } 324 | } 325 | 326 | 327 | void MainWindow::Byte2Float(unsigned char *Byte, unsigned char Subscript, float *FloatValue) 328 | { 329 | FloatUnion.floatByte[0] = Byte[Subscript]; 330 | FloatUnion.floatByte[1] = Byte[Subscript + 1]; 331 | FloatUnion.floatByte[2] = Byte[Subscript + 2]; 332 | FloatUnion.floatByte[3] = Byte[Subscript + 3]; 333 | 334 | *FloatValue = FloatUnion.floatValue; 335 | } 336 | 337 | 338 | void MainWindow::NCLinkDataGet() 339 | { 340 | qint64 byteLen = serialPort->bytesAvailable(); 341 | 342 | if(byteLen < 0) 343 | { 344 | return; 345 | } 346 | receivedData=serialPort->readAll(); 347 | for(int i=0;i0)//数据区 384 | { 385 | _data_len--; 386 | RxBuffer[4+_data_cnt++]=data; 387 | if(_data_len==0) 388 | state = 5; 389 | } 390 | else if(state==5)//校验和 391 | { 392 | state = 6; 393 | RxBuffer[4+_data_cnt++]=data; 394 | } 395 | else if(state==6&&data==NCLink_End0)//帧尾0 396 | { 397 | state = 7; 398 | RxBuffer[4+_data_cnt++]=data; 399 | } 400 | else if(state==7&&data==NCLink_End1)//帧尾1 401 | { 402 | state = 0; 403 | RxBuffer[4+_data_cnt]=data; 404 | dataSort(RxBuffer,_data_cnt+5); 405 | } 406 | else 407 | { 408 | state = 0; 409 | //qDebug()<<"default"; 410 | } 411 | } 412 | 413 | 414 | 415 | void MainWindow::dataSort(uint8_t *data_buf,uint8_t num) 416 | { 417 | uint8_t sum = 0; 418 | for(uint8_t i=0;i<(num-3);i++) sum^=(*(data_buf+i));//计算校验和 419 | if(!(sum==*(data_buf+num-3))) 420 | { 421 | //qDebug()<<"default"; 422 | return; 423 | } 424 | if(!(*(data_buf)==NCLink_Head0 && *(data_buf+1)==NCLink_Head1))//帧头校验 425 | { 426 | //qDebug()<<"default"; 427 | return; 428 | } 429 | if(!(*(data_buf+num-2)==NCLink_End0 && *(data_buf+num-1)==NCLink_End1))//帧尾校验 430 | { 431 | //qDebug()<<"default"; 432 | return; 433 | } 434 | //qDebug()<<"sum check okay"<<"FC:"<setWindowFlags(Qt::Window); 874 | remote->setAttribute(Qt::WA_DeleteOnClose); 875 | connect(remote,SIGNAL(exitwindows()),this,SLOT(redraw()));//当点击子界面时,调用主界面的redraw()函数 876 | connect(this,SIGNAL(sendcheck(uint8_t)),remote,SLOT(getcheck(uint8_t))); 877 | remote->show(); 878 | this->hide(); 879 | } 880 | } 881 | 882 | void MainWindow::on_bt_calibration_clicked() 883 | { 884 | //串口设置ui 885 | cal =new calibration(); 886 | cal->setWindowFlags(Qt::Window); 887 | cal->setAttribute(Qt::WA_DeleteOnClose); 888 | connect(cal,SIGNAL(exitwindows()),this,SLOT(redraw()));//当点击子界面时,调用主界面的redraw()函数 889 | connect(this,SIGNAL(sendcheck(uint8_t)),cal,SLOT(getcheck(uint8_t))); 890 | 891 | cal->show(); 892 | this->hide(); 893 | } 894 | -------------------------------------------------------------------------------- /NGroundStation/mainwindow.h: -------------------------------------------------------------------------------- 1 | #ifndef MAINWINDOW_H 2 | #define MAINWINDOW_H 3 | 4 | #include 5 | #include "Headfile.h" 6 | 7 | 8 | 9 | extern bool serialflag; 10 | extern QSerialPort* serialPort; 11 | extern sendandreceive *serialsendandreceive; 12 | extern serialsetup *usbsetup; 13 | extern waveshow *wave; 14 | 15 | extern QString bt_switch_text; 16 | QT_BEGIN_NAMESPACE 17 | namespace Ui { class MainWindow; } 18 | QT_END_NAMESPACE 19 | 20 | class MainWindow : public QMainWindow 21 | { 22 | Q_OBJECT 23 | private: 24 | Ui::MainWindow *ui; 25 | public: 26 | MainWindow(QWidget *parent = nullptr); 27 | ~MainWindow(); 28 | QTimer *timer_textshow=nullptr; 29 | bool threadshow_flag=false; 30 | //重写关闭事件 31 | void closeEvent(QCloseEvent *); 32 | 33 | 34 | bool serial_init(); 35 | void NCLinkDataPrase(uint8_t data); 36 | void dataSort(uint8_t *data_buf,uint8_t num); 37 | void Float2Byte(float *FloatValue, unsigned char *Byte, unsigned char Subscript); 38 | void Byte2Float(unsigned char *Byte, unsigned char Subscript, float *FloatValue); 39 | private slots: 40 | void on_bt_serialsetup_clicked(); 41 | void on_bt_switch_clicked(); 42 | void on_bt_sendandreceive_clicked(); 43 | QString GetCPUManID(); 44 | void readdata(QString data); 45 | void getthreaddata(QByteArray data); 46 | 47 | 48 | void NCLinkDataGet(); 49 | //private: 50 | void on_bt_datawave_clicked(); 51 | void on_bt_flightstate_clicked(); 52 | void on_bt_parameter_clicked(); 53 | void redraw(); 54 | void on_bt_remote_clicked(); 55 | void on_bt_calibration_clicked(); 56 | 57 | public slots: 58 | void help(); 59 | void surfWeb(); 60 | void blog(); 61 | void store(); 62 | void update(); 63 | private: 64 | QByteArray receivedData; //接收的数据 65 | QByteArray sendData; //发送的数据 66 | QMutex mutex; 67 | QMutex mutexdata; 68 | qint64 byteLen_now; 69 | qint64 byteLen_read; 70 | signals: 71 | void redrawparameter(uint8_t);//新建一个信号槽 72 | void sendcheck(uint8_t);//新建一个信号槽 73 | void showwave(); 74 | }; 75 | #endif // MAINWINDOW_H 76 | -------------------------------------------------------------------------------- /NGroundStation/mainwindow.ui: -------------------------------------------------------------------------------- 1 | 2 | 3 | MainWindow 4 | 5 | 6 | Qt::ApplicationModal 7 | 8 | 9 | 10 | 0 11 | 0 12 | 401 13 | 579 14 | 15 | 16 | 17 | 18 | 0 19 | 0 20 | 21 | 22 | 23 | 24 | true 25 | 26 | 27 | 28 | false 29 | 30 | 31 | MainWindow 32 | 33 | 34 | true 35 | 36 | 37 | false 38 | 39 | 40 | QTabWidget::Triangular 41 | 42 | 43 | false 44 | 45 | 46 | 47 | QWidget 48 | { 49 | background-color: rgb(233,235,254); 50 | border-radius: 20px; 51 | color: rgb(0, 0, 0); 52 | } 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 0 62 | 0 63 | 64 | 65 | 66 | 67 | 楷体 68 | 20 69 | 70 | 71 | 72 | QPushButton 73 | { 74 | background-color: rgb(233,235,254); 75 | border-radius: 20px; 76 | color: rgb(0, 0, 0); 77 | } 78 | QPushButton:hover 79 | { 80 | background-color: rgb(200,235,254); 81 | } 82 | 83 | QPushButton:disabled 84 | { 85 | background-color: rgb(167, 164, 170); 86 | } 87 | 88 | 89 | 配置串口 90 | 91 | 92 | 93 | :/image/usb.png:/image/usb.png 94 | 95 | 96 | 97 | 50 98 | 50 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 0 108 | 0 109 | 110 | 111 | 112 | 113 | 楷体 114 | 20 115 | 116 | 117 | 118 | QPushButton 119 | { 120 | background-color: rgb(233,235,254); 121 | border-radius: 20px; 122 | color: rgb(0, 0, 0); 123 | } 124 | QPushButton:hover 125 | { 126 | background-color: rgb(200,235,254); 127 | } 128 | 129 | 130 | 打开串口 131 | 132 | 133 | 134 | :/image/closecom.png 135 | :/image/opencom.png:/image/closecom.png 136 | 137 | 138 | 139 | 50 140 | 50 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 0 150 | 0 151 | 152 | 153 | 154 | 155 | 楷体 156 | 20 157 | 158 | 159 | 160 | QPushButton 161 | { 162 | background-color: rgb(233,235,254); 163 | border-radius: 20px; 164 | color: rgb(0, 0, 0); 165 | } 166 | QPushButton:hover 167 | { 168 | background-color: rgb(200,235,254); 169 | } 170 | 171 | 172 | 飞控状态 173 | 174 | 175 | 176 | :/image/Logo.png:/image/Logo.png 177 | 178 | 179 | 180 | 50 181 | 50 182 | 183 | 184 | 185 | 186 | 187 | 188 | 189 | 190 | 0 191 | 0 192 | 193 | 194 | 195 | 196 | 楷体 197 | 20 198 | 199 | 200 | 201 | QPushButton 202 | { 203 | background-color: rgb(233,235,254); 204 | border-radius: 20px; 205 | color: rgb(0, 0, 0); 206 | } 207 | QPushButton:hover 208 | { 209 | background-color: rgb(200,235,254); 210 | } 211 | 212 | 213 | 数据波形 214 | 215 | 216 | 217 | :/image/wave.png:/image/wave.png 218 | 219 | 220 | 221 | 50 222 | 50 223 | 224 | 225 | 226 | 227 | 228 | 229 | 230 | 231 | 0 232 | 0 233 | 234 | 235 | 236 | 237 | 楷体 238 | 20 239 | 240 | 241 | 242 | QPushButton 243 | { 244 | background-color: rgb(233,235,254); 245 | border-radius: 20px; 246 | color: rgb(0, 0, 0); 247 | } 248 | QPushButton:hover 249 | { 250 | background-color: rgb(200,235,254); 251 | } 252 | 253 | 254 | 参数调试 255 | 256 | 257 | 258 | :/image/debug.png:/image/debug.png 259 | 260 | 261 | 262 | 50 263 | 50 264 | 265 | 266 | 267 | 268 | 269 | 270 | 271 | 272 | 0 273 | 0 274 | 275 | 276 | 277 | 278 | 楷体 279 | 20 280 | 281 | 282 | 283 | QPushButton 284 | { 285 | background-color: rgb(233,235,254); 286 | border-radius: 20px; 287 | color: rgb(0, 0, 0); 288 | } 289 | QPushButton:hover 290 | { 291 | background-color: rgb(200,235,254); 292 | } 293 | 294 | 295 | 虚拟遥控 296 | 297 | 298 | 299 | :/image/remote.png:/image/remote.png 300 | 301 | 302 | 303 | 50 304 | 50 305 | 306 | 307 | 308 | 309 | 310 | 311 | 312 | 313 | 0 314 | 0 315 | 316 | 317 | 318 | 319 | 楷体 320 | 20 321 | 322 | 323 | 324 | QPushButton 325 | { 326 | background-color: rgb(233,235,254); 327 | border-radius: 20px; 328 | color: rgb(0, 0, 0); 329 | } 330 | QPushButton:hover 331 | { 332 | background-color: rgb(200,235,254); 333 | } 334 | 335 | 336 | 飞控校准 337 | 338 | 339 | 340 | :/image/calibration.png:/image/calibration.png 341 | 342 | 343 | 344 | 50 345 | 50 346 | 347 | 348 | 349 | 350 | 351 | 352 | 353 | 354 | 0 355 | 0 356 | 357 | 358 | 359 | 360 | 楷体 361 | 20 362 | 363 | 364 | 365 | QPushButton 366 | { 367 | background-color: rgb(233,235,254); 368 | border-radius: 20px; 369 | color: rgb(0, 0, 0); 370 | } 371 | QPushButton:hover 372 | { 373 | background-color: rgb(200,235,254); 374 | } 375 | 376 | 377 | 基本收发 378 | 379 | 380 | 381 | :/image/senddata.png:/image/senddata.png 382 | 383 | 384 | 385 | 50 386 | 50 387 | 388 | 389 | 390 | 391 | 392 | 393 | 394 | 395 | 396 | 397 | 398 | 399 | 0 400 | 0 401 | 401 402 | 26 403 | 404 | 405 | 406 | 407 | 使用帮助 408 | 409 | 410 | 411 | 412 | 413 | 414 | 415 | 关于我们 416 | 417 | 418 | 419 | 420 | 421 | 422 | 423 | 424 | 425 | 426 | 427 | 428 | true 429 | 430 | 431 | true 432 | 433 | 434 | 435 | :/image/book.png:/image/book.png 436 | 437 | 438 | 通讯协议V1.0.1 439 | 440 | 441 | 442 | 443 | 444 | :/image/web.png:/image/web.png 445 | 446 | 447 | 官网官网(链接) 448 | 449 | 450 | 451 | 452 | 453 | :/image/blog.png:/image/blog.png 454 | 455 | 456 | 技术社区(链接) 457 | 458 | 459 | 460 | 461 | 462 | :/image/taobao.png:/image/taobao.png 463 | 464 | 465 | 淘宝店铺(链接) 466 | 467 | 468 | 技术交流QQ群:465082224 469 | 470 | 471 | 472 | 473 | 474 | :/image/tech.png:/image/tech.png 475 | 476 | 477 | 技术客服(微信):15871778515 478 | 479 | 480 | 481 | 482 | 483 | :/image/QQ.png:/image/QQ.png 484 | 485 | 486 | 技术交流QQ群:465082224 487 | 488 | 489 | 490 | 491 | 492 | :/image/update.png:/image/update.png 493 | 494 | 495 | 软件升级(当前版本V1.0.1) 496 | 497 | 498 | 软件升级 499 | 500 | 501 | 502 | 503 | 504 | 505 | 506 | 507 | -------------------------------------------------------------------------------- /NGroundStation/remotectrl.cpp: -------------------------------------------------------------------------------- 1 | #include "Headfile.h" 2 | #include "remotectrl.h" 3 | #include "ui_remotectrl.h" 4 | 5 | QTimer *timer_remote=nullptr; 6 | int16_t channel[8]={0}; 7 | uint16_t channel_package[8]={0}; 8 | uint8_t flag_unlock=0,flag_takeoff=0; 9 | double accuracy=0; 10 | double accuracy_send_cnt=0,accuracy_rec_cnt=0; 11 | 12 | 13 | remotectrl::remotectrl(QWidget *parent) : 14 | QWidget(parent), 15 | ui(new Ui::remotectrl) 16 | { 17 | ui->setupUi(this); 18 | 19 | 20 | accuracy=0; 21 | accuracy_send_cnt=0; 22 | accuracy_rec_cnt=0; 23 | 24 | 25 | 26 | setWindowFlags(windowFlags()&~Qt::WindowMaximizeButtonHint); // 禁止最大化按钮 27 | setFixedSize(this->width(),this->height()); // 禁止拖动窗口大小 28 | this->setWindowTitle("虚拟遥控器"); //设置主界面名称 29 | setWindowIcon(QIcon(":/image/remote.png")); //设置主界面LOGO 30 | QPalette palette(this->palette()); 31 | palette.setColor(QPalette::Background, QColor(233,235,254));//QColor(78,168,243) 32 | this->setPalette(palette); 33 | 34 | ui->lineEdit_front->setValidator(new QIntValidator(0, 100000, this));//限制数据输入范围 35 | ui->lineEdit_behind->setValidator(new QIntValidator(0, 100000, this)); 36 | ui->lineEdit_left->setValidator(new QIntValidator(0, 100000, this)); 37 | ui->lineEdit_right->setValidator(new QIntValidator(0, 100000, this)); 38 | ui->lineEdit_up->setValidator(new QIntValidator(0, 100000, this)); 39 | ui->lineEdit_down->setValidator(new QIntValidator(0, 100000, this)); 40 | 41 | ui->order_front->setValidator(new QIntValidator(0, 100000, this));//限制数据输入范围 42 | ui->order_behind->setValidator(new QIntValidator(0, 100000, this)); 43 | ui->order_left->setValidator(new QIntValidator(0, 100000, this)); 44 | ui->order_right->setValidator(new QIntValidator(0, 100000, this)); 45 | ui->order_up->setValidator(new QIntValidator(0, 100000, this)); 46 | ui->order_down->setValidator(new QIntValidator(0, 100000, this)); 47 | 48 | timer_remote = new QTimer(this); 49 | connect(timer_remote, SIGNAL(timeout()), this, SLOT(timer_event())); 50 | int period_cnt=20; 51 | timer_remote->start(period_cnt); 52 | 53 | connect(ui->customRocker_ch12, SIGNAL(moveAngle(double,double)), this, SLOT(sort_data12(double,double)),Qt::AutoConnection);//DirectConnection 54 | connect(ui->customRocker_ch34, SIGNAL(moveAngle(double,double)), this, SLOT(sort_data34(double,double)),Qt::AutoConnection);//DirectConnection 55 | 56 | connect(ui->bt_unlock, SIGNAL(checkedChanged(bool)), this, SLOT(sort_data_bt_unlock(bool)),Qt::AutoConnection);//DirectConnection 57 | connect(ui->bt_takeoff, SIGNAL(checkedChanged(bool)), this, SLOT(sort_data_bt_takeoff(bool)),Qt::AutoConnection);//DirectConnection 58 | } 59 | 60 | remotectrl::~remotectrl() 61 | { 62 | delete ui; 63 | } 64 | 65 | 66 | //当窗口出发关闭事件后,将信号发射出去 67 | void remotectrl::closeEvent(QCloseEvent *) 68 | { 69 | emit exitwindows(); 70 | } 71 | 72 | 73 | void remotectrl::on_checkBox_stateChanged(int arg1) 74 | { 75 | if(ui->checkBox->isChecked()) 76 | { 77 | timer_remote = new QTimer(this); 78 | connect(timer_remote, SIGNAL(timeout()), this, SLOT(timer_event())); 79 | int period_cnt=20; 80 | timer_remote->start(period_cnt); 81 | } 82 | else 83 | { 84 | timer_remote->stop(); 85 | delete timer_remote; 86 | } 87 | } 88 | 89 | void remotectrl::sort_data12(double angle,double r) 90 | { 91 | 92 | channel[0]=(int16_t)(r*(double)(cos((angle/180.0)*3.141593f))); 93 | channel[1]=(int16_t)(r*(double)(sin((angle/180.0)*3.141593f))); 94 | 95 | channel_package[0]=1500+500*channel[0]/132; 96 | channel_package[1]=1500+500*channel[1]/132; 97 | 98 | ui->ch0_pro->setValue(channel_package[0]); 99 | ui->ch1_pro->setValue(channel_package[1]); 100 | 101 | ui->ch0->setText(QString::number(channel_package[0])); 102 | ui->ch1->setText(QString::number(channel_package[1])); 103 | } 104 | 105 | void remotectrl::sort_data34(double angle,double r) 106 | { 107 | 108 | channel[2]=(int16_t)(r*(double)(sin((angle/180.0)*3.141593f))); 109 | channel[3]=(int16_t)(r*(double)(cos((angle/180.0)*3.141593f))); 110 | 111 | channel_package[2]=1500+500*channel[2]/132; 112 | channel_package[3]=1500+500*channel[3]/132; 113 | 114 | ui->ch2_pro->setValue(channel_package[2]); 115 | ui->ch3_pro->setValue(channel_package[3]); 116 | 117 | ui->ch2->setText(QString::number(channel_package[2])); 118 | ui->ch3->setText(QString::number(channel_package[3])); 119 | } 120 | 121 | 122 | 123 | void remotectrl::sort_data_bt_unlock(bool flag) 124 | { 125 | if(ui->bt_unlock->getChecked()==true) flag_unlock=1;//解锁 126 | else flag_unlock=0;//上锁 127 | } 128 | 129 | void remotectrl::sort_data_bt_takeoff(bool flag) 130 | { 131 | if(ui->bt_takeoff->getChecked()==true) flag_takeoff=1;//一键起飞 132 | else flag_takeoff=0;//一键降落 133 | } 134 | 135 | 136 | 137 | void remotectrl::timer_event() 138 | { 139 | if(ui->customRocker_ch12->pressed==false) 140 | { 141 | channel_package[0]=1500; 142 | channel_package[1]=1500; 143 | ui->ch0_pro->setValue(channel_package[0]); 144 | ui->ch1_pro->setValue(channel_package[1]); 145 | ui->ch0->setText(QString::number(channel_package[0])); 146 | ui->ch1->setText(QString::number(channel_package[1])); 147 | } 148 | 149 | if(ui->customRocker_ch34->pressed==false) 150 | { 151 | channel_package[2]=1500; 152 | channel_package[3]=1500; 153 | ui->ch2_pro->setValue(channel_package[2]); 154 | ui->ch3_pro->setValue(channel_package[3]); 155 | ui->ch2->setText(QString::number(channel_package[2])); 156 | ui->ch3->setText(QString::number(channel_package[3])); 157 | } 158 | 159 | channel[4]=ui->xslider1->value(); 160 | channel[5]=ui->xslider2->value(); 161 | channel[6]=ui->xslider3->value(); 162 | channel[7]=ui->xslider4->value(); 163 | 164 | ui->ch4_pro->setValue(channel[4]); 165 | ui->ch5_pro->setValue(channel[5]); 166 | ui->ch6_pro->setValue(channel[6]); 167 | ui->ch7_pro->setValue(channel[7]); 168 | 169 | ui->ch4->setText(QString::number(channel[4])); 170 | ui->ch5->setText(QString::number(channel[5])); 171 | ui->ch6->setText(QString::number(channel[6])); 172 | ui->ch7->setText(QString::number(channel[7])); 173 | 174 | channel_package[4]=channel[4]; 175 | channel_package[5]=channel[5]; 176 | channel_package[6]=channel[6]; 177 | channel_package[7]=channel[7]; 178 | 179 | Send_RC(channel_package[0],channel_package[1],channel_package[2],channel_package[3], 180 | channel_package[4],channel_package[5],channel_package[6],channel_package[7], 181 | flag_unlock,flag_takeoff); 182 | 183 | flag_unlock=2;//中间状态 184 | flag_takeoff=2;//中间状态 185 | accuracy_send_cnt++; 186 | } 187 | 188 | 189 | extern QSerialPort* serialPort; 190 | void remotectrl::Send_RC(uint16_t ch0,uint16_t ch1,uint16_t ch2,uint16_t ch3,uint16_t ch4,uint16_t ch5,uint16_t ch6,uint16_t ch7,uint8_t unlock_flag,uint8_t takeoff_flag)//地面站指令发送RC数据 191 | { 192 | uint8_t data_to_send[50]; 193 | uint8_t sum = 0,i=0,cnt=0; 194 | uint16_t _temp; 195 | data_to_send[cnt++]=NCLink_Head1; 196 | data_to_send[cnt++]=NCLink_Head0; 197 | data_to_send[cnt++]=0x09; 198 | data_to_send[cnt++]=0; 199 | 200 | _temp = ch0; 201 | data_to_send[cnt++]=BYTE1(_temp); 202 | data_to_send[cnt++]=BYTE0(_temp); 203 | _temp = ch1; 204 | data_to_send[cnt++]=BYTE1(_temp); 205 | data_to_send[cnt++]=BYTE0(_temp); 206 | _temp = ch2; 207 | data_to_send[cnt++]=BYTE1(_temp); 208 | data_to_send[cnt++]=BYTE0(_temp); 209 | _temp = ch3; 210 | data_to_send[cnt++]=BYTE1(_temp); 211 | data_to_send[cnt++]=BYTE0(_temp); 212 | _temp = ch4; 213 | data_to_send[cnt++]=BYTE1(_temp); 214 | data_to_send[cnt++]=BYTE0(_temp); 215 | _temp = ch5; 216 | data_to_send[cnt++]=BYTE1(_temp); 217 | data_to_send[cnt++]=BYTE0(_temp); 218 | _temp = ch6; 219 | data_to_send[cnt++]=BYTE1(_temp); 220 | data_to_send[cnt++]=BYTE0(_temp); 221 | _temp = ch7; 222 | data_to_send[cnt++]=BYTE1(_temp); 223 | data_to_send[cnt++]=BYTE0(_temp); 224 | 225 | data_to_send[cnt++]=BYTE0(unlock_flag); 226 | data_to_send[cnt++]=BYTE0(takeoff_flag); 227 | 228 | data_to_send[3] = cnt-4; 229 | for(i=0;iwrite((char *)(data_to_send),cnt); 234 | else 235 | { 236 | QDateTime current_date_time = QDateTime::currentDateTime(); 237 | QString current_time = current_date_time.toString("hh:mm:ss.zzz"); 238 | } 239 | } 240 | 241 | 242 | 243 | void remotectrl::getcheck(uint8_t ch) 244 | { 245 | QDateTime current_date_time = QDateTime::currentDateTime(); 246 | QString current_time = current_date_time.toString("hh:mm:ss.zzz"); 247 | if(ch==0x11) 248 | { 249 | ui->msg->appendPlainText(current_time+"毫秒>飞控接收遥控器数据成功"); 250 | accuracy_rec_cnt++; 251 | accuracy=(double)(100*accuracy_rec_cnt/accuracy_send_cnt); 252 | ui->progressArc->setValue(accuracy); 253 | if(accuracy_send_cnt>=1000) 254 | { 255 | accuracy_send_cnt=0; 256 | accuracy_rec_cnt=0; 257 | } 258 | } 259 | else if(ch==0x12) 260 | { 261 | ui->msg->appendPlainText(current_time+"毫秒>飞控接收位移数据成功"); 262 | } 263 | ui->msg->moveCursor(QTextCursor::End, QTextCursor::MoveAnchor); 264 | 265 | } 266 | 267 | void remotectrl::on_clear_clicked() 268 | { 269 | ui->msg->clear(); 270 | ui->msg->moveCursor(QTextCursor::End, QTextCursor::MoveAnchor); 271 | } 272 | 273 | 274 | 275 | void remotectrl::Send_DIS(uint8_t move_flag,uint8_t move_order,uint16_t move_distance)//地面站指令发送移动距离数据 276 | { 277 | uint8_t data_to_send[50]; 278 | uint8_t sum = 0,i=0,cnt=0; 279 | uint16_t _temp; 280 | data_to_send[cnt++]=NCLink_Head1; 281 | data_to_send[cnt++]=NCLink_Head0; 282 | data_to_send[cnt++]=0x0A; 283 | data_to_send[cnt++]=0; 284 | 285 | 286 | data_to_send[cnt++]=BYTE0(move_flag); 287 | data_to_send[cnt++]=BYTE0(move_order); 288 | 289 | _temp = move_distance; 290 | data_to_send[cnt++]=BYTE1(_temp); 291 | data_to_send[cnt++]=BYTE0(_temp); 292 | 293 | data_to_send[3] = cnt-4; 294 | for(i=0;iwrite((char *)(data_to_send),cnt); 299 | else 300 | { 301 | QDateTime current_date_time = QDateTime::currentDateTime(); 302 | QString current_time = current_date_time.toString("hh:mm:ss.zzz"); 303 | } 304 | } 305 | 306 | 307 | 308 | void remotectrl::on_bt_send1_clicked() 309 | { 310 | Send_DIS(0x00,ui->order_front->text().toUInt(),ui->lineEdit_front->text().toUInt()); 311 | 312 | QDateTime current_date_time = QDateTime::currentDateTime(); 313 | QString current_time = current_date_time.toString("hh:mm:ss.zzz"); 314 | ui->msg->appendPlainText(current_time+"毫秒>地面站向前位移数据已发送"); 315 | ui->msg->moveCursor(QTextCursor::End, QTextCursor::MoveAnchor); 316 | } 317 | 318 | void remotectrl::on_bt_send2_clicked() 319 | { 320 | Send_DIS(0x01,ui->order_behind->text().toUInt(),ui->lineEdit_behind->text().toUInt()); 321 | QDateTime current_date_time = QDateTime::currentDateTime(); 322 | QString current_time = current_date_time.toString("hh:mm:ss.zzz"); 323 | ui->msg->appendPlainText(current_time+"毫秒>地面站向后位移数据已发送"); 324 | ui->msg->moveCursor(QTextCursor::End, QTextCursor::MoveAnchor); 325 | } 326 | 327 | void remotectrl::on_bt_send3_clicked() 328 | { 329 | Send_DIS(0x02,ui->order_left->text().toUInt(),ui->lineEdit_left->text().toUInt()); 330 | QDateTime current_date_time = QDateTime::currentDateTime(); 331 | QString current_time = current_date_time.toString("hh:mm:ss.zzz"); 332 | ui->msg->appendPlainText(current_time+"毫秒>地面站向左位移数据已发送"); 333 | ui->msg->moveCursor(QTextCursor::End, QTextCursor::MoveAnchor); 334 | } 335 | 336 | void remotectrl::on_bt_send4_clicked() 337 | { 338 | Send_DIS(0x03,ui->order_right->text().toUInt(),ui->lineEdit_right->text().toUInt()); 339 | QDateTime current_date_time = QDateTime::currentDateTime(); 340 | QString current_time = current_date_time.toString("hh:mm:ss.zzz"); 341 | ui->msg->appendPlainText(current_time+"毫秒>地面站向右位移数据已发送"); 342 | ui->msg->moveCursor(QTextCursor::End, QTextCursor::MoveAnchor); 343 | } 344 | 345 | void remotectrl::on_bt_send5_clicked() 346 | { 347 | Send_DIS(0x04,ui->order_up->text().toUInt(),ui->lineEdit_up->text().toUInt()); 348 | QDateTime current_date_time = QDateTime::currentDateTime(); 349 | QString current_time = current_date_time.toString("hh:mm:ss.zzz"); 350 | ui->msg->appendPlainText(current_time+"毫秒>地面站向上位移数据已发送"); 351 | ui->msg->moveCursor(QTextCursor::End, QTextCursor::MoveAnchor); 352 | } 353 | 354 | void remotectrl::on_bt_send6_clicked() 355 | { 356 | Send_DIS(0x05,ui->order_down->text().toUInt(),ui->lineEdit_down->text().toUInt()); 357 | QDateTime current_date_time = QDateTime::currentDateTime(); 358 | QString current_time = current_date_time.toString("hh:mm:ss.zzz"); 359 | ui->msg->appendPlainText(current_time+"毫秒>地面站向下位移数据已发送"); 360 | ui->msg->moveCursor(QTextCursor::End, QTextCursor::MoveAnchor); 361 | 362 | accuracy=0; 363 | accuracy_send_cnt=0; 364 | accuracy_rec_cnt=0; 365 | } 366 | 367 | void remotectrl::on_manualsend_clicked() 368 | { 369 | //timer_remote->stop(); 370 | //delete timer_remote; 371 | if(ui->checkBox->isChecked()) 372 | { 373 | ui->checkBox->setChecked(false); 374 | } 375 | timer_event(); 376 | } 377 | -------------------------------------------------------------------------------- /NGroundStation/remotectrl.h: -------------------------------------------------------------------------------- 1 | #ifndef REMOTECTRL_H 2 | #define REMOTECTRL_H 3 | 4 | #include 5 | 6 | namespace Ui { 7 | class remotectrl; 8 | } 9 | 10 | class remotectrl : public QWidget 11 | { 12 | Q_OBJECT 13 | 14 | public: 15 | explicit remotectrl(QWidget *parent = nullptr); 16 | ~remotectrl(); 17 | void closeEvent(QCloseEvent *);//重写关闭事件 18 | void Send_RC(uint16_t ch0,uint16_t ch1,uint16_t ch2,uint16_t ch3,uint16_t ch4,uint16_t ch5,uint16_t ch6,uint16_t ch7,uint8_t unlock_flag,uint8_t takeoff_flag); 19 | void Send_DIS(uint8_t move_flag,uint8_t move_order,uint16_t move_distance); 20 | private: 21 | Ui::remotectrl *ui; 22 | signals: 23 | void exitwindows();//新建一个信号槽 24 | private slots: 25 | void on_checkBox_stateChanged(int arg1); 26 | void timer_event(); 27 | void sort_data12(double angle,double r); 28 | void sort_data34(double angle,double r); 29 | void sort_data_bt_unlock(bool flag); 30 | void sort_data_bt_takeoff(bool flag); 31 | void getcheck(uint8_t ch); 32 | void on_clear_clicked(); 33 | void on_bt_send1_clicked(); 34 | void on_bt_send2_clicked(); 35 | void on_bt_send3_clicked(); 36 | void on_bt_send4_clicked(); 37 | void on_bt_send5_clicked(); 38 | void on_bt_send6_clicked(); 39 | void on_manualsend_clicked(); 40 | }; 41 | 42 | #endif // REMOTECTRL_H 43 | -------------------------------------------------------------------------------- /NGroundStation/sendandreceive.cpp: -------------------------------------------------------------------------------- 1 | #include "sendandreceive.h" 2 | #include "ui_sendandreceive.h" 3 | #include "Headfile.h" 4 | 5 | #include "mainwindow.h" 6 | 7 | uint32_t rec_cnt=0; 8 | uint32_t send_cnt=0; 9 | QByteArray buffer_Serial; 10 | QByteArray str_buffer_Serial; 11 | serial_config config; 12 | QSerialPort* serialbasic=nullptr;//创建串口对象 13 | QTimer *timer_serialsendandreceive=nullptr; 14 | QTimer *timer_autosend=nullptr; 15 | sendandreceive::sendandreceive(QWidget *parent) : 16 | QWidget(parent), 17 | ui(new Ui::sendandreceive) 18 | { 19 | ui->setupUi(this); 20 | this->setWindowTitle("基本收发"); //设置主界面名称 21 | setWindowIcon(QIcon(":/image/senddata.png")); //设置主界面LOGO 22 | 23 | //串口接收界面刷新定时器 24 | timer_serialsendandreceive = new QTimer(this); 25 | connect(timer_serialsendandreceive, SIGNAL(timeout()), this, SLOT(timer_serialsendandreceiveEvent())); 26 | timer_serialsendandreceive->start(10); 27 | 28 | ui->send_period->setValidator(new QIntValidator(1, 100000, this));//限制数据输入范围 29 | 30 | QPalette palette(this->palette()); 31 | palette.setColor(QPalette::Background, QColor(233,235,254));//QColor(78,168,243) 32 | this->setPalette(palette); 33 | 34 | init(); 35 | connect(ui->cBox_SerialPortNum, SIGNAL(activated(int)),this,SLOT(serialconfig_update(int))); 36 | connect(ui->cBox_SerialPortBaud, SIGNAL(activated(int)),this,SLOT(serialconfig_update(int))); 37 | connect(ui->CBox_SerialPortcheck, SIGNAL(activated(int)),this,SLOT(serialconfig_update(int))); 38 | connect(ui->cBox_SerialPortStopBit, SIGNAL(activated(int)),this,SLOT(serialconfig_update(int))); 39 | connect(ui->cBox_SerialPortDataNum, SIGNAL(activated(int)),this,SLOT(serialconfig_update(int))); 40 | } 41 | 42 | sendandreceive::~sendandreceive() 43 | { 44 | delete ui; 45 | } 46 | 47 | void sendandreceive::on_bt_clearshow_clicked() 48 | { 49 | ui->SerialPortDataShow->clear();//清屏 50 | } 51 | 52 | void sendandreceive::on_bt_clearsend_clicked() 53 | { 54 | ui->SerialPortDataSend->clear();//清屏 55 | } 56 | 57 | void sendandreceive::timer_serialsendandreceiveEvent() 58 | { 59 | static uint32_t last_cnt=0; 60 | QByteArray bufferHex = str_buffer_Serial.toHex();//转换成hex 61 | bufferHex=bufferHex.toUpper();//转换成大写 62 | QString str_buffer1; 63 | if(ui->cb_rechex->isChecked())//16进制显示 64 | { 65 | str_buffer1 = QString(bufferHex);//转换成字符 66 | for(int i = str_buffer1.count(); i > 0; i = i-2) 67 | { 68 | str_buffer1.insert(i," "); 69 | } 70 | } 71 | else//字符形式显示 72 | { 73 | str_buffer1 = QString(str_buffer_Serial); 74 | } 75 | if(ui->opencolse->text()=="关闭串口") 76 | { 77 | ui->SerialPortDataShow->insertPlainText(str_buffer1); 78 | ui->SerialPortDataShow->moveCursor(QTextCursor::End); 79 | } 80 | str_buffer1=ui->SerialPortDataShow->toPlainText(); 81 | if(str_buffer1.size()>10000) ui->SerialPortDataShow->clear(); 82 | 83 | QString str1 ="共接收:"; 84 | QString str2=QString::number(rec_cnt,10);//转化成十进制字符型数据 85 | QString str3 ="字节,速度:"; 86 | QString str4=QString::number((uint32_t)((rec_cnt-last_cnt)/0.01),10);//转化成十进制字符型数据 87 | QString str5 ="字节/秒,共发送:"; 88 | QString str6 =QString::number(send_cnt,10);//转化成十进制字符型数据; 89 | QString str7 =str1+str2+str3+str4+str5+str6+"字节"; 90 | ui->Label_RecSend_Cnt->setText(str7); 91 | 92 | str_buffer_Serial.clear(); 93 | 94 | last_cnt=rec_cnt; 95 | } 96 | 97 | 98 | 99 | #include "mainwindow.h" 100 | #include "ui_mainwindow.h" 101 | void sendandreceive::on_bt_sendserialdata_clicked() 102 | { 103 | //emit senddata(ui->SerialPortDataSend->toPlainText()); 104 | 105 | if(ui->opencolse->text()=="打开串口") 106 | { 107 | QMessageBox::critical(this,"温馨提示","主窗口串口未打开。",QMessageBox::Yes,QMessageBox::Yes); 108 | return; 109 | } 110 | QString command = ui->SerialPortDataSend->toPlainText();//从发送窗口取出文本 111 | if(ui->cb_sendhex->isChecked()) 112 | { 113 | QStringList commadList = command.split(' ');//寻找空格把字符串分开成字符 114 | QByteArray byteArray; 115 | byteArray.resize(commadList.count());//初始化新数组 116 | bool ok = false; 117 | for(int i = 0; i < commadList.count(); i++) 118 | { 119 | byteArray[i]=commadList.at(i).toInt(&ok,16); 120 | } 121 | send_cnt+=commadList.count(); 122 | serialbasic->write(byteArray);//以16进制形式发送 123 | } 124 | else 125 | { 126 | serialbasic->write(command.toUtf8().data());//以字符形式发送 127 | send_cnt+=command.length(); 128 | } 129 | 130 | int a=(int)QThread::currentThreadId(); 131 | QString LogInfo=QString::number(a,10); 132 | //qDebug() << "sendandreceive " <<"threadID : "<cb_autosend->isChecked()) 146 | { 147 | timer_autosend = new QTimer(this); 148 | connect(timer_autosend, SIGNAL(timeout()), this, SLOT(timer_autosend_event())); 149 | QString period=ui->send_period->text(); 150 | int period_cnt=period.toInt(); 151 | timer_autosend->start(period_cnt); 152 | //qDebug()<<"自动发送开始"<<"start"; 153 | } 154 | else 155 | { 156 | timer_autosend->stop(); 157 | delete timer_autosend; 158 | //qDebug()<<"自动发送结束"<<"stop"; 159 | } 160 | } 161 | 162 | 163 | void sendandreceive::timer_autosend_event() 164 | { 165 | QString command = ui->SerialPortDataSend->toPlainText();//从发送窗口取出文本 166 | if(ui->opencolse->text()=="打开串口") 167 | { 168 | //QMessageBox::critical(this,"温馨提示","窗口串口未打开。",QMessageBox::Yes,QMessageBox::Yes); 169 | return; 170 | } 171 | 172 | if(ui->cb_sendhex->isChecked()) 173 | { 174 | QStringList commadList = command.split(' ');//寻找空格把字符串分开成字符 175 | QByteArray byteArray; 176 | byteArray.resize(commadList.count());//初始化新数组 177 | bool ok = false; 178 | for(int i = 0; i < commadList.count(); i++) 179 | { 180 | byteArray[i]=commadList.at(i).toInt(&ok,16); 181 | } 182 | send_cnt+=commadList.count(); 183 | serialbasic->write(byteArray);//以16进制形式发送 184 | } 185 | else 186 | { 187 | serialbasic->write(command.toUtf8().data());//以字符形式发送 188 | send_cnt+=command.length(); 189 | } 190 | } 191 | 192 | void sendandreceive::on_send_period_editingFinished()//设置发送周期,回车后生效 193 | { 194 | if(ui->cb_autosend->isChecked()) 195 | { 196 | QString period=ui->send_period->text(); 197 | int period_cnt=period.toInt(); 198 | timer_autosend->start(period_cnt); 199 | //qDebug()<<"周期设置完毕"<<"period_set success"; 200 | } 201 | } 202 | 203 | 204 | 205 | void sendandreceive::on_bt_send1_clicked() 206 | { 207 | if(ui->opencolse->text()=="打开串口") 208 | { 209 | QMessageBox::critical(this,"温馨提示","主窗口串口未打开。",QMessageBox::Yes,QMessageBox::Yes); 210 | return; 211 | } 212 | QString command = ui->lineEdit1->text();//从发送窗口取出文本 213 | if(ui->cb_hex1->isChecked()) 214 | { 215 | QStringList commadList = command.split(' ');//寻找空格把字符串分开成字符 216 | QByteArray byteArray; 217 | byteArray.resize(commadList.count());//初始化新数组 218 | bool ok = false; 219 | for(int i = 0; i < commadList.count(); i++) 220 | { 221 | byteArray[i]=commadList.at(i).toInt(&ok,16); 222 | } 223 | send_cnt+=commadList.count(); 224 | serialbasic->write(byteArray);//以16进制形式发送 225 | } 226 | else 227 | { 228 | serialbasic->write(command.toUtf8().data());//以字符形式发送 229 | send_cnt+=command.length(); 230 | } 231 | } 232 | 233 | void sendandreceive::on_bt_send2_clicked() 234 | { 235 | if(ui->opencolse->text()=="打开串口") 236 | { 237 | QMessageBox::critical(this,"温馨提示","主窗口串口未打开。",QMessageBox::Yes,QMessageBox::Yes); 238 | return; 239 | } 240 | QString command = ui->lineEdit2->text();//从发送窗口取出文本 241 | if(ui->cb_hex2->isChecked()) 242 | { 243 | QStringList commadList = command.split(' ');//寻找空格把字符串分开成字符 244 | QByteArray byteArray; 245 | byteArray.resize(commadList.count());//初始化新数组 246 | bool ok = false; 247 | for(int i = 0; i < commadList.count(); i++) 248 | { 249 | byteArray[i]=commadList.at(i).toInt(&ok,16); 250 | } 251 | send_cnt+=commadList.count(); 252 | serialbasic->write(byteArray);//以16进制形式发送 253 | } 254 | else 255 | { 256 | serialbasic->write(command.toUtf8().data());//以字符形式发送 257 | send_cnt+=command.length(); 258 | } 259 | } 260 | 261 | void sendandreceive::on_bt_send3_clicked() 262 | { 263 | if(ui->opencolse->text()=="打开串口") 264 | { 265 | QMessageBox::critical(this,"温馨提示","主窗口串口未打开。",QMessageBox::Yes,QMessageBox::Yes); 266 | return; 267 | } 268 | QString command = ui->lineEdit3->text();//从发送窗口取出文本 269 | if(ui->cb_hex3->isChecked()) 270 | { 271 | QStringList commadList = command.split(' ');//寻找空格把字符串分开成字符 272 | QByteArray byteArray; 273 | byteArray.resize(commadList.count());//初始化新数组 274 | bool ok = false; 275 | for(int i = 0; i < commadList.count(); i++) 276 | { 277 | byteArray[i]=commadList.at(i).toInt(&ok,16); 278 | } 279 | send_cnt+=commadList.count(); 280 | serialbasic->write(byteArray);//以16进制形式发送 281 | } 282 | else 283 | { 284 | serialbasic->write(command.toUtf8().data());//以字符形式发送 285 | send_cnt+=command.length(); 286 | } 287 | } 288 | 289 | void sendandreceive::on_bt_send4_clicked() 290 | { 291 | if(ui->opencolse->text()=="打开串口") 292 | { 293 | QMessageBox::critical(this,"温馨提示","主窗口串口未打开。",QMessageBox::Yes,QMessageBox::Yes); 294 | return; 295 | } 296 | QString command = ui->lineEdit4->text();//从发送窗口取出文本 297 | if(ui->cb_hex4->isChecked()) 298 | { 299 | QStringList commadList = command.split(' ');//寻找空格把字符串分开成字符 300 | QByteArray byteArray; 301 | byteArray.resize(commadList.count());//初始化新数组 302 | bool ok = false; 303 | for(int i = 0; i < commadList.count(); i++) 304 | { 305 | byteArray[i]=commadList.at(i).toInt(&ok,16); 306 | } 307 | send_cnt+=commadList.count(); 308 | serialbasic->write(byteArray);//以16进制形式发送 309 | } 310 | else 311 | { 312 | serialbasic->write(command.toUtf8().data());//以字符形式发送 313 | send_cnt+=command.length(); 314 | } 315 | } 316 | 317 | void sendandreceive::on_bt_send5_clicked() 318 | { 319 | if(ui->opencolse->text()=="打开串口") 320 | { 321 | QMessageBox::critical(this,"温馨提示","主窗口串口未打开。",QMessageBox::Yes,QMessageBox::Yes); 322 | return; 323 | } 324 | QString command = ui->lineEdit5->text();//从发送窗口取出文本 325 | if(ui->cb_hex5->isChecked()) 326 | { 327 | QStringList commadList = command.split(' ');//寻找空格把字符串分开成字符 328 | QByteArray byteArray; 329 | byteArray.resize(commadList.count());//初始化新数组 330 | bool ok = false; 331 | for(int i = 0; i < commadList.count(); i++) 332 | { 333 | byteArray[i]=commadList.at(i).toInt(&ok,16); 334 | } 335 | send_cnt+=commadList.count(); 336 | serialbasic->write(byteArray);//以16进制形式发送 337 | } 338 | else 339 | { 340 | serialbasic->write(command.toUtf8().data());//以字符形式发送 341 | send_cnt+=command.length(); 342 | } 343 | } 344 | 345 | 346 | void sendandreceive::init(void) 347 | { 348 | QList comList = QSerialPortInfo::availablePorts();//获取可用串口列表 349 | 350 | ui->cBox_SerialPortNum->clear();//清空item,避免搜索后重复添加 351 | ui->cBox_SerialPortBaud->clear();//清空item,避免搜索后重复添加 352 | ui->CBox_SerialPortcheck->clear();//清空item,避免搜索后重复添加 353 | ui->cBox_SerialPortStopBit->clear();//清空item,避免搜索后重复添加 354 | ui->cBox_SerialPortDataNum->clear();//清空item,避免搜索后重复添加 355 | 356 | if(comList.isEmpty())//若没有可用串口,则发送警告 357 | { 358 | QMessageBox::warning(this,"Waring!","There's no avalible COM to use, plese check your serialport!"); 359 | } 360 | else//将可用串口显示到comboBox上以供选择 361 | { 362 | for(int i = 0; i < comList.size(); i ++) 363 | { 364 | ui->cBox_SerialPortNum->addItem(comList[i].portName()); 365 | //ui->cBox_SerialPortNum->addItem(comList[i].description());//设备描述 366 | } 367 | } 368 | 369 | QStringList baudRateList = QStringList() << "1200" << "2400" << "4800" 370 | << "9600" << "14400" << "19200" << "38400" << "43000" << "57600" 371 | << "76800" << "115200" << "128000" << "230400" << "256000" <<"460800" 372 | << "921600" << "1382400"; 373 | QStringList parityList = QStringList() << "无" << "奇校验" << "偶校验"; 374 | QStringList stopBitsList = QStringList() << "1" << "1.5" << "2"; 375 | QStringList dataBitsList = QStringList() << "8" << "7" << "6" << "5"; 376 | 377 | ui->cBox_SerialPortBaud->addItems(baudRateList); 378 | ui->CBox_SerialPortcheck->addItems(parityList); 379 | ui->cBox_SerialPortStopBit->addItems(stopBitsList); 380 | ui->cBox_SerialPortDataNum->addItems(dataBitsList); 381 | 382 | ui->cBox_SerialPortBaud->setCurrentIndex(10);//设置115200为默认选项 383 | 384 | 385 | config.serialname=ui->cBox_SerialPortNum->currentText();//获取串口号; 386 | QString strBaudRate = ui->cBox_SerialPortBaud->currentText();//获取波特率 387 | config.baudrate=strBaudRate.toInt();//文本转整型; 388 | config.parity=ui->CBox_SerialPortcheck->currentIndex();//校验形式; 389 | config.dataBit=ui->cBox_SerialPortDataNum->currentIndex();//数据位数; 390 | config.stopBit=ui->cBox_SerialPortStopBit->currentIndex();//停止位数; 391 | } 392 | 393 | void sendandreceive::on_opencolse_clicked() 394 | { 395 | if(ui->opencolse->text()=="打开串口") 396 | { 397 | 398 | 399 | serialbasic= new QSerialPort(this);//构建串口设备 400 | serialbasic->setPortName(config.serialname);//设置串口号 401 | if(serialbasic->isOpen())//如果串口已打开,立刻关闭 402 | { 403 | serialbasic->close(); 404 | } 405 | 406 | bool bOK = serialbasic->open(QIODevice::ReadWrite); 407 | if(!bOK) 408 | { 409 | QMessageBox::critical(this,"提示","无法打开串口,请检查是否被占用。",QMessageBox::Yes,QMessageBox::Yes); 410 | return; 411 | } 412 | 413 | serialbasic->setBaudRate(config.baudrate); 414 | 415 | 416 | switch(config.parity)//设置数据校验形式 417 | { 418 | case 0: 419 | serialbasic->setParity(QSerialPort::NoParity);//无校验 420 | break; 421 | case 1: 422 | serialbasic->setParity(QSerialPort::OddParity);//奇校验 423 | break; 424 | case 2: 425 | serialbasic->setParity(QSerialPort::EvenParity);//偶校验 426 | break; 427 | default: 428 | serialbasic->setParity(QSerialPort::NoParity); 429 | break; 430 | } 431 | 432 | switch(config.dataBit)//设置数据位 433 | { 434 | case 0: 435 | serialbasic->setDataBits(QSerialPort::Data8); 436 | break; 437 | case 1: 438 | serialbasic->setDataBits(QSerialPort::Data7); 439 | break; 440 | case 2: 441 | serialbasic->setDataBits(QSerialPort::Data6); 442 | break; 443 | case 3: 444 | serialbasic->setDataBits(QSerialPort::Data5); 445 | break; 446 | default: 447 | serialbasic->setDataBits(QSerialPort::Data8); 448 | break; 449 | } 450 | 451 | switch(config.stopBit)//设置停止位 452 | { 453 | case 0: 454 | serialbasic->setStopBits(QSerialPort::OneStop); 455 | break; 456 | case 1: 457 | serialbasic->setStopBits(QSerialPort::OneAndHalfStop); 458 | break; 459 | case 2: 460 | serialbasic->setStopBits(QSerialPort::TwoStop); 461 | break; 462 | default: 463 | serialbasic->setStopBits(QSerialPort::OneStop); 464 | break; 465 | } 466 | serialbasic->setFlowControl(QSerialPort::NoFlowControl); //无流控 467 | serialbasic->setReadBufferSize(8192); //数据缓冲区长度 468 | connect(serialbasic,SIGNAL(readyRead()),this,SLOT(serialPort_getdata()),Qt::DirectConnection);//连接串口接收信号与槽函数 469 | 470 | ui->cBox_SerialPortNum->setEnabled(false); 471 | ui->cBox_SerialPortBaud->setEnabled(false); 472 | ui->CBox_SerialPortcheck->setEnabled(false); 473 | ui->cBox_SerialPortDataNum->setEnabled(false); 474 | ui->cBox_SerialPortStopBit->setEnabled(false); 475 | 476 | ui->opencolse->setText("关闭串口"); 477 | ui->opencolse->setIcon(QIcon(":/image/opencom.png")); 478 | } 479 | else 480 | { 481 | ui->opencolse->setText("打开串口"); 482 | ui->opencolse->setIcon(QIcon(":/image/closecom.png")); 483 | serialbasic->close(); 484 | delete serialbasic; 485 | 486 | ui->cBox_SerialPortNum->setEnabled(true); 487 | ui->cBox_SerialPortBaud->setEnabled(true); 488 | ui->CBox_SerialPortcheck->setEnabled(true); 489 | ui->cBox_SerialPortDataNum->setEnabled(true); 490 | ui->cBox_SerialPortStopBit->setEnabled(true); 491 | } 492 | } 493 | 494 | void sendandreceive::serialconfig_update(int index) 495 | { 496 | config.serialname=ui->cBox_SerialPortNum->currentText(); //获取串口号; 497 | QString strBaudRate =ui->cBox_SerialPortBaud->currentText();//获取波特率 498 | config.baudrate=strBaudRate.toInt(); //文本转整型; 499 | config.parity=ui->CBox_SerialPortcheck->currentIndex(); //校验形式; 500 | config.dataBit=ui->cBox_SerialPortDataNum->currentIndex(); //数据位数; 501 | config.stopBit=ui->cBox_SerialPortStopBit->currentIndex(); //停止位数; 502 | 503 | //qDebug() << config.serialname<bytesAvailable(); 516 | if(byteLen_now < 0) 517 | { 518 | return; 519 | } 520 | //qDebug()<<"当前缓存长度"<readAll(); 523 | 524 | QByteArray bufferHex = buffer_Serial.toHex();//转换成hex 525 | bufferHex=bufferHex.toUpper();//转换成大写 526 | rec_cnt=rec_cnt + buffer_Serial.count();//接收计数器自增 527 | str_buffer_Serial+=buffer_Serial; 528 | 529 | //QString str_buffer = QString(buffer_Serial); 530 | QString str_buffer = QString(bufferHex);//转换成字符 531 | for(int i = str_buffer.count(); i > 0; i = i-2) 532 | { 533 | str_buffer.insert(i," "); 534 | } 535 | 536 | buffer_Serial.clear(); 537 | } 538 | 539 | 540 | void sendandreceive::on_cBox_SerialPortNum_highlighted(int index) 541 | { 542 | QList comList = QSerialPortInfo::availablePorts();//获取可用串口列表 543 | //qDebug() <<"搜索长度"<cBox_SerialPortNum->count(); 545 | if(comList.isEmpty())//若没有可用串口,则发送警告 546 | { 547 | QMessageBox::warning(this,"Waring!","There's no avalible COM to use, plese check your serialport!"); 548 | } 549 | else//将可用串口显示到comboBox上以供选择 550 | { 551 | if(comList.size()!=ui->cBox_SerialPortNum->count()) 552 | { 553 | ui->cBox_SerialPortNum->clear();//清空item,避免搜索后重复添加 554 | for(int i = 0; i < comList.size(); i ++) 555 | { 556 | ui->cBox_SerialPortNum->addItem(comList[i].portName()); 557 | } 558 | } 559 | } 560 | } 561 | 562 | 563 | //当窗口出发关闭事件后,将信号发射出去 564 | void sendandreceive::closeEvent(QCloseEvent *) 565 | { 566 | emit exitwindows(); 567 | } 568 | -------------------------------------------------------------------------------- /NGroundStation/sendandreceive.h: -------------------------------------------------------------------------------- 1 | #ifndef SENDANDRECEIVE_H 2 | #define SENDANDRECEIVE_H 3 | 4 | #include 5 | #include "Headfile.h" 6 | 7 | 8 | extern serial_config config; 9 | extern QSerialPort* serialbasic; 10 | 11 | 12 | namespace Ui { 13 | class sendandreceive; 14 | } 15 | 16 | class sendandreceive : public QWidget 17 | { 18 | Q_OBJECT 19 | public: 20 | explicit sendandreceive(QWidget *parent = nullptr); 21 | ~sendandreceive(); 22 | void closeEvent(QCloseEvent *);//重写关闭事件 23 | //private: 24 | Ui::sendandreceive *ui; 25 | private slots: 26 | void init(void); 27 | void on_bt_clearshow_clicked(); 28 | void timer_serialsendandreceiveEvent(); 29 | void on_bt_sendserialdata_clicked(); 30 | void on_bt_clearstatistics_clicked(); 31 | 32 | void on_cb_autosend_stateChanged(int arg1); 33 | void timer_autosend_event(); 34 | void on_send_period_editingFinished(); 35 | 36 | void on_bt_clearsend_clicked(); 37 | 38 | void on_bt_send1_clicked(); 39 | 40 | void on_bt_send2_clicked(); 41 | 42 | void on_bt_send3_clicked(); 43 | 44 | void on_bt_send4_clicked(); 45 | 46 | void on_bt_send5_clicked(); 47 | 48 | void on_opencolse_clicked(); 49 | void serialconfig_update(int index); 50 | void serialPort_getdata(); 51 | 52 | void on_cBox_SerialPortNum_highlighted(int index); 53 | 54 | signals: 55 | void senddata(QString); 56 | void exitwindows();//新建一个信号槽 57 | }; 58 | 59 | #endif // SENDANDRECEIVE_H 60 | -------------------------------------------------------------------------------- /NGroundStation/serialportthread.cpp: -------------------------------------------------------------------------------- 1 | #include "Headfile.h" 2 | #include "serialportthread.h" 3 | #include 4 | #include 5 | 6 | 7 | 8 | qint64 thr_cnt1=0,thr_cnt2=0; 9 | qint64 thr_cnt3=0,thr_cnt4=0; 10 | qint64 thr_cnt5=0; 11 | 12 | //第一帧数据,功能字0x01 数据长度24 13 | float pitch=0,roll=0,yaw=0;//姿态角 14 | float pitch_gyro=0,roll_gyro=0,yaw_gyro=0;//姿态角速度 15 | float vbat=0; 16 | float imu_temp=0; 17 | uint8_t fly_mode=0;//飞行模式 18 | uint8_t armed_flag=0;//解锁标志 19 | 20 | //第二帧数据,功能字0x02 数据长度18 21 | int16_t ax,ay,az; 22 | int16_t gx,gy,gz; 23 | int16_t mx,my,mz; 24 | 25 | //第三帧数据,功能字0x03 数据长度16 26 | int16_t rc[8]; 27 | 28 | //第四帧数据,功能字0x04 数据长度14 29 | double gps_lng=0,gps_lat=0,gps_alt=0; 30 | int16_t gps_pdop=0; 31 | uint8_t gps_state=0; 32 | uint8_t gps_satellite_num=0; 33 | 34 | //第五帧数据,功能字0x05 数据长度8 35 | float lat_pos_obs=0,lng_pos_obs=0; 36 | float lat_vel_obs=0,lng_vel_obs=0; 37 | 38 | //第六帧数据,功能字0x06 数据长度16 39 | float alt_obs_baro=0,alt_obs_ult=0; 40 | float opt_vel_p=0,opt_vel_r=0; 41 | 42 | //第七帧数据,功能字0x07 数据长度8 43 | float alt_pos_fus=0;//融合高度 44 | float alt_vel_fus=0;//融合高度 45 | float alt_accel_fus=0;//融合高度 46 | 47 | //第八帧数据,功能字0x08 数据长度24 48 | float lat_pos_fusion=0,lng_pos_fusion=0; 49 | float lat_vel_fusion=0,lng_vel_fusion=0; 50 | float lat_accel_fusion=0,lng_accel_fusion=0; 51 | 52 | //第九帧数据,功能字0x09 数据长度36 53 | float userdata[9]={0}; 54 | 55 | //第10、11、12、13、14、15帧数据,功能字0x0A、0x0B、0x0C、0x0D、0x0E、0x0F 数据长度18 56 | uint16_t kp[18]={0}; 57 | uint16_t ki[18]={0}; 58 | uint16_t kd[18]={0}; 59 | 60 | 61 | //第16帧数据,功能字11 数据长度36 62 | uint8_t gyro_auto_cal_flag=0; 63 | float gyro_x_raw=0; 64 | float gyro_y_raw=0; 65 | float gyro_z_raw=0; 66 | float acce_x_raw=0; 67 | float acce_y_raw=0; 68 | float acce_z_raw=0; 69 | float mag_x_raw=0; 70 | float mag_y_raw=0; 71 | float mag_z_raw=0; 72 | 73 | 74 | //第17帧数据,功能字12 数据长度56 75 | float gyro_x_offset; 76 | float gyro_y_offset; 77 | float gyro_z_offset; 78 | float acce_x_offset; 79 | float acce_y_offset; 80 | float acce_z_offset; 81 | float acce_x_scale; 82 | float acce_y_scale; 83 | float acce_z_scale; 84 | float mag_x_offset; 85 | float mag_y_offset; 86 | float mag_z_offset; 87 | float pitch_offset; 88 | float roll_offset; 89 | 90 | 91 | //第16帧数据,功能字0x10 数据长度16 92 | uint16_t targeheight,safeheight,safevbat,maxheight; 93 | uint16_t maxradius,maxupvel,maxdownvel,maxhorvel; 94 | -------------------------------------------------------------------------------- /NGroundStation/serialportthread.h: -------------------------------------------------------------------------------- 1 | #ifndef SERIALPORTTHREAD_H 2 | #define SERIALPORTTHREAD_H 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | #define BYTE0(dwTemp) ( *( (char *)(&dwTemp) ) ) 9 | #define BYTE1(dwTemp) ( *( (char *)(&dwTemp) + 1) ) 10 | #define BYTE2(dwTemp) ( *( (char *)(&dwTemp) + 2) ) 11 | #define BYTE3(dwTemp) ( *( (char *)(&dwTemp) + 3) ) 12 | 13 | 14 | #define NCLink_Head0 0xFF 15 | #define NCLink_Head1 0xFC 16 | #define NCLink_End0 0xA1 17 | #define NCLink_End1 0xA2 18 | #define BufferSizeMax (65536*2) 19 | 20 | 21 | extern qint64 thr_cnt1,thr_cnt2; 22 | extern qint64 thr_cnt3,thr_cnt4; 23 | extern qint64 thr_cnt5; 24 | 25 | 26 | 27 | 28 | 29 | 30 | //第一帧数据,功能字0x01 数据长度12 31 | extern float pitch,roll,yaw;//姿态角 32 | extern float pitch_gyro,roll_gyro,yaw_gyro;//姿态角速度 33 | extern float vbat; 34 | extern float imu_temp; 35 | extern uint8_t fly_mode;//飞行模式 36 | extern uint8_t armed_flag;//解锁标志 37 | 38 | //第二帧数据,功能字0x02 数据长度18 39 | extern int16_t ax,ay,az; 40 | extern int16_t gx,gy,gz; 41 | extern int16_t mx,my,mz; 42 | 43 | 44 | //第三帧数据,功能字0x03 数据长度16 45 | extern int16_t rc[8]; 46 | 47 | 48 | //第四帧数据,功能字0x04 数据长度14 49 | extern double gps_lng,gps_lat,gps_alt; 50 | extern int16_t gps_pdop; 51 | extern uint8_t gps_state; 52 | extern uint8_t gps_satellite_num; 53 | 54 | //第五帧数据,功能字0x05 数据长度8 55 | extern float lat_vel_obs,lng_vel_obs; 56 | extern float lat_pos_obs,lng_pos_obs; 57 | 58 | //第六帧数据,功能字0x06 数据长度8 59 | extern float alt_obs_baro,alt_obs_ult; 60 | extern float opt_vel_p,opt_vel_r; 61 | 62 | 63 | //第七帧数据,功能字0x06 数据长度8 64 | extern float alt_pos_fus;//融合高度 65 | extern float alt_vel_fus;//融合高度 66 | extern float alt_accel_fus;//融合高度 67 | 68 | //第八帧数据,功能字0x08 数据长度24 69 | extern float lat_pos_fusion,lng_pos_fusion; 70 | extern float lat_vel_fusion,lng_vel_fusion; 71 | extern float lat_accel_fusion,lng_accel_fusion; 72 | 73 | 74 | //第九帧数据,功能字0x09 数据长度36 75 | extern float userdata[9]; 76 | 77 | //第10、11、12、13、14、15帧数据,功能字0x0A、0x0B、0x0C、0x0D、0x0E、0x0F 数据长度18 78 | extern uint16_t kp[18]; 79 | extern uint16_t ki[18]; 80 | extern uint16_t kd[18]; 81 | 82 | //第16帧数据,功能字0x10 数据长度16 83 | extern uint16_t targeheight,safeheight,safevbat,maxheight; 84 | extern uint16_t maxradius,maxupvel,maxdownvel,maxhorvel; 85 | 86 | //第17帧数据,功能字11 数据长度36 87 | extern uint8_t gyro_auto_cal_flag; 88 | extern float gyro_x_raw,gyro_y_raw,gyro_z_raw; 89 | extern float acce_x_raw,acce_y_raw,acce_z_raw; 90 | extern float mag_x_raw,mag_y_raw,mag_z_raw; 91 | 92 | 93 | //第17帧数据,功能字12 数据长度56 94 | extern float gyro_x_offset,gyro_y_offset,gyro_z_offset; 95 | extern float acce_x_offset,acce_y_offset,acce_z_offset; 96 | extern float acce_x_scale,acce_y_scale,acce_z_scale; 97 | extern float mag_x_offset,mag_y_offset,mag_z_offset; 98 | extern float pitch_offset,roll_offset; 99 | 100 | 101 | #endif // SERIALPORTTHREAD_H 102 | -------------------------------------------------------------------------------- /NGroundStation/serialsetup.cpp: -------------------------------------------------------------------------------- 1 | #include "serialsetup.h" 2 | #include "ui_serialsetup.h" 3 | 4 | #include "Headfile.h" 5 | 6 | 7 | serial_config serialconfig; 8 | extern serialsetup *usbsetup; 9 | 10 | 11 | serialsetup::serialsetup(QWidget *parent) : 12 | QWidget(parent), 13 | ui(new Ui::serialsetup) 14 | { 15 | ui->setupUi(this); 16 | setWindowFlags(windowFlags()&~Qt::WindowMaximizeButtonHint); // 禁止最大化按钮 17 | setFixedSize(this->width(),this->height()); // 禁止拖动窗口大小 18 | this->setWindowTitle("串口配置"); //设置主界面名称 19 | setWindowIcon(QIcon(":/image/usb.png")); //设置主界面LOGO 20 | QPalette palette(this->palette()); 21 | palette.setColor(QPalette::Background, QColor(233,235,254));//QColor(78,168,243) 22 | this->setPalette(palette); 23 | 24 | connect(ui->cBox_SerialPortNum, SIGNAL(activated(int)),this,SLOT(serialconfig_update(int))); 25 | connect(ui->cBox_SerialPortBaud, SIGNAL(activated(int)),this,SLOT(serialconfig_update(int))); 26 | connect(ui->CBox_SerialPortcheck, SIGNAL(activated(int)),this,SLOT(serialconfig_update(int))); 27 | connect(ui->cBox_SerialPortStopBit, SIGNAL(activated(int)),this,SLOT(serialconfig_update(int))); 28 | connect(ui->cBox_SerialPortDataNum, SIGNAL(activated(int)),this,SLOT(serialconfig_update(int))); 29 | 30 | connect(ui->SerialPortBaud,SIGNAL(editingFinished()),this,SLOT(serial_update())); 31 | 32 | /* 33 | void textChanged(const QString &); 34 | void textEdited(const QString &); 35 | void cursorPositionChanged(int, int); 36 | void returnPressed(); 37 | void editingFinished(); 38 | void selectionChanged(); 39 | void inputRejected(); 40 | */ 41 | ui->SerialPortBaud->setValidator(new QIntValidator(0, 4500000, this));//限制数据输入范围 42 | } 43 | 44 | 45 | serialsetup::~serialsetup() 46 | { 47 | delete ui; 48 | } 49 | 50 | 51 | void serialsetup::serialinit(void) 52 | { 53 | QList comList = QSerialPortInfo::availablePorts();//获取可用串口列表 54 | 55 | ui->cBox_SerialPortNum->clear();//清空item,避免搜索后重复添加 56 | ui->cBox_SerialPortBaud->clear();//清空item,避免搜索后重复添加 57 | ui->CBox_SerialPortcheck->clear();//清空item,避免搜索后重复添加 58 | ui->cBox_SerialPortStopBit->clear();//清空item,避免搜索后重复添加 59 | ui->cBox_SerialPortDataNum->clear();//清空item,避免搜索后重复添加 60 | 61 | if(comList.isEmpty())//若没有可用串口,则发送警告 62 | { 63 | QMessageBox::warning(this,"串口异常警告","电脑没有可用串口设备, 请检查硬件连接!!!"); 64 | } 65 | else//将可用串口显示到comboBox上以供选择 66 | { 67 | for(int i = 0; i < comList.size(); i ++) 68 | { 69 | ui->cBox_SerialPortNum->addItem(comList[i].portName()); 70 | //ui->cBox_SerialPortNum->addItem(comList[i].description());//设备描述 71 | } 72 | } 73 | /* 74 | QStringList comList = QStringList() << "COM0" << "COM1" << "COM2" 75 | << "COM3" << "COM4" << "COM5" << "COM6" << "COM7" << "COM8" 76 | << "COM9" << "COM10" << "COM11" << "COM12" << "COM13" <<"COM14" 77 | << "COM15" << "COM16"; 78 | ui->cBox_SerialPortNum->addItems(comList); 79 | */ 80 | QStringList baudRateList = QStringList() << "1200" << "2400" << "4800" 81 | << "9600" << "14400" << "19200" << "38400" << "43000" << "57600" 82 | << "76800" << "115200" << "128000" << "230400" << "256000" <<"460800" 83 | << "921600" << "1382400"; 84 | QStringList parityList = QStringList() << "无" << "奇校验" << "偶校验"; 85 | QStringList stopBitsList = QStringList() << "1" << "1.5" << "2"; 86 | QStringList dataBitsList = QStringList() << "8" << "7" << "6" << "5"; 87 | 88 | ui->cBox_SerialPortBaud->addItems(baudRateList); 89 | ui->CBox_SerialPortcheck->addItems(parityList); 90 | ui->cBox_SerialPortStopBit->addItems(stopBitsList); 91 | ui->cBox_SerialPortDataNum->addItems(dataBitsList); 92 | 93 | ui->cBox_SerialPortBaud->setCurrentIndex(15);//设置115200为默认选项 15 94 | 95 | serial_update(); 96 | } 97 | 98 | 99 | void serialsetup::serialsetup_enable(bool flag) 100 | { 101 | serialconfig.serialname=usbsetup->ui->cBox_SerialPortNum->currentText();//获取串口号; 102 | //QString strBaudRate = usbsetup->ui->cBox_SerialPortBaud->currentText();//获取波特率 103 | QString strBaudRate = usbsetup->ui->SerialPortBaud->text();//获取波特率 104 | serialconfig.baudrate=strBaudRate.toInt();//文本转整型; 105 | serialconfig.parity=usbsetup->ui->CBox_SerialPortcheck->currentIndex();//校验形式; 106 | serialconfig.dataBit=usbsetup->ui->cBox_SerialPortDataNum->currentIndex();//数据位数; 107 | serialconfig.stopBit=usbsetup->ui->cBox_SerialPortStopBit->currentIndex();//停止位数; 108 | 109 | ui->cBox_SerialPortNum->setEnabled(flag); 110 | ui->cBox_SerialPortBaud->setEnabled(flag); 111 | ui->cBox_SerialPortDataNum->setEnabled(flag); 112 | ui->CBox_SerialPortcheck->setEnabled(flag); 113 | ui->cBox_SerialPortStopBit->setEnabled(flag); 114 | } 115 | 116 | 117 | 118 | void serialsetup::serialconfig_update(int index) 119 | { 120 | serialconfig.serialname=usbsetup->ui->cBox_SerialPortNum->currentText();//获取串口号; 121 | //QString strBaudRate = usbsetup->ui->cBox_SerialPortBaud->currentText();//获取波特率 122 | QString strBaudRate = usbsetup->ui->SerialPortBaud->text();//获取波特率 123 | serialconfig.baudrate=strBaudRate.toInt();//文本转整型; 124 | serialconfig.parity=usbsetup->ui->CBox_SerialPortcheck->currentIndex();//校验形式; 125 | serialconfig.dataBit=usbsetup->ui->cBox_SerialPortDataNum->currentIndex();//数据位数; 126 | serialconfig.stopBit=usbsetup->ui->cBox_SerialPortStopBit->currentIndex();//停止位数; 127 | } 128 | 129 | void serialsetup::serial_update() 130 | { 131 | serialconfig.serialname=usbsetup->ui->cBox_SerialPortNum->currentText();//获取串口号; 132 | //QString strBaudRate = usbsetup->ui->cBox_SerialPortBaud->currentText();//获取波特率 133 | QString strBaudRate = usbsetup->ui->SerialPortBaud->text();//获取波特率 134 | serialconfig.baudrate=strBaudRate.toInt();//文本转整型; 135 | serialconfig.parity=usbsetup->ui->CBox_SerialPortcheck->currentIndex();//校验形式; 136 | serialconfig.dataBit=usbsetup->ui->cBox_SerialPortDataNum->currentIndex();//数据位数; 137 | serialconfig.stopBit=usbsetup->ui->cBox_SerialPortStopBit->currentIndex();//停止位数; 138 | } 139 | 140 | 141 | void serialsetup::on_cBox_SerialPortNum_highlighted(int index) 142 | { 143 | QList comList = QSerialPortInfo::availablePorts();//获取可用串口列表 144 | //qDebug() <<"搜索长度"<cBox_SerialPortNum->count(); 146 | if(comList.isEmpty())//若没有可用串口,则发送警告 147 | { 148 | QMessageBox::warning(this,"Waring!","There's no avalible COM to use, plese check your serialport!"); 149 | } 150 | else//将可用串口显示到comboBox上以供选择 151 | { 152 | if(comList.size()!=ui->cBox_SerialPortNum->count()) 153 | { 154 | ui->cBox_SerialPortNum->clear();//清空item,避免搜索后重复添加 155 | for(int i = 0; i < comList.size(); i ++) 156 | { 157 | ui->cBox_SerialPortNum->addItem(comList[i].portName()); 158 | } 159 | } 160 | } 161 | } 162 | 163 | //当窗口出发关闭事件后,将信号发射出去 164 | void serialsetup::closeEvent(QCloseEvent *) 165 | { 166 | emit exitwindows(); 167 | } 168 | 169 | 170 | void serialsetup::on_cBox_SerialPortBaud_currentIndexChanged(int index) 171 | { 172 | ui->SerialPortBaud->setText(ui->cBox_SerialPortBaud->currentText()); 173 | } 174 | -------------------------------------------------------------------------------- /NGroundStation/serialsetup.h: -------------------------------------------------------------------------------- 1 | #ifndef SERIALSETUP_H 2 | #define SERIALSETUP_H 3 | 4 | #include 5 | #include "Headfile.h" 6 | 7 | 8 | 9 | extern serial_config serialconfig; 10 | 11 | 12 | namespace Ui { 13 | class serialsetup; 14 | } 15 | 16 | class serialsetup : public QWidget 17 | { 18 | Q_OBJECT 19 | 20 | public: 21 | explicit serialsetup(QWidget *parent = nullptr); 22 | ~serialsetup(); 23 | void closeEvent(QCloseEvent *);//重写关闭事件 24 | void serialinit(void); 25 | void serialsetup_enable(bool flag); 26 | //private: 27 | Ui::serialsetup *ui; 28 | private slots: 29 | void serialconfig_update(int index); 30 | void serial_update(); 31 | void on_cBox_SerialPortNum_highlighted(int index); 32 | void on_cBox_SerialPortBaud_currentIndexChanged(int index); 33 | 34 | signals: 35 | void exitwindows();//新建一个信号槽 36 | }; 37 | 38 | #endif // SERIALSETUP_H 39 | -------------------------------------------------------------------------------- /NGroundStation/serialsetup.ui: -------------------------------------------------------------------------------- 1 | 2 | 3 | serialsetup 4 | 5 | 6 | 7 | 0 8 | 0 9 | 356 10 | 232 11 | 12 | 13 | 14 | Form 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 0 30 | 0 31 | 32 | 33 | 34 | 35 | 200 36 | 16777215 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 0 52 | 0 53 | 54 | 55 | 56 | 57 | 16777215 58 | 16777215 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 0 71 | 0 72 | 73 | 74 | 75 | 串口号: 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 0 84 | 0 85 | 86 | 87 | 88 | 波特率: 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 0 97 | 0 98 | 99 | 100 | 101 | 数据位: 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 0 110 | 0 111 | 112 | 113 | 114 | 校验: 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 0 123 | 0 124 | 125 | 126 | 127 | 停止位: 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | -------------------------------------------------------------------------------- /NGroundStation/serialthread.qrc: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /NGroundStation/setparameter.cpp: -------------------------------------------------------------------------------- 1 | #include "Headfile.h" 2 | #include "setparameter.h" 3 | #include "ui_setparameter.h" 4 | 5 | 6 | QTimer *setparameter=nullptr; 7 | SetParameter::SetParameter(QWidget *parent) : 8 | QWidget(parent), 9 | ui(new Ui::SetParameter) 10 | { 11 | ui->setupUi(this); 12 | 13 | this->setWindowTitle("参数调试"); 14 | setWindowIcon(QIcon(":/image/debug.png")); 15 | 16 | QPalette palette(this->palette()); 17 | palette.setColor(QPalette::Background, QColor(233,235,254));//QColor(78,168,243) 18 | this->setPalette(palette); 19 | 20 | ui->kp1->setValidator(new QIntValidator(0, 100000, this));//限制数据输入范围 21 | ui->kp2->setValidator(new QIntValidator(0, 100000, this)); 22 | ui->kp3->setValidator(new QIntValidator(0, 100000, this)); 23 | ui->kp4->setValidator(new QIntValidator(0, 100000, this)); 24 | ui->kp5->setValidator(new QIntValidator(0, 100000, this)); 25 | ui->kp6->setValidator(new QIntValidator(0, 100000, this)); 26 | ui->kp7->setValidator(new QIntValidator(0, 100000, this)); 27 | ui->kp8->setValidator(new QIntValidator(0, 100000, this)); 28 | ui->kp9->setValidator(new QIntValidator(0, 100000, this)); 29 | ui->kp10->setValidator(new QIntValidator(0, 100000, this)); 30 | ui->kp11->setValidator(new QIntValidator(0, 100000, this)); 31 | ui->kp12->setValidator(new QIntValidator(0, 100000, this)); 32 | ui->kp13->setValidator(new QIntValidator(0, 100000, this)); 33 | ui->kp14->setValidator(new QIntValidator(0, 100000, this)); 34 | ui->kp15->setValidator(new QIntValidator(0, 100000, this)); 35 | ui->kp16->setValidator(new QIntValidator(0, 100000, this)); 36 | ui->kp17->setValidator(new QIntValidator(0, 100000, this)); 37 | ui->kp18->setValidator(new QIntValidator(0, 100000, this)); 38 | 39 | ui->ki1->setValidator(new QIntValidator(0, 100000, this));//限制数据输入范围 40 | ui->ki2->setValidator(new QIntValidator(0, 100000, this)); 41 | ui->ki3->setValidator(new QIntValidator(0, 100000, this)); 42 | ui->ki4->setValidator(new QIntValidator(0, 100000, this)); 43 | ui->ki5->setValidator(new QIntValidator(0, 100000, this)); 44 | ui->ki6->setValidator(new QIntValidator(0, 100000, this)); 45 | ui->ki7->setValidator(new QIntValidator(0, 100000, this)); 46 | ui->ki8->setValidator(new QIntValidator(0, 100000, this)); 47 | ui->ki9->setValidator(new QIntValidator(0, 100000, this)); 48 | ui->ki10->setValidator(new QIntValidator(0, 100000, this)); 49 | ui->ki11->setValidator(new QIntValidator(0, 100000, this)); 50 | ui->ki12->setValidator(new QIntValidator(0, 100000, this)); 51 | ui->ki13->setValidator(new QIntValidator(0, 100000, this)); 52 | ui->ki14->setValidator(new QIntValidator(0, 100000, this)); 53 | ui->ki15->setValidator(new QIntValidator(0, 100000, this)); 54 | ui->ki16->setValidator(new QIntValidator(0, 100000, this)); 55 | ui->ki17->setValidator(new QIntValidator(0, 100000, this)); 56 | ui->ki18->setValidator(new QIntValidator(0, 100000, this)); 57 | 58 | ui->kd1->setValidator(new QIntValidator(0, 100000, this));//限制数据输入范围 59 | ui->kd2->setValidator(new QIntValidator(0, 100000, this)); 60 | ui->kd3->setValidator(new QIntValidator(0, 100000, this)); 61 | ui->kd4->setValidator(new QIntValidator(0, 100000, this)); 62 | ui->kd5->setValidator(new QIntValidator(0, 100000, this)); 63 | ui->kd6->setValidator(new QIntValidator(0, 100000, this)); 64 | ui->kd7->setValidator(new QIntValidator(0, 100000, this)); 65 | ui->kd8->setValidator(new QIntValidator(0, 100000, this)); 66 | ui->kd9->setValidator(new QIntValidator(0, 100000, this)); 67 | ui->kd10->setValidator(new QIntValidator(0, 100000, this)); 68 | ui->kd11->setValidator(new QIntValidator(0, 100000, this)); 69 | ui->kd12->setValidator(new QIntValidator(0, 100000, this)); 70 | ui->kd13->setValidator(new QIntValidator(0, 100000, this)); 71 | ui->kd14->setValidator(new QIntValidator(0, 100000, this)); 72 | ui->kd15->setValidator(new QIntValidator(0, 100000, this)); 73 | ui->kd16->setValidator(new QIntValidator(0, 100000, this)); 74 | ui->kd17->setValidator(new QIntValidator(0, 100000, this)); 75 | ui->kd18->setValidator(new QIntValidator(0, 100000, this)); 76 | 77 | ui->targeheight->setValidator(new QIntValidator(0, 100000, this)); 78 | ui->safeheight->setValidator(new QIntValidator(0, 100000, this)); 79 | ui->safevbat->setValidator(new QIntValidator(0, 100000, this)); 80 | ui->maxheight->setValidator(new QIntValidator(0, 100000, this)); 81 | ui->maxradius->setValidator(new QIntValidator(0, 100000, this)); 82 | 83 | setparameter = new QTimer(this); 84 | connect(setparameter, SIGNAL(timeout()), this, SLOT(timer_setparameter_show())); 85 | setparameter->start(50);//20HZ 86 | } 87 | 88 | SetParameter::~SetParameter() 89 | { 90 | delete ui; 91 | } 92 | 93 | 94 | //当窗口出发关闭事件后,将信号发射出去 95 | void SetParameter::closeEvent(QCloseEvent *) 96 | { 97 | emit exitwindows(); 98 | } 99 | 100 | void SetParameter::setparameter_show(uint8_t ch) 101 | { 102 | ui->kp1->setText(QString::number(kp[0])); 103 | ui->kp2->setText(QString::number(kp[1])); 104 | ui->kp3->setText(QString::number(kp[2])); 105 | ui->kp4->setText(QString::number(kp[3])); 106 | ui->kp5->setText(QString::number(kp[4])); 107 | ui->kp6->setText(QString::number(kp[5])); 108 | ui->kp7->setText(QString::number(kp[6])); 109 | ui->kp8->setText(QString::number(kp[7])); 110 | ui->kp9->setText(QString::number(kp[8])); 111 | ui->kp10->setText(QString::number(kp[9])); 112 | ui->kp11->setText(QString::number(kp[10])); 113 | ui->kp12->setText(QString::number(kp[11])); 114 | ui->kp13->setText(QString::number(kp[12])); 115 | ui->kp14->setText(QString::number(kp[13])); 116 | ui->kp15->setText(QString::number(kp[14])); 117 | ui->kp16->setText(QString::number(kp[15])); 118 | ui->kp17->setText(QString::number(kp[16])); 119 | ui->kp18->setText(QString::number(kp[17])); 120 | 121 | ui->ki1->setText(QString::number(ki[0])); 122 | ui->ki2->setText(QString::number(ki[1])); 123 | ui->ki3->setText(QString::number(ki[2])); 124 | ui->ki4->setText(QString::number(ki[3])); 125 | ui->ki5->setText(QString::number(ki[4])); 126 | ui->ki6->setText(QString::number(ki[5])); 127 | ui->ki7->setText(QString::number(ki[6])); 128 | ui->ki8->setText(QString::number(ki[7])); 129 | ui->ki9->setText(QString::number(ki[8])); 130 | ui->ki10->setText(QString::number(ki[9])); 131 | ui->ki11->setText(QString::number(ki[10])); 132 | ui->ki12->setText(QString::number(ki[11])); 133 | ui->ki13->setText(QString::number(ki[12])); 134 | ui->ki14->setText(QString::number(ki[13])); 135 | ui->ki15->setText(QString::number(ki[14])); 136 | ui->ki16->setText(QString::number(ki[15])); 137 | ui->ki17->setText(QString::number(ki[16])); 138 | ui->ki18->setText(QString::number(ki[17])); 139 | 140 | ui->kd1->setText(QString::number(kd[0])); 141 | ui->kd2->setText(QString::number(kd[1])); 142 | ui->kd3->setText(QString::number(kd[2])); 143 | ui->kd4->setText(QString::number(kd[3])); 144 | ui->kd5->setText(QString::number(kd[4])); 145 | ui->kd6->setText(QString::number(kd[5])); 146 | ui->kd7->setText(QString::number(kd[6])); 147 | ui->kd8->setText(QString::number(kd[7])); 148 | ui->kd9->setText(QString::number(kd[8])); 149 | ui->kd10->setText(QString::number(kd[9])); 150 | ui->kd11->setText(QString::number(kd[10])); 151 | ui->kd12->setText(QString::number(kd[11])); 152 | ui->kd13->setText(QString::number(kd[12])); 153 | ui->kd14->setText(QString::number(kd[13])); 154 | ui->kd15->setText(QString::number(kd[14])); 155 | ui->kd16->setText(QString::number(kd[15])); 156 | ui->kd17->setText(QString::number(kd[16])); 157 | ui->kd18->setText(QString::number(kd[17])); 158 | 159 | ui->targeheight->setText(QString::number(targeheight)); 160 | ui->safeheight->setText(QString::number(safeheight)); 161 | ui->safevbat->setText(QString::number(safevbat)); 162 | ui->maxheight->setText(QString::number(maxheight)); 163 | ui->maxradius->setText(QString::number(maxradius)); 164 | ui->maxupvel->setText(QString::number(maxupvel)); 165 | ui->maxdownvel->setText(QString::number(maxdownvel)); 166 | ui->maxhorvel->setText(QString::number(maxhorvel)); 167 | 168 | QDateTime current_date_time = QDateTime::currentDateTime(); 169 | QString current_time = current_date_time.toString("hh:mm:ss.zzz"); 170 | if(ch==1) 171 | { 172 | ui->msg->appendPlainText(current_time+"毫秒>>PID1-PID3读取成功"); 173 | } 174 | else if(ch==2) 175 | { 176 | ui->msg->appendPlainText(current_time+"毫秒>>PID4-PID6读取成功"); 177 | } 178 | else if(ch==3) 179 | { 180 | ui->msg->appendPlainText(current_time+"毫秒>>PID7-PID9读取成功"); 181 | } 182 | else if(ch==4) 183 | { 184 | ui->msg->appendPlainText(current_time+"毫秒>>PID10-PID12读取成功"); 185 | } 186 | else if(ch==5) 187 | { 188 | ui->msg->appendPlainText(current_time+"毫秒>>PID13-PID15读取成功"); 189 | } 190 | else if(ch==6) 191 | { 192 | ui->msg->appendPlainText(current_time+"毫秒>>PID16-PID18读取成功"); 193 | } 194 | else if(ch==7) 195 | { 196 | ui->msg->appendPlainText(current_time+"毫秒>>读取其它参数成功"); 197 | } 198 | ui->msg->moveCursor(QTextCursor::End, QTextCursor::MoveAnchor); 199 | } 200 | void SetParameter::timer_setparameter_show() 201 | { 202 | 203 | } 204 | 205 | 206 | void SetParameter::getcheck(uint8_t ch) 207 | { 208 | uint16_t kp[3]={0},ki[3]={0},kd[3]={0}; 209 | QDateTime current_date_time = QDateTime::currentDateTime(); 210 | QString current_time = current_date_time.toString("hh:mm:ss.zzz"); 211 | if(ch==0x0A) 212 | { 213 | ui->msg->appendPlainText(current_time+"毫秒>>飞控返回校验:PID1-PID3写入成功"); 214 | 215 | kp[0]=ui->kp4->text().toUInt(); 216 | ki[0]=ui->ki4->text().toUInt(); 217 | kd[0]=ui->kd4->text().toUInt(); 218 | 219 | kp[1]=ui->kp5->text().toUInt(); 220 | ki[1]=ui->ki5->text().toUInt(); 221 | kd[1]=ui->kd5->text().toUInt(); 222 | 223 | kp[2]=ui->kp6->text().toUInt(); 224 | ki[2]=ui->ki6->text().toUInt(); 225 | kd[2]=ui->kd6->text().toUInt(); 226 | Send_PID(2,kp[0],ki[0],kd[0], 227 | kp[1],ki[1],kd[1], 228 | kp[2],ki[2],kd[2]); 229 | 230 | } 231 | else if(ch==0x0B) 232 | { 233 | ui->msg->appendPlainText(current_time+"毫秒>>飞控返回校验:PID4-PID6写入成功"); 234 | kp[0]=ui->kp7->text().toUInt(); 235 | ki[0]=ui->ki7->text().toUInt(); 236 | kd[0]=ui->kd7->text().toUInt(); 237 | 238 | kp[1]=ui->kp8->text().toUInt(); 239 | ki[1]=ui->ki8->text().toUInt(); 240 | kd[1]=ui->kd8->text().toUInt(); 241 | 242 | kp[2]=ui->kp9->text().toUInt(); 243 | ki[2]=ui->ki9->text().toUInt(); 244 | kd[2]=ui->kd9->text().toUInt(); 245 | Send_PID(3,kp[0],ki[0],kd[0], 246 | kp[1],ki[1],kd[1], 247 | kp[2],ki[2],kd[2]); 248 | } 249 | else if(ch==0x0C) 250 | { 251 | ui->msg->appendPlainText(current_time+"毫秒>>飞控返回校验:PID7-PID9写入成功"); 252 | kp[0]=ui->kp10->text().toUInt(); 253 | ki[0]=ui->ki10->text().toUInt(); 254 | kd[0]=ui->kd10->text().toUInt(); 255 | 256 | kp[1]=ui->kp11->text().toUInt(); 257 | ki[1]=ui->ki11->text().toUInt(); 258 | kd[1]=ui->kd11->text().toUInt(); 259 | 260 | kp[2]=ui->kp12->text().toUInt(); 261 | ki[2]=ui->ki12->text().toUInt(); 262 | kd[2]=ui->kd12->text().toUInt(); 263 | Send_PID(4,kp[0],ki[0],kd[0], 264 | kp[1],ki[1],kd[1], 265 | kp[2],ki[2],kd[2]); 266 | } 267 | else if(ch==0x0D) 268 | { 269 | ui->msg->appendPlainText(current_time+"毫秒>>飞控返回校验:PID10-PID12写入成功"); 270 | kp[0]=ui->kp13->text().toUInt(); 271 | ki[0]=ui->ki13->text().toUInt(); 272 | kd[0]=ui->kd13->text().toUInt(); 273 | 274 | kp[1]=ui->kp14->text().toUInt(); 275 | ki[1]=ui->ki14->text().toUInt(); 276 | kd[1]=ui->kd14->text().toUInt(); 277 | 278 | kp[2]=ui->kp15->text().toUInt(); 279 | ki[2]=ui->ki15->text().toUInt(); 280 | kd[2]=ui->kd15->text().toUInt(); 281 | Send_PID(5,kp[0],ki[0],kd[0], 282 | kp[1],ki[1],kd[1], 283 | kp[2],ki[2],kd[2]); 284 | } 285 | else if(ch==0x0E) 286 | { 287 | ui->msg->appendPlainText(current_time+"毫秒>>飞控返回校验:PID13-PID15写入成功"); 288 | kp[0]=ui->kp16->text().toUInt(); 289 | ki[0]=ui->ki16->text().toUInt(); 290 | kd[0]=ui->kd16->text().toUInt(); 291 | 292 | kp[1]=ui->kp17->text().toUInt(); 293 | ki[1]=ui->ki17->text().toUInt(); 294 | kd[1]=ui->kd17->text().toUInt(); 295 | 296 | kp[2]=ui->kp18->text().toUInt(); 297 | ki[2]=ui->ki18->text().toUInt(); 298 | kd[2]=ui->kd18->text().toUInt(); 299 | Send_PID(6,kp[0],ki[0],kd[0], 300 | kp[1],ki[1],kd[1], 301 | kp[2],ki[2],kd[2]); 302 | } 303 | else if(ch==0x0F) 304 | { 305 | ui->msg->appendPlainText(current_time+"毫秒>>飞控返回校验:PID16-PID18写入成功"); 306 | } 307 | else if(ch==0x10) 308 | { 309 | ui->msg->appendPlainText(current_time+"毫秒>>飞控返回校验:其它参数写入成功"); 310 | } 311 | ui->msg->moveCursor(QTextCursor::End, QTextCursor::MoveAnchor); 312 | } 313 | 314 | extern QSerialPort* serialPort; 315 | 316 | 317 | #define NCLink_Head0 0xFF 318 | #define NCLink_Head1 0xFC 319 | #define NCLink_End0 0xA1 320 | #define NCLink_End1 0xA2 321 | void SetParameter::Send_Cmd_Check(uint8_t cmd,uint8_t data)//地面站指令发送 322 | { 323 | uint8_t data_to_send[50]; 324 | uint8_t sum = 0,i=0,len=0; 325 | len=1; 326 | data_to_send[0]=NCLink_Head1; 327 | data_to_send[1]=NCLink_Head0; 328 | data_to_send[2]=cmd; 329 | data_to_send[3]=len; 330 | data_to_send[4]=data; 331 | for(i=0;i<5;i++) 332 | sum ^= data_to_send[i]; 333 | data_to_send[5]=sum; 334 | data_to_send[6]=NCLink_End0; 335 | data_to_send[7]=NCLink_End1; 336 | if(serialflag) serialPort->write((char *)(data_to_send),8); 337 | else 338 | { 339 | QDateTime current_date_time = QDateTime::currentDateTime(); 340 | QString current_time = current_date_time.toString("hh:mm:ss.zzz"); 341 | ui->msg->appendPlainText(current_time+"毫秒>>读写串口失败,请检查串口配置!!!"); 342 | ui->msg->moveCursor(QTextCursor::End, QTextCursor::MoveAnchor); 343 | } 344 | } 345 | 346 | void SetParameter::Send_PID(uint8_t group,uint16_t kp1,uint16_t ki1,uint16_t kd1, 347 | uint16_t kp2,uint16_t ki2,uint16_t kd2, 348 | uint16_t kp3,uint16_t ki3,uint16_t kd3)//地面站指令发送 349 | { 350 | uint8_t data_to_send[50]; 351 | uint8_t sum = 0,i=0,cnt=0; 352 | uint16_t _temp; 353 | data_to_send[cnt++]=NCLink_Head1; 354 | data_to_send[cnt++]=NCLink_Head0; 355 | data_to_send[cnt++]=0x02+group-1; 356 | data_to_send[cnt++]=0; 357 | 358 | _temp = kp1; 359 | data_to_send[cnt++]=BYTE1(_temp); 360 | data_to_send[cnt++]=BYTE0(_temp); 361 | _temp = ki1; 362 | data_to_send[cnt++]=BYTE1(_temp); 363 | data_to_send[cnt++]=BYTE0(_temp); 364 | _temp = kd1; 365 | data_to_send[cnt++]=BYTE1(_temp); 366 | data_to_send[cnt++]=BYTE0(_temp); 367 | 368 | _temp = kp2; 369 | data_to_send[cnt++]=BYTE1(_temp); 370 | data_to_send[cnt++]=BYTE0(_temp); 371 | _temp = ki2; 372 | data_to_send[cnt++]=BYTE1(_temp); 373 | data_to_send[cnt++]=BYTE0(_temp); 374 | _temp = kd2; 375 | data_to_send[cnt++]=BYTE1(_temp); 376 | data_to_send[cnt++]=BYTE0(_temp); 377 | 378 | _temp = kp3; 379 | data_to_send[cnt++]=BYTE1(_temp); 380 | data_to_send[cnt++]=BYTE0(_temp); 381 | _temp = ki3; 382 | data_to_send[cnt++]=BYTE1(_temp); 383 | data_to_send[cnt++]=BYTE0(_temp); 384 | _temp = kd3; 385 | data_to_send[cnt++]=BYTE1(_temp); 386 | data_to_send[cnt++]=BYTE0(_temp); 387 | 388 | data_to_send[3] = cnt-4; 389 | 390 | for(i=0;iwrite((char *)(data_to_send),cnt); 395 | else 396 | { 397 | QDateTime current_date_time = QDateTime::currentDateTime(); 398 | QString current_time = current_date_time.toString("hh:mm:ss.zzz"); 399 | ui->msg->appendPlainText(current_time+"毫秒>>读写串口失败,请检查串口配置!!!"); 400 | ui->msg->moveCursor(QTextCursor::End, QTextCursor::MoveAnchor); 401 | } 402 | } 403 | 404 | 405 | void SetParameter::Send_Parameter(uint8_t group, 406 | uint16_t targeheight, 407 | uint16_t safeheight, 408 | uint16_t safevbat, 409 | uint16_t maxheight, 410 | uint16_t maxradius, 411 | uint16_t maxupvel, 412 | uint16_t maxdownvel, 413 | uint16_t maxhorvel)//地面站指令发送 414 | { 415 | uint8_t data_to_send[50]; 416 | uint8_t sum = 0,i=0,cnt=0; 417 | uint16_t _temp; 418 | data_to_send[cnt++]=NCLink_Head1; 419 | data_to_send[cnt++]=NCLink_Head0; 420 | data_to_send[cnt++]=0x08+group-1; 421 | data_to_send[cnt++]=0; 422 | 423 | _temp = targeheight; 424 | data_to_send[cnt++]=BYTE1(_temp); 425 | data_to_send[cnt++]=BYTE0(_temp); 426 | 427 | _temp = safeheight; 428 | data_to_send[cnt++]=BYTE1(_temp); 429 | data_to_send[cnt++]=BYTE0(_temp); 430 | 431 | _temp = safevbat; 432 | data_to_send[cnt++]=BYTE1(_temp); 433 | data_to_send[cnt++]=BYTE0(_temp); 434 | 435 | _temp = maxheight; 436 | data_to_send[cnt++]=BYTE1(_temp); 437 | data_to_send[cnt++]=BYTE0(_temp); 438 | 439 | _temp = maxradius; 440 | data_to_send[cnt++]=BYTE1(_temp); 441 | data_to_send[cnt++]=BYTE0(_temp); 442 | 443 | _temp = maxupvel; 444 | data_to_send[cnt++]=BYTE1(_temp); 445 | data_to_send[cnt++]=BYTE0(_temp); 446 | 447 | _temp = maxdownvel; 448 | data_to_send[cnt++]=BYTE1(_temp); 449 | data_to_send[cnt++]=BYTE0(_temp); 450 | 451 | _temp = maxhorvel; 452 | data_to_send[cnt++]=BYTE1(_temp); 453 | data_to_send[cnt++]=BYTE0(_temp); 454 | 455 | data_to_send[3] = cnt-4; 456 | 457 | for(i=0;iwrite((char *)(data_to_send),cnt); 462 | else 463 | { 464 | QDateTime current_date_time = QDateTime::currentDateTime(); 465 | QString current_time = current_date_time.toString("hh:mm:ss.zzz"); 466 | ui->msg->appendPlainText(current_time+"毫秒>>读写串口失败,请检查串口配置!!!"); 467 | ui->msg->moveCursor(QTextCursor::End, QTextCursor::MoveAnchor); 468 | } 469 | } 470 | 471 | 472 | void SetParameter::on_readall_clicked() 473 | { 474 | Send_Cmd_Check(0x01,0x01); 475 | } 476 | 477 | void SetParameter::on_defaultall_clicked() 478 | { 479 | Send_Cmd_Check(0x01,0x02); 480 | } 481 | 482 | void SetParameter::on_writeall_clicked() 483 | { 484 | //QString period=ui->send_period->text(); 485 | //int period_cnt=period.toInt(); 486 | uint16_t kp[3]={0},ki[3]={0},kd[3]={0}; 487 | kp[0]=ui->kp1->text().toUInt(); 488 | ki[0]=ui->ki1->text().toUInt(); 489 | kd[0]=ui->kd1->text().toUInt(); 490 | 491 | kp[1]=ui->kp2->text().toUInt(); 492 | ki[1]=ui->ki2->text().toUInt(); 493 | kd[1]=ui->kd2->text().toUInt(); 494 | 495 | kp[2]=ui->kp3->text().toUInt(); 496 | ki[2]=ui->ki3->text().toUInt(); 497 | kd[2]=ui->kd3->text().toUInt(); 498 | Send_PID(1,kp[0],ki[0],kd[0], 499 | kp[1],ki[1],kd[1], 500 | kp[2],ki[2],kd[2]); 501 | } 502 | 503 | void SetParameter::on_clear_clicked() 504 | { 505 | ui->msg->clear(); 506 | ui->msg->moveCursor(QTextCursor::End, QTextCursor::MoveAnchor); 507 | } 508 | 509 | void SetParameter::on_write_clicked() 510 | { 511 | uint16_t targeheight=0,safeheight=0,safevbat=0,maxheight=0,maxradius=0,maxupvel=0,maxdownvel=0,maxhorvel=0; 512 | targeheight=ui->targeheight->text().toUInt(); 513 | safeheight=ui->safeheight->text().toUInt(); 514 | safevbat=ui->safevbat->text().toUInt(); 515 | maxheight=ui->maxheight->text().toUInt(); 516 | maxradius=ui->maxradius->text().toUInt(); 517 | maxupvel=ui->maxupvel->text().toUInt(); 518 | maxdownvel=ui->maxdownvel->text().toUInt(); 519 | maxhorvel=ui->maxhorvel->text().toUInt(); 520 | 521 | Send_Parameter(1,targeheight,safeheight,safevbat,maxheight,maxradius,maxupvel,maxdownvel,maxhorvel); 522 | 523 | } 524 | 525 | void SetParameter::on_read_clicked() 526 | { 527 | Send_Cmd_Check(0x01,0x03); 528 | } 529 | 530 | void SetParameter::on_factory_clicked() 531 | { 532 | Send_Cmd_Check(0x01,0x04); 533 | } 534 | -------------------------------------------------------------------------------- /NGroundStation/setparameter.h: -------------------------------------------------------------------------------- 1 | #ifndef SETPARAMETER_H 2 | #define SETPARAMETER_H 3 | 4 | #include 5 | 6 | 7 | extern bool serialflag; 8 | 9 | 10 | namespace Ui { 11 | class SetParameter; 12 | } 13 | 14 | class SetParameter : public QWidget 15 | { 16 | Q_OBJECT 17 | 18 | public: 19 | explicit SetParameter(QWidget *parent = nullptr); 20 | ~SetParameter(); 21 | void closeEvent(QCloseEvent *);//重写关闭事件 22 | void Send_Cmd_Check(uint8_t cmd,uint8_t data); 23 | void Send_PID(uint8_t group,uint16_t kp1,uint16_t ki1,uint16_t kd1, 24 | uint16_t kp2,uint16_t ki2,uint16_t kd2, 25 | uint16_t kp3,uint16_t ki3,uint16_t kd3); 26 | void Send_Parameter(uint8_t group, 27 | uint16_t targeheight, 28 | uint16_t safeheight, 29 | uint16_t safevbat, 30 | uint16_t maxheight, 31 | uint16_t maxradius, 32 | uint16_t maxupvel, 33 | uint16_t maxdownvel, 34 | uint16_t maxhorvel); 35 | private: 36 | Ui::SetParameter *ui; 37 | signals: 38 | void exitwindows();//新建一个信号槽 39 | private slots: 40 | void timer_setparameter_show(); 41 | void on_readall_clicked(); 42 | void on_defaultall_clicked(); 43 | void on_writeall_clicked(); 44 | void setparameter_show(uint8_t ch); 45 | void getcheck(uint8_t ch); 46 | void on_clear_clicked(); 47 | void on_write_clicked(); 48 | void on_read_clicked(); 49 | void on_factory_clicked(); 50 | }; 51 | 52 | #endif // SETPARAMETER_H 53 | -------------------------------------------------------------------------------- /NGroundStation/waveshow.h: -------------------------------------------------------------------------------- 1 | #ifndef WAVESHOW_H 2 | #define WAVESHOW_H 3 | 4 | #include 5 | #include "Headfile.h" 6 | 7 | #define MAX_DATA_CH 27 //一屏显示的最大数据点数 8 | #define MAX_DATA_SIZE 100 //一屏显示的最大数据点数 9 | #define MAX_CH_LEN (50000)//40000 20000//20000*5 10 | extern QwtPlotCurve *ch_curve[MAX_DATA_CH]; 11 | extern double ch_time[MAX_DATA_SIZE]; 12 | extern double ch_val[MAX_DATA_CH][MAX_DATA_SIZE]; 13 | extern int ch_val_cnt[MAX_DATA_CH]; 14 | extern int iActDataLen; 15 | extern bool showflag; 16 | typedef struct 17 | { 18 | QVector xdata,ydata; 19 | uint64_t cnt; 20 | bool update_flag; 21 | }qwtdata; 22 | 23 | extern qwtdata qwt_ch_val[MAX_DATA_CH]; 24 | 25 | //extern QVector xdata,ydata; 26 | 27 | namespace Ui { 28 | class waveshow; 29 | } 30 | 31 | class waveshow : public QWidget 32 | { 33 | Q_OBJECT 34 | 35 | public: 36 | explicit waveshow(QWidget *parent = nullptr); 37 | ~waveshow(); 38 | void closeEvent(QCloseEvent *);//重写关闭事件 39 | 40 | Ui::waveshow *ui; 41 | void wave_init(); 42 | void show_redraw(int present); 43 | void receiveMessage(const QString& info); 44 | void progress(int present); 45 | 46 | private slots: 47 | void timerwave(); 48 | void showItemChecked(const QVariant &itemInfo, bool on); 49 | void select_axis_zoomer( QRectF ); 50 | void showwave(); 51 | void readcsvfile(); 52 | // Ui::waveshow *ui; 53 | void on_bt_zoominx_clicked(); 54 | 55 | void on_bt_zoominy_clicked(); 56 | void on_bt_zoomouty_clicked(); 57 | void on_bt_zoomoutx_clicked(); 58 | void on_bt_zoominy_zero_clicked(); 59 | void on_bt_clearshow_clicked(); 60 | void on_bt_startshow_clicked(); 61 | void on_bt_export_clicked(); 62 | 63 | void on_bt_import_clicked(); 64 | 65 | private: 66 | QMutex mutexwave; 67 | 68 | signals: 69 | void exitwindows();//新建一个信号槽 70 | 71 | }; 72 | 73 | #endif // WAVESHOW_H 74 | -------------------------------------------------------------------------------- /NGroundStation/waveshow.ui: -------------------------------------------------------------------------------- 1 | 2 | 3 | waveshow 4 | 5 | 6 | 7 | 0 8 | 0 9 | 888 10 | 805 11 | 12 | 13 | 14 | 15 | 800 16 | 600 17 | 18 | 19 | 20 | Form 21 | 22 | 23 | QWidget 24 | { 25 | background-color: rgb(233,235,254); 26 | border-radius: 20px; 27 | color: rgb(0, 0, 0); 28 | } 29 | 30 | 31 | 32 | 33 | 34 | 35 | 9 36 | 37 | 38 | 39 | QFrame::NoFrame 40 | 41 | 42 | QFrame::Plain 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 0 53 | 0 54 | 55 | 56 | 57 | 58 | 100 59 | 50 60 | 61 | 62 | 63 | 64 | 3ds 65 | 12 66 | 75 67 | true 68 | 69 | 70 | 71 | QPushButton 72 | { 73 | background-color: rgb(233,200,254); 74 | border-radius: 20px; 75 | color: rgb(0, 0, 0); 76 | } 77 | QPushButton:hover 78 | { 79 | background-color: rgb(200,235,254); 80 | } 81 | 82 | 83 | Y放大 84 | 85 | 86 | 87 | :/image/zoomout.png:/image/zoomout.png 88 | 89 | 90 | 91 | 40 92 | 40 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 0 102 | 0 103 | 104 | 105 | 106 | 107 | 100 108 | 50 109 | 110 | 111 | 112 | 113 | 3ds 114 | 12 115 | 75 116 | true 117 | 118 | 119 | 120 | QPushButton 121 | { 122 | background-color: rgb(233,200,254); 123 | border-radius: 20px; 124 | color: rgb(0, 0, 0); 125 | } 126 | QPushButton:hover 127 | { 128 | background-color: rgb(200,235,254); 129 | } 130 | 131 | 132 | X缩小 133 | 134 | 135 | 136 | :/image/zoomin.png:/image/zoomin.png 137 | 138 | 139 | 140 | 40 141 | 40 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 0 151 | 0 152 | 153 | 154 | 155 | 156 | 100 157 | 50 158 | 159 | 160 | 161 | 162 | 3ds 163 | 12 164 | 75 165 | true 166 | 167 | 168 | 169 | QPushButton 170 | { 171 | background-color: rgb(233,200,254); 172 | border-radius: 20px; 173 | color: rgb(0, 0, 0); 174 | } 175 | QPushButton:hover 176 | { 177 | background-color: rgb(200,235,254); 178 | } 179 | 180 | 181 | 清空显示 182 | 183 | 184 | 185 | :/image/sw.png:/image/sw.png 186 | 187 | 188 | 189 | 40 190 | 40 191 | 192 | 193 | 194 | 195 | 196 | 197 | 198 | 199 | 0 200 | 0 201 | 202 | 203 | 204 | 205 | 100 206 | 50 207 | 208 | 209 | 210 | 211 | 3ds 212 | 12 213 | 75 214 | true 215 | 216 | 217 | 218 | QPushButton 219 | { 220 | background-color: rgb(233,200,254); 221 | border-radius: 20px; 222 | color: rgb(0, 0, 0); 223 | } 224 | QPushButton:hover 225 | { 226 | background-color: rgb(200,235,254); 227 | } 228 | 229 | 230 | Y缩小 231 | 232 | 233 | 234 | :/image/zoomin.png:/image/zoomin.png 235 | 236 | 237 | 238 | 40 239 | 40 240 | 241 | 242 | 243 | 244 | 245 | 246 | 247 | 248 | 0 249 | 0 250 | 251 | 252 | 253 | 254 | 100 255 | 50 256 | 257 | 258 | 259 | 260 | 3ds 261 | 12 262 | 75 263 | true 264 | 265 | 266 | 267 | QPushButton 268 | { 269 | background-color: rgb(233,200,254); 270 | border-radius: 20px; 271 | color: rgb(0, 0, 0); 272 | } 273 | QPushButton:hover 274 | { 275 | background-color: rgb(200,235,254); 276 | } 277 | 278 | 279 | X放大 280 | 281 | 282 | 283 | :/image/zoomout.png:/image/zoomout.png 284 | 285 | 286 | 287 | 40 288 | 40 289 | 290 | 291 | 292 | 293 | 294 | 295 | 296 | 297 | 0 298 | 0 299 | 300 | 301 | 302 | 303 | 100 304 | 50 305 | 306 | 307 | 308 | 309 | 3ds 310 | 12 311 | 75 312 | true 313 | 314 | 315 | 316 | QPushButton 317 | { 318 | background-color: rgb(233,200,254); 319 | border-radius: 20px; 320 | color: rgb(0, 0, 0); 321 | } 322 | QPushButton:hover 323 | { 324 | background-color: rgb(200,235,254); 325 | } 326 | 327 | 328 | 停止显示 329 | 330 | 331 | 332 | :/image/show.png:/image/show.png 333 | 334 | 335 | 336 | 40 337 | 40 338 | 339 | 340 | 341 | 342 | 343 | 344 | 345 | 346 | 0 347 | 0 348 | 349 | 350 | 351 | 352 | 100 353 | 50 354 | 355 | 356 | 357 | 358 | 3ds 359 | 12 360 | 75 361 | true 362 | 363 | 364 | 365 | QPushButton 366 | { 367 | background-color: rgb(233,200,254); 368 | border-radius: 20px; 369 | color: rgb(0, 0, 0); 370 | } 371 | QPushButton:hover 372 | { 373 | background-color: rgb(200,235,254); 374 | } 375 | 376 | 377 | Y归零 378 | 379 | 380 | 381 | :/image/tozero.png:/image/tozero.png 382 | 383 | 384 | 385 | 40 386 | 40 387 | 388 | 389 | 390 | 391 | 392 | 393 | 394 | 395 | 0 396 | 0 397 | 398 | 399 | 400 | 401 | 100 402 | 50 403 | 404 | 405 | 406 | 407 | 3ds 408 | 12 409 | 75 410 | true 411 | 412 | 413 | 414 | QPushButton 415 | { 416 | background-color: rgb(233,200,254); 417 | border-radius: 20px; 418 | color: rgb(0, 0, 0); 419 | } 420 | QPushButton:hover 421 | { 422 | background-color: rgb(200,235,254); 423 | } 424 | 425 | 426 | 数据导出 427 | 428 | 429 | 430 | :/image/export.png:/image/export.png 431 | 432 | 433 | 434 | 40 435 | 40 436 | 437 | 438 | 439 | 440 | 441 | 442 | 443 | 444 | 0 445 | 0 446 | 447 | 448 | 449 | 450 | 100 451 | 50 452 | 453 | 454 | 455 | 456 | 3ds 457 | 12 458 | 75 459 | true 460 | 461 | 462 | 463 | QPushButton 464 | { 465 | background-color: rgb(233,200,254); 466 | border-radius: 20px; 467 | color: rgb(0, 0, 0); 468 | } 469 | QPushButton:hover 470 | { 471 | background-color: rgb(200,235,254); 472 | } 473 | 474 | 475 | 数据导入 476 | 477 | 478 | 479 | :/image/import.png:/image/import.png 480 | 481 | 482 | 483 | 40 484 | 40 485 | 486 | 487 | 488 | 489 | 490 | 491 | 492 | 493 | 0 494 | 0 495 | 496 | 497 | 498 | 499 | 0 500 | 0 501 | 502 | 503 | 504 | 505 | 16777215 506 | 50 507 | 508 | 509 | 510 | 511 | 512 | 513 | 514 | 515 | 516 | 517 | QwtPlot 518 | QFrame 519 |
qwt_plot.h
520 | 1 521 |
522 |
523 | 524 | 525 | 526 | 527 |
528 | -------------------------------------------------------------------------------- /images/1586249791769.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wustyuyi/NGroundStation/ddcdffde18b8c035d6bbe78ea84d704106d2d6d6/images/1586249791769.png -------------------------------------------------------------------------------- /images/NGS.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wustyuyi/NGroundStation/ddcdffde18b8c035d6bbe78ea84d704106d2d6d6/images/NGS.png -------------------------------------------------------------------------------- /images/basic_window.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wustyuyi/NGroundStation/ddcdffde18b8c035d6bbe78ea84d704106d2d6d6/images/basic_window.png -------------------------------------------------------------------------------- /images/cal_window.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wustyuyi/NGroundStation/ddcdffde18b8c035d6bbe78ea84d704106d2d6d6/images/cal_window.png -------------------------------------------------------------------------------- /images/learn-1586145845974.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wustyuyi/NGroundStation/ddcdffde18b8c035d6bbe78ea84d704106d2d6d6/images/learn-1586145845974.png -------------------------------------------------------------------------------- /images/learn.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wustyuyi/NGroundStation/ddcdffde18b8c035d6bbe78ea84d704106d2d6d6/images/learn.png -------------------------------------------------------------------------------- /images/main_window.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wustyuyi/NGroundStation/ddcdffde18b8c035d6bbe78ea84d704106d2d6d6/images/main_window.png -------------------------------------------------------------------------------- /images/noserial.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wustyuyi/NGroundStation/ddcdffde18b8c035d6bbe78ea84d704106d2d6d6/images/noserial.png -------------------------------------------------------------------------------- /images/open_serial-1586076513816.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wustyuyi/NGroundStation/ddcdffde18b8c035d6bbe78ea84d704106d2d6d6/images/open_serial-1586076513816.png -------------------------------------------------------------------------------- /images/open_serial.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wustyuyi/NGroundStation/ddcdffde18b8c035d6bbe78ea84d704106d2d6d6/images/open_serial.png -------------------------------------------------------------------------------- /images/para_window.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wustyuyi/NGroundStation/ddcdffde18b8c035d6bbe78ea84d704106d2d6d6/images/para_window.png -------------------------------------------------------------------------------- /images/pressed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wustyuyi/NGroundStation/ddcdffde18b8c035d6bbe78ea84d704106d2d6d6/images/pressed.png -------------------------------------------------------------------------------- /images/public.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wustyuyi/NGroundStation/ddcdffde18b8c035d6bbe78ea84d704106d2d6d6/images/public.png -------------------------------------------------------------------------------- /images/remote_window.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wustyuyi/NGroundStation/ddcdffde18b8c035d6bbe78ea84d704106d2d6d6/images/remote_window.png -------------------------------------------------------------------------------- /images/serialsetup.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wustyuyi/NGroundStation/ddcdffde18b8c035d6bbe78ea84d704106d2d6d6/images/serialsetup.png -------------------------------------------------------------------------------- /images/state_window.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wustyuyi/NGroundStation/ddcdffde18b8c035d6bbe78ea84d704106d2d6d6/images/state_window.png -------------------------------------------------------------------------------- /images/wave_import.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wustyuyi/NGroundStation/ddcdffde18b8c035d6bbe78ea84d704106d2d6d6/images/wave_import.png -------------------------------------------------------------------------------- /images/wave_window.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wustyuyi/NGroundStation/ddcdffde18b8c035d6bbe78ea84d704106d2d6d6/images/wave_window.png -------------------------------------------------------------------------------- /readme.md: -------------------------------------------------------------------------------- 1 | # 无名创新飞控开源地面站——NGroundStation 2 | 3 | ## 一、地面站开源初衷与下载链接: 4 | 5 | ​ 无名创新飞控开源飞控地面站是无名小哥为广大自研飞控开发者、电子发烧友们专门开发的一款多功能上位机软件,地面站功能涵盖:飞控状态显示、数据波形、参数调试、虚拟遥控器、飞控传感器校准串口助手常用等,开发此款地面站的初衷是方便大家高效学习与调试。 6 | 7 | ​ 初学者在学习无人机飞控相关算法选择地面站时,个人小众开发者设计的地面站,在功能和性能上各有优缺点,无法兼容常用功能,而针对APM/PX4的开源地面站MP与QGC功能复杂,很多冗余的功能用不上,开发者需要自行移植并裁剪Mavlink协议来适配自己的飞控,导致开发者往往为选择一款合适的地面站而发愁,为兼容不同家地面站需要花一定功夫。 8 | 9 | ​ 考虑到目前国内没有一家开源飞控地面站软件代码开源出来给大家学习,为了做到初学者也能简单高效的开发出满足自己需要的地面站软件,无名小哥选择采用QT开发平台,基于C++图形用户界面开发了此地面站软件,整个工程代码框架清晰,每个功能模块单独封装,注释详尽,使得有一定编程经验的初学者能对整个地面站软件运行逻辑一目了然,并能基于我们开源的地面站软件进行二次开发,后续会上线更多功能,地面站软件持续更新,欢迎大家公测,只要您是为了整个开源生态的建设,批评指正,拍砖打脸没关系。下面来依次介绍本地面站功能。 10 | 11 | ##### 无名地面站下载:http://www.nameless.tech/download.html 12 | 13 | ##### 开源地面站NGroundStation使用教程:https://www.bilibili.com/video/BV1JE411c7vU?from=search&seid=4801164549946953127 14 | 15 | ##### 无名创新开源地面站交流QQ群:465082224、540707961 16 | 17 | ##### 无名地面站开源代码下载链接在文末 18 | 19 | ## 二、开源地面站的使用 20 | 21 | ### 2.1、主界面介绍与串口配置 22 | 23 | ​ 无名创新地面站发布采用免安装的方式,用户在官方下载地面站后,直接解压后点击NGroundStation.exe运行即可,同路径文件夹下后缀为.dll依赖库文件不得随意删除,否则点击运行时,会报缺少xxx.dll文件。 24 | 25 | ![NGS](images/NGS.png) 26 | 27 | ​ 用户打开地面站后进入如下主界面,导航栏有无名创新团队介绍与软件使用帮助,主界面有各个功能模块。首先第一步先点击配置串口: 28 | 29 | ![main_window](images/main_window.png) 30 | 31 | ​ 点击后软件会自动搜索当前电脑可用的串口设备(USB转TTL设备、USB虚拟串口VCP、RS232/485等),若系统上没有可用设备时,软件会提示界面如下,此时请检查您的电脑有相关串口外设设备或者查看设备管理器是否有对应外设驱动。 32 | 33 | ![noserial](images/noserial.png) 34 | 35 | ​ 软件会自动搜索当前可用串口设备,搜索出的串口号为对应外设的设备号,当存在多个串口设备时,需要自行勾选需要连接的串口。常用波特率可以通过波特率设置行下拉选择,同时若需要调试其它非常规设备,也支持手动输入任意波特率,手动输入时输入完毕后请点击电脑回车键进行输入确认,不点击回车键直接退出为无效输入。设置好串口设备后,退出设置界面。在主界面点击打开串口后地面站解析数据即开始工作。 36 | 37 | ![serialsetup](images/serialsetup.png) 38 | 39 | ![open_serial](images/open_serial-1586076513816.png) 40 | 41 | ​ 飞控状态、数据波形、参数调试、虚拟遥控、飞控校准功能都是建立在地面站正常解析飞控数据的前提下,故当上述功能界面不能正常使用时,请回头检查串口配置和串口是否已经打开/占用。 42 | 43 | ### 2.2、飞控状态显示 44 | 45 | ​ 飞控状态显示界面分飞控基本状态、罗盘与速度、航姿仪表、IMU数据、遥控器数据、观测传感器数据、姿态角度曲线等模块。用户可以通过地面站实时可视化观察无人机的常用状态。用户可以根据状态提示来了解无人机的各个参数。 46 | 47 | ![state_window](images/state_window.png) 48 | 49 | ### 2.3、数据波形显示 50 | 51 | ​ 数据波形显示界面可以动态观察无人机关键状态的数据波形曲线,如分析各个传感器数据、姿态数据、惯导数据、控制指令等数据,在自己研究对比飞控算法性能、滤波器参数整定、突发故障异常分析过程中非常实用。无名创新地面站预留了6组用户数据通道可以供客户自行发送数据。数据波形支持导入\导出,文件名为电脑系统时间精确到S,导出的csv格式数据可以很方便的用数值处理软件如Matlab、Origin等做后续数据处理分析。 52 | 53 | ![wave_window](images/wave_window.png) 54 | 55 | ![wave_import](images/wave_import.png) 56 | 57 | ### 2.4、参数调试 58 | 59 | ​ 自研飞控开发者在学习过程中需要对结合不同的动力装对飞控PID参数进行调整,来确保无人机拥有稳定的飞行性能,关键参数为姿态内环—角速度环参数,主要工作是对角速度环PID参数进行整定,主PD,辅积分参数I。参数调试界面后,各个参数框中均为0,先点击读取参数,地面站会发送获取参数指令给飞控,地面站获取到飞控发上来的参数后会刷新UI界面显示当前飞控内部参数,需要调整参数时,手动在对应参数框中输入设定参数,点击写入参数后,飞控即保存参数于FLASH/EEPROM中,下次上电飞控会自动从FLASH/EEPROM中读取参数值。同理对飞控其它参数的设置过程也一样,先读取,更改后点击写入。当用户想要恢复默认初始参数时,点击恢复默认参数即可。用户在设置参数写入、恢复过程中,飞控会返回操作是否成功的应答给地面站显示写入状态。 60 | 61 | ![para_window](images/para_window.png) 62 | 63 | ### 2.5、虚拟遥控 64 | 65 | ​ 虚拟遥控器界面模拟了8通道双回中式遥控器数据,默认以左手油门的形式发送1-8通道数据,本功能可以在在无遥控器操作下,解锁上锁电机、测试无人机电调行程,若要在实际飞行中运用该功能,需要保障所有数传模块在当前实用条件下通讯可靠。地面站在发送数据的同时,接收了飞控解析数据正常的回传数据,并计算通讯的成功率,地面站每20ms发送一次遥控器数据,飞控端在20ms内返回应答一次算一次通讯正常,若飞控端回传应答频率小于50HZ,实际又可能造成通讯没有异常,但地面站获取的成功率小于100%的情况。同时设计了飞行指令控制功能,即通过指令控制无人机空间的位移方向与距离。 66 | 67 | ![remote_window](images/remote_window.png) 68 | 69 | ### 2.6、飞控校准 70 | 71 | ​ 入手飞控第一步就是传感器校准,打开飞控校准界面,有四种和传感器相关的校准操作,其中陀螺仪校准和机架水平校准不需要人为操作飞行器,保持无人机静置与水平面,点击校准按键即自动进行。飞行器对陀螺仪的校准是每次飞控上电工作均会自动进行一次,即飞控IMU温度升温到50℃后,若此时飞行器保持静止,陀螺仪会自动校准偏移,地面站也加入了人为校准陀螺仪偏移,点击开始校准陀螺仪后,飞控会自动再次校准陀螺仪零偏。 72 | 73 | ​ 飞控加速度校准采用和APM/PX4一致的6面校准法,首先点击加速度校准进入,随后点击对应面按钮,每一面会提示如何放置飞行器。6面数据都采集完毕后,飞控会计算校准参数并发送到地面站。 74 | 75 | ​ 磁力计校准采用椭球拟合的方式,实际需要采集3个面内36角点数据,飞控自带显示屏会提示每一面如何放置并旋转,显示屏上有显示每个角点数据采集状态,三个面所有角点采集完毕后,会计算校准参数并发送到地面站。 76 | 77 | ​ 机架水平校准主要目的是针对飞控安装在机架上与水平面之间的夹角误差,因此需要结合水平仪来进行操作,实用中将飞控安装在机架上后,首先校准加速度计,然后将水平仪放置在机架所在平面,调整机架脚架使得水平仪气泡居中,再进行机架水平校准操作。 78 | 79 | ​ 其它按键获取校准参数、退出当前校准等不赘述,上述所有校准中,除磁力计骄傲,其它均需要温控系统稳定工作后,因此最好等温度达到50°并且稳定后,再开始进行陀螺仪、加速度、机架水平的校准操作。无名飞控对飞控校准均保留遥控器直接校准的方式,因此用户可以结合实际场景,灵活确定,遥控器校准传感器视频教程如下。 80 | 81 | ##### **1、加速度校准教程:https://www.bilibili.com/video/BV1it411k7CJ?from=search&seid=255111440291059640* 82 | 83 | ##### *2、磁力计校准:https://www.bilibili.com/video/BV1it411k7CC?from=search&seid=15429067159432134560* 84 | 85 | ##### *3、机架水平校准:https://www.bilibili.com/video/BV1L4411E7j2?from=search&seid=14438186151189674967* 86 | 87 | ![cal_window](images/cal_window.png) 88 | 89 | ### 2.7、基本收发 90 | 91 | ​ 地面站保留了普通串口调试助手的功能,这一项是和上述功能区分开的,可以作为普通串口调试助手实用,数据以文本/16进制收发,定时自动发送、多项指令发送等。 92 | 93 | ![basic_window](images/basic_window.png) 94 | 95 | # 三、地面站软件代码开源 96 | 97 | ## 3.1 QT开发环境 98 | 99 | 链接:https://pan.baidu.com/s/1R__jn921zaPGsYB2VQV3mQ 提取码:hgo7 100 | 101 | ## 3.2 第三方支持包,自行网上搜索教程安装 102 | 103 | ### QWT6.1.3:https://qwt.sourceforge.io/ 104 | 105 | 链接:https://pan.baidu.com/s/1W2UUki_e73pQ7X-7qgs5Fw 提取码:x1aj 106 | 107 | ### QUC自定义控件:http://www.qtcontrol.cn/ 108 | 109 | 链接:https://pan.baidu.com/s/1s9gpVaawuqrKXAXMFsIvWQ 提取码:dyxq 110 | 111 | ## 3.3 无名创新地面站源码下载 112 | 113 | #### Github下载链接:https://github.com/wustyuyi/NGroundStation 114 | 115 | #### 欢迎mark加star,小伙伴们赶快加入我们吧!!! 116 | 117 | #### 感谢您的支持,地面站开发教程与更多功能敬请期待!!! 118 | 119 | #### 为广大开发者提供地面站二次开发交流平台,微信扫描加入知识星球: 120 | 121 | ![learn](images/learn-1586145845974.png) 122 | 123 | 124 | 125 | ## 3.4 二次开发者TIP搜集: 126 | 127 | 1、在QT开发环境,安装以上两个支持包后,编译地面站源码时会出现以下提示 128 | 129 | ![pressed](images/pressed.png) 130 | 131 | ​ 原因是地面站虚拟遥控器界面代码调用了customrocker.h类的私有成员变量,解决办法:把customrocker.h里面bool pressed变量从private改到public下就行。 132 | 133 | ![public](images/public.png) -------------------------------------------------------------------------------- /无名创新地面站.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wustyuyi/NGroundStation/ddcdffde18b8c035d6bbe78ea84d704106d2d6d6/无名创新地面站.zip --------------------------------------------------------------------------------