Browse Source

业务逻辑增加

master
pry 2 years ago
parent
commit
1fd730e4ef
6 changed files with 531 additions and 12 deletions
  1. +333
    -1
      HBLConsole.Business/Devices/MORKS.cs
  2. +1
    -0
      HBLConsole.Business/MessageServer/Base.cs
  3. +10
    -4
      HBLConsole.Communication/ModbusTcpHelper.cs
  4. +145
    -7
      HBLConsole.GVL/MORKS.cs
  5. +1
    -0
      HBLConsole.MainConsole/Main.cs
  6. +41
    -0
      HBLConsole.Service/RTrig.cs

+ 333
- 1
HBLConsole.Business/Devices/MORKS.cs View File

@@ -1,4 +1,5 @@
using HBLConsole.Communication;
using BPA.Message;
using HBLConsole.Communication;
using HBLConsole.Factory;
using HBLConsole.Interface;
using HBLConsole.Model;
@@ -7,7 +8,9 @@ using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using BPA.Message.Enum;

namespace HBLConsole.Business.Devices
{
@@ -17,6 +20,8 @@ namespace HBLConsole.Business.Devices
public static MORKS GetInstance => _Instance ?? (_Instance = new MORKS());
private MORKS() { }

GVL.MORKS mORKS = new GVL.MORKS();

/// <summary>
/// 写入配方数据到 PLC
/// </summary>
@@ -42,6 +47,9 @@ namespace HBLConsole.Business.Devices
ActionManagerment.GetInstance.Register(new Action(() =>
{
WriteRecipeBoms();
ReadPlcData();
DataParse();
Main();
}), "ConnectOk");

//获取物料信息
@@ -50,6 +58,330 @@ namespace HBLConsole.Business.Devices
//Modbus Tcp 连接
ModbusTcpHelper.GetInstance.ModbusTcpConnect("127.0.0.1");
}

/// <summary>
/// 数据读取
/// </summary>
private void ReadPlcData()
{
ThreadManagerment.GetInstance.StartLong(new Action(() =>
{
object result;
result = ModbusTcpHelper.GetInstance.Read(1120, ReadType.Coils, 16);
if (result != null)
{
if (result is bool[] bools)
{
if (bools.Length == 16)
{
mORKS.InitComplete = bools[0];
mORKS.TakeBowlIdle = bools[1];
mORKS.TemperatureReached = bools[2];
mORKS.AllowFallNoodle = bools[3];
mORKS.RbTakeNoodleComplete = bools[4];
mORKS.RbFallNoodleComplete = bools[5];
mORKS.RbOutMealComplete = bools[6];
mORKS.RobotIdle = bools[7];
mORKS.TakeMealDetect = bools[8];
mORKS.MissingBowl = bools[9];
mORKS.TurntableLowerLimit = bools[11];
}
}
}

//读取煮面栏状态
result = ModbusTcpHelper.GetInstance.Read(1136, ReadType.Coils, 6);
if (result != null)
{
if (result is bool[] bools)
{
if (bools.Length == 6)
{
for (int i = 0; i < 6; i++)
{
mORKS.NoodleCookerStatus[i] = bools[i];
}
}
}
}

//读取煮面炉完成信号
result = ModbusTcpHelper.GetInstance.Read(1144, ReadType.Coils, 6);
if (result != null)
{
if (result is bool[] bools)
{
if (bools.Length == 6)
{
for (int i = 0; i < 6; i++)
{
mORKS.CookNoodlesComplete[i] = bools[i];
}
}
}
}
Thread.Sleep(500);
}), "Read PLC Data");
}

/// <summary>
/// 数据解析
/// </summary>
private void DataParse()
{
ActionManagerment.GetInstance.Register(new Action<object>((o) =>
{
if (o is MorkOrderPush morkOrderPush)
{
foreach (var item in morkOrderPush.GoodBatchings)
{
var res = Json<BatchingInfoPar>.GetInstance.Base.orderMaterialDelivery.BatchingInfo.FirstOrDefault(p => p.BatchingId == item.BatchingId);
if (res != null)
{
if (ushort.TryParse(res.BatchingLoc, out ushort loc))
{
if (loc >= 1 && loc <= 5)
{
mORKS.RBTakeNoodleTask.Enqueue(new GVL.OrderLocInfo() { Loc = loc, SuborderId = morkOrderPush.SuborderId });
}
else if (loc >= 10 && loc <= 11)
{
mORKS.TakeBowlTask.Enqueue(new GVL.OrderLocInfo() { Loc = loc, SuborderId = morkOrderPush.SuborderId, RecipeNumber = (ushort)morkOrderPush.RecipeId });
}
}
}
}
}
}), "MorksParse");
}

