You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
314 lines
12 KiB
C#
314 lines
12 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Security.Cryptography.X509Certificates;
|
|
using System.Text;
|
|
using System.Threading.Tasks;
|
|
using Microsoft.Extensions.DependencyInjection;
|
|
using Newtonsoft.Json;
|
|
using Sln.Wcs.HikRoBotApi.Domain.Dto.GenAgvSchedulingTask;
|
|
using Sln.Wcs.HikRoBotSdk;
|
|
using Sln.Wcs.Model.Domain;
|
|
using Sln.Wcs.Plc;
|
|
using Sln.Wcs.Serilog;
|
|
using Sln.Wcs.WCS.Global;
|
|
using SlnMesnac.Business.@base;
|
|
using SqlSugar;
|
|
using Sln.Wcs.HikRoBotApi.Service.Impl;
|
|
|
|
namespace Sln.Wcs.Function
|
|
{
|
|
/// <summary>
|
|
/// 子任务执行
|
|
/// </summary>
|
|
public class SubTaskControl : BaseBusiness
|
|
{
|
|
private readonly SerilogHelper _logger;
|
|
private readonly ISqlSugarClient sqlSugarClient;
|
|
|
|
public HikRoBotService hikRoBotService;
|
|
|
|
public PlcAbsractFactory workShopPlc1;
|
|
|
|
public PlcAbsractFactory workShopPlc2;
|
|
|
|
public List<WcsAgvStatus> agvStatusList = new List<WcsAgvStatus>();
|
|
|
|
public SubTaskControl(IServiceProvider serviceProvider) : base(serviceProvider)
|
|
{
|
|
hikRoBotService = serviceProvider.GetRequiredService<HikRoBotService>();
|
|
sqlSugarClient = serviceProvider.GetRequiredService<ISqlSugarClient>();
|
|
_logger = serviceProvider.GetRequiredService<SerilogHelper>();
|
|
|
|
}
|
|
|
|
/// <summary>
|
|
/// 启动扫描监听
|
|
/// </summary>
|
|
public void StartPoint()
|
|
{
|
|
|
|
try
|
|
{
|
|
//List<WcsBaseEquip> agvList = sqlSugarClient.Queryable<WcsBaseEquip>().Where(x => agvEquipNos.Contains(x.EquipNo)).ToList();
|
|
Task.Run(async () =>
|
|
{
|
|
while (true)
|
|
{
|
|
await ExecuteSubTaskAsync();
|
|
await Task.Delay(5000);
|
|
}
|
|
});
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
_logger.Error($"agv执行任务启动扫描监听失败:{ex.Message},{ex.StackTrace}");
|
|
}
|
|
|
|
}
|
|
|
|
/// <summary>
|
|
/// 执行分任务
|
|
/// </summary>
|
|
private async Task ExecuteSubTaskAsync()
|
|
{
|
|
try
|
|
{
|
|
sqlSugarClient.AsTenant().ChangeDatabase("wcs");
|
|
var db = sqlSugarClient.CopyNew();
|
|
List<SubTaskInstance> taskList = db.Queryable<SubTaskInstance>().OrderBy(x => x.CreatedTime).ToList();
|
|
foreach (SubTaskInstance item in taskList)
|
|
{
|
|
item.UpdatedTime = DateTime.Now;
|
|
switch (item.TaskType)
|
|
{
|
|
//AGV下发任务
|
|
case StaticTaskType.MovePalletHTGTask:
|
|
case StaticTaskType.MovePalletGTHTask:
|
|
case StaticTaskType.MovePalletXTGTask:
|
|
case StaticTaskType.MovePalletGTXTask:
|
|
case StaticTaskType.MovePalletHTGJTask:
|
|
case StaticTaskType.MovePalletGTHJTask:
|
|
case StaticTaskType.MovePalletXTGJTask:
|
|
case StaticTaskType.MovePalletGTXJTask:
|
|
TransPalletTaskHandler(item);
|
|
break;
|
|
//提升机下发任务
|
|
case StaticTaskType.ElevatorBoxTask:
|
|
ElevatorTaskHandler(item);
|
|
break;
|
|
default: break;
|
|
}
|
|
}
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
_logger.Error($"ExecuteTask异常{ex.StackTrace}");
|
|
Thread.Sleep(2000);
|
|
}
|
|
}
|
|
|
|
#region 不同任务处理流程
|
|
|
|
/// <summary>
|
|
/// 运输任务处理
|
|
/// </summary>
|
|
private void TransPalletTaskHandler(SubTaskInstance task)
|
|
{
|
|
|
|
if (task.TaskStatus == 0)
|
|
{
|
|
try
|
|
{
|
|
var db = sqlSugarClient.CopyNew();
|
|
var wcsLocation = db.Queryable<BaseLocation>().First(t => t.AgvPositionCode == task.CurrAGVPoint);
|
|
workShopPlc1 = base.GetPlcByKey("workshop" + wcsLocation.WorkshopId + "Plc");
|
|
WcsBaseDictionary wcsBaseDictionary = db.Queryable<WcsBaseDictionary>().First(t => t.Id == task.TaskType);
|
|
List<Position> PathList = new List<Position>();
|
|
PathList.Add(new Position { positionCode = task.CurrAGVPoint, type = "00" });
|
|
PathList.Add(new Position { positionCode = task.EndAGVPoint, type = "00" });
|
|
var agvTask = new GenAgvSchedulingTaskDto
|
|
{
|
|
reqCode = StaticData.SnowId.NextId().ToString(),
|
|
positionCodePath = PathList,
|
|
taskTyp = wcsBaseDictionary.DicValue,
|
|
ctnrTyp = "2",
|
|
};
|
|
|
|
var result = hikRoBotService.GetGenAgvSchedulingTask(agvTask);
|
|
|
|
result.code = 0; //测试用,记得删除
|
|
|
|
if (result.code == 0)
|
|
{
|
|
task.TaskStatus = 1;
|
|
var updateflag = db.Updateable<SubTaskInstance>(task).ExecuteCommandAsync();
|
|
}
|
|
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
_logger.Error("TransPalletTaskHandler方法异常:" + ex.Message);
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
/// <summary>
|
|
/// 提升机任务处理
|
|
/// </summary>
|
|
private void ElevatorTaskHandler(SubTaskInstance task)
|
|
{
|
|
try
|
|
{
|
|
var db = sqlSugarClient.CopyNew();
|
|
var startLocation = db.Queryable<BaseLocation>().First(t => t.AgvPositionCode == task.CurrAGVPoint);
|
|
var endLocation = db.Queryable<BaseLocation>().First(t => t.AgvPositionCode == task.EndAGVPoint);
|
|
workShopPlc1 = base.GetPlcByKey("workshop" + startLocation.WorkshopId + "Plc");
|
|
var elevator = db.Queryable<BaseEquipInfo>().First(t => t.EquipNo == task.EquipmentNo);
|
|
|
|
if (workShopPlc1 == null || !workShopPlc1.IsConnected)
|
|
{
|
|
_logger.Plc(DateTime.Now + "PLC未连接,请检查网络!");
|
|
return;
|
|
}
|
|
|
|
int busyFlag = workShopPlc1.readInt16ByAddress(StaticData.GetPlcAddress("线体忙碌状态"));
|
|
|
|
if (task.TaskStatus == 0) //呼叫提升机
|
|
{
|
|
if (busyFlag == 1)
|
|
{
|
|
return;
|
|
}
|
|
if (busyFlag == 0)
|
|
{
|
|
|
|
int hoistFloor = workShopPlc1.readInt16ByAddress(StaticData.GetPlcAddress(elevator.EquipName + "号提升机当前层"));
|
|
if (hoistFloor != startLocation.WorkshopLevel)
|
|
{
|
|
workShopPlc1.writeInt16ByAddress("任务执行命令", (int)(NumberConverter(elevator.EquipName) * 100 + hoistFloor * 10 + startLocation.WorkshopLevel));
|
|
}
|
|
task.TaskStatus = 1;
|
|
}
|
|
}
|
|
if (task.TaskStatus == 1)//提升机到起点后,发送信号放置完成
|
|
{
|
|
if (busyFlag == 1)
|
|
{
|
|
return;
|
|
}
|
|
if (busyFlag == 0)
|
|
{
|
|
workShopPlc1.writeBoolByAddress("放置完成", true);
|
|
task.TaskStatus = 2;
|
|
}
|
|
}
|
|
if (task.TaskStatus == 2)//开始运输到终点
|
|
{
|
|
if (busyFlag == 1)
|
|
{
|
|
return;
|
|
}
|
|
if (busyFlag == 0)
|
|
{
|
|
if(workShopPlc1.readBoolByAddress(elevator.EquipName+"号提升机"+NumberConverter((int)startLocation.WorkshopLevel)+ "读写器读取触发"))
|
|
{
|
|
workShopPlc1.writeInt16ByAddress("任务执行命令", (int)(NumberConverter(elevator.EquipName) * 100 + startLocation.WorkshopLevel * 10 + endLocation.WorkshopLevel));
|
|
task.TaskStatus = 3;
|
|
}
|
|
}
|
|
}
|
|
if(task.TaskStatus == 3)//提升机到终点后,发送信号提升完成
|
|
{
|
|
if (busyFlag == 1)
|
|
{
|
|
return;
|
|
}
|
|
if (busyFlag == 0)
|
|
{
|
|
workShopPlc1.writeBoolByAddress("提升完成", true); //继续下一步任务<-待定
|
|
if (workShopPlc1.readBoolByAddress(elevator.EquipName + "提升机"+ NumberConverter((int)endLocation.WorkshopLevel) + "楼接驳位状态"))
|
|
{
|
|
var mainTask = db.Queryable<WcsTaskInstance>().First(t => t.TaskCode == task.MaintaskCode);
|
|
mainTask.ResultCode = 1;
|
|
db.Updateable(mainTask).ExecuteCommand();
|
|
db.Deleteable(task).ExecuteCommand();
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
sqlSugarClient.AsTenant().BeginTran();
|
|
try
|
|
{
|
|
db.Updateable(task).ExecuteCommand();
|
|
db.AsTenant().CommitTran();
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
db.AsTenant().RollbackTran();
|
|
_logger.Error("提交事务异常:" + ex.Message);
|
|
}
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
_logger.Error("TransPalletTaskHandler方法异常:" + ex.Message);
|
|
}
|
|
}
|
|
#endregion
|
|
|
|
#region 任务状态流转处理逻辑
|
|
/// <summary>
|
|
/// 根据不同任务模版获取路径
|
|
/// </summary>
|
|
/// <param name="currPointNo"></param>
|
|
/// <param name="endPointNo"></param>
|
|
/// <param name="dicValue"></param>
|
|
/// <returns></returns>
|
|
private List<Position> GetPositionPath(string currPointNo, string endPointNo, string dicValue, int taskType)
|
|
{
|
|
List<Position> PathList = new List<Position>();
|
|
if (dicValue == "Transport") //同层只需要起点、终点
|
|
{
|
|
PathList.Add(new Position { positionCode = currPointNo, type = "00" });
|
|
PathList.Add(new Position { positionCode = endPointNo, type = "00" });
|
|
}
|
|
else if (dicValue == "XLXQL")
|
|
{
|
|
|
|
}
|
|
return PathList;
|
|
}
|
|
|
|
public static int NumberConverter(string number)
|
|
{
|
|
switch (number)
|
|
{
|
|
case "一": return 1;
|
|
case "二": return 2;
|
|
case "三": return 3;
|
|
case "四": return 4;
|
|
case "五": return 5;
|
|
case "六": return 6;
|
|
case "七": return 7;
|
|
case "八": return 8;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
public static string NumberConverter(int number)
|
|
{
|
|
switch (number)
|
|
{
|
|
case 1: return "一";
|
|
case 2: return "二";
|
|
case 3: return "三";
|
|
case 4: return "四";
|
|
case 5: return "五";
|
|
}
|
|
return "无";
|
|
}
|
|
#endregion 任务状态流转处理逻辑
|
|
}
|
|
}
|