first commit -push

This commit is contained in:
dungtt
2025-10-15 15:15:53 +07:00
parent 674ae395be
commit a9577c5756
885 changed files with 74595 additions and 0 deletions

View File

@@ -0,0 +1,108 @@
namespace RobotNet.MapManager.Services;
public class LoggerController<T>(ILogger<T> Logger)
{
public event Action? LoggerUpdate;
public void Write(string message, LogLevel level)
{
switch (level)
{
case LogLevel.Trace:
Logger.LogTrace("{mes}", message);
break;
case LogLevel.Debug:
Logger.LogDebug("{mes}", message);
break;
case LogLevel.Information:
Logger.LogInformation("{mes}", message);
break;
case LogLevel.Warning:
Logger.LogWarning("{mes}", message);
break;
case LogLevel.Error:
Logger.LogError("{mes}", message);
break;
case LogLevel.Critical:
Logger.LogCritical("{mes}", message);
break;
}
LoggerUpdate?.Invoke();
}
public void Write(string message)
{
Write(message, LogLevel.Information);
}
public async Task WriteAsync(string message)
{
var write = Task.Run(() => Write(message));
await write.WaitAsync(CancellationToken.None);
}
public async Task TraceAsync(string message)
{
var write = Task.Run(() => Write(message, LogLevel.Trace));
await write.WaitAsync(CancellationToken.None);
}
public async Task DebugAsync(string message)
{
var write = Task.Run(() => Write(message, LogLevel.Debug));
await write.WaitAsync(CancellationToken.None);
}
public async Task InfoAsync(string message)
{
var write = Task.Run(() => Write(message, LogLevel.Information));
await write.WaitAsync(CancellationToken.None);
}
public async Task WarningAsync(string message)
{
var write = Task.Run(() => Write(message, LogLevel.Warning));
await write.WaitAsync(CancellationToken.None);
}
public async Task ErrorAsync(string message)
{
var write = Task.Run(() => Write(message, LogLevel.Error));
await write.WaitAsync(CancellationToken.None);
}
public async Task CriticalAsync(string message)
{
var write = Task.Run(() => Write(message, LogLevel.Critical));
await write.WaitAsync(CancellationToken.None);
}
public void Trace(string message)
{
Write(message, LogLevel.Trace);
}
public void Debug(string message)
{
Write(message, LogLevel.Debug);
}
public void Info(string message)
{
Write(message, LogLevel.Information);
}
public void Warning(string message)
{
Write(message, LogLevel.Warning);
}
public void Error(string message)
{
Write(message, LogLevel.Error);
}
public void Critical(string message)
{
Write(message, LogLevel.Critical);
}
}

View File