bool AllowRun = false;
string TakeBowlId = string.Empty;//取碗订单ID
string IngredientsCompleteId = string.Empty;//配料完成订单ID
string[] CookNodelId = new string[6] { string.Empty, string.Empty, string.Empty, string.Empty, string.Empty, string.Empty, };
bool RobotTaskInterlock = false;//机器人任务互锁信号
string OutMealId = string.Empty;

private void Main()
{
ThreadManagerment.GetInstance.StartLong(new Action(() =>
{
AllowRun = mORKS.InitComplete && mORKS.TemperatureReached;

if (AllowRun)
{
TakeBowlTask();

TakeNoodleTask();
}
OutNoodleTask();
SingleDetect();

Thread.Sleep(1);
}), "Main Task");

}

/// <summary>
/// 取碗控制
/// </summary>
private void TakeBowlTask()
{
//取碗控制
if (RTrig.GetInstance("TakeBowl").Start(mORKS.TakeBowlIdle && mORKS.TakeBowlTask.Count > 0))
{
if (mORKS.TakeBowlTask.TryDequeue(out GVL.OrderLocInfo orderLocInfo))
{
TakeBowlId = orderLocInfo.SuborderId;
TakeBowlControl(orderLocInfo.Loc);
SetRecipeNumber(orderLocInfo.RecipeNumber);
SimpleFactory.GetInstance.OrderChanged(TakeBowlId, ORDER_STATUS.COOKING);
MessageLog.GetInstance.Show($"订单【{TakeBowlId}】,位置:[{orderLocInfo.Loc}]");
}
}
}

/// <summary>
/// 取面任务
/// </summary>
private void TakeNoodleTask()
{
//取面控制
if (!RobotTaskInterlock)
{
if (RTrig.GetInstance("TakeNoodle").Start(mORKS.RobotIdle && mORKS.RBTakeNoodleTask.Count > 0))
{
if (mORKS.RBTakeNoodleTask.TryDequeue(out GVL.OrderLocInfo orderLocInfo))
{
//设置转台位置
SetTurntableLoc(orderLocInfo.Loc);

//设置倒面位置
int loc = Array.FindIndex(mORKS.NoodleCookerStatus, p => p == false);//查找煮面炉空闲位置
if (loc >= 0 && loc <= 5)
{
CookNodelId[loc] = orderLocInfo.SuborderId;
SetFallNoodleLoc((ushort)(loc + 1));
}

//机器人开始取面
RobotTakeNoodle();

SimpleFactory.GetInstance.OrderChanged(orderLocInfo.SuborderId, ORDER_STATUS.COOKING);

MessageLog.GetInstance.Show($"订单【{orderLocInfo.SuborderId}】,转台:[{orderLocInfo.Loc}],煮面栏:[{loc}]");

}
}
}
}

/// <summary>
/// 出餐控制
/// </summary>
private void OutNoodleTask()
{
if (RobotTaskInterlock)
{
if (mORKS.AllowFallNoodle && mORKS.RobotIdle && !mORKS.TakeMealDetect)
{
int loc = Array.FindIndex(CookNodelId, p => p == IngredientsCompleteId);
if (loc >= 0 && loc <= 5)
{
if (mORKS.CookNoodlesComplete[loc])
{
SetTakeNoodleLoc((ushort)(loc + 1));
RobotOutMeal();
CookNoodleStatusReset((ushort)(loc + 1));
OutMealId = IngredientsCompleteId;
IngredientsCompleteId = string.Empty;
CookNodelId[loc] = string.Empty;
}
}

}
}
}

/// <summary>
/// 信号检测
/// </summary>
private void SingleDetect()
{
if (RTrig.GetInstance("AllowFallNoodle").Start(mORKS.AllowFallNoodle))
{
IngredientsCompleteId = TakeBowlId;
TakeBowlId = string.Empty;
}

if (RTrig.GetInstance("CompleteChange").Start(mORKS.RbOutMealComplete))
{
SimpleFactory.GetInstance.OrderChanged(OutMealId, ORDER_STATUS.COMPLETED_COOK);
MessageLog.GetInstance.Show($"订单【{OutMealId}】制作完成");
}

if (DelayRTrig.GetInstance("CompleteChange1").Start(mORKS.RbOutMealComplete && !mORKS.TakeMealDetect, 2))
{
SimpleFactory.GetInstance.OrderChanged(OutMealId, ORDER_STATUS.COMPLETED_TAKE);
MessageLog.GetInstance.Show($"订单【{OutMealId}】取餐完成");
OutMealId = string.Empty;
}

RobotTaskInterlock = mORKS.RobotIdle && mORKS.AllowFallNoodle && mORKS.NoodleCookerStatus.Where(p => p == true).ToList().Count >= 3;
}




