#ifndef PARKINGSPACEGUIDEPRESENTER_H #define PARKINGSPACEGUIDEPRESENTER_H #include #include #include #include #include #include #include #include #include #include #include #include #include #include "ConfigManager.h" #include "IMvsDevice.h" #include "ILedDisplayDevice.h" #include "IRsLidarDevice.h" #include "IYParkingSpaceGuideStatus.h" class DetectPresenter; class GpioInput; class IYUDPClient; class ParkingStatusHttpServer; class ParkingSpaceGuideRemoteServer; struct ParkingGuideAlgorithmState; struct CameraFrameInfo { int width = 0; int height = 0; int pixelFormat = 0; unsigned long long frameId = 0; unsigned long long timestamp = 0; }; struct ParkingSpaceGuideSimulationOptions { bool enabled = false; QString dataDirectory; int frameIntervalMs = 100; bool loop = false; }; class ParkingSpaceGuidePresenter : public QObject, public IVrConfigChangeNotify { Q_OBJECT public: explicit ParkingSpaceGuidePresenter(QObject* parent = nullptr); ParkingSpaceGuidePresenter( const ParkingSpaceGuideSimulationOptions& simulationOptions, QObject* parent = nullptr); ~ParkingSpaceGuidePresenter() override; int Init(); void RequestShutdown(); void DeinitApp(); bool StartAutomaticDetection(int cameraIndex = -1); bool StartDetection(const QString& selectedModelType, int cameraIndex = -1); bool SelectModel(const QString& selectedModelType); bool TriggerDetection(int cameraIndex = -1); int StopDetection(); bool IsDetectionRunning() const; int LoadAndDetect(const QString& fileName); int SaveDetectionDataToFile(const std::string& filePath); int GetDetectionDataCacheSize() const; void SetDefaultCameraIndex(int cameraIndex); int GetDetectIndex() const; QString GetAlgoVersion() const; ConfigManager* GetConfigManager(); std::vector> GetCameraList() const; template void SetStatusCallback(StatusCallbackType* statusCallback) { m_statusCallback = static_cast(statusCallback); } void OnConfigChanged(const ConfigResult& configResult) override; signals: void SelectedModelChanged(const QString& modelType); private: struct OwnedCloudFrame { std::vector points; RsCloudData cloud; RsFrameInfo info; qint64 timestampMs = 0; }; struct ModelRecognitionTaskResult { int returnCode = -1; QImage image; QImage sourceImage; QRect sourceRoi; QString modelType; double confidence = 0.0; QString message; bool verified = false; bool recognitionComplete = false; bool verificationSupported = true; bool confidenceAccepted = false; bool verificationAccepted = false; }; IYParkingSpaceGuideStatus* StatusCallback() const; int InitConfig(); int InitMvsCamera(const MvsCameraConfig& config); int InitRsLidar(const RsLidarConfig& config); int InitLedDisplay(const LedDisplayConfig& config); int InitUdpBroadcast(const UdpBroadcastConfig& config); int InitHttpServer(const HttpServerConfig& config); int InitRemoteView(const RemoteViewConfig& config); int InitEmergencyStop(const EmergencyStopConfig& config); int InitSimulationData(); void CloseEmergencyStop(bool clearLatch = true); void CloseUdpBroadcast(); void CloseHttpServer(); void CloseRemoteView(); void CloseDevices(); void ClearSimulationData(); void EnrichDetectionResult(DetectionResult& result) const; void UpdateCurrentStatus(const DetectionResult& result); std::string CurrentStatusJson() const; bool BroadcastDetectionResult(const DetectionResult& result); void NotifyStatus(const std::string& message); void NotifyWorkStatus(WorkStatus status); void NotifyCameraStatus(bool connected); void NotifyLidarStatus(bool connected); void NotifyLedStatus(bool connected); LedDisplayResult ConvertLedResult(const DetectionResult& result) const; std::shared_ptr AcquireCloudFrameBuffer(); static bool CopyCloudFrame(const RsCloudData& cloud, const RsFrameInfo& info, OwnedCloudFrame& destination); bool SubmitCloudFrame(const RsCloudData& cloud, const RsFrameInfo& info); unsigned long long SubmitOwnedCloudFrame( const std::shared_ptr& frame); bool LoadSimulationRadarFrame(size_t frameIndex, std::shared_ptr& frame, QString& errorMessage); bool LoadSimulationCameraFile(size_t imageIndex, QImage& image, QString& errorMessage); void CacheSimulationCameraFrame(size_t frameIndex, const QImage& image); bool WaitForSimulationFrameProcessed(unsigned long long sequence); bool WaitForSimulationInterval(int intervalMs); void SimulationPlaybackLoop(); bool ProcessAirplanePresence(const RsCloudData& cloud); bool DetectOnce(const RsCloudData& cloud, qint64 frameTimestampMs, ParkingGuideAlgorithmState& algorithmState); bool StartDetectionInternal(const QString& selectedModelType, int cameraIndex, bool clearSafetyLatch, bool automaticMode); void PublishDetectionResult(DetectionResult& result, bool safetyResult = false); void PublishErrorResult(int errorCode, const QString& message); bool CaptureModelRecognitionImage(QImage& image, QString& errorMessage); bool StartModelRecognitionTask(const QByteArray& recognitionContext, const VrModelRecognitionParam& modelParam, int attempt, const VrDebugParam& debugParam, QString& errorMessage); bool TakeModelRecognitionTaskResult(ModelRecognitionTaskResult& result); void WaitForModelRecognitionTask(bool discardResult); void ApplyModelRecognitionTaskResult( const ModelRecognitionTaskResult& taskResult, ParkingGuideAlgorithmState& algorithmState, DetectionResult& result, const VrModelRecognitionParam& modelParam); void UpdateDetectionResultModelFields( DetectionResult& result, const ParkingGuideAlgorithmState& algorithmState) const; void DetectionLoop(QString selectedModelType, bool automaticMode); void HandleEmergencyStopChanged(bool active); void HandleEmergencyStopStatus(bool available, const std::string& message); void RequestDetectionStopForSafety(); DetectionResult CreateGuideStateResult(ParkingGuideState state, const QString& guideText, const QString& message, bool preserveLastMeasurement) const; void PublishGuideState(ParkingGuideState state, const QString& guideText, const QString& message, bool preserveLastMeasurement); bool PublishCurrentSafetyState(bool publishWaitingWhenClear, bool preserveLastMeasurement); void StartVideoStream(const HttpFlvStreamConfig& config, const MvsCameraConfig& cameraConfig); void RequestVideoStreamStop(); void StopVideoStream(); void VideoStreamLoop(HttpFlvStreamConfig config, MvsCameraConfig cameraConfig); bool CacheMvsFrame(const MvsImageData& image, QImage& frame); private: ConfigManager* m_configManager = nullptr; DetectPresenter* m_detectPresenter = nullptr; IMvsDevice* m_mvsDevice = nullptr; IRsLidarDevice* m_lidarDevice = nullptr; ILedDisplayDevice* m_ledDisplay = nullptr; std::unique_ptr m_emergencyStopInput; IYUDPClient* m_udpClient = nullptr; ParkingStatusHttpServer* m_httpServer = nullptr; ParkingSpaceGuideRemoteServer* m_remoteServer = nullptr; UdpBroadcastConfig m_udpBroadcastConfig; EmergencyStopConfig m_emergencyStopConfig; RemoteViewConfig m_remoteViewConfig; bool m_hasEmergencyStopConfig = false; bool m_hasRemoteViewConfig = false; ParkingSpaceGuideSimulationOptions m_simulationOptions; void* m_statusCallback = nullptr; mutable std::mutex m_dataMutex; mutable std::mutex m_udpMutex; mutable std::mutex m_statusMutex; mutable std::mutex m_publishMutex; mutable std::mutex m_outputMutex; mutable std::mutex m_safetyMutex; mutable std::mutex m_safetyPublishMutex; mutable std::mutex m_workStatusMutex; mutable std::mutex m_sessionMutex; mutable std::mutex m_cameraCaptureMutex; std::string m_currentStatusJson; DetectionResult m_lastDetectionResult; std::vector m_latestFrame; CameraFrameInfo m_latestFrameInfo; bool m_hasFrame = false; std::array, 3> m_cloudFrameSlots; std::shared_ptr m_latestCloudFrame; size_t m_nextCloudFrameSlot = 0; unsigned long long m_cloudSequence = 0; unsigned long long m_consumedCloudSequence = 0; unsigned long long m_processedCloudSequence = 0; bool m_lidarErrorPending = false; QString m_lidarErrorMessage; QString m_selectedModelType; std::vector m_simulationRadarFiles; std::vector m_simulationCameraFiles; std::vector> m_simulationRadarFrames; std::vector m_simulationCameraFrames; QImage m_simulationCameraImage; std::vector> m_cameraList; int m_currentCameraIndex = 1; int m_detectIndex = 1; std::atomic m_initialized{false}; std::atomic m_reconfiguring{false}; std::atomic m_shutdownRequested{false}; std::atomic m_emergencyStopEnabled{false}; std::atomic m_emergencyStopAvailable{true}; std::atomic m_emergencyStopActive{false}; std::atomic m_emergencyStopLatched{false}; std::atomic m_detectionRunning{false}; std::atomic m_automaticDetection{false}; std::atomic m_stopDetectionRequested{false}; std::atomic m_trackingMode{false}; std::atomic m_simulationRound{0}; std::atomic m_lastProbeAcceptedMs{0}; std::atomic m_cloudCopyErrorReported{false}; std::mutex m_detectionThreadMutex; std::mutex m_detectionExecutionMutex; std::mutex m_reconfigurationMutex; std::condition_variable m_detectionCondition; std::thread m_detectionThread; std::thread m_simulationThread; std::atomic m_videoStreamStopRequested{true}; std::atomic m_videoStreamRunning{false}; std::mutex m_videoStreamMutex; std::condition_variable m_videoStreamCondition; std::thread m_videoStreamThread; std::mutex m_modelRecognitionMutex; std::thread m_modelRecognitionThread; ModelRecognitionTaskResult m_modelRecognitionTaskResult; std::atomic m_modelRecognitionRunning{false}; std::atomic m_modelRecognitionResultReady{false}; std::atomic m_modelRecognitionResultApplying{false}; }; #endif // PARKINGSPACEGUIDEPRESENTER_H