Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 20 additions & 20 deletions TaskManagers/EQTransferTaskManager.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
using AGVSystem.Models.EQDevices;
using AGVSystem.Models.EQDevices;
using AGVSystem.Models.Map;
using AGVSystem.Models.Sys;
using AGVSystem.Models.TaskAllocation.HotRun;
Expand Down Expand Up @@ -123,7 +123,7 @@ public static (bool confirm, ALARMS alarm_code, string message, string message_e
if (actiontype == ACTION_TYPE.Unload)
{
if (Eq.Unload_Request == false)
return new(false, ALARMS.EQ_UNLOAD_REQUEST_IS_NOT_ON, $"設備[{Eq.EQName}] 沒有[出料]請求", $"EQ {Eq.EQName} not raised [Unload] request", null, null);
return new(false, ALARMS.Source_Eq_Unload_Request_Off, $"來源設備[{Eq.EQName}] 沒有[出料]請求", $"Source EQ {Eq.EQName} not raised [Unload] request", null, null);
if (Eq.Port_Exist == false)
return new(false, ALARMS.EQ_UNLOAD_REQUEST_ON_BUT_NO_CARGO, $"設備[{Eq.EQName}] PORT內無貨物,無法載出", $"No cargo at EQ {Eq.EQName},can't execute Unload task", null, null);
if (Eq.EndPointOptions.HasLDULDMechanism && Eq.Up_Pose == false)
Expand All @@ -135,7 +135,7 @@ public static (bool confirm, ALARMS alarm_code, string message, string message_e
else if (actiontype == ACTION_TYPE.Load)
{
if (Eq.Load_Request == false)
return new(false, ALARMS.EQ_LOAD_REQUEST_IS_NOT_ON, $"設備[{Eq.EQName}] 沒有[入料]請求", $"EQ {Eq.EQName} not raised [Load] request", null, null);
return new(false, ALARMS.Destine_Eq_Load_Request_Off, $"目的設備[{Eq.EQName}] 沒有[入料]請求", $"Destine EQ {Eq.EQName} not raised [Load] request", null, null);
if (Eq.Port_Exist == true)
return new(false, ALARMS.EQ_LOAD_REQUEST_ON_BUT_HAS_CARGO, $"設備[{Eq.EQName}] 內有貨物,無法載入", $"Cargo exist at EQ {Eq.EQName},can't execute Load task", null, null);
if (Eq.EndPointOptions.HasLDULDMechanism && Eq.Down_Pose == false)
Expand Down Expand Up @@ -164,7 +164,7 @@ public static (bool confirm, ALARMS alarm_code, string message, string message_e
if (actiontype == ACTION_TYPE.Unload)
{
if (Eq.Unload_Request == false)
return new(false, ALARMS.EQ_UNLOAD_REQUEST_IS_NOT_ON, $"設備[{Eq.EQName}] 沒有[出料]請求", $"EQ {Eq.EQName} has no [Unload] request", null, null);
return new(false, ALARMS.Source_Eq_Unload_Request_Off, $"來源設備[{Eq.EQName}] 沒有[出料]請求", $"Source EQ {Eq.EQName} has no [Unload] request", null, null);
if (Eq.Port_Exist == false)
return new(false, ALARMS.EQ_UNLOAD_REQUEST_ON_BUT_NO_CARGO, $"設備[{Eq.EQName}] PORT內無貨物,無法載出", $"No cargo at EQ {Eq.EQName}, can't unload", null, null);
if (Eq.Up_Pose == false)
Expand All @@ -175,7 +175,7 @@ public static (bool confirm, ALARMS alarm_code, string message, string message_e
else if (actiontype == ACTION_TYPE.Load)
{
if (Eq.Load_Request == false)
return new(false, ALARMS.EQ_LOAD_REQUEST_IS_NOT_ON, $"設備[{Eq.EQName}] 沒有[入料]請求", $"EQ {Eq.EQName} has no [Load] request", null, null);
return new(false, ALARMS.Destine_Eq_Load_Request_Off, $"目的設備[{Eq.EQName}] 沒有[入料]請求", $"Destine EQ {Eq.EQName} has no [Load] request", null, null);
if (Eq.Port_Exist == true)
return new(false, ALARMS.EQ_LOAD_REQUEST_ON_BUT_HAS_CARGO, $"設備[{Eq.EQName}] 內有貨物,無法載入", $"Cargo exists at EQ {Eq.EQName}, can't load", null, null);
if (Eq.Down_Pose == false)
Expand Down Expand Up @@ -216,13 +216,13 @@ public static (bool confirm, ALARMS alarm_code, string message, string message_e
}
else if (actiontype == ACTION_TYPE.Load || actiontype == ACTION_TYPE.LoadAndPark)
{
bool _isCarrierExist = specificport.CargoExist == true;
bool _isCarrierIDExist = !string.IsNullOrEmpty(specificport.CarrierID);
if (_isCarrierExist || _isCarrierIDExist)
{
string _failReason = _isCarrierExist ? "料座有貨物存在" : "料座有 Carrier ID 未清除";
string _failReasonEn = _isCarrierExist ? "Carrier exist at port" : "Carrier ID not clear at port";
bool _isCarrierExist = specificport.CargoExist == true;
bool _isCarrierIDExist = !string.IsNullOrEmpty(specificport.CarrierID);

if (_isCarrierExist || _isCarrierIDExist)
{
string _failReason = _isCarrierExist ? "料座有貨物存在" : "料座有 Carrier ID 未清除";
string _failReasonEn = _isCarrierExist ? "Carrier exist at port" : "Carrier ID not clear at port";
return new(false, ALARMS.DestineRackPortHasCargo, $"WIP設備[{Rack.EQName}, ID:{specificport.Properties.ID}] {_failReason}", $"WIP EQ {Rack.EQName}, ID:{specificport.Properties.ID} {_failReasonEn}", null, null);
}
}
Expand All @@ -249,17 +249,17 @@ public static (bool confirm, ALARMS alarm_code, string message, string message_e
//若該儲格第一層是設備 需確認設備 1. 是否當機

clsEQ eqInFirstLayer = StaEQPManagager.GetEQByTag(MapPoint.TagNumber);
if (eqInFirstLayer != null)
{
if (eqInFirstLayer.IS_EQ_STATUS_DOWN)
{
bool _isSourceEQDown = actiontype == ACTION_TYPE.Unload;
if (eqInFirstLayer != null)
{
if (eqInFirstLayer.IS_EQ_STATUS_DOWN)
{
bool _isSourceEQDown = actiontype == ACTION_TYPE.Unload;
return (false, _isSourceEQDown ? ALARMS.Source_Eq_Status_Down : ALARMS.Destine_Eq_Status_Down,
$"取放 [{eqInFirstLayer.EQName}]上層儲格但 [{eqInFirstLayer.EQName}] 狀態為當機",
$"Cannot pick/place the upper storage slot of [{eqInFirstLayer.EQName}]: equipment is down.",
null,
$"Cannot pick/place the upper storage slot of [{eqInFirstLayer.EQName}]: equipment is down.",
null,
null);
}
}
}


Expand Down
136 changes: 69 additions & 67 deletions TaskManagers/TaskManager.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
using AGVSystem.Controllers;
using AGVSystem.Controllers;
using AGVSystem.Models.BayMeasure;
using AGVSystem.Models.Map;
using AGVSystem.Models.Sys;
Expand Down Expand Up @@ -141,6 +141,7 @@ bool _IsMoveDestineIsForbidden(VEHICLE_TYPE model, int destineTag)
results.confirm = results2.confirm;
results.alarm_code = results2.alarm_code;
results.message = results2.message;
results.message_en = results2.message_en;
if (!results.confirm)
return results;
}
Expand Down Expand Up @@ -319,7 +320,7 @@ bool _IsMoveDestineIsForbidden(VEHICLE_TYPE model, int destineTag)
if (database.tables.AgvStates.Where(agv => agv.AGV_Name != taskData.DesignatedAGVName).Any(agv => agv.CurrentLocation == taskData.To_Station))
{
AlarmManagerCenter.AddAlarmAsync(ALARMS.Destine_Charge_Station_Has_AGV, ALARM_SOURCE.AGVS, level: ALARM_LEVEL.WARNING);
return (false, ALARMS.Destine_Eq_Station_Has_Task_To_Park, $"目的充電站已有AGV停駐", "The destination charging station already has an AGV parked.");
return (false, ALARMS.Destine_Charge_Station_Has_AGV, $"目的充電站已有AGV停駐", "The destination charging station already has an AGV parked.");
}
}
catch (Exception ex)
Expand Down Expand Up @@ -379,8 +380,8 @@ bool _IsMoveDestineIsForbidden(VEHICLE_TYPE model, int destineTag)
{
taskData.State = TASK_RUN_STATUS.FAILURE;
string failReasonZh = isNeedTransferButNoUsableEqToLoad ? "無可用的轉運站可供貨物移入暫存" : "無可用的轉運站可供貨物暫存移出";
string failReasonEn = "No_Transfer_Station_To_Work";
taskData.FailureReason = $"{failReasonZh}({failReasonEn})";
string failReasonEn = "No_Transfer_Station_To_Work";
taskData.FailureReason = $"{failReasonZh}({failReasonEn})";
await WriteTaskDtoToDatabase(taskData);
return new(false, ALARMS.No_Transfer_Station_To_Work, failReasonZh, failReasonEn);
}
Expand Down Expand Up @@ -496,12 +497,12 @@ private static void SetTransferInfo(clsTaskDto taskData, out bool isNeedTransfer
{
isNeedTransferButNoUsableEqToLoad = true;
return;
}
//TODO 挑選最優換車點邏輯
clsEQ transferPort = _GetOptimizeTransferPort(transferPortsFilterOut, taskData);
}


//TODO 挑選最優換車點邏輯
clsEQ transferPort = _GetOptimizeTransferPort(transferPortsFilterOut, taskData);

taskData.TransferToTag = transferPort.EndPointOptions.TagID;

MapPoint loadTransferEqPt = AGVSMapManager.GetMapPointByTag(taskData.TransferToTag);
Expand All @@ -512,58 +513,58 @@ private static void SetTransferInfo(clsTaskDto taskData, out bool isNeedTransfer
{
isNeedTransferButNoUsableEqToUnLoad = true;
return;
}
var transferStationPort = StaEQPManagager.RackPortsList.FirstOrDefault(port => port.Properties.Row == 0 && port.TagNumbers.Contains(taskData.TransferToTag));
//taskData.TransferToTag
if (transferStationPort != null)
{
var _rackOfTransferPort = transferStationPort.GetParentRack();
taskData.changeVehicleStationPortID = transferStationPort.GetLocID();
taskData.changeVehicleStationZoneID = _rackOfTransferPort.RackOption.DeviceID;
}

var transferStationPort = StaEQPManagager.RackPortsList.FirstOrDefault(port => port.Properties.Row == 0 && port.TagNumbers.Contains(taskData.TransferToTag));
//taskData.TransferToTag
if (transferStationPort != null)
{
var _rackOfTransferPort = transferStationPort.GetParentRack();
taskData.changeVehicleStationPortID = transferStationPort.GetLocID();
taskData.changeVehicleStationZoneID = _rackOfTransferPort.RackOption.DeviceID;
}
taskData.TransferFromTag = unoadTransferEqPt.TagNumber;

}
private static clsEQ _GetOptimizeTransferPort(List<clsEQ> transferPortsCandiites, clsTaskDto taskData)
{
try
{
logger.Info($"開始挑選換車站->終點放貨 Tag:{taskData.To_Station_Tag}, 候選站數量:{transferPortsCandiites.Count}");
clsEQ sameColumnOfDestineEq = transferPortsCandiites.FirstOrDefault(eq => eq.EndPointOptions.TagID == taskData.To_Station_Tag);
if (sameColumnOfDestineEq != null)
return sameColumnOfDestineEq;
MapPoint destineTag = taskData.To_Station_Tag.GetMapPointByTagNumber();
var orderedCandites = transferPortsCandiites.OrderBy(eq =>
{
var _eqPt = eq.EndPointOptions.TagID.GetMapPointByTagNumber();
PathFinder pathFinder = new PathFinder();
AGVSystemCommonNet6.MAP.PathFinder.clsPathInfo _pathInfo = pathFinder.FindShortestPath(eq.EndPointOptions.TagID, taskData.To_Station_Tag, new PathFinder.PathFinderOption
{
Algorithm = PathFinder.PathFinderOption.ALGORITHM.Dijsktra,
OnlyNormalPoint = false,
});
return _pathInfo.total_travel_distance;
}).ToList();
var _eq = orderedCandites.First();
logger.Info($"換車站最終獲勝的是 : {_eq.EndPointOptions.Name}(Tag:{_eq.EndPointOptions.TagID})");
return _eq;
}
catch (Exception ex)
{
logger.Error(ex, "挑選換車站的途中發生例外錯誤!");
return transferPortsCandiites.First();
}
}
}

private static clsEQ _GetOptimizeTransferPort(List<clsEQ> transferPortsCandiites, clsTaskDto taskData)
{
try
{
logger.Info($"開始挑選換車站->終點放貨 Tag:{taskData.To_Station_Tag}, 候選站數量:{transferPortsCandiites.Count}");

clsEQ sameColumnOfDestineEq = transferPortsCandiites.FirstOrDefault(eq => eq.EndPointOptions.TagID == taskData.To_Station_Tag);
if (sameColumnOfDestineEq != null)
return sameColumnOfDestineEq;


MapPoint destineTag = taskData.To_Station_Tag.GetMapPointByTagNumber();

var orderedCandites = transferPortsCandiites.OrderBy(eq =>
{
var _eqPt = eq.EndPointOptions.TagID.GetMapPointByTagNumber();
PathFinder pathFinder = new PathFinder();
AGVSystemCommonNet6.MAP.PathFinder.clsPathInfo _pathInfo = pathFinder.FindShortestPath(eq.EndPointOptions.TagID, taskData.To_Station_Tag, new PathFinder.PathFinderOption
{
Algorithm = PathFinder.PathFinderOption.ALGORITHM.Dijsktra,
OnlyNormalPoint = false,
});

return _pathInfo.total_travel_distance;

}).ToList();
var _eq = orderedCandites.First();
logger.Info($"換車站最終獲勝的是 : {_eq.EndPointOptions.Name}(Tag:{_eq.EndPointOptions.TagID})");
return _eq;
}
catch (Exception ex)
{
logger.Error(ex, "挑選換車站的途中發生例外錯誤!");
return transferPortsCandiites.First();
}
}


private static async Task WriteTaskDtoToDatabase(clsTaskDto taskData)
{
try
Expand Down Expand Up @@ -638,10 +639,11 @@ private static (bool confirm, ALARMS alarmCode, string message, string message_e
{
string sourceKey = $"{taskData.From_Station}_{taskData.From_Slot}";
if (currentNotUsableGoalKeyList.Contains(sourceKey))
{
ALARMS _alarm = taskData.IsSourceWipPort(out clsRack rack, out clsPortOfRack _port) ? ALARMS.RackSourcePortAlreadyHasCommand : ALARMS.Destine_Eq_Already_Has_Task_To_Excute;
string _message = _alarm == ALARMS.RackSourcePortAlreadyHasCommand ? "來源儲格已有任務" : "The source equipment already has a carry task";
string _messageEn = _alarm == ALARMS.RackSourcePortAlreadyHasCommand ? "The source rack port already has a carry task" : "The source equipment already has a carry task";
{
bool isSourceWipPort = taskData.IsSourceWipPort(out _, out _);
ALARMS _alarm = ALARMS.RackSourcePortAlreadyHasCommand;
string _message = isSourceWipPort ? "來源儲格已有任務" : "來源設備已有搬運任務";
string _messageEn = isSourceWipPort ? "The source rack port already has a carry task" : "The source equipment already has a carry task";
AlarmManagerCenter.AddAlarmAsync(_alarm, ALARM_SOURCE.AGVS);
return (false, _alarm, _message, _messageEn);
}
Expand Down Expand Up @@ -669,10 +671,10 @@ private static async Task SetUnknowCarrierID(clsTaskDto taskData, DeviceIDInfo s
int flowNumber = 0;
string unknowCargoID = "";

if (sourceDeviceIDInfo.outputRackType == clsEQ.RACK_CONTENT_STATE.FULL_UNBAKED || sourceDeviceIDInfo.outputRackType == clsEQ.RACK_CONTENT_STATE.FULL_BAKED)
{
taskData.Carrier_ID = await AGVSConfigulator.GetRackUnknownFlowID();
return;
if (sourceDeviceIDInfo.outputRackType == clsEQ.RACK_CONTENT_STATE.FULL_UNBAKED || sourceDeviceIDInfo.outputRackType == clsEQ.RACK_CONTENT_STATE.FULL_BAKED)
{
taskData.Carrier_ID = await AGVSConfigulator.GetRackUnknownFlowID();
return;
}


Expand Down