#pragma once #include #include #include #include #include #include #include #include #include #include #include "videoframe.h" class QButtonGroup; class QCheckBox; class QComboBox; class QDoubleSpinBox; class QDialog; class QEvent; class QHBoxLayout; class QGridLayout; class QLabel; class QLineEdit; class QProgressBar; class QPushButton; class QResizeEvent; class QSettings; class QSpinBox; class QStackedWidget; class QTableWidget; class QTabWidget; class QTextEdit; class QTimer; class TrendWidget; class RobotClient; class QuicTestServer; class UrdfViewerWidget; class AudioStreamManager; class VideoRenderWidget; class MainWindow : public QMainWindow { Q_OBJECT public: explicit MainWindow(QWidget *parent = nullptr); ~MainWindow() override; protected: bool nativeEvent(const QByteArray &eventType, void *message, long *result) override; void changeEvent(QEvent *event) override; void resizeEvent(QResizeEvent *event) override; private slots: void selectPage(int index); void toggleConnection(); void updateConnection(bool connected, int latencyMs, const QString &detail); void updateTelemetry(const QVariantList &joints, const QVariantMap &pose); void updateSystemStatus(double cpu, double memory, double disk, int devices); void updateSystemInfo(const QVariantMap &info); void updateImage(const QImage &image, const QString &detail); void updateVideoFrame(const QString &cameraId, const VideoFrame &frame, const QString &detail); void updateCameraStreamState(const QString &cameraId, bool running, const QString &detail); void updateCameraRecordingState(bool recording, const QString &detail); void updateAgvState(const QVariantMap &state, const QVariantMap &navigation); void updateAgvInventory(const QStringList &maps, const QVariantList &stations); void handleCommand(const QString &command, bool success, const QString &detail); void appendLog(const QString &level, const QString &message); void toggleQuicServer(); void updateQuicRunning(bool running, quint16 port, const QString &detail); void appendQuicLog(const QString &level, const QString &message); void sendMoveJ(); void sendMoveJPose(); void recordCurrentJointPoint(); void executeSelectedJointPoint(); void startJointPointLoop(); void stopJointPointLoop(const QString &reason = QString()); void advanceJointPointLoop(); void refreshRecordedJointPoints(); void refreshJointFlowTable(); void saveSnapshot(); private: QWidget *createSystemPage(); QWidget *createArmPage(); QWidget *createCameraPage(); QStringList configuredCameraIds() const; void rebuildCameraPreviewGrid(const QStringList &cameraIds); void refreshCameraStreamControls(); QWidget *createAgvPage(); QWidget *createAudioPage(bool speaker); QWidget *createRpcPage(const QString &serviceName); QWidget *createQuicPage(); QWidget *createDiagnosticsPage(); void loadSettings(); void saveSettings(); void loadJointPrograms(QSettings &settings); void saveJointPrograms(QSettings &settings) const; void setControlsEnabled(bool enabled); void updateWindowChrome(); void ensureArmModelLoaded(); QString endpoint() const; RobotClient *m_client = nullptr; AudioStreamManager *m_audioManager = nullptr; QuicTestServer *m_quicServer = nullptr; QStackedWidget *m_pages = nullptr; QButtonGroup *m_navGroup = nullptr; QList m_navButtons; QWidget *m_windowSurface = nullptr; QWidget *m_customTitleBar = nullptr; QLabel *m_titleBarPage = nullptr; QLabel *m_titleBarBuild = nullptr; QPushButton *m_minimizeWindowButton = nullptr; QPushButton *m_maximizeWindowButton = nullptr; QPushButton *m_closeWindowButton = nullptr; QSize m_windowChromeSize; bool m_windowChromeInitialized = false; bool m_windowChromeMaximized = false; bool m_updatingWindowChrome = false; QLineEdit *m_hostEdit = nullptr; QSpinBox *m_portSpin = nullptr; QCheckBox *m_demoCheck = nullptr; QPushButton *m_connectButton = nullptr; QLabel *m_connectionDot = nullptr; QLabel *m_connectionText = nullptr; QLabel *m_latencyLabel = nullptr; QLabel *m_pageTitle = nullptr; QLabel *m_pageSubtitle = nullptr; QHBoxLayout *m_headerLayout = nullptr; QWidget *m_armHeaderControls = nullptr; QLabel *m_sidebarEndpointValue = nullptr; QLabel *m_sidebarQuicValue = nullptr; QLabel *m_bottomLogLevel = nullptr; QLabel *m_bottomLogMessage = nullptr; QLabel *m_bottomVersion = nullptr; QLabel *m_cpuValue = nullptr; QLabel *m_memoryValue = nullptr; QLabel *m_diskValue = nullptr; QLabel *m_deviceValue = nullptr; QLabel *m_systemNameValue = nullptr; QLabel *m_systemVersionValue = nullptr; QLabel *m_systemOsValue = nullptr; QLineEdit *m_systemTargetEdit = nullptr; QPushButton *m_systemRefreshButton = nullptr; QPushButton *m_systemStopButton = nullptr; QLineEdit *m_armIdEdit = nullptr; QComboBox *m_armSideCombo = nullptr; QPushButton *m_armTelemetryButton = nullptr; QPushButton *m_armGlobalStopButton = nullptr; QLabel *m_armDeviceSummary = nullptr; QLabel *m_servoStatusValue = nullptr; QLabel *m_faultStatusValue = nullptr; QLabel *m_poseValue = nullptr; QLabel *m_updatedValue = nullptr; TrendWidget *m_trend = nullptr; QTableWidget *m_jointTable = nullptr; QTableWidget *m_motionTable = nullptr; QTableWidget *m_leftMotionTable = nullptr; QList m_targetSpins; QList m_leftTargetSpins; QList m_rightTargetSpins; QStringList m_leftArmJointNames; QStringList m_rightArmJointNames; QStringList m_activeArmJointNames; QTabWidget *m_motionCommandTabs = nullptr; QList m_moveJPoseSpins; QComboBox *m_moveJPoseBaseLinkCombo = nullptr; QPushButton *m_copyCurrentPoseButton = nullptr; QVariantMap m_latestArmPose; QDoubleSpinBox *m_velocitySpin = nullptr; QDoubleSpinBox *m_accelerationSpin = nullptr; QPushButton *m_sendMoveButton = nullptr; QPushButton *m_torqueOnButton = nullptr; QPushButton *m_torqueOffButton = nullptr; QPushButton *m_clearFaultButton = nullptr; QComboBox *m_zeroJointCombo = nullptr; QPushButton *m_calibrateZeroButton = nullptr; QPushButton *m_stopButton = nullptr; UrdfViewerWidget *m_urdfViewer = nullptr; QPushButton *m_teachModeButton = nullptr; QPushButton *m_teachRestoreButton = nullptr; QPushButton *m_teachSendButton = nullptr; QLabel *m_teachSelectedLabel = nullptr; QDoubleSpinBox *m_teachPositionSpin = nullptr; QTableWidget *m_teachJointTable = nullptr; QString m_teachSelectedJoint; QString m_pendingUrdfPath; bool m_armModelLoadScheduled = false; struct RecordedJointPoint { QString name; QString side; QString deviceId; QStringList jointNames; QVector positions; }; struct JointFlowStep { QString pointName; double waitSeconds = 1.0; QString loopGroup; int loopCount = 1; }; QList m_recordedJointPoints; QList m_jointFlowSteps; QHash m_latestArmJointPositions; QLineEdit *m_jointPointNameEdit = nullptr; QTableWidget *m_jointPointTable = nullptr; QLabel *m_jointPointDetailLabel = nullptr; QSpinBox *m_jointPointLoopCount = nullptr; QDoubleSpinBox *m_jointPointInterval = nullptr; QLineEdit *m_jointFlowGroupEdit = nullptr; QSpinBox *m_jointFlowGroupCount = nullptr; QTableWidget *m_jointFlowTable = nullptr; QPushButton *m_recordJointPointButton = nullptr; QPushButton *m_runJointPointButton = nullptr; QPushButton *m_deleteJointPointButton = nullptr; QPushButton *m_startJointPointLoopButton = nullptr; QPushButton *m_stopJointPointLoopButton = nullptr; QLabel *m_jointPointLoopStatus = nullptr; QVector m_jointPointLoopRows; QVector m_jointPointExecutionWaits; int m_jointPointLoopCursor = 0; int m_jointPointLoopsCompleted = 0; int m_jointPointLoopTarget = 0; bool m_jointPointLoopActive = false; bool m_jointPointMovePending = false; QLineEdit *m_cameraIdEdit = nullptr; VideoRenderWidget *m_videoRender = nullptr; QLabel *m_imageMetaLabel = nullptr; QPushButton *m_snapshotButton = nullptr; QPushButton *m_cameraStreamButton = nullptr; QPushButton *m_saveImageButton = nullptr; QComboBox *m_cameraCodecCombo = nullptr; QComboBox *m_cameraStreamModeCombo = nullptr; QLabel *m_cameraStreamStateLabel = nullptr; QLineEdit *m_cameraRecordPathEdit = nullptr; QPushButton *m_cameraRecordButton = nullptr; QLabel *m_cameraRecordStateLabel = nullptr; QWidget *m_cameraPreviewContainer = nullptr; QGridLayout *m_cameraPreviewGrid = nullptr; struct CameraPreviewTile { QWidget *container = nullptr; VideoRenderWidget *render = nullptr; QLabel *status = nullptr; QLabel *meta = nullptr; }; QHash m_cameraPreviewTiles; QSet m_runningCameraIds; QImage m_lastImage; bool m_cameraStreaming = false; bool m_cameraRecording = false; QLineEdit *m_agvIdEdit = nullptr; QDialog *m_agvStatusDialog = nullptr; QCheckBox *m_agvStatusSwitch = nullptr; QTimer *m_agvStatusRefreshTimer = nullptr; QLabel *m_agvConnectionValue = nullptr; QLabel *m_agvPoseValue = nullptr; QLabel *m_agvMotionValue = nullptr; QLabel *m_agvBatteryValue = nullptr; QLabel *m_agvMapValue = nullptr; QLabel *m_agvNavigationValue = nullptr; QLabel *m_agvErrorValue = nullptr; QLabel *m_agvModeValue = nullptr; QLabel *m_agvMotionStateValue = nullptr; QLabel *m_agvSafetyValue = nullptr; QLabel *m_agvPowerValue = nullptr; QLabel *m_agvTimestampValue = nullptr; QLabel *m_agvMapOverview = nullptr; QLabel *m_agvMappingPreview = nullptr; QLabel *m_agvMappingStateLabel = nullptr; QProgressBar *m_agvProgress = nullptr; QDoubleSpinBox *m_agvXSpin = nullptr; QDoubleSpinBox *m_agvYSpin = nullptr; QDoubleSpinBox *m_agvThetaSpin = nullptr; QDoubleSpinBox *m_agvMaxSpeedSpin = nullptr; QDoubleSpinBox *m_agvVxSpin = nullptr; QDoubleSpinBox *m_agvVySpin = nullptr; QDoubleSpinBox *m_agvWzSpin = nullptr; QComboBox *m_agvMapCombo = nullptr; QComboBox *m_agvStationCombo = nullptr; QTableWidget *m_agvStationTable = nullptr; QString m_agvDownloadPath; QList m_serviceButtons; QPushButton *m_speakerStreamStartButton = nullptr; QPushButton *m_speakerStreamStopButton = nullptr; QPushButton *m_microphoneStreamStartButton = nullptr; QPushButton *m_microphoneStreamStopButton = nullptr; QLineEdit *m_quicBindEdit = nullptr; QSpinBox *m_quicPortSpin = nullptr; QLineEdit *m_quicAlpnEdit = nullptr; QLineEdit *m_quicCertificateEdit = nullptr; QLineEdit *m_quicPasswordEdit = nullptr; QPushButton *m_quicToggleButton = nullptr; QLabel *m_quicStateValue = nullptr; QLabel *m_quicBoundValue = nullptr; QLabel *m_quicClientValue = nullptr; QLabel *m_quicRegistrationValue = nullptr; QLabel *m_quicHeartbeatValue = nullptr; QLabel *m_quicDatagramValue = nullptr; QLabel *m_quicDatagramBytesValue = nullptr; QLabel *m_quicNodeValue = nullptr; QLabel *m_quicBootValue = nullptr; QLabel *m_quicGrpcValue = nullptr; QLabel *m_quicPeerValue = nullptr; QTextEdit *m_quicLogView = nullptr; QTextEdit *m_logView = nullptr; QLabel *m_endpointValue = nullptr; QLabel *m_backendValue = nullptr; QLabel *m_buildValue = nullptr; bool m_connected = false; };