using RobotNet10.RobotApp.Client.Shared.SLAM; using RobotNet10.RobotApp.Shared; using RobotNet10.RobotApp.Shared.Enums; using RobotNet10.RobotApp.SLAM.Cartographer.Geometry; using RobotNet10.Shared.Geometry; using RobotNet10.Shared.Localization; using RobotNet10.Shared.Numbers; namespace RobotNet10.RobotApp.SLAM; /// /// Unified interface for Cartographer SLAM service including localization, scan mapping, and occupancy grid /// public interface ISLAMService { // ==================== State and Properties ==================== /// /// Gets the current state /// SLAMState State { get; } /// /// Gets the current pose (from localization or scan mapping depending on current state) /// Pose CurrentPose { get; } /// /// Gets the covariance of pose estimate (only available during localization) /// Matrix3x3? PoseCovariance { get; } // ==================== Localization Operations ==================== string? CurrentMap { get; } double? LocalizationScore { get; } /// /// Start localization with a saved map. /// Validates state, stores pending data, and fires StartLocalization trigger. /// The actual localization setup is handled asynchronously by the state machine. /// /// Name of the map to load /// Optional initial pose: base_link in map frame. No transform to sensor frame needed. void StartLocalization(string mapName, Pose? initialPose = null); /// /// Set initial pose for localization (must be called after StartLocalization). /// Pose must be base_link in map frame (e.g. from map click). No transform to sensor frame is needed; MCL uses base_link + baseLink2Laser internally. /// Validates state, stores pending data, and fires trigger. Actual work handled by state machine. /// void SetInitialPose(Pose pose); /// /// Stop localization and cleanup resources. /// Fires StopLocalization trigger. State machine handles the actual cleanup. /// void StopLocalization(); // ==================== Scan Mapping Control ==================== /// /// Start scan mapping with the specified map name. /// Validates state, stores map name, and fires StartScanMapping trigger. /// The actual scan mapping setup is handled by the state machine. /// /// Map name to be used when saving void StartScanMapping(string mapName); /// /// Save current map and stop scan mapping. /// Validates state and fires SaveMap trigger. The full save workflow (finish trajectory, /// optimization, save to storage) is handled asynchronously by the state machine. /// void SaveScanMap(); /// /// Get trajectory nodes from pose graph (dùng nội bộ khi build OccupancyGridDto). /// Trả về nodes khi Localizing (từ map đã load) hoặc ScanMapping (từ pose graph hiện tại). /// List<(int NodeId, Pose Pose)>? GetTrajectoryNodes(); /// /// Get aggregated sample point cloud from lidar (map/global frame). /// Returns points from AddSensorData SamplePointCloudGlobal when available; otherwise empty list. /// /// Read-only list of Point32 in global frame IReadOnlyList GetAggregatedSamplePointCloud(); // ==================== Occupancy Grid ==================== /// /// Lấy occupancy grid hiện tại /// Trả về: /// - OccupancyGrid từ file PGM nếu đang ở chế độ Localizing /// - OccupancyGrid được generate từ tất cả submaps nếu đang ở chế độ ScanMapping /// OccupancyGrid? GetOccupancyGrid(); /// /// Lấy occupancy grid mới hơn thời gian chỉ định /// Trả về OccupancyGrid nếu LastUpdated > since, ngược lại trả về null /// /// Thời gian để so sánh /// OccupancyGrid nếu có update mới hơn, null nếu không có OccupancyGrid? GetOccupancyGrid(DateTime since); /// /// Thời gian cuối cùng occupancy grid được cập nhật /// DateTime LastUpdatedOccupancyGrid { get; } // ==================== Map Management ==================== /// /// Liệt kê các maps có sẵn trong thư mục maps /// IReadOnlyList ListMaps(); /// /// Lấy thông tin chi tiết của một map theo tên /// /// Tên map /// MapInfo nếu tìm thấy, null nếu không MapInfo? GetMapInfo(string mapName); /// /// Lấy trạng thái xử lý của map /// /// Tên map /// True nếu map đang được xử lý, false nếu không bool GetMapProcessingStatus(string mapName); /// /// Lấy đường dẫn đến file ảnh PNG của map /// /// Tên map /// Đường dẫn đến file ảnh PNG nếu tồn tại, null nếu không string? GetMapImagePath(string mapName); /// /// Xóa map folder /// /// Tên map cần xóa /// Cancellation token /// True nếu xóa thành công Task DeleteMapAsync(string mapName, CancellationToken cancellationToken = default); /// /// Transform map để chọn lại gốc tọa độ /// /// Tên map cần transform /// Gốc tọa độ mới /// Cancellation token /// True nếu transform thành công Task TransformMapOriginAsync(string mapName, Pose newOrigin, CancellationToken cancellationToken = default); /// /// Rerender map image files (PNG, JPG, PGM) with custom OccupancyGridConfiguration. /// Reload pbstream, regenerate occupancy grid với config mới, và lưu lại các file ảnh. /// /// Tên map cần rerender /// Cấu hình OccupancyGrid tùy chỉnh /// Cancellation token /// True nếu rerender được bắt đầu thành công Task RerenderMapWithConfigAsync(string mapName, OccupancyGridConfigurationDto configDto, CancellationToken cancellationToken = default); }