CmvrControlStation/src/mainwindow.h

324 lines
12 KiB
C++

#pragma once
#include <QImage>
#include <QHash>
#include <QList>
#include <QMainWindow>
#include <QSet>
#include <QStyle>
#include <QStringList>
#include <QVariantList>
#include <QVariantMap>
#include <QVector>
#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<QPushButton *> 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<QDoubleSpinBox *> m_targetSpins;
QList<QDoubleSpinBox *> m_leftTargetSpins;
QList<QDoubleSpinBox *> m_rightTargetSpins;
QStringList m_leftArmJointNames;
QStringList m_rightArmJointNames;
QStringList m_activeArmJointNames;
QTabWidget *m_motionCommandTabs = nullptr;
QList<QDoubleSpinBox *> 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<double> positions;
};
struct JointFlowStep {
QString pointName;
double waitSeconds = 1.0;
QString loopGroup;
int loopCount = 1;
};
QList<RecordedJointPoint> m_recordedJointPoints;
QList<JointFlowStep> m_jointFlowSteps;
QHash<QString, double> 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<int> m_jointPointLoopRows;
QVector<double> 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<QString, CameraPreviewTile> m_cameraPreviewTiles;
QSet<QString> 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<QPushButton *> 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;
};