|
|
using Microsoft.Extensions.Logging;
|
|
|
using SlnMesnac.Repository.service;
|
|
|
using System;
|
|
|
using System.Collections.Generic;
|
|
|
using System.Diagnostics;
|
|
|
using System.Threading.Tasks;
|
|
|
using SlnMesnac.Repository;
|
|
|
using SlnMesnac.Repository.service.Impl;
|
|
|
using TouchSocket.Sockets;
|
|
|
using SlnMesnac.Model.domain;
|
|
|
using SlnMesnac.TouchSocket;
|
|
|
using System.Timers;
|
|
|
using SlnMesnac.Model.Enum;
|
|
|
using HslCommunication.Enthernet;
|
|
|
using System.Threading;
|
|
|
using SlnMesnac.TouchSocket.Entity;
|
|
|
|
|
|
namespace SlnMesnac.Business.@base
|
|
|
{
|
|
|
public class BaseTaskInfoBusiness
|
|
|
{
|
|
|
private TcpServer _tcpServer = null;
|
|
|
public Action<AirportTask> _Taskaction;
|
|
|
public Action<string> _RefreshLogMessageAction;
|
|
|
private static BaseTaskInfoBusiness instance;
|
|
|
private ILogger<BaseTaskInfoBusiness> _logger;
|
|
|
private IAirportTaskService _Taskservice;
|
|
|
private IAGVStateService _AGVStateService;
|
|
|
public BaseTaskInfoBusiness(ILogger<BaseTaskInfoBusiness> logger, IAirportTaskService Taskservice, IAGVStateService agvService, TcpServer tcpServer)
|
|
|
{
|
|
|
_logger = logger;
|
|
|
_tcpServer = tcpServer;
|
|
|
_tcpServer.VisionSysStateEvent += TcpServerOnVisionSysStateEvent;
|
|
|
_tcpServer.StackWorkDoneEvent += _tcpServer_StackWorkDoneEvent;
|
|
|
_Taskservice = Taskservice;
|
|
|
_AGVStateService = agvService;
|
|
|
InitClearTimer();
|
|
|
//doWhileGetAGVTaskInfo();
|
|
|
}
|
|
|
/// <summary>
|
|
|
/// 一次码垛完成,发送码垛结果
|
|
|
/// </summary>
|
|
|
/// <param name="entity"></param>
|
|
|
private void _tcpServer_StackWorkDoneEvent(TcpVisionEntity entity)
|
|
|
{
|
|
|
try
|
|
|
{
|
|
|
if (entity != null)
|
|
|
{
|
|
|
//码垛完成
|
|
|
if (entity.DataBytes[0] == 0x00)
|
|
|
{
|
|
|
//更新码垛数量
|
|
|
|
|
|
|
|
|
}
|
|
|
//码垛过程失败
|
|
|
else if (entity.DataBytes[1] == 0x01)
|
|
|
{
|
|
|
|
|
|
}
|
|
|
//码垛过程失败
|
|
|
else if (entity.DataBytes[2] == 0x02)
|
|
|
{
|
|
|
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
catch (Exception ex)
|
|
|
{
|
|
|
|
|
|
}
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
|
/// 视觉系统回复给上位机调度系统开始工作状态
|
|
|
/// </summary>
|
|
|
/// <param name="entity"></param>
|
|
|
private void TcpServerOnVisionSysStateEvent(TcpVisionEntity entity)
|
|
|
{
|
|
|
try
|
|
|
{
|
|
|
if (entity != null)
|
|
|
{
|
|
|
//任务正常
|
|
|
if (entity.DataBytes[0] == 0x00)
|
|
|
{
|
|
|
//更新AMR任务状态
|
|
|
|
|
|
}
|
|
|
//任务异常
|
|
|
else if (entity.DataBytes[0] == 0x01)
|
|
|
{
|
|
|
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
catch (Exception ex)
|
|
|
{
|
|
|
|
|
|
|
|
|
}
|
|
|
}
|
|
|
|
|
|
public static BaseTaskInfoBusiness GetInstance(ILogger<BaseTaskInfoBusiness> logger, IAirportTaskService Taskservice, IAGVStateService agvService, TcpServer tcpServer)
|
|
|
{
|
|
|
if (instance == null)
|
|
|
{
|
|
|
instance = new BaseTaskInfoBusiness(logger, Taskservice,agvService, tcpServer);
|
|
|
}
|
|
|
return instance;
|
|
|
}
|
|
|
|
|
|
private void doWhileGetAGVTaskInfo()
|
|
|
{
|
|
|
try
|
|
|
{
|
|
|
Task.Run((() =>
|
|
|
{
|
|
|
while (true)
|
|
|
{
|
|
|
GetAGVTaskInfo(null,null);
|
|
|
Task.Delay(1000);
|
|
|
}
|
|
|
|
|
|
|
|
|
}));
|
|
|
|
|
|
}
|
|
|
catch (Exception ex)
|
|
|
{
|
|
|
|
|
|
}
|
|
|
}
|
|
|
private void InitClearTimer()
|
|
|
{
|
|
|
System.Timers.Timer timer = new System.Timers.Timer
|
|
|
{
|
|
|
Interval = 1000, // 每天执行一次
|
|
|
AutoReset = true,
|
|
|
|
|
|
};
|
|
|
timer.Elapsed += GetAGVTaskInfo;
|
|
|
timer.Start();
|
|
|
|
|
|
}
|
|
|
/// <summary>
|
|
|
/// 获取任务列表
|
|
|
/// </summary>
|
|
|
private void GetAGVTaskInfo(object source, ElapsedEventArgs e)
|
|
|
{
|
|
|
try
|
|
|
{
|
|
|
List<AirportTask> Task = _Taskservice.GetAGVTaskInfos();
|
|
|
if (Task != null)
|
|
|
{
|
|
|
if (Task.Count > 0)
|
|
|
{
|
|
|
_RefreshLogMessageAction?.Invoke("任务数量:" + Task.Count);
|
|
|
foreach (var TaskItem in Task)
|
|
|
{
|
|
|
//AGV未派发,AMR未派发
|
|
|
if (string.IsNullOrEmpty(TaskItem.agvno) && string.IsNullOrEmpty(TaskItem.manipulatorno))
|
|
|
{
|
|
|
_RefreshLogMessageAction?.Invoke($"正在为AGV,AMR分配任务...");
|
|
|
_logger.LogInformation($"正在为AGV,AMR分配任务");
|
|
|
//查询AGV设备状态及AMR设备状态
|
|
|
//这里要看AGV是否会立刻更新状态
|
|
|
CreateAGVTask(TaskItem);
|
|
|
//查询机械臂状态
|
|
|
}
|
|
|
//AGV已派发,AMR未派发
|
|
|
if (!string.IsNullOrEmpty(TaskItem.agvno) && string.IsNullOrEmpty(TaskItem.manipulatorno))
|
|
|
{
|
|
|
//查询AMR状态
|
|
|
CreateAMRTask(TaskItem);
|
|
|
_RefreshLogMessageAction?.Invoke($"正在为AMR分配任务...");
|
|
|
|
|
|
_logger.LogInformation($"正在为AMR分配任务");
|
|
|
}
|
|
|
//AGV未派发,AMR已派发
|
|
|
if (string.IsNullOrEmpty(TaskItem.agvno) && !string.IsNullOrEmpty(TaskItem.manipulatorno))
|
|
|
{
|
|
|
_RefreshLogMessageAction?.Invoke($"正在为AGV分配任务...");
|
|
|
|
|
|
_logger.LogInformation($"正在为AGV分配任务");
|
|
|
|
|
|
}
|
|
|
_Taskaction?.Invoke(TaskItem);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
catch (Exception ex)
|
|
|
{
|
|
|
|
|
|
}
|
|
|
}
|
|
|
/// <summary>
|
|
|
/// 向AMR派发任务
|
|
|
/// </summary>
|
|
|
/// <param name="AirportTask"></param>
|
|
|
/// <returns></returns>
|
|
|
private bool CreateAMRTask(AirportTask AirportTask)
|
|
|
{
|
|
|
bool iflag = false;
|
|
|
try
|
|
|
{
|
|
|
iflag = true;
|
|
|
List<AGVState> State = GetAgvState(AgvType.AMR);
|
|
|
foreach (var AgvItem in State)
|
|
|
{
|
|
|
//根据规则筛选最优AGV
|
|
|
if (AgvItem.agvworkstate == "任务空闲")
|
|
|
{
|
|
|
_logger.LogInformation($"获取空闲AMR列表");
|
|
|
_RefreshLogMessageAction?.Invoke("执行站台[" + AirportTask.conveyorno + "],下发" + "[" + AirportTask.taskno + "]任务");
|
|
|
//调用派发任务接口,向任务状态为任务空闲的AGV派发任务
|
|
|
bool iTaskflag = true;
|
|
|
if (iTaskflag)
|
|
|
{
|
|
|
_RefreshLogMessageAction?.Invoke("[" + AgvItem.agvno + "]AMR,执行任务[" + AirportTask.taskno + "]");
|
|
|
AgvItem.taskno = AirportTask.taskno;
|
|
|
AgvItem.agvworkstate = "任务执行中";
|
|
|
AgvItem.refreshtime = DateTime.Now;
|
|
|
_AGVStateService.UpdateAsync(AgvItem);
|
|
|
|
|
|
//更新任务信息表状态为执行中
|
|
|
AirportTask.manipulatorno = AgvItem.agvno;
|
|
|
AirportTask.taskstate = "执行中";
|
|
|
_Taskservice.UpdateTaskAsync(AirportTask);
|
|
|
break;
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
return iflag;
|
|
|
}
|
|
|
catch (Exception ex)
|
|
|
{
|
|
|
return iflag;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
|
/// 向AGV派发任务
|
|
|
/// </summary>
|
|
|
/// <returns></returns>
|
|
|
private bool CreateAGVTask(AirportTask AirportTask)
|
|
|
{
|
|
|
bool iflag = false;
|
|
|
try
|
|
|
{
|
|
|
iflag = true;
|
|
|
List<AGVState> State = GetAgvState(AgvType.AGV);
|
|
|
foreach (var AgvItem in State)
|
|
|
{
|
|
|
//根据规则筛选最优AGV
|
|
|
if (AgvItem.agvworkstate == "任务空闲")
|
|
|
{
|
|
|
_logger.LogInformation($"获取空闲AGV列表");
|
|
|
_RefreshLogMessageAction?.Invoke("执行站台[" + AirportTask.conveyorno + "],下发" + "[" + AirportTask.taskno + "]任务");
|
|
|
//调用派发任务接口,向任务状态为任务空闲的AGV派发任务
|
|
|
bool iTaskflag = true;
|
|
|
if (iTaskflag)
|
|
|
{
|
|
|
_RefreshLogMessageAction?.Invoke("[" + AgvItem.agvno + "]AGV,执行任务[" + AirportTask.taskno + "]");
|
|
|
AgvItem.taskno = AirportTask.taskno;
|
|
|
AgvItem.agvworkstate = "任务执行中";
|
|
|
AgvItem.refreshtime = DateTime.Now;
|
|
|
_AGVStateService.UpdateAsync(AgvItem);
|
|
|
|
|
|
//更新任务信息表状态为执行中
|
|
|
AirportTask.agvno = AgvItem.agvno;
|
|
|
AirportTask.taskstate = "执行中";
|
|
|
_Taskservice.UpdateTaskAsync(AirportTask);
|
|
|
break;
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
return iflag;
|
|
|
}
|
|
|
catch (Exception ex)
|
|
|
{
|
|
|
return iflag;
|
|
|
}
|
|
|
}
|
|
|
/// <summary>
|
|
|
/// 获取agv设备状态
|
|
|
/// </summary>
|
|
|
/// <returns></returns>
|
|
|
private List<AGVState> GetAgvState(AgvType AgvType)
|
|
|
{
|
|
|
List<AGVState> State = null;
|
|
|
try
|
|
|
{
|
|
|
State = _AGVStateService.GetAgvState(AgvType);
|
|
|
return State;
|
|
|
}
|
|
|
catch (Exception ex)
|
|
|
{
|
|
|
return State;
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
private void GetTaskStateDetail()
|
|
|
{
|
|
|
try
|
|
|
{
|
|
|
Task.Run(() =>
|
|
|
{
|
|
|
List<AirportTask> Task = _Taskservice.GetAGVTaskInfos();
|
|
|
if (Task.Count > 0)
|
|
|
{
|
|
|
// 设置计时器
|
|
|
Stopwatch stopwatch = new Stopwatch();
|
|
|
stopwatch.Start();
|
|
|
//通过任务编号查询agv任务
|
|
|
|
|
|
|
|
|
|
|
|
// 检查是否超过两秒
|
|
|
if (stopwatch.ElapsedMilliseconds > 2000)
|
|
|
{
|
|
|
_logger.LogError("超时");
|
|
|
}
|
|
|
Thread.Sleep(100);
|
|
|
}
|
|
|
|
|
|
});
|
|
|
}
|
|
|
catch (Exception ex)
|
|
|
{
|
|
|
|
|
|
}
|
|
|
}
|
|
|
|
|
|
|
|
|
}
|
|
|
} |