/// <summary>
/// 取面完成复位
/// </summary>
private void TakeNoodleCompleteReset()
{
ModbusTcpHelper.GetInstance.Write(1124, WriteType.Coils, false);
}

/// <summary>
/// 指定煮面口状态复位
/// </summary>
/// <param name="num"></param>
private void CookNoodleStatusReset(int num)
{
if (num >= 1 && num <= 6)
{
ushort addRess = (ushort)(1136 + num - 1);
ModbusTcpHelper.GetInstance.Write(1136, WriteType.Coils, false);
}
}

/// <summary>
/// 写配方编号
/// </summary>
/// <param name="num"></param>
private void SetRecipeNumber(ushort num)
{
ModbusTcpHelper.GetInstance.Write(100, WriteType.HoldingRegisters, num);
}

/// <summary>
/// 设置转台位置
/// </summary>
/// <param name="loc"></param>
private void SetTurntableLoc(ushort loc)
{
ModbusTcpHelper.GetInstance.Write(101, WriteType.HoldingRegisters, loc);
}

/// <summary>
/// 设置倒面位置
/// </summary>
/// <param name="loc"></param>
private void SetFallNoodleLoc(ushort loc)
{
ModbusTcpHelper.GetInstance.Write(102, WriteType.HoldingRegisters, loc);
}

/// <summary>
/// 设置取面位置
/// </summary>
/// <param name="loc"></param>
private void SetTakeNoodleLoc(ushort loc)
{
ModbusTcpHelper.GetInstance.Write(103, WriteType.HoldingRegisters, loc);
}

/// <summary>
/// 取碗控制
/// </summary>
/// <param name="loc"></param>
private void TakeBowlControl(ushort loc)
{
if (loc == 10)
{
ModbusTcpHelper.GetInstance.Write(321, WriteType.Coils, true);
}
else if (loc == 11)
{
ModbusTcpHelper.GetInstance.Write(322, WriteType.Coils, true);
}
}

/// <summary>
/// 机器人取面
/// </summary>
private void RobotTakeNoodle()
{
ModbusTcpHelper.GetInstance.Write(323, WriteType.Coils, true);
}

/// <summary>
/// 机器人取餐
/// </summary>
private void RobotOutMeal()
{
ModbusTcpHelper.GetInstance.Write(324, WriteType.Coils, true);
}

}

}


+ 1
- 0
HBLConsole.Business/MessageServer/Base.cs View File

@@ -28,6 +28,7 @@ namespace HBLConsole.Business.MessageServer
OrderPush = morkOrderpush
});
ActionManagerment.GetInstance.Send("AddOrder", morkOrderpush);
ActionManagerment.GetInstance.Send("MorksParse", morkOrderpush);
}
}



+ 10
- 4
HBLConsole.Communication/ModbusTcpHelper.cs View File

@@ -112,8 +112,11 @@ namespace HBLConsole.Communication
catch (Exception ex)
{
MessageLog.GetInstance.Show(ex.ToString());
tcpClient = null;
Connect();
if (ex.InnerException is SocketException)
{
tcpClient = null;
Connect();
}
}
return result;
}
@@ -174,8 +177,11 @@ namespace HBLConsole.Communication
catch (Exception ex)
{
MessageLog.GetInstance.Show(ex.ToString());
tcpClient = null;
Connect();
if (ex.InnerException is SocketException)
{
tcpClient = null;
Connect();
}
}
return true;
}


+ 145
- 7
HBLConsole.GVL/MORKS.cs View File

@@ -4,6 +4,7 @@ using System.Linq;
using System.Text;
using System.Threading.Tasks;
using HBLConsole.Interface;
using System.Collections.Concurrent;

