Initial commit
This commit is contained in:
@@ -0,0 +1,13 @@
|
||||
using RobotNet10.Shared.Geometry;
|
||||
|
||||
namespace RobotNet10.RobotApp.Client.Shared.Devices;
|
||||
|
||||
/// <summary>
|
||||
/// DTO cho Camera QR data
|
||||
/// </summary>
|
||||
public class CameraQrDataDto
|
||||
{
|
||||
public bool IsConnected { get; set; }
|
||||
public Dictionary<string, PoseStamped> Codes { get; set; } = [];
|
||||
}
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
namespace RobotNet10.RobotApp.Client.Shared.Devices;
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// DTO cho CiA402Servo data
|
||||
/// </summary>
|
||||
public struct CiA402ServoDataDto
|
||||
{
|
||||
public ushort Statusword { get; set; }
|
||||
public string DriveState { get; set; }
|
||||
public string OperationMode { get; set; }
|
||||
public int Position { get; set; }
|
||||
public int Velocity { get; set; }
|
||||
public short Torque { get; set; }
|
||||
public ushort ErrorCode { get; set; }
|
||||
public bool IsConnected { get; set; }
|
||||
/// <summary>Profile Speed (0x6081) - đọc từ drive khi GetServoData</summary>
|
||||
public uint ProfileSpeed { get; set; }
|
||||
/// <summary>Profile Acceleration (0x6083) - đọc từ drive khi GetServoData</summary>
|
||||
public uint ProfileAcceleration { get; set; }
|
||||
/// <summary>Profile Deceleration (0x6084) - đọc từ drive khi GetServoData</summary>
|
||||
public uint ProfileDeceleration { get; set; }
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
namespace RobotNet10.RobotApp.Client.Shared.Devices;
|
||||
|
||||
/// <summary>
|
||||
/// DTO cho thông tin device để truyền qua SignalR
|
||||
/// </summary>
|
||||
public class DeviceDto
|
||||
{
|
||||
public string DeviceId { get; set; } = string.Empty;
|
||||
public string DeviceName { get; set; } = string.Empty;
|
||||
public DeviceType DeviceType { get; set; }
|
||||
public string? Description { get; set; }
|
||||
public DeviceStatus Status { get; set; }
|
||||
public bool IsConnected { get; set; }
|
||||
public DateTime LastUpdateTime { get; set; }
|
||||
public DateTime? LastConnectedTime { get; set; }
|
||||
public DateTime? LastDisconnectedTime { get; set; }
|
||||
public string? LastError { get; set; }
|
||||
public int ReconnectAttemptCount { get; set; }
|
||||
public bool AutoReconnectEnabled { get; set; }
|
||||
public int ReconnectDelayMs { get; set; }
|
||||
public int MaxReconnectAttempts { get; set; }
|
||||
public List<PropertyDescription> PropertyDescriptions { get; set; } = new();
|
||||
public Dictionary<string, string> Properties { get; set; } = new();
|
||||
}
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
namespace RobotNet10.RobotApp.Client.Shared.Devices;
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// DTO cho Device info (shared với server)
|
||||
/// </summary>
|
||||
public class DeviceInfoDto
|
||||
{
|
||||
public string DeviceId { get; set; } = string.Empty;
|
||||
public string DeviceName { get; set; } = string.Empty;
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
namespace RobotNet10.RobotApp.Client.Shared.Devices;
|
||||
|
||||
/// <summary>
|
||||
/// Trạng thái của thiết bị (State Machine)
|
||||
/// </summary>
|
||||
public enum DeviceStatus
|
||||
{
|
||||
/// <summary>
|
||||
/// Chưa khởi tạo
|
||||
/// </summary>
|
||||
Uninitialized = 0,
|
||||
|
||||
/// <summary>
|
||||
/// Đang khởi tạo
|
||||
/// </summary>
|
||||
Initializing,
|
||||
|
||||
/// <summary>
|
||||
/// Đang kết nối
|
||||
/// </summary>
|
||||
Connecting,
|
||||
|
||||
/// <summary>
|
||||
/// Đã kết nối và sẵn sàng
|
||||
/// </summary>
|
||||
Connected,
|
||||
|
||||
/// <summary>
|
||||
/// Đang ngắt kết nối
|
||||
/// </summary>
|
||||
Disconnecting,
|
||||
|
||||
/// <summary>
|
||||
/// Đã ngắt kết nối
|
||||
/// </summary>
|
||||
Disconnected,
|
||||
|
||||
/// <summary>
|
||||
/// Đang kết nối lại (auto-reconnect)
|
||||
/// </summary>
|
||||
Reconnecting,
|
||||
|
||||
/// <summary>
|
||||
/// Lỗi - cần xử lý
|
||||
/// </summary>
|
||||
Error,
|
||||
|
||||
/// <summary>
|
||||
/// Đã bị dispose
|
||||
/// </summary>
|
||||
Disposed
|
||||
}
|
||||
|
||||
@@ -0,0 +1,44 @@
|
||||
namespace RobotNet10.RobotApp.Client.Shared.Devices;
|
||||
|
||||
/// <summary>
|
||||
/// Loại thiết bị trong hệ thống AMR
|
||||
/// </summary>
|
||||
public enum DeviceType
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
/// Servo motor theo chuẩn CiA402
|
||||
/// </summary>
|
||||
CiA402Servo = 0,
|
||||
|
||||
/// <summary>
|
||||
/// LiDAR - cảm biến quét laser
|
||||
/// </summary>
|
||||
Lidar,
|
||||
|
||||
/// <summary>
|
||||
/// IMU - Inertial Measurement Unit
|
||||
/// </summary>
|
||||
Imu,
|
||||
|
||||
/// <summary>
|
||||
/// Pin/Battery
|
||||
/// </summary>
|
||||
Battery,
|
||||
|
||||
/// <summary>
|
||||
/// ModbusTCP client/server
|
||||
/// </summary>
|
||||
ModbusTcp,
|
||||
|
||||
/// <summary>
|
||||
/// Tay điều khiển RF (RF Handle)
|
||||
/// </summary>
|
||||
RfHandle,
|
||||
|
||||
/// <summary>
|
||||
/// Camera phát hiện QR code
|
||||
/// </summary>
|
||||
CameraQr,
|
||||
}
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
namespace RobotNet10.RobotApp.Client.Shared.Devices;
|
||||
|
||||
/// <summary>
|
||||
/// DTO cho device update events qua SignalR
|
||||
/// </summary>
|
||||
public class DeviceUpdateDto
|
||||
{
|
||||
public string DeviceId { get; set; } = string.Empty;
|
||||
public DeviceStatus? Status { get; set; }
|
||||
public Dictionary<string, string>? Properties { get; set; }
|
||||
public string? LastError { get; set; }
|
||||
public DateTime? LastUpdateTime { get; set; }
|
||||
public DateTime? LastConnectedTime { get; set; }
|
||||
public DateTime? LastDisconnectedTime { get; set; }
|
||||
public int? ReconnectAttemptCount { get; set; }
|
||||
}
|
||||
|
||||
@@ -0,0 +1,52 @@
|
||||
namespace RobotNet10.RobotApp.Client.Shared.Devices;
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// DTO cho Modbus value (register)
|
||||
/// </summary>
|
||||
public struct ModbusValue
|
||||
{
|
||||
public ushort Address { get; set; }
|
||||
public ushort Index { get; set; }
|
||||
public ushort Value { get; set; }
|
||||
public string Name { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// DTO cho Modbus bool value (coil/discrete input)
|
||||
/// </summary>
|
||||
public struct ModbusBoolValue
|
||||
{
|
||||
public ushort Address { get; set; }
|
||||
public ushort Index { get; set; }
|
||||
public bool Value { get; set; }
|
||||
public string Name { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// DTO cho Modbus range data
|
||||
/// </summary>
|
||||
public struct ModbusRangeData
|
||||
{
|
||||
public ushort StartAddress { get; set; }
|
||||
public ushort Quantity { get; set; }
|
||||
public string Name { get; set; }
|
||||
public string[] ChildrenNames { get; set; }
|
||||
public ModbusValue[] Values { get; set; }
|
||||
public ModbusBoolValue[] BoolValues { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// DTO cho ModbusTCP data
|
||||
/// </summary>
|
||||
public struct ModbusTcpData
|
||||
{
|
||||
public string IpAddress { get; set; }
|
||||
public int Port { get; set; }
|
||||
public byte SlaveId { get; set; }
|
||||
public bool IsConnected { get; set; }
|
||||
public ModbusRangeData[] HoldingRegisters { get; set; }
|
||||
public ModbusRangeData[] InputRegisters { get; set; }
|
||||
public ModbusRangeData[] Coils { get; set; }
|
||||
public ModbusRangeData[] DiscreteInputs { get; set; }
|
||||
}
|
||||
@@ -0,0 +1,69 @@
|
||||
namespace RobotNet10.RobotApp.Client.Shared.Devices;
|
||||
|
||||
/// <summary>
|
||||
/// Mô tả một property của thiết bị (dùng để hiển thị trên web UI)
|
||||
/// </summary>
|
||||
public class PropertyDescription
|
||||
{
|
||||
/// <summary>
|
||||
/// Tên key của property (phải khớp với key trong Properties dictionary)
|
||||
/// </summary>
|
||||
public string Key { get; set; } = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// Tên hiển thị trên UI
|
||||
/// </summary>
|
||||
public string DisplayName { get; set; } = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// Mô tả chi tiết về property
|
||||
/// </summary>
|
||||
public string? Description { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Loại dữ liệu (ví dụ: "string", "number", "boolean", "date", "url", etc.)
|
||||
/// </summary>
|
||||
public string DataType { get; set; } = "string";
|
||||
|
||||
/// <summary>
|
||||
/// Đơn vị đo (ví dụ: "V", "A", "Hz", "°C", "m/s", etc.) - null nếu không có
|
||||
/// </summary>
|
||||
public string? Unit { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Giá trị mặc định
|
||||
/// </summary>
|
||||
public string? DefaultValue { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Có thể chỉnh sửa trên UI hay không
|
||||
/// </summary>
|
||||
public bool IsReadOnly { get; set; } = false;
|
||||
|
||||
/// <summary>
|
||||
/// Thứ tự hiển thị trên UI (số nhỏ hơn hiển thị trước)
|
||||
/// </summary>
|
||||
public int DisplayOrder { get; set; } = 0;
|
||||
|
||||
/// <summary>
|
||||
/// Nhóm/category của property (để nhóm các properties lại với nhau trên UI)
|
||||
/// </summary>
|
||||
public string? Category { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Format string để hiển thị giá trị (ví dụ: "{0:F2}", "{0:yyyy-MM-dd}", etc.)
|
||||
/// </summary>
|
||||
public string? Format { get; set; }
|
||||
|
||||
public PropertyDescription()
|
||||
{
|
||||
}
|
||||
|
||||
public PropertyDescription(string key, string displayName, string? description = null)
|
||||
{
|
||||
Key = key ?? throw new ArgumentNullException(nameof(key));
|
||||
DisplayName = displayName ?? throw new ArgumentNullException(nameof(displayName));
|
||||
Description = description;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
namespace RobotNet10.RobotApp.Client.Shared.Devices;
|
||||
|
||||
|
||||
// ======================================================================
|
||||
// DTO LITE – khớp 100% IRfHandle Lite + RfHandleHub Lite
|
||||
// ======================================================================
|
||||
public class RfHandleDataDto
|
||||
{
|
||||
public string DeviceId { get; set; } = "";
|
||||
|
||||
public int Heartbeat { get; set; }
|
||||
public bool RemoteReady { get; set; }
|
||||
public bool EStop { get; set; }
|
||||
|
||||
public bool LiftUp { get; set; }
|
||||
public bool LiftDown { get; set; }
|
||||
public bool RotateLeft { get; set; }
|
||||
public bool RotateRight { get; set; }
|
||||
|
||||
public bool ModeSelect { get; set; }
|
||||
public bool Enable { get; set; }
|
||||
|
||||
public int Speed { get; set; }
|
||||
public double Linear { get; set; }
|
||||
public double Angular { get; set; }
|
||||
public string Mode { get; set; } = "Unknown";
|
||||
|
||||
public DateTime LastUpdateTime { get; set; }
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
namespace RobotNet10.RobotApp.Client.Shared.Modules;
|
||||
|
||||
/// <summary>
|
||||
/// DTO cho trạng thái LiftModule (dùng cho SignalR)
|
||||
/// </summary>
|
||||
public class LiftModuleStatusDto
|
||||
{
|
||||
public string State { get; set; } = string.Empty;
|
||||
public bool IsReady { get; set; }
|
||||
public int CurrentPosition { get; set; }
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
namespace RobotNet10.RobotApp.Client.Shared.Modules;
|
||||
|
||||
/// <summary>
|
||||
/// DTO cho trạng thái RotationModule (dùng cho SignalR)
|
||||
/// </summary>
|
||||
public class RotationModuleStatusDto
|
||||
{
|
||||
public string State { get; set; } = string.Empty;
|
||||
public bool IsReady { get; set; }
|
||||
public double CurrentAngle { get; set; }
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
namespace RobotNet10.RobotApp.Client.Shared.Motion;
|
||||
|
||||
/// <summary>
|
||||
/// DTO cho trạng thái ManualControlService
|
||||
/// </summary>
|
||||
public class ManualControlStatusDto
|
||||
{
|
||||
public string State { get; set; } = string.Empty;
|
||||
public bool IsEnabled { get; set; }
|
||||
public double CurrentLinearVelocity { get; set; }
|
||||
public double CurrentAngularVelocity { get; set; }
|
||||
public RfHandleStatusDto? RfHandleStatus { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// DTO cho trạng thái RF Handle
|
||||
/// </summary>
|
||||
public class RfHandleStatusDto
|
||||
{
|
||||
public int Heartbeat { get; set; }
|
||||
public bool Ready { get; set; }
|
||||
public bool Locked { get; set; }
|
||||
public bool EStop { get; set; }
|
||||
public bool Enable { get; set; }
|
||||
public int Speed { get; set; }
|
||||
public double Linear { get; set; }
|
||||
public double Angular { get; set; }
|
||||
public string Mode { get; set; } = string.Empty;
|
||||
public DateTime LastUpdateTime { get; set; }
|
||||
}
|
||||
|
||||
@@ -0,0 +1,95 @@
|
||||
namespace RobotNet10.RobotApp.Client.Shared.Motion;
|
||||
|
||||
/// <summary>
|
||||
/// DTO cho thông tin Odometry từ IOdometryEstimator
|
||||
/// SignalR serialization-friendly version using simple properties
|
||||
/// instead of System.Numerics types which don't serialize properly with System.Text.Json
|
||||
/// </summary>
|
||||
public class OdometryDto
|
||||
{
|
||||
/// <summary>
|
||||
/// Timestamp của pose
|
||||
/// </summary>
|
||||
public DateTime Timestamp { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Frame ID (header.frame_id, parent frame, typically "odom")
|
||||
/// </summary>
|
||||
public string FrameId { get; set; } = "odom";
|
||||
|
||||
/// <summary>
|
||||
/// Child frame ID (typically "base_link" or "base_footprint") - cùng giá trị gửi lên XLOC
|
||||
/// </summary>
|
||||
public string ChildFrameId { get; set; } = "base_link";
|
||||
|
||||
/// <summary>
|
||||
/// Position X (meters)
|
||||
/// </summary>
|
||||
public double PositionX { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Position Y (meters)
|
||||
/// </summary>
|
||||
public double PositionY { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Position Z (meters)
|
||||
/// </summary>
|
||||
public double PositionZ { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Orientation Quaternion X
|
||||
/// </summary>
|
||||
public double OrientationX { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Orientation Quaternion Y
|
||||
/// </summary>
|
||||
public double OrientationY { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Orientation Quaternion Z
|
||||
/// </summary>
|
||||
public double OrientationZ { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Orientation Quaternion W
|
||||
/// </summary>
|
||||
public double OrientationW { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Tần số update odometry hiện tại (Hz)
|
||||
/// </summary>
|
||||
public double UpdateFrequency { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Vận tốc tuyến tính X (m/s) - hướng tiến
|
||||
/// </summary>
|
||||
public double LinearVelocityX { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Vận tốc tuyến tính Y (m/s)
|
||||
/// </summary>
|
||||
public double LinearVelocityY { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Vận tốc tuyến tính Z (m/s)
|
||||
/// </summary>
|
||||
public double LinearVelocityZ { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Vận tốc góc X (rad/s)
|
||||
/// </summary>
|
||||
public double AngularVelocityX { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Vận tốc góc Y (rad/s)
|
||||
/// </summary>
|
||||
public double AngularVelocityY { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Vận tốc góc Z (rad/s) - quay quanh trục dọc
|
||||
/// </summary>
|
||||
public double AngularVelocityZ { get; set; }
|
||||
}
|
||||
|
||||
@@ -0,0 +1,60 @@
|
||||
using RobotNet.VDA5050.Type;
|
||||
|
||||
namespace RobotNet10.RobotApp.Client.Shared.Plc;
|
||||
|
||||
/// <summary>
|
||||
/// DTO cho trạng thái PlcController (dùng cho SignalR)
|
||||
/// </summary>
|
||||
public class PlcControllerStatusDto
|
||||
{
|
||||
public bool IsReady { get; set; }
|
||||
|
||||
// Operating mode
|
||||
public string PeripheralMode { get; set; } = string.Empty;
|
||||
public string SafetySpeed { get; set; } = string.Empty;
|
||||
|
||||
// Safety sensors
|
||||
public bool Emergency { get; set; }
|
||||
public bool Bumper { get; set; }
|
||||
public bool LidarFrontProtectField { get; set; }
|
||||
public bool LidarBackProtectField { get; set; }
|
||||
public bool LidarFrontTimProtectField { get; set; }
|
||||
|
||||
// Lift state
|
||||
public bool LiftedUp { get; set; }
|
||||
public bool LiftedDown { get; set; }
|
||||
public bool LiftHome { get; set; }
|
||||
|
||||
// Motor state
|
||||
public bool LeftMotorReady { get; set; }
|
||||
public bool RightMotorReady { get; set; }
|
||||
public bool LiftMotorReady { get; set; }
|
||||
|
||||
// Button state
|
||||
public bool ButtonStart { get; set; }
|
||||
public bool ButtonStop { get; set; }
|
||||
public bool ButtonReset { get; set; }
|
||||
|
||||
// Other state
|
||||
public bool HasLoad { get; set; }
|
||||
public bool EnabledCharger { get; set; }
|
||||
public bool Charging { get; set; }
|
||||
public bool MutedBase { get; set; }
|
||||
public bool MutedLoad { get; set; }
|
||||
|
||||
// Current stop state (for display)
|
||||
public string StopState { get; set; } = "None";
|
||||
|
||||
// Write state - các giá trị đã được ghi xuống PLC
|
||||
public string CurrentSystemState { get; set; } = "INIT";
|
||||
public string CurrentOperationState { get; set; } = "None";
|
||||
public string CurrentRFMode { get; set; } = "None";
|
||||
public bool SetHorizontalLoadValue { get; set; }
|
||||
public bool SetMutedBaseValue { get; set; }
|
||||
public bool SetMutedLoadValue { get; set; }
|
||||
public bool SetEnableChargerValue { get; set; }
|
||||
public bool SetHasLoadValue { get; set; }
|
||||
public bool SetRFEStopValue { get; set; }
|
||||
public bool SetBatteryLowValue { get; set; }
|
||||
public bool SetLightOnValue { get; set; }
|
||||
}
|
||||
@@ -0,0 +1,256 @@
|
||||
using RobotNet10.Shared.Geometry;
|
||||
using RobotNet10.Shared.Numbers;
|
||||
using QuaternionGeometry = RobotNet10.Shared.Geometry.Quaternion;
|
||||
|
||||
namespace RobotNet10.RobotApp.Client.Shared.SLAM;
|
||||
|
||||
/// <summary>
|
||||
/// DTO cho Pose với covariance (3x3 matrix flattened to 9 values)
|
||||
/// </summary>
|
||||
public class PoseDto
|
||||
{
|
||||
public RobotNet10.Shared.Numbers.Vector3 Position { get; set; } = new();
|
||||
public QuaternionGeometry Orientation { get; set; } = new();
|
||||
|
||||
/// <summary>
|
||||
/// Covariance matrix (3x3) flattened to 9 values: [xx, xy, xθ, yx, yy, yθ, θx, θy, θθ]
|
||||
/// null if covariance is not available
|
||||
/// </summary>
|
||||
public double[]? Covariance { get; set; }
|
||||
|
||||
public double Score { get; set; }
|
||||
|
||||
public DateTime Timestamp { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// DTO cho OccupancyGrid (optimized sparse format for SignalR transmission)
|
||||
/// Chỉ chứa các cell đã biết (known cells) và occupied cells để giảm bandwidth
|
||||
/// </summary>
|
||||
public class OccupancyGridDto
|
||||
{
|
||||
public double Resolution { get; set; }
|
||||
public int Width { get; set; }
|
||||
public int Height { get; set; }
|
||||
public Pose Origin { get; set; } = new();
|
||||
|
||||
/// <summary>
|
||||
/// Sparse format: chỉ chứa các cell đã biết (value >= 0)
|
||||
/// Format: byte[] với mỗi cell = 5 bytes: [index_byte0, index_byte1, index_byte2, index_byte3, value]
|
||||
/// Index: 4 bytes little-endian (32-bit unsigned integer, max 4,294,967,295)
|
||||
/// Value: 1 byte (0-100 = occupancy probability, 0 = free, 100 = occupied)
|
||||
/// Index được tính: y * Width + x (row-major order)
|
||||
/// </summary>
|
||||
public byte[] KnownCells { get; set; } = [];
|
||||
|
||||
/// <summary>
|
||||
/// Version number để detect changes (increment mỗi khi grid thay đổi)
|
||||
/// </summary>
|
||||
public long Version { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Thời gian cuối cùng update grid base (từ CartographerService.LastUpdatedBase).
|
||||
/// </summary>
|
||||
public DateTime LastBaseUpdated { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Thời gian cuối cùng update OccupancyGridUpdating (từ CartographerService.LastUpdatedUpdating).
|
||||
/// </summary>
|
||||
public DateTime LastUpdated { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Trajectory nodes (từ pose graph) kèm theo grid; dùng để vẽ trajectory polyline.
|
||||
/// Có khi lấy grid base hoặc grid updating.
|
||||
/// </summary>
|
||||
public TrajectoryNodeDto[]? TrajectoryNodes { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// DTO cho TrajectoryNode
|
||||
/// </summary>
|
||||
public class TrajectoryNodeDto
|
||||
{
|
||||
public int NodeId { get; set; }
|
||||
public Pose Pose { get; set; } = new();
|
||||
public DateTime Timestamp { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// DTO cho MapInfo
|
||||
/// </summary>
|
||||
public class MapInfoDto
|
||||
{
|
||||
public string Name { get; set; } = string.Empty;
|
||||
public DateTime CreatedDate { get; set; }
|
||||
public double Resolution { get; set; }
|
||||
/// <summary>
|
||||
/// Width of map in meters
|
||||
/// </summary>
|
||||
public double Width { get; set; }
|
||||
/// <summary>
|
||||
/// Height of map in meters
|
||||
/// </summary>
|
||||
public double Height { get; set; }
|
||||
public int TrajectoryNodeCount { get; set; }
|
||||
/// <summary>
|
||||
/// Origin X coordinate in meters
|
||||
/// </summary>
|
||||
public double OriginX { get; set; }
|
||||
/// <summary>
|
||||
/// Origin Y coordinate in meters
|
||||
/// </summary>
|
||||
public double OriginY { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Indicates if the map is currently being processed on the server
|
||||
/// </summary>
|
||||
public bool IsProcessing { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// DTO cho error information
|
||||
/// </summary>
|
||||
public class ErrorDto
|
||||
{
|
||||
public string Message { get; set; } = string.Empty;
|
||||
public DateTime Timestamp { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Strategy for merging multiple submaps into a single occupancy grid.
|
||||
/// </summary>
|
||||
public enum SubmapMergeStrategyDto
|
||||
{
|
||||
/// <summary>
|
||||
/// Porter-Duff Source-Over compositing (Cairo-style).
|
||||
/// </summary>
|
||||
PorterDuff = 0,
|
||||
|
||||
/// <summary>
|
||||
/// Sum log-odds from all submaps (Bayesian approach).
|
||||
/// </summary>
|
||||
LogOddsSum = 1,
|
||||
|
||||
/// <summary>
|
||||
/// Take maximum probability (most pessimistic/conservative).
|
||||
/// </summary>
|
||||
MaxProbability = 2
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// DTO cho OccupancyGridConfiguration - dùng để customize cách render occupancy grid
|
||||
/// </summary>
|
||||
public class OccupancyGridConfigurationDto
|
||||
{
|
||||
#region Merge Strategy
|
||||
|
||||
/// <summary>
|
||||
/// Strategy for merging overlapping cells from multiple submaps.
|
||||
/// Default: LogOddsSum (clearer free/occupied distinction)
|
||||
/// </summary>
|
||||
public SubmapMergeStrategyDto MergeStrategy { get; set; } = SubmapMergeStrategyDto.LogOddsSum;
|
||||
|
||||
/// <summary>
|
||||
/// Clamp log-odds to prevent extreme values from dominating.
|
||||
/// Range: [1, 20], Default: 10
|
||||
/// </summary>
|
||||
public double LogOddsClamp { get; set; } = 10.0;
|
||||
|
||||
/// <summary>
|
||||
/// When true, use average log-odds instead of sum.
|
||||
/// Default: true
|
||||
/// </summary>
|
||||
public bool UseLogOddsAverage { get; set; } = true;
|
||||
|
||||
#endregion
|
||||
|
||||
#region Threshold Configuration
|
||||
|
||||
/// <summary>
|
||||
/// Threshold for classifying a cell as FREE.
|
||||
/// Higher value = stricter (fewer free cells).
|
||||
/// Range: [0, 255], Default: 100
|
||||
/// </summary>
|
||||
public int FreeSpaceThreshold { get; set; } = 100;
|
||||
|
||||
/// <summary>
|
||||
/// Threshold for classifying a cell as OCCUPIED.
|
||||
/// Higher value = stricter (fewer occupied cells, thinner walls).
|
||||
/// Range: [0, 255], Default: 0
|
||||
/// </summary>
|
||||
public int OccupiedSpaceThreshold { get; set; } = 0;
|
||||
|
||||
#endregion
|
||||
|
||||
#region Output Mode
|
||||
|
||||
/// <summary>
|
||||
/// When true, output only binary values (0=free, 100=occupied, -1=unknown).
|
||||
/// When false, output gradient values (0-100) based on probability.
|
||||
/// Default: true
|
||||
/// </summary>
|
||||
public bool UseBinaryOutput { get; set; } = true;
|
||||
|
||||
#endregion
|
||||
|
||||
#region Wall Thinning (Post-processing)
|
||||
|
||||
/// <summary>
|
||||
/// Enable morphological erosion to thin walls in the occupancy grid.
|
||||
/// Default: false
|
||||
/// </summary>
|
||||
public bool EnableWallThinning { get; set; } = false;
|
||||
|
||||
/// <summary>
|
||||
/// Number of erosion iterations for wall thinning.
|
||||
/// Range: [1, 5], Default: 1
|
||||
/// </summary>
|
||||
public int WallThinningIterations { get; set; } = 1;
|
||||
|
||||
/// <summary>
|
||||
/// Minimum wall thickness to preserve (in pixels) during wall thinning.
|
||||
/// Range: [1, 10], Default: 1
|
||||
/// </summary>
|
||||
public int MinWallThicknessPixels { get; set; } = 1;
|
||||
|
||||
#endregion
|
||||
|
||||
#region Ambiguous Cell Handling
|
||||
|
||||
/// <summary>
|
||||
/// How to handle ambiguous cells (probability ~0.5).
|
||||
/// Values: -1 = Unknown, 0 = Free, 100 = Occupied
|
||||
/// Default: -1
|
||||
/// </summary>
|
||||
public sbyte AmbiguousCellValue { get; set; } = -1;
|
||||
|
||||
/// <summary>
|
||||
/// Lower bound of the ambiguous range (probability).
|
||||
/// Default: 0.35
|
||||
/// </summary>
|
||||
public double AmbiguousRangeLower { get; set; } = 0.35;
|
||||
|
||||
/// <summary>
|
||||
/// Upper bound of the ambiguous range (probability).
|
||||
/// Default: 0.65
|
||||
/// </summary>
|
||||
public double AmbiguousRangeUpper { get; set; } = 0.65;
|
||||
|
||||
#endregion
|
||||
|
||||
#region Advanced Options
|
||||
|
||||
/// <summary>
|
||||
/// Apply median filter to reduce noise.
|
||||
/// Default: false
|
||||
/// </summary>
|
||||
public bool EnableMedianFilter { get; set; } = false;
|
||||
|
||||
/// <summary>
|
||||
/// Kernel size for median filter (must be odd number).
|
||||
/// Range: [3, 7], Default: 3
|
||||
/// </summary>
|
||||
public int MedianFilterKernelSize { get; set; } = 3;
|
||||
|
||||
#endregion
|
||||
}
|
||||
Reference in New Issue
Block a user