773 lines
23 KiB
C++
773 lines
23 KiB
C++
#include "DemoControlPresenter.h"
|
||
#include <QDebug>
|
||
#include <chrono>
|
||
#include <thread>
|
||
|
||
DemoControlPresenter::DemoControlPresenter(QObject *parent)
|
||
: QObject(parent)
|
||
{
|
||
m_robot = std::make_unique<FairinoRobotWrapper>();
|
||
}
|
||
|
||
DemoControlPresenter::~DemoControlPresenter()
|
||
{
|
||
StopWorkflow();
|
||
DisconnectController();
|
||
DisconnectRobot();
|
||
}
|
||
|
||
int DemoControlPresenter::Init()
|
||
{
|
||
SendStatusMessage("主控程序初始化完成");
|
||
return 0;
|
||
}
|
||
|
||
bool DemoControlPresenter::ConnectToController(const QString& ip, int port)
|
||
{
|
||
if (m_controllerConnected) {
|
||
SendStatusMessage("控制器已连接");
|
||
return true;
|
||
}
|
||
|
||
SendStatusMessage(QString("正在连接控制器 %1:%2...").arg(ip).arg(port));
|
||
|
||
// 创建ModbusTCP客户端
|
||
if (!IYModbusTCPClient::CreateInstance(&m_modbusClient, ip.toStdString(), port)) {
|
||
SendStatusMessage("创建ModbusTCP客户端失败");
|
||
emit controllerConnectionChanged(false);
|
||
return false;
|
||
}
|
||
|
||
// 设置连接状态回调
|
||
m_modbusClient->SetConnectionStateCallback([this](IYModbusTCPClient::ConnectionState oldState,
|
||
IYModbusTCPClient::ConnectionState newState,
|
||
const std::string& message) {
|
||
QString msg = QString::fromStdString(message);
|
||
SendStatusMessage(QString("控制器连接状态: %1").arg(msg));
|
||
|
||
bool connected = (newState == IYModbusTCPClient::CONNECTED);
|
||
m_controllerConnected = connected;
|
||
emit controllerConnectionChanged(connected);
|
||
});
|
||
|
||
// 连接
|
||
auto result = m_modbusClient->Connect();
|
||
if (result != IYModbusTCPClient::SUCCESS) {
|
||
SendStatusMessage(QString("连接控制器失败: %1")
|
||
.arg(QString::fromStdString(m_modbusClient->GetLastError())));
|
||
emit controllerConnectionChanged(false);
|
||
return false;
|
||
}
|
||
|
||
m_controllerConnected = true;
|
||
SendStatusMessage("控制器连接成功");
|
||
emit controllerConnectionChanged(true);
|
||
return true;
|
||
}
|
||
|
||
void DemoControlPresenter::DisconnectController()
|
||
{
|
||
if (m_modbusClient) {
|
||
m_modbusClient->Disconnect();
|
||
delete m_modbusClient;
|
||
m_modbusClient = nullptr;
|
||
}
|
||
m_controllerConnected = false;
|
||
emit controllerConnectionChanged(false);
|
||
SendStatusMessage("控制器已断开连接");
|
||
}
|
||
|
||
bool DemoControlPresenter::ConnectToRobot(const QString& ip)
|
||
{
|
||
if (m_robotConnected) {
|
||
SendStatusMessage("机械臂已连接");
|
||
return true;
|
||
}
|
||
|
||
SendStatusMessage(QString("正在连接机械臂 %1...").arg(ip));
|
||
|
||
errno_t ret = m_robot->Connect(ip.toStdString());
|
||
if (ret != 0) {
|
||
SendStatusMessage(QString("连接机械臂失败: 错误码 %1").arg(ret));
|
||
emit robotConnectionChanged(false);
|
||
return false;
|
||
}
|
||
|
||
m_robotConnected = true;
|
||
SendStatusMessage("机械臂连接成功");
|
||
emit robotConnectionChanged(true);
|
||
return true;
|
||
}
|
||
|
||
void DemoControlPresenter::DisconnectRobot()
|
||
{
|
||
if (m_robot) {
|
||
m_robot->Disconnect();
|
||
}
|
||
m_robotConnected = false;
|
||
emit robotConnectionChanged(false);
|
||
SendStatusMessage("机械臂已断开连接");
|
||
}
|
||
|
||
bool DemoControlPresenter::IsControllerConnected() const
|
||
{
|
||
return m_controllerConnected;
|
||
}
|
||
|
||
bool DemoControlPresenter::IsRobotConnected() const
|
||
{
|
||
return m_robotConnected;
|
||
}
|
||
|
||
void DemoControlPresenter::StartWorkflow()
|
||
{
|
||
if (m_workflowRunning) {
|
||
SendStatusMessage("工作流程已在运行中");
|
||
return;
|
||
}
|
||
|
||
if (!m_controllerConnected) {
|
||
SendStatusMessage("错误: 控制器未连接");
|
||
return;
|
||
}
|
||
|
||
if (!m_robotConnected) {
|
||
SendStatusMessage("错误: 机械臂未连接");
|
||
return;
|
||
}
|
||
|
||
// 清理旧的线程对象(如果存在)
|
||
if (m_workflowThread.joinable()) {
|
||
m_workflowThread.join();
|
||
}
|
||
|
||
m_workflowShouldStop = false;
|
||
m_workflowPaused = false;
|
||
m_workflowStepMode = false;
|
||
m_nextStepToExecute = 0; // 从第一步开始
|
||
m_workflowRunning = true;
|
||
|
||
// 启动工作流程线程
|
||
m_workflowThread = std::thread(&DemoControlPresenter::WorkflowThreadFunc, this);
|
||
|
||
SendStatusMessage("工作流程已启动");
|
||
}
|
||
|
||
void DemoControlPresenter::StopWorkflow()
|
||
{
|
||
if (!m_workflowRunning) {
|
||
return;
|
||
}
|
||
|
||
m_workflowShouldStop = true;
|
||
m_workflowPaused = false;
|
||
m_workflowStepMode = false;
|
||
m_nextStepToExecute = 0; // 重置步骤
|
||
|
||
// 唤醒可能在等待的线程
|
||
m_stepCondition.notify_all();
|
||
|
||
if (m_workflowThread.joinable()) {
|
||
m_workflowThread.join();
|
||
}
|
||
|
||
m_workflowRunning = false;
|
||
UpdateWorkflowStep(WorkflowStep::Idle, "工作流程已停止");
|
||
}
|
||
|
||
void DemoControlPresenter::PauseWorkflow()
|
||
{
|
||
if (!m_workflowRunning || m_workflowPaused) {
|
||
return;
|
||
}
|
||
|
||
m_workflowPaused = true;
|
||
SendStatusMessage("工作流程已暂停");
|
||
}
|
||
|
||
void DemoControlPresenter::ResumeWorkflow()
|
||
{
|
||
if (!m_workflowRunning || !m_workflowPaused) {
|
||
return;
|
||
}
|
||
|
||
m_workflowPaused = false;
|
||
m_workflowStepMode = false;
|
||
m_stepCondition.notify_all();
|
||
SendStatusMessage("工作流程已恢复");
|
||
}
|
||
|
||
void DemoControlPresenter::StepWorkflow()
|
||
{
|
||
if (m_workflowRunning && !m_workflowPaused) {
|
||
SendStatusMessage("请先暂停工作流程");
|
||
return;
|
||
}
|
||
|
||
if (!m_controllerConnected) {
|
||
SendStatusMessage("错误: 控制器未连接");
|
||
return;
|
||
}
|
||
|
||
if (!m_robotConnected) {
|
||
SendStatusMessage("错误: 机械臂未连接");
|
||
return;
|
||
}
|
||
|
||
// 如果工作流程未运行,启动单步模式
|
||
if (!m_workflowRunning) {
|
||
// 清理旧的线程对象(如果存在)
|
||
if (m_workflowThread.joinable()) {
|
||
m_workflowThread.join();
|
||
}
|
||
|
||
m_workflowShouldStop = false;
|
||
m_workflowPaused = true;
|
||
m_workflowStepMode = true;
|
||
m_workflowStepReady = true;
|
||
m_nextStepToExecute = 0; // 从第一步开始
|
||
m_workflowRunning = true;
|
||
|
||
// 启动工作流程线程
|
||
m_workflowThread = std::thread(&DemoControlPresenter::WorkflowThreadFunc, this);
|
||
SendStatusMessage("单步执行已启动,从第一步开始");
|
||
} else {
|
||
// 工作流程已运行且暂停,切换到单步模式并执行下一步
|
||
m_workflowStepMode = true; // 切换到单步模式
|
||
m_workflowStepReady = true;
|
||
m_stepCondition.notify_all();
|
||
SendStatusMessage(QString("单步执行下一步(步骤 %1)").arg(m_nextStepToExecute + 1));
|
||
}
|
||
}
|
||
|
||
void DemoControlPresenter::SetReadyPosition(double x, double y, double z, double rx, double ry, double rz)
|
||
{
|
||
m_readyPosition.x = x;
|
||
m_readyPosition.y = y;
|
||
m_readyPosition.z = z;
|
||
m_readyPosition.rx = rx;
|
||
m_readyPosition.ry = ry;
|
||
m_readyPosition.rz = rz;
|
||
}
|
||
|
||
void DemoControlPresenter::SetPlacePosition(double x, double y, double z, double rx, double ry, double rz)
|
||
{
|
||
m_placePosition.x = x;
|
||
m_placePosition.y = y;
|
||
m_placePosition.z = z;
|
||
m_placePosition.rx = rx;
|
||
m_placePosition.ry = ry;
|
||
m_placePosition.rz = rz;
|
||
}
|
||
|
||
void DemoControlPresenter::SetGraspOffset(double offsetZ)
|
||
{
|
||
m_graspOffsetZ = offsetZ;
|
||
}
|
||
|
||
void DemoControlPresenter::SetToolNumber(int tool)
|
||
{
|
||
m_toolNumber = tool;
|
||
}
|
||
|
||
void DemoControlPresenter::SetVelocity(double velocity)
|
||
{
|
||
m_velocity = velocity;
|
||
}
|
||
|
||
void DemoControlPresenter::SetAcceleration(double acceleration)
|
||
{
|
||
m_acceleration = acceleration;
|
||
}
|
||
|
||
bool DemoControlPresenter::TestMoveToReady()
|
||
{
|
||
if (!m_robotConnected) {
|
||
SendStatusMessage("错误: 机械臂未连接");
|
||
return false;
|
||
}
|
||
|
||
SendStatusMessage("测试移动到准备位置...");
|
||
|
||
errno_t ret = m_robot->MoveJByPose(
|
||
m_readyPosition.x, m_readyPosition.y, m_readyPosition.z,
|
||
m_readyPosition.rx, m_readyPosition.ry, m_readyPosition.rz,
|
||
static_cast<float>(m_velocity), static_cast<float>(m_acceleration), -1.0f,
|
||
m_toolNumber, 0
|
||
);
|
||
|
||
if (ret != 0) {
|
||
SendStatusMessage(QString("移动到准备位置失败: 错误码 %1").arg(ret));
|
||
return false;
|
||
}
|
||
|
||
SendStatusMessage("已到达准备位置");
|
||
return true;
|
||
}
|
||
|
||
bool DemoControlPresenter::TestMoveToPlace()
|
||
{
|
||
if (!m_robotConnected) {
|
||
SendStatusMessage("错误: 机械臂未连接");
|
||
return false;
|
||
}
|
||
|
||
SendStatusMessage("测试移动到放置位置...");
|
||
|
||
errno_t ret = m_robot->MoveJByPose(
|
||
m_placePosition.x, m_placePosition.y, m_placePosition.z,
|
||
m_placePosition.rx, m_placePosition.ry, m_placePosition.rz,
|
||
static_cast<float>(m_velocity), static_cast<float>(m_acceleration), -1.0f,
|
||
m_toolNumber, 0
|
||
);
|
||
|
||
if (ret != 0) {
|
||
SendStatusMessage(QString("移动到放置位置失败: 错误码 %1").arg(ret));
|
||
return false;
|
||
}
|
||
|
||
SendStatusMessage("已到达放置位置");
|
||
return true;
|
||
}
|
||
|
||
bool DemoControlPresenter::GetCurrentPosition(double& x, double& y, double& z, double& rx, double& ry, double& rz)
|
||
{
|
||
if (!m_robotConnected) {
|
||
SendStatusMessage("错误: 机械臂未连接");
|
||
return false;
|
||
}
|
||
|
||
errno_t ret = m_robot->GetCurrentTCPPose(x, y, z, rx, ry, rz, 0);
|
||
|
||
if (ret != 0) {
|
||
SendStatusMessage(QString("读取当前位置失败: 错误码 %1").arg(ret));
|
||
return false;
|
||
}
|
||
|
||
SendStatusMessage(QString("当前位置: X=%1, Y=%2, Z=%3, RX=%4, RY=%5, RZ=%6")
|
||
.arg(x, 0, 'f', 2).arg(y, 0, 'f', 2).arg(z, 0, 'f', 2)
|
||
.arg(rx, 0, 'f', 2).arg(ry, 0, 'f', 2).arg(rz, 0, 'f', 2));
|
||
return true;
|
||
}
|
||
|
||
void DemoControlPresenter::WorkflowThreadFunc()
|
||
{
|
||
while (!m_workflowShouldStop) {
|
||
// 检查是否需要等待(暂停或单步模式)
|
||
if (m_workflowPaused || m_workflowStepMode) {
|
||
std::unique_lock<std::mutex> lock(m_stepMutex);
|
||
m_stepCondition.wait(lock, [this]() {
|
||
return m_workflowShouldStop || (!m_workflowPaused && !m_workflowStepMode) || m_workflowStepReady;
|
||
});
|
||
|
||
if (m_workflowShouldStop) break;
|
||
|
||
// 单步模式下,执行完一步后重新等待
|
||
if (m_workflowStepMode) {
|
||
m_workflowStepReady = false;
|
||
}
|
||
}
|
||
|
||
// 根据 m_nextStepToExecute 执行对应的步骤
|
||
bool stepSuccess = false;
|
||
int currentStep = m_nextStepToExecute.load();
|
||
|
||
switch (currentStep) {
|
||
case 0: // 步骤1: 机械臂运行到准备位置
|
||
stepSuccess = ExecuteMovingToReady();
|
||
if (!stepSuccess) {
|
||
UpdateWorkflowStep(WorkflowStep::Error, "移动到准备位置失败");
|
||
} else {
|
||
m_nextStepToExecute = 1;
|
||
}
|
||
break;
|
||
|
||
case 1: // 步骤2: 触发控制器检测
|
||
stepSuccess = ExecuteTriggeringDetection();
|
||
if (!stepSuccess) {
|
||
UpdateWorkflowStep(WorkflowStep::Error, "触发检测失败");
|
||
} else {
|
||
m_nextStepToExecute = 2;
|
||
}
|
||
break;
|
||
|
||
case 2: // 步骤3: 等待检测完成
|
||
stepSuccess = ExecuteWaitingDetectionComplete();
|
||
if (!stepSuccess) {
|
||
UpdateWorkflowStep(WorkflowStep::Error, "等待检测完成失败");
|
||
} else {
|
||
m_nextStepToExecute = 3;
|
||
}
|
||
break;
|
||
|
||
case 3: // 步骤4: 读取检测结果
|
||
stepSuccess = ExecuteReadingResult();
|
||
if (!stepSuccess) {
|
||
UpdateWorkflowStep(WorkflowStep::Error, "读取检测结果失败");
|
||
} else {
|
||
m_nextStepToExecute = 4;
|
||
}
|
||
break;
|
||
|
||
case 4: // 步骤5: 机械臂移动到抓取位置
|
||
stepSuccess = ExecuteMovingToGrasp();
|
||
if (!stepSuccess) {
|
||
UpdateWorkflowStep(WorkflowStep::Error, "移动到抓取位置失败");
|
||
} else {
|
||
m_nextStepToExecute = 5;
|
||
}
|
||
break;
|
||
|
||
case 5: // 步骤6: 执行抓取
|
||
stepSuccess = ExecuteGrasping();
|
||
if (!stepSuccess) {
|
||
UpdateWorkflowStep(WorkflowStep::Error, "执行抓取失败");
|
||
} else {
|
||
m_nextStepToExecute = 6;
|
||
}
|
||
break;
|
||
|
||
case 6: // 步骤7: 机械臂移动到放置位置
|
||
stepSuccess = ExecuteMovingToPlace();
|
||
if (!stepSuccess) {
|
||
UpdateWorkflowStep(WorkflowStep::Error, "移动到放置位置失败");
|
||
} else {
|
||
m_nextStepToExecute = 7;
|
||
}
|
||
break;
|
||
|
||
case 7: // 步骤8: 执行放置
|
||
stepSuccess = ExecutePlacing();
|
||
if (!stepSuccess) {
|
||
UpdateWorkflowStep(WorkflowStep::Error, "执行放置失败");
|
||
} else {
|
||
// 完成一次循环
|
||
UpdateWorkflowStep(WorkflowStep::Completed, "工作流程完成");
|
||
|
||
// 如果是单步模式,完成后停止工作流程
|
||
if (m_workflowStepMode) {
|
||
m_nextStepToExecute = 0; // 重置到第一步
|
||
m_workflowRunning = false;
|
||
SendStatusMessage("单步执行已完成所有步骤,下次将从第一步重新开始");
|
||
return; // 退出线程
|
||
}
|
||
|
||
// 连续模式下,重置到第一步继续循环
|
||
m_nextStepToExecute = 0;
|
||
std::this_thread::sleep_for(std::chrono::milliseconds(500));
|
||
}
|
||
break;
|
||
|
||
default:
|
||
// 未知步骤,重置
|
||
m_nextStepToExecute = 0;
|
||
break;
|
||
}
|
||
|
||
// 如果步骤失败,退出循环
|
||
if (!stepSuccess) {
|
||
break;
|
||
}
|
||
|
||
// 如果是单步模式,执行完一步后继续等待
|
||
if (m_workflowStepMode && currentStep < 7) {
|
||
continue;
|
||
}
|
||
|
||
// 检查是否需要停止
|
||
if (m_workflowShouldStop) break;
|
||
|
||
// 检查暂停
|
||
if (m_workflowPaused) continue;
|
||
}
|
||
|
||
m_workflowRunning = false;
|
||
}
|
||
|
||
bool DemoControlPresenter::ExecuteMovingToReady()
|
||
{
|
||
UpdateWorkflowStep(WorkflowStep::MovingToReady);
|
||
|
||
errno_t ret = m_robot->MoveJByPose(
|
||
m_readyPosition.x, m_readyPosition.y, m_readyPosition.z,
|
||
m_readyPosition.rx, m_readyPosition.ry, m_readyPosition.rz,
|
||
static_cast<float>(m_velocity), static_cast<float>(m_acceleration), -1.0f,
|
||
m_toolNumber, 0
|
||
);
|
||
|
||
if (ret != 0) {
|
||
SendStatusMessage(QString("机械臂移动失败: 错误码 %1").arg(ret));
|
||
return false;
|
||
}
|
||
|
||
SendStatusMessage("机械臂已到达准备位置");
|
||
return true;
|
||
}
|
||
|
||
bool DemoControlPresenter::ExecuteTriggeringDetection()
|
||
{
|
||
UpdateWorkflowStep(WorkflowStep::TriggeringDetection);
|
||
|
||
// 写1到地址0触发检测
|
||
if (!WriteModbusRegister(0, 1)) {
|
||
SendStatusMessage("触发检测失败");
|
||
return false;
|
||
}
|
||
|
||
SendStatusMessage("已触发控制器检测");
|
||
std::this_thread::sleep_for(std::chrono::milliseconds(100));
|
||
return true;
|
||
}
|
||
|
||
bool DemoControlPresenter::ExecuteWaitingDetectionComplete()
|
||
{
|
||
UpdateWorkflowStep(WorkflowStep::WaitingDetectionComplete);
|
||
|
||
// 轮询地址1,等待检测完成
|
||
const int maxRetries = 100; // 最多等待10秒
|
||
for (int i = 0; i < maxRetries && !m_workflowShouldStop; ++i) {
|
||
uint16_t status = 0;
|
||
if (!ReadModbusRegister(1, status)) {
|
||
SendStatusMessage("读取检测状态失败");
|
||
return false;
|
||
}
|
||
|
||
if (status == 1) {
|
||
SendStatusMessage("检测完成(正常)");
|
||
return true;
|
||
} else if (status == 2) {
|
||
SendStatusMessage("检测完成(异常)");
|
||
return false;
|
||
}
|
||
|
||
// 状态为0,继续等待
|
||
std::this_thread::sleep_for(std::chrono::milliseconds(100));
|
||
}
|
||
|
||
SendStatusMessage("等待检测完成超时");
|
||
return false;
|
||
}
|
||
|
||
bool DemoControlPresenter::ExecuteReadingResult()
|
||
{
|
||
UpdateWorkflowStep(WorkflowStep::ReadingResult);
|
||
|
||
// 读取地址2-13的位姿数据(6个float = 12个寄存器)
|
||
std::vector<uint16_t> registers;
|
||
if (!ReadModbusRegisters(2, 12, registers)) {
|
||
SendStatusMessage("读取检测结果失败");
|
||
return false;
|
||
}
|
||
|
||
// 解析float数据
|
||
DetectionResult result;
|
||
result.x = IYModbusTCPClient::RegistersToFloat(registers[0], registers[1]);
|
||
result.y = IYModbusTCPClient::RegistersToFloat(registers[2], registers[3]);
|
||
result.z = IYModbusTCPClient::RegistersToFloat(registers[4], registers[5]);
|
||
result.roll = IYModbusTCPClient::RegistersToFloat(registers[6], registers[7]);
|
||
result.pitch = IYModbusTCPClient::RegistersToFloat(registers[8], registers[9]);
|
||
result.yaw = IYModbusTCPClient::RegistersToFloat(registers[10], registers[11]);
|
||
result.valid = true;
|
||
|
||
{
|
||
std::lock_guard<std::mutex> lock(m_resultMutex);
|
||
m_lastResult = result;
|
||
}
|
||
|
||
emit detectionResultUpdated(result);
|
||
|
||
SendStatusMessage(QString("检测结果: X=%1, Y=%2, Z=%3, Roll=%4, Pitch=%5, Yaw=%6")
|
||
.arg(result.x, 0, 'f', 2).arg(result.y, 0, 'f', 2).arg(result.z, 0, 'f', 2)
|
||
.arg(result.roll, 0, 'f', 2).arg(result.pitch, 0, 'f', 2).arg(result.yaw, 0, 'f', 2));
|
||
|
||
return true;
|
||
}
|
||
|
||
bool DemoControlPresenter::ExecuteMovingToGrasp()
|
||
{
|
||
UpdateWorkflowStep(WorkflowStep::MovingToGrasp);
|
||
|
||
DetectionResult result;
|
||
{
|
||
std::lock_guard<std::mutex> lock(m_resultMutex);
|
||
result = m_lastResult;
|
||
}
|
||
|
||
if (!result.valid) {
|
||
SendStatusMessage("检测结果无效");
|
||
return false;
|
||
}
|
||
|
||
// 第一步:移动到目标位置上方(安全高度)
|
||
SendStatusMessage("移动到抓取位置上方...");
|
||
errno_t ret = m_robot->MoveJByPose(
|
||
result.x, result.y, result.z,
|
||
result.roll, result.pitch, result.yaw,
|
||
static_cast<float>(m_velocity), static_cast<float>(m_acceleration), -1.0f,
|
||
m_toolNumber, 0
|
||
);
|
||
|
||
if (ret != 0) {
|
||
SendStatusMessage(QString("移动到抓取位置上方失败: 错误码 %1").arg(ret));
|
||
return false;
|
||
}
|
||
|
||
SendStatusMessage("已到达抓取位置上方,准备下降...");
|
||
|
||
// 第二步:下降到抓取位置(加上Z轴偏移)
|
||
ret = m_robot->MoveJByPose(
|
||
result.x, result.y, result.z + m_graspOffsetZ,
|
||
result.roll, result.pitch, result.yaw,
|
||
static_cast<float>(m_velocity), static_cast<float>(m_acceleration), -1.0f,
|
||
m_toolNumber, 0
|
||
);
|
||
|
||
if (ret != 0) {
|
||
SendStatusMessage(QString("下降到抓取位置失败: 错误码 %1").arg(ret));
|
||
return false;
|
||
}
|
||
|
||
SendStatusMessage("已到达抓取位置");
|
||
return true;
|
||
}
|
||
|
||
bool DemoControlPresenter::ExecuteGrasping()
|
||
{
|
||
UpdateWorkflowStep(WorkflowStep::Grasping);
|
||
|
||
// 这里可以添加夹爪控制逻辑
|
||
// 目前仅模拟等待
|
||
std::this_thread::sleep_for(std::chrono::milliseconds(500));
|
||
|
||
SendStatusMessage("抓取完成");
|
||
return true;
|
||
}
|
||
|
||
bool DemoControlPresenter::ExecuteMovingToPlace()
|
||
{
|
||
UpdateWorkflowStep(WorkflowStep::MovingToPlace);
|
||
|
||
DetectionResult result;
|
||
{
|
||
std::lock_guard<std::mutex> lock(m_resultMutex);
|
||
result = m_lastResult;
|
||
}
|
||
|
||
if (!result.valid) {
|
||
SendStatusMessage("检测结果无效");
|
||
return false;
|
||
}
|
||
|
||
// 第一步:从抓取位置抬起到安全高度
|
||
SendStatusMessage("从抓取位置抬起...");
|
||
errno_t ret = m_robot->MoveJByPose(
|
||
result.x, result.y, result.z,
|
||
result.roll, result.pitch, result.yaw,
|
||
static_cast<float>(m_velocity), static_cast<float>(m_acceleration), -1.0f,
|
||
m_toolNumber, 0
|
||
);
|
||
|
||
if (ret != 0) {
|
||
SendStatusMessage(QString("抬起失败: 错误码 %1").arg(ret));
|
||
return false;
|
||
}
|
||
|
||
SendStatusMessage("已抬起到安全高度,准备移动到放置位置上方...");
|
||
|
||
// 第二步:移动到放置位置上方(安全高度)
|
||
ret = m_robot->MoveJByPose(
|
||
m_placePosition.x, m_placePosition.y, m_placePosition.z - m_graspOffsetZ,
|
||
m_placePosition.rx, m_placePosition.ry, m_placePosition.rz,
|
||
static_cast<float>(m_velocity), static_cast<float>(m_acceleration), -1.0f,
|
||
m_toolNumber, 0
|
||
);
|
||
|
||
if (ret != 0) {
|
||
SendStatusMessage(QString("移动到放置位置上方失败: 错误码 %1").arg(ret));
|
||
return false;
|
||
}
|
||
|
||
SendStatusMessage("已到达放置位置上方,准备下降...");
|
||
|
||
// 第三步:下降到放置位置
|
||
ret = m_robot->MoveJByPose(
|
||
m_placePosition.x, m_placePosition.y, m_placePosition.z,
|
||
m_placePosition.rx, m_placePosition.ry, m_placePosition.rz,
|
||
static_cast<float>(m_velocity), static_cast<float>(m_acceleration), -1.0f,
|
||
m_toolNumber, 0
|
||
);
|
||
|
||
if (ret != 0) {
|
||
SendStatusMessage(QString("下降到放置位置失败: 错误码 %1").arg(ret));
|
||
return false;
|
||
}
|
||
|
||
SendStatusMessage("已到达放置位置");
|
||
return true;
|
||
}
|
||
|
||
bool DemoControlPresenter::ExecutePlacing()
|
||
{
|
||
UpdateWorkflowStep(WorkflowStep::Placing);
|
||
|
||
// 这里可以添加夹爪释放逻辑
|
||
// 目前仅模拟等待
|
||
std::this_thread::sleep_for(std::chrono::milliseconds(500));
|
||
|
||
SendStatusMessage("放置完成");
|
||
return true;
|
||
}
|
||
|
||
void DemoControlPresenter::UpdateWorkflowStep(WorkflowStep step, const QString& message)
|
||
{
|
||
{
|
||
std::lock_guard<std::mutex> lock(m_stepMutex);
|
||
m_currentStep = step;
|
||
}
|
||
|
||
QString msg = message.isEmpty() ? WorkflowStepToString(step) : message;
|
||
emit workflowStepChanged(step, msg);
|
||
SendStatusMessage(msg);
|
||
}
|
||
|
||
void DemoControlPresenter::SendStatusMessage(const QString& message)
|
||
{
|
||
emit statusMessageUpdated(message);
|
||
}
|
||
|
||
bool DemoControlPresenter::ReadModbusRegister(int address, uint16_t& value)
|
||
{
|
||
if (!m_modbusClient || !m_controllerConnected) {
|
||
return false;
|
||
}
|
||
|
||
std::vector<uint16_t> values;
|
||
auto result = m_modbusClient->ReadHoldingRegisters(address, 1, values);
|
||
if (result != IYModbusTCPClient::SUCCESS || values.empty()) {
|
||
return false;
|
||
}
|
||
|
||
value = values[0];
|
||
return true;
|
||
}
|
||
|
||
bool DemoControlPresenter::WriteModbusRegister(int address, uint16_t value)
|
||
{
|
||
if (!m_modbusClient || !m_controllerConnected) {
|
||
return false;
|
||
}
|
||
|
||
auto result = m_modbusClient->WriteSingleRegister(address, value);
|
||
return (result == IYModbusTCPClient::SUCCESS);
|
||
}
|
||
|
||
bool DemoControlPresenter::ReadModbusRegisters(int startAddress, int quantity, std::vector<uint16_t>& values)
|
||
{
|
||
if (!m_modbusClient || !m_controllerConnected) {
|
||
return false;
|
||
}
|
||
|
||
auto result = m_modbusClient->ReadHoldingRegisters(startAddress, quantity, values);
|
||
return (result == IYModbusTCPClient::SUCCESS);
|
||
}
|