|
|
|
|
|
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;
|
|
|
using static SlnMesnac.TouchSocket.TcpServer;
|
|
|
|
|
|
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;
|
|
|
private AirPorthttpClient _airPorthttpClient;
|
|
|
public BaseTaskInfoBusiness(ILogger<BaseTaskInfoBusiness> logger, IAirportTaskService Taskservice, IAGVStateService agvService, TcpServer tcpServer, AirPorthttpClient airPorthttpClient)
|
|
|
{
|
|
|
_logger = logger;
|
|
|
_tcpServer = tcpServer;
|
|
|
_tcpServer.ReceiveVisionSysStateEvent += TcpServerOnVisionSysStateEvent;
|
|
|
_tcpServer.ReceiveStackWorkDoneEvent += _tcpServer_StackWorkDoneEvent;
|
|
|
_Taskservice = Taskservice;
|
|
|
_AGVStateService = agvService;
|
|
|
//InitClearTimer();
|
|
|
_airPorthttpClient = airPorthttpClient;
|
|
|
//doWhileGetAGVTaskInfo();
|
|
|
//GetTaskStateDetail();
|
|
|
}
|
|
|
/// <summary>
|
|
|
/// 一次码垛完成,发送码垛结果
|
|
|
/// </summary>
|
|
|
/// <param name="entity"></param>
|
|
|
private void _tcpServer_StackWorkDoneEvent(TcpVisionEntity entity, string id)
|
|
|
{
|
|
|
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, string id)
|
|
|
{
|
|
|
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, AirPorthttpClient airPorthttpClient)
|
|
|
{
|
|
|
if (instance == null)
|
|
|
{
|
|
|
instance = new BaseTaskInfoBusiness(logger, Taskservice,agvService, tcpServer, airPorthttpClient);
|
|
|
}
|
|
|
return instance;
|
|
|
}
|
|
|
|
|
|
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 == "任务空闲")
|
|
|
{
|
|
|
//搬运机器人是否已到位
|
|
|
if (string.IsNullOrEmpty(AirportTask.agvtaskno))
|
|
|
{
|
|
|
_logger.LogInformation($"获取空闲AGV列表");
|
|
|
_RefreshLogMessageAction?.Invoke("执行站台[" + AirportTask.conveyorno + "],下发" + "[" + AirportTask.taskno + "]任务");
|
|
|
|
|
|
//调用派发任务接口,向任务状态为任务空闲的复合AGV、搬运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 = "AGV执行中";
|
|
|
//等待agv返回任务编号
|
|
|
AirportTask.agvtaskno = Guid.NewGuid().ToString("N");
|
|
|
|
|
|
|
|
|
_Taskservice.UpdateTaskAsync(AirportTask);
|
|
|
break;
|
|
|
}
|
|
|
}
|
|
|
//复合机器人是否已到位
|
|
|
if (string.IsNullOrEmpty(AirportTask.amrtaskno))
|
|
|
{
|
|
|
_logger.LogInformation($"获取空闲AGV列表");
|
|
|
_RefreshLogMessageAction?.Invoke("执行站台[" + AirportTask.conveyorno + "],下发" + "[" + AirportTask.taskno + "]任务");
|
|
|
|
|
|
//调用派发任务接口,向任务状态为任务空闲的复合AGV、搬运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 = "AMR执行中";
|
|
|
//等待agv返回任务编号
|
|
|
AirportTask.amrtaskno = Guid.NewGuid().ToString("N");
|
|
|
_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(() =>
|
|
|
{
|
|
|
while (true)
|
|
|
{
|
|
|
List<AirportTask> Task = _Taskservice.GetAGVTaskInfos();
|
|
|
if (Task != null)
|
|
|
{
|
|
|
// 设置计时器
|
|
|
Stopwatch stopwatch = new Stopwatch();
|
|
|
stopwatch.Start();
|
|
|
foreach (AirportTask airportTask in Task)
|
|
|
{
|
|
|
//1.根据搬运AGV任务编号查询agv是否到达
|
|
|
if (!string.IsNullOrEmpty(airportTask.agvtaskno))
|
|
|
{
|
|
|
Console.WriteLine("搬运AGV已到达");
|
|
|
//2.调用3.查询任务状态接口
|
|
|
//根据搬运AGV任务编号查询agv是否到达
|
|
|
bool iflag = true;
|
|
|
if (iflag)
|
|
|
{
|
|
|
//3:已完成
|
|
|
// if (state == 3)
|
|
|
// {
|
|
|
//
|
|
|
// }
|
|
|
//更新任务表中AGV编号
|
|
|
airportTask.agvno = "";
|
|
|
//更新agv返回任务编号
|
|
|
airportTask.agvtaskno = Guid.NewGuid().ToString("N");
|
|
|
_Taskservice.UpdateTaskAsync(airportTask);
|
|
|
}
|
|
|
}
|
|
|
//根据复合AGV任务编号查询复合agv是否到达
|
|
|
if (!string.IsNullOrEmpty(airportTask.amrtaskno))
|
|
|
{
|
|
|
Console.WriteLine("复合AGV已到达");
|
|
|
//根据复合AGV任务编号查询agv是否到达
|
|
|
bool iflag = true;
|
|
|
if (iflag)
|
|
|
{
|
|
|
//已到达更新任务表中AGV编号
|
|
|
|
|
|
}
|
|
|
}
|
|
|
//复合、搬运已到上料点
|
|
|
if (!string.IsNullOrEmpty(airportTask.agvtaskno) && !string.IsNullOrEmpty(airportTask.agvtaskno))
|
|
|
{
|
|
|
Console.WriteLine("复合AGV已到达且搬运AGV已到达");
|
|
|
Console.WriteLine("下发视觉抓取任务");
|
|
|
|
|
|
//1.获取任务抓取数量
|
|
|
//判断是否为第一车,搬运机器人码垛无需定位
|
|
|
if (airportTask.loadcount == 0)
|
|
|
{
|
|
|
//下发视觉抓取任务
|
|
|
|
|
|
}
|
|
|
if (airportTask.loadcount == 0)
|
|
|
{
|
|
|
//下发视觉抓取任务
|
|
|
|
|
|
}
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
// 检查是否超过两秒
|
|
|
if (stopwatch.ElapsedMilliseconds > 2000)
|
|
|
{
|
|
|
_logger.LogError("超时");
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
Thread.Sleep(100);
|
|
|
|
|
|
});
|
|
|
}
|
|
|
catch (Exception ex)
|
|
|
{
|
|
|
|
|
|
}
|
|
|
}
|
|
|
|
|
|
|
|
|
}
|
|
|
} |