diff --git a/HPPA/HPPA.cpp b/HPPA/HPPA.cpp
index 19b0aa8..67b7fa5 100644
--- a/HPPA/HPPA.cpp
+++ b/HPPA/HPPA.cpp
@@ -292,6 +292,14 @@ HPPA::HPPA(QWidget *parent)
connect(pc, &PowerControl::powerOpened, this, &HPPA::newMotor);
connect(pc, &PowerControl::powerClosed, this, &HPPA::deleteMotor);
+ //机械臂控制
+ RobotArmControl* rac = new RobotArmControl();
+ QDockWidget* dock_rac = new QDockWidget(QString::fromLocal8Bit("机械臂控制"), this);
+ dock_rac->setAllowedAreas(Qt::LeftDockWidgetArea | Qt::RightDockWidgetArea);
+ dock_rac->setWidget(rac);
+ tabifyDockWidget(dock_adt, dock_rac);
+ mPanelMenu->addAction(dock_rac->toggleViewAction());
+
createActionGroups();
connect(mImagerGroup, &QActionGroup::triggered, this, &HPPA::selectingImager);
@@ -796,7 +804,7 @@ void HPPA::timerEvent(QTimerEvent *event)
{
if (m_xMotor == nullptr || m_yMotor == nullptr)
{
- qDebug() << "Motor pointer is null!!!!!";
+ //qDebug() << "Motor pointer is null!!!!!";
xmotor_state_label1->setStyleSheet("QLabel{background-color:rgb(255,0,0);}");
SetXMotorWidgetEnable(false);
diff --git a/HPPA/HPPA.h b/HPPA/HPPA.h
index 82554f7..3f6d56b 100644
--- a/HPPA/HPPA.h
+++ b/HPPA/HPPA.h
@@ -33,6 +33,7 @@
#include "adjustTable.h"
#include "PowerControl.h"
#include "PathPlan.h"
+#include "RobotArmControl.h"
#include "hppaConfigFile.h"
#include "path_tc.h"
diff --git a/HPPA/HPPA.ui b/HPPA/HPPA.ui
index f245af2..341a2e3 100644
--- a/HPPA/HPPA.ui
+++ b/HPPA/HPPA.ui
@@ -6,8 +6,8 @@
0
0
- 1120
- 675
+ 1318
+ 882
@@ -46,7 +46,7 @@
- 1
+ 0
@@ -84,7 +84,7 @@
0
0
- 1120
+ 1318
30
diff --git a/HPPA/HPPA.vcxproj b/HPPA/HPPA.vcxproj
index 4c3f7cb..c70716c 100644
--- a/HPPA/HPPA.vcxproj
+++ b/HPPA/HPPA.vcxproj
@@ -86,7 +86,7 @@
MultiThreadedDebugDLL
- Windows
+ Console
true
@@ -116,6 +116,7 @@
+
Create
Create
@@ -139,6 +140,7 @@
+
@@ -153,6 +155,7 @@
+
diff --git a/HPPA/HPPA.vcxproj.filters b/HPPA/HPPA.vcxproj.filters
index 64429d0..1b7ece5 100644
--- a/HPPA/HPPA.vcxproj.filters
+++ b/HPPA/HPPA.vcxproj.filters
@@ -106,6 +106,9 @@
Source Files
+
+ Source Files
+
@@ -153,6 +156,9 @@
Header Files
+
+ Header Files
+
@@ -196,6 +202,9 @@
Form Files
+
+ Form Files
+
diff --git a/HPPA/RobotArmControl.cpp b/HPPA/RobotArmControl.cpp
new file mode 100644
index 0000000..85d5689
--- /dev/null
+++ b/HPPA/RobotArmControl.cpp
@@ -0,0 +1,427 @@
+#include "RobotArmControl.h"
+
+RobotArmControl::RobotArmControl(QWidget* parent): QDialog(parent)
+{
+ ui.setupUi(this);
+ robotController = new RobotController(this);
+ connect(robotController, SIGNAL(commandResponse(bool, const QJsonObject)), this, SLOT(onCommandResponse(bool, const QJsonObject)));
+
+
+ connect(ui.get_task_list_btn, SIGNAL(clicked()), this, SLOT(getTaskList()));
+ connect(ui.get_pose_btn, SIGNAL(clicked()), this, SLOT(getPose()));
+ connect(ui.connect2arm_btn, SIGNAL(clicked()), this, SLOT(connectRobotArm()));
+
+ connect(ui.execute_task_btn, SIGNAL(clicked()), this, SLOT(executeTask()));
+ connect(ui.pause_task_btn, SIGNAL(clicked()), this, SLOT(pauseTask()));
+ connect(ui.continue_task_btn, SIGNAL(clicked()), this, SLOT(continueTask()));
+
+ robotMonitor = new EC8056;
+ connect(robotMonitor, &EC8056::dataReceived, this, &RobotArmControl::monitorRobotArm);
+
+
+ m_pModel = new QStringListModel(ui.taskList_listView);
+
+ //将字符串列表模型设置到树形视图上
+ ui.taskList_listView->setModel(m_pModel);
+}
+
+RobotArmControl::~RobotArmControl()
+{
+
+}
+
+void RobotArmControl::monitorRobotArm(const ECData& data)
+{
+ double x = data.machinePose[0];
+ double y = data.machinePose[1];
+ double z = data.machinePose[2];
+
+ ui.pose_x_label->setText(QString::number(x));
+ ui.pose_y_label->setText(QString::number(y));
+ ui.pose_z_label->setText(QString::number(z));
+}
+
+void RobotArmControl::onCommandResponse(bool success, const QJsonObject& response)
+{
+ if (success)
+ {
+ QString re;
+ if (response.contains("result"))
+ {
+ re = response["result"].toVariant().toString();
+ ui.textEdit->append("Result: " + re);
+ }
+ else if (response.contains("error"))
+ {
+ auto errorStr = response["error"].toObject()["message"].toString();
+
+ ui.textEdit->append("Error: " + errorStr);
+ }
+ }
+}
+
+void RobotArmControl::getTaskList()
+{
+ QString pythonScript = "D:\\PycharmProjects\\ELITE_ROBOTS\\get_jbi_filename.py";
+
+ QProcess process;
+
+ process.start("C:\\ProgramData\\anaconda3\\python.exe", QStringList() << pythonScript);
+ process.waitForFinished();
+ QString output = process.readAllStandardOutput();
+
+ QStringList files;
+ //files.append("tc20250324down.jbi");
+ //files.append("tc20250324circle.jbi");
+ //files.append("tc20250324side.jbi");
+ QStringList lines = output.split('\n', QString::SkipEmptyParts);
+ for (const QString& line : lines)
+ {
+ files.append(line.trimmed());
+ }
+
+ ////先清除数据,然后添加数据
+ //for (size_t i = 0; i < files.length(); i++)
+ //{
+ // int row = m_pModel->rowCount();
+ // m_pModel->insertRow(row);
+ // QModelIndex index = m_pModel->index(row);
+ // m_pModel->setData(index, files[i]);
+ //}
+
+ m_pModel->setStringList(files);
+}
+
+void RobotArmControl::getPose()
+{
+ robotController->getRobotPose();
+}
+
+void RobotArmControl::connectRobotArm()
+{
+ bool re = robotController->connectToRobot("192.168.1.100");
+ robotMonitor->connectToHost("192.168.1.100");
+}
+
+void RobotArmControl::executeTask()
+{
+ QModelIndex index = ui.taskList_listView->currentIndex();
+ if (-1 == index.row())
+ {
+ //弹窗提示用户选择文件
+ ui.textEdit->append("Please select file on the left!");
+ return;
+ }
+ QString fileName = index.data(Qt::DisplayRole).toString();
+
+ robotController->runJbi(fileName);
+}
+
+void RobotArmControl::pauseTask()
+{
+ robotController->pauseTask();
+}
+
+void RobotArmControl::continueTask()
+{
+ robotController->continueTask();
+}
+
+
+
+
+
+
+RobotController::RobotController(QObject* parent) : QObject(parent), socket(new QTcpSocket(this))
+{
+ connect(socket, &QTcpSocket::readyRead, this, &RobotController::onReadyRead);
+
+ timer = new QTimer(this);
+ connect(timer, SIGNAL(timeout()), this, SLOT(getPoint()));
+}
+
+RobotController::~RobotController()
+{
+ disconnectFromRobot();
+}
+
+bool RobotController::connectToRobot(const QString& ip, quint16 port)
+{
+ socket->setProxy(QNetworkProxy::NoProxy);
+
+ socket->connectToHost(ip, port);
+
+ if (!socket->waitForConnected(3000)) {
+ qDebug() << "Connection failed:" << socket->errorString();
+ return false;
+ }
+ qDebug() << "Connected successfully!";
+
+ return true;
+
+}
+
+void RobotController::disconnectFromRobot()
+{
+ if (socket->isOpen())
+ {
+ socket->close();
+ }
+}
+
+void RobotController::getPoint()
+{
+ getJbiState();
+ getCurrentJobLine();
+}
+
+void RobotController::sendCommand(const QString& cmd, const QJsonValue& params, int id)
+{
+ QJsonObject request;
+ request["method"] = cmd;
+ request["params"] = params;
+ request["jsonrpc"] = "2.0";
+ request["id"] = id;
+
+ QJsonDocument doc(request);
+ QByteArray data = doc.toJson(QJsonDocument::Compact) + "\n";
+ qDebug() << "send command:" << data.constData();
+
+ socket->write(data);
+}
+
+void RobotController::onReadyRead()
+{
+ QByteArray data = socket->readAll();
+ QJsonDocument doc = QJsonDocument::fromJson(data);
+ if (!doc.isNull() && doc.isObject())
+ {
+ QJsonObject response = doc.object();
+ //qDebug() << "Received all:" << response;
+
+ if (response.contains("result"))
+ {
+ //qDebug() << "Received result:" << response["result"].toVariant();
+ }
+ else if (response.contains("error"))
+ {
+ //qDebug() << "Received error:" << response["error"];
+ }
+
+ emit commandResponse(true, doc.object());
+ }
+ else
+ {
+ emit commandResponse(false, QJsonObject());
+ }
+}
+
+void RobotController::getRobotPose()
+{
+ sendCommand("getRobotPose");
+}
+
+void RobotController::getRobotState()
+{
+ sendCommand("getRobotState");
+}
+
+void RobotController::getJbiState()
+{
+ sendCommand("getJbiState");
+}
+
+void RobotController::getCurrentJobLine()
+{
+ sendCommand("getCurrentJobLine");
+}
+
+void RobotController::getRobotMode()
+{
+ sendCommand("getRobotMode");
+}
+
+void RobotController::runJbi(const QString& jbiFilename)
+{
+ QJsonObject paramsRunJbi;
+ paramsRunJbi["filename"] = jbiFilename;//使用对象结构
+
+ QJsonObject params_set_servo_status;
+ params_set_servo_status["status"] = 1;//使用对象结构
+
+ //sendCommand("checkJbiExist", paramsRunJbi);
+ sendCommand("set_servo_status", params_set_servo_status);
+ sendCommand("runJbi", paramsRunJbi);
+
+ //timer->start(1000);
+}
+
+void RobotController::pauseTask()
+{
+ sendCommand("pause");
+}
+
+void RobotController::run()
+{
+ sendCommand("run");
+}
+
+void RobotController::continueTask()
+{
+ sendCommand("run");
+}
+
+void RobotController::setRobotPowerStatus(int status)
+{
+ sendCommand("set_robot_power_status", QJsonArray{ status });
+}
+
+
+
+
+
+
+
+
+EC8056::EC8056(QObject* parent) : QObject(parent), socket(new QTcpSocket(this))
+{
+ connect(socket, &QTcpSocket::readyRead, this, &EC8056::onReadyRead);
+ /*connect(socket, QOverload::of(&QTcpSocket::errorOccurred),
+ this, &EC8056::onSocketError);*/
+ //connect(socket, SIGNAL(error(QAbstractSocket::SocketError)),
+ // this, SLOT(onSocketError(QAbstractSocket::SocketError)));
+}
+
+void EC8056::connectToHost(const QString& host, quint16 port)
+{
+ socket->setProxy(QNetworkProxy::NoProxy);
+
+ socket->connectToHost(QHostAddress(host), port);
+
+ if (!socket->waitForConnected(3000)) {
+ qDebug() << "Connection failed:" << socket->errorString();
+ return;
+ }
+ qDebug() << "Connected successfully!";
+}
+
+quint8 EC8056::readUInt8(const QByteArray& buf, int& offset)
+{
+ return static_cast(buf[offset++]);
+}
+
+quint32 EC8056::readUInt32(const QByteArray& buf, int& offset)
+{
+ quint32 val;
+ memcpy(&val, buf.constData() + offset, sizeof(val));
+ offset += sizeof(val);
+ return qFromBigEndian(val);
+}
+
+qint32 EC8056::readInt32(const QByteArray& buf, int& offset)
+{
+ qint32 val;
+ memcpy(&val, buf.constData() + offset, sizeof(val));
+ offset += sizeof(val);
+ return qFromBigEndian(val);
+}
+
+quint64 EC8056::readUInt64(const QByteArray& buf, int& offset)
+{
+ quint64 val;
+ memcpy(&val, buf.constData() + offset, sizeof(val));
+ offset += sizeof(val);
+ return qFromBigEndian(val);
+}
+
+double EC8056::readDouble(const QByteArray& buf, int& offset)
+{
+ QByteArray b = buf.mid(offset, sizeof(double));
+ offset += sizeof(double);
+ if (QSysInfo::ByteOrder == QSysInfo::LittleEndian)
+ std::reverse(b.begin(), b.end());
+
+ double val;
+ memcpy(&val, b.constData(), sizeof(double));
+ return val;
+}
+
+void EC8056::onReadyRead()
+{
+ buffer.append(socket->readAll());
+
+ if (buffer.size() < 1024)
+ return;
+
+ int offset = 0;
+ ECData data;
+
+ data.msgSize = readUInt32(buffer, offset);
+ offset = 1020;
+ data.matchingWord = readUInt32(buffer, offset);
+
+ if ((data.msgSize == 1024)/* && (data.matchingWord == 3967833836)*/)
+ {
+ offset = 0;
+
+ data.msgSize = readUInt32(buffer, offset);
+ data.timeStamp = readUInt64(buffer, offset);
+ data.auto_cycle = readUInt8(buffer, offset);
+
+ for (int i = 0; i < 8; ++i) data.machinePos[i] = readDouble(buffer, offset);
+ for (int i = 0; i < 6; ++i) data.machinePose[i] = readDouble(buffer, offset);
+ for (int i = 0; i < 6; ++i) data.machineUserPose[i] = readDouble(buffer, offset);
+ for (int i = 0; i < 8; ++i) data.torque[i] = readDouble(buffer, offset);
+
+ data.robotState = readUInt32(buffer, offset);
+ data.servoReady = readUInt32(buffer, offset);
+ data.can_motor_run = readUInt32(buffer, offset);
+
+ for (int i = 0; i < 8; ++i) data.motor_speed[i] = readInt32(buffer, offset);
+
+ data.robotMode = readUInt32(buffer, offset);
+
+ for (int i = 0; i < 3; ++i) data.analog_ioInput[i] = readDouble(buffer, offset);
+ for (int i = 0; i < 5; ++i) data.analog_ioOutput[i] = readDouble(buffer, offset);
+
+ data.digital_ioInput = readUInt64(buffer, offset);
+ data.digital_ioOutput = readUInt64(buffer, offset);
+
+ data.collision = readUInt8(buffer, offset);
+
+ for (int i = 0; i < 6; ++i) data.machineFlangePose[i] = readDouble(buffer, offset);
+ for (int i = 0; i < 6; ++i) data.machineUserFlangePose[i] = readDouble(buffer, offset);
+
+ data.emergencyStopState = readUInt8(buffer, offset);
+ data.tcpSpeed = readDouble(buffer, offset);
+ for (int i = 0; i < 8; ++i) data.joIntSpeed[i] = readDouble(buffer, offset);
+ data.tcpAcc = readDouble(buffer, offset);
+ for (int i = 0; i < 8; ++i) data.joIntAcc[i] = readDouble(buffer, offset);
+ for (int i = 0; i < 6; ++i) data.joIntTemperature[i] = readDouble(buffer, offset);
+ for (int i = 0; i < 6; ++i) data.joIntTorque[i] = readDouble(buffer, offset);
+ for (int i = 0; i < 6; ++i) data.extJoIntTorques[i] = readDouble(buffer, offset);
+ for (int i = 0; i < 6; ++i) data.exTcpForceIntool[i] = readDouble(buffer, offset);
+
+ data.dragState = readUInt8(buffer, offset);
+ data.sensor_connected_state = readUInt8(buffer, offset);
+ data.reserved = readUInt8(buffer, offset);
+ data.matchingWord = readUInt32(buffer, offset);
+
+ /*if (data.msgSize != 1024 || data.matchingWord != 0xec8056ec) {
+ buffer.clear();
+ emit errorOccurred("Invalid packet received");
+ return;
+ }*/
+
+ emit dataReceived(data);
+ }
+
+
+ buffer.clear();
+}
+
+void EC8056::onSocketError(QAbstractSocket::SocketError socketError)
+{
+ Q_UNUSED(socketError)
+ emit errorOccurred(socket->errorString());
+}
diff --git a/HPPA/RobotArmControl.h b/HPPA/RobotArmControl.h
new file mode 100644
index 0000000..9548609
--- /dev/null
+++ b/HPPA/RobotArmControl.h
@@ -0,0 +1,152 @@
+#pragma once
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include "ui_RobotArmControl.h"
+
+
+struct ECData
+{
+ quint32 msgSize;
+ quint64 timeStamp;
+ quint8 auto_cycle;
+ double machinePos[8];//关节坐标
+ double machinePose[6];//基座坐标
+ double machineUserPose[6];//用户坐标
+ double torque[8];//关节额定力矩百分比
+ quint32 robotState;//机器人状态
+ quint32 servoReady;//伺服使能状态
+ quint32 can_motor_run;//同步状态
+ qint32 motor_speed[8];//各轴电机转速
+ quint32 robotMode;//机器人模式
+ double analog_ioInput[3];//模拟量输入口数据
+ double analog_ioOutput[5];//模拟量输出口数据
+ quint64 digital_ioInput;//数字量输入口数据的二进制形式
+ quint64 digital_ioOutput;//数字量输出口数据的二进制形式
+ quint8 collision;//碰撞报警状态
+ double machineFlangePose[6];//基座坐标系下的法兰盘中心位姿
+ double machineUserFlangePose[6];//用户坐标系下的法兰盘中心位姿
+ quint8 emergencyStopState;//当前是否处于急停状态
+ double tcpSpeed;//tcp运动速度
+ double joIntSpeed[8];//关节运动下各关节运动速度
+ double tcpAcc;//tcp加速度
+ double joIntAcc[8];//关节运动下各关节加速度
+ double joIntTemperature[6];//温度
+ double joIntTorque[6];//输出扭矩
+ double extJoIntTorques[6];//外部关节扭矩值
+ double exTcpForceIntool[6];//当前工具坐标系下的外部末端力/力矩估计值
+ quint8 dragState;//拖动使能状态
+ quint8 sensor_connected_state;//力控传感器连接状态
+ quint8 reserved;
+ quint32 matchingWord;
+};
+
+class EC8056 : public QObject
+{
+ Q_OBJECT
+
+public:
+ explicit EC8056(QObject* parent = nullptr);
+ void connectToHost(const QString& host, quint16 port= 8056);
+
+signals:
+ void dataReceived(const ECData& data);
+ void errorOccurred(const QString& error);
+
+private slots:
+ void onReadyRead();
+ void onSocketError(QAbstractSocket::SocketError socketError);
+
+private:
+ QTcpSocket* socket;
+ QByteArray buffer;
+
+ double readDouble(const QByteArray& buf, int& offset);
+ quint64 readUInt64(const QByteArray& buf, int& offset);
+ quint32 readUInt32(const QByteArray& buf, int& offset);
+ qint32 readInt32(const QByteArray& buf, int& offset);
+ quint8 readUInt8(const QByteArray& buf, int& offset);
+};
+
+class RobotController : public QObject
+{
+ Q_OBJECT
+public:
+ explicit RobotController(QObject* parent = nullptr);
+ ~RobotController();
+
+ bool connectToRobot(const QString& ip, quint16 port = 8055);
+ void disconnectFromRobot();
+ void sendCommand(const QString& cmd, const QJsonValue& params = QJsonArray(), int id = 1);
+
+ void getRobotPose();
+ void getRobotState();//停止状态 0,暂停状态 1,急停状态 2,运行状态 3,报警状态 4,碰撞状态 5
+ void getJbiState();//0 停止状态,1 暂停状态,2 急停状态,3 运行状态,4 错误状态
+ void getCurrentJobLine();
+ void getRobotMode();//示教模式 0,自动模式 1,远程模式 2
+ void runJbi(const QString& jbiFilename);
+ void pauseTask();
+ void run();
+ void continueTask();
+ void setRobotPowerStatus(int status);
+
+signals:
+ void commandResponse(bool success, const QJsonObject& response);
+
+private slots:
+ void onReadyRead();
+ void getPoint();
+
+private:
+ QTcpSocket* socket;
+
+ QTimer* timer;
+};
+
+class RobotArmControl : public QDialog
+{
+ Q_OBJECT
+
+public:
+ RobotArmControl(QWidget* parent = nullptr);
+ ~RobotArmControl();
+ RobotController* robotController;
+
+
+public Q_SLOTS:
+ void onCommandResponse(bool success, const QJsonObject& response);
+ void getTaskList();
+ void getPose();
+
+ void connectRobotArm();
+ void executeTask();
+ void pauseTask();
+ void continueTask();
+
+ void monitorRobotArm(const ECData& data);
+
+signals:
+ //void Opened();
+ //void Closed();
+
+private:
+ Ui::RobotArmControl_UI ui;
+
+ EC8056* robotMonitor;
+ QStringListModel* m_pModel;
+};
diff --git a/HPPA/RobotArmControl.ui b/HPPA/RobotArmControl.ui
new file mode 100644
index 0000000..7b85f7d
--- /dev/null
+++ b/HPPA/RobotArmControl.ui
@@ -0,0 +1,138 @@
+
+
+ RobotArmControl_UI
+
+
+
+ 0
+ 0
+ 424
+ 364
+
+
+
+ Dialog
+
+
+ -
+
+
+ 鏆傚仠浠诲姟
+
+
+
+ -
+
+
+ 杩炴帴鏈烘鑷
+
+
+
+ -
+
+
+ 鎵ц浠诲姟
+
+
+
+ -
+
+
+ 鑾峰彇pose
+
+
+
+ -
+
+
+ 缁х画浠诲姟
+
+
+
+ -
+
+
+ -
+
+
+ QFrame::StyledPanel
+
+
+ QFrame::Raised
+
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
-
+
+
+ 鑾峰彇浠诲姟鍒楄〃
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+ QFrame::StyledPanel
+
+
+ QFrame::Raised
+
+
+
-
+
+
+ z
+
+
+ Qt::AlignCenter
+
+
+
+ -
+
+
+ x
+
+
+ Qt::AlignCenter
+
+
+
+ -
+
+
+ y
+
+
+ Qt::AlignCenter
+
+
+
+
+
+
+
+
+
+
+