|
@ -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(); |
|
|
|
|
|
// 打印分析报告
|
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
{ |
|
|
{ |
|
|