增加通讯协议

This commit is contained in:
xu
2026-10-14 09:59:42 +08:00
parent 32878a9a80
commit 950e9e6c9e
102 changed files with 5538 additions and 2679 deletions
+74 -58
View File
@@ -1,13 +1,14 @@
#include "arm.h"
#include "titlebar.h"
#include "statusstrip.h"
#include "alarmbanner.h"
#include "datacard.h"
#include "udpcommunication.h"
#include "car.h"
#include "confirmdialog.h"
#include <QVBoxLayout>
#include <QHBoxLayout>
#include <QGridLayout>
//#include <QGridLayout> // 末端按钮原为 2×3 网格,改为竖列后暂不需要
#include <QPushButton>
#include <QLabel>
#include <QTimer>
@@ -34,8 +35,8 @@ ArmPage::ArmPage(AppContext* ctx, QWidget* parent)
// 左控制列(6 运动按钮 + 系统回位/暂停)
QWidget* left = new QWidget(this);
QVBoxLayout* leftLay = new QVBoxLayout(left);
leftLay->setContentsMargins(0, 0, 0, 0);
leftLay->setSpacing(8);
leftLay->setContentsMargins(10,10,20,10);
leftLay->setSpacing(30);
auto addMove = [&](const QString& t, const QString& axis, int dir) {
QPushButton* b = makeMoveButton(t, axis, dir);
@@ -49,11 +50,14 @@ ArmPage::ArmPage(AppContext* ctx, QWidget* parent)
addMove("前平移", "y", +1);
addMove("后平移", "y", -1);
m_returnBtn = button("系统回位/暂停", "", left);
m_returnBtn = button("系统回位/\n暂停", "", left);
m_returnBtn->setCheckable(true);
m_returnBtn->setFixedSize(180, 90);
m_returnBtn->setStyleSheet(QString("font-size:22px;background-color:%1;color:%2;border:1px solid %3;border-radius:12px;")
.arg(C::PANEL_HI, C::TEXT, C::BORDER));
m_returnBtn->setFixedSize(270, 120); // 两行文字,故加高
m_returnBtn->setStyleSheet(QString(
"QPushButton{font-size:40px;background-color:%1;color:%2;border:1px solid %3;border-radius:12px;}"
"QPushButton:hover,QPushButton:focus,QPushButton:checked"
"{background-color:%4;color:#FFFFFF;border:2px solid #8ABFFF;}")
.arg(C::PANEL_HI, C::TEXT, C::BORDER, C::PRIMARY));
connect(m_returnBtn, &QPushButton::toggled, this, &ArmPage::onReturnToggled);
leftLay->addWidget(m_returnBtn);
@@ -63,69 +67,72 @@ ArmPage::ArmPage(AppContext* ctx, QWidget* parent)
leftLay->addWidget(m_returnStatus);
leftLay->addStretch(1);
left->setFixedWidth(180);
left->setFixedWidth(300); // 270 按钮 + 左右边距 30,避免按钮被裁
main->addWidget(left);
// 中央卡片区(底盘/洗消/气体检测仪)
// 中央区:左侧三张状态卡 + 机械臂参数卡,并排放在中间
QWidget* center = new QWidget(this);
QVBoxLayout* centerLay = new QVBoxLayout(center);
QHBoxLayout* centerLay = new QHBoxLayout(center);
centerLay->setContentsMargins(0, 0, 0, 0);
centerLay->setSpacing(12);
m_chassisCard = new DataCard("底盘", center);
m_chassisCard->addField("电量", "85%");
m_chassisCard->addField("电压", "360V");
m_chassisCard->addField("故障", "无");
QWidget* cardsCol = new QWidget(center);
QVBoxLayout* cardsLay = new QVBoxLayout(cardsCol);
cardsLay->setContentsMargins(0, 0, 0, 0);
cardsLay->setSpacing(12);
m_washCard = new DataCard("洗消", center);
m_washCard->addField("A液位", "100L");
m_washCard->addField("泡沫液位", "30L");
m_chassisCard = new DataCard("底盘", cardsCol);
m_chassisCard->addField("底盘电量SOC", "85%");
m_chassisCard->addField("底盘电压", "360V");
m_chassisCard->addField("底盘故障", "无");
m_gasCard = new DataCard("气体检测仪", center);
m_gasCard->addField("主机状态", "待机");
m_gasCard->addField("浓度", "0 ppb");
m_washCard = new DataCard("洗消", cardsCol);
m_washCard->addField("A组分/清水液位", "100L");
m_washCard->addField("泡沫箱液位", "30L");
centerLay->addWidget(m_chassisCard, 1);
centerLay->addWidget(m_washCard, 1);
centerLay->addWidget(m_gasCard, 1);
m_gasCard = new DataCard("气体检测仪", cardsCol);
m_gasCard->addField("主机状态", "点火状态");
m_gasCard->addField("有毒物种类", "S级");
m_gasCard->addField("有毒物等级", "二级");
cardsLay->addWidget(m_chassisCard, 1);
cardsLay->addWidget(m_washCard, 1);
cardsLay->addWidget(m_gasCard, 1);
m_armCard = new DataCard("机械臂参数", center);
m_armCard->addField("末端位置", "XYZ");
m_armCard->addField("末端姿态", "RX/RY/RZ");
m_armCard->addField("末端速度", "0");
m_armCard->addField("Joint1关节角", "30°");
m_armCard->addField("Joint2关节角", "20°");
m_armCard->addField("Joint3关节角", "0°");
m_armCard->addField("Joint4关节角", "90°");
m_armCard->addField("Joint5关节角", "45°");
m_armCard->addField("Joint6关节角", "0°");
centerLay->addWidget(cardsCol, 1);
centerLay->addWidget(m_armCard, 1);
main->addWidget(center, 1);
// 右参数区(机械臂参数卡 + 末端按钮列)
// 右控制列(末端 6 姿态按钮,与左侧按钮列对称)
QWidget* right = new QWidget(this);
QVBoxLayout* rightLay = new QVBoxLayout(right);
rightLay->setContentsMargins(0, 0, 0, 0);
rightLay->setSpacing(12);
rightLay->setContentsMargins(10, 20, 20, 20);
rightLay->setSpacing(15);
m_armCard = new DataCard("机械臂参数", right);
m_armCard->addField("末端位置", "XYZ");
m_armCard->addField("姿态", "RX/RY/RZ");
m_armCard->addField("速度", "0");
m_armCard->addField("J1", "30°");
m_armCard->addField("J2", "20°");
m_armCard->addField("J3", "0°");
m_armCard->addField("J4", "90°");
m_armCard->addField("J5", "45°");
m_armCard->addField("J6", "0°");
rightLay->addWidget(m_armCard, 1);
// 末端 6 姿态按钮(2 列 × 3 行)
QGridLayout* endGrid = new QGridLayout();
endGrid->setSpacing(8);
auto addEnd = [&](const QString& t, const QString& axis, int dir, int r, int c) {
auto addEnd = [&](const QString& t, const QString& axis, int dir) {
QPushButton* b = makeMoveButton(t, axis, dir);
b->setFixedHeight(80);
m_endButtons << b;
endGrid->addWidget(b, r, c);
rightLay->addWidget(b);
};
addEnd("末端仰", "pitch", +1, 0, 0);
addEnd("末端俯", "pitch", -1, 0, 1);
addEnd("末端正偏航", "yaw", +1, 1, 0);
addEnd("末端负偏航", "yaw", -1, 1, 1);
addEnd("末端左横滚", "roll", -1, 2, 0);
addEnd("末端右横滚", "roll", +1, 2, 1);
rightLay->addLayout(endGrid);
addEnd("末端仰", "pitch", +1);
addEnd("末端俯", "pitch", -1);
addEnd("末端正偏航", "yaw", +1);
addEnd("末端负偏航", "yaw", -1);
addEnd("末端左横滚", "roll", -1);
addEnd("末端右横滚", "roll", +1);
right->setFixedWidth(430);
right->setFixedWidth(300); // 与左列同宽,按钮 270 不被裁
main->addWidget(right);
root->addLayout(main, 1);
@@ -141,9 +148,10 @@ ArmPage::ArmPage(AppContext* ctx, QWidget* parent)
m_returnStatus->setText("");
});
connect(ctx->comm(), &UdpCommunication::telemetryUpdated, this, &ArmPage::refresh);
connect(ctx->comm(), &CarCommunication::telemetryUpdated, this, &ArmPage::refresh);
connect(ctx, &AppContext::modeChanged, this, [this](Mode) { updateModeGating(); });
connect(ctx, &AppContext::estopChanged, this, [this](bool) { updateModeGating(); });
connect(ctx, &AppContext::rcDrivingChanged, this, [this](bool) { updateModeGating(); });
updateModeGating();
refresh();
}
@@ -151,10 +159,17 @@ ArmPage::ArmPage(AppContext* ctx, QWidget* parent)
QPushButton* ArmPage::makeMoveButton(const QString& text, const QString& axis, int dir)
{
QPushButton* b = button(text, "", this);
b->setFixedSize(180, 90);
b->setStyleSheet(QString("font-size:24px;background-color:%1;color:%2;border:1px solid %3;border-radius:12px;")
.arg(C::PANEL_HI, C::TEXT, C::BORDER));
b->setFixedSize(270, 76);
b->setStyleSheet(QString(
"QPushButton{font-size:45px;background-color:%1;color:%2;border:1px solid %3;border-radius:12px;}"
"QPushButton:hover,QPushButton:focus,QPushButton:pressed"
"{background-color:%4;color:#FFFFFF;border:2px solid #8ABFFF;}")
.arg(C::PANEL_HI, C::TEXT, C::BORDER, C::PRIMARY));
connect(b, &QPushButton::pressed, this, [this, axis, dir]() {
if (ctx()->rcDriving()) {
ConfirmDialog::toast(this, "遥控器操作中");
return;
}
if (ctx()->mode != Mode::Arm) {
ConfirmDialog::toast(this, "请切换至机械臂模式");
return;
@@ -169,7 +184,8 @@ QPushButton* ArmPage::makeMoveButton(const QString& text, const QString& axis, i
void ArmPage::updateModeGating()
{
bool arm = (ctx()->mode == Mode::Arm) && !ctx()->estopTriggered;
// 非机械臂模式、急停触发或遥控器正在操作时禁用动作按钮(遥控器优先)
bool arm = (ctx()->mode == Mode::Arm) && !ctx()->estopTriggered && !ctx()->rcDriving();
for (QPushButton* b : m_moveButtons) b->setEnabled(arm);
for (QPushButton* b : m_endButtons) b->setEnabled(arm);
}