@@ -0,0 +1,140 @@
using Minio;
using Minio.DataModel.Args;
using Minio.Exceptions;
namespace RobotNet.MapManager.Services;
public class MapEditorStorageRepository
{
private class MinioOption
{
public bool UsingLocal { get; set; }
public string? Endpoint { get; set; }
public string? User { get; set; }
public string? Password { get; set; }
public string? Bucket { get; set; }
}
private readonly IMinioClient MinioClient;
private readonly MinioOption MinioOptions = new();
public MapEditorStorageRepository(IConfiguration configuration)
{
configuration.Bind("MinIO", MinioOptions);
MinioClient = new MinioClient()
.WithEndpoint(MinioOptions.Endpoint)
.WithCredentials(MinioOptions.User, MinioOptions.Password)
.WithSSL(false)
.Build();
}
public async Task<(bool, string)> UploadAsync(string path, string objectName, Stream data, long size, string contentType, CancellationToken cancellationToken)
{
try
{
if (!MinioOptions.UsingLocal)
{
var beArgs = new BucketExistsArgs().WithBucket(MinioOptions.Bucket);
bool found = await MinioClient.BucketExistsAsync(beArgs, cancellationToken).ConfigureAwait(false);
if (!found)
{
var mbArgs = new MakeBucketArgs()
.WithBucket(MinioOptions.Bucket);
await MinioClient.MakeBucketAsync(mbArgs, cancellationToken).ConfigureAwait(false);
}
var getListBucketsTask = await MinioClient.ListBucketsAsync(cancellationToken);
var putObjectArgs = new PutObjectArgs()
.WithBucket(MinioOptions.Bucket)
.WithObject($"{path}/{objectName}")
.WithObjectSize(size)
.WithStreamData(data)
.WithContentType(contentType);
await MinioClient.PutObjectAsync(putObjectArgs, cancellationToken).ConfigureAwait(false);
return (true, "");
}
var mapImageFolder = string.IsNullOrEmpty(MinioOptions.Bucket) ? "MapImages" : MinioOptions.Bucket;
if (!Directory.Exists(mapImageFolder)) Directory.CreateDirectory(mapImageFolder);
var folderPath = Path.Combine(mapImageFolder, path);
if (!Directory.Exists(folderPath)) Directory.CreateDirectory(folderPath);
var pathLocal = Path.Combine(folderPath, $"{objectName}.png");
if (File.Exists($"{pathLocal}.bk")) File.Delete($"{pathLocal}.bk");
if (File.Exists(pathLocal)) File.Move(pathLocal, $"{pathLocal}.bk");
using (Stream fileStream = new FileStream(pathLocal, FileMode.Create))
{
await data.CopyToAsync(fileStream, cancellationToken);
}
return (true, "");
}
catch (MinioException ex)
{
return (false, ex.Message);
}
}
public (bool usingLocal, string url) GetUrl(string path, string objectName)
{
try
{
if (!MinioOptions.UsingLocal)
{
var presignedGetObjectArgs = new PresignedGetObjectArgs()
.WithBucket(MinioOptions.Bucket)
.WithObject($"{path}/{objectName}")
.WithExpiry(60 * 60 * 24);
var url = MinioClient.PresignedGetObjectAsync(presignedGetObjectArgs);
url.Wait();
return (false, url.Result);
}
var mapImageFolder = string.IsNullOrEmpty(MinioOptions.Bucket) ? "MapImages" : MinioOptions.Bucket;
if (Directory.Exists(mapImageFolder))
{
var folderPath = Path.Combine(mapImageFolder, path);
if (Directory.Exists(folderPath))
{
var pathLocal = Path.Combine(folderPath, $"{objectName}.png");
if (File.Exists(pathLocal))
{
return (true, pathLocal);
}
}
}
return (true, "");
}
catch (MinioException ex)
{
return (false, ex.Message);
}
}
public async Task<(bool, string)> DeleteAsync(string path, string objectName, CancellationToken cancellationToken)
{
try
{
if (!MinioOptions.UsingLocal)
{
var removeObjectArgs = new RemoveObjectArgs()
.WithBucket(MinioOptions.Bucket)
.WithObject($"{path}/{objectName}");
await MinioClient.RemoveObjectAsync(removeObjectArgs, cancellationToken).ConfigureAwait(false);
return (true, "");
}
var mapImageFolder = string.IsNullOrEmpty(MinioOptions.Bucket) ? "MapImages" : MinioOptions.Bucket;
if (Directory.Exists(mapImageFolder))
{
var folderPath = Path.Combine(mapImageFolder, path);
if (Directory.Exists(folderPath))
{
var pathLocal = Path.Combine(folderPath, $"{objectName}.png");
if (File.Exists(pathLocal)) File.Delete(pathLocal);
if (File.Exists($"{pathLocal}.bk")) File.Delete($"{pathLocal}.bk");
}
}
return (true, "");
}
catch (MinioException ex)
{
return (false, ex.Message);
}
}
}

View File

