583 lines
24 KiB
C#
583 lines
24 KiB
C#
|
|
using Cowain.Bake.BLL;
|
|||
|
|
using Cowain.Bake.Common;
|
|||
|
|
using Cowain.Bake.Common.Core;
|
|||
|
|
using Cowain.Bake.Common.Enums;
|
|||
|
|
using Cowain.Bake.Common.Interface;
|
|||
|
|
using Cowain.Bake.Common.Models;
|
|||
|
|
using Cowain.Bake.Communication.Interface;
|
|||
|
|
using Cowain.Bake.Communication.MOM;
|
|||
|
|
using Cowain.Bake.Main.ViewModels;
|
|||
|
|
using Cowain.Bake.Model;
|
|||
|
|
using Cowain.Bake.Model.Entity;
|
|||
|
|
using Cowain.Bake.Model.Models;
|
|||
|
|
using HslCommunication;
|
|||
|
|
using Newtonsoft.Json;
|
|||
|
|
using Opc.Ua;
|
|||
|
|
using Prism.Ioc;
|
|||
|
|
using System;
|
|||
|
|
using System.Collections.Generic;
|
|||
|
|
using System.Linq;
|
|||
|
|
using System.Threading;
|
|||
|
|
using System.Threading.Tasks;
|
|||
|
|
using Unity;
|
|||
|
|
using JSON = Newtonsoft.Json.JsonConvert;
|
|||
|
|
|
|||
|
|
namespace Cowain.Bake.Main.Station
|
|||
|
|
{
|
|||
|
|
public class TaskStation: IServerManager
|
|||
|
|
{
|
|||
|
|
public string Name { get; set; }
|
|||
|
|
static Int16 _lastStepId = 0;
|
|||
|
|
public IUnityContainer _unityContainer { get; set; }
|
|||
|
|
readonly CancellationTokenSource cts = new CancellationTokenSource();
|
|||
|
|
readonly TDeviceConfig config;
|
|||
|
|
IPLCDevice agv = null;
|
|||
|
|
readonly List<CavityInfoModel> _stationCavity;
|
|||
|
|
public List<TStation> _station = null;
|
|||
|
|
public AutoResetEvent _newTaskEvent = new AutoResetEvent(true);
|
|||
|
|
public TaskStation(IUnityContainer unityContainer)
|
|||
|
|
{
|
|||
|
|
_unityContainer = unityContainer;
|
|||
|
|
_station = _unityContainer.Resolve<MemoryDataProvider>().AllStation;
|
|||
|
|
config = _unityContainer.Resolve<DeviceConfigService>().GetConfig(EDeviceType.PLC, EDeviceName.AGV)[0];
|
|||
|
|
_stationCavity = _unityContainer.Resolve<CavityInfoService>().GetAllStation();
|
|||
|
|
Start();
|
|||
|
|
StartNewTask();
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
public void Start()
|
|||
|
|
{
|
|||
|
|
var task = _unityContainer.Resolve<TaskRecordService>().UnexecuteTask();
|
|||
|
|
if (null == task)
|
|||
|
|
{
|
|||
|
|
_lastStepId = (int)ETaskStep.None;
|
|||
|
|
}
|
|||
|
|
else
|
|||
|
|
{
|
|||
|
|
_lastStepId = (short)task.StepId;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
agv = _unityContainer.Resolve<IPLCDevice>(config.Name);
|
|||
|
|
//TTaskRecord task = await GenerateTask(); #测试
|
|||
|
|
}
|
|||
|
|
public async Task DealTask(DataValue data, Variable node)
|
|||
|
|
{
|
|||
|
|
bool dealResult = false; //进去这里,看会不会触发别的
|
|||
|
|
LogHelper.Instance.Info($"开始任务--------------信号,线程ID:{System.Threading.Thread.CurrentThread.ManagedThreadId},{node.VarDesc}");
|
|||
|
|
do
|
|||
|
|
{
|
|||
|
|
// 启动任务并等待结果
|
|||
|
|
//dealResult = await Task.Run(() => ThreadDealTask(data, node));
|
|||
|
|
dealResult = ThreadDealTask(data, node);
|
|||
|
|
if (!dealResult)
|
|||
|
|
{
|
|||
|
|
LogHelper.Instance.Error("-------------------------处理任务异常!");
|
|||
|
|
await Task.Delay(2 * 1000);
|
|||
|
|
}
|
|||
|
|
} while(!dealResult);
|
|||
|
|
LogHelper.Instance.Info($"完成任务--------------信号,线程ID:{System.Threading.Thread.CurrentThread.ManagedThreadId}");
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
void StartNewTask()
|
|||
|
|
{
|
|||
|
|
Task.Run( () =>
|
|||
|
|
{
|
|||
|
|
agv = _unityContainer.Resolve<IPLCDevice>(config.Name);
|
|||
|
|
while (!cts.Token.IsCancellationRequested)
|
|||
|
|
{
|
|||
|
|
if (Global.AppExit)
|
|||
|
|
{
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
DealNewTask();
|
|||
|
|
}
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
public void DealNewTask()
|
|||
|
|
{
|
|||
|
|
_newTaskEvent.WaitOne(10*1000);
|
|||
|
|
|
|||
|
|
Variable nodeTemp = (from secondaryList in agv.Storages //不能做触发,因为没有任务。要地直运行里面,来检测是否有任务
|
|||
|
|
from item in secondaryList.VariableList
|
|||
|
|
where item.ParamName == EAgvPLC.RetCount.ToString()
|
|||
|
|
select item).FirstOrDefault();
|
|||
|
|
Variable node = BasicFramework.DeepCopy<Variable>(nodeTemp);
|
|||
|
|
|
|||
|
|
if (null == node || !node.Quality || null == node.CurValue) //无值,退出
|
|||
|
|
{
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
TTaskRecord oldTask = _unityContainer.Resolve<TaskRecordService>().UnexecuteTask();
|
|||
|
|
|
|||
|
|
//1.有任务 + 自动 ,退出
|
|||
|
|
//2.有任务 + 手动 + 任务执行中: 退出
|
|||
|
|
if (null != oldTask)
|
|||
|
|
{
|
|||
|
|
if (oldTask.Status != (int)ETaskStatus.UnExecute)
|
|||
|
|
{
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
TaskEntity task = GetTask();
|
|||
|
|
|
|||
|
|
if (null == task)
|
|||
|
|
{
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
CommonCoreHelper.Instance.BlockTask.Add(task); //更新界面(任务未执行)
|
|||
|
|
SetCount(node);
|
|||
|
|
_lastStepId = (int)ETaskStep.MoveFrom; //StepId:手动第一次为1,自动第一次为10
|
|||
|
|
if (!SendNextStep(task, node.Json, false)) //发送第一步
|
|||
|
|
{
|
|||
|
|
return; //发送失败
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
|
|||
|
|
//一条任务第一次发任务时
|
|||
|
|
if (!_unityContainer.Resolve<TaskRecordService>().ModifyTaskStatus(ETaskStatus.Executing)) //更新任务状态为执行中
|
|||
|
|
{
|
|||
|
|
LogHelper.Instance.Fatal("更改任务状态失败");
|
|||
|
|
}
|
|||
|
|
CommonCoreHelper.Instance.BlockTask.Add(task); //任务没有执行完。所以不需要更新界面
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
void SetCount(Variable node)
|
|||
|
|
{
|
|||
|
|
var model = agv.Read<Int16>(node.Address + node.VarName);
|
|||
|
|
if (!model.IsSuccess
|
|||
|
|
|| 1 != model.Content)
|
|||
|
|
{
|
|||
|
|
SettingProvider.Instance.CountCmd = 0; //每条任务从1开始
|
|||
|
|
}
|
|||
|
|
else
|
|||
|
|
{
|
|||
|
|
SettingProvider.Instance.CountCmd = 100;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
private TaskEntity GetTask()
|
|||
|
|
{
|
|||
|
|
if (SettingProvider.Instance.DispMode == EDispatchMode.Auto)
|
|||
|
|
{
|
|||
|
|
var oldTask = _unityContainer.Resolve<TaskRecordService>().UnexecuteTask();
|
|||
|
|
if (oldTask != null)
|
|||
|
|
{
|
|||
|
|
return GetStationManualTask(oldTask);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
//看到过有任务还生成
|
|||
|
|
return _unityContainer.Resolve<TaskRecordService>().GetTask(); //获得调度任务,并插入一条任务进任务记录表
|
|||
|
|
}
|
|||
|
|
else //手动从数据库获取
|
|||
|
|
{
|
|||
|
|
TTaskRecord manualTask = _unityContainer.Resolve<TaskRecordService>().UnexecuteTask();
|
|||
|
|
if (null == manualTask)
|
|||
|
|
{
|
|||
|
|
return null; //没有任务(手动任务),就退出
|
|||
|
|
}
|
|||
|
|
return GetStationManualTask(manualTask);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
/*
|
|||
|
|
//1.执行中:机器人正在执行任务中, 如果上位机重启,会触发,
|
|||
|
|
//2.无务任或任务执行完成:计命令计算为0或最后一步执行完成,更新状态(无任务不需要),生成任务,下发下一步指令
|
|||
|
|
//3.一步任务完成: 更新状态, 下发下一步指令
|
|||
|
|
*/
|
|||
|
|
public bool ThreadDealTask(DataValue data, Variable node)
|
|||
|
|
{
|
|||
|
|
string msg = "";
|
|||
|
|
LogHelper.Instance.Error("开始接收调度机器人信息!");
|
|||
|
|
Int16 countValue ;
|
|||
|
|
dynamic d = JsonConvert.DeserializeObject<dynamic>(node.TrigJson);
|
|||
|
|
if (null == agv || !agv.IsConnect)
|
|||
|
|
{
|
|||
|
|
msg = "连接机器人的PLC断开!";
|
|||
|
|
LogHelper.Instance.Error(msg);
|
|||
|
|
_unityContainer.Resolve<MainWindowViewModel>().AddPromptContent(msg);
|
|||
|
|
return false;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
try
|
|||
|
|
{
|
|||
|
|
var stepValue = agv.Read<Int16>((string)d.ReadCmd); //可以改成直接读PLC [命令地址]
|
|||
|
|
var resultValue = agv.Read<int>((string)d.ReadResult); //这是直接读PLC [执行命令结果]
|
|||
|
|
|
|||
|
|
if (!stepValue.IsSuccess || !resultValue.IsSuccess)
|
|||
|
|
{
|
|||
|
|
LogHelper.Instance.Error($"PLC反馈任务时,读取失败!,失败原因:{stepValue.Message},{stepValue.Message}");
|
|||
|
|
return false;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (data.WrappedValue.TypeInfo.BuiltInType == Opc.Ua.BuiltInType.Int16)
|
|||
|
|
{
|
|||
|
|
countValue = (Int16)data.WrappedValue.Value;
|
|||
|
|
LogHelper.Instance.Debug($"接收任务信息:计数:{countValue},命令步:{stepValue.Content},结果:{resultValue.Content},当前命令步:{_lastStepId},当前计数:{SettingProvider.Instance.CountCmd}");
|
|||
|
|
}
|
|||
|
|
else
|
|||
|
|
{
|
|||
|
|
LogHelper.Instance.Warn($"没有找到这个数据类型,节点名为{node.VarDesc}", true);
|
|||
|
|
return false;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (!EnumHelper.IsDefined<ETaskStep>(stepValue.Content)) //不在范围内
|
|||
|
|
{
|
|||
|
|
LogHelper.Instance.Warn($"获取PLC的命令有问题,值:{countValue}", true);
|
|||
|
|
return false;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
_unityContainer.Resolve<EquipmentMonitorViewModel>().SetAgvImage(resultValue.Content);
|
|||
|
|
if (resultValue.Content == (int)EAgvMoveStatus.Error) // -1:表示没有完成
|
|||
|
|
{
|
|||
|
|
//if (countValue > SettingProvider.Instance.CountCmd) 此时上位机是1,PLC是3。 如果执行下面,后续PLC执行1,就不会任务了
|
|||
|
|
//{
|
|||
|
|
// SettingProvider.Instance.CountCmd = countValue;
|
|||
|
|
// LogHelper.Instance.Debug($"更改当前计数:{SettingProvider.Instance.CountCmd}");
|
|||
|
|
//}
|
|||
|
|
return false;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
//1.机器人正在执行任务中, 如果上位机重启,此时又有任务
|
|||
|
|
//如果:countValue=3000,Instance.CountCmd=1,时,到下面退出,也不影响。
|
|||
|
|
if (countValue == SettingProvider.Instance.CountCmd - 1) //(重启上位机,任务在执行中)
|
|||
|
|
{
|
|||
|
|
LogHelper.Instance.Warn($"重启上位机,此时又有任务在执行中!");
|
|||
|
|
return true;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (_lastStepId == (int)ETaskStep.None)
|
|||
|
|
{
|
|||
|
|
LogHelper.Instance.Warn($"重启上位机, 没有任务在执行!");
|
|||
|
|
return true;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
//表示执行完成了,执行下一个; 或无任务
|
|||
|
|
if (
|
|||
|
|
countValue >= SettingProvider.Instance.CountCmd
|
|||
|
|
&& stepValue.Content == _lastStepId
|
|||
|
|
)
|
|||
|
|
{
|
|||
|
|
SettingProvider.Instance.CountCmd = countValue; //PLC跳步
|
|||
|
|
TTaskRecord task = _unityContainer.Resolve<TaskRecordService>().UnexecuteTask();
|
|||
|
|
if (null == task) //无任务:不需要做什么,有任务:更新状态
|
|||
|
|
{
|
|||
|
|
LogHelper.Instance.Fatal($"此时应该数据库中要有未执行的任务,计数:{countValue},命令:{stepValue}");
|
|||
|
|
return true;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
TaskEntity detailTask = GetStationManualTask(task); //通过任务,获取工站信息
|
|||
|
|
detailTask.StepId = (sbyte)stepValue.Content;
|
|||
|
|
|
|||
|
|
if (!DealFinishCmd(detailTask, _lastStepId))
|
|||
|
|
{
|
|||
|
|
return false;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (_lastStepId == (int)ETaskStep.Place //表示当前是一个任务的最后一条命令
|
|||
|
|
/* || 0 == countCmd*/) //PLC重启为0,一条完整的任务完成了,将获取最后一条指令
|
|||
|
|
{
|
|||
|
|
detailTask.StepId = (int)ETaskStep.Finish;
|
|||
|
|
CommonCoreHelper.Instance.BlockTask.Add(detailTask); //机器人界面显示
|
|||
|
|
CommonCoreHelper.Instance.MainViewAutoEvent.Set();
|
|||
|
|
_newTaskEvent.Set();
|
|||
|
|
return true; //完成了一条完整的任务,另外一个方法生成新的任务
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
//发送下一步命令
|
|||
|
|
if (!SendNextStep(detailTask, node.Json))
|
|||
|
|
{
|
|||
|
|
return false;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
CommonCoreHelper.Instance.BlockTask.Add(detailTask); //机器人界面显示
|
|||
|
|
CommonCoreHelper.Instance.MainViewAutoEvent.Set();
|
|||
|
|
LogHelper.Instance.Error("处理完接收调度机器人信息!");
|
|||
|
|
}
|
|||
|
|
else
|
|||
|
|
{
|
|||
|
|
LogHelper.Instance.Error($"接收到的信息PLC的调试任务异常,plc cmd:{stepValue},plc 计数:{countValue};\r" +
|
|||
|
|
$"上位机 cmd:{_lastStepId},上位机 计数:{SettingProvider.Instance.CountCmd},正常不会执行到这里!");
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
catch(Exception ex)
|
|||
|
|
{
|
|||
|
|
LogHelper.Instance.GetCurrentClassError($"{ex.Message}-{ex.StackTrace}");
|
|||
|
|
return false;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
|
|||
|
|
|
|||
|
|
return true;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
public bool SendNextStep(TaskEntity detailTask, string json, bool next = true)
|
|||
|
|
{
|
|||
|
|
LogHelper.Instance.Info($"发送步骤:{detailTask.StepId},命令计数:{SettingProvider.Instance.CountCmd}");
|
|||
|
|
|
|||
|
|
detailTask = SetNextStep(detailTask, next); //会设置CountCmd StepId
|
|||
|
|
if (!SendTask(detailTask, json)) //发送任务
|
|||
|
|
{
|
|||
|
|
LogHelper.Instance.Error($"发送任务信息失败,{JsonConvert.SerializeObject(detailTask)}!");
|
|||
|
|
return false;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
_lastStepId = detailTask.StepId;
|
|||
|
|
SettingProvider.Instance.CountCmd = detailTask.CountCmd;
|
|||
|
|
LogHelper.Instance.Debug($"计数改变:{SettingProvider.Instance.CountCmd}");
|
|||
|
|
return StartStep(detailTask);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
public bool ManualTaskCmd(TTaskRecord task, short stepId) //界面上指定再发送一次时,
|
|||
|
|
{
|
|||
|
|
Variable nodeCountCmd = (from secondaryList in agv.Storages //不能做触发,因为没有任务。要地直运行里面,来检测是否有任务
|
|||
|
|
from item in secondaryList.VariableList
|
|||
|
|
where item.ParamName == EAgvPLC.RetCount.ToString()
|
|||
|
|
select item).FirstOrDefault();
|
|||
|
|
|
|||
|
|
_lastStepId = (short)stepId;
|
|||
|
|
TaskEntity detailTask = GetStationManualTask(task); //通过任务,获取工站信息
|
|||
|
|
return SendNextStep(detailTask, nodeCountCmd.Json, false);
|
|||
|
|
}
|
|||
|
|
bool DealFinishCmd(TaskEntity detailTask, Int16 cmdValue)
|
|||
|
|
{
|
|||
|
|
if (0 >= _unityContainer.Resolve<TaskStepService>().UpdateEndTime(detailTask.Id, (ETaskStep)cmdValue))
|
|||
|
|
{
|
|||
|
|
LogHelper.Instance.Error($"修改命令结束时间失败!任务ID:{detailTask.Id},命令:{_lastStepId}");
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return UpdateFinishStep(detailTask);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
bool StartStep(TaskEntity detailTask)
|
|||
|
|
{
|
|||
|
|
if (0 >= _unityContainer.Resolve<TaskStepService>().UpdateStartTime((int)detailTask.Id, detailTask.CountCmd, detailTask.StepId))
|
|||
|
|
{
|
|||
|
|
LogHelper.Instance.Error($"修改命令开始时间失败!任务ID:{detailTask.Id},命令:{detailTask.StepId},命令计算:{detailTask.CountCmd}");
|
|||
|
|
return false;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return true;
|
|||
|
|
}
|
|||
|
|
bool UpdateFinishStep(TaskEntity stationTask)
|
|||
|
|
{
|
|||
|
|
int result = 0;
|
|||
|
|
switch (stationTask.StepId)
|
|||
|
|
{
|
|||
|
|
case (int)ETaskStep.MoveFrom:
|
|||
|
|
//修改机器人的位置,给界面发信号
|
|||
|
|
result =_unityContainer.Resolve<CavityInfoService>().SetRobotPos(stationTask.FromStationNumber);
|
|||
|
|
break;
|
|||
|
|
case (int)ETaskStep.Pick:
|
|||
|
|
UpdateOutStoveTime(stationTask); //更改出炉时间
|
|||
|
|
result = _unityContainer.Resolve<TaskRecordService>().BindPalletToRobot(); //将夹具绑定在机器人上
|
|||
|
|
break;
|
|||
|
|
case (int)ETaskStep.MoveTo:
|
|||
|
|
result = _unityContainer.Resolve<CavityInfoService>().SetRobotPos(stationTask.ToStationNumber);
|
|||
|
|
break;
|
|||
|
|
case (int)ETaskStep.Place:
|
|||
|
|
result = _unityContainer.Resolve<TaskRecordService>().UpdateTask(); //1.加锁,解锁,2.绑定,解绑夹具,3.更新机器人的位置,4.更新任务状态完成,
|
|||
|
|
SendIntoStove(stationTask); //如果是满载夹具,要将调用烘烤进站接口
|
|||
|
|
_unityContainer.Resolve<TaskRecordService>().UpdateFinishStepId(stationTask.Id); //修改任务步为完成
|
|||
|
|
break;
|
|||
|
|
default:
|
|||
|
|
break;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (result <= 0)
|
|||
|
|
{
|
|||
|
|
LogHelper.Instance.Error($"接到任务完成,但处理异常:{result},cmd:{stationTask.StepId}");
|
|||
|
|
//return false;
|
|||
|
|
}
|
|||
|
|
return true;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
void UpdateOutStoveTime(TaskEntity stationTask)
|
|||
|
|
{
|
|||
|
|
var cavityStove = _stationCavity.Where(x => x.Id == stationTask.Source && x.Type == (int)EStationType.Stove).FirstOrDefault();
|
|||
|
|
if (null != cavityStove) //更改出炉时间
|
|||
|
|
{
|
|||
|
|
_unityContainer.Resolve<PalletInfoService>().UpdateOutStoveTime(cavityStove.PalletId);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
void SendIntoStove(TaskEntity stationTask)
|
|||
|
|
{
|
|||
|
|
//if (!_unityContainer.Resolve<TaskTypeService>().IsPullInBaker(stationTask.TaskTypeId))
|
|||
|
|
if (1 != stationTask.TaskTypeId)// 1: 上料满夹具->烤箱
|
|||
|
|
{
|
|||
|
|
return ;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
var cavityInfo = _stationCavity.Where(x=>x.Id == stationTask.Target).FirstOrDefault();
|
|||
|
|
var palletInfo = _unityContainer.Resolve<PalletInfoService>().GetPalletInfo(stationTask.PalletId);
|
|||
|
|
List<string> batteryCodes = _unityContainer.Resolve<BatteryInfoService>().GetBatteryInfos(palletInfo.VirtualId).Select(x=>x.BatteryCode).ToList();
|
|||
|
|
|
|||
|
|
if (int.Parse(_unityContainer.Resolve<SysSetupService>().GetValueByParaID(ESysSetup.MOMEnable.ToString())) == (int)EMOMEnable.Enable
|
|||
|
|
&& 0 != batteryCodes.Count)
|
|||
|
|
{
|
|||
|
|
_unityContainer.Resolve<MESProcess>().MESBakingInput(cavityInfo.CavityName, palletInfo.PalletCode, batteryCodes, _unityContainer.Resolve<BasicInfoViewModel>().CurrentOperation);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
|
|||
|
|
public TaskEntity GetStationManualTask(TTaskRecord task)
|
|||
|
|
{
|
|||
|
|
TaskEntity taskEn = JSON.DeserializeObject<TaskEntity>(JSON.SerializeObject(task));
|
|||
|
|
var sourceDetail = _unityContainer.Resolve<CavityInfoService>().GetStationDetailById(task.Source);
|
|||
|
|
var targetDetail = _unityContainer.Resolve<CavityInfoService>().GetStationDetailById(task.Target);
|
|||
|
|
var stationTask = MakeManualTask(taskEn, sourceDetail, targetDetail);
|
|||
|
|
//stationTask.Copy(task, stationTask);
|
|||
|
|
return stationTask;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
TaskEntity SetNextStep(TaskEntity task, bool isNext = true)
|
|||
|
|
{
|
|||
|
|
sbyte nextStepId = (sbyte)_lastStepId;
|
|||
|
|
if (isNext)
|
|||
|
|
{
|
|||
|
|
nextStepId = (sbyte)_unityContainer.Resolve<RgvActionService>().GetNext(_lastStepId); //下一步
|
|||
|
|
}
|
|||
|
|
task.CountCmd = SettingProvider.Instance.CountCmd + 1; //下一个计数
|
|||
|
|
task.StepId = (sbyte)nextStepId;
|
|||
|
|
return task;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
public TaskEntity MakeManualTask(TaskEntity taskEn, TCavityInfo src, TCavityInfo desc)
|
|||
|
|
{
|
|||
|
|
taskEn.FromStationNumber = src.StationNumber;
|
|||
|
|
taskEn.FromRow = src.Layer;
|
|||
|
|
taskEn.FromColumn = src.Column;
|
|||
|
|
taskEn.ToStationNumber = desc.StationNumber;
|
|||
|
|
taskEn.ToRow = desc.Layer;
|
|||
|
|
taskEn.ToColumn = desc.Column;
|
|||
|
|
return taskEn;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
public bool SendTask(TaskEntity task, string json)
|
|||
|
|
{
|
|||
|
|
LogHelper.Instance.Info($"发送任务开始");
|
|||
|
|
List<AddrValue> makeAddrValues = new List<AddrValue>();
|
|||
|
|
dynamic d = JsonConvert.DeserializeObject<dynamic>(json);
|
|||
|
|
string fromStation = d.FromStation;
|
|||
|
|
string fromLayer = d.FromRow;
|
|||
|
|
string fromColumn = d.FromColumn;
|
|||
|
|
string toStation = d.ToStation;
|
|||
|
|
string toLayer = d.ToRow;
|
|||
|
|
string toColumn = d.ToColumn;
|
|||
|
|
string cmd = d.Cmd;
|
|||
|
|
string countAddr = d.Count;
|
|||
|
|
|
|||
|
|
makeAddrValues.Add(new AddrValue()
|
|||
|
|
{
|
|||
|
|
Addr = fromStation,
|
|||
|
|
Value = (int)task.FromStationNumber,
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
var from = _station.Where(p => p.Id == (int)task.FromStationNumber).FirstOrDefault();
|
|||
|
|
if (from.Type == (int)EStationType.Loading
|
|||
|
|
|| from.Type == (int)EStationType.UnLoading)
|
|||
|
|
{
|
|||
|
|
makeAddrValues.Add(new AddrValue()
|
|||
|
|
{
|
|||
|
|
Addr = fromLayer,
|
|||
|
|
Value = (int)task.FromRow,
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
makeAddrValues.Add(new AddrValue()
|
|||
|
|
{
|
|||
|
|
Addr = fromColumn,
|
|||
|
|
Value = (int)task.FromColumn,
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
else
|
|||
|
|
{
|
|||
|
|
makeAddrValues.Add(new AddrValue()
|
|||
|
|
{
|
|||
|
|
Addr = fromLayer,
|
|||
|
|
Value = (int)task.FromColumn,
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
makeAddrValues.Add(new AddrValue()
|
|||
|
|
{
|
|||
|
|
Addr = fromColumn,
|
|||
|
|
Value = (int)task.FromRow,
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
makeAddrValues.Add(new AddrValue()
|
|||
|
|
{
|
|||
|
|
Addr = toStation,
|
|||
|
|
Value = (int)task.ToStationNumber,
|
|||
|
|
});
|
|||
|
|
var to = _station.Where(p => p.Id == (int)task.ToStationNumber).FirstOrDefault();
|
|||
|
|
if (to.Type == (int)EStationType.Loading
|
|||
|
|
|| to.Type == (int)EStationType.UnLoading)
|
|||
|
|
{
|
|||
|
|
makeAddrValues.Add(new AddrValue()
|
|||
|
|
{
|
|||
|
|
Addr = toLayer,
|
|||
|
|
Value = (int)task.ToRow,
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
makeAddrValues.Add(new AddrValue()
|
|||
|
|
{
|
|||
|
|
Addr = toColumn,
|
|||
|
|
Value = (int)task.ToColumn,
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
else
|
|||
|
|
{
|
|||
|
|
makeAddrValues.Add(new AddrValue()
|
|||
|
|
{
|
|||
|
|
Addr = toLayer,
|
|||
|
|
Value = (int)task.ToColumn,
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
makeAddrValues.Add(new AddrValue()
|
|||
|
|
{
|
|||
|
|
Addr = toColumn,
|
|||
|
|
Value = (int)task.ToRow,
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
makeAddrValues.Add(new AddrValue()
|
|||
|
|
{
|
|||
|
|
Addr = cmd,
|
|||
|
|
Value = (Int16)task.StepId,
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
//makeAddrValues.Add(new AddrValue()
|
|||
|
|
//{
|
|||
|
|
// Addr = countAddr,
|
|||
|
|
// Value = (Int16)task.CountCmd, //必须最后一个写
|
|||
|
|
//});
|
|||
|
|
|
|||
|
|
OperateResult result = agv.Writes(makeAddrValues.Select(x => x.Addr).ToArray(), makeAddrValues.Select(x => x.Value).ToArray());
|
|||
|
|
if (!result.IsSuccess)
|
|||
|
|
{
|
|||
|
|
LogHelper.Instance.Fatal($"写任务步骤失败:{JsonConvert.SerializeObject(makeAddrValues)},{JsonConvert.SerializeObject(makeAddrValues)}");
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
result = agv.Write<Int16>(countAddr, (Int16)task.CountCmd);
|
|||
|
|
if (!result.IsSuccess)
|
|||
|
|
{
|
|||
|
|
LogHelper.Instance.Fatal($"写任务计数失败:{JsonConvert.SerializeObject(makeAddrValues)},{JsonConvert.SerializeObject(makeAddrValues)}");
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
LogHelper.Instance.Debug($"发送任务:{JsonConvert.SerializeObject(makeAddrValues)}");
|
|||
|
|
LogHelper.Instance.Debug($"发送计数:{countAddr}:{(Int16)task.CountCmd}");
|
|||
|
|
//_unityContainer.Resolve<LogService>().AddLog("TaskStation:SendTask:发送任务结束", E_LogType.Info.ToString());
|
|||
|
|
return result.IsSuccess;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
public void Stop()
|
|||
|
|
{
|
|||
|
|
// 在需要取消任务的时候,调用以下代码:
|
|||
|
|
cts.Cancel();
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
}
|
|||
|
|
}
|