add,计划采集20,上海农科院3D植物表型:
1、新增任务类型AutoFocus:执行自动调焦过程;
This commit is contained in:
@ -682,6 +682,9 @@ void HPPA::initTimedDataCollection()
|
|||||||
connect(m_omc_LiftingPlatform, &OneMotorControl_LiftingPlatform::sequenceComplete, m_tdc, &TimedDataCollection::subTaskCompleted);
|
connect(m_omc_LiftingPlatform, &OneMotorControl_LiftingPlatform::sequenceComplete, m_tdc, &TimedDataCollection::subTaskCompleted);
|
||||||
connect(m_omc_LiftingPlatform, &OneMotorControl_LiftingPlatform::back2OriginSignal_TimedDataCollection, m_tdc, &TimedDataCollection::onBack2Origin);
|
connect(m_omc_LiftingPlatform, &OneMotorControl_LiftingPlatform::back2OriginSignal_TimedDataCollection, m_tdc, &TimedDataCollection::onBack2Origin);
|
||||||
|
|
||||||
|
//自动调焦
|
||||||
|
connect(m_tdc, &TimedDataCollection::AutoFocusSignals, this, &HPPA::onAutoFocus_TimedDataCollection);
|
||||||
|
|
||||||
m_tdc->show();
|
m_tdc->show();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -790,6 +793,13 @@ void HPPA::onLiftingPlatform(SubTask subTaskParams)
|
|||||||
m_omc_LiftingPlatform->run();
|
m_omc_LiftingPlatform->run();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void HPPA::onAutoFocus_TimedDataCollection(SubTask subTaskParams)
|
||||||
|
{
|
||||||
|
m_tmc->setImager(m_Imager);
|
||||||
|
//先使用subTaskParams.autoFocusMotorConfigFilePath替换文件oneMotorConfigFile_focus.cfg
|
||||||
|
m_tmc->run5_AutoFocus(subTaskParams.autoFocusX, subTaskParams.autoFocusY);
|
||||||
|
}
|
||||||
|
|
||||||
void HPPA::onTimedDataCollection()
|
void HPPA::onTimedDataCollection()
|
||||||
{
|
{
|
||||||
QAction* checkedScenario = m_ScenarioActionGroup->checkedAction();
|
QAction* checkedScenario = m_ScenarioActionGroup->checkedAction();
|
||||||
|
|||||||
@ -452,6 +452,7 @@ public Q_SLOTS:
|
|||||||
void onStartTimedDataCollection(int camType);
|
void onStartTimedDataCollection(int camType);
|
||||||
void onObtainTargetDepthInformation(SubTask subTaskParams);
|
void onObtainTargetDepthInformation(SubTask subTaskParams);
|
||||||
void onLiftingPlatform(SubTask subTaskParams);
|
void onLiftingPlatform(SubTask subTaskParams);
|
||||||
|
void onAutoFocus_TimedDataCollection(SubTask subTaskParams);
|
||||||
|
|
||||||
void onStretchedImageReady(int fileNumber, const QString& filePath, QPixmap& pixmap);
|
void onStretchedImageReady(int fileNumber, const QString& filePath, QPixmap& pixmap);
|
||||||
void onStretchProcessingError(int fileNumber, const QString& filePath, const QString& error);
|
void onStretchProcessingError(int fileNumber, const QString& filePath, const QString& error);
|
||||||
|
|||||||
@ -131,70 +131,70 @@ QVariant TaskTreeModel::data(const QModelIndex& index, int role) const
|
|||||||
if (node->nodeType == TreeNodeType::Task && node->taskData) {
|
if (node->nodeType == TreeNodeType::Task && node->taskData) {
|
||||||
const TimedTask& task = *node->taskData;
|
const TimedTask& task = *node->taskData;
|
||||||
switch (index.column()) {
|
switch (index.column()) {
|
||||||
case ColName:
|
case ColName:
|
||||||
return QString::fromLocal8Bit("定时任务 %1").arg(task.id);
|
return QString::fromLocal8Bit("定时任务 %1").arg(task.id);
|
||||||
case ColScheduledTime:
|
case ColScheduledTime:
|
||||||
return task.scheduledTime.toString("yyyy-MM-dd HH:mm:ss");
|
return task.scheduledTime.toString("yyyy-MM-dd HH:mm:ss");
|
||||||
case ColCountdown: {
|
case ColCountdown: {
|
||||||
if (task.status == TaskStatus::Finished || task.status == TaskStatus::Running)
|
if (task.status == TaskStatus::Finished || task.status == TaskStatus::Running)
|
||||||
{
|
{
|
||||||
return QString::fromLocal8Bit("0");
|
return QString::fromLocal8Bit("0");
|
||||||
|
}
|
||||||
|
qint64 seconds = QDateTime::currentDateTime().secsTo(task.scheduledTime);
|
||||||
|
if (seconds < 0)
|
||||||
|
{
|
||||||
|
return QString::fromLocal8Bit("已超时");
|
||||||
|
}
|
||||||
|
return formatCountdown(seconds);
|
||||||
}
|
}
|
||||||
qint64 seconds = QDateTime::currentDateTime().secsTo(task.scheduledTime);
|
case ColStartTime:
|
||||||
if (seconds < 0)
|
return task.startTime.isValid() ?
|
||||||
{
|
task.startTime.toString("HH:mm:ss") : "-";
|
||||||
return QString::fromLocal8Bit("已超时");
|
case ColEndTime:
|
||||||
|
return task.endTime.isValid() ?
|
||||||
|
task.endTime.toString("HH:mm:ss") : "-";
|
||||||
|
case ColDuration:
|
||||||
|
return formatDuration(task.durationMinutes);
|
||||||
|
case ColEstimatedDuration:
|
||||||
|
return formatDuration(task.estimatedDurationMinutes);
|
||||||
|
case ColStatus:
|
||||||
|
return statusToString(task.status);
|
||||||
|
case ColProgress: {
|
||||||
|
int finished = 0;
|
||||||
|
for (const auto& sub : task.subTasks) {
|
||||||
|
if (sub.status == TaskStatus::Finished) finished++;
|
||||||
|
}
|
||||||
|
return QString("%1/%2").arg(finished).arg(task.subTasks.size());
|
||||||
}
|
}
|
||||||
return formatCountdown(seconds);
|
case ColPath:
|
||||||
}
|
return task.savePath;
|
||||||
case ColStartTime:
|
|
||||||
return task.startTime.isValid() ?
|
|
||||||
task.startTime.toString("HH:mm:ss") : "-";
|
|
||||||
case ColEndTime:
|
|
||||||
return task.endTime.isValid() ?
|
|
||||||
task.endTime.toString("HH:mm:ss") : "-";
|
|
||||||
case ColDuration:
|
|
||||||
return formatDuration(task.durationMinutes);
|
|
||||||
case ColEstimatedDuration:
|
|
||||||
return formatDuration(task.estimatedDurationMinutes);
|
|
||||||
case ColStatus:
|
|
||||||
return statusToString(task.status);
|
|
||||||
case ColProgress: {
|
|
||||||
int finished = 0;
|
|
||||||
for (const auto& sub : task.subTasks) {
|
|
||||||
if (sub.status == TaskStatus::Finished) finished++;
|
|
||||||
}
|
|
||||||
return QString("%1/%2").arg(finished).arg(task.subTasks.size());
|
|
||||||
}
|
|
||||||
case ColPath:
|
|
||||||
return task.savePath;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (node->nodeType == TreeNodeType::SubTask && node->subTaskData) {
|
else if (node->nodeType == TreeNodeType::SubTask && node->subTaskData) {
|
||||||
const SubTask& subTask = *node->subTaskData;
|
const SubTask& subTask = *node->subTaskData;
|
||||||
switch (index.column()) {
|
switch (index.column()) {
|
||||||
case ColName:
|
case ColName:
|
||||||
return subTaskTypeToString(subTask.type);
|
return subTaskTypeToString(subTask.type);
|
||||||
case ColScheduledTime:
|
case ColScheduledTime:
|
||||||
return "-";
|
return "-";
|
||||||
case ColCountdown:
|
case ColCountdown:
|
||||||
return "-";
|
return "-";
|
||||||
case ColStartTime:
|
case ColStartTime:
|
||||||
return subTask.startTime.isValid() ?
|
return subTask.startTime.isValid() ?
|
||||||
subTask.startTime.toString("HH:mm:ss") : "-";
|
subTask.startTime.toString("HH:mm:ss") : "-";
|
||||||
case ColEndTime:
|
case ColEndTime:
|
||||||
return subTask.endTime.isValid() ?
|
return subTask.endTime.isValid() ?
|
||||||
subTask.endTime.toString("HH:mm:ss") : "-";
|
subTask.endTime.toString("HH:mm:ss") : "-";
|
||||||
case ColDuration:
|
case ColDuration:
|
||||||
return formatDuration(subTask.durationMinutes);
|
return formatDuration(subTask.durationMinutes);
|
||||||
case ColEstimatedDuration:
|
case ColEstimatedDuration:
|
||||||
return formatDuration(subTask.estimatedDurationMinutes);
|
return formatDuration(subTask.estimatedDurationMinutes);
|
||||||
case ColStatus:
|
case ColStatus:
|
||||||
return statusToString(subTask.status);
|
return statusToString(subTask.status);
|
||||||
case ColProgress:
|
case ColProgress:
|
||||||
return "-";
|
return "-";
|
||||||
case ColPath:
|
case ColPath:
|
||||||
return "-";
|
return "-";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -114,6 +114,7 @@ void TimedDataCollection::setupConnections()
|
|||||||
|
|
||||||
connect(m_scheduler, &TaskScheduler::ObtainingDepthInformationSignals, this, &TimedDataCollection::ObtainingDepthInformationSignals);
|
connect(m_scheduler, &TaskScheduler::ObtainingDepthInformationSignals, this, &TimedDataCollection::ObtainingDepthInformationSignals);
|
||||||
connect(m_scheduler, &TaskScheduler::LiftingPlatformSignals, this, &TimedDataCollection::LiftingPlatformSignals);
|
connect(m_scheduler, &TaskScheduler::LiftingPlatformSignals, this, &TimedDataCollection::LiftingPlatformSignals);
|
||||||
|
connect(m_scheduler, &TaskScheduler::AutoFocusSignals, this, &TimedDataCollection::AutoFocusSignals);
|
||||||
|
|
||||||
connect(m_scheduler, &TaskScheduler::switchHalogenLampSignal,
|
connect(m_scheduler, &TaskScheduler::switchHalogenLampSignal,
|
||||||
this, &TimedDataCollection::switchHalogenLampSignal);
|
this, &TimedDataCollection::switchHalogenLampSignal);
|
||||||
@ -419,6 +420,7 @@ void TimedDataCollection::readTimedTaskFromFile(const QString& filePath)
|
|||||||
double totalEstimatedMinutes = 0.0;
|
double totalEstimatedMinutes = 0.0;
|
||||||
for (int j = 0; j < loadedTasks[i].subTasks.size(); ++j)
|
for (int j = 0; j < loadedTasks[i].subTasks.size(); ++j)
|
||||||
{
|
{
|
||||||
|
loadedTasks[i].subTasks[j].durationMinutes = 0.0; // 初始化实际耗时为0
|
||||||
QString pathLineFilePath = loadedTasks[i].subTasks[j].pathLineFilePath;
|
QString pathLineFilePath = loadedTasks[i].subTasks[j].pathLineFilePath;
|
||||||
if (!pathLineFilePath.isEmpty())
|
if (!pathLineFilePath.isEmpty())
|
||||||
{
|
{
|
||||||
@ -429,6 +431,7 @@ void TimedDataCollection::readTimedTaskFromFile(const QString& filePath)
|
|||||||
}
|
}
|
||||||
double slrTimeMinute = 135 / 60;
|
double slrTimeMinute = 135 / 60;
|
||||||
loadedTasks[i].estimatedDurationMinutes = totalEstimatedMinutes + loadedTasks[i].HalogenLampPreheatingTime_Minute + slrTimeMinute;
|
loadedTasks[i].estimatedDurationMinutes = totalEstimatedMinutes + loadedTasks[i].HalogenLampPreheatingTime_Minute + slrTimeMinute;
|
||||||
|
loadedTasks[i].durationMinutes = 0.0; // 初始化实际耗时为0
|
||||||
}
|
}
|
||||||
|
|
||||||
m_taskModel->setTasks(loadedTasks);
|
m_taskModel->setTasks(loadedTasks);
|
||||||
|
|||||||
@ -54,6 +54,7 @@ Q_SIGNALS:
|
|||||||
|
|
||||||
void ObtainingDepthInformationSignals(SubTask info);
|
void ObtainingDepthInformationSignals(SubTask info);
|
||||||
void LiftingPlatformSignals(SubTask info);
|
void LiftingPlatformSignals(SubTask info);
|
||||||
|
void AutoFocusSignals(SubTask info);
|
||||||
|
|
||||||
void switchHalogenLampSignal(int state);
|
void switchHalogenLampSignal(int state);
|
||||||
void switchD65LampSignal(int state);
|
void switchD65LampSignal(int state);
|
||||||
|
|||||||
@ -121,6 +121,23 @@ SubTaskType TimedDataCollectionDataStructuresReaderWriter::stringToSubTaskType(c
|
|||||||
return SubTaskType::SingleLensReflex;
|
return SubTaskType::SingleLensReflex;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QString TimedDataCollectionDataStructuresReaderWriter::hyperImagerTypeToString(HyperImagerType type)
|
||||||
|
{
|
||||||
|
switch (type) {
|
||||||
|
case HyperImagerType::Pika_L: return "Pika_L";
|
||||||
|
case HyperImagerType::Pika_NIR: return "Pika_NIR";
|
||||||
|
default: return "Unknown";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
HyperImagerType TimedDataCollectionDataStructuresReaderWriter::stringToHyperImagerType(const QString& str)
|
||||||
|
{
|
||||||
|
if (str == "Pika_L") return HyperImagerType::Pika_L;
|
||||||
|
if (str == "Pika_NIR") return HyperImagerType::Pika_NIR;
|
||||||
|
|
||||||
|
return HyperImagerType::Pika_L;
|
||||||
|
}
|
||||||
|
|
||||||
// ==================== SubTask序列化 ====================
|
// ==================== SubTask序列化 ====================
|
||||||
|
|
||||||
QJsonObject TimedDataCollectionDataStructuresReaderWriter::subTaskToJson(const SubTask& subTask)
|
QJsonObject TimedDataCollectionDataStructuresReaderWriter::subTaskToJson(const SubTask& subTask)
|
||||||
@ -138,6 +155,7 @@ QJsonObject TimedDataCollectionDataStructuresReaderWriter::subTaskToJson(const S
|
|||||||
obj["defaultRenderBand"] = subTask.defaultRenderBand;
|
obj["defaultRenderBand"] = subTask.defaultRenderBand;
|
||||||
obj["captureIntervalSeconds"] = subTask.captureIntervalSeconds;
|
obj["captureIntervalSeconds"] = subTask.captureIntervalSeconds;
|
||||||
|
|
||||||
|
obj["autoFocusHyperImagerType"] = hyperImagerTypeToString(subTask.autoFocusHyperImagerType);
|
||||||
obj["autoFocusMotorConfigFilePath"] = subTask.autoFocusMotorConfigFilePath;
|
obj["autoFocusMotorConfigFilePath"] = subTask.autoFocusMotorConfigFilePath;
|
||||||
obj["autoFocusX"] = subTask.autoFocusX;
|
obj["autoFocusX"] = subTask.autoFocusX;
|
||||||
obj["autoFocusY"] = subTask.autoFocusY;
|
obj["autoFocusY"] = subTask.autoFocusY;
|
||||||
@ -164,6 +182,7 @@ bool TimedDataCollectionDataStructuresReaderWriter::jsonToSubTask(const QJsonObj
|
|||||||
subTask.defaultRenderBand = json["defaultRenderBand"].toInt();
|
subTask.defaultRenderBand = json["defaultRenderBand"].toInt();
|
||||||
subTask.captureIntervalSeconds = json["captureIntervalSeconds"].toDouble();
|
subTask.captureIntervalSeconds = json["captureIntervalSeconds"].toDouble();
|
||||||
|
|
||||||
|
subTask.autoFocusHyperImagerType = stringToHyperImagerType(json["autoFocusHyperImagerType"].toString());
|
||||||
subTask.autoFocusMotorConfigFilePath = json["autoFocusMotorConfigFilePath"].toString();
|
subTask.autoFocusMotorConfigFilePath = json["autoFocusMotorConfigFilePath"].toString();
|
||||||
subTask.autoFocusX = json["autoFocusX"].toDouble();
|
subTask.autoFocusX = json["autoFocusX"].toDouble();
|
||||||
subTask.autoFocusY = json["autoFocusY"].toDouble();
|
subTask.autoFocusY = json["autoFocusY"].toDouble();
|
||||||
@ -466,84 +485,102 @@ void TaskExecutor::executeNextSubTask()
|
|||||||
|
|
||||||
switch (subTask.type)
|
switch (subTask.type)
|
||||||
{
|
{
|
||||||
case SubTaskType::ObtainingDepthInformation:
|
case SubTaskType::ObtainingDepthInformation:
|
||||||
{
|
{
|
||||||
//(1)移动到指定位置并通过深度相机获取深度信息(2)调整升降板高度(白板+调焦板)(3)回到零位(0,0)
|
//(1)移动到指定位置并通过深度相机获取深度信息(2)调整升降板高度(白板+调焦板)(3)回到零位(0,0)
|
||||||
emit switchD65LampSignal(1);
|
emit switchD65LampSignal(1);
|
||||||
emit ObtainingDepthInformationSignals(subTask);
|
emit ObtainingDepthInformationSignals(subTask);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case SubTaskType::AutoFocus:
|
case SubTaskType::AutoFocus:
|
||||||
{
|
{
|
||||||
//先判断高光谱相机类型,然后发送相机参数hyperCamParm连接相机
|
switch (subTask.autoFocusHyperImagerType)
|
||||||
|
{
|
||||||
|
case HyperImagerType::Pika_L:
|
||||||
|
m_camType = 0;
|
||||||
|
m_currentFolder = makeSubTaskDataFolder("L");
|
||||||
|
emit hyperCamParm(m_camType, subTask.frameRate, subTask.exposureTime, m_currentFolder, "L");
|
||||||
|
|
||||||
//执行自动调焦任务
|
break;
|
||||||
break;
|
case HyperImagerType::Pika_NIR:
|
||||||
}
|
m_camType = 1;
|
||||||
case SubTaskType::LiftingPlatform:
|
m_currentFolder = makeSubTaskDataFolder("NIR");
|
||||||
{
|
emit hyperCamParm(m_camType, subTask.frameRate, subTask.exposureTime, m_currentFolder, "NIR");
|
||||||
//执行升降平台任务
|
|
||||||
emit LiftingPlatformSignals(subTask);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case SubTaskType::HyperSpectual400_1000nm:
|
|
||||||
{
|
|
||||||
m_camType = 0;
|
|
||||||
m_currentFolder = makeSubTaskDataFolder("L");
|
|
||||||
emit hyperCamParm(m_camType, subTask.frameRate, subTask.exposureTime, m_currentFolder, "L");
|
|
||||||
|
|
||||||
emit motorParm(subTask.pathLineFilePath);
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
emit switchHalogenLampSignal(1);
|
||||||
|
|
||||||
// 打开卤素灯预热
|
//执行自动调焦任务
|
||||||
emit switchHalogenLampSignal(1);
|
QTimer::singleShot(3 * 1000, this, &TaskExecutor::emitAutoFocusSignal);
|
||||||
printMsgAndTime("open HalogenLamp");
|
break;
|
||||||
double sleepTimeSecond = m_task.HalogenLampPreheatingTime_Minute * 60;
|
}
|
||||||
QTimer::singleShot(sleepTimeSecond * 1000, this, &TaskExecutor::emitRecordSignal);
|
case SubTaskType::LiftingPlatform:
|
||||||
|
{
|
||||||
|
//执行升降平台任务
|
||||||
|
emit LiftingPlatformSignals(subTask);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case SubTaskType::HyperSpectual400_1000nm:
|
||||||
|
{
|
||||||
|
m_camType = 0;
|
||||||
|
m_currentFolder = makeSubTaskDataFolder("L");
|
||||||
|
emit hyperCamParm(m_camType, subTask.frameRate, subTask.exposureTime, m_currentFolder, "L");
|
||||||
|
|
||||||
break;
|
emit motorParm(subTask.pathLineFilePath);
|
||||||
}
|
|
||||||
case SubTaskType::HyperSpectual1000_1700nm:
|
|
||||||
{
|
|
||||||
m_camType = 1;
|
|
||||||
m_currentFolder = makeSubTaskDataFolder("NIR");
|
|
||||||
emit hyperCamParm(m_camType, subTask.frameRate, subTask.exposureTime, m_currentFolder, "NIR");
|
|
||||||
|
|
||||||
emit motorParm(subTask.pathLineFilePath);
|
// 打开卤素灯预热
|
||||||
|
emit switchHalogenLampSignal(1);
|
||||||
|
printMsgAndTime("open HalogenLamp");
|
||||||
|
double sleepTimeSecond = m_task.HalogenLampPreheatingTime_Minute * 60;
|
||||||
|
QTimer::singleShot(sleepTimeSecond * 1000, this, &TaskExecutor::emitRecordSignal);
|
||||||
|
|
||||||
QTimer::singleShot(3 * 1000, this, &TaskExecutor::emitRecordSignal);
|
break;
|
||||||
|
}
|
||||||
|
case SubTaskType::HyperSpectual1000_1700nm:
|
||||||
|
{
|
||||||
|
m_camType = 1;
|
||||||
|
m_currentFolder = makeSubTaskDataFolder("NIR");
|
||||||
|
emit hyperCamParm(m_camType, subTask.frameRate, subTask.exposureTime, m_currentFolder, "NIR");
|
||||||
|
|
||||||
break;
|
emit motorParm(subTask.pathLineFilePath);
|
||||||
}
|
|
||||||
case SubTaskType::SingleLensReflex:
|
|
||||||
{
|
|
||||||
m_camType = 2;
|
|
||||||
m_currentFolder = makeSubTaskDataFolder("SLR");
|
|
||||||
emit camParm(m_camType, 3, m_currentFolder);
|
|
||||||
|
|
||||||
emit motorParm(subTask.pathLineFilePath);
|
QTimer::singleShot(3 * 1000, this, &TaskExecutor::emitRecordSignal);
|
||||||
|
|
||||||
emit switchD65LampSignal(1);
|
break;
|
||||||
|
}
|
||||||
|
case SubTaskType::SingleLensReflex:
|
||||||
|
{
|
||||||
|
m_camType = 2;
|
||||||
|
m_currentFolder = makeSubTaskDataFolder("SLR");
|
||||||
|
emit camParm(m_camType, 3, m_currentFolder);
|
||||||
|
|
||||||
emit switchSlrSignal(1);
|
emit motorParm(subTask.pathLineFilePath);
|
||||||
|
|
||||||
QTimer::singleShot(3 * 1000, this, &TaskExecutor::emitRecordSignal);
|
emit switchD65LampSignal(1);
|
||||||
|
|
||||||
break;
|
emit switchSlrSignal(1);
|
||||||
}
|
|
||||||
case SubTaskType::DepthCamera:
|
|
||||||
{
|
|
||||||
m_camType = 3;
|
|
||||||
m_currentFolder = makeSubTaskDataFolder("DepthCamera");
|
|
||||||
emit camParm(m_camType, 3, m_currentFolder);
|
|
||||||
|
|
||||||
emit motorParm(subTask.pathLineFilePath);
|
QTimer::singleShot(3 * 1000, this, &TaskExecutor::emitRecordSignal);
|
||||||
|
|
||||||
emit switchD65LampSignal(1);
|
break;
|
||||||
|
}
|
||||||
|
case SubTaskType::DepthCamera:
|
||||||
|
{
|
||||||
|
m_camType = 3;
|
||||||
|
m_currentFolder = makeSubTaskDataFolder("DepthCamera");
|
||||||
|
emit camParm(m_camType, 3, m_currentFolder);
|
||||||
|
|
||||||
QTimer::singleShot(3 * 1000, this, &TaskExecutor::emitRecordSignal);
|
emit motorParm(subTask.pathLineFilePath);
|
||||||
|
|
||||||
break;
|
emit switchD65LampSignal(1);
|
||||||
}
|
|
||||||
|
QTimer::singleShot(3 * 1000, this, &TaskExecutor::emitRecordSignal);
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
ensurePreTaskLighting();
|
ensurePreTaskLighting();
|
||||||
}
|
}
|
||||||
@ -553,6 +590,12 @@ void TaskExecutor::emitRecordSignal()
|
|||||||
emit startRecordSignal(m_camType);
|
emit startRecordSignal(m_camType);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void TaskExecutor::emitAutoFocusSignal()
|
||||||
|
{
|
||||||
|
SubTask& subTask = m_task.subTasks[m_currentSubTaskIndex];
|
||||||
|
emit AutoFocusSignals(subTask);
|
||||||
|
}
|
||||||
|
|
||||||
// ==================== TaskScheduler 实现 ====================
|
// ==================== TaskScheduler 实现 ====================
|
||||||
|
|
||||||
TaskScheduler::TaskScheduler(QObject* parent)
|
TaskScheduler::TaskScheduler(QObject* parent)
|
||||||
@ -729,6 +772,7 @@ void TaskScheduler::executeTask(TimedTask& task)
|
|||||||
|
|
||||||
connect(m_currentExecutor, &TaskExecutor::ObtainingDepthInformationSignals, this, &TaskScheduler::ObtainingDepthInformationSignals);
|
connect(m_currentExecutor, &TaskExecutor::ObtainingDepthInformationSignals, this, &TaskScheduler::ObtainingDepthInformationSignals);
|
||||||
connect(m_currentExecutor, &TaskExecutor::LiftingPlatformSignals, this, &TaskScheduler::LiftingPlatformSignals);
|
connect(m_currentExecutor, &TaskExecutor::LiftingPlatformSignals, this, &TaskScheduler::LiftingPlatformSignals);
|
||||||
|
connect(m_currentExecutor, &TaskExecutor::AutoFocusSignals, this, &TaskScheduler::AutoFocusSignals);
|
||||||
|
|
||||||
connect(m_currentExecutor, &TaskExecutor::switchHalogenLampSignal, this, &TaskScheduler::switchHalogenLampSignal);
|
connect(m_currentExecutor, &TaskExecutor::switchHalogenLampSignal, this, &TaskScheduler::switchHalogenLampSignal);
|
||||||
connect(m_currentExecutor, &TaskExecutor::switchD65LampSignal, this, &TaskScheduler::switchD65LampSignal);
|
connect(m_currentExecutor, &TaskExecutor::switchD65LampSignal, this, &TaskScheduler::switchD65LampSignal);
|
||||||
|
|||||||
@ -30,6 +30,10 @@ enum class SubTaskType {
|
|||||||
AutoFocus, // 自动对焦
|
AutoFocus, // 自动对焦
|
||||||
LiftingPlatform // 升降平台
|
LiftingPlatform // 升降平台
|
||||||
};
|
};
|
||||||
|
enum class HyperImagerType {
|
||||||
|
Pika_L,
|
||||||
|
Pika_NIR
|
||||||
|
};
|
||||||
|
|
||||||
// ==================== 统一子任务封装 ====================
|
// ==================== 统一子任务封装 ====================
|
||||||
|
|
||||||
@ -58,6 +62,7 @@ struct SubTask {
|
|||||||
double percentageOfEffectiveArea = 50.0; //深度图像的有效范围百分比
|
double percentageOfEffectiveArea = 50.0; //深度图像的有效范围百分比
|
||||||
|
|
||||||
//高光谱自动调焦
|
//高光谱自动调焦
|
||||||
|
HyperImagerType autoFocusHyperImagerType;//取值范围:L、NIR
|
||||||
QString autoFocusMotorConfigFilePath;//马达配置文件
|
QString autoFocusMotorConfigFilePath;//马达配置文件
|
||||||
double autoFocusX = 0.0;
|
double autoFocusX = 0.0;
|
||||||
double autoFocusY = 0.0;
|
double autoFocusY = 0.0;
|
||||||
@ -124,6 +129,9 @@ private:
|
|||||||
|
|
||||||
static QString subTaskTypeToString(SubTaskType type);
|
static QString subTaskTypeToString(SubTaskType type);
|
||||||
static SubTaskType stringToSubTaskType(const QString& str);
|
static SubTaskType stringToSubTaskType(const QString& str);
|
||||||
|
|
||||||
|
static QString hyperImagerTypeToString(HyperImagerType type);
|
||||||
|
static HyperImagerType stringToHyperImagerType(const QString& str);
|
||||||
};
|
};
|
||||||
|
|
||||||
// ==================== 任务执行器 ====================
|
// ==================== 任务执行器 ====================
|
||||||
@ -168,6 +176,7 @@ signals:
|
|||||||
|
|
||||||
void ObtainingDepthInformationSignals(SubTask info);
|
void ObtainingDepthInformationSignals(SubTask info);
|
||||||
void LiftingPlatformSignals(SubTask info);
|
void LiftingPlatformSignals(SubTask info);
|
||||||
|
void AutoFocusSignals(SubTask info);
|
||||||
|
|
||||||
void switchHalogenLampSignal(int state);
|
void switchHalogenLampSignal(int state);
|
||||||
void switchD65LampSignal(int state);
|
void switchD65LampSignal(int state);
|
||||||
@ -179,6 +188,7 @@ public slots:
|
|||||||
void onError(const QString& error);
|
void onError(const QString& error);
|
||||||
|
|
||||||
void emitRecordSignal();
|
void emitRecordSignal();
|
||||||
|
void emitAutoFocusSignal();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QString m_currentFolder;
|
QString m_currentFolder;
|
||||||
@ -240,6 +250,7 @@ signals:
|
|||||||
|
|
||||||
void ObtainingDepthInformationSignals(SubTask info);
|
void ObtainingDepthInformationSignals(SubTask info);
|
||||||
void LiftingPlatformSignals(SubTask info);
|
void LiftingPlatformSignals(SubTask info);
|
||||||
|
void AutoFocusSignals(SubTask info);
|
||||||
|
|
||||||
void switchHalogenLampSignal(int state);
|
void switchHalogenLampSignal(int state);
|
||||||
void switchD65LampSignal(int state);
|
void switchD65LampSignal(int state);
|
||||||
|
|||||||
@ -232,6 +232,25 @@ void TwoMotorControl::run4_ObtainTargetDepthInfo(DepthCameraWindow* window, int
|
|||||||
m_ObtainTargetDepthInfoCoordinator->moveToTarget(depthInfoX, depthInfoY, xmotor_move_speed, ymotor_move_speed);
|
m_ObtainTargetDepthInfoCoordinator->moveToTarget(depthInfoX, depthInfoY, xmotor_move_speed, ymotor_move_speed);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void TwoMotorControl::run5_AutoFocus(double autoFocusX, double autoFocusY)
|
||||||
|
{
|
||||||
|
m_focusWindow = new focusWindow(this, m_Imager);
|
||||||
|
m_focusWindow->onConnectMotor();
|
||||||
|
m_focusWindow->show();
|
||||||
|
|
||||||
|
//自动调焦的协调器添加功能:先归零
|
||||||
|
m_autoFocusCoordinator = new TwoMotor1PosCoordinator(m_multiAxisController);
|
||||||
|
connect(m_autoFocusCoordinator, &TwoMotor1PosCoordinator::ArrivalSignal, m_focusWindow, &focusWindow::onAutoFocus);
|
||||||
|
connect(m_focusWindow, &focusWindow::AutoFocusFinishedSignal, m_autoFocusCoordinator, &TwoMotor1PosCoordinator::back2origin);
|
||||||
|
connect(m_focusWindow, &focusWindow::AutoFocusFinishedSignal, this, &TwoMotorControl::sequenceComplete, Qt::UniqueConnection);
|
||||||
|
connect(m_autoFocusCoordinator, &TwoMotor1PosCoordinator::back2OriginSignal, this, &TwoMotorControl::onBack2Origin4);
|
||||||
|
|
||||||
|
|
||||||
|
double xmotor_move_speed = ui.xmotor_move_speed_lineEdit->text().toDouble();
|
||||||
|
double ymotor_move_speed = ui.ymotor_move_speed_lineEdit->text().toDouble();
|
||||||
|
m_autoFocusCoordinator->moveToTarget(autoFocusX, autoFocusY, xmotor_move_speed, ymotor_move_speed);
|
||||||
|
}
|
||||||
|
|
||||||
void TwoMotorControl::saveDepthValue(double depthValue)
|
void TwoMotorControl::saveDepthValue(double depthValue)
|
||||||
{
|
{
|
||||||
if (m_depthType == 0)//0表示植被深度,1表示白板/调焦版深度
|
if (m_depthType == 0)//0表示植被深度,1表示白板/调焦版深度
|
||||||
@ -251,6 +270,16 @@ void TwoMotorControl::onBack2Origin3()
|
|||||||
emit back2OriginSignal_TimedDataCollection();
|
emit back2OriginSignal_TimedDataCollection();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void TwoMotorControl::onBack2Origin4()
|
||||||
|
{
|
||||||
|
m_focusWindow->deleteLater();
|
||||||
|
m_focusWindow = nullptr;
|
||||||
|
|
||||||
|
m_autoFocusCoordinator->deleteLater();
|
||||||
|
m_autoFocusCoordinator = nullptr;
|
||||||
|
emit back2OriginSignal_TimedDataCollection();
|
||||||
|
}
|
||||||
|
|
||||||
void TwoMotorControl::run()
|
void TwoMotorControl::run()
|
||||||
{
|
{
|
||||||
if (getState())
|
if (getState())
|
||||||
|
|||||||
@ -17,6 +17,8 @@
|
|||||||
|
|
||||||
#include "DepthValueLogger.h"
|
#include "DepthValueLogger.h"
|
||||||
|
|
||||||
|
#include "focusWindow.h"
|
||||||
|
|
||||||
#define PI 3.1415926
|
#define PI 3.1415926
|
||||||
|
|
||||||
class TwoMotorControl : public QDialog, public MotorWindowBase
|
class TwoMotorControl : public QDialog, public MotorWindowBase
|
||||||
@ -85,9 +87,11 @@ public Q_SLOTS:
|
|||||||
void run2(SingleLensReflexCameraWindow* w);
|
void run2(SingleLensReflexCameraWindow* w);
|
||||||
void run3(DepthCameraWindow* window);
|
void run3(DepthCameraWindow* window);
|
||||||
void run4_ObtainTargetDepthInfo(DepthCameraWindow* window, int depthType, double depthInfoX, double depthInfoY, int averageNumberOfTimes, double percentageOfEffectiveArea);
|
void run4_ObtainTargetDepthInfo(DepthCameraWindow* window, int depthType, double depthInfoX, double depthInfoY, int averageNumberOfTimes, double percentageOfEffectiveArea);
|
||||||
|
void run5_AutoFocus(double autoFocusX, double autoFocusY);
|
||||||
void onBack2Origin2();
|
void onBack2Origin2();
|
||||||
void saveDepthValue(double depthValue);
|
void saveDepthValue(double depthValue);
|
||||||
void onBack2Origin3();
|
void onBack2Origin3();
|
||||||
|
void onBack2Origin4();
|
||||||
|
|
||||||
void stop_record();
|
void stop_record();
|
||||||
|
|
||||||
@ -117,6 +121,7 @@ private:
|
|||||||
TwoMotionCaptureCoordinator* m_coordinator = nullptr;
|
TwoMotionCaptureCoordinator* m_coordinator = nullptr;
|
||||||
TwoMotionCaptureCoordinator* m_coordinator_TimedDataCollection = nullptr;
|
TwoMotionCaptureCoordinator* m_coordinator_TimedDataCollection = nullptr;
|
||||||
TwoMotor1PosCoordinator* m_ObtainTargetDepthInfoCoordinator = nullptr;
|
TwoMotor1PosCoordinator* m_ObtainTargetDepthInfoCoordinator = nullptr;
|
||||||
|
TwoMotor1PosCoordinator* m_autoFocusCoordinator = nullptr;
|
||||||
|
|
||||||
DarkAndWhiteCaptureCoordinator* m_darkCaptureCoordinator = nullptr;
|
DarkAndWhiteCaptureCoordinator* m_darkCaptureCoordinator = nullptr;
|
||||||
DarkAndWhiteCaptureCoordinator* m_whiteCaptureCoordinator = nullptr;
|
DarkAndWhiteCaptureCoordinator* m_whiteCaptureCoordinator = nullptr;
|
||||||
@ -125,4 +130,6 @@ private:
|
|||||||
IrisMultiMotorController* m_multiAxisController = nullptr;
|
IrisMultiMotorController* m_multiAxisController = nullptr;
|
||||||
|
|
||||||
int m_depthType;
|
int m_depthType;
|
||||||
|
|
||||||
|
focusWindow* m_focusWindow = nullptr;
|
||||||
};
|
};
|
||||||
|
|||||||
@ -299,7 +299,7 @@ void focusWindow::connectMotor(bool isNotification)//需要修改这个函数
|
|||||||
if (m_coordinator)
|
if (m_coordinator)
|
||||||
{
|
{
|
||||||
disconnect(&m_MotionCaptureCoordinatorThread, SIGNAL(finished()), m_coordinator, SLOT(deleteLater()));
|
disconnect(&m_MotionCaptureCoordinatorThread, SIGNAL(finished()), m_coordinator, SLOT(deleteLater()));
|
||||||
disconnect(this, SIGNAL(startStepMotion(double, int, double, double)), m_coordinator, SLOT(startStepMotion(double, int, double, double)));
|
disconnect(this, SIGNAL(startStepMotionSignal(double, int, double, double)), m_coordinator, SLOT(startStepMotion(double, int, double, double)));
|
||||||
disconnect(m_coordinator, SIGNAL(progressChanged(int)), this, SLOT(onAutoFocusProgress(int)));
|
disconnect(m_coordinator, SIGNAL(progressChanged(int)), this, SLOT(onAutoFocusProgress(int)));
|
||||||
disconnect(m_coordinator, SIGNAL(sequenceComplete()), this, SLOT(onAutoFocusFinished()));
|
disconnect(m_coordinator, SIGNAL(sequenceComplete()), this, SLOT(onAutoFocusFinished()));
|
||||||
|
|
||||||
@ -343,7 +343,7 @@ void focusWindow::connectMotor(bool isNotification)//需要修改这个函数
|
|||||||
m_coordinator = new MotionCaptureCoordinator(m_multiAxisController, m_Imager);
|
m_coordinator = new MotionCaptureCoordinator(m_multiAxisController, m_Imager);
|
||||||
m_coordinator->moveToThread(&m_MotionCaptureCoordinatorThread);
|
m_coordinator->moveToThread(&m_MotionCaptureCoordinatorThread);
|
||||||
connect(&m_MotionCaptureCoordinatorThread, SIGNAL(finished()), m_coordinator, SLOT(deleteLater()));
|
connect(&m_MotionCaptureCoordinatorThread, SIGNAL(finished()), m_coordinator, SLOT(deleteLater()));
|
||||||
connect(this, SIGNAL(startStepMotion(double, int, double, double)), m_coordinator, SLOT(startStepMotion(double, int, double, double)));
|
connect(this, SIGNAL(startStepMotionSignal(double, int, double, double)), m_coordinator, SLOT(startStepMotion(double, int, double, double)));
|
||||||
connect(m_coordinator, SIGNAL(progressChanged(int)), this, SLOT(onAutoFocusProgress(int)));
|
connect(m_coordinator, SIGNAL(progressChanged(int)), this, SLOT(onAutoFocusProgress(int)));
|
||||||
connect(m_coordinator, SIGNAL(sequenceComplete()), this, SLOT(onAutoFocusFinished()));
|
connect(m_coordinator, SIGNAL(sequenceComplete()), this, SLOT(onAutoFocusFinished()));
|
||||||
m_MotionCaptureCoordinatorThread.start();
|
m_MotionCaptureCoordinatorThread.start();
|
||||||
@ -475,7 +475,7 @@ void focusWindow::onAutoFocus()
|
|||||||
//获取马达最大位置
|
//获取马达最大位置
|
||||||
std::vector<double> maxRangeLocations = m_multiAxisController->getMaxPos();
|
std::vector<double> maxRangeLocations = m_multiAxisController->getMaxPos();
|
||||||
double maxPos = maxRangeLocations[0];
|
double maxPos = maxRangeLocations[0];
|
||||||
emit startStepMotion(m_dSpeed, m_iStepSize, 0, maxPos);
|
emit startStepMotionSignal(m_dSpeed, m_iStepSize, 0, maxPos);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -649,26 +649,48 @@ void focusWindow::moveAfterAutoFocus(int motorID, double location)
|
|||||||
|
|
||||||
std::cout << "\n已经到达位置:" << location << std::endl;
|
std::cout << "\n已经到达位置:" << location << std::endl;
|
||||||
|
|
||||||
double tmp = abs(location - m_goodPos) / m_goodPos * 100;
|
double errorRate = getErrorRate(m_goodPos, location);
|
||||||
if (tmp < 5 || m_goodPos == 0)
|
if (errorRate < 5|| m_moveRetryCount > MAX_MOVE_RETRY)
|
||||||
{
|
{
|
||||||
m_isMoveAfterAutoFocus = false;
|
m_isMoveAfterAutoFocus = false;
|
||||||
|
m_moveRetryCount = 0;
|
||||||
if (!m_isAutoFocusSuccess)
|
if (!m_isAutoFocusSuccess)
|
||||||
{
|
{
|
||||||
showMessageBox(QString::fromLocal8Bit("纹理较弱,自动调焦效果不佳!请使用调焦纸进行自动调焦!"));
|
qDebug() << "纹理较弱,自动调焦效果不佳!请使用调焦纸进行自动调焦!";
|
||||||
|
//showMessageBox(QString::fromLocal8Bit("纹理较弱,自动调焦效果不佳!请使用调焦纸进行自动调焦!"));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
showMessageBox(QString::fromLocal8Bit("自动调焦成功!"));
|
qDebug() << "自动调焦成功!";
|
||||||
|
//showMessageBox(QString::fromLocal8Bit("自动调焦成功!"));
|
||||||
}
|
}
|
||||||
|
emit AutoFocusFinishedSignal(0);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
m_moveRetryCount++;
|
||||||
|
qDebug() << "自动调焦后目标马达位置,重试次数:" << m_moveRetryCount;
|
||||||
//移动马达到最佳位置
|
//移动马达到最佳位置
|
||||||
emit move2LocSignal(0, (double)m_goodPos, m_dSpeed, 1000);
|
emit move2LocSignal(0, (double)m_goodPos, m_dSpeed, 1000);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
double focusWindow::getErrorRate(double targetLoc, double actualLoc)
|
||||||
|
{
|
||||||
|
double targetLocTmp;
|
||||||
|
if (targetLoc == 0)
|
||||||
|
{
|
||||||
|
targetLocTmp = 0.001;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
targetLocTmp = targetLoc;
|
||||||
|
}
|
||||||
|
double errorRate = abs(targetLoc - actualLoc) / targetLocTmp * 100;
|
||||||
|
|
||||||
|
return errorRate;
|
||||||
|
}
|
||||||
|
|
||||||
void focusWindow::getGaussianInitParam(const std::vector<double>& pos, const std::vector<double>& index, double& a_init, double& mu_init, double& sigma_init, double& c_init)
|
void focusWindow::getGaussianInitParam(const std::vector<double>& pos, const std::vector<double>& index, double& a_init, double& mu_init, double& sigma_init, double& c_init)
|
||||||
{
|
{
|
||||||
auto minmax_element = std::minmax_element(index.begin(), index.end());
|
auto minmax_element = std::minmax_element(index.begin(), index.end());
|
||||||
@ -819,11 +841,15 @@ MotionCaptureCoordinator::MotionCaptureCoordinator(
|
|||||||
, m_currentPos(0)
|
, m_currentPos(0)
|
||||||
, m_endPos(0)
|
, m_endPos(0)
|
||||||
, m_isRunning(false)
|
, m_isRunning(false)
|
||||||
|
, m_isZeroing(false)
|
||||||
{
|
{
|
||||||
//这些信号槽是按照逻辑顺序的
|
//这些信号槽是按照逻辑顺序的
|
||||||
connect(this, SIGNAL(moveTo(int, double, double, int)),
|
connect(this, SIGNAL(moveTo(int, double, double, int)),
|
||||||
m_motorCtrl, SLOT(moveTo(int, double, double, int)));
|
m_motorCtrl, SLOT(moveTo(int, double, double, int)));
|
||||||
|
|
||||||
|
connect(this, &MotionCaptureCoordinator::zeroStart,
|
||||||
|
m_motorCtrl, &IrisMultiMotorController::zeroStart);
|
||||||
|
|
||||||
connect(m_motorCtrl, &IrisMultiMotorController::motorStopSignal,
|
connect(m_motorCtrl, &IrisMultiMotorController::motorStopSignal,
|
||||||
this, &MotionCaptureCoordinator::handlePositionReached);
|
this, &MotionCaptureCoordinator::handlePositionReached);
|
||||||
//connect(m_motorCtrl, &IrisMultiMotorController::moveFailed,
|
//connect(m_motorCtrl, &IrisMultiMotorController::moveFailed,
|
||||||
@ -860,15 +886,37 @@ void MotionCaptureCoordinator::startStepMotion(double speed, int stepInterval, d
|
|||||||
m_speed = speed;
|
m_speed = speed;
|
||||||
m_iStepInterval = stepInterval;
|
m_iStepInterval = stepInterval;
|
||||||
m_iStepIntervalRealTime = 1;
|
m_iStepIntervalRealTime = 1;
|
||||||
m_currentPos = startPos;
|
m_startPos = startPos;
|
||||||
m_endPos = endPos;
|
m_endPos = endPos;
|
||||||
m_posInternal = (endPos - startPos) / stepInterval;
|
m_posInternal = (endPos - startPos) / stepInterval;
|
||||||
|
|
||||||
m_isRunning = true;
|
m_isRunning = true;
|
||||||
|
m_isZeroing = true;
|
||||||
|
|
||||||
|
// 先执行归零操作
|
||||||
|
emit zeroStart(0);
|
||||||
|
qDebug() << "MotionCaptureCoordinator::startStepMotion: Zeroing started.";
|
||||||
|
}
|
||||||
|
|
||||||
|
void MotionCaptureCoordinator::startMotionSequence()
|
||||||
|
{
|
||||||
|
QMutexLocker locker(&m_dataMutex);
|
||||||
|
|
||||||
|
m_currentPos = m_startPos;
|
||||||
|
m_isZeroing = false;
|
||||||
|
qDebug() << "MotionCaptureCoordinator::startMotionSequence: Zeroing complete. Starting motion sequence.";
|
||||||
|
|
||||||
processNextPosition();
|
processNextPosition();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MotionCaptureCoordinator::handleZeroComplete(int motorID, double pos)
|
||||||
|
{
|
||||||
|
if (!m_isRunning || !m_isZeroing) return;
|
||||||
|
|
||||||
|
// 归零完成,开始分步运动
|
||||||
|
startMotionSequence();
|
||||||
|
}
|
||||||
|
|
||||||
void MotionCaptureCoordinator::stopStepMotion()
|
void MotionCaptureCoordinator::stopStepMotion()
|
||||||
{
|
{
|
||||||
QMutexLocker locker(&m_dataMutex);
|
QMutexLocker locker(&m_dataMutex);
|
||||||
@ -911,6 +959,13 @@ void MotionCaptureCoordinator::handlePositionReached(int motorID, double pos)
|
|||||||
{
|
{
|
||||||
if (!m_isRunning) return;
|
if (!m_isRunning) return;
|
||||||
|
|
||||||
|
// 如果正在等待归零完成,调用归零完成处理
|
||||||
|
if (m_isZeroing)
|
||||||
|
{
|
||||||
|
handleZeroComplete(motorID, pos);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
QMutexLocker locker(&m_dataMutex);
|
QMutexLocker locker(&m_dataMutex);
|
||||||
|
|
||||||
//验证马达运动位置是否到达指定位置
|
//验证马达运动位置是否到达指定位置
|
||||||
|
|||||||
@ -70,14 +70,17 @@ signals:
|
|||||||
void errorOccurred(const QString& error);
|
void errorOccurred(const QString& error);
|
||||||
void moveTo(int, double, double, int);
|
void moveTo(int, double, double, int);
|
||||||
void getFocusIndexSobel();
|
void getFocusIndexSobel();
|
||||||
|
void zeroStart(int motorID);
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void handlePositionReached(int motorID, double pos);
|
void handlePositionReached(int motorID, double pos);
|
||||||
void handleCaptureComplete(double index);
|
void handleCaptureComplete(double index);
|
||||||
void handleError(const QString& error);
|
void handleError(const QString& error);
|
||||||
|
void handleZeroComplete(int motorID, double pos);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void processNextPosition();
|
void processNextPosition();
|
||||||
|
void startMotionSequence();
|
||||||
|
|
||||||
IrisMultiMotorController* m_motorCtrl;
|
IrisMultiMotorController* m_motorCtrl;
|
||||||
ImagerOperationBase* m_cameraCtrl;
|
ImagerOperationBase* m_cameraCtrl;
|
||||||
@ -86,6 +89,7 @@ private:
|
|||||||
|
|
||||||
double m_posInternal;
|
double m_posInternal;
|
||||||
double m_currentPos;
|
double m_currentPos;
|
||||||
|
double m_startPos;
|
||||||
double m_endPos;
|
double m_endPos;
|
||||||
bool m_isRunning;
|
bool m_isRunning;
|
||||||
double m_speed;
|
double m_speed;
|
||||||
@ -93,6 +97,7 @@ private:
|
|||||||
int m_iStepInterval;
|
int m_iStepInterval;
|
||||||
int m_iStepIntervalRealTime;
|
int m_iStepIntervalRealTime;
|
||||||
int m_counter;
|
int m_counter;
|
||||||
|
bool m_isZeroing;
|
||||||
};
|
};
|
||||||
|
|
||||||
class focusWindow:public QDialog
|
class focusWindow:public QDialog
|
||||||
@ -134,6 +139,8 @@ private:
|
|||||||
double m_goodPos;
|
double m_goodPos;
|
||||||
bool m_isAutoFocusSuccess;
|
bool m_isAutoFocusSuccess;
|
||||||
bool m_isMoveAfterAutoFocus = false;
|
bool m_isMoveAfterAutoFocus = false;
|
||||||
|
int m_moveRetryCount = 0;
|
||||||
|
static constexpr int MAX_MOVE_RETRY = 3;
|
||||||
void getGaussianInitParam(const std::vector<double>& pos, const std::vector<double>& index, double& a_init, double& mu_init, double& sigma_init, double& c_init);
|
void getGaussianInitParam(const std::vector<double>& pos, const std::vector<double>& index, double& a_init, double& mu_init, double& sigma_init, double& c_init);
|
||||||
void gaussian_fit(const std::vector<double>& x_data, const std::vector<double>& y_data, double& a, double& mu, double& sigma, double& c);
|
void gaussian_fit(const std::vector<double>& x_data, const std::vector<double>& y_data, double& a, double& mu, double& sigma, double& c);
|
||||||
|
|
||||||
@ -143,6 +150,8 @@ private:
|
|||||||
|
|
||||||
void showMessageBox(QString msg, QString title = QString::fromLocal8Bit("提示"));
|
void showMessageBox(QString msg, QString title = QString::fromLocal8Bit("提示"));
|
||||||
|
|
||||||
|
double getErrorRate(double targetLoc, double actualLoc);
|
||||||
|
|
||||||
public Q_SLOTS:
|
public Q_SLOTS:
|
||||||
void onConnectMotor();
|
void onConnectMotor();
|
||||||
void onMove2MotorLogicZero();
|
void onMove2MotorLogicZero();
|
||||||
@ -176,8 +185,10 @@ signals:
|
|||||||
void zeroStartSignal(int);
|
void zeroStartSignal(int);
|
||||||
void testConnectivitySignal(int, int);
|
void testConnectivitySignal(int, int);
|
||||||
|
|
||||||
void startStepMotion(double speed, int stepInterval = 100, double startPos = 0, double endPos = -1);
|
void startStepMotionSignal(double speed, int stepInterval = 100, double startPos = 0, double endPos = -1);
|
||||||
void closeSignal();
|
void closeSignal();
|
||||||
|
|
||||||
|
void AutoFocusFinishedSignal(int status);
|
||||||
};
|
};
|
||||||
|
|
||||||
class WorkerThread2 : public QThread
|
class WorkerThread2 : public QThread
|
||||||
|
|||||||
Reference in New Issue
Block a user