@@ -0,0 +1,161 @@
using RobotNet.MapManager.Data;
using RobotNet.MapShares.Dtos;
using RobotNet.MapShares.Enums;
namespace RobotNet.MapManager.Services;
public class ServerHelper
{
public static Edge CreateEdge(Map map, Guid startNodeId, Guid endNodeId, TrajectoryDegree trajectoryDegree, double cpX1 = 0, double cpY1 = 0, double cpX2 = 0, double cpY2 = 0)
{
return new Edge()
{
MapId = map.Id,
StartNodeId = startNodeId,
EndNodeId = endNodeId,
TrajectoryDegree = trajectoryDegree,
DirectionAllowed = map.EdgeDirectionAllowedDefault,
RotationAllowed = map.EdgeRotationAllowedDefault,
MaxSpeed = trajectoryDegree == TrajectoryDegree.One ? map.EdgeStraightMaxSpeedDefault : map.EdgeCurveMaxSpeedDefault,
MaxRotationSpeed = map.EdgeMaxRotationSpeedDefault,
MaxHeight = map.EdgeMaxHeightDefault,
MinHeight = map.EdgeMinHeightDefault,
Actions = "[]",
AllowedDeviationXy = map.EdgeAllowedDeviationXyDefault,
AllowedDeviationTheta = map.EdgeAllowedDeviationThetaDefault,
ControlPoint1X = cpX1,
ControlPoint1Y = cpY1,
ControlPoint2X = cpX2,
ControlPoint2Y = cpY2,
};
}
public static Node CreateNode(Map map, double x, double y)
{
return new Node()
{
MapId = map.Id,
Name = map.NodeNameAutoGenerate ? $"{map.NodeNameTemplateDefault}{++map.NodeCount}" : string.Empty,
X = x,
Y = y,
Theta = 0,
AllowedDeviationXy = map.NodeAllowedDeviationXyDefault,
AllowedDeviationTheta = map.NodeAllowedDeviationThetaDefault,
Actions = "[]",
};
}
public static EdgeDto CreateEdgeDto(Edge edge, Node startNode, Node endNode)
{
return new EdgeDto()
{
Id = edge.Id,
MapId = edge.MapId,
StartNodeId = edge.StartNodeId,
EndNodeId = edge.EndNodeId,
TrajectoryDegree = edge.TrajectoryDegree,
ControlPoint1X = edge.ControlPoint1X,
ControlPoint1Y = edge.ControlPoint1Y,
ControlPoint2X = edge.ControlPoint2X,
ControlPoint2Y = edge.ControlPoint2Y,
DirectionAllowed = edge.DirectionAllowed,
RotationAllowed = edge.RotationAllowed,
MaxSpeed = edge.MaxSpeed,
MaxRotationSpeed = edge.MaxRotationSpeed,
MaxHeight = edge.MaxHeight,
MinHeight = edge.MinHeight,
Actions = edge.Actions,
AllowedDeviationXy = edge.AllowedDeviationXy,
AllowedDeviationTheta = edge.AllowedDeviationTheta,
StartNode = new NodeDto()
{
Id = startNode.Id,
Name = startNode.Name,
MapId = startNode.MapId,
Theta = startNode.Theta,
X = startNode.X,
Y = startNode.Y,
Actions = startNode.Actions,
AllowedDeviationXy = startNode.AllowedDeviationXy,
AllowedDeviationTheta = startNode.AllowedDeviationTheta,
},
EndNode = new NodeDto()
{
Id = endNode.Id,
Name = endNode.Name,
MapId = endNode.MapId,
Theta = endNode.Theta,
X = endNode.X,
Y = endNode.Y,
AllowedDeviationXy = endNode.AllowedDeviationXy,
AllowedDeviationTheta = endNode.AllowedDeviationTheta,
Actions = endNode.Actions,
},
};
}
public static NodeDto CreateNodeDto(Node node)
{
return new NodeDto()
{
Id = node.Id,
Name = node.Name,
MapId = node.MapId,
Theta = node.Theta,
X = node.X,
Y = node.Y,
AllowedDeviationXy = node.AllowedDeviationXy,
AllowedDeviationTheta = node.AllowedDeviationTheta,
Actions = node.Actions,
};
}
public static Edge? GetClosesEdge(double x, double y, IEnumerable<Node> nodes, IEnumerable<Edge> edges, double allowDistance)
{
double minDistance = double.MaxValue;
Edge? edgeResult = null;
foreach (var edge in edges)
{
if (edge is not null)
{
var startNode = nodes.FirstOrDefault(n => n.Id == edge.StartNodeId);
var endNode = nodes.FirstOrDefault(n => n.Id == edge.EndNodeId);
if (startNode is null || endNode is null) continue;
var distance = DistanceToSegment(x, y, startNode.X, startNode.Y, endNode.X, endNode.Y);
if (distance < minDistance)
{
minDistance = distance;
edgeResult = edge;
}
}
}
if (minDistance > allowDistance) return null;
return edgeResult;
}
private static double DistanceToSegment(double x, double y, double x1, double y1, double x2, double y2)
{
double dx = x2 - x1;
double dy = y2 - y1;
double segmentLengthSquared = dx * dx + dy * dy;
double t;
if (segmentLengthSquared == 0)
{
t = 0;
}
else
{
t = ((x - x1) * dx + (y - y1) * dy) / segmentLengthSquared;
t = Math.Max(0, Math.Min(1, t));
}
double nearestX = x1 + t * dx;
double nearestY = y1 + t * dy;
double distanceSquared = (x - nearestX) * (x - nearestX) + (y - nearestY) * (y - nearestY);
return Math.Sqrt(distanceSquared);
}
}