namespace HBLConsole.GVL
{
@@ -12,34 +13,171 @@ namespace HBLConsole.GVL
/// </summary>
public class MORKS : IGvl
{
/// <summary>
/// 初始化完成
/// </summary>
public bool InitComplete { get; set; }


/// <summary>
/// 机器人取面
/// PLC -> M0.3
/// ModbusTcp -> 323
/// </summary>
public bool RobotTakeNoodle { get; set; }

/// <summary>
/// 机器人出餐
/// PLC -> M0.4
/// ModbusTcp -> 324
/// </summary>
public bool RobotOutMeal { get; set; }

/// <summary>
/// 移动转台
/// PLC -> M0.5
/// ModbusTcp -> 325
/// </summary>
public bool MoveTurntable { get; set; }




/// <summary>
/// 煮面炉状态
/// 初始化完成
/// PLC -> M100.0
/// ModbusTcp -> 1120
/// </summary>
public bool[] NoodleCookerStatus { get; set; } = new bool[6] { false, false, false, false, false, false };
public bool InitComplete { get; set; }

/// <summary>
/// 取完空闲
/// 取碗机构空闲,True:忙碌,false:空闲
/// PLC -> M100.1
/// ModbusTcp -> 1121
/// </summary>
public bool TakeBowlIdle { get; set; }

/// <summary>
/// 温度到达,True:表示到达,false:未到达
/// PLC -> M100.2
/// ModbusTcp -> 1122
/// </summary>
public bool TemperatureReached { get; set; }

/// <summary>
/// 允许到面,配料完成
/// PLC -> M100.3
/// ModbusTcp -> 1123
/// </summary>
public bool AllowFallNoodle { get; set; }

/// <summary>
/// 机器人取面完成
/// PLC -> M100.4
/// ModbusTcp -> 1124
/// </summary>
public bool RbTakeNoodleComplete { get; set; }

/// <summary>
/// 机器人倒面完成
/// PLC -> M100.5
/// ModbusTcp -> 1125
/// </summary>
public bool RbFallNoodleComplete { get; set; }

/// <summary>
/// 机器人出餐完成,上报取餐完成
/// PLC -> M100.6
/// ModbusTcp -> 1126
/// </summary>
public bool RbOutMealComplete { get; set; }

/// <summary>
/// 机器人空闲
/// PLC -> M100.7
/// ModbusTcp -> 1127
/// </summary>
public bool RobotIdle { get; set; }

/// <summary>
/// 取餐口检测
/// PLC -> M101.0
/// ModbusTcp -> 1128
/// </summary>
public bool TakeMealDetect { get; set; }

/// <summary>
/// 缺碗信号,false:缺碗,true:有碗
/// PLC -> M101.1
/// ModbusTcp -> 1129
/// </summary>
public bool MissingBowl { get; set; }

/// <summary>
/// 转台下限检测
/// PLC -> M101.3
/// ModbusTcp -> 1131
/// </summary>
public bool TurntableLowerLimit { get; set; }

/// <summary>
/// 煮面炉状态,True:忙碌,false:空闲
/// M102.0 - M102.5
/// 1136 - 1141
/// </summary>
public bool[] NoodleCookerStatus { get; set; } = new bool[6] { false, false, false, false, false, false };

/// <summary>
/// 煮面完成,上升后给信号
/// M103.0 - M103.5
/// 1144 - 1149
/// </summary>
public bool[] CookNoodlesComplete { get; set; } = new bool[6] { false, false, false, false, false, false };

/// <summary>
/// 配方编号
/// PLC -> VW0
/// ModbusTcp -> 100
/// </summary>
public ushort RecipeNumber { get; set; }

/// <summary>
/// 转台位置
/// PLC -> VW2
/// ModbusTcp -> 101
/// </summary>
public ushort TurntableLoc { get; set; }

/// <summary>
/// 到面至煮面炉位置
/// PLC -> VW4
/// ModbusTcp -> 102
/// </summary>
public ushort FallNoodleLoc { get; set; }

/// <summary>
/// 取面位置
/// PLC -> VW6
/// ModbusTcp -> 103
/// </summary>
public ushort TakeNoodleLoc { get; set; }




/// <summary>
/// 机器人取面位置队列
/// </summary>
public ConcurrentQueue<OrderLocInfo> RBTakeNoodleTask { get; set; } = new ConcurrentQueue<OrderLocInfo>();

public ConcurrentQueue<OrderLocInfo> TakeBowlTask { get; set; } = new ConcurrentQueue<OrderLocInfo>();

}

public class OrderLocInfo
{
public string SuborderId { get; set; }
public ushort Loc { get; set; }
public ushort RecipeNumber { get; set; }
}




}

+ 1
- 0
HBLConsole.MainConsole/Main.cs View File

@@ -32,6 +32,7 @@ namespace HBLConsole.MainConsole
{
Json<MorkOrderPushPar>.GetInstance.Save();
Json<BatchingInfoPar>.GetInstance.Save();
TextHelper.GetInstance.SaveLogInfo(MessageLog.GetInstance.LogInfo, "LogInfo");
}

public void BusinessInit()


+ 41
- 0
HBLConsole.Service/RTrig.cs View File

@@ -0,0 +1,41 @@
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace HBLConsole.Service
{
public class RTrig
{

private volatile static ConcurrentDictionary<string, RTrig> _Instance;
public static RTrig GetInstance(string name)
{
if (_Instance == null) _Instance = new ConcurrentDictionary<string, RTrig>();
if (!_Instance.ContainsKey(name)) _Instance.TryAdd(name, new RTrig());
return _Instance[name];
}
private RTrig() { }

private bool flag1;
public bool Q { get; private set; }
private bool IN1
{
set
{
Q = value && !flag1;
flag1 = value;
}
}
public bool Start(bool IN)
{
IN1 = IN;
return Q;
}



}
}

Loading…
Cancel
Save