This commit is contained in:
Đăng Nguyễn 2025-12-30 16:59:08 +07:00
parent 2785a8f161
commit b3f765d261
11 changed files with 88 additions and 75 deletions

View File

@ -1,2 +1,5 @@
# RobotApp # RobotApp
docker build -t robotics.doc/robotnet/robotapp_dde:2.7 .
docker save -o robotapp-dde.2.7.tar robotics.doc/robotnet/robotapp_dde:2.7
scp .\robotapp-dde.2.7.tar robotics@172.20.235.176:~/DDE

View File

@ -21,13 +21,11 @@
<MudIconButton Icon="@Icons.Material.Filled.Edit" <MudIconButton Icon="@Icons.Material.Filled.Edit"
Color="Color.Primary" Color="Color.Primary"
Size="Size.Small" Size="Size.Small"
OnClick="@(() => EditNodeAsync(node))" OnClick="@(() => EditNodeAsync(node))" />
StopPropagation />
<MudIconButton Icon="@Icons.Material.Filled.Delete" <MudIconButton Icon="@Icons.Material.Filled.Delete"
Color="Color.Error" Color="Color.Error"
Size="Size.Small" Size="Size.Small"
OnClick="@(() => RemoveNodeAsync(node))" OnClick="@(() => RemoveNodeAsync(node))" />
StopPropagation />
</div> </div>
</div> </div>
</TitleContent> </TitleContent>
@ -78,22 +76,22 @@
Label="Y" /> Label="Y" />
</MudItem> </MudItem>
<MudItem xs="12"> @* <MudItem xs="12">
<MudTextField Value="@node.NodePosition.MapId" <MudTextField Value="@node.NodePosition.MapId"
ValueChanged="@((string v) => SetValue(() => node.NodePosition.MapId = v))" ValueChanged="@((string v) => SetValue(() => node.NodePosition.MapId = v))"
Immediate="true" Immediate="true"
Label="Map ID" /> Label="Map ID" />
</MudItem> </MudItem> *@
<MudItem xs="6"> @* <MudItem xs="6">
<MudNumericField T="double" <MudNumericField T="double"
Value="@node.NodePosition.Theta" Value="@node.NodePosition.Theta"
ValueChanged="@((double v) => SetValue(() => node.NodePosition.Theta = v))" ValueChanged="@((double v) => SetValue(() => node.NodePosition.Theta = v))"
Immediate="true" Immediate="true"
Label="Theta (rad)" /> Label="Theta (rad)" />
</MudItem> </MudItem> *@
<MudItem xs="6"> @* <MudItem xs="6">
<MudNumericField T="double" <MudNumericField T="double"
Value="@node.NodePosition.AllowedDeviationXY" Value="@node.NodePosition.AllowedDeviationXY"
ValueChanged="@((double v) => SetValue(() => node.NodePosition.AllowedDeviationXY = v))" ValueChanged="@((double v) => SetValue(() => node.NodePosition.AllowedDeviationXY = v))"
@ -107,7 +105,7 @@
ValueChanged="@((double v) => SetValue(() => node.NodePosition.AllowedDeviationTheta = v))" ValueChanged="@((double v) => SetValue(() => node.NodePosition.AllowedDeviationTheta = v))"
Immediate="true" Immediate="true"
Label="Allowed Dev Theta" /> Label="Allowed Dev Theta" />
</MudItem> </MudItem> *@
<!-- Actions --> <!-- Actions -->
<MudItem xs="12"> <MudItem xs="12">

View File

@ -84,7 +84,7 @@
new JsonSerializerOptions new JsonSerializerOptions
{ {
WriteIndented = true, WriteIndented = true,
DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull PropertyNamingPolicy = JsonNamingPolicy.CamelCase,
}); });
} }
private async Task OpenImportDialog() private async Task OpenImportDialog()
@ -220,7 +220,12 @@
try try
{ {
var orderMsg = JsonSerializer.Deserialize<OrderMsg>(OrderJson); var orderMsg = JsonSerializer.Deserialize<OrderMsg>(OrderJson,
new JsonSerializerOptions
{
WriteIndented = true,
PropertyNamingPolicy = JsonNamingPolicy.CamelCase,
});
if (orderMsg is null) if (orderMsg is null)
{ {
Snackbar.Add("Unable to convert JSON to Order", Severity.Warning); Snackbar.Add("Unable to convert JSON to Order", Severity.Warning);
@ -251,20 +256,17 @@
} }
} }
var response = await Http.PostAsJsonAsync( var response = await Http.PostAsJsonAsync("/api/order",orderMsg);
"/api/order",
JsonSerializer.Deserialize<OrderMsg>(OrderJson)
);
sendSuccess = response.IsSuccessStatusCode; sendSuccess = response.IsSuccessStatusCode;
} }
catch(JsonException jsonEx) catch(JsonException jsonEx)
{ {
Snackbar.Add($"Json to Order failed: {jsonEx.Message}", Severity.Warning); Snackbar.Add($"Json to Order failed: {jsonEx.Message}", Severity.Warning);
} }
catch catch (Exception ex)
{ {
Snackbar.Add($"Send Order failed: {ex.Message}", Severity.Warning);
sendSuccess = false; sendSuccess = false;
} }

View File

@ -127,11 +127,11 @@ public static class QuarterGeometry
public class OrderMessage public class OrderMessage
{ {
public int HeaderId { get; set; } public int HeaderId { get; set; }
public string Timestamp { get; set; } = ""; public string Timestamp { get; set; } = DateTime.UtcNow.ToString("yyyy-MM-ddTHH:mm:ss.fffZ");
public string Version { get; set; } = "v1"; public string Version { get; set; } = "2.1.0";
public string Manufacturer { get; set; } = "PNKX"; public string Manufacturer { get; set; } = "PhenikaaX";
public string SerialNumber { get; set; } = "T800-002"; public string SerialNumber { get; set; } = "T800-003";
public string OrderId { get; set; } public string OrderId { get; set; } = "";
public int OrderUpdateId { get; set; } public int OrderUpdateId { get; set; }
public string? ZoneSetId { get; set; } public string? ZoneSetId { get; set; }
@ -411,9 +411,7 @@ public class OrderMessage
{ {
HeaderId = (uint)HeaderId++, HeaderId = (uint)HeaderId++,
Timestamp = string.IsNullOrWhiteSpace(Timestamp) Timestamp = DateTime.UtcNow.ToString("yyyy-MM-ddTHH:mm:ss.fffZ"),
? DateTime.UtcNow.ToString("O")
: Timestamp,
Version = Version, Version = Version,
Manufacturer = Manufacturer, Manufacturer = Manufacturer,

View File

@ -2,7 +2,6 @@
namespace RobotApp.VDA5050.Order; namespace RobotApp.VDA5050.Order;
#nullable disable
public class Edge public class Edge
{ {
@ -26,7 +25,7 @@ public class Edge
public bool RotationAllowed { get; set; } public bool RotationAllowed { get; set; }
public double MaxRotationSpeed { get; set; } public double MaxRotationSpeed { get; set; }
public double Length { get; set; } public double Length { get; set; }
public Trajectory Trajectory { get; set; } public Trajectory? Trajectory { get; set; }
public Corridor Corridor { get; set; } = new(); public Corridor Corridor { get; set; } = new();
[Required] [Required]
public InstantAction.Action[] Actions { get; set; } = []; public InstantAction.Action[] Actions { get; set; } = [];

View File

@ -21,7 +21,7 @@ public enum ActionType
//liftUp, //liftUp,
//liftDown, //liftDown,
//liftRotate, //liftRotate,
//rotate, rotate,
//rotateKeepLift, //rotateKeepLift,
//mutedBaseOn, //mutedBaseOn,
//mutedBaseOff, //mutedBaseOff,

View File

@ -21,7 +21,7 @@ public class RobotActionStorage(IServiceProvider ServiceProvider)
ActionType.drop => new RobotDropAction(ServiceProvider), ActionType.drop => new RobotDropAction(ServiceProvider),
ActionType.pick => new RobotPickAction(ServiceProvider), ActionType.pick => new RobotPickAction(ServiceProvider),
//ActionType.liftRotate => new RobotLiftRotateAction(ServiceProvider), //ActionType.liftRotate => new RobotLiftRotateAction(ServiceProvider),
//ActionType.rotate => new RobotRotateAction(ServiceProvider), ActionType.rotate => new RobotRotateAction(ServiceProvider),
//ActionType.rotateKeepLift => new RobotRotateKeepLift(ServiceProvider), //ActionType.rotateKeepLift => new RobotRotateKeepLift(ServiceProvider),
//ActionType.mutedBaseOn => new RobotMutedBaseOnAction(ServiceProvider), //ActionType.mutedBaseOn => new RobotMutedBaseOnAction(ServiceProvider),
//ActionType.mutedBaseOff => new RobotMutedBaseOffAction(ServiceProvider), //ActionType.mutedBaseOff => new RobotMutedBaseOffAction(ServiceProvider),

View File

@ -26,12 +26,16 @@ public class RobotConnection(RobotConfiguration RobotConfiguration,
{ {
//Logger.Debug($"Nhận Order: {data}"); //Logger.Debug($"Nhận Order: {data}");
var msg = JsonSerializer.Deserialize<OrderMsg>(data, JsonOptionExtends.Read); var msg = JsonSerializer.Deserialize<OrderMsg>(data, JsonOptionExtends.Read);
if (msg is null || string.IsNullOrEmpty(msg.SerialNumber) || msg.SerialNumber != RobotConfiguration.SerialNumber) return; if (msg is null || string.IsNullOrEmpty(msg.SerialNumber) || msg.SerialNumber != RobotConfiguration.SerialNumber)
{
Logger.Warning($"SerialNumber cuả order không hợp lệ: message SerialNumber {msg?.SerialNumber}");
return;
}
OrderUpdated?.Invoke(msg); OrderUpdated?.Invoke(msg);
} }
catch (Exception ex) catch (Exception ex)
{ {
Logger.Warning($"Nhận Order xảy ra lỗi: {ex.Message} - {ex.StackTrace}"); Logger.Warning($"Nhận Order xảy ra lỗi: {ex.Message}");
} }
} }
@ -41,12 +45,16 @@ public class RobotConnection(RobotConfiguration RobotConfiguration,
{ {
//Logger.Debug($"Nhận InstanceActions: {data}"); //Logger.Debug($"Nhận InstanceActions: {data}");
var msg = JsonSerializer.Deserialize<InstantActionsMsg>(data, JsonOptionExtends.Read); var msg = JsonSerializer.Deserialize<InstantActionsMsg>(data, JsonOptionExtends.Read);
if (msg is null || string.IsNullOrEmpty(msg.SerialNumber) || msg.SerialNumber != RobotConfiguration.SerialNumber) return; if (msg is null || string.IsNullOrEmpty(msg.SerialNumber) || msg.SerialNumber != RobotConfiguration.SerialNumber)
{
Logger.Warning($"SerialNumber của action không hợp lệ: message SerialNumber {msg?.SerialNumber}");
return;
}
ActionUpdated?.Invoke(msg); ActionUpdated?.Invoke(msg);
} }
catch (Exception ex) catch (Exception ex)
{ {
Logger.Warning($"Nhận InstanceActions xảy ra lỗi: {ex.Message} - {ex.StackTrace}"); Logger.Warning($"Nhận InstanceActions xảy ra lỗi: {ex.Message}");
} }
} }

View File

@ -25,7 +25,7 @@ public class RobotFactsheet(RobotConnection RobotConnection, RobotConfiguration
{ ActionType.pick, Pick}, { ActionType.pick, Pick},
{ ActionType.drop, Drop}, { ActionType.drop, Drop},
//{ ActionType.liftRotate, LiftRotate}, //{ ActionType.liftRotate, LiftRotate},
//{ ActionType.rotate, Rotate}, { ActionType.rotate, Rotate},
//{ ActionType.rotateKeepLift, RotateKeepLift}, //{ ActionType.rotateKeepLift, RotateKeepLift},
//{ ActionType.mutedBaseOn, MutedBaseOn}, //{ ActionType.mutedBaseOn, MutedBaseOn},
//{ ActionType.mutedBaseOff, MutedBaseOff}, //{ ActionType.mutedBaseOff, MutedBaseOff},
@ -224,22 +224,22 @@ public class RobotFactsheet(RobotConnection RobotConnection, RobotConfiguration
// BlockingTypes = [BlockingType.HARD.ToString()], // BlockingTypes = [BlockingType.HARD.ToString()],
//}; //};
//public readonly static AgvAction Rotate = new() public readonly static AgvAction Rotate = new()
//{ {
// ActionType = ActionType.rotate.ToString(), ActionType = ActionType.rotate.ToString(),
// ActionDescription = "Xoay robot tại chỗ.", ActionDescription = "Xoay robot tại chỗ.",
// ActionScopes = [ActionScopes.INSTANT.ToString(), ActionScopes.NODE.ToString()], ActionScopes = [ActionScopes.INSTANT.ToString(), ActionScopes.NODE.ToString()],
// ActionParameters = [ ActionParameters = [
// new() new()
// { {
// Key = "angle", Key = "angle",
// Description = "Góc xoay của robot. (rad)", Description = "Góc xoay của robot. (rad)",
// ValueDataType = ValueDataType.FLOAT.ToString(), ValueDataType = ValueDataType.FLOAT.ToString(),
// IsOptional = false, IsOptional = false,
// }], }],
// ResultDescription = "Robot đã xoay tại chỗ.", ResultDescription = "Robot đã xoay tại chỗ.",
// BlockingTypes = [BlockingType.HARD.ToString()], BlockingTypes = [BlockingType.HARD.ToString()],
//}; };
//public readonly static AgvAction RotateKeepLift = new() //public readonly static AgvAction RotateKeepLift = new()
//{ //{

View File

@ -3,7 +3,7 @@ using RobotApp.VDA5050.State;
namespace RobotApp.Services.Robot; namespace RobotApp.Services.Robot;
public class RobotLoads(IPeripheral PeriperalManager) : ILoad public class RobotLoads() : ILoad
{ {
//public Load[] Load => PeriperalManager.HasLoad ? [GetLoad()] : []; //public Load[] Load => PeriperalManager.HasLoad ? [GetLoad()] : [];
public Load[] Load { get; private set; } = []; public Load[] Load { get; private set; } = [];

View File

@ -274,32 +274,37 @@ public class RobotLocalization(RobotConfiguration RobotConfiguration, Simulation
{ {
try try
{ {
var xyzw = QuaternionToXYZW(0, 0, theta); if (IsSimulation) SimVisualization.LocalizationInitialize(x, y, theta);
var response = XlocClient.SetInitialPose(new SetInitialPoseRequest()
{
InitialPose = new Pose()
{
Position = new Point()
{
X = x,
Y = y,
Z = 0,
},
Orientation = new Quaternion()
{
X = xyzw.x,
Y = xyzw.y,
Z = xyzw.z,
W = xyzw.w
}
}
});
if (response.Status.Code == StatusResponse.Types.StatusCode.Ok) return new(true);
else else
{ {
Logger.Warning("Khởi tạo vị trí cho robot thất bại. Kết quả trả về: {response.Status.Code} - {response.Status.Message}"); var xyzw = QuaternionToXYZW(0, 0, theta);
return new(false, "Khởi tạo vị trí cho robot thất bại"); var response = XlocClient.SetInitialPose(new SetInitialPoseRequest()
{
InitialPose = new Pose()
{
Position = new Point()
{
X = x,
Y = y,
Z = 0,
},
Orientation = new Quaternion()
{
X = xyzw.x,
Y = xyzw.y,
Z = xyzw.z,
W = xyzw.w
}
}
});
if (response.Status.Code == StatusResponse.Types.StatusCode.Ok) return new(true);
else
{
Logger.Warning("Khởi tạo vị trí cho robot thất bại. Kết quả trả về: {response.Status.Code} - {response.Status.Message}");
return new(false, "Khởi tạo vị trí cho robot thất bại");
}
} }
return new(true);
} }
catch (Exception ex) catch (Exception ex)
{ {