Browse Source

update

master
zhaohe 1 year ago
parent
commit
2e33dcb1d3
  1. 3
      .gitmodules
  2. 7
      CMakeLists.txt
  3. 13
      README.md
  4. 1
      a8k_optalgo
  5. 4
      libzqt/zui/zqui.hpp
  6. 10
      src/basic/widgetplot2d.cpp
  7. 16
      src/basic/zcsv.cpp
  8. 5
      src/basic/zcsv.hpp
  9. 2
      src/mainwindow.cpp
  10. 228
      src/tab/a8k_opt_tab.cpp
  11. 12
      src/ui/dialog.cpp
  12. 24
      src/ui/dialog.h
  13. 78
      src/ui/dialog.ui

3
.gitmodules

@ -1,3 +1,6 @@
[submodule "a8000_protocol"] [submodule "a8000_protocol"]
path = a8000_protocol path = a8000_protocol
url = zwsd@192.168.1.3:project_boditech_vidas_a8000_v3/a8000_protocol.git url = zwsd@192.168.1.3:project_boditech_vidas_a8000_v3/a8000_protocol.git
[submodule "a8k_optalgo"]
path = a8k_optalgo
url = zwsd@192.168.1.3:project_boditech_vidas_a8000_v3/a8k_optalgo.git

7
CMakeLists.txt

@ -75,8 +75,15 @@ set(PROJECT_SOURCES
src/basic/a8k_id_card_writer.cpp src/basic/a8k_id_card_writer.cpp
src/tab/a8k_opt_tab.cpp src/tab/a8k_opt_tab.cpp
a8k_optalgo/a8k_opt_algo.cpp
app.rc app.rc
src/ui/dialog.ui
src/ui/dialog.cpp
) )

13
README.md

@ -224,9 +224,6 @@ ID地址:
@ -245,4 +242,14 @@ T光学
lasterGain 100 lasterGain 100
scanGain 20 scanGain 20
F光学
lasterGain 0 (数值越大,功率越小)
scanGain 0
第一次扫描,0,0
实验材料:
Fx3-23 -> F光学,位置80,120,160
``` ```

1
a8k_optalgo

@ -0,0 +1 @@
Subproject commit f1e84f5f99f42f6e810a77611cf197826a430271

4
libzqt/zui/zqui.hpp

@ -66,4 +66,6 @@ class ZQUI : public QObject {
void doinui_signal(QFunction); void doinui_signal(QFunction);
}; };
extern void DoInUi(std::function<void()> dowhat);
extern void DoInUi(std::function<void()> dowhat);
#define ISHOW(fmt, ...) ZQUI::ins()->ishow(fmt, ##__VA_ARGS__)

10
src/basic/widgetplot2d.cpp

@ -1,9 +1,9 @@
#include "widgetplot2d.h" #include "widgetplot2d.h"
#include <QDebug>
#include <QStandardPaths>
#include <QColorDialog> #include <QColorDialog>
#include <QDebug>
#include <QFileDialog> #include <QFileDialog>
#include <QStandardPaths>
#include <QToolTip> #include <QToolTip>
#include "ui_widgetplot2d.h" #include "ui_widgetplot2d.h"
@ -406,10 +406,10 @@ void WidgetPlot2D::savePlotPng() {
ZCSV csv; ZCSV csv;
int datacnt = ui->customPlot->graph(0)->dataCount(); int datacnt = ui->customPlot->graph(0)->dataCount();
csv.setdata(1, 1, "pointIndex"); csv.setdata(1, 1, "pointIndex");
csv.setdata(1, 2, "value");
csv.setdata(2, 1, "value");
for (size_t i = 0; i < datacnt; i++) { for (size_t i = 0; i < datacnt; i++) {
csv.setdata(i + 1, 1, QString::number(ui->customPlot->graph(0)->data()->at(i)->key).toStdString());
csv.setdata(i + 1, 2, QString::number(ui->customPlot->graph(0)->data()->at(i)->value).toStdString());
csv.setdata(1, i + 1, QString::number(ui->customPlot->graph(0)->data()->at(i)->key).toStdString());
csv.setdata(2, i + 1, QString::number(ui->customPlot->graph(0)->data()->at(i)->value).toStdString());
} }
csv.dumpCSV(fileName.toStdString()); csv.dumpCSV(fileName.toStdString());
} }

16
src/basic/zcsv.cpp

@ -1,5 +1,8 @@
#include "zcsv.hpp" #include "zcsv.hpp"
#include <stdarg.h>
using namespace std; using namespace std;
using namespace iflytop; using namespace iflytop;
@ -63,7 +66,7 @@ ZCSVCell* ZCSV::findCell(int rowNum, int colNum) {
return NULL; return NULL;
} }
void ZCSV::setdata(int rowNum, int colNum, string data) {
void ZCSV::setdata(int colNum, int rowNum, string data) {
ZCSVCell* cell = findCell(rowNum, colNum); ZCSVCell* cell = findCell(rowNum, colNum);
if (cell != NULL) { if (cell != NULL) {
cell->data = data; cell->data = data;
@ -84,7 +87,16 @@ void ZCSV::setdata(int rowNum, int colNum, string data) {
csvData.push_back(newCell); csvData.push_back(newCell);
} }
} }
string ZCSV::getdata(int rowNum, int colNum) {
void ZCSV::setdata(int colNum, int rowNum, const char* fmt, ...) {
char buffer[1024];
va_list args;
va_start(args, fmt);
vsnprintf(buffer, 1024, fmt, args);
va_end(args);
setdata(colNum, rowNum, string(buffer));
}
string ZCSV::getdata(int colNum, int rowNum) {
ZCSVCell* cell = findCell(rowNum, colNum); ZCSVCell* cell = findCell(rowNum, colNum);
if (cell != NULL) { if (cell != NULL) {
return cell->data; return cell->data;

5
src/basic/zcsv.hpp

@ -32,8 +32,9 @@ class ZCSV {
bool parseCSV(string filename); bool parseCSV(string filename);
void setdata(int rowNum, int colNum, string data);
string getdata(int rowNum, int colNum);
void setdata(int colNum, int rowNum, string data);
void setdata(int colNum, int rowNum, const char* fmt, ...);
string getdata(int colNum, int rowNum);
int maxRowNum() { return m_maxRowNum; } int maxRowNum() { return m_maxRowNum; }
int maxColNum() { return m_maxColNum; } int maxColNum() { return m_maxColNum; }

2
src/mainwindow.cpp

@ -185,7 +185,7 @@ void MainWindow::parse_ptv2_cmd(zcr_cmd_header_t *frame, int32_t packetlen) {
} else { } else {
// //
if (cmdId == kpipette_write_cmd_direct || cmdId == ka8000_idcard_write_raw) { if (cmdId == kpipette_write_cmd_direct || cmdId == ka8000_idcard_write_raw) {
ZQUI::ins()->rawshow("[CMD ] %d mid:%d cmdid:%s(0x%04x) param:%s", frame->packetindex, cmdid2str(cmdId), cmdId, mid, //
ZQUI::ins()->rawshow("[CMD ] %d mid:%d cmdid:%s(0x%04x) param:%s", frame->packetindex, mid, cmdid2str(cmdId), cmdId, //
zhex2str(frame->data, packetlen - sizeof(zcr_cmd_header_t)).c_str()); zhex2str(frame->data, packetlen - sizeof(zcr_cmd_header_t)).c_str());
} else { } else {
int32_t paramNum = (packetlen - sizeof(zcr_cmd_header_t)) / 4; int32_t paramNum = (packetlen - sizeof(zcr_cmd_header_t)) / 4;

228
src/tab/a8k_opt_tab.cpp

@ -12,12 +12,16 @@
#include "../basic/format_memory.hpp" #include "../basic/format_memory.hpp"
#include "../basic/stm32_pin.hpp" #include "../basic/stm32_pin.hpp"
#include "../ui/dialog.h"
#include "./mainwindow.h" #include "./mainwindow.h"
#include "a8k_optalgo\a8k_opt_algo.hpp"
#include "basic\widgetplot2d.h" #include "basic\widgetplot2d.h"
#include "zcsv.hpp"
#include "zui\zqui.hpp" #include "zui\zqui.hpp"
// //
using namespace iflytop; using namespace iflytop;
using namespace std; using namespace std;
using namespace a8k_opt_algo;
extern Ui::MainWindow *main_ui; extern Ui::MainWindow *main_ui;
@ -31,6 +35,63 @@ typedef struct {
int dataNum; int dataNum;
} opt_result_t; } opt_result_t;
typedef enum {
kfopt = 1,
ktopt = 2,
} opt_type_t;
static const char *optType2Str(opt_type_t type) {
switch (type) {
case kfopt:
return "F光学";
case ktopt:
return "T光学";
default:
return "未知";
}
}
static vector<float> array2vector(opt_result_t result) {
vector<float> ret;
ret.reserve(result.dataNum);
for (int i = 0; i < result.dataNum; i++) {
ret.push_back(result.data[i]);
}
return ret;
}
opt_result_t m_optData;
opt_type_t m_optType;
int32_t m_scanGain;
int32_t m_laserGain;
void dumpRawData() {
ZQUI::ins()->ishow("---------------------opt result(%d)---------------------", m_optData.dataNum);
ISHOW("laster gain:%d", m_laserGain);
ISHOW("scan gain:%d", m_scanGain);
ISHOW("opt Type:%s", optType2Str(m_optType));
for (size_t i = 0; i < m_optData.dataNum; i++) {
ZQUI::ins()->ishow("%5d,%d", i, m_optData.data[i]);
}
DoInUi([]() {
WidgetPlot2D *plot2d = new WidgetPlot2D();
QStringList lines;
lines.push_back("line1");
plot2d->initGraphName(lines);
for (int i = 0; i < m_optData.dataNum; i++) {
plot2d->addData("line1", m_optData.data[i]);
}
// 250 个点的情况下,峰的标准位置在 40 80 120 160 200
// 1200个点的情况下,峰的标准位置在 40*4.8 80*4.8 120*4.8 160*4.8 200*4.8
for (int i = 1; i < 6; i++) {
plot2d->addRefLine(4.8 * 40 * i);
}
plot2d->show();
});
}
A8kOptTab *A8kOptTab::inst() { A8kOptTab *A8kOptTab::inst() {
static A8kOptTab *ins = new A8kOptTab(); static A8kOptTab *ins = new A8kOptTab();
return ins; return ins;
@ -41,6 +102,29 @@ void A8kOptTab::construct(QTabWidget *fathertab) {
* * * *
***********************************************************************************************************************/ ***********************************************************************************************************************/
ZQVTabPage *tab = new ZQVTabPage(fathertab, "光学模组"); ZQVTabPage *tab = new ZQVTabPage(fathertab, "光学模组");
{
ZQFunctionListBox *box = new ZQFunctionListBox(tab, "说明文档", 4);
box->newSubButton("说明", [this](int argn, const char **args) { //
DoInUi([this]() {
Dialog *dialog = new Dialog();
dialog->show();
dialog->setHelpInfo(
"" //
"扫描位置:\n"
"推杆电机: 52\n"
" F光学扫描位置:kreg_a8k_opt_f_pos_offset\n"
" kreg_a8k_opt_f_reverse_scan_pos_offset\n"
" T光学扫描位置:kreg_a8k_opt_t_pos_offset\n"
" kreg_a8k_opt_t_reverse_scan_pos_offset\n"
"详细说明参考:\n"
" https://iflytop1.feishu.cn/wiki/LbfHwPFmki3G1uk9p0KcA9lvnSd?fromScene=spaceOverview \n"
"");
});
});
// ModuleNameText->setObjectName(QString::fromUtf8("ModuleNameText"));
}
{ {
ZQFunctionListBox *box = new ZQFunctionListBox(tab, "光学测试", 4); ZQFunctionListBox *box = new ZQFunctionListBox(tab, "光学测试", 4);
@ -63,7 +147,7 @@ void A8kOptTab::construct(QTabWidget *fathertab) {
ICM->callcmd1(PUSH_AND_PULL_MOTOR, kstep_motor_easy_move_to, 1100); ICM->callcmd1(PUSH_AND_PULL_MOTOR, kstep_motor_easy_move_to, 1100);
}); });
box->newSubButtonEnd(); box->newSubButtonEnd();
box->newSubButton("丢板", [this](int argn, const char **args) { ICM->callcmd1(CAMERA_MOTOR, kstep_motor_easy_move_to, 0); });
box->newSubButton("丢板", [this](int argn, const char **args) { ICM->callcmd1(CAMERA_MOTOR, kstep_motor_easy_move_to, -350); });
box->newSubButtonEnd(); box->newSubButtonEnd();
box->newFunc("T光学-开始扫描", {"scanDirection", "lasterGain", "scanGain"}, [this](int argn, const char **args) { box->newFunc("T光学-开始扫描", {"scanDirection", "lasterGain", "scanGain"}, [this](int argn, const char **args) {
@ -71,6 +155,9 @@ void A8kOptTab::construct(QTabWidget *fathertab) {
int32_t lasterGain = atoi(args[1]); int32_t lasterGain = atoi(args[1]);
int32_t scanGain = atoi(args[2]); int32_t scanGain = atoi(args[2]);
ICM->callcmd3(getDeviceId(), ka8k_opt_v2_t_start_scan, scanDirection, lasterGain, scanGain); ICM->callcmd3(getDeviceId(), ka8k_opt_v2_t_start_scan, scanDirection, lasterGain, scanGain);
m_optType = ktopt;
m_scanGain = scanGain;
m_laserGain = lasterGain;
}); });
box->newFunc("F光学-开始扫描", {"scanDirection", "lasterGain", "scanGain"}, [this](int argn, const char **args) { box->newFunc("F光学-开始扫描", {"scanDirection", "lasterGain", "scanGain"}, [this](int argn, const char **args) {
@ -78,11 +165,13 @@ void A8kOptTab::construct(QTabWidget *fathertab) {
int32_t lasterGain = atoi(args[1]); int32_t lasterGain = atoi(args[1]);
int32_t scanGain = atoi(args[2]); int32_t scanGain = atoi(args[2]);
ICM->callcmd3(getDeviceId(), ka8k_opt_v2_f_start_scan, scanDirection, lasterGain, scanGain); ICM->callcmd3(getDeviceId(), ka8k_opt_v2_f_start_scan, scanDirection, lasterGain, scanGain);
m_optType = kfopt;
m_scanGain = scanGain;
m_laserGain = lasterGain;
}); });
box->newSubButton("读取扫描结果", [this](int argn, const char **args) { box->newSubButton("读取扫描结果", [this](int argn, const char **args) {
// ka8000_optical_read_raw // ka8000_optical_read_raw
uint8_t rdbuf[5000]; uint8_t rdbuf[5000];
int32_t readsize = 0; int32_t readsize = 0;
int i = 0; int i = 0;
@ -95,39 +184,132 @@ void A8kOptTab::construct(QTabWidget *fathertab) {
readsize += ICM->getAckBufLen(); readsize += ICM->getAckBufLen();
i++; i++;
} }
int16_t *data = (int16_t *)rdbuf; int16_t *data = (int16_t *)rdbuf;
ZQUI::ins()->ishow("---------------------opt result(%d)---------------------", readsize / 2);
memcpy(m_optData.data, data, readsize);
m_optData.dataNum = readsize / 2;
for (size_t i = 0; i < readsize / 2; i++) {
ZQUI::ins()->ishow("%5d,%d", i, data[i]);
}
dumpRawData();
});
opt_result_t optdata;
memcpy(optdata.data, data, readsize);
optdata.dataNum = readsize / 2;
box->newSubButton("保存数据", [this](int argn, const char **args) {
DoInUi([this]() {
QString savePath = QStandardPaths::writableLocation(QStandardPaths::DesktopLocation);
QString fileName = QFileDialog::getSaveFileName(nullptr,
"保存波形数据", // 对话框的标题
savePath, // 保存的默认路径为程序运行路径
"Save Picture (*.csv)"); // 打开文件的类型,;隔开
if (fileName.isNull()) return;
ZCSV csv;
int datacnt = m_optData.dataNum;
csv.setdata(1, 1, "Index");
csv.setdata(2, 1, "Data");
csv.setdata(3, 1, "OptType(1:f,2:t)");
csv.setdata(4, 1, "ScanGain(0...255)");
csv.setdata(5, 1, "LasterGain(0...255)");
for (int i = 0; i < datacnt; i++) {
csv.setdata(1, i + 2, QString::number(i + 1).toStdString()); // 第一列数据
csv.setdata(2, i + 2, QString::number(m_optData.data[i]).toStdString()); // 第二列数据
}
DoInUi([this, optdata]() {
WidgetPlot2D *plot2d = new WidgetPlot2D();
QStringList lines;
lines.push_back("line1");
plot2d->initGraphName(lines);
csv.setdata(3, 2, "%d", m_optType);
csv.setdata(4, 2, "%d", m_scanGain);
csv.setdata(5, 2, "%d", m_laserGain);
for (int i = 0; i < optdata.dataNum; i++) {
plot2d->addData("line1", optdata.data[i]);
csv.dumpCSV(fileName.toStdString());
ISHOW("保存成功");
});
});
box->newSubButton("载入数据", [this](int argn, const char **args) {
DoInUi([]() {
QString filePath = QFileDialog::getOpenFileName(nullptr, "Select a file");
if (!filePath.isEmpty()) {
QFile file(filePath);
if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
ZQUI::ins()->ishow("open file fail");
return;
}
} }
// 250 个点的情况下,峰的标准位置在 40 80 120 160 200
// 1200个点的情况下,峰的标准位置在 40*4.8 80*4.8 120*4.8 160*4.8 200*4.8
for (int i = 1; i < 6; i++) {
plot2d->addRefLine(4.8 * 40 * i);
ZCSV csv;
csv.parseCSV(filePath.toStdString());
int datacnt = csv.maxRowNum() - 1;
m_optData.dataNum = datacnt;
for (int i = 0; i < datacnt; i++) {
m_optData.data[i] = atoi(csv.getdata(2, i + 2).c_str());
} }
plot2d->show();
m_optType = (opt_type_t)atoi(csv.getdata(3, 2).c_str());
m_scanGain = atoi(csv.getdata(4, 2).c_str());
m_laserGain = atoi(csv.getdata(5, 2).c_str());
dumpRawData();
}); });
});
}
{
//
ZQFunctionListBox *box = new ZQFunctionListBox(tab, "结果处理", 4);
// 预分析结果
box->newSubButton("光学结果预分析", [this](int argn, const char **args) {
int32_t lasterGain = atoi(args[0]);
int32_t scanGain = atoi(args[1]);
ICM->callcmd2(getDeviceId(), ka8k_opt_v2_t_open_laster, lasterGain, scanGain);
if (m_optData.dataNum == 0) {
ZQUI::ins()->ishow("请先进行光学分析,并读取扫描结果");
return;
}
ISHOW("------ OptRawResultInfo ------");
ISHOW("laster gain:%d", lasterGain);
ISHOW("scan gain:%d", scanGain);
ISHOW("opt Type:%s", optType2Str(m_optType));
// 1. 预分析
OptAlgoPreProcessResult result;
if (m_optType == kfopt) {
F_A8kOptAlgoPreProcess(array2vector(m_optData), scanGain, 2600, 2800, result);
} else if (m_optType == ktopt) {
T_A8kOptAlgoPreProcess(array2vector(m_optData), scanGain, 2600, 2800, result);
}
ISHOW("------ OptPreParseResult ------");
ISHOW("scanAgain :%s", result.scanAgain ? "true" : "false");
ISHOW("suggestScanGain:%d", result.suggestScanGain);
});
box->newSubButtonEnd();
// 分析结果
// 打印读取到的结果
box->newSubButton("光学结果分析", [this](int argn, const char **args) {
int32_t lasterGain = atoi(args[0]);
int32_t scanGain = atoi(args[1]);
ICM->callcmd2(getDeviceId(), ka8k_opt_v2_t_open_laster, lasterGain, scanGain);
if (m_optData.dataNum == 0) {
ZQUI::ins()->ishow("请先进行光学分析,并读取扫描结果");
return;
}
ISHOW("------ OptRawResultInfo ------");
ISHOW("laster gain:%d", lasterGain);
ISHOW("scan gain:%d", scanGain);
ISHOW("opt Type:%s", optType2Str(m_optType));
// 1. 预分析
OptAlgoPreProcessResult result;
if (m_optType == kfopt) {
F_A8kOptAlgoPreProcess(array2vector(m_optData), scanGain, 2600, 2800, result);
} else if (m_optType == ktopt) {
T_A8kOptAlgoPreProcess(array2vector(m_optData), scanGain, 2600, 2800, result);
}
ISHOW("------ OptPreParseResult ------");
ISHOW("scanAgain :%s", result.scanAgain ? "true" : "false");
ISHOW("suggestScanGain:%d", result.suggestScanGain);
}); });
box->newSubButtonEnd();
// 打印分析报告
} }
{ {

12
src/ui/dialog.cpp

@ -0,0 +1,12 @@
#include "dialog.h"
#include "ui_dialog.h"
Dialog::Dialog(QWidget *parent) : QDialog(parent), ui(new Ui::Dialog) { ui->setupUi(this); }
Dialog::~Dialog() { delete ui; }
void Dialog::setHelpInfo(QString info) {
ui->helpInfo->setText(info);
}

24
src/ui/dialog.h

@ -0,0 +1,24 @@
#ifndef DIALOG_H
#define DIALOG_H
#include <QDialog>
namespace Ui {
class Dialog;
}
class Dialog : public QDialog
{
Q_OBJECT
public:
explicit Dialog(QWidget *parent = nullptr);
~Dialog();
void setHelpInfo(QString info);
private:
Ui::Dialog *ui;
};
#endif // DIALOG_H

78
src/ui/dialog.ui

@ -0,0 +1,78 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>Dialog</class>
<widget class="QDialog" name="Dialog">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>640</width>
<height>480</height>
</rect>
</property>
<property name="windowTitle">
<string>Dialog</string>
</property>
<widget class="QDialogButtonBox" name="buttonBox">
<property name="geometry">
<rect>
<x>10</x>
<y>440</y>
<width>621</width>
<height>32</height>
</rect>
</property>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="standardButtons">
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
</property>
</widget>
<widget class="QTextBrowser" name="helpInfo">
<property name="geometry">
<rect>
<x>30</x>
<y>40</y>
<width>571</width>
<height>371</height>
</rect>
</property>
</widget>
</widget>
<resources/>
<connections>
<connection>
<sender>buttonBox</sender>
<signal>accepted()</signal>
<receiver>Dialog</receiver>
<slot>accept()</slot>
<hints>
<hint type="sourcelabel">
<x>248</x>
<y>254</y>
</hint>
<hint type="destinationlabel">
<x>157</x>
<y>274</y>
</hint>
</hints>
</connection>
<connection>
<sender>buttonBox</sender>
<signal>rejected()</signal>
<receiver>Dialog</receiver>
<slot>reject()</slot>
<hints>
<hint type="sourcelabel">
<x>316</x>
<y>260</y>
</hint>
<hint type="destinationlabel">
<x>286</x>
<y>274</y>
</hint>
</hints>
</connection>
</connections>
</ui>
Loading…
Cancel
Save