update
This commit is contained in:
parent
e4e135e35f
commit
a51cfe80c8
|
|
@ -13,7 +13,7 @@
|
||||||
<!-- Header Dashboard -->
|
<!-- Header Dashboard -->
|
||||||
<MudPaper Class="pa-6 mb-4 d-flex align-center justify-space-between" Elevation="3">
|
<MudPaper Class="pa-6 mb-4 d-flex align-center justify-space-between" Elevation="3">
|
||||||
<div>
|
<div>
|
||||||
<MudText Typo="Typo.h3" Class="mb-2" >Robot Dashboard</MudText>
|
<MudText Typo="Typo.h3" Class="mb-2">Robot Dashboard</MudText>
|
||||||
@if (CurrentState != null)
|
@if (CurrentState != null)
|
||||||
{
|
{
|
||||||
<MudText Typo="Typo.subtitle1">
|
<MudText Typo="Typo.subtitle1">
|
||||||
|
|
@ -38,8 +38,8 @@
|
||||||
{
|
{
|
||||||
<MudChip T="string"
|
<MudChip T="string"
|
||||||
Icon="@(IsConnected
|
Icon="@(IsConnected
|
||||||
? Icons.Material.Filled.CheckCircle
|
? Icons.Material.Filled.CheckCircle
|
||||||
: Icons.Material.Filled.Error)"
|
: Icons.Material.Filled.Error)"
|
||||||
Size="Size.Large"
|
Size="Size.Large"
|
||||||
Color="@(IsConnected ? Color.Success : Color.Error)"
|
Color="@(IsConnected ? Color.Success : Color.Error)"
|
||||||
Variant="Variant.Filled"
|
Variant="Variant.Filled"
|
||||||
|
|
@ -152,7 +152,7 @@
|
||||||
Rounded="true"
|
Rounded="true"
|
||||||
Striped="true"
|
Striped="true"
|
||||||
Color="@(msg.BatteryState.BatteryCharge > 50 ? Color.Success :
|
Color="@(msg.BatteryState.BatteryCharge > 50 ? Color.Success :
|
||||||
msg.BatteryState.BatteryCharge > 20 ? Color.Warning : Color.Error)"
|
msg.BatteryState.BatteryCharge > 20 ? Color.Warning : Color.Error)"
|
||||||
Class="mb-4"
|
Class="mb-4"
|
||||||
Style="height: 28px;" />
|
Style="height: 28px;" />
|
||||||
|
|
||||||
|
|
@ -266,7 +266,7 @@
|
||||||
<MudChip T="string"
|
<MudChip T="string"
|
||||||
Size="Size.Small"
|
Size="Size.Small"
|
||||||
Color="@(context.Level.Contains("ERROR", StringComparison.OrdinalIgnoreCase) ? Color.Error :
|
Color="@(context.Level.Contains("ERROR", StringComparison.OrdinalIgnoreCase) ? Color.Error :
|
||||||
context.Level.Contains("WARN", StringComparison.OrdinalIgnoreCase) ? Color.Warning : Color.Info)"
|
context.Level.Contains("WARN", StringComparison.OrdinalIgnoreCase) ? Color.Warning : Color.Info)"
|
||||||
Variant="@Variant.Filled">
|
Variant="@Variant.Filled">
|
||||||
@context.Level
|
@context.Level
|
||||||
</MudChip>
|
</MudChip>
|
||||||
|
|
@ -317,8 +317,8 @@
|
||||||
<MudChip T="string"
|
<MudChip T="string"
|
||||||
Size="Size.Small"
|
Size="Size.Small"
|
||||||
Color="@(context.ActionStatus == "RUNNING" ? Color.Info :
|
Color="@(context.ActionStatus == "RUNNING" ? Color.Info :
|
||||||
context.ActionStatus == "FINISHED" ? Color.Success :
|
context.ActionStatus == "FINISHED" ? Color.Success :
|
||||||
context.ActionStatus == "FAILED" ? Color.Error : Color.Default)"
|
context.ActionStatus == "FAILED" ? Color.Error : Color.Default)"
|
||||||
Variant="@Variant.Filled">
|
Variant="@Variant.Filled">
|
||||||
@context.ActionStatus
|
@context.ActionStatus
|
||||||
</MudChip>
|
</MudChip>
|
||||||
|
|
@ -373,45 +373,34 @@
|
||||||
|
|
||||||
private StateMsg? CurrentState;
|
private StateMsg? CurrentState;
|
||||||
private bool IsConnected;
|
private bool IsConnected;
|
||||||
private readonly string RobotSerial = "T800-002";
|
|
||||||
private List<MessageRow> MessageRows = new();
|
private List<MessageRow> MessageRows = new();
|
||||||
|
|
||||||
protected override async Task OnInitializedAsync()
|
protected override async Task OnAfterRenderAsync(bool firstRender)
|
||||||
{
|
{
|
||||||
|
await base.OnAfterRenderAsync(firstRender);
|
||||||
|
if (!firstRender) return;
|
||||||
RobotStateClient.OnStateReceived += OnRobotStateReceived;
|
RobotStateClient.OnStateReceived += OnRobotStateReceived;
|
||||||
RobotStateClient.OnRobotConnectionChanged += OnRobotConnectionChanged;
|
RobotStateClient.OnRobotConnectionChanged += OnRobotConnectionChanged;
|
||||||
|
|
||||||
if (RobotStateClient.ConnectionState == RobotClientState.Disconnected)
|
await RobotStateClient.StartAsync();
|
||||||
{
|
CurrentState = RobotStateClient.GetLatestState();
|
||||||
await RobotStateClient.StartAsync();
|
|
||||||
}
|
|
||||||
|
|
||||||
await RobotStateClient.SubscribeRobotAsync(RobotSerial);
|
|
||||||
|
|
||||||
CurrentState = RobotStateClient.GetLatestState(RobotSerial);
|
|
||||||
IsConnected = RobotStateClient.IsRobotConnected;
|
IsConnected = RobotStateClient.IsRobotConnected;
|
||||||
|
|
||||||
UpdateMessageRows();
|
UpdateMessageRows();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnRobotConnectionChanged(bool connected)
|
private void OnRobotConnectionChanged(bool connected)
|
||||||
{
|
{
|
||||||
InvokeAsync(() =>
|
IsConnected = connected;
|
||||||
{
|
StateHasChanged();
|
||||||
IsConnected = connected;
|
|
||||||
StateHasChanged();
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private void OnRobotStateReceived(string serialNumber, StateMsg state)
|
private void OnRobotStateReceived(string serialNumber, StateMsg state)
|
||||||
{
|
{
|
||||||
if (serialNumber != RobotSerial) return;
|
CurrentState = state;
|
||||||
InvokeAsync(() =>
|
UpdateMessageRows();
|
||||||
{
|
StateHasChanged();
|
||||||
CurrentState = state;
|
|
||||||
UpdateMessageRows();
|
|
||||||
StateHasChanged();
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void UpdateMessageRows()
|
private void UpdateMessageRows()
|
||||||
|
|
|
||||||
|
|
@ -17,6 +17,7 @@
|
||||||
|
|
||||||
protected override async Task OnAfterRenderAsync(bool firstRender)
|
protected override async Task OnAfterRenderAsync(bool firstRender)
|
||||||
{
|
{
|
||||||
|
await base.OnAfterRenderAsync(firstRender);
|
||||||
if (firstRender)
|
if (firstRender)
|
||||||
{
|
{
|
||||||
MonitorService.OnDataReceived += OnMonitorDataReceived;
|
MonitorService.OnDataReceived += OnMonitorDataReceived;
|
||||||
|
|
@ -28,7 +29,7 @@
|
||||||
{
|
{
|
||||||
_monitorData = data;
|
_monitorData = data;
|
||||||
RobotMonitorViewRef?.UpdatePath();
|
RobotMonitorViewRef?.UpdatePath();
|
||||||
InvokeAsync(StateHasChanged);
|
StateHasChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
public async ValueTask DisposeAsync()
|
public async ValueTask DisposeAsync()
|
||||||
|
|
@ -41,3 +42,7 @@
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -107,7 +107,7 @@ public sealed class RobotStateClient : IAsyncDisposable
|
||||||
// ================= SIGNALR HANDLERS =================
|
// ================= SIGNALR HANDLERS =================
|
||||||
|
|
||||||
// VDA5050 State
|
// VDA5050 State
|
||||||
_connection.On<string>("ReceiveState", HandleState);
|
_connection.On<StateMsg>("ReceiveState", HandleState);
|
||||||
|
|
||||||
// Robot connection (bool only)
|
// Robot connection (bool only)
|
||||||
_connection.On<bool>("ReceiveRobotConnection", HandleRobotConnection);
|
_connection.On<bool>("ReceiveRobotConnection", HandleRobotConnection);
|
||||||
|
|
@ -125,21 +125,21 @@ public sealed class RobotStateClient : IAsyncDisposable
|
||||||
}
|
}
|
||||||
|
|
||||||
// ================= HANDLE STATE =================
|
// ================= HANDLE STATE =================
|
||||||
private void HandleState(string stateJson)
|
private void HandleState(StateMsg state)
|
||||||
{
|
{
|
||||||
StateMsg? state;
|
//StateMsg? state;
|
||||||
|
|
||||||
try
|
//try
|
||||||
{
|
//{
|
||||||
state = JsonSerializer.Deserialize<StateMsg>(
|
// state = JsonSerializer.Deserialize<StateMsg>(
|
||||||
stateJson,
|
// stateJson,
|
||||||
JsonOptionExtends.Read
|
// JsonOptionExtends.Read
|
||||||
);
|
// );
|
||||||
}
|
//}
|
||||||
catch
|
//catch
|
||||||
{
|
//{
|
||||||
return;
|
// return;
|
||||||
}
|
//}
|
||||||
|
|
||||||
if (state?.SerialNumber == null)
|
if (state?.SerialNumber == null)
|
||||||
return;
|
return;
|
||||||
|
|
@ -189,10 +189,10 @@ public sealed class RobotStateClient : IAsyncDisposable
|
||||||
}
|
}
|
||||||
|
|
||||||
// ================= GET CACHE =================
|
// ================= GET CACHE =================
|
||||||
public StateMsg? GetLatestState(string serialNumber)
|
public StateMsg? GetLatestState()
|
||||||
{
|
{
|
||||||
LatestStates.TryGetValue(serialNumber, out var state);
|
if (!LatestStates.IsEmpty) return LatestStates.First().Value;
|
||||||
return state;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ================= DISPOSE =================
|
// ================= DISPOSE =================
|
||||||
|
|
|
||||||
|
|
@ -60,3 +60,7 @@ window.robotMonitor = {
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -28,7 +28,6 @@ public class OrderController(IOrder robotOrderController, IInstantActions instan
|
||||||
{
|
{
|
||||||
robotOrderController.StopOrder();
|
robotOrderController.StopOrder();
|
||||||
instantActions.StopOrderAction();
|
instantActions.StopOrderAction();
|
||||||
|
|
||||||
return Ok(new
|
return Ok(new
|
||||||
{
|
{
|
||||||
success = true,
|
success = true,
|
||||||
|
|
|
||||||
|
|
@ -21,8 +21,8 @@ namespace RobotApp.Hubs
|
||||||
// Phương thức này sẽ được gọi từ service để broadcast
|
// Phương thức này sẽ được gọi từ service để broadcast
|
||||||
public async Task SendState(string serialNumber, StateMsg state)
|
public async Task SendState(string serialNumber, StateMsg state)
|
||||||
{
|
{
|
||||||
var json = JsonSerializer.Serialize(state, JsonOptionExtends.Write);
|
//var json = JsonSerializer.Serialize(state, JsonOptionExtends.Write);
|
||||||
await Clients.Group(serialNumber).SendAsync("ReceiveState", json);
|
await Clients.Group(serialNumber).SendAsync("ReceiveState", state);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -12,3 +12,7 @@ public class RobotMonitorHub : Hub
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -63,7 +63,7 @@ builder.Services.AddRobot();
|
||||||
builder.Services.AddSingleton<RobotApp.Services.RobotMonitorService>();
|
builder.Services.AddSingleton<RobotApp.Services.RobotMonitorService>();
|
||||||
builder.Services.AddHostedService(sp => sp.GetRequiredService<RobotApp.Services.RobotMonitorService>());
|
builder.Services.AddHostedService(sp => sp.GetRequiredService<RobotApp.Services.RobotMonitorService>());
|
||||||
|
|
||||||
builder.Services.AddScoped<RobotStateClient>();
|
//builder.Services.AddScoped<RobotStateClient>();
|
||||||
builder.Services.AddHostedService<RobotStatePublisher>();
|
builder.Services.AddHostedService<RobotStatePublisher>();
|
||||||
|
|
||||||
var app = builder.Build();
|
var app = builder.Build();
|
||||||
|
|
|
||||||
|
|
@ -105,7 +105,8 @@ public class RobotErrors : IError
|
||||||
=> CreateError(ErrorType.INITIALIZE_ORDER, "Vui lòng kiểm tra lại order", ErrorLevel.WARNING, $"Order mới nhận được không phải là nối tiếp của order khi LastNodeSequenceId: {lastNodeSequenceId} mà node đầu tiên của order mới có sequence: {newStartNodeSequenceId}");
|
=> CreateError(ErrorType.INITIALIZE_ORDER, "Vui lòng kiểm tra lại order", ErrorLevel.WARNING, $"Order mới nhận được không phải là nối tiếp của order khi LastNodeSequenceId: {lastNodeSequenceId} mà node đầu tiên của order mới có sequence: {newStartNodeSequenceId}");
|
||||||
public static Error Error1018(int oldOrderUpdateId, int newOrderUpdateId)
|
public static Error Error1018(int oldOrderUpdateId, int newOrderUpdateId)
|
||||||
=> CreateError(ErrorType.INITIALIZE_ORDER, "Vui lòng kiểm tra lại OrderUpdateId", ErrorLevel.WARNING, $"OrderUpdateId {newOrderUpdateId} nhận được nhỏ hơn OrderUpdateId hiện tại là {oldOrderUpdateId}");
|
=> CreateError(ErrorType.INITIALIZE_ORDER, "Vui lòng kiểm tra lại OrderUpdateId", ErrorLevel.WARNING, $"OrderUpdateId {newOrderUpdateId} nhận được nhỏ hơn OrderUpdateId hiện tại là {oldOrderUpdateId}");
|
||||||
|
public static Error Error1019()
|
||||||
|
=> CreateError(ErrorType.INITIALIZE_ORDER, "Vui lòng kiểm tra lại Order", ErrorLevel.WARNING, "Order có node đầu tiên quá xa robot");
|
||||||
|
|
||||||
public static Error Error2001()
|
public static Error Error2001()
|
||||||
=> CreateError(ErrorType.READ_PERIPHERAL_FAILURE, "2001", ErrorLevel.FATAL, "Có lỗi xảy ra trong quá trình đọc tín hiệu từ hệ thống ngoại vi(PLC)");
|
=> CreateError(ErrorType.READ_PERIPHERAL_FAILURE, "2001", ErrorLevel.FATAL, "Có lỗi xảy ra trong quá trình đọc tín hiệu từ hệ thống ngoại vi(PLC)");
|
||||||
|
|
|
||||||
|
|
@ -9,6 +9,7 @@ using RobotApp.VDA5050.Order;
|
||||||
using RobotApp.VDA5050.State;
|
using RobotApp.VDA5050.State;
|
||||||
using System.Collections.Concurrent;
|
using System.Collections.Concurrent;
|
||||||
using System.Data;
|
using System.Data;
|
||||||
|
using System.Xml.Linq;
|
||||||
using Action = RobotApp.VDA5050.InstantAction.Action;
|
using Action = RobotApp.VDA5050.InstantAction.Action;
|
||||||
|
|
||||||
namespace RobotApp.Services.Robot;
|
namespace RobotApp.Services.Robot;
|
||||||
|
|
@ -247,11 +248,6 @@ public class RobotOrderController(INavigation NavigationManager,
|
||||||
UpdateState();
|
UpdateState();
|
||||||
}
|
}
|
||||||
|
|
||||||
private bool IsNewPath()
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void ClearLastNode()
|
private void ClearLastNode()
|
||||||
{
|
{
|
||||||
if (LastNode is null) return;
|
if (LastNode is null) return;
|
||||||
|
|
@ -292,6 +288,7 @@ public class RobotOrderController(INavigation NavigationManager,
|
||||||
|
|
||||||
private void HandleOrder()
|
private void HandleOrder()
|
||||||
{
|
{
|
||||||
|
if (Nodes.Length <= 0) return;
|
||||||
if (IsCancelOrder)
|
if (IsCancelOrder)
|
||||||
{
|
{
|
||||||
NavigationManager.CancelMovement();
|
NavigationManager.CancelMovement();
|
||||||
|
|
@ -309,9 +306,13 @@ public class RobotOrderController(INavigation NavigationManager,
|
||||||
{
|
{
|
||||||
var action = FinalAction[0];
|
var action = FinalAction[0];
|
||||||
var robotAction = ActionManager[action.ActionId];
|
var robotAction = ActionManager[action.ActionId];
|
||||||
if (robotAction is null) return;
|
if (robotAction is null)
|
||||||
if (robotAction.IsCompleted) FinalAction.Remove(action);
|
{
|
||||||
if (robotAction.Status == ActionStatus.WAITING) ActionManager.StartOrderAction(action.ActionId);
|
FinalAction.Remove(action);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (robotAction.IsCompleted)
|
||||||
|
if (robotAction.Status == ActionStatus.WAITING) ActionManager.StartOrderAction(action.ActionId);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
@ -398,6 +399,10 @@ public class RobotOrderController(INavigation NavigationManager,
|
||||||
if (NodeStates.Length != 0 || EdgeStates.Length != 0) HandleUpdateOrder(NewOrderHandler);
|
if (NodeStates.Length != 0 || EdgeStates.Length != 0) HandleUpdateOrder(NewOrderHandler);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
Node startNode = NewOrderHandler.Nodes[0];
|
||||||
|
var nodeDeviation = startNode.NodePosition.AllowedDeviationXY == 0.0 ? NewOrderHandler.Nodes.Length == 1 ? 0.3 : 0.5 : startNode.NodePosition.AllowedDeviationXY;
|
||||||
|
var distance = Localization.DistanceTo(startNode.NodePosition.X, startNode.NodePosition.Y);
|
||||||
|
if (distance > nodeDeviation) throw new OrderException(RobotErrors.Error1019());
|
||||||
HandleNewOrder(NewOrderHandler);
|
HandleNewOrder(NewOrderHandler);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -409,6 +414,7 @@ public class RobotOrderController(INavigation NavigationManager,
|
||||||
{
|
{
|
||||||
ErrorManager.AddError(orEx.Error, TimeSpan.FromSeconds(10));
|
ErrorManager.AddError(orEx.Error, TimeSpan.FromSeconds(10));
|
||||||
Logger.Warning($"Lỗi khi xử lí Order: {orEx.Error.ErrorDescription}");
|
Logger.Warning($"Lỗi khi xử lí Order: {orEx.Error.ErrorDescription}");
|
||||||
|
HandleOrderStop();
|
||||||
}
|
}
|
||||||
else Logger.Warning($"Lỗi khi xử lí Order: {orEx.Message}");
|
else Logger.Warning($"Lỗi khi xử lí Order: {orEx.Message}");
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -12,148 +12,27 @@ using System.Text.Json;
|
||||||
|
|
||||||
namespace RobotApp.Services.Robot;
|
namespace RobotApp.Services.Robot;
|
||||||
|
|
||||||
public class RobotStatePublisher : BackgroundService
|
public class RobotStatePublisher(
|
||||||
|
IHubContext<RobotHub> _hubContext,
|
||||||
|
RobotStates _robotState,
|
||||||
|
RobotConnection _robotConnection) : BackgroundService
|
||||||
{
|
{
|
||||||
private readonly IHubContext<RobotHub> _hubContext;
|
|
||||||
private readonly RobotConfiguration _robotConfig;
|
|
||||||
private readonly IOrder _orderManager;
|
|
||||||
private readonly IInstantActions _actionManager;
|
|
||||||
private readonly IPeripheral _peripheralManager;
|
|
||||||
private readonly IInfomation _infoManager;
|
|
||||||
private readonly IError _errorManager;
|
|
||||||
private readonly ILocalization _localizationManager;
|
|
||||||
private readonly IBattery _batteryManager;
|
|
||||||
private readonly ILoad _loadManager;
|
|
||||||
private readonly INavigation _navigationManager;
|
|
||||||
private readonly RobotStateMachine _stateManager;
|
|
||||||
private readonly RobotConnection _robotConnection;
|
|
||||||
private bool? _lastRobotConnectionState;
|
private bool? _lastRobotConnectionState;
|
||||||
|
|
||||||
private uint _headerId = 0;
|
|
||||||
private readonly PeriodicTimer _timer = new(TimeSpan.FromMilliseconds(1000)); // 1 giây/lần
|
private readonly PeriodicTimer _timer = new(TimeSpan.FromMilliseconds(1000)); // 1 giây/lần
|
||||||
|
|
||||||
public RobotStatePublisher(
|
|
||||||
IHubContext<RobotHub> hubContext,
|
|
||||||
RobotConfiguration robotConfig,
|
|
||||||
IOrder orderManager,
|
|
||||||
IInstantActions actionManager,
|
|
||||||
IPeripheral peripheralManager,
|
|
||||||
IInfomation infoManager,
|
|
||||||
IError errorManager,
|
|
||||||
ILocalization localizationManager,
|
|
||||||
IBattery batteryManager,
|
|
||||||
ILoad loadManager,
|
|
||||||
INavigation navigationManager,
|
|
||||||
RobotStateMachine stateManager,
|
|
||||||
RobotConnection robotConnection)
|
|
||||||
{
|
|
||||||
_hubContext = hubContext;
|
|
||||||
_robotConfig = robotConfig;
|
|
||||||
_orderManager = orderManager;
|
|
||||||
_actionManager = actionManager;
|
|
||||||
_peripheralManager = peripheralManager;
|
|
||||||
_infoManager = infoManager;
|
|
||||||
_errorManager = errorManager;
|
|
||||||
_localizationManager = localizationManager;
|
|
||||||
_batteryManager = batteryManager;
|
|
||||||
_loadManager = loadManager;
|
|
||||||
_navigationManager = navigationManager;
|
|
||||||
_stateManager = stateManager;
|
|
||||||
_robotConnection = robotConnection;
|
|
||||||
}
|
|
||||||
|
|
||||||
private StateMsg GetStateMsg()
|
|
||||||
{
|
|
||||||
return new StateMsg
|
|
||||||
{
|
|
||||||
HeaderId = _headerId++,
|
|
||||||
Timestamp = DateTime.UtcNow.ToString("o"), // ISO 8601
|
|
||||||
Manufacturer = _robotConfig.VDA5050Setting.Manufacturer,
|
|
||||||
Version = _robotConfig.VDA5050Setting.Version,
|
|
||||||
SerialNumber = _robotConfig.SerialNumber,
|
|
||||||
Maps = [],
|
|
||||||
OrderId = _orderManager.OrderId,
|
|
||||||
OrderUpdateId = _orderManager.OrderUpdateId,
|
|
||||||
ZoneSetId = "",
|
|
||||||
LastNodeId = _orderManager.LastNodeId,
|
|
||||||
LastNodeSequenceId = _orderManager.LastNodeSequenceId,
|
|
||||||
Driving = Math.Abs(_navigationManager.VelocityX) > 0.01 || Math.Abs(_navigationManager.Omega) > 0.01,
|
|
||||||
Paused = false,
|
|
||||||
NewBaseRequest = true,
|
|
||||||
DistanceSinceLastNode = 0,
|
|
||||||
OperatingMode = _peripheralManager.PeripheralMode.ToString(),
|
|
||||||
NodeStates = _orderManager.NodeStates,
|
|
||||||
EdgeStates = _orderManager.EdgeStates,
|
|
||||||
ActionStates = _actionManager.ActionStates,
|
|
||||||
Information = [General, .. _infoManager.InformationState],
|
|
||||||
Errors = _errorManager.ErrorsState,
|
|
||||||
AgvPosition = new AgvPosition
|
|
||||||
{
|
|
||||||
X = _localizationManager.X,
|
|
||||||
Y = _localizationManager.Y,
|
|
||||||
Theta = _localizationManager.Theta,
|
|
||||||
LocalizationScore = _localizationManager.MatchingScore,
|
|
||||||
MapId = _localizationManager.CurrentActiveMap,
|
|
||||||
DeviationRange = _localizationManager.Reliability,
|
|
||||||
PositionInitialized = _localizationManager.IsReady,
|
|
||||||
},
|
|
||||||
BatteryState = new BatteryState
|
|
||||||
{
|
|
||||||
Charging = _batteryManager.IsCharging,
|
|
||||||
BatteryHealth = _batteryManager.SOH,
|
|
||||||
Reach = 0,
|
|
||||||
BatteryVoltage = _batteryManager.Voltage,
|
|
||||||
BatteryCharge = _batteryManager.SOC,
|
|
||||||
},
|
|
||||||
Loads = _loadManager.Load,
|
|
||||||
Velocity = new Velocity
|
|
||||||
{
|
|
||||||
Vx = _navigationManager.VelocityX,
|
|
||||||
Vy = _navigationManager.VelocityY,
|
|
||||||
Omega = _navigationManager.Omega,
|
|
||||||
},
|
|
||||||
SafetyState = new SafetyState
|
|
||||||
{
|
|
||||||
FieldViolation = _peripheralManager.LidarBackProtectField ||
|
|
||||||
_peripheralManager.LidarFrontProtectField ||
|
|
||||||
_peripheralManager.LidarFrontTimProtectField,
|
|
||||||
EStop = (_peripheralManager.Emergency || _peripheralManager.Bumper)
|
|
||||||
? EStop.AUTOACK.ToString()
|
|
||||||
: EStop.NONE.ToString(),
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
private Information General => new()
|
|
||||||
{
|
|
||||||
InfoType = InformationType.robot_general.ToString(),
|
|
||||||
InfoDescription = "Thông tin chung của robot",
|
|
||||||
InfoLevel = InfoLevel.INFO.ToString(),
|
|
||||||
InfoReferences =
|
|
||||||
[
|
|
||||||
new InfomationReferences
|
|
||||||
{
|
|
||||||
ReferenceKey = InformationReferencesKey.robot_state.ToString(),
|
|
||||||
ReferenceValue = _stateManager.CurrentStateName,
|
|
||||||
}
|
|
||||||
]
|
|
||||||
};
|
|
||||||
|
|
||||||
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
|
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
|
||||||
{
|
{
|
||||||
while (await _timer.WaitForNextTickAsync(stoppingToken))
|
while (await _timer.WaitForNextTickAsync(stoppingToken))
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var serialNumber = _robotConfig.SerialNumber;
|
|
||||||
|
|
||||||
// ===== SEND STATE =====
|
// ===== SEND STATE =====
|
||||||
var state = GetStateMsg();
|
var state = _robotState.GetStateMsg();
|
||||||
var json = JsonSerializer.Serialize(state, JsonOptionExtends.Write);
|
//var json = JsonSerializer.Serialize(state, JsonOptionExtends.Write);
|
||||||
|
|
||||||
await _hubContext.Clients
|
await _hubContext.Clients.All
|
||||||
.Group(serialNumber)
|
.SendAsync("ReceiveState", state, stoppingToken);
|
||||||
.SendAsync("ReceiveState", json, stoppingToken);
|
|
||||||
|
|
||||||
// ===== SEND ROBOT CONNECTION (ONLY WHEN CHANGED) =====
|
// ===== SEND ROBOT CONNECTION (ONLY WHEN CHANGED) =====
|
||||||
var isConnected = _robotConnection.IsConnected;
|
var isConnected = _robotConnection.IsConnected;
|
||||||
|
|
@ -162,8 +41,7 @@ public class RobotStatePublisher : BackgroundService
|
||||||
{
|
{
|
||||||
_lastRobotConnectionState = isConnected;
|
_lastRobotConnectionState = isConnected;
|
||||||
|
|
||||||
await _hubContext.Clients
|
await _hubContext.Clients.All
|
||||||
.Group(serialNumber) // routing only
|
|
||||||
.SendAsync(
|
.SendAsync(
|
||||||
"ReceiveRobotConnection",
|
"ReceiveRobotConnection",
|
||||||
isConnected, // payload only bool
|
isConnected, // payload only bool
|
||||||
|
|
@ -177,10 +55,10 @@ public class RobotStatePublisher : BackgroundService
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public override Task StopAsync(CancellationToken cancellationToken)
|
||||||
public override void Dispose()
|
|
||||||
{
|
{
|
||||||
_timer?.Dispose();
|
_timer?.Dispose();
|
||||||
base.Dispose();
|
base.Dispose();
|
||||||
|
return base.StopAsync(cancellationToken);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -36,7 +36,7 @@ public class RobotStates(RobotConfiguration RobotConfiguration,
|
||||||
catch { }
|
catch { }
|
||||||
}
|
}
|
||||||
|
|
||||||
private StateMsg GetStateMsg()
|
public StateMsg GetStateMsg()
|
||||||
{
|
{
|
||||||
return new StateMsg
|
return new StateMsg
|
||||||
{
|
{
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user