From 2c3e7ec5d0d2b6624455b13b5fd29c69bb3efbe2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=A6=82=E6=84=8F=20=E5=BD=AD?= <2417589739@qq.com> Date: Tue, 31 May 2022 16:52:56 +0800 Subject: [PATCH] =?UTF-8?q?morkt=E7=A7=BB=E6=A4=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- BPASmartClient.DRCoffee/CoffeeMachine.cs | 4 + BPASmartClient.Device/BaseDevice.cs | 8 + BPASmartClient.Helper/ExpandMethod.cs | 47 +- .../BPASmartClient.JAKA.csproj | 14 + BPASmartClient.JAKA/JakaMachine.cs | 83 ++ .../BPASmartClient.JakaRobot.csproj | 13 + BPASmartClient.JakaRobot/JaKaHelper.cs | 371 ++++++ BPASmartClient.JakaRobot/jakaAPI.cs | 1063 +++++++++++++++++ BPASmartClient.JakaRobot/jkType.cs | 364 ++++++ .../BPASmartClient.Juicer.csproj | 14 + BPASmartClient.Juicer/JuicerMachine.cs | 61 + BPASmartClient.Lebai/LebaiRobot.cs | 3 + BPASmartClient.MCU/BPASmartClient.MCU.csproj | 14 + BPASmartClient.MCU/MCUMachine.cs | 71 ++ BPASmartClient.MORKSM.BK.PLC/PLCMachine.cs | 6 +- BPASmartClient.Model/BaseEvent.cs | 2 + BPASmartClient.Model/PLC/ReadModel.cs | 2 + BPASmartClient.Model/单片机/SCChipEvent.cs | 21 +- BPASmartClient.Model/果汁机/JuicerModel.cs | 66 + .../节卡机器人/JakaModel.cs | 51 + .../BPASmartClient.MorkTLebaiJC.csproj | 4 + BPASmartClient.MorkT.Lebai.JC/Class1.cs | 8 - .../Control_MORKJC2.cs | 865 ++++++++++++++ .../PolymerBatching.cs | 152 +++ .../BPASmartClient.MorkTJAKAJC.csproj | 4 + BPASmartClient.Morkt.JAKA.JC/Class1.cs | 8 - .../Control_MORKJC.cs | 828 +++++++++++++ BPASmartClient.Morkt.JAKA.JC/GVL_MORKJC.cs | 8 + .../PolymerBatching.cs | 152 +++ BPASmartClient.Peripheral/BasePeripheral.cs | 10 + BPASmartClient.Peripheral/IPeripheral.cs | 2 + BPASmartClient.SCChip/Protocal/IC_CMD.cs | 1 + BPASmartClient.SerialPort/JuicerHelper.cs | 113 ++ BPASmartClient.SerialPort/MCUSerialHelper.cs | 140 +++ SmartClient.sln | 98 +- 35 files changed, 4614 insertions(+), 57 deletions(-) create mode 100644 BPASmartClient.JAKA/BPASmartClient.JAKA.csproj create mode 100644 BPASmartClient.JAKA/JakaMachine.cs create mode 100644 BPASmartClient.JakaRobot/BPASmartClient.JakaRobot.csproj create mode 100644 BPASmartClient.JakaRobot/JaKaHelper.cs create mode 100644 BPASmartClient.JakaRobot/jakaAPI.cs create mode 100644 BPASmartClient.JakaRobot/jkType.cs create mode 100644 BPASmartClient.Juicer/BPASmartClient.Juicer.csproj create mode 100644 BPASmartClient.Juicer/JuicerMachine.cs create mode 100644 BPASmartClient.MCU/BPASmartClient.MCU.csproj create mode 100644 BPASmartClient.MCU/MCUMachine.cs create mode 100644 BPASmartClient.Model/果汁机/JuicerModel.cs create mode 100644 BPASmartClient.Model/节卡机器人/JakaModel.cs delete mode 100644 BPASmartClient.MorkT.Lebai.JC/Class1.cs create mode 100644 BPASmartClient.MorkT.Lebai.JC/Control_MORKJC2.cs create mode 100644 BPASmartClient.MorkT.Lebai.JC/PolymerBatching.cs delete mode 100644 BPASmartClient.Morkt.JAKA.JC/Class1.cs create mode 100644 BPASmartClient.Morkt.JAKA.JC/Control_MORKJC.cs create mode 100644 BPASmartClient.Morkt.JAKA.JC/GVL_MORKJC.cs create mode 100644 BPASmartClient.Morkt.JAKA.JC/PolymerBatching.cs create mode 100644 BPASmartClient.SerialPort/JuicerHelper.cs create mode 100644 BPASmartClient.SerialPort/MCUSerialHelper.cs diff --git a/BPASmartClient.DRCoffee/CoffeeMachine.cs b/BPASmartClient.DRCoffee/CoffeeMachine.cs index 37b886dc..fe7df2c0 100644 --- a/BPASmartClient.DRCoffee/CoffeeMachine.cs +++ b/BPASmartClient.DRCoffee/CoffeeMachine.cs @@ -243,5 +243,9 @@ namespace BPASmartClient.DRCoffee public override void WriteData(string address, object value) { } + + //public override void ReadData(string address) + //{ + //} } } diff --git a/BPASmartClient.Device/BaseDevice.cs b/BPASmartClient.Device/BaseDevice.cs index c511c86f..df5ad193 100644 --- a/BPASmartClient.Device/BaseDevice.cs +++ b/BPASmartClient.Device/BaseDevice.cs @@ -13,6 +13,8 @@ using System.Text; using System.Threading; using System.Threading.Tasks; using System.Collections.ObjectModel; +using BPASmartClient.Model.单片机; +using BPASmartClient.EventBus; namespace BPASmartClient.Device { @@ -110,6 +112,11 @@ namespace BPASmartClient.Device #endregion + /// + /// 写控制 + /// + /// + /// public void WriteControl(string address, object value) { if (peripherals != null) @@ -536,5 +543,6 @@ namespace BPASmartClient.Device IEnumerable property = from pi in t.GetProperties() where pi.Name.ToLower() == field.ToLower() select pi; return property.First().GetValue(info, null); } + } } diff --git a/BPASmartClient.Helper/ExpandMethod.cs b/BPASmartClient.Helper/ExpandMethod.cs index 97336f6e..4265b59c 100644 --- a/BPASmartClient.Helper/ExpandMethod.cs +++ b/BPASmartClient.Helper/ExpandMethod.cs @@ -79,37 +79,20 @@ namespace BPASmartClient.Helper } - - ///// - ///// 保存数据 - ///// - //public static void Save(this T ot) - //{ - // string outjson = JsonConvert.SerializeObject(ot); - // var str = ot.GetType().GenericTypeArguments; - // if (str != null && str.Length > 0) - // { - // File.WriteAllText(LocaPath.GetInstance.Getpath(str[0].Name), outjson); - // } - - //} - - ///// - ///// 获取保存的数据 - ///// - //public static void Read(this object ot) - //{ - // var str = ot.GetType().GenericTypeArguments; - // if (str != null && str.Length > 0) - // { - // string pa = LocaPath.GetInstance.Getpath(str[0].Name); - // if (File.Exists(pa)) - // { - // string JsonString = File.ReadAllText(pa); - // var result = JsonConvert.DeserializeObject(JsonString); - // if (result != null) { Json.Data = result; } - // } - // } - //} + /// + /// 字节数组转换成32位整数 + /// + /// + /// + public static int BytesToInt(this byte[] bytes) + { + if (bytes.Length > 4) return -1; + int ReturnVlaue = 0; + for (int i = 0; i < bytes.Length; i++) + { + ReturnVlaue += (int)(bytes[i] << (i * 8)); + } + return ReturnVlaue; + } } } diff --git a/BPASmartClient.JAKA/BPASmartClient.JAKA.csproj b/BPASmartClient.JAKA/BPASmartClient.JAKA.csproj new file mode 100644 index 00000000..7a26a48f --- /dev/null +++ b/BPASmartClient.JAKA/BPASmartClient.JAKA.csproj @@ -0,0 +1,14 @@ + + + + net6.0 + enable + enable + + + + + + + + diff --git a/BPASmartClient.JAKA/JakaMachine.cs b/BPASmartClient.JAKA/JakaMachine.cs new file mode 100644 index 00000000..2df5fbc5 --- /dev/null +++ b/BPASmartClient.JAKA/JakaMachine.cs @@ -0,0 +1,83 @@ +using BPASmartClient.EventBus; +using BPASmartClient.Helper; +using BPASmartClient.JakaRobot; +using BPASmartClient.Model; +using BPASmartClient.Peripheral; +using static BPASmartClient.EventBus.EventBus; + +namespace BPASmartClient.JAKA +{ + public class JakaMachine : BasePeripheral + { + JaKaHelper jaKaHelper = new JaKaHelper(); + public override void Init() + { + jaKaHelper.Connect(communicationPar.IPAddress); + + ThreadManage.GetInstance().StartLong(new Action(() => + { + IsConnected = jaKaHelper.IsConnected; + if (!IsConnected) IsWork = false; + while (IsConnected) + { + IsWork = true; + if (status != null) + { + SetStatus("GetProgramStatus", (int)jaKaHelper.GetProgramStatus()); + SetStatus("Get_RobotAO1", jaKaHelper.Get_RobotAO1()); + + } + Thread.Sleep(500); + } + Thread.Sleep(1000); + }), $"设备[{DeviceId}]节卡机器人读取线程", true); + + + + EventBus.EventBus.GetInstance().Subscribe(DeviceId, delegate (IEvent @event, EventCallBackHandle callBack) + { + if (@event == null) return; + var par = @event as WriteJaka; + switch (par?.TagName) + { + case "Power_On": + jaKaHelper.Power_On(); + break; + case "Enable_robot": + jaKaHelper.Enable_robot(); + break; + case "Set_RobotAO1": + if (par?.Value is int intvalue) jaKaHelper.Set_RobotAO1(intvalue); + break; + case "JaKaProgramName": + if (par?.Value is string stringvalue) jaKaHelper.JaKaProgramName(stringvalue); + break; + default: + break; + } + }); + } + + //public override void ReadData(string address) + //{ + + //} + + public override void Start() + { + } + + public override void Stop() + { + } + + public override void WriteData(string address, object value) + { + + } + + protected override void InitStatus() + { + } + } +} \ No newline at end of file diff --git a/BPASmartClient.JakaRobot/BPASmartClient.JakaRobot.csproj b/BPASmartClient.JakaRobot/BPASmartClient.JakaRobot.csproj new file mode 100644 index 00000000..ef6914fa --- /dev/null +++ b/BPASmartClient.JakaRobot/BPASmartClient.JakaRobot.csproj @@ -0,0 +1,13 @@ + + + + net6.0 + enable + enable + + + + + + + diff --git a/BPASmartClient.JakaRobot/JaKaHelper.cs b/BPASmartClient.JakaRobot/JaKaHelper.cs new file mode 100644 index 00000000..b6f259c4 --- /dev/null +++ b/BPASmartClient.JakaRobot/JaKaHelper.cs @@ -0,0 +1,371 @@ +using BPASmartClient.Message; +using System.Text; + +namespace BPASmartClient.JakaRobot +{ + public class JaKaHelper + { + + #region 果汁机设备 + /*public const string SENCE_取咖啡杯 = "10000"; + public const string SENCE_取果汁杯 = "10001"; + public const string SENCE_取茶水杯 = "10002"; + public const string SENCE_取水杯 = "10003"; + public const string SENCE_取咖啡杯检测 = "11000"; + public const string SENCE_取果汁杯检测 = "11001"; + public const string SENCE_取茶水杯检测 = "11002"; + public const string SENCE_取水杯检测 = "11003"; + + public const string SENCE_接咖啡 = "12000"; + public const string SENCE_接果汁1 = "12001"; + public const string SENCE_接果汁2 = "12002"; + public const string SENCE_接果汁3 = "12003"; + public const string SENCE_接果汁4 = "12004"; + public const string SENCE_接茶 = "12005"; + public const string SENCE_接水 = "12006"; + + public const string SENCE_放咖啡杯 = "13000"; + public const string SENCE_放果汁杯1 = "13001"; + public const string SENCE_放果汁杯2 = "13002"; + public const string SENCE_放果汁杯3 = "13003"; + public const string SENCE_放果汁杯4 = "13004"; + public const string SENCE_放茶水杯 = "13005"; + public const string SENCE_放水杯 = "13006";*/ + + //public const string SENCE_取杯 = "10000"; + //public const string SENCE_放杯位检测 = "10100"; + //public const string SENCE_取杯检测 = "11000"; + + //public const string SENCE_接咖啡 = "12000"; + //public const string SENCE_接果汁1 = "12001"; + //public const string SENCE_接果汁2 = "12002"; + //public const string SENCE_接果汁3 = "12003"; + //public const string SENCE_接果汁4 = "12004"; + //public const string SENCE_接茶 = "12005"; + //public const string SENCE_接水 = "12006"; + //public const string SENCE_接茶_接水 = "12007"; + + //public const string SENCE_放咖啡杯 = "13000";//接饮料位---放饮料过渡位 + //public const string SENCE_放果汁杯1 = "13001"; + //public const string SENCE_放果汁杯2 = "13002"; + //public const string SENCE_放果汁杯3 = "13003"; + //public const string SENCE_放果汁杯4 = "13004"; + //public const string SENCE_放茶水杯 = "13005"; + + //public const string SENCE_放杯 = "14000";//放杯过渡位到-放杯 + + //public const string SENCE_放杯检测 = "15000"; + + //public const string SENCE_初始位 = "20000"; + + #endregion + private int rshd = -1; + private bool login = false; + + /// + /// 机器人的状态 + /// + private JKTYPE.RobotStatus robot_Status; + private JKTYPE.ProgramState program_status; + //private volatile static JaKaHelper _Instance; + //public static JaKaHelper GetInstance => _Instance ?? (_Instance = new JaKaHelper()); + //private JaKaHelper() { } + public bool IsIdle { get; set; } = false; + public bool IsConnected { get { return login; } } + + public void Connect(string ip) + { + bool ErrorFlag = false; + while (rshd == -1 || login == false) + { + try + { + jakaAPI.create_handler(ip.ToCharArray(), ref rshd); + + login = true; + + } + catch (Exception ex) + { + if (!ErrorFlag) + { + MessageLog.GetInstance.ShowEx(ex.ToString()); + ErrorFlag = true; + login = false; + } + Thread.Sleep(3000); + } + } + if (login) + { + try + { + Power_On();//打开机器人电源 + Thread.Sleep(1000); + Enable_robot();//机器人上使能 + MessageLog.GetInstance.Show("机器人已上电使能"); + } + catch (Exception ex) + { + MessageLog.GetInstance.ShowEx("机器人未完成上电和使能"); + } + } + } + public void Power_On() + { + if (login) + { + try + { + jakaAPI.power_on(ref rshd); + } + catch (System.AccessViolationException ave) + { + MessageLog.GetInstance.ShowEx(ave.ToString()); + } + //catch (Exception ex) + //{ + // MessageLog.GetInstance.ShowEx(ex.ToString()); + //} + } + else + { + MessageLog.GetInstance.Show("jaka机器人未连接成功!"); + } + } + + public void Power_Off() + { + if (login) + { + try + { + jakaAPI.power_off(ref rshd); + } + catch (Exception ex) + { + + } + } + else + { + MessageLog.GetInstance.Show("jaka机器人未连接成功!"); + } + } + + public void Enable_robot() + { + if (!(rshd == -1)) + { + try + { + jakaAPI.enable_robot(ref rshd); + } + catch (Exception ex) + { + + } + } + else + { + MessageLog.GetInstance.Show("jaka机器人未连接成功!"); + } + } + + public void disEnable_robot() + { + if (!(rshd == -1)) + { + try + { + jakaAPI.disable_robot(ref rshd); + } + catch (Exception ex) + { + + } + } + else + { + MessageLog.GetInstance.Show("jaka机器人未连接成功!"); + } + } + + /// + /// 设置机器人的DO值 + /// + /// + /// + /// + public bool Set_RobotDO(int DOIndex, bool value) + { + try + { + jakaAPI.set_digital_output(ref rshd, JKTYPE.IOType.IO_CABINET, DOIndex, value); + return value; + + } + catch (Exception ex) + { + return false; + } + } + /// + /// 设置机器人的AO值 + /// + /// 设置值 + /// + public int Set_RobotAO1(int Value) + { + try + { + return jakaAPI.set_analog_output(ref rshd, JKTYPE.IOType.IO_CABINET, 0, Value); + + } + catch (Exception ex) + { + return 0; + } + } + /// + /// 设置机器人的AO值 + /// + /// 索引值 + /// 设置值 + /// + public int Set_RobotAO(int Index, int Value) + { + try + { + return jakaAPI.set_analog_output(ref rshd, JKTYPE.IOType.IO_CABINET, Index, Value); + } + catch (Exception ex) + { + return 0; + } + } + + /// + /// 获取机器人的AO值 + /// + /// 索引值 + /// 设置值 + /// + public float Get_RobotAO(int Index, int value) + { + try + { + float bResult = 0; + jakaAPI.get_analog_output(ref rshd, JKTYPE.IOType.IO_CABINET, Index, ref bResult); + return bResult; + } + catch (Exception ex) + { + return 0; + } + } + /// + /// 获取机器人的AO值 + /// + /// 索引值 + /// 设置值 + /// + public float Get_RobotAO1() + { + try + { + float bResult = 0; + jakaAPI.get_analog_output(ref rshd, JKTYPE.IOType.IO_CABINET, 0, ref bResult); + return bResult; + } + catch (Exception ex) + { + return 0; + } + } + + /// + /// 获取机器人的DI输入 + /// + /// + /// + public bool Get_RobotDI(int index) + { + bool bResult = false; + jakaAPI.get_digital_input(ref rshd, JKTYPE.IOType.IO_CABINET, index, ref bResult); + return bResult; + } + + /// + /// 获取机器人的状态 + /// + public void GetRobotStatus() + { + jakaAPI.get_robot_status(ref rshd, ref robot_Status); + } + + public JKTYPE.ProgramState GetProgramStatus() + { + jakaAPI.get_program_state(ref rshd, ref program_status); + return program_status; + + } + + StringBuilder jakafile; + JKTYPE.ProgramState status; + char[] file; + public void JaKaProgramName(String Programname) + { + try + { + //加载 + file = Programname.ToCharArray(); + MessageLog.GetInstance.Show($"调用文件名:{Programname}"); + status = new JKTYPE.ProgramState(); + jakaAPI.get_program_state(ref rshd, ref status); + if (status != JKTYPE.ProgramState.PROGRAM_IDLE) + { + MessageLog.GetInstance.Show($"程序运行中,无法加载程序!!!"); + } + else + { + if (jakaAPI.program_load(ref rshd, file) == 0) + { + MessageLog.GetInstance.Show($"加载程序完成"); + } + else + { + MessageLog.GetInstance.Show($"加载程序失败!!!"); + } + } + if (status == JKTYPE.ProgramState.PROGRAM_RUNNING) + { + MessageLog.GetInstance.Show($"程序处于已处于启动状态!!!"); + } + else if (status == JKTYPE.ProgramState.PROGRAM_IDLE) + { + jakafile = new StringBuilder(); + jakaAPI.get_loaded_program(ref rshd, jakafile); + if (jakafile.Length == 0) + { + MessageLog.GetInstance.Show($"未加载程序,无法运行!!!"); + } + else + { + MessageLog.GetInstance.Show($"当前加载程序为:" + jakafile); + jakaAPI.program_run(ref rshd); + MessageLog.GetInstance.Show($"程序启动"); + } + } + else + { + MessageLog.GetInstance.Show($"程序处于暂停状态,无法重新启动程序!!!"); + } + } + catch (Exception ex) + { + MessageLog.GetInstance.ShowEx(ex.ToString()); + } + } + } +} \ No newline at end of file diff --git a/BPASmartClient.JakaRobot/jakaAPI.cs b/BPASmartClient.JakaRobot/jakaAPI.cs new file mode 100644 index 00000000..6ac8ee50 --- /dev/null +++ b/BPASmartClient.JakaRobot/jakaAPI.cs @@ -0,0 +1,1063 @@ +using System; +using System.Collections.Generic; +using System.Runtime.InteropServices; +using System.Text; + +namespace BPASmartClient.JakaRobot +{ + delegate void CallBackFuncType(int error_code); + class jakaAPI + { + /// + /// 获取版本控制器的Ip + /// + /// + /// + /// + [DllImport("jakaAPI.dll", EntryPoint = "get_controller_ip", ExactSpelling = false, CallingConvention = CallingConvention.Cdecl)] + public static extern int get_controller_ip(char[] controller_name, ref byte ip); + + /// + /// 创建机器人控制句柄 + /// + /// + /// + /// + [DllImport("jakaAPI.dll", EntryPoint = "create_handler", ExactSpelling = false, CallingConvention = CallingConvention.Cdecl)] + public static extern int create_handler(char[] ip, ref int handle); + + /// + /// 断开机器人控制句柄 + /// + /// + /// + [DllImport("jakaAPI.dll", EntryPoint = "destory_handler", ExactSpelling = false, CallingConvention = CallingConvention.Cdecl)] + public static extern int destory_handler(ref int handle); + + /// + /// 打开机器人电源 + /// + /// 机器人控制句柄 + /// ERR_SUCC 成功 其他失败 + [DllImport("jakaAPI.dll", EntryPoint = "power_on", ExactSpelling = false, CallingConvention = CallingConvention.Cdecl)] + public static extern int power_on(ref int handle); + + /// + /// 关闭机器人电源 + /// + /// 机器人控制句柄 + /// ERR_SUCC 成功 其他失败 + [DllImport("jakaAPI.dll", EntryPoint = "power_off", ExactSpelling = false, CallingConvention = CallingConvention.Cdecl)] + public static extern int power_off(ref int handle); + + /// + /// 机器人控制柜关机 + /// + /// + /// ERR_SUCC 成功 其他失败 + [DllImport("jakaAPI.dll", EntryPoint = "shut_down", ExactSpelling = false, CallingConvention = CallingConvention.Cdecl)] + public static extern int shut_down(ref int handle); + + /// + /// 控制机器人上使能 + /// + /// + /// + [DllImport("jakaAPI.dll", EntryPoint = "enable_robot", ExactSpelling = false, CallingConvention = CallingConvention.Cdecl)] + public static extern int enable_robot(ref int handle); + + /// + /// 控制机器人下使能 + /// + /// + /// + [DllImport("jakaAPI.dll", EntryPoint = "disable_robot", ExactSpelling = false, CallingConvention = CallingConvention.Cdecl)] + public static extern int disable_robot(ref int handle); + + /// + /// 控制机器人手动模式下运动 + /// + /// + /// 标识值,在关节空间下代表关节号0-5,笛卡尔下依次为x,y,z,rx,ry,rz + /// 机器人运动模式,增量运动或者连续运动 + /// 机器人运动坐标系,工具坐标系,基坐标系(当前的世界/用户坐标系)或关节空间 + /// 指令速度,旋转轴或关节运动单位为rad/s,移动轴单位为mm/s + /// 指令位置,旋转轴或关节运动单位为rad,移动轴单位为mm + /// + [DllImport("jakaAPI.dll", EntryPoint = "jog", ExactSpelling = false, CallingConvention = CallingConvention.Cdecl)] + public static extern int jog(ref int handle, int aj_num, JKTYPE.MoveMode move_mode, JKTYPE.CoordType coord_type, double vel_cmd, double pos_cmd); + + /// + /// 控制机器人手动模式下运动停止 + /// + /// + /// + /// + [DllImport("jakaAPI.dll", EntryPoint = "jog_stop", ExactSpelling = false, CallingConvention = CallingConvention.Cdecl)] + public static extern int jog_stop(ref int handle, ref int num); + + /// + /// 机器人关节运动 + /// + /// + /// 机器人关节运动目标位置 + /// 指定运动模式:增量运动(相对运动)或绝对运动 + /// 设置接口是否为阻塞接口,TRUE为阻塞接口 FALSE为非阻塞接口 + /// 机器人关节运动速度,单位:rad/s + /// + [DllImport("jakaAPI.dll", EntryPoint = "joint_move", ExactSpelling = false, CallingConvention = CallingConvention.StdCall, CharSet = CharSet.Unicode)] + public static extern int joint_move(ref int handle, ref JKTYPE.JointValue joint_pos, JKTYPE.MoveMode move_mode, bool is_block, double speed); + + /// + /// 机器人末端直线运动 + /// + /// + /// 机器人末端运动目标位置 + /// 指定运动模式:增量运动(相对运动)或绝对运动 + /// 设置接口是否为阻塞接口,TRUE 为阻塞接口 FALSE 为非阻塞接口 + /// 机器人直线运动速度,单位:mm/s + /// + [DllImport("jakaAPI.dll", EntryPoint = "linear_move", ExactSpelling = false, CallingConvention = CallingConvention.Cdecl)] + public static extern int linear_move(ref int handle, ref JKTYPE.CartesianPose end_pos, JKTYPE.MoveMode move_mode, bool is_block, double speed); + + /// + /// 机器人SERVO MOVE模式使能 + /// + /// + /// TRUE为进入SERVO MOVE模式,FALSE表示退出该模式 + /// + [DllImport("jakaAPI.dll", EntryPoint = "servo_move_enable", ExactSpelling = false, CallingConvention = CallingConvention.Cdecl)] + public static extern int servo_move_enable(ref int handle, bool enable); + + /// + /// 机器人关节空间位置控制模式 + /// + /// + /// 机器人关节运动目标位置 + /// 指定运动模式:增量运动或绝对运动 + /// + [DllImport("jakaAPI.dll", EntryPoint = "servo_j", ExactSpelling = false, CallingConvention = CallingConvention.Cdecl)] + public static extern int servo_j(ref int handle, ref JKTYPE.JointValue joint_pos, JKTYPE.MoveMode move_mode); + + /// + /// 机器人关节空间位置控制模式 + /// + /// + /// 机器人关节运动目标位置 + /// 指定运动模式:增量运动或绝对运动 + /// 倍分周期,servo_j运动周期为step_num*8ms,其中step_num>=1 + /// + [DllImport("jakaAPI.dll", EntryPoint = "servo_j_extend", ExactSpelling = false, CallingConvention = CallingConvention.Cdecl)] + public static extern int servo_j_extend(ref int handle, ref JKTYPE.JointValue joint_pos, JKTYPE.MoveMode move_mode, int step_num); + + /// + /// 机器人笛卡尔空间位置控制模式 + /// + /// + /// 机器人笛卡尔空间运动目标位置 + /// 指定运动模式:增量运动或绝对运动 + /// + [DllImport("jakaAPI.dll", EntryPoint = "servo_p", ExactSpelling = false, CallingConvention = CallingConvention.Cdecl)] + public static extern int servo_p(ref int handle, ref JKTYPE.CartesianPose cartesian_pose, JKTYPE.MoveMode move_mode); + + /// + /// 机器人笛卡尔空间位置控制模式 + /// + /// + /// 机器人笛卡尔空间运动目标位置 + /// 指定运动模式:增量运动或绝对运动 + /// 倍分周期,servo_p运动周期为step_num*8ms,其中step_num>=1 + /// + [DllImport("jakaAPI.dll", EntryPoint = "servo_p_extend", ExactSpelling = false, CallingConvention = CallingConvention.Cdecl)] + public static extern int servo_p_extend(ref int handle, ref JKTYPE.CartesianPose cartesian_pose, JKTYPE.MoveMode move_mode, int step_num); + + /// + /// 设置数字输出变量(DO)的值 + /// + /// + /// type DO类型 + /// index DO索引 + /// value DO设置值 + /// + [DllImport("jakaAPI.dll", EntryPoint = "set_digital_output", ExactSpelling = false, CallingConvention = CallingConvention.Cdecl)] + public static extern int set_digital_output(ref int handle, JKTYPE.IOType type, int index, bool value); + + /// + /// 设置模拟输出变量的值(AO)的值 + /// + /// + /// AO类型 + /// AO索引 + /// AO设置值 + /// + [DllImport("jakaAPI.dll", EntryPoint = "set_analog_output", ExactSpelling = false, CallingConvention = CallingConvention.Cdecl)] + public static extern int set_analog_output(ref int handle, JKTYPE.IOType type, int index, float value); + + /// + /// 查询数字输入(DI)状态 + /// + /// + /// DI类型 + /// DI索引 + /// DI状态查询结果 + /// + [DllImport("jakaAPI.dll", EntryPoint = "get_digital_input", ExactSpelling = false, CallingConvention = CallingConvention.Cdecl)] + public static extern int get_digital_input(ref int handle, JKTYPE.IOType type, int index, ref bool result); + + /// + /// 查询数字输出(DO)状态 + /// + /// + /// DO类型 + /// DO索引 + /// DO状态查询结果 + /// + [DllImport("jakaAPI.dll", EntryPoint = "get_digital_output", ExactSpelling = false, CallingConvention = CallingConvention.Cdecl)] + public static extern int get_digital_output(ref int handle, JKTYPE.IOType type, int index, ref bool result); + + /// + /// 获取模拟量输入变量(AI)的值 + /// + /// + /// AI的类型 + /// AI索引 + /// 指定AI状态查询结果 + /// + [DllImport("jakaAPI.dll", EntryPoint = "get_analog_input", ExactSpelling = false, CallingConvention = CallingConvention.Cdecl)] + public static extern int get_analog_input(ref int handle, JKTYPE.IOType type, int index, ref float result); + + /// + /// 获取模拟量输出变量(AO)的值 + /// + /// + /// AO的类型 + /// AO索引 + /// 指定AO状态查询结果 + /// + [DllImport("jakaAPI.dll", EntryPoint = "get_analog_output", ExactSpelling = false, CallingConvention = CallingConvention.Cdecl)] + public static extern int get_analog_output(ref int handle, JKTYPE.IOType type, int index, ref float result); + + /// + /// 查询扩展IO模块是否运行 + /// + /// + /// + /// + [DllImport("jakaAPI.dll", EntryPoint = "is_extio_running", ExactSpelling = false, CallingConvention = CallingConvention.Cdecl)] + public static extern int is_extio_running(ref int handle, ref bool is_running); + + /// + /// 运行当前加载的作业程序 + /// + /// + /// + [DllImport("jakaAPI.dll", EntryPoint = "program_run", ExactSpelling = false, CallingConvention = CallingConvention.Cdecl)] + public static extern int program_run(ref int handle); + + /// + /// 暂停当前运行的作业程序 + /// + /// + /// + [DllImport("jakaAPI.dll", EntryPoint = "program_pause", ExactSpelling = false, CallingConvention = CallingConvention.Cdecl)] + public static extern int program_pause(ref int handle); + + /// + /// 继续运行当前暂停的作业程序 + /// + /// + /// + [DllImport("jakaAPI.dll", EntryPoint = "program_resume", ExactSpelling = false, CallingConvention = CallingConvention.Cdecl)] + public static extern int program_resume(ref int handle); + + /// + /// 终止当前执行的作业程序 + /// + /// + /// + [DllImport("jakaAPI.dll", EntryPoint = "program_abort", ExactSpelling = false, CallingConvention = CallingConvention.Cdecl)] + public static extern int program_abort(ref int handle); + + /// + /// 加载指定的作业程序 + /// + /// + /// 程序文件路径 + /// + [DllImport("jakaAPI.dll", EntryPoint = "program_load", ExactSpelling = false, CallingConvention = CallingConvention.Cdecl)] + public static extern int program_load(ref int handle, char[] file); + + /// + /// 获取已加载的作业程序名字 + /// + /// + /// + /// + [DllImport("jakaAPI.dll", EntryPoint = "get_loaded_program", ExactSpelling = false, CallingConvention = CallingConvention.Cdecl)] + public static extern int get_loaded_program(ref int handle, StringBuilder file); + + /// + /// 获取当前机器人作业程序的执行行号 + /// + /// + /// 当前行号查询结果 + /// + [DllImport("jakaAPI.dll", EntryPoint = "get_current_line", ExactSpelling = false, CallingConvention = CallingConvention.Cdecl)] + public static extern int get_current_line(ref int handle, ref int curr_line); + + /// + /// 获取机器人作业程序执行状态 + /// + /// + /// 作业程序执行状态查询结果 + /// + [DllImport("jakaAPI.dll", EntryPoint = "get_program_state", ExactSpelling = false, CallingConvention = CallingConvention.Cdecl)] + public static extern int get_program_state(ref int handle, ref JKTYPE.ProgramState status); + + /// + /// 设置机器人运行倍率 + /// + /// + /// 是程序运行倍率,设置范围为[0,1] + /// + [DllImport("jakaAPI.dll", EntryPoint = "set_rapidrate", ExactSpelling = false, CallingConvention = CallingConvention.Cdecl)] + public static extern int set_rapidrate(ref int handle, double rapid_rate); + + /// + /// 获取机器人运行倍率 + /// + /// + /// 当前控制系统倍率 + /// + [DllImport("jakaAPI.dll", EntryPoint = "get_rapidrate", ExactSpelling = false, CallingConvention = CallingConvention.Cdecl)] + public static extern int get_rapidrate(ref int handle, ref double rapid_rate); + + /// + /// 设置指定编号的工具信息 + /// + /// + /// 工具编号 + /// 工具坐标系相对法兰坐标系偏置 + /// 指定工具的别名 + /// + [DllImport("jakaAPI.dll", EntryPoint = "set_tool_data", ExactSpelling = false, CallingConvention = CallingConvention.Cdecl)] + public static extern int set_tool_data(ref int handle, int id, ref JKTYPE.CartesianPose tcp, char[] name); + + /// + /// 查询使用的工具信息 + /// + /// + /// 工具ID查询结果 + /// 工具坐标系相对法兰坐标系偏置 + /// + [DllImport("jakaAPI.dll", EntryPoint = "get_tool_data", ExactSpelling = false, CallingConvention = CallingConvention.Cdecl)] + public static extern int get_tool_data(ref int handle, ref int id, ref JKTYPE.CartesianPose tcp); + + /// + /// 设置当前使用的工具ID + /// + /// + /// 工具坐标系ID + /// + [DllImport("jakaAPI.dll", EntryPoint = "set_tool_id", ExactSpelling = false, CallingConvention = CallingConvention.Cdecl)] + public static extern int set_tool_id(ref int handle, int id); + + /// + /// 查询当前使用的工具ID + /// + /// + /// 工具ID查询结果 + /// + [DllImport("jakaAPI.dll", EntryPoint = "get_tool_id", ExactSpelling = false, CallingConvention = CallingConvention.Cdecl)] + public static extern int get_tool_id(ref int handle, ref int id); + + /// + /// 设置指定编号的用户坐标系信息 + /// + /// + /// 用户坐标系编号 + /// 用户坐标系偏置值 + /// 用户坐标系别名 + /// + [DllImport("jakaAPI.dll", EntryPoint = "set_user_frame_data", ExactSpelling = false, CallingConvention = CallingConvention.Cdecl)] + public static extern int set_user_frame_data(ref int handle, int id, ref JKTYPE.CartesianPose user_frame, char[] name); + + /// + /// + /// + /// + /// + /// + /// + [DllImport("jakaAPI.dll", EntryPoint = "get_user_frame_data", ExactSpelling = false, CallingConvention = CallingConvention.Cdecl)] + public static extern int get_user_frame_data(ref int handle, ref int id, ref JKTYPE.CartesianPose user_frame); + + /// + /// + /// + /// + /// + /// + [DllImport("jakaAPI.dll", EntryPoint = "set_user_frame_id", ExactSpelling = false, CallingConvention = CallingConvention.Cdecl)] + public static extern int set_user_frame_id(ref int handle, int id); + + /// + /// 查询当前使用的用户坐标系ID + /// + /// + /// 获取的结果 + /// + [DllImport("jakaAPI.dll", EntryPoint = "get_user_frame_id", ExactSpelling = false, CallingConvention = CallingConvention.Cdecl)] + public static extern int get_user_frame_id(ref int handle, ref int id); + + /// + /// 控制机器人进入或退出拖拽模式 + /// + /// + /// TRUE为进入拖拽模式,FALSE为退出拖拽模式 + /// + [DllImport("jakaAPI.dll", EntryPoint = "drag_mode_enable", ExactSpelling = false, CallingConvention = CallingConvention.Cdecl)] + public static extern int drag_mode_enable(ref int handle, bool enable); + + /// + /// 查询机器人是否处于拖拽模式 + /// + /// + /// + /// + [DllImport("jakaAPI.dll", EntryPoint = "is_in_drag_mode", ExactSpelling = false, CallingConvention = CallingConvention.Cdecl)] + public static extern int is_in_drag_mode(ref int handle, ref bool in_drag); + + /// + /// 获取机器人状态 + /// + /// + /// 机器人状态查询结果 + /// + [DllImport("jakaAPI.dll", EntryPoint = "get_robot_state", ExactSpelling = false, CallingConvention = CallingConvention.Cdecl)] + public static extern int get_robot_state(ref int handle, ref JKTYPE.RobotState state); + + /// + /// 获取当前设置下工具末端的位姿 + /// + /// + /// 工具末端位置查询结果 + /// + [DllImport("jakaAPI.dll", EntryPoint = "get_tcp_position", ExactSpelling = false, CallingConvention = CallingConvention.Cdecl)] + public static extern int get_tcp_position(ref int handle, ref JKTYPE.CartesianPose tcp_position); + + /// + /// 获取当前机器人关节角度 + /// + /// + /// 关节角度查询结果 + /// + [DllImport("jakaAPI.dll", EntryPoint = "get_joint_position", ExactSpelling = false, CallingConvention = CallingConvention.Cdecl)] + public static extern int get_joint_position(ref int handle, ref JKTYPE.JointValue joint_position); + + /// + /// 查询机器人是否处于碰撞保护模式 + /// + /// + /// 查询结果 + /// + [DllImport("jakaAPI.dll", EntryPoint = "is_in_collision", ExactSpelling = false, CallingConvention = CallingConvention.Cdecl)] + public static extern int is_in_collision(ref int handle, ref bool in_collision); + + /// + /// 查询机器人是否超出限位 + /// + /// + /// 查询结果 + /// + [DllImport("jakaAPI.dll", EntryPoint = "is_on_limit", ExactSpelling = false, CallingConvention = CallingConvention.Cdecl)] + public static extern int is_on_limit(ref int handle, ref bool on_limit); + + /// + /// 查询机器人运动是否停止 + /// + /// + /// + /// + [DllImport("jakaAPI.dll", EntryPoint = "is_in_pos", ExactSpelling = false, CallingConvention = CallingConvention.Cdecl)] + public static extern int is_in_pos(ref int handle, ref bool in_pos); + + /// + /// + /// + /// + /// + [DllImport("jakaAPI.dll", EntryPoint = "collision_recover", ExactSpelling = false, CallingConvention = CallingConvention.Cdecl)] + public static extern int collision_recover(ref int handle); + + /// + /// 设置机器人碰撞等级 + /// + /// + /// 碰撞等级,等级0-5 ,0为关闭碰撞,1为碰撞阈值25N,2为碰撞阈值50N,3为碰撞阈值75N,4为碰撞阈值100N,5为碰撞阈值125N + /// + [DllImport("jakaAPI.dll", EntryPoint = "set_collision_level", ExactSpelling = false, CallingConvention = CallingConvention.Cdecl)] + public static extern int set_collision_level(ref int handle, int level); + + /// + /// 获取机器人设置的碰撞等级 + /// + /// + /// 碰撞等级,等级0-5 ,0为关闭碰撞,1为碰撞阈值25N,2为碰撞阈值50N,3为碰撞阈值75N,4为碰撞阈值100N,5为碰撞阈值125N + /// + [DllImport("jakaAPI.dll", EntryPoint = "get_collision_level", ExactSpelling = false, CallingConvention = CallingConvention.Cdecl)] + public static extern int get_collision_level(ref int handle, ref int level); + + /// + /// 计算指定位姿在当前工具、当前安装角度以及当前用户坐标系设置下的逆解 + /// + /// + /// + /// + /// + /// + [DllImport("jakaAPI.dll", EntryPoint = "kine_inverse", ExactSpelling = false, CallingConvention = CallingConvention.Cdecl)] + public static extern int kine_inverse(ref int handle, ref JKTYPE.JointValue ref_pos, ref JKTYPE.CartesianPose cartesian_pose, ref JKTYPE.JointValue joint_pos); + + /// + /// 计算指定关节位置在当前工具、当前安装角度以及当前用户坐标系设置下的位姿值 + /// + /// + /// 关节空间位置 + /// 笛卡尔空间位姿计算结果 + /// + [DllImport("jakaAPI.dll", EntryPoint = "kine_forward", ExactSpelling = false, CallingConvention = CallingConvention.Cdecl)] + public static extern int kine_forward(ref int handle, ref JKTYPE.JointValue joint_pos, ref JKTYPE.CartesianPose cartesian_pose); + + /// + /// 欧拉角到旋转矩阵的转换 + /// + /// + /// 待转换的欧拉角数据 + /// 转换后的旋转矩阵 + /// + [DllImport("jakaAPI.dll", EntryPoint = "rpy_to_rot_matrix", ExactSpelling = false, CallingConvention = CallingConvention.Cdecl)] + public static extern int rpy_to_rot_matrix(ref int handle, ref JKTYPE.Rpy rpy, ref JKTYPE.RotMatrix rot_matrix); + + /// + /// 旋转矩阵到欧拉角的转换 + /// + /// + /// 待转换的旋转矩阵数据 + /// 转换后的RPY欧拉角结果 + /// + [DllImport("jakaAPI.dll", EntryPoint = "rot_matrix_to_rpy", ExactSpelling = false, CallingConvention = CallingConvention.Cdecl)] + public static extern int rot_matrix_to_rpy(ref int handle, ref JKTYPE.RotMatrix rot_matrix, ref JKTYPE.Rpy rpy); + + /// + /// 四元数到旋转矩阵的转换 + /// + /// + /// 待转换的四元数数据 + /// 转换后的旋转矩阵结果 + /// + [DllImport("jakaAPI.dll", EntryPoint = "quaternion_to_rot_matrix", ExactSpelling = false, CallingConvention = CallingConvention.Cdecl)] + public static extern int quaternion_to_rot_matrix(ref int handle, ref JKTYPE.Quaternion quaternion, ref JKTYPE.RotMatrix rot_matrix); + + /// + /// 旋转矩阵到四元数的转换 + /// + /// + /// 待转换的旋转矩阵 + /// 转换后的四元数结果 + /// + [DllImport("jakaAPI.dll", EntryPoint = "rot_matrix_to_quaternion", ExactSpelling = false, CallingConvention = CallingConvention.Cdecl)] + public static extern int rot_matrix_to_quaternion(ref int handle, ref JKTYPE.RotMatrix rot_matrix, ref JKTYPE.Quaternion quaternion); + + /// + /// + /// + /// + /// + /// + [DllImport("jakaAPI.dll", EntryPoint = "torque_control_enable", ExactSpelling = false, CallingConvention = CallingConvention.Cdecl)] + public static extern int torque_control_enable(ref int handle, bool enable); + + /// + /// + /// + /// + /// + /// + /// + [DllImport("jakaAPI.dll", EntryPoint = "torque_feedforward", ExactSpelling = false, CallingConvention = CallingConvention.Cdecl)] + public static extern int torque_feedforward(ref int handle, JKTYPE.TorqueValue tor_val, int grv_flag); + + /// + /// 机器人负载设置 + /// + /// + /// 负载质心、质量数据 + /// + [DllImport("jakaAPI.dll", EntryPoint = "set_payload", ExactSpelling = false, CallingConvention = CallingConvention.Cdecl)] + public static extern int set_payload(ref int handle, ref JKTYPE.PayLoad payload); + + /// + /// 获取机器人负载数据 + /// + /// + /// 负载查询结果 + /// + [DllImport("jakaAPI.dll", EntryPoint = "get_payload", ExactSpelling = false, CallingConvention = CallingConvention.Cdecl)] + public static extern int get_payload(ref int handle, ref JKTYPE.PayLoad payload); + + /// + /// 注册机器人出现错误时的回调函数 + /// + /// + /// 指向用户定义的函数的函数指针 + /// + [DllImport("jakaAPI.dll", EntryPoint = "set_error_handler", ExactSpelling = false, CallingConvention = CallingConvention.Cdecl)] + public static extern int set_error_handler(ref int i, CallBackFuncType func); + + /// + /// 获取SDK版本号 + /// + /// + /// SDK版本号 + /// + [DllImport("jakaAPI.dll", EntryPoint = "get_sdk_version", ExactSpelling = false, CallingConvention = CallingConvention.Cdecl)] + public static extern int get_sdk_version(ref int i, StringBuilder version); + + /// + /// 获取机器人状态数据 + /// + /// + /// 机器人状态 + /// + [DllImport("jakaAPI.dll", EntryPoint = "get_robot_status", ExactSpelling = false, CallingConvention = CallingConvention.Cdecl)] + public static extern int get_robot_status(ref int i, ref JKTYPE.RobotStatus status); + + /// + /// 终止当前机械臂运动 + /// + /// + /// + [DllImport("jakaAPI.dll", EntryPoint = "motion_abort", ExactSpelling = false, CallingConvention = CallingConvention.Cdecl)] + public static extern int motion_abort(ref int i); + + /// + /// 设置错误码文件路径,需要使用get_last_error接口时需要设置错误码文件路径,如果不使用get_last_error接口,则不需要设置该接口 + /// + /// + /// + /// + [DllImport("jakaAPI.dll", EntryPoint = "set_errorcode_file_path", ExactSpelling = false, CallingConvention = CallingConvention.Cdecl)] + public static extern int set_errorcode_file_path(ref int i, StringBuilder path); + + /// + /// 获取机器人运行过程中最后一个错误码,当调用clear_error时,最后一个错误码会清零 + /// + /// + /// + /// + [DllImport("jakaAPI.dll", EntryPoint = "get_last_error", ExactSpelling = false, CallingConvention = CallingConvention.Cdecl)] + public static extern int get_last_error(ref int i, ref JKTYPE.ErrorCode code); + + /// + /// + /// + /// + /// + /// + [DllImport("jakaAPI.dll", EntryPoint = "set_debug_mode", ExactSpelling = false, CallingConvention = CallingConvention.Cdecl)] + public static extern int set_debug_mode(ref int i, bool mode); + + /// + /// 设置是否开启调试模式,选择TRUE时,开始调试模式,此时会在标准输出流中输出调试信息,选择FALSE时,不输出调试信息 + /// + /// + /// + /// + [DllImport("jakaAPI.dll", EntryPoint = "set_traj_config", ExactSpelling = false, CallingConvention = CallingConvention.Cdecl)] + public static extern int set_traj_config(ref int i, ref JKTYPE.TrajTrackPara para); + + /// + /// 获取轨迹复现配置参数 + /// + /// + /// 轨迹复现配置参数 + /// + [DllImport("jakaAPI.dll", EntryPoint = "get_traj_config", ExactSpelling = false, CallingConvention = CallingConvention.Cdecl)] + public static extern int get_traj_config(ref int i, ref JKTYPE.TrajTrackPara para); + + /// + /// 采集轨迹复现数据控制开关 + /// + /// + /// 选择TRUE时,开始数据采集,选择FALSE时,结束数据采集 + /// 采集数据的存储文件名,当filename为空指针时,存储文件以当前日期命名 + /// + [DllImport("jakaAPI.dll", EntryPoint = "set_traj_sample_mode", ExactSpelling = false, CallingConvention = CallingConvention.Cdecl)] + public static extern int set_traj_sample_mode(ref int i, bool mode, char[] filename); + + /// + /// 采集轨迹复现数据状态查询 + /// + /// + /// 为TRUE时,数据正在采集,为FALSE时,数据采集结束,在数据采集状态时不允许再次开启数据采集开关 + /// + [DllImport("jakaAPI.dll", EntryPoint = "get_traj_sample_status", ExactSpelling = false, CallingConvention = CallingConvention.Cdecl)] + public static extern int get_traj_sample_status(ref int i, ref bool sample_statuse); + + /// + /// 查询控制器中已经存在的轨迹复现数据的文件名 + /// + /// + /// 控制器中已经存在的轨迹复现数据的文件名 + /// + [DllImport("jakaAPI.dll", EntryPoint = "get_exist_traj_file_name", ExactSpelling = false, CallingConvention = CallingConvention.Cdecl)] + public static extern int get_exist_traj_file_name(ref int i, ref JKTYPE.MultStrStorType filename); + + /// + /// 重命名轨迹复现数据的文件名 + /// + /// + /// 原文件名 + /// 目标文件名,文件名长度不能超过100个字符,文件名不能为空,目标文件名不支持中文 + /// + [DllImport("jakaAPI.dll", EntryPoint = "rename_traj_file_name", ExactSpelling = false, CallingConvention = CallingConvention.Cdecl)] + public static extern int rename_traj_file_name(ref int i, ref char[] src, ref char[] dest); + + /// + /// 删除控制器中轨迹复现数据文件 + /// + /// + /// 要删除的文件的文件名,文件名为数据文件名字 + /// + [DllImport("jakaAPI.dll", EntryPoint = "remove_traj_file", ExactSpelling = false, CallingConvention = CallingConvention.Cdecl)] + public static extern int remove_traj_file(ref int i, char[] filename); + + /// + /// + /// + /// + /// + /// + [DllImport("jakaAPI.dll", EntryPoint = "generate_traj_exe_file", ExactSpelling = false, CallingConvention = CallingConvention.Cdecl)] + public static extern int generate_traj_exe_file(ref int i, char[] filename); + + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + [DllImport("jakaAPI.dll", EntryPoint = "joint_move_extend", ExactSpelling = false, CallingConvention = CallingConvention.Cdecl)] + public static extern int joint_move_extend(ref int i, ref JKTYPE.JointValue joint_pos, JKTYPE.MoveMode move_mode, bool is_block, double speed, double acc, double tol, ref JKTYPE.OptionalCond option_cond); + + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + [DllImport("jakaAPI.dll", EntryPoint = "linear_move_extend", ExactSpelling = false, CallingConvention = CallingConvention.Cdecl)] + public static extern int linear_move_extend(ref int i, ref JKTYPE.CartesianPose cart_pos, JKTYPE.MoveMode move_mode, bool is_block, double speed, double acc, double tol, ref JKTYPE.OptionalCond option_cond); + + /// + /// 机器人末端圆弧运动 + /// + /// + /// 机器人末端运动目标位置 + /// 机器人末端运中间点 + /// 指定运动模式:增量运动(相对运动)或绝对运动 + /// 设置接口是否为阻塞接口,TRUE 为阻塞接口 FALSE 为非阻塞接口 + /// 机器人圆弧运动速度,单位:rad/s + /// 机器人圆弧运动加速度,单位:rad/s^2 + /// 机器人圆弧运动终点误差, 单位mm + /// 机器人关节可选参数,如果不需要,该值可不赋值,填入空指针就可 + /// + [DllImport("jakaAPI.dll", EntryPoint = "circular_move", ExactSpelling = false, CallingConvention = CallingConvention.Cdecl)] + public static extern int circular_move(ref int i, ref JKTYPE.CartesianPose end_pos, ref JKTYPE.CartesianPose mid_pos, JKTYPE.MoveMode move_mode, bool is_block, double speed, double acc, double tol, ref JKTYPE.OptionalCond option_cond); + + /// + /// SERVO模式下不使用滤波器,该指令在SERVO模式下不可设置,退出SERVO后可设置 + /// + /// + /// + [DllImport("jakaAPI.dll", EntryPoint = "servo_move_use_none_filter", ExactSpelling = false, CallingConvention = CallingConvention.Cdecl)] + public static extern int servo_move_use_none_filter(ref int i); + + /// + /// SERVO模式下关节空间一阶低通滤波,该指令在SERVO模式下不可设置,退出SERVO后可设置 + /// + /// + /// 一阶低通滤波器截止频率 + /// + [DllImport("jakaAPI.dll", EntryPoint = "servo_move_use_joint_LPF", ExactSpelling = false, CallingConvention = CallingConvention.Cdecl)] + public static extern int servo_move_use_joint_LPF(ref int i, double cutoffFreq); + + /// + /// SERVO模式下关节空间非线性滤波,该指令在SERVO模式下不可设置,退出SERVO后可设置 + /// + /// + /// 笛卡尔空间姿态变化速度的速度上限值(绝对值)°/s + /// 笛卡尔空间姿态变化速度的加速度上限值(绝对值)°/s^2 + /// 笛卡尔空间姿态变化速度的加加速度上限值(绝对值)°/s^3 + /// + [DllImport("jakaAPI.dll", EntryPoint = "servo_move_use_joint_NLF", ExactSpelling = false, CallingConvention = CallingConvention.Cdecl)] + public static extern int servo_move_use_joint_NLF(ref int i, double max_vr, double max_ar, double max_jr); + + /// + /// SERVO模式下笛卡尔空间非线性滤波,该指令在SERVO模式下不可设置,退出SERVO后可设置 + /// + /// + /// 笛卡尔空间下移动指令速度的上限值(绝对值)。单位:mm/s + /// 笛卡尔空间下移动指令加速度的上限值(绝对值)。单位:mm/s^2 + /// 笛卡尔空间下移动指令加加速度的上限值(绝对值)单位:mm/s^3 + /// 笛卡尔空间姿态变化速度的速度上限值(绝对值)°/s + /// 笛卡尔空间姿态变化速度的加速度上限值(绝对值)°/s^2 + /// 笛卡尔空间姿态变化速度的加加速度上限值(绝对值)°/s^3 + /// + [DllImport("jakaAPI.dll", EntryPoint = "servo_move_use_carte_NLF", ExactSpelling = false, CallingConvention = CallingConvention.Cdecl)] + public static extern int servo_move_use_carte_NLF(ref int i, double max_vp, double max_ap, double max_jp, double max_vr, double max_ar, double max_jr); + + /// + /// SERVO模式下关节空间多阶均值滤波器,该指令在SERVO模式下不可设置,退出SERVO后可设置 + /// + /// + /// 均值滤波器缓冲区的大小 + /// 加速度滤波系数 + /// 速度滤波系数 + /// 位置滤波系数 + /// + [DllImport("jakaAPI.dll", EntryPoint = "servo_move_use_joint_MMF", ExactSpelling = false, CallingConvention = CallingConvention.Cdecl)] + public static extern int servo_move_use_joint_MMF(ref int i, int max_buf, double kp, double kv, double ka); + + /// + /// SERVO模式下速度前瞻参数设置 + /// + /// + /// 缓冲区的大小 + /// 加速度滤波系数 + /// + [DllImport("jakaAPI.dll", EntryPoint = "servo_speed_foresight", ExactSpelling = false, CallingConvention = CallingConvention.Cdecl)] + public static extern int servo_speed_foresight(ref int i, int max_buf, double kp); + + /// + /// 设置SDK日志路径 + /// + /// + /// SDK日志路径 + /// + [DllImport("jakaAPI.dll", EntryPoint = "set_SDK_filepath", ExactSpelling = false, CallingConvention = CallingConvention.Cdecl)] + public static extern int set_SDK_filepath(ref int i, ref char[] filepath); + + /// + /// 设置传感器品牌 + /// + /// + /// 传感器品牌,可选值为1,2,3 分别代表不同品牌力矩传感器 + /// + [DllImport("jakaAPI.dll", EntryPoint = "set_torsenosr_brand", ExactSpelling = false, CallingConvention = CallingConvention.Cdecl)] + public static extern int set_torsenosr_brand(ref int i, int sensor_brand); + + /// + /// 获取传感器品牌 + /// + /// + /// 传感器品牌,可选值为1,2,3 分别代表不同品牌力矩传感器 + /// + [DllImport("jakaAPI.dll", EntryPoint = "get_torsenosr_brand", ExactSpelling = false, CallingConvention = CallingConvention.Cdecl)] + public static extern int get_torsenosr_brand(ref int i, ref int sensor_brand); + + /// + /// 开启或关闭力矩传感器 + /// + /// + /// 0代表关闭传感器,1代表开启力矩传感器 + /// + [DllImport("jakaAPI.dll", EntryPoint = "set_torque_sensor_mode", ExactSpelling = false, CallingConvention = CallingConvention.Cdecl)] + public static extern int set_torque_sensor_mode(ref int i, int sensor_mode); + + /// + /// 设置柔顺控制参数 + /// + /// + /// 代表配置哪一轴,可选值为0~5 + /// 柔顺方向,可选值为 1 2 3 4 5 6分别对应 fx fy fz mx my mz 0代表没有勾选 + /// 阻尼力,表示用户用多大的力才能让机器人的沿着某个方向以最大速度进行运动 + /// 回弹力,表示机器人回到初始状态的能力 + /// 代表恒力,手动操作时全部设置为0 + /// 法向跟踪,手动操作时全部设置为0, + /// + [DllImport("jakaAPI.dll", EntryPoint = "set_admit_ctrl_config", ExactSpelling = false, CallingConvention = CallingConvention.Cdecl)] + public static extern int set_admit_ctrl_config(ref int i, int axis, int opt, int ftUser, int ftConstant, int ftNnormalTrack, int ftReboundFK); + + /// + /// 开始辨识工具末端负载 + /// + /// + /// 使用力矩传感器进行自动负载辨识时的结束位置 + /// + [DllImport("jakaAPI.dll", EntryPoint = "start_torq_sensor_payload_identify", ExactSpelling = false, CallingConvention = CallingConvention.Cdecl)] + public static extern int start_torq_sensor_payload_identify(ref int i, ref JKTYPE.JointValue joint_pos); + + /// + /// + /// + /// + /// + /// + [DllImport("jakaAPI.dll", EntryPoint = "get_torq_sensor_identify_staus", ExactSpelling = false, CallingConvention = CallingConvention.Cdecl)] + public static extern int get_torq_sensor_identify_staus(ref int i, ref int identify_status); + + /// + /// 获取末端负载辨识结果 + /// + /// + /// 末端负载 + /// + [DllImport("jakaAPI.dll", EntryPoint = "get_torq_sensor_payload_identify_result", ExactSpelling = false, CallingConvention = CallingConvention.Cdecl)] + public static extern int get_torq_sensor_payload_identify_result(ref int i, ref JKTYPE.PayLoad payload); + + /// + /// 设置传感器末端负载 + /// + /// + /// 末端负载 + /// + [DllImport("jakaAPI.dll", EntryPoint = "set_torq_sensor_tool_payload", ExactSpelling = false, CallingConvention = CallingConvention.Cdecl)] + public static extern int set_torq_sensor_tool_payload(ref int i, ref JKTYPE.PayLoad payload); + + /// + /// 获取传感器末端负载 + /// + /// + /// 末端负载 + /// + [DllImport("jakaAPI.dll", EntryPoint = "get_torq_sensor_tool_payload", ExactSpelling = false, CallingConvention = CallingConvention.Cdecl)] + public static extern int get_torq_sensor_tool_payload(ref int i, ref JKTYPE.PayLoad payload); + + /// + /// 力控拖拽使能 + /// + /// + /// 0为关闭力控拖拽使能,1为开启 + /// + [DllImport("jakaAPI.dll", EntryPoint = "enable_admittance_ctrl", ExactSpelling = false, CallingConvention = CallingConvention.Cdecl)] + public static extern int enable_admittance_ctrl(ref int i, int enable_flag); + + /// + /// 设置力控类型和传感器初始化状态 + /// + /// + /// 是否开启传感器补偿,1代表开启即初始化,0代表不初始化 + /// 0 代表不使用任何一种柔顺控制方法 1 代表恒力柔顺控制,2 代表速度柔顺控制 + /// + [DllImport("jakaAPI.dll", EntryPoint = "set_compliant_type", ExactSpelling = false, CallingConvention = CallingConvention.Cdecl)] + public static extern int set_compliant_type(ref int i, int sensor_compensation, int compliance_type); + + /// + /// 获取力控类型和传感器初始化状态 + /// + /// + /// 是否开启传感器补偿,1代表开启即初始化,0代表不初始化 + /// 0 代表不使用任何一种柔顺控制方法 1 代表恒力柔顺控制,2 代表速度柔顺控制 + /// + [DllImport("jakaAPI.dll", EntryPoint = "get_compliant_type", ExactSpelling = false, CallingConvention = CallingConvention.Cdecl)] + public static extern int get_compliant_type(ref int i, ref int sensor_compensation, ref int compliance_type); + + /// + /// 错误状态清除 + /// + /// + /// + [DllImport("jakaAPI.dll", EntryPoint = "clear_error", ExactSpelling = false, CallingConvention = CallingConvention.Cdecl)] + public static extern int clear_error(ref int i); + + /// + /// 获取力控柔顺控制参数 + /// + /// + /// 机器人力控柔顺控制参数存储地址 + /// + [DllImport("jakaAPI.dll", EntryPoint = "get_admit_ctrl_config", ExactSpelling = false, CallingConvention = CallingConvention.Cdecl)] + public static extern int get_admit_ctrl_config(ref int i, ref JKTYPE.RobotAdmitCtrl admit_ctrl_cfg); + + /// + /// 设置力控传感器ip地址 + /// + /// + /// 0为使用tcp/ip协议,1为使用RS485协议 + /// 为力控传感器地址 + /// 为使用tcp/ip协议时力控传感器端口号 + /// + [DllImport("jakaAPI.dll", EntryPoint = "set_torque_sensor_comm", ExactSpelling = false, CallingConvention = CallingConvention.Cdecl)] + public static extern int set_torque_sensor_comm(ref int i, int type, ref char[] ip_addr, int port); + + /// + /// 获取力控传感器ip地址 + /// + /// + /// 0为使用tcp/ip协议,1为使用RS485协议 + /// 力控传感器地址 + /// 使用tcp/ip协议时力控传感器端口号 + /// + [DllImport("jakaAPI.dll", EntryPoint = "get_torque_sensor_comm", ExactSpelling = false, CallingConvention = CallingConvention.Cdecl)] + public static extern int get_torque_sensor_comm(ref int i, ref int type, ref byte ip_addr, ref int port); + + /// + /// 关闭力控 + /// + /// + /// + [DllImport("jakaAPI.dll", EntryPoint = "disable_force_control", ExactSpelling = false, CallingConvention = CallingConvention.Cdecl)] + public static extern int disable_force_control(ref int i); + + /// + /// 设置速度柔顺控制参数 + /// + /// + /// 速度柔顺控制参数 + /// + [DllImport("jakaAPI.dll", EntryPoint = "set_vel_compliant_ctrl", ExactSpelling = false, CallingConvention = CallingConvention.Cdecl)] + public static extern int set_vel_compliant_ctrl(ref int i, ref JKTYPE.VelCom vel); + + /// + /// 设置柔顺控制力矩条件 + /// + /// + /// ft为柔顺控制力矩条件 + /// + [DllImport("jakaAPI.dll", EntryPoint = "set_compliance_condition", ExactSpelling = false, CallingConvention = CallingConvention.Cdecl)] + public static extern int set_compliance_condition(ref int i, ref JKTYPE.FTxyz ft); + + /// + /// 设置网络异常,SDK与机器人控制器失去连接后多长时间机器人控制器终止机械臂当前运动 + /// + /// + /// 时间参数,单位毫秒 + /// 网络异常时机器人需要进行的动作类型 + /// + [DllImport("jakaAPI.dll", EntryPoint = "set_network_exception_handle", ExactSpelling = false, CallingConvention = CallingConvention.Cdecl)] + public static extern int set_network_exception_handle(ref int i, float millisecond, JKTYPE.ProcessType mnt); + + /// + /// 设置机器人状态数据自动更新时间间隔 + /// + /// + /// 时间参数,单位毫秒 + /// + [DllImport("jakaAPI.dll", EntryPoint = "set_status_data_update_time_interval", ExactSpelling = false, CallingConvention = CallingConvention.Cdecl)] + public static extern int set_status_data_update_time_interval(ref int i, float millisecond); + } +} diff --git a/BPASmartClient.JakaRobot/jkType.cs b/BPASmartClient.JakaRobot/jkType.cs new file mode 100644 index 00000000..94e64149 --- /dev/null +++ b/BPASmartClient.JakaRobot/jkType.cs @@ -0,0 +1,364 @@ +using System; +using System.Collections.Generic; +//using System.Numerics; +using System.Text; +using System.Runtime.InteropServices; + + +namespace BPASmartClient.JakaRobot +{ + + public class JKTYPE + { + /** + * @brief 笛卡尔空间位置数据类型 + */ + [StructLayout(LayoutKind.Sequential)] + public struct CartesianTran + { + + public double x; ///< x轴坐标,单位mm + public double y; ///< y轴坐标,单位mm + public double z; ///< z轴坐标,单位mm + }; + + /** + * @brief 欧拉角姿态数据类型 + */ + [StructLayout(LayoutKind.Sequential)] + public struct Rpy + { + public double rx; ///< 绕固定轴X旋转角度,单位:rad + public double ry; ///< 绕固定轴Y旋转角度,单位:rad + public double rz; ///< 绕固定轴Z旋转角度,单位:rad + }; + + /** + * @brief 四元数姿态数据类型 + */ + [StructLayout(LayoutKind.Sequential)] + public struct Quaternion + { + public double s; + public double x; + public double y; + public double z; + }; + + /** + *@brief 笛卡尔空间位姿类型 + */ + [StructLayout(LayoutKind.Sequential)] + public struct CartesianPose + { + public CartesianTran tran; ///< 笛卡尔空间位置 + public Rpy rpy; ///< 笛卡尔空间姿态 + }; + + /** + * @brief 旋转矩阵数据类型 + */ + [StructLayout(LayoutKind.Sequential)] + public struct RotMatrix + { + public CartesianTran x; ///< x轴列分量 + public CartesianTran y; ///< y轴列分量 + public CartesianTran z; ///< z轴列分量 + }; + + /** + * @brief 程序运行状态枚举类型 + */ + public enum ProgramState + { + PROGRAM_IDLE, ///< 机器人停止运行 + PROGRAM_RUNNING, ///< 机器人正在运行 + PROGRAM_PAUSED ///< 机器人暂停 + }; + + /** + * @brief 坐标系选择枚举类型 + */ + public enum CoordType + { + COORD_BASE, ///< 基坐标系 + COORD_JOINT, ///< 关节空间 + COORD_TOOL ///< 工具坐标系 + }; + + /** + * @brief jog运动模式枚举 + */ + public enum MoveMode + { + ABS = 0, ///< 绝对运动 + INCR ///< 增量运动 + }; + + /** + * @brief 系统监测数据类型 + */ + [StructLayout(LayoutKind.Sequential)] + public struct SystemMonitorData + { + public int scbMajorVersion; ///rate1>rate2>rate3>rate4>0 + * 等级为1时,只能设置rate1,rate2两个等级。rate3,rate4的值为0 + * 等级为2时,只能设置rate1,rate2,rate3 三个等级。rate4的值为0 + * 等级为3时,能设置 rate1,rate2,rate3,rate4 4个等级 + */ + [StructLayout(LayoutKind.Sequential)] + public struct VelCom + { + int vc_level; //速度柔顺控制等级 + double rate1; //比率1等级 + double rate2; //比率2等级 + double rate3; //比率3等级 + double rate4; //比率4等级 + } + + /** + * @brief 力传感器的受力分量和力矩分量 + */ + [StructLayout(LayoutKind.Sequential)] + public struct FTxyz + { + double fx; // 沿x轴受力分量 + double fy; // 沿y轴受力分量 + double fz; // 沿z轴受力分量 + double tx; // 绕x轴力矩分量 + double ty; // 绕y轴力矩分量 + double tz; // 绕z轴力矩分量 + } + + } +} diff --git a/BPASmartClient.Juicer/BPASmartClient.Juicer.csproj b/BPASmartClient.Juicer/BPASmartClient.Juicer.csproj new file mode 100644 index 00000000..601a8f6f --- /dev/null +++ b/BPASmartClient.Juicer/BPASmartClient.Juicer.csproj @@ -0,0 +1,14 @@ + + + + net6.0 + enable + enable + + + + + + + + diff --git a/BPASmartClient.Juicer/JuicerMachine.cs b/BPASmartClient.Juicer/JuicerMachine.cs new file mode 100644 index 00000000..047e3770 --- /dev/null +++ b/BPASmartClient.Juicer/JuicerMachine.cs @@ -0,0 +1,61 @@ +using BPASmartClient.EventBus; +using BPASmartClient.Helper; +using BPASmartClient.Model; +using BPASmartClient.Peripheral; +using BPASmartClient.SerialPort; +using static BPASmartClient.EventBus.EventBus; + +namespace BPASmartClient.Juicer +{ + public class JuicerMachine : BasePeripheral + { + JuicerHelper juicerHelper = new JuicerHelper(); + public override void Init() + { + juicerHelper.Open(communicationPar.SerialPort, communicationPar.BaudRate); + + ThreadManage.GetInstance().StartLong(new Action(() => + { + IsConnected = juicerHelper.IsOpen; + if (!IsConnected) IsWork = false; + while (IsConnected) + { + IsWork = true; + if (status != null) + { + SetStatus("GetDeviceStatus", juicerHelper.GetDeviceStatus()); + } + Thread.Sleep(500); + } + Thread.Sleep(1000); + }), $"设备[{DeviceId}]果汁机读取线程", true); + + EventBus.EventBus.GetInstance().Subscribe(DeviceId, delegate (IEvent @event, EventCallBackHandle callBack) + { + if (@event == null) return; + var par = @event as WriteJuicer; + juicerHelper.StartCook(Convert.ToByte(par?.Value)); + }); + } + + //public override void ReadData(string address) + //{ + //} + + public override void Start() + { + } + + public override void Stop() + { + } + + public override void WriteData(string address, object value) + { + } + + protected override void InitStatus() + { + } + } +} \ No newline at end of file diff --git a/BPASmartClient.Lebai/LebaiRobot.cs b/BPASmartClient.Lebai/LebaiRobot.cs index 07a7ced0..1ecfbe59 100644 --- a/BPASmartClient.Lebai/LebaiRobot.cs +++ b/BPASmartClient.Lebai/LebaiRobot.cs @@ -48,6 +48,9 @@ namespace BPASmartClient.Lebai status["RobotIsConnected"] = LebaiHelper.GetInstance().IsConnected; status["RobotOK"] = LebaiHelper.GetInstance().GetValueAsync().Ok; status["RobotValue"] = LebaiHelper.GetInstance().GetValueAsync().Value; + status["RobotValue1"] = LebaiHelper.GetInstance().GetValueAsync(1).Value; + status["GetInput"] = LebaiHelper.GetInstance().GetInput(); + status["GetInput2"] = LebaiHelper.GetInstance().GetInput(2); if (LebaiHelper.GetInstance().robotData != null) status["RobotMode"] = LebaiHelper.GetInstance().robotData.RobotMode.Mode; LebaiHelper.GetInstance().GetRobotModeStatus(); Thread.Sleep(10); diff --git a/BPASmartClient.MCU/BPASmartClient.MCU.csproj b/BPASmartClient.MCU/BPASmartClient.MCU.csproj new file mode 100644 index 00000000..601a8f6f --- /dev/null +++ b/BPASmartClient.MCU/BPASmartClient.MCU.csproj @@ -0,0 +1,14 @@ + + + + net6.0 + enable + enable + + + + + + + + diff --git a/BPASmartClient.MCU/MCUMachine.cs b/BPASmartClient.MCU/MCUMachine.cs new file mode 100644 index 00000000..8568ad1a --- /dev/null +++ b/BPASmartClient.MCU/MCUMachine.cs @@ -0,0 +1,71 @@ +using BPASmartClient.EventBus; +using BPASmartClient.Model.PLC; +using BPASmartClient.Model.单片机; +using BPASmartClient.Peripheral; +using BPASmartClient.SerialPort; +using static BPASmartClient.EventBus.EventBus; + +namespace BPASmartClient.MCU +{ + public class MCUMachine : BasePeripheral + { + MCUSerialHelper mCUSerialHelper = new MCUSerialHelper(); + + public override void Init() + { + mCUSerialHelper.Open(communicationPar.SerialPort, communicationPar.BaudRate); + + EventBus.EventBus.GetInstance().Subscribe(DeviceId, delegate (IEvent @event, EventCallBackHandle callBack) + { + if (@event == null) return; + var par = @event as ReadMcu; + if (status != null) + { + SetStatus(par?.TagName, mCUSerialHelper.GetInputStatus(Convert.ToByte(par?.ReadPar))); + } + }); + + EventBus.EventBus.GetInstance().Subscribe(DeviceId, delegate (IEvent @event, EventCallBackHandle callBack) + { + if (@event == null) return; + var par = @event as WriteMcu; + switch (par?.TagName) + { + case "OutputControl": + mCUSerialHelper.OutputControl(Convert.ToByte(par?.Address), Convert.ToBoolean(par?.Value)); + break; + case "ServoControl": + mCUSerialHelper.ServoControl(Convert.ToByte(par?.Address), Convert.ToByte(par?.Value)); + break; + default: + break; + } + }); + } + + //public override void ReadData(string address) + //{ + + //} + + public override void Start() + { + + } + + public override void Stop() + { + + } + + public override void WriteData(string address, object value) + { + + } + + protected override void InitStatus() + { + + } + } +} \ No newline at end of file diff --git a/BPASmartClient.MORKSM.BK.PLC/PLCMachine.cs b/BPASmartClient.MORKSM.BK.PLC/PLCMachine.cs index 3551f1ff..eb34ff5e 100644 --- a/BPASmartClient.MORKSM.BK.PLC/PLCMachine.cs +++ b/BPASmartClient.MORKSM.BK.PLC/PLCMachine.cs @@ -48,11 +48,15 @@ namespace BPASmartClient.PLC { if (@event == null) return; var par = @event as WriteModel; - //M32.7地址复位 modbusTcp.Write(par?.Address, par?.Value); }); } + //public override void ReadData(string address) + //{ + + //} + public override void Start() { diff --git a/BPASmartClient.Model/BaseEvent.cs b/BPASmartClient.Model/BaseEvent.cs index 3ee63db2..bfd5714b 100644 --- a/BPASmartClient.Model/BaseEvent.cs +++ b/BPASmartClient.Model/BaseEvent.cs @@ -11,6 +11,8 @@ namespace BPASmartClient.Model public class BaseEvent : IEvent { public int DeviceId { get; set; } + + public string TagName { get; set; } public DeviceClientType deviceClientType { get; set; } } } diff --git a/BPASmartClient.Model/PLC/ReadModel.cs b/BPASmartClient.Model/PLC/ReadModel.cs index 75d479e9..b12efb44 100644 --- a/BPASmartClient.Model/PLC/ReadModel.cs +++ b/BPASmartClient.Model/PLC/ReadModel.cs @@ -8,7 +8,9 @@ namespace BPASmartClient.Model.PLC { public class ReadModel : BaseEvent { + public string Address { get; set; } public ushort Length { get; set; } + public object ReadPar { get; set; } } } diff --git a/BPASmartClient.Model/单片机/SCChipEvent.cs b/BPASmartClient.Model/单片机/SCChipEvent.cs index 270d4e88..d8cf00e6 100644 --- a/BPASmartClient.Model/单片机/SCChipEvent.cs +++ b/BPASmartClient.Model/单片机/SCChipEvent.cs @@ -1,4 +1,5 @@ -using BPASmartClient.Model.单片机.Enum; +using BPASmartClient.Model.PLC; +using BPASmartClient.Model.单片机.Enum; using System; using System.Collections.Generic; using System.Linq; @@ -16,7 +17,7 @@ namespace BPASmartClient.Model.单片机 /// /// STM32F103RCT6单片机下杯 /// - public class SCChip_TakeCupEvent :BaseEvent + public class SCChip_TakeCupEvent : BaseEvent { /// /// 杯 @@ -27,7 +28,7 @@ namespace BPASmartClient.Model.单片机 /// /// STM32F103RCT6单片机舵机打料 /// - public class SCChip_MakeIceCreamEvent :BaseEvent + public class SCChip_MakeIceCreamEvent : BaseEvent { public IC_SE SteeringEngine { get; set; } } @@ -35,7 +36,7 @@ namespace BPASmartClient.Model.单片机 /// /// STM32F103RCT6单片机舵机打开或者关闭 /// - public class SCChip_SESwitchCreamEvent :BaseEvent + public class SCChip_SESwitchCreamEvent : BaseEvent { public IC_SE SteeringEngine { get; set; } public bool IsOpen { get; set; } @@ -44,7 +45,7 @@ namespace BPASmartClient.Model.单片机 /// /// STM32F103RCT6单片机控制冰淇淋机器转 /// - public class SCChip_RotorSwitchEvent :BaseEvent + public class SCChip_RotorSwitchEvent : BaseEvent { public bool TurnOn { get; set; } } @@ -62,4 +63,14 @@ namespace BPASmartClient.Model.单片机 { } + + public class WriteMcu : WriteModel + { + + } + + public class ReadMcu : ReadModel + { + + } } diff --git a/BPASmartClient.Model/果汁机/JuicerModel.cs b/BPASmartClient.Model/果汁机/JuicerModel.cs new file mode 100644 index 00000000..8855d87f --- /dev/null +++ b/BPASmartClient.Model/果汁机/JuicerModel.cs @@ -0,0 +1,66 @@ +using BPASmartClient.Model.PLC; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace BPASmartClient.Model +{ + public class JuicerModel + { + #region 果汁机设备MORKT2 Lebai机器人 + public const int JUICE2_初始位 = 10021; + public const int JUICE2_检测位回原点 = 10023; + public const int JUICE2_取纸杯 = 10006; + public const int JUICE2_二次取杯 = 10008; + public const int JUICE2_纸杯检测 = 10007; + public const int JUICE2_再检测 = 10024; + public const int JUICE2_接咖啡 = 10009; + public const int JUICE2_放咖啡杯 = 10010; + + public const int JUICE2_接茶叶 = 10017; + public const int JUICE2_接茶水 = 10018; + public const int JUICE2_接水 = 10020; + public const int JUICE2_放水杯 = 10019; + + public const int JUICE2_接果汁公共位 = 10011; + public const int JUICE2_接1号果汁 = 10012; + public const int JUICE2_接2号果汁 = 10013; + public const int JUICE2_接3号果汁 = 10014; + public const int JUICE2_接4号果汁 = 10015; + public const int JUICE2_放果汁杯 = 10016; + #endregion + + #region 果汁机设备 MORKT1 JAKA机器人 + public const int JUICE_初始位 = 20000; + public const int JUICE_取杯 = 20001; + public const int JUICE_取杯检测 = 20010; + public const int JUICE_接咖啡 = 20020; + public const int JUICE_接1号果汁 = 20030; + public const int JUICE_接2号果汁 = 20040; + public const int JUICE_接3号果汁 = 20050; + public const int JUICE_接4号果汁 = 20060; + public const int JUICE_接茶 = 20070; + public const int JUICE_接茶水 = 20075; + public const int JUICE_接水 = 20080; + + public const int JUICE_放咖啡杯 = 20090; + public const int JUICE_放果汁杯 = 20100; + public const int JUICE_放茶水杯 = 20110; + + public const int JUICE_放杯 = 20120; + public const int JUICE_放杯检测 = 20120; + #endregion + } + + public class WriteJuicer : WriteModel + { + + } + + public class ReadJuicer : ReadModel + { + + } +} diff --git a/BPASmartClient.Model/节卡机器人/JakaModel.cs b/BPASmartClient.Model/节卡机器人/JakaModel.cs new file mode 100644 index 00000000..6ec5a876 --- /dev/null +++ b/BPASmartClient.Model/节卡机器人/JakaModel.cs @@ -0,0 +1,51 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace BPASmartClient.Model +{ + public class JakaModel + { + public const string SENCE_取杯 = "10000"; + public const string SENCE_放杯位检测 = "10100"; + public const string SENCE_取杯检测 = "11000"; + + public const string SENCE_接咖啡 = "12000"; + public const string SENCE_接果汁1 = "12001"; + public const string SENCE_接果汁2 = "12002"; + public const string SENCE_接果汁3 = "12003"; + public const string SENCE_接果汁4 = "12004"; + public const string SENCE_接茶 = "12005"; + public const string SENCE_接水 = "12006"; + public const string SENCE_接茶_接水 = "12007"; + + public const string SENCE_放咖啡杯 = "13000";//接饮料位---放饮料过渡位 + public const string SENCE_放果汁杯1 = "13001"; + public const string SENCE_放果汁杯2 = "13002"; + public const string SENCE_放果汁杯3 = "13003"; + public const string SENCE_放果汁杯4 = "13004"; + public const string SENCE_放茶水杯 = "13005"; + + public const string SENCE_放杯 = "14000";//放杯过渡位到-放杯 + + public const string SENCE_放杯检测 = "15000"; + + public const string SENCE_初始位 = "20000"; + } + + public class WriteJaka : BaseEvent + { + public string Address { get; set; } + public object Value { get; set; } + } + + public class ReadJaka : BaseEvent + { + public string Address { get; set; } + public ushort Length { get; set; } + public object ReadPar { get; set; } + } +} + diff --git a/BPASmartClient.MorkT.Lebai.JC/BPASmartClient.MorkTLebaiJC.csproj b/BPASmartClient.MorkT.Lebai.JC/BPASmartClient.MorkTLebaiJC.csproj index 9a7c06f1..ef077463 100644 --- a/BPASmartClient.MorkT.Lebai.JC/BPASmartClient.MorkTLebaiJC.csproj +++ b/BPASmartClient.MorkT.Lebai.JC/BPASmartClient.MorkTLebaiJC.csproj @@ -6,4 +6,8 @@ true + + + + diff --git a/BPASmartClient.MorkT.Lebai.JC/Class1.cs b/BPASmartClient.MorkT.Lebai.JC/Class1.cs deleted file mode 100644 index 8f78d56d..00000000 --- a/BPASmartClient.MorkT.Lebai.JC/Class1.cs +++ /dev/null @@ -1,8 +0,0 @@ -using System; - -namespace BPASmartClient.MorkTLebaiJC -{ - public class Class1 - { - } -} diff --git a/BPASmartClient.MorkT.Lebai.JC/Control_MORKJC2.cs b/BPASmartClient.MorkT.Lebai.JC/Control_MORKJC2.cs new file mode 100644 index 00000000..51b87ca5 --- /dev/null +++ b/BPASmartClient.MorkT.Lebai.JC/Control_MORKJC2.cs @@ -0,0 +1,865 @@ +using System; +using System.Collections.Generic; +using System.Configuration; +using System.Linq; +using System.Threading; +using System.Collections.Concurrent; +using System.Diagnostics; +using System.Threading.Tasks; +using BPASmartClient.Device; +using BPA.Message.Enum; +using BPA.Message; +using BPASmartClient.Helper; +using BPASmartClient.Model.咖啡机.Enum; +using BPASmartClient.Model; +using BPASmartClient.EventBus; +using static BPASmartClient.EventBus.EventBus; +using BPASmartClient.Message; +using BPASmartClient.Model.乐白机器人; +using BPASmartClient.Model.单片机; + +namespace BPASmartClient.MorkTLebaiJC +{ + /* + * 冰淇淋咖啡机组合套装 + * 物料位置: + * 1:冰淇料 + * 2:冰淇淋杯 + * 5:咖啡 + * 6:咖啡杯 + * 9: 茶 + * 10: 茶杯 + */ + public class Control_MORKJC2 : BaseDevice + { + //private CoffeEndCook coffeEndCook = new CoffeEndCook();//模拟咖啡制作成功 + //咖啡机主控程序 + //private CoffeeMachine coffeeMachine; + //物料存放位置 + private Dictionary batchings = new Dictionary(); + //容器位置 + private string holderLoc; + /// + /// 获取乐百机器人的数据 + /// + //SignalResult lebai = new SignalResult(); + //主料位置 + private string mainMaterialLoc; + //子订单ID + private string subOrderId; + + private bool enableFunny = false; + private DateTime lastRecvdOrder = DateTime.Now; + private bool working = false; + /// + /// 果汁机做法,true:热饮,false:冷饮 + /// + private bool GuMake = false; + + //private SerialPortClient commProxy; + public void ConnectOk() + { + + } + ConcurrentQueue morkOrderPushes = new ConcurrentQueue(); + public void Init() + { + //ActionManage.GetInstance.Register(new Action((s) => + //{ + // if (s is DrCoffeeDrinksCode cf) + // { + // DoCoffee(); + // } + // else if (s is Dictionary ms) + // { + // if (ms.ContainsKey("Button")) + // { + // switch (ms["Button"]) + // { + // case "启动示教": + // JuicerModel.GetInstance.StartTeachMode(); + // break; + // case "停止示教": + // JuicerModel.GetInstance.EndtTeachMode(); + // break; + // case "启动机器人": + // JuicerModel.GetInstance.StartRobot(); + // break; + // case "急停": + // JuicerModel.GetInstance.EStopRobot(); + // break; + // default: + // break; + // } + // } + // } + //}), "SimCoffee"); + + //构建所有商品物料信息 + batchings = PolymerBatching.BuildAll(); + + EventBus.EventBus.GetInstance().Subscribe(DeviceId, CoffeEndCookHandle); + + System.Configuration.Configuration config = System.Configuration.ConfigurationManager.OpenExeConfiguration(System.Configuration.ConfigurationUserLevel.None); + //一系列外围基础配置 + var com_Coffee = config.AppSettings.Settings["COM_Coffee"].Value; + var baud_Coffee = config.AppSettings.Settings["BAUD_Coffee"].Value; + //咖啡机创建 + //coffeeMachine = new CoffeeMachine(com_Coffee, (BaudRates)Enum.Parse(typeof(BaudRates), baud_Coffee)); + + Main(); + ReadData(); + ThreadManage.GetInstance().StartLong(new Action(() => + { + while (IsHealth && (morkOrderPushes.Count > 0)) + { + working = true; + if (morkOrderPushes.TryDequeue(out MorkOrderPush order)) + { + MessageLog.GetInstance.Show($"开始制作订单[{order.SortNum}]"); + //商品类型 + GOODS_TYPE currentGoodsType = GOODS_TYPE.NEITHER; + //子订单ID + subOrderId = order.SuborderId; + //遍历物料 + foreach (var item in order.GoodBatchings) + { + var res = Json.Data.orderMaterialDelivery.BatchingInfo.FirstOrDefault(p => p.BatchingId == item.BatchingId); + if (res != null) + { + //获取主料和容器位置 + switch (batchings[res.BatchingLoc].BatchingClass) + { + case BATCHING_CLASS.HOLDER: + holderLoc = res.BatchingLoc; + break; + case BATCHING_CLASS.MAIN_MATERIAL: + // mainMaterialLoc ="1"; + mainMaterialLoc = res.BatchingLoc; + //验证商品是咖啡还是冰淇淋 + if (ValidateGoodsByBatching(res.BatchingLoc) != GOODS_TYPE.NEITHER) + { + //获取当前物料所属商品类型 + currentGoodsType = ValidateGoodsByBatching(res.BatchingLoc); + } + break; + } + } + } + + //根据商品类型执行具体制作流程 + switch (currentGoodsType) + { + case GOODS_TYPE.COFFEE: + DoCoffee(); + break; + case GOODS_TYPE.JUICE: + GuMake = order.MakeID == "2"; + DoJuicer(); + break; + case GOODS_TYPE.TEA: + DoTea(); + break; + case GOODS_TYPE.WATER: + DoWater(); + break; + case GOODS_TYPE.NEITHER: + MessageLog.GetInstance.Show("未知的商品类型"); + break; + } + } + working = false; + lastRecvdOrder = DateTime.Now; + } + Thread.Sleep(1000); + }), "订单制作"); + } + + public void Main() + { + //咖啡机开启主线程 + //coffeeMachine.Start(); + //开始心跳刷新,根据咖啡机及冰淇淋机来判断 + ThreadManage.GetInstance().StartLong(new Action(() => + { + //GeneralConfig.Healthy = + // JuicerModel.GetInstance.IsConnected && + // MorkCStatus.GetInstance().CanDo && + // JuicerHelper.GetInstance.IsOpen && + // MCUSerialHelper.GetInstance.IsOpen; + //GeneralConfig.Healthy = true; + Thread.Sleep(100); + }), "MORK-IC心跳刷新"); + //ThreadManage.GetInstance.Start(new Action(() => + //{ + // while (!JuicerModel.GetInstance.IsConnected) + // { + // Thread.Sleep(10); + // } + // //Sence(JuicerModel.SENCE_欢迎); + //}), "MORK-JC欢迎"); + } + + private void OrderChange(string subid, ORDER_STATUS oRDER_STATUS) + { + EventBus.EventBus.GetInstance().Publish(new OrderStatusChangedEvent() { Status = oRDER_STATUS, SubOrderId = subid, deviceClientType = DeviceType }); + } + + public void DataParse(T order) + { + if (order is MorkOrderPush morkOrderPush) + { + morkOrderPushes.Enqueue(morkOrderPush); + } + } + + /// + /// 验证当前是做咖啡还是做冰淇淋 + /// + /// 物料位置 + private GOODS_TYPE ValidateGoodsByBatching(string batchingLoc) + { + if (batchings.ContainsKey(batchingLoc)) + return batchings[batchingLoc].GoodsType; + return GOODS_TYPE.NEITHER; + } + + private AutoResetEvent are = new AutoResetEvent(false); + + private void Wait(int value = 101) + { + while (!((bool)peripheralStatus["RobotOK"] && (int)peripheralStatus["RobotValue"] == value)) + { + Thread.Sleep(5); + } + new LebaiRobot_SetValueEvent { DeviceId = DeviceId, RobotSetValue = 0 }.Publish(); + } + + private void Sence(int sen) + { + new LebaiRobot_LebaiSenceEvent { DeviceId = DeviceId, LebaiSence = sen }.Publish(); + } + + private T GetStatus(string key) + { + if (peripheralStatus.ContainsKey(key)) + { + if (peripheralStatus[key] != null) + { + return (T)(peripheralStatus[key]); + } + } + return default; + } + + int[] devStatusBy = new int[2] { 0, 0 }; + bool outCupCheck = false;//放纸杯位置有无判断 + /// + /// 传感器的输入信号 0:无意义 1:有信号 2:无信号 3:信号不正确 + /// + int bSensorInput; + /// + /// 延迟的超时时间 + /// + DateTime delayTimeOut; + /// + /// 做咖啡 + /// + private void DoCoffee() + { + + #region 接咖啡流程 + are.Reset(); + while (GetStatus("RobotValue1"))//判断放杯位置是否有物品 + { + if (!outCupCheck) + MessageLog.GetInstance.ShowEx("成品处有纸杯存在,请取走!!"); + outCupCheck = true; + } + outCupCheck = false; + OrderChange(subOrderId, BPA.Message.Enum.ORDER_STATUS.COOKING); + int resultTakeCup = takeCup(); + if (resultTakeCup == 1) + { + MessageLog.GetInstance.Show("咖啡杯取杯完成"); + new LebaiRobot_SetValueEvent { DeviceId = DeviceId, RobotSetValue = 0 }.Publish(); + Sence(JuicerModel.JUICE2_接咖啡); + Wait(); + + new DRCoffee_MakeCoffeeEvent() { DrinkCode = (DrCoffeeDrinksCode)int.Parse(mainMaterialLoc) }.Publish(); //接咖啡控制 //DrCoffeeDrinksCode.热水 + //Task.Delay(10000).Wait();//模拟接咖啡 + //coffeEndCook.Publish();//模拟咖啡制作完成 + are.WaitOne(1000 * 360); + while (GetStatus("RobotValue1"))//判断放杯位置是否有物品 + { + if (!outCupCheck) + MessageLog.GetInstance.ShowEx("成品处有纸杯存在,请取走!!"); + outCupCheck = true; + } + outCupCheck = false; + while (GetStatus("RobotValue1"))//判断放杯位置是否有物品 + { + if (!outCupCheck) + MessageLog.GetInstance.ShowEx("成品处有纸杯存在,请取走!!"); + outCupCheck = true; + } + outCupCheck = false; + new LebaiRobot_SetValueEvent { DeviceId = DeviceId, RobotSetValue = 0 }.Publish(); + Sence(JuicerModel.JUICE2_放咖啡杯); + Wait(); + OrderChange(subOrderId, BPA.Message.Enum.ORDER_STATUS.COMPLETED_TAKE); + MessageLog.GetInstance.Show("咖啡制作完成"); + + } + else + { + return; + } + #endregion + } + /// + /// 做茶 + /// + private void DoTea() + { + #region 接茶流程 + while (GetStatus("RobotValue1"))//判断放杯位置是否有物品 + { + if (!outCupCheck) + MessageLog.GetInstance.ShowEx("成品处有纸杯存在,请取走!!"); + outCupCheck = true; + } + outCupCheck = false; + OrderChange(subOrderId, BPA.Message.Enum.ORDER_STATUS.COOKING); + int resultTakeCup = takeCup(); + if (resultTakeCup == 1) + { + MessageLog.GetInstance.Show("取茶杯完成"); + new LebaiRobot_SetValueEvent { DeviceId = DeviceId, RobotSetValue = 0 }.Publish(); + Sence(JuicerModel.JUICE2_接茶叶); + Wait(); + + new WriteMcu() { TagName = "ServoControl", Address = "1", Value = 90 }.Publish(); + Thread.Sleep(1000); + new WriteMcu() { TagName = "ServoControl", Address = "1", Value = 150 }.Publish(); + Thread.Sleep(1000); + new WriteMcu() { TagName = "ServoControl", Address = "1", Value = 90 }.Publish(); + + Thread.Sleep(3000); + new LebaiRobot_SetValueEvent { DeviceId = DeviceId, RobotSetValue = 0 }.Publish(); + Sence(JuicerModel.JUICE2_接茶水); + Wait(); + + new WriteMcu() { TagName = "OutputControl", Address = "1", Value = false }.Publish(); + + new WriteMcu() { TagName = "OutputControl", Address = "0", Value = false }.Publish(); + Thread.Sleep(100); + new WriteMcu() { TagName = "OutputControl", Address = "0", Value = true }.Publish(); + Thread.Sleep(3000); + new WriteMcu() { TagName = "OutputControl", Address = "0", Value = false }.Publish(); + Thread.Sleep(100); + + new WriteMcu() { TagName = "OutputControl", Address = "1", Value = false }.Publish(); + Thread.Sleep(100); + new WriteMcu() { TagName = "OutputControl", Address = "1", Value = true }.Publish(); + Thread.Sleep(500); + new WriteMcu() { TagName = "OutputControl", Address = "1", Value = false }.Publish(); + Thread.Sleep(46000); + while (GetStatus("RobotValue1"))//判断放杯位置是否有物品 + { + if (!outCupCheck) + MessageLog.GetInstance.ShowEx("成品处有纸杯存在,请取走!!"); + outCupCheck = true; + } + outCupCheck = false; + new LebaiRobot_SetValueEvent { DeviceId = DeviceId, RobotSetValue = 0 }.Publish(); + Sence(JuicerModel.JUICE2_放水杯); + Wait(); + + + OrderChange(subOrderId, BPA.Message.Enum.ORDER_STATUS.COMPLETED_TAKE); + MessageLog.GetInstance.Show("茶水制作完成"); + + } + else + { + return; + } + #endregion + } + + /// + /// 接开水 + /// + private void DoWater() + { + #region 接水流程 + while (GetStatus("RobotValue1"))//判断放杯位置是否有物品 + { + if (!outCupCheck) + MessageLog.GetInstance.ShowEx("成品处有纸杯存在,请取走!!"); + outCupCheck = true; + } + outCupCheck = false; + OrderChange(subOrderId, BPA.Message.Enum.ORDER_STATUS.COOKING); + int resultTakeCup = takeCup(); + if (resultTakeCup == 1) + { + new LebaiRobot_SetValueEvent { DeviceId = DeviceId, RobotSetValue = 0 }.Publish(); + Sence(JuicerModel.JUICE2_接水); + Wait(); + new WriteMcu() { TagName = "OutputControl", Address = "1", Value = false }.Publish(); + new WriteMcu() { TagName = "OutputControl", Address = "0", Value = false }.Publish(); + Thread.Sleep(100); + new WriteMcu() { TagName = "OutputControl", Address = "0", Value = true }.Publish(); + Thread.Sleep(3000); + new WriteMcu() { TagName = "OutputControl", Address = "0", Value = false }.Publish(); + Thread.Sleep(100); + + new WriteMcu() { TagName = "OutputControl", Address = "1", Value = false }.Publish(); + Thread.Sleep(100); + new WriteMcu() { TagName = "OutputControl", Address = "1", Value = true }.Publish(); + Thread.Sleep(500); + new WriteMcu() { TagName = "OutputControl", Address = "1", Value = false }.Publish(); + Thread.Sleep(46000); + while (GetStatus("RobotValue1"))//判断放杯位置是否有物品 + { + if (!outCupCheck) + MessageLog.GetInstance.ShowEx("成品处有纸杯存在,请取走!!"); + outCupCheck = true; + } + outCupCheck = false; + //添加控制接水机构程序 + new LebaiRobot_SetValueEvent { DeviceId = DeviceId, RobotSetValue = 0 }.Publish(); + Sence(JuicerModel.JUICE2_放水杯); + Wait(); + OrderChange(subOrderId, BPA.Message.Enum.ORDER_STATUS.COMPLETED_TAKE); + MessageLog.GetInstance.Show("纯净水制作完成"); + + } + else + { + return; + } + #endregion + } + /// + /// 果汁机控制信号 + /// + private byte JuicerNum; + /// + /// 做果汁 + /// + private void DoJuicer() + { + #region 接果汁流程 + are.Reset(); + while (GetStatus("RobotValue1"))//判断放杯位置是否有物品 + { + if (!outCupCheck) + MessageLog.GetInstance.ShowEx("成品处有纸杯存在,请取走!!"); + outCupCheck = true; + } + OrderChange(subOrderId, BPA.Message.Enum.ORDER_STATUS.COOKING); + int resultTakeCup = takeCup(); + if (resultTakeCup == 1) + { + int JuicerNum1 = int.Parse(mainMaterialLoc); + switch (JuicerNum1) + { + case 52: + if (GuMake) + { + JuicerNum = 0x00; + } + else + { + JuicerNum = 0x01; + } + new LebaiRobot_SetValueEvent { DeviceId = DeviceId, RobotSetValue = 0 }.Publish(); + Sence(JuicerModel.JUICE2_接果汁公共位); + Wait(); + + new LebaiRobot_SetValueEvent { DeviceId = DeviceId, RobotSetValue = 0 }.Publish(); + Sence(JuicerModel.JUICE2_接1号果汁); + Wait(); + + break; + case 53: + if (GuMake) + { + JuicerNum = 0x02; + } + else + { + JuicerNum = 0x03; + } + new LebaiRobot_SetValueEvent { DeviceId = DeviceId, RobotSetValue = 0 }.Publish(); + Sence(JuicerModel.JUICE2_接果汁公共位); + Wait(); + + new LebaiRobot_SetValueEvent { DeviceId = DeviceId, RobotSetValue = 0 }.Publish(); + Sence(JuicerModel.JUICE2_接2号果汁); + Wait(); + + break; + case 54: + if (GuMake) + { + JuicerNum = 0x04; + } + else + { + JuicerNum = 0x05; + } + new LebaiRobot_SetValueEvent { DeviceId = DeviceId, RobotSetValue = 0 }.Publish(); + Sence(JuicerModel.JUICE2_接果汁公共位); + Wait(); + + new LebaiRobot_SetValueEvent { DeviceId = DeviceId, RobotSetValue = 0 }.Publish(); + Sence(JuicerModel.JUICE2_接3号果汁); + Wait(); + + break; + case 55: + if (GuMake) + { + JuicerNum = 0x06; + } + else + { + JuicerNum = 0x07; + } + new LebaiRobot_SetValueEvent { DeviceId = DeviceId, RobotSetValue = 0 }.Publish(); + Sence(JuicerModel.JUICE2_接果汁公共位); + Wait(); + + new LebaiRobot_SetValueEvent { DeviceId = DeviceId, RobotSetValue = 0 }.Publish(); + Sence(JuicerModel.JUICE2_接4号果汁); ; + Wait(); + + break; + default: + JuicerNum = 0x00; + new LebaiRobot_SetValueEvent { DeviceId = DeviceId, RobotSetValue = 0 }.Publish(); + Sence(JuicerModel.JUICE2_接果汁公共位); + Wait(); + + new LebaiRobot_SetValueEvent { DeviceId = DeviceId, RobotSetValue = 0 }.Publish(); + Sence(JuicerModel.JUICE_接1号果汁); + Wait(); + + break; + } + var devStatus = GetStatus("GetDeviceStatus"); + var devStatus1 = Convert.ToString(devStatus[0], 2); + var devStatus2 = devStatus[1]; + + if (devStatus1.IndexOf("0") == 1 && devStatus2 == 0) + { + new WriteJuicer() { Value = JuicerNum }.Publish(); + Thread.Sleep(100); + devStatusBy = GetStatus("GetDeviceStatus"); + while (!(devStatusBy[1] == 0)) + { + Thread.Sleep(100); + devStatusBy = GetStatus("GetDeviceStatus"); + while (devStatusBy.Length != 2) + { + Thread.Sleep(100); + devStatusBy = GetStatus("GetDeviceStatus"); + } + } + devStatusBy = GetStatus("GetDeviceStatus"); + Thread.Sleep(5000); + while (GetStatus("RobotValue1"))//判断放杯位置是否有物品 + { + if (!outCupCheck) + MessageLog.GetInstance.ShowEx("成品处有纸杯存在,请取走!!"); + outCupCheck = true; + } + outCupCheck = false; + new LebaiRobot_SetValueEvent { DeviceId = DeviceId, RobotSetValue = 0 }.Publish(); + Sence(JuicerModel.JUICE2_放果汁杯); + Wait(); + + OrderChange(subOrderId, BPA.Message.Enum.ORDER_STATUS.COMPLETED_TAKE); + MessageLog.GetInstance.Show("果汁制作完成"); + + } + ////模拟果汁 + //Thread.Sleep(15000); + //while (GetStatus("RobotValue1"))//判断放杯位置是否有物品 + //{ + // if (!outCupCheck) + // MessageLog.GetInstance.ShowEx("成品处有纸杯存在,请取走!!"); + // outCupCheck = true; + //} + //outCupCheck = false; + //new LebaiRobot_SetValueEvent { DeviceId = DeviceId, RobotSetValue = 0 }.Publish(); + //Sence(JuicerModel.JUICE2_放果汁杯); + //Wait(); + + //OrderChange(subOrderId, BPA.Message.Enum.ORDER_STATUS.COMPLETED_TAKE); + //MessageLog.GetInstance.Show("果汁制作完成"); + } + else + { + return; + } + #endregion + } + /// + /// 取杯的次数 + /// + private int nCnt; + private int checkCnt;//检测次数 + + public override DeviceClientType DeviceType => throw new NotImplementedException(); + + /// + /// 取杯流程 + /// + /// 0:无意义,1:取杯成功 2:取杯失败 + private int takeCup() + { + try + { + + nCnt = 0; + new LebaiRobot_SetValueEvent { DeviceId = DeviceId, RobotSetValue = 0 }.Publish(); + Sence(JuicerModel.JUICE2_初始位); + Wait(); + + + new LebaiRobot_SetValueEvent { DeviceId = DeviceId, RobotSetValue = 0 }.Publish(); + Sence(JuicerModel.JUICE2_取纸杯); + Wait(); + + + new LebaiRobot_SetValueEvent { DeviceId = DeviceId, RobotSetValue = 0 }.Publish(); + Sence(JuicerModel.JUICE2_纸杯检测); + Wait(); + + nCnt++; + Thread.Sleep(2000); + while (checkCnt < 3) + { + if (!GetStatus("GetInput")) + { + new LebaiRobot_SetValueEvent { DeviceId = DeviceId, RobotSetValue = 0 }.Publish(); + Sence(JuicerModel.JUICE2_再检测); + Wait(); + } + else + { + break; + } + checkCnt++; + } + checkCnt = 0; + while (!GetStatus("GetInput")) //读取传感器的值 + { + if (nCnt > 3) + { + nCnt = 0; + MessageLog.GetInstance.ShowEx("三次取杯失败,回原点"); + new LebaiRobot_SetValueEvent { DeviceId = DeviceId, RobotSetValue = 0 }.Publish(); + Sence(JuicerModel.JUICE2_检测位回原点); + Wait(); + return 2; + } + else + { + + + nCnt++; + new LebaiRobot_SetValueEvent { DeviceId = DeviceId, RobotSetValue = 0 }.Publish(); + Sence(JuicerModel.JUICE2_二次取杯); + Wait(); + + new LebaiRobot_SetValueEvent { DeviceId = DeviceId, RobotSetValue = 0 }.Publish(); + Sence(JuicerModel.JUICE2_纸杯检测); + Wait(); + checkCnt = 0; + while (checkCnt < 3) + { + if (!GetStatus("GetInput")) + { + new LebaiRobot_SetValueEvent { DeviceId = DeviceId, RobotSetValue = 0 }.Publish(); + Sence(JuicerModel.JUICE2_再检测); + Wait(); + } + else + { + checkCnt = 0; + return 1; + + } + checkCnt++; + } + + } + Thread.Sleep(1000); + } + } + catch (Exception ex) + { + MessageLog.GetInstance.Show(ex.ToString()); + } + + return 1; + } + /// + /// 放杯 + /// + /// 0:无意义 1:放杯成功 2:执行失败(传感器还有信号) 3:放杯异常 + private int putCup() + { + try + { + if (GetStatus("RobotValue1")) return 2; + Sence(JuicerModel.JUICE_放杯); + Wait(); + new LebaiRobot_SetValueEvent() { RobotSetValue = 1 }.Publish(); + Sence(JuicerModel.JUICE_放杯检测); + Wait(); + new LebaiRobot_SetValueEvent() { RobotSetValue = 1 }.Publish(); + if (GetStatus("GetInput2")) + { + return 1; + } + else + { + return 3; + } + } + catch (Exception ex) + { + MessageLog.GetInstance.Show(ex.ToString()); + return 0; + } + } + + /// + /// 检测放杯位,是否有杯子 + /// + /// 0:无意义 1:没有杯子 2:有杯子 + private int checkCup() + { + try + { + while (GetStatus("RobotValue1")) + { + Thread.Sleep(100); + if (DateTime.Now.Subtract(delayTimeOut).TotalSeconds >= 1) return 2; + } + MessageLog.GetInstance.Show("放杯位有杯子未取走,等待取走,最多等待60s,即跳出流程"); + return 1; + } + catch (Exception ex) + { + MessageLog.GetInstance.Show(ex.ToString()); + return 0; + } + } + + private void CoffeEndCookHandle(IEvent @event, EventCallBackHandle callBack) + { + are.Set(); + } + + + //public void ReadData() + //{ + // //ThreadManage.GetInstance.StartLong(new Action(() => + // //{ + // // lebai = JuicerModel.GetInstance.GetValueAsync(); + // // JuicerModel.GetInstance.GetRobotModeStatus(); + // // //JuicerModel.GetInstance.GetInput(); + + + // // Thread.Sleep(100); + // //}), "乐百机器人数据读取", true); + //} + + public void SimOrder(T simOrder) + { + //if (morkOrderPushes.Count > 0) + //{ + // morkOrderPushes.Clear(); + //} + //morkOrderPushes.Enqueue(simOrder as MorkOrderPush); + } + + + + /// + /// IOT 广播消息命令 + /// + //public void IotBroadcast(T broadcast) + //{ + // if (broadcast != null && broadcast is IOTCommandModel iOTCommand) + // { + // switch (iOTCommand.CommandName) + // { + // case 0://控制类 + // if (iOTCommand.CommandValue != null) + // { + // if (iOTCommand.CommandValue.ContainsKey("SimOrder")) + // { + // //SimOrder(new SimOrderData { NoodleLoc = 1, BowlLoc = 10 }); + // } + // } + // break; + // case 1://设置属性 + + // break; + // case 2://通知消息 + + // break; + // default: + // break; + // } + // } + //} + + public override void DoMain() + { + } + + public override void Stop() + { + } + + public override void ReadData() + { + + } + + public override void MainTask() + { + } + + public override void ResetProgram() + { + } + + public class SimOrderData + { + public string id { get; set; } + + public int OrderStatus { get; set; } + + public string Loc { get; set; } + + public MorkOrderPush morkOrder { get; set; } + + public SimOrderData() + { + id = Guid.NewGuid().ToString(); + OrderStatus = 0; + } + } + } +} diff --git a/BPASmartClient.MorkT.Lebai.JC/PolymerBatching.cs b/BPASmartClient.MorkT.Lebai.JC/PolymerBatching.cs new file mode 100644 index 00000000..be2b0443 --- /dev/null +++ b/BPASmartClient.MorkT.Lebai.JC/PolymerBatching.cs @@ -0,0 +1,152 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace BPASmartClient.MorkTLebaiJC +{ + internal enum GOODS_TYPE + { + /// + /// 未知 + /// + NEITHER, + /// + /// 咖啡 + /// + COFFEE, + /// + /// 果汁 + /// + JUICE, + /// + /// 茶水 + /// + TEA, + /// + /// 水 + /// + WATER, + /// + /// 杯子 + /// + CUP + } + + internal enum BATCHING_CLASS + { + HOLDER, + MAIN_MATERIAL, + } + + internal class PolymerBatching + { + internal const string Juicer_MAIN_BATCHIN1_LOC = "52"; + internal const string Juicer_MAIN_BATCHIN2_LOC = "53"; + internal const string Juicer_MAIN_BATCHIN3_LOC = "54"; + internal const string Juicer_MAIN_BATCHIN4_LOC = "55"; + //internal const string Juicer_MAIN_BATCHIN5_LOC = "56"; + //internal const string Juicer_MAIN_BATCHIN6_LOC = "57"; + //internal const string Juicer_MAIN_BATCHIN7_LOC = "58"; + //internal const string Juicer_MAIN_BATCHIN8_LOC = "59"; + + internal const string COFFEE_HOLDER_LOC = "30"; + internal const string TEA_HOLDER_LOC = "51"; + public static Dictionary GOODS_TYPES = new Dictionary() { + {"1", GOODS_TYPE.COFFEE}, + {"2", GOODS_TYPE.COFFEE}, + {"3", GOODS_TYPE.COFFEE}, + {"4", GOODS_TYPE.COFFEE}, + {"5", GOODS_TYPE.COFFEE}, + {"6", GOODS_TYPE.COFFEE}, + {"7", GOODS_TYPE.COFFEE}, + {"8", GOODS_TYPE.COFFEE}, + {"9", GOODS_TYPE.COFFEE}, + {"10",GOODS_TYPE.COFFEE}, + {"11",GOODS_TYPE.COFFEE}, + {"12",GOODS_TYPE.COFFEE}, + {"13",GOODS_TYPE.COFFEE}, + {"14",GOODS_TYPE.COFFEE}, + {"15",GOODS_TYPE.COFFEE}, + {"16",GOODS_TYPE.COFFEE}, + {"17",GOODS_TYPE.COFFEE}, + {"18",GOODS_TYPE.COFFEE}, + {"19",GOODS_TYPE.COFFEE}, + {"20",GOODS_TYPE.COFFEE}, + {"21",GOODS_TYPE.COFFEE}, + {"22",GOODS_TYPE.COFFEE}, + {"23",GOODS_TYPE.COFFEE}, + {"24",GOODS_TYPE.COFFEE}, + {"25",GOODS_TYPE.COFFEE}, + { COFFEE_HOLDER_LOC,GOODS_TYPE.CUP}, + {"56",GOODS_TYPE.TEA }, + {"61",GOODS_TYPE.WATER }, + {Juicer_MAIN_BATCHIN1_LOC,GOODS_TYPE.JUICE}, + {Juicer_MAIN_BATCHIN2_LOC,GOODS_TYPE.JUICE}, + {Juicer_MAIN_BATCHIN3_LOC,GOODS_TYPE.JUICE}, + {Juicer_MAIN_BATCHIN4_LOC,GOODS_TYPE.JUICE}, + //{Juicer_MAIN_BATCHIN5_LOC,GOODS_TYPE.JUICE}, + //{Juicer_MAIN_BATCHIN6_LOC,GOODS_TYPE.JUICE}, + //{Juicer_MAIN_BATCHIN7_LOC,GOODS_TYPE.JUICE}, + //{Juicer_MAIN_BATCHIN8_LOC,GOODS_TYPE.JUICE}, + }; + + public GOODS_TYPE GoodsType { get; set; } + public BATCHING_CLASS BatchingClass { get; set; } + private string loc; + + public string Loc + { + get { return loc; } + set + { + loc = value; + if (GOODS_TYPES.ContainsKey(loc)) + GoodsType = GOODS_TYPES[loc]; + switch (loc) + { + case COFFEE_HOLDER_LOC: + case TEA_HOLDER_LOC: + BatchingClass = BATCHING_CLASS.HOLDER; + break; + default: + BatchingClass = BATCHING_CLASS.MAIN_MATERIAL; + break; + } + } + } + + internal static Dictionary BuildAll() + { + Dictionary temp = new Dictionary(); + foreach (var item in GOODS_TYPES) + { + temp.Add(item.Key, new PolymerBatching() { Loc = item.Key }); + } + return temp; + } + + //internal static IC_SE GetIceCreamSE(string loc, out string sence) + //{ + // switch (loc) + // { + // case Juicer_MAIN_BATCHIN1_LOC: + // sence = JaKaHelper.SENCE_接果汁1; + // return IC_SE.SE_1; + + // case Juicer_MAIN_BATCHIN2_LOC: + // sence = JaKaHelper.SENCE_接果汁2; + // return IC_SE.SE_2; + + // case Juicer_MAIN_BATCHIN3_LOC: + // sence = JaKaHelper.SENCE_接果汁3; + // return IC_SE.SE_3; + + // default: + // sence = JaKaHelper.SENCE_接果汁1; + // return IC_SE.SE_1; + // } + //} + } +} diff --git a/BPASmartClient.Morkt.JAKA.JC/BPASmartClient.MorkTJAKAJC.csproj b/BPASmartClient.Morkt.JAKA.JC/BPASmartClient.MorkTJAKAJC.csproj index 9a7c06f1..ef077463 100644 --- a/BPASmartClient.Morkt.JAKA.JC/BPASmartClient.MorkTJAKAJC.csproj +++ b/BPASmartClient.Morkt.JAKA.JC/BPASmartClient.MorkTJAKAJC.csproj @@ -6,4 +6,8 @@ true + + + + diff --git a/BPASmartClient.Morkt.JAKA.JC/Class1.cs b/BPASmartClient.Morkt.JAKA.JC/Class1.cs deleted file mode 100644 index bf85f49d..00000000 --- a/BPASmartClient.Morkt.JAKA.JC/Class1.cs +++ /dev/null @@ -1,8 +0,0 @@ -using System; - -namespace BPASmartClient.MorktJAKAJC -{ - public class Class1 - { - } -} diff --git a/BPASmartClient.Morkt.JAKA.JC/Control_MORKJC.cs b/BPASmartClient.Morkt.JAKA.JC/Control_MORKJC.cs new file mode 100644 index 00000000..f8ff22c1 --- /dev/null +++ b/BPASmartClient.Morkt.JAKA.JC/Control_MORKJC.cs @@ -0,0 +1,828 @@ +using System; +using System.Collections.Generic; +using System.Configuration; +using System.Linq; +using System.Threading; +using System.Collections.Concurrent; +using System.Diagnostics; +using System.Threading.Tasks; +using BPASmartClient.Device; +using BPA.Message.Enum; +using BPA.Message; +using BPASmartClient.Helper; +using BPASmartClient.Model.咖啡机.Enum; +using BPASmartClient.Model; +using BPASmartClient.EventBus; +using static BPASmartClient.EventBus.EventBus; +using BPASmartClient.Model.PLC; +using BPASmartClient.Model.单片机; + +namespace BPASmartClient.MorktJAKAJC +{ + /* + * 冰淇淋咖啡机组合套装 + * 物料位置: + * 1:冰淇料 + * 2:冰淇淋杯 + * 5:咖啡 + * 6:咖啡杯 + * 9: 茶 + * 10: 茶杯 + */ + public class Control_MORKJC : BaseDevice + { + GVL_MORKJC mORKD = new GVL_MORKJC(); + //咖啡机主控程序 + //private CoffeeMachine coffeeMachine; + ////果汁机主控程序 + //private JuicerMachine juicerMachine; + ////单片机主控程序 + //private ICChipMachine icchipMachine; + //物料存放位置 + private Dictionary batchings = new Dictionary(); + //容器位置 + private string holderLoc; + //主料位置 + private string mainMaterialLoc; + //子订单ID + private string subOrderId; + + private bool enableFunny = false; + private DateTime lastRecvdOrder = DateTime.Now; + private bool working = false; + /// + /// 果汁机做法,true:热饮,false:冷饮 + /// + private bool GuMake = false; + + private void OrderChange(string subid, ORDER_STATUS oRDER_STATUS) + { + EventBus.EventBus.GetInstance().Publish(new OrderStatusChangedEvent() { Status = oRDER_STATUS, SubOrderId = subid, deviceClientType = DeviceType }); + } + + //private SerialPortClient commProxy; + public void ConnectOk() + { + + } + ConcurrentQueue morkOrderPushes = new ConcurrentQueue(); + public void Init() + { + ActionManage.GetInstance.Register(new Action((s) => + { + if (s is DrCoffeeDrinksCode cf) + { + mainMaterialLoc = ((int)cf).ToString(); + DoCoffee(); + } + }), "SimCoffee"); + + //构建所有商品物料信息 + batchings = PolymerBatching.BuildAll(); + EventBus.EventBus.GetInstance().Subscribe(DeviceId, DRCoffee_CoffeEndCookEventHandle); + + System.Configuration.Configuration config = System.Configuration.ConfigurationManager.OpenExeConfiguration(System.Configuration.ConfigurationUserLevel.None); + //一系列外围基础配置 + var com_Coffee = config.AppSettings.Settings["COM_Coffee"].Value; + var baud_Coffee = config.AppSettings.Settings["BAUD_Coffee"].Value; + //咖啡机创建 + //coffeeMachine = new CoffeeMachine(com_Coffee, (BaudRates)Enum.Parse(typeof(BaudRates), baud_Coffee)); + Main(); + ReadData(); + ThreadManage.GetInstance().StartLong(new Action(() => + { + while (morkOrderPushes.Count > 0) + { + while (enableFunny) { Thread.Sleep(10); } + DeviceProcessLogShow("当前非自嗨模式,允许开工"); + working = true; + if (morkOrderPushes.TryDequeue(out MorkOrderPush order)) + { + DeviceProcessLogShow($"开始制作订单[{order.SortNum}]"); + + + + //商品类型 + GOODS_TYPE currentGoodsType = GOODS_TYPE.NEITHER; + //子订单ID + subOrderId = order.SuborderId; + //遍历物料 + foreach (var item in order.GoodBatchings) + { + var res = Json.Data.orderMaterialDelivery.BatchingInfo.FirstOrDefault(p => p.BatchingId == item.BatchingId); + if (res != null) + { + //获取主料和容器位置 + switch (batchings[res.BatchingLoc].BatchingClass) + { + case BATCHING_CLASS.HOLDER: + holderLoc = res.BatchingLoc; + break; + case BATCHING_CLASS.MAIN_MATERIAL: + // mainMaterialLoc ="1"; + mainMaterialLoc = res.BatchingLoc; + //验证商品是咖啡还是冰淇淋 + if (ValidateGoodsByBatching(res.BatchingLoc) != GOODS_TYPE.NEITHER) + { + //获取当前物料所属商品类型 + currentGoodsType = ValidateGoodsByBatching(res.BatchingLoc); + } + break; + } + } + } + + //根据商品类型执行具体制作流程 + switch (currentGoodsType) + { + case GOODS_TYPE.COFFEE: + DoCoffee(); + break; + case GOODS_TYPE.JUICE: + GuMake = order.MakeID == "2"; + DoJuicer(); + break; + case GOODS_TYPE.TEA: + DoTea(); + break; + case GOODS_TYPE.WATER: + DoWater(); + break; + case GOODS_TYPE.NEITHER: + DeviceProcessLogShow("未知的商品类型"); + break; + } + } + working = false; + lastRecvdOrder = DateTime.Now; + } + Thread.Sleep(1000); + }), "订单制作"); + } + + public void Main() + { + //咖啡机开启主线程 + //coffeeMachine.Start(); + //开始心跳刷新,根据咖啡机及冰淇淋机来判断 + ThreadManage.GetInstance().StartLong(new Action(() => + { + //IsHealth = + // Write.IsConnected && + // MorkCStatus.GetInstance().CanDo && + // JuicerHelper.GetInstance.IsOpen && + // MCUSerialHelper.GetInstance.IsOpen; + //GeneralConfig.Healthy = true; + Thread.Sleep(100); + }), "MORK-IC心跳刷新"); + //ThreadManage.GetInstance().Start(new Action(() => + //{ + // while (!Write.IsConnected) + // { + // Thread.Sleep(10); + // } + // //LebaiHelper.GetInstance.Scene(LebaiHelper.SENCE_欢迎); + //}), "MORK-JC欢迎"); + } + + public void DataParse(T order) + { + if (order is MorkOrderPush morkOrderPush) + { + morkOrderPushes.Enqueue(morkOrderPush); + } + } + + /// + /// 验证当前是做咖啡还是做冰淇淋 + /// + /// 物料位置 + private GOODS_TYPE ValidateGoodsByBatching(string batchingLoc) + { + if (batchings.ContainsKey(batchingLoc)) + return batchings[batchingLoc].GoodsType; + return GOODS_TYPE.NEITHER; + } + + private AutoResetEvent are = new AutoResetEvent(false); + + private T GetStatus(string key) + { + if (peripheralStatus.ContainsKey(key)) + { + if (peripheralStatus[key] != null) + { + return (T)(peripheralStatus[key]); + } + } + return default; + } + + private void Wait(int value) + { + while (!((GetStatus("Get_RobotAO1") == value) && GetStatus("GetProgramStatus") == 0))//判断文件是否已经执行结束 且 文件末端变量值==文件名 + { + Thread.Sleep(5); + } + } + int[] devStatusBy = new int[2] { 0, 0 }; + + /// + /// 传感器的输入信号 0:无意义 1:有信号 2:无信号 3:信号不正确 + /// + int bSensorInput; + /// + /// 延迟的超时时间 + /// + DateTime delayTimeOut; + /// + /// 做咖啡 + /// + private void DoCoffee() + { + #region 接咖啡流程 + are.Reset(); + // OrderChange(subOrderId, BPA.Message.Enum.ORDER_STATUS.COOKING); + OrderChange(subOrderId, BPA.Message.Enum.ORDER_STATUS.COOKING); + int resultTakeCup = takeCup(); + if (resultTakeCup == 1) + { + DeviceProcessLogShow("咖啡杯取杯完成"); + new WriteJaka() { TagName = "JaKaProgramName", Value = JakaModel.SENCE_接咖啡 }.Publish(); + // Write("JaKaProgramName",JakaModel.SENCE_接咖啡); + Wait(int.Parse(JakaModel.SENCE_接咖啡)); + new DRCoffee_MakeCoffeeEvent() { DeviceId = DeviceId, DrinkCode = (DrCoffeeDrinksCode)int.Parse(mainMaterialLoc) }.Publish(); //接咖啡控制 //DrCoffeeDrinksCode.热水 + are.WaitOne(1000 * 180); + new WriteJaka() { TagName = "JaKaProgramName", Value = JakaModel.SENCE_放咖啡杯 }.Publish(); + Wait(int.Parse(JakaModel.SENCE_放咖啡杯)); + int resultputCup = putCup(); + if (resultputCup == 1) + { + //订单状态改变:完成 + new WriteJaka() { TagName = "JaKaProgramName", Value = JakaModel.SENCE_初始位 }.Publish(); + Wait(int.Parse(JakaModel.SENCE_初始位)); + OrderChange(subOrderId, BPA.Message.Enum.ORDER_STATUS.COMPLETED_TAKE); + } + else + { + new WriteJaka() { TagName = "JaKaProgramName", Value = JakaModel.SENCE_初始位 }.Publish(); + Wait(int.Parse(JakaModel.SENCE_初始位)); + } + } + else if (resultTakeCup == 2 || resultTakeCup == 3) + { + new WriteJaka() { TagName = "JaKaProgramName", Value = JakaModel.SENCE_初始位 }.Publish(); + Wait(int.Parse(JakaModel.SENCE_初始位)); + } + #endregion + } + /// + /// 做茶 + /// + private void DoTea() + { + #region 接茶流程 + OrderChange(subOrderId, BPA.Message.Enum.ORDER_STATUS.COOKING); + int resultTakeCup = takeCup(); + if (resultTakeCup == 1) + { + DeviceProcessLogShow("取茶杯完成"); + new WriteJaka() { TagName = "JaKaProgramName", Value = JakaModel.SENCE_接茶 }.Publish(); + Wait(int.Parse(JakaModel.SENCE_接茶)); + + new WriteMcu() { TagName = "ServoControl", Address = "1", Value = 105 }.Publish(); + Thread.Sleep(1000); + new WriteMcu() { TagName = "ServoControl", Address = "1", Value = 130 }.Publish(); + Thread.Sleep(1000); + new WriteMcu() { TagName = "ServoControl", Address = "1", Value = 105 }.Publish(); + + Thread.Sleep(3000); + new WriteJaka() { TagName = "JaKaProgramName", Value = JakaModel.SENCE_接茶_接水 }.Publish(); + Wait(int.Parse(JakaModel.SENCE_接茶_接水)); + + + new WriteMcu() { TagName = "OutputControl", Value = false, Address = "4" }.Publish(); + new WriteMcu() { TagName = "OutputControl", Value = false, Address = "3" }.Publish(); + + Thread.Sleep(100); + new WriteMcu() { TagName = "OutputControl", Value = true, Address = "3" }.Publish(); + Thread.Sleep(3000); + new WriteMcu() { TagName = "OutputControl", Value = false, Address = "3" }.Publish(); + Thread.Sleep(100); + + new WriteMcu() { TagName = "OutputControl", Value = false, Address = "4" }.Publish(); + Thread.Sleep(100); + new WriteMcu() { TagName = "OutputControl", Value = true, Address = "4" }.Publish(); + Thread.Sleep(500); + new WriteMcu() { TagName = "OutputControl", Value = false, Address = "4" }.Publish(); + + Thread.Sleep(50000); + + new WriteJaka() { TagName = "JaKaProgramName", Value = JakaModel.SENCE_放茶水杯 }.Publish(); + Wait(int.Parse(JakaModel.SENCE_放茶水杯)); + int resultputCup = putCup(); + if (resultputCup == 1) + { + new WriteJaka() { TagName = "JaKaProgramName", Value = JakaModel.SENCE_初始位 }.Publish(); + Wait(int.Parse(JakaModel.SENCE_初始位)); + OrderChange(subOrderId, BPA.Message.Enum.ORDER_STATUS.COMPLETED_TAKE); + } + else + { + new WriteJaka() { TagName = "JaKaProgramName", Value = JakaModel.SENCE_初始位 }.Publish(); + Wait(int.Parse(JakaModel.SENCE_初始位)); + } + } + else if (resultTakeCup == 2 || resultTakeCup == 3) + { + new WriteJaka() { TagName = "JaKaProgramName", Value = JakaModel.SENCE_初始位 }.Publish(); + Wait(int.Parse(JakaModel.SENCE_初始位)); + } + #endregion + } + + /// + /// 接开水 + /// + private void DoWater() + { + #region 接水流程 + OrderChange(subOrderId, BPA.Message.Enum.ORDER_STATUS.COOKING); + int resultTakeCup = takeCup(); + if (resultTakeCup == 1) + { + + new WriteJaka() { TagName = "JaKaProgramName", Value = JakaModel.SENCE_接水 }.Publish(); + Wait(int.Parse(JakaModel.SENCE_接水)); + + new WriteMcu() { TagName = "OutputControl", Value = false, Address = "4" }.Publish(); + + + new WriteMcu() { TagName = "OutputControl", Value = false, Address = "3" }.Publish(); + Thread.Sleep(100); + new WriteMcu() { TagName = "OutputControl", Value = true, Address = "3" }.Publish(); + Thread.Sleep(3000); + new WriteMcu() { TagName = "OutputControl", Value = false, Address = "3" }.Publish(); + Thread.Sleep(100); + + new WriteMcu() { TagName = "OutputControl", Value = false, Address = "4" }.Publish(); + Thread.Sleep(100); + new WriteMcu() { TagName = "OutputControl", Value = true, Address = "4" }.Publish(); + Thread.Sleep(500); + new WriteMcu() { TagName = "OutputControl", Value = false, Address = "4" }.Publish(); + + Thread.Sleep(50000); + //添加控制接水机构程序 + + new WriteJaka() { TagName = "JaKaProgramName", Value = JakaModel.SENCE_放茶水杯 }.Publish(); + Wait(int.Parse(JakaModel.SENCE_放茶水杯)); + int resultputCup = putCup(); + if (resultputCup == 1) + { + new WriteJaka() { TagName = "JaKaProgramName", Value = JakaModel.SENCE_初始位 }.Publish(); + Wait(int.Parse(JakaModel.SENCE_初始位)); + OrderChange(subOrderId, BPA.Message.Enum.ORDER_STATUS.COMPLETED_TAKE); + } + else + { + new WriteJaka() { TagName = "JaKaProgramName", Value = JakaModel.SENCE_初始位 }.Publish(); + Wait(int.Parse(JakaModel.SENCE_初始位)); + } + } + else if (resultTakeCup == 2 || resultTakeCup == 3) + { + new WriteJaka() { TagName = "JaKaProgramName", Value = JakaModel.SENCE_初始位 }.Publish(); + Wait(int.Parse(JakaModel.SENCE_初始位)); + } + #endregion + } + /// + /// 果汁机控制信号 + /// + private byte JuicerNum; + /// + /// 做果汁 + /// + private void DoJuicer() + { + #region 接果汁流程 + are.Reset(); + OrderChange(subOrderId, BPA.Message.Enum.ORDER_STATUS.COOKING); + int resultTakeCup = takeCup(); + if (resultTakeCup == 1) + { + int JuicerNum1 = int.Parse(mainMaterialLoc); + switch (JuicerNum1) + { + case 52: + if (GuMake) + { + JuicerNum = 0x00; + } + else + { + JuicerNum = 0x01; + } + new WriteJaka() { TagName = "JaKaProgramName", Value = JakaModel.SENCE_接果汁1 }.Publish(); + Wait(int.Parse(JakaModel.SENCE_接果汁1)); + break; + case 53: + if (GuMake) + { + JuicerNum = 0x02; + } + else + { + JuicerNum = 0x03; + } + new WriteJaka() { TagName = "JaKaProgramName", Value = JakaModel.SENCE_接果汁2 }.Publish(); + Wait(int.Parse(JakaModel.SENCE_接果汁2)); + break; + case 54: + if (GuMake) + { + JuicerNum = 0x04; + } + else + { + JuicerNum = 0x05; + } + new WriteJaka() { TagName = "JaKaProgramName", Value = JakaModel.SENCE_接果汁3 }.Publish(); + Wait(int.Parse(JakaModel.SENCE_接果汁3)); + break; + case 55: + if (GuMake) + { + JuicerNum = 0x06; + } + else + { + JuicerNum = 0x07; + } + new WriteJaka() { TagName = "JaKaProgramName", Value = JakaModel.SENCE_接果汁4 }.Publish(); + Wait(int.Parse(JakaModel.SENCE_接果汁4)); + break; + default: + JuicerNum = 0x00; + new WriteJaka() { TagName = "JaKaProgramName", Value = JakaModel.SENCE_接果汁1 }.Publish(); + Wait(int.Parse(JakaModel.SENCE_接果汁1)); + break; + } + var devStatus = GetStatus("GetDeviceStatus"); + var devStatus1 = Convert.ToString(devStatus[0], 2); + var devStatus2 = devStatus[1]; + + if (devStatus1.IndexOf("0") == 1 && devStatus2 == 0) + { + if (sensor_Sign(1) == 1) + { + new WriteJuicer() { Value = JuicerNum }.Publish(); + } + Thread.Sleep(100); + devStatusBy = GetStatus("GetDeviceStatus"); + while (!(devStatusBy[1] == 0)) + { + Thread.Sleep(100); + devStatusBy = GetStatus("GetDeviceStatus"); + while (devStatusBy.Length != 2) + { + Thread.Sleep(100); + devStatusBy = GetStatus("GetDeviceStatus"); + } + } + devStatusBy = GetStatus("GetDeviceStatus"); + Thread.Sleep(5000); + switch (JuicerNum1) + { + case 52: + new WriteJaka() { TagName = "JaKaProgramName", Value = JakaModel.SENCE_放果汁杯1 }.Publish(); + Wait(int.Parse(JakaModel.SENCE_放果汁杯1)); + break; + case 53: + new WriteJaka() { TagName = "JaKaProgramName", Value = JakaModel.SENCE_放果汁杯2 }.Publish(); + Wait(int.Parse(JakaModel.SENCE_放果汁杯2)); + break; + case 54: + new WriteJaka() { TagName = "JaKaProgramName", Value = JakaModel.SENCE_放果汁杯3 }.Publish(); + Wait(int.Parse(JakaModel.SENCE_放果汁杯3)); + break; + case 55: + new WriteJaka() { TagName = "JaKaProgramName", Value = JakaModel.SENCE_放果汁杯4 }.Publish(); + Wait(int.Parse(JakaModel.SENCE_放果汁杯4)); + break; + default: + new WriteJaka() { TagName = "JaKaProgramName", Value = JakaModel.SENCE_放果汁杯1 }.Publish(); + Wait(int.Parse(JakaModel.SENCE_放果汁杯1)); + break; + } + int resultputCup = putCup(); + if (resultputCup == 1) + { + new WriteJaka() { TagName = "JaKaProgramName", Value = JakaModel.SENCE_初始位 }.Publish(); + Wait(int.Parse(JakaModel.SENCE_初始位)); + OrderChange(subOrderId, BPA.Message.Enum.ORDER_STATUS.COMPLETED_TAKE); + } + else + { + new WriteJaka() { TagName = "JaKaProgramName", Value = JakaModel.SENCE_初始位 }.Publish(); + Wait(int.Parse(JakaModel.SENCE_初始位)); + } + } + else + { + switch (JuicerNum1) + { + case 52: + new WriteJaka() { TagName = "JaKaProgramName", Value = JakaModel.SENCE_放果汁杯1 }.Publish(); + Wait(int.Parse(JakaModel.SENCE_放果汁杯1)); + break; + case 53: + new WriteJaka() { TagName = "JaKaProgramName", Value = JakaModel.SENCE_放果汁杯2 }.Publish(); + Wait(int.Parse(JakaModel.SENCE_放果汁杯2)); + break; + case 54: + new WriteJaka() { TagName = "JaKaProgramName", Value = JakaModel.SENCE_放果汁杯3 }.Publish(); + Wait(int.Parse(JakaModel.SENCE_放果汁杯3)); + break; + case 55: + new WriteJaka() { TagName = "JaKaProgramName", Value = JakaModel.SENCE_放果汁杯4 }.Publish(); + Wait(int.Parse(JakaModel.SENCE_放果汁杯4)); + break; + default: + new WriteJaka() { TagName = "JaKaProgramName", Value = JakaModel.SENCE_放果汁杯1 }.Publish(); + Wait(int.Parse(JakaModel.SENCE_放果汁杯1)); + break; + } + int resultputCup = putCup(); + if (resultputCup == 1) + { + new WriteJaka() { TagName = "JaKaProgramName", Value = JakaModel.SENCE_初始位 }.Publish(); + Wait(int.Parse(JakaModel.SENCE_初始位)); + OrderChange(subOrderId, BPA.Message.Enum.ORDER_STATUS.COMPLETED_TAKE); + } + else + { + new WriteJaka() { TagName = "JaKaProgramName", Value = JakaModel.SENCE_初始位 }.Publish(); + Wait(int.Parse(JakaModel.SENCE_初始位)); + } + } + } + else if (resultTakeCup == 2 || resultTakeCup == 3) + { + new WriteJaka() { TagName = "JaKaProgramName", Value = JakaModel.SENCE_初始位 }.Publish(); + Wait(int.Parse(JakaModel.SENCE_初始位)); + } + #endregion + } + private int getCup_cnt; + /// + /// 取杯流程 + /// + /// 0:无意义,1:取杯成功 2:机构有杯子,取杯失败 3:机构没有杯子 + private int takeCup() + { + try + { + getCup_cnt = 0;//取杯次数复位 + new WriteJaka() { TagName = "Set_RobotAO1", Value = 0 }.Publish(); + Wait(0); + new WriteJaka() { TagName = "JaKaProgramName", Value = JakaModel.SENCE_初始位 }.Publish(); + Wait(int.Parse(JakaModel.SENCE_初始位)); + new WriteMcu() { TagName = "OutputControl", Address = "1", Value = true }.Publish(); + Thread.Sleep(10); + new WriteMcu() { TagName = "OutputControl", Address = "1", Value = true }.Publish(); + new WriteJaka() { TagName = "Set_RobotAO1", Value = 0 }.Publish(); + Wait(0); + new WriteJaka() { TagName = "JaKaProgramName", Value = JakaModel.SENCE_取杯 }.Publish(); + Wait(int.Parse(JakaModel.SENCE_取杯)); + bSensorInput = sensor_Sign(1); + if (bSensorInput == 2) + { + Thread.Sleep(100); + new WriteMcu() { TagName = "OutputControl", Address = "1", Value = false }.Publish(); + new WriteMcu() { TagName = "OutputControl", Address = "1", Value = false }.Publish(); + Thread.Sleep(100); + new WriteJaka() { TagName = "JaKaProgramName", Value = JakaModel.SENCE_取杯检测 }.Publish(); + Wait(int.Parse(JakaModel.SENCE_取杯检测)); + DeviceProcessLogShow("落杯器没有纸杯了"); + return 3; + } + if (bSensorInput == 1) + { + Thread.Sleep(100); + new WriteMcu() { TagName = "OutputControl", Address = "1", Value = false }.Publish(); + new WriteMcu() { TagName = "OutputControl", Address = "1", Value = false }.Publish(); + Thread.Sleep(100); + new WriteJaka() { TagName = "JaKaProgramName", Value = JakaModel.SENCE_取杯检测 }.Publish(); + Wait(int.Parse(JakaModel.SENCE_取杯检测)); + bSensorInput = sensor_Sign(1); + /*delayTimeOut = DateTime.Now; + bSensorInput = sensor_Sign(1); + while (bSensorInput == 3) + { + Thread.Sleep(100); + bSensorInput = sensor_Sign(1); + }*/ + while (getCup_cnt < 4 && (bSensorInput == 2 || bSensorInput == 3)) + { + DeviceProcessLogShow($"第{getCup_cnt}次取杯失败"); + Thread.Sleep(100); + new WriteMcu() { TagName = "OutputControl", Address = "1", Value = true }.Publish(); + new WriteMcu() { TagName = "OutputControl", Address = "1", Value = true }.Publish(); + Thread.Sleep(100); + new WriteJaka() { TagName = "JaKaProgramName", Value = JakaModel.SENCE_取杯 }.Publish(); + Wait(int.Parse(JakaModel.SENCE_取杯)); + getCup_cnt = getCup_cnt + 1; + Thread.Sleep(100); + new WriteMcu() { TagName = "OutputControl", Address = "1", Value = false }.Publish(); + new WriteMcu() { TagName = "OutputControl", Address = "1", Value = false }.Publish(); + Thread.Sleep(100); + new WriteJaka() { TagName = "JaKaProgramName", Value = JakaModel.SENCE_取杯检测 }.Publish(); + Wait(int.Parse(JakaModel.SENCE_取杯检测)); + bSensorInput = sensor_Sign(1); + } + if (bSensorInput == 1) + { + return 1; + } + else + { + return 2; + } + } + return 1; + } + catch (Exception ex) + { + DeviceProcessLogShow(ex.ToString()); + return 0; + } + } + /// + /// 放杯 + /// + /// 0:无意义 1:执行成功 2:执行失败(传感器还有信号) + private int putCup() + { + try + { + while (checkCup() == 2) + { + Thread.Sleep(100); + } + new WriteJaka() { TagName = "JaKaProgramName", Value = JakaModel.SENCE_放杯 }.Publish(); + Wait(int.Parse(JakaModel.SENCE_放杯)); + new WriteMcu() { TagName = "OutputControl", Address = "1", Value = true }.Publish(); + Thread.Sleep(10); + new WriteMcu() { TagName = "OutputControl", Address = "1", Value = true }.Publish(); + Thread.Sleep(10); + new WriteJaka() { TagName = "JaKaProgramName", Value = JakaModel.SENCE_放杯检测 }.Publish(); + Wait(int.Parse(JakaModel.SENCE_放杯检测)); + bSensorInput = sensor_Sign(2); + delayTimeOut = DateTime.Now; + while (bSensorInput == 2) + { + Thread.Sleep(100); + bSensorInput = sensor_Sign(2); + if (DateTime.Now.Subtract(delayTimeOut).TotalSeconds >= 2) return 2; + } + if (bSensorInput == 2) + { + DeviceProcessLogShow("放杯失败传感器没有信号"); + new WriteJaka() { TagName = "JaKaProgramName", Value = JakaModel.SENCE_初始位 }.Publish(); + Wait(int.Parse(JakaModel.SENCE_初始位)); + return 1; + } + return 1; + } + catch (Exception ex) + { + DeviceProcessLogShow(ex.ToString()); + return 0; + } + } + private int cnt_Check; + + public override DeviceClientType DeviceType => throw new NotImplementedException(); + + /// + /// 检测放杯位,是否有杯子 + /// + /// 0:无意义 1:没有杯子 2:有杯子 + private int checkCup() + { + try + { + //cnt_Check = 0; + bSensorInput = sensor_Sign(2); + if (bSensorInput == 2) + { + DeviceProcessLogShow($"放杯位传感器没有信号:{cnt_Check}"); + return 1; + } + else if (bSensorInput == 1) + { + DeviceProcessLogShow($"放杯位传感器有信号:{cnt_Check}"); + return 2; + } + return 2; + } + catch (Exception ex) + { + DeviceProcessLogShow(ex.ToString()); + return 0; + } + } + + private T McuRead(string tagName, object par) + { + new ReadMcu() { DeviceId = DeviceId, TagName = tagName, ReadPar = par }; + if (peripheralStatus.ContainsKey(tagName)) + { + if (peripheralStatus[tagName] != null) + { + return (T)peripheralStatus[tagName]; + } + } + return default; + } + + + + /// + /// 传感器防抖0.2s内检测20次, + /// + /// + /// + private int sensor_Sign(byte num) + { + DeviceProcessLogShow($"开始检测{num}号传感器信号"); + int cnt = 0; + cnt_Check = 0; + while (true) + { + Thread.Sleep(10); + bSensorInput = McuRead("GetInputStatus", num); + if (bSensorInput == 1) + { + cnt_Check = cnt_Check + 1; + cnt = cnt + 1; + } + else if (bSensorInput == 2) + { + cnt_Check = cnt_Check - 1; + cnt = cnt + 1; + } + if (cnt >= 20) + { + break; + } + + } + if (cnt_Check >= 0) + { + DeviceProcessLogShow($"{num}传感器有信号:{cnt_Check}"); + return 1; + } + else + { + DeviceProcessLogShow($"{num}传感器没有信号:{cnt_Check}"); + return 2; + } + } + private void DRCoffee_CoffeEndCookEventHandle(IEvent @event, EventCallBackHandle callBack) + { + are.Set(); + } + + public void SimOrder(T simOrder) + { + + } + + public override void DoMain() + { + + } + + public override void Stop() + { + + } + + public override void ReadData() + { + + } + + public override void MainTask() + { + + } + + public override void ResetProgram() + { + + } + } +} diff --git a/BPASmartClient.Morkt.JAKA.JC/GVL_MORKJC.cs b/BPASmartClient.Morkt.JAKA.JC/GVL_MORKJC.cs new file mode 100644 index 00000000..c12d4f3c --- /dev/null +++ b/BPASmartClient.Morkt.JAKA.JC/GVL_MORKJC.cs @@ -0,0 +1,8 @@ +using BPASmartClient.Device; + +namespace BPASmartClient.MorktJAKAJC +{ + public class GVL_MORKJC : IStatus + { + } +} diff --git a/BPASmartClient.Morkt.JAKA.JC/PolymerBatching.cs b/BPASmartClient.Morkt.JAKA.JC/PolymerBatching.cs new file mode 100644 index 00000000..68de4338 --- /dev/null +++ b/BPASmartClient.Morkt.JAKA.JC/PolymerBatching.cs @@ -0,0 +1,152 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace BPASmartClient.MorktJAKAJC +{ + internal enum GOODS_TYPE + { + /// + /// 未知 + /// + NEITHER, + /// + /// 咖啡 + /// + COFFEE, + /// + /// 果汁 + /// + JUICE, + /// + /// 茶水 + /// + TEA, + /// + /// 水 + /// + WATER, + /// + /// 杯子 + /// + CUP + } + + internal enum BATCHING_CLASS + { + HOLDER, + MAIN_MATERIAL, + } + + internal class PolymerBatching + { + internal const string Juicer_MAIN_BATCHIN1_LOC = "52"; + internal const string Juicer_MAIN_BATCHIN2_LOC = "53"; + internal const string Juicer_MAIN_BATCHIN3_LOC = "54"; + internal const string Juicer_MAIN_BATCHIN4_LOC = "55"; + //internal const string Juicer_MAIN_BATCHIN5_LOC = "56"; + //internal const string Juicer_MAIN_BATCHIN6_LOC = "57"; + //internal const string Juicer_MAIN_BATCHIN7_LOC = "58"; + //internal const string Juicer_MAIN_BATCHIN8_LOC = "59"; + + internal const string COFFEE_HOLDER_LOC = "30"; + internal const string TEA_HOLDER_LOC = "51"; + public static Dictionary GOODS_TYPES = new Dictionary() { + {"1", GOODS_TYPE.COFFEE}, + {"2", GOODS_TYPE.COFFEE}, + {"3", GOODS_TYPE.COFFEE}, + {"4", GOODS_TYPE.COFFEE}, + {"5", GOODS_TYPE.COFFEE}, + {"6", GOODS_TYPE.COFFEE}, + {"7", GOODS_TYPE.COFFEE}, + {"8", GOODS_TYPE.COFFEE}, + {"9", GOODS_TYPE.COFFEE}, + {"10",GOODS_TYPE.COFFEE}, + {"11",GOODS_TYPE.COFFEE}, + {"12",GOODS_TYPE.COFFEE}, + {"13",GOODS_TYPE.COFFEE}, + {"14",GOODS_TYPE.COFFEE}, + {"15",GOODS_TYPE.COFFEE}, + {"16",GOODS_TYPE.COFFEE}, + {"17",GOODS_TYPE.COFFEE}, + {"18",GOODS_TYPE.COFFEE}, + {"19",GOODS_TYPE.COFFEE}, + {"20",GOODS_TYPE.COFFEE}, + {"21",GOODS_TYPE.COFFEE}, + {"22",GOODS_TYPE.COFFEE}, + {"23",GOODS_TYPE.COFFEE}, + {"24",GOODS_TYPE.COFFEE}, + {"25",GOODS_TYPE.COFFEE}, + { COFFEE_HOLDER_LOC,GOODS_TYPE.CUP}, + {"56",GOODS_TYPE.TEA }, + {Juicer_MAIN_BATCHIN1_LOC,GOODS_TYPE.JUICE}, + {Juicer_MAIN_BATCHIN2_LOC,GOODS_TYPE.JUICE}, + {Juicer_MAIN_BATCHIN3_LOC,GOODS_TYPE.JUICE}, + {Juicer_MAIN_BATCHIN4_LOC,GOODS_TYPE.JUICE}, + {"61",GOODS_TYPE.WATER}, + //{Juicer_MAIN_BATCHIN5_LOC,GOODS_TYPE.JUICE}, + //{Juicer_MAIN_BATCHIN6_LOC,GOODS_TYPE.JUICE}, + //{Juicer_MAIN_BATCHIN7_LOC,GOODS_TYPE.JUICE}, + //{Juicer_MAIN_BATCHIN8_LOC,GOODS_TYPE.JUICE}, + }; + + public GOODS_TYPE GoodsType { get; set; } + public BATCHING_CLASS BatchingClass { get; set; } + private string loc; + + public string Loc + { + get { return loc; } + set + { + loc = value; + if (GOODS_TYPES.ContainsKey(loc)) + GoodsType = GOODS_TYPES[loc]; + switch (loc) + { + case COFFEE_HOLDER_LOC: + case TEA_HOLDER_LOC: + BatchingClass = BATCHING_CLASS.HOLDER; + break; + default: + BatchingClass = BATCHING_CLASS.MAIN_MATERIAL; + break; + } + } + } + + internal static Dictionary BuildAll() + { + Dictionary temp = new Dictionary(); + foreach (var item in GOODS_TYPES) + { + temp.Add(item.Key, new PolymerBatching() { Loc = item.Key }); + } + return temp; + } + + //internal static IC_SE GetIceCreamSE(string loc, out string sence) + //{ + // switch (loc) + // { + // case Juicer_MAIN_BATCHIN1_LOC: + // sence = JaKaHelper.SENCE_接果汁1; + // return IC_SE.SE_1; + + // case Juicer_MAIN_BATCHIN2_LOC: + // sence = JaKaHelper.SENCE_接果汁2; + // return IC_SE.SE_2; + + // case Juicer_MAIN_BATCHIN3_LOC: + // sence = JaKaHelper.SENCE_接果汁3; + // return IC_SE.SE_3; + + // default: + // sence = JaKaHelper.SENCE_接果汁1; + // return IC_SE.SE_1; + // } + //} + } +} diff --git a/BPASmartClient.Peripheral/BasePeripheral.cs b/BPASmartClient.Peripheral/BasePeripheral.cs index 96664eb5..f07e6af0 100644 --- a/BPASmartClient.Peripheral/BasePeripheral.cs +++ b/BPASmartClient.Peripheral/BasePeripheral.cs @@ -47,12 +47,22 @@ namespace BPASmartClient.Peripheral return null; } + public void SetStatus(string statusName, object value) + { + if (status.ContainsKey(statusName)) + status[statusName] = value; + else + status.TryAdd(statusName, value); + } + public abstract void Start(); public abstract void Stop(); public abstract void Init(); + //public abstract void ReadData(string address); + public abstract void WriteData(string address, object value); public ConcurrentDictionary GetAllStatus() diff --git a/BPASmartClient.Peripheral/IPeripheral.cs b/BPASmartClient.Peripheral/IPeripheral.cs index 7aaa611c..2a3e6d41 100644 --- a/BPASmartClient.Peripheral/IPeripheral.cs +++ b/BPASmartClient.Peripheral/IPeripheral.cs @@ -55,6 +55,8 @@ namespace BPASmartClient.Peripheral void WriteData(string address, object value); + //void ReadData(string address); + /// /// 初始化 /// diff --git a/BPASmartClient.SCChip/Protocal/IC_CMD.cs b/BPASmartClient.SCChip/Protocal/IC_CMD.cs index 41523526..a4e029e0 100644 --- a/BPASmartClient.SCChip/Protocal/IC_CMD.cs +++ b/BPASmartClient.SCChip/Protocal/IC_CMD.cs @@ -39,5 +39,6 @@ namespace BPASmartClient.SCChip /// 检测物品距离 /// ARTICLE_DIST = 0x06 + } } diff --git a/BPASmartClient.SerialPort/JuicerHelper.cs b/BPASmartClient.SerialPort/JuicerHelper.cs new file mode 100644 index 00000000..4a3b5589 --- /dev/null +++ b/BPASmartClient.SerialPort/JuicerHelper.cs @@ -0,0 +1,113 @@ +using BPASmartClient.Helper; +using BPASmartClient.Message; +using System; +using System.Collections.Concurrent; +using System.Collections.Generic; +using System.IO.Ports; +using System.Linq; +using System.Text; +using System.Threading; +using System.Threading.Tasks; + +namespace BPASmartClient.SerialPort +{ + public class JuicerHelper + { + + //private volatile static JuicerHelper _Instance; + //public static JuicerHelper GetInstance => _Instance ?? (_Instance = new JuicerHelper()); + //private JuicerHelper() { } + + private System.IO.Ports.SerialPort comPort = new System.IO.Ports.SerialPort(); + ConcurrentQueue SerialMessages = new ConcurrentQueue(); + public bool IsOpen => comPort.IsOpen; + + public bool Open(string portName, int baudRate) + { + while (!System.IO.Ports.SerialPort.GetPortNames().Contains(portName)) + { + Thread.Sleep(1000); + } + while (!comPort.IsOpen) + { + comPort.PortName = portName; + comPort.BaudRate = baudRate; + comPort.DataBits = 8; + comPort.Parity = Parity.None; + comPort.StopBits = StopBits.One; + comPort.ReadTimeout = 1000; + comPort.WriteTimeout = 1000; + //comPort.DataReceived += ComPort_DataReceived; + comPort.RtsEnable = true; + try + { + comPort.Open(); + } + catch (Exception ex) + { + MessageLog.GetInstance.ShowEx(ex.ToString()); + Thread.Sleep(5000); + } + } + MessageLog.GetInstance.Show($"{portName} 串口打开成功"); + return comPort.IsOpen; + } + + /// + /// 开始制作 + /// + /// + /// + public bool StartCook(byte aisle) + { + byte sum = (byte)(0x21 + aisle); + byte checksum = (byte)~sum; + checksum++; + byte[] buffers = new byte[6] { 0x7E, 0x03, 0x00, 0x21, aisle, checksum }; + + if (comPort.IsOpen) + { + comPort.Write(buffers, 0, buffers.Length); + while (comPort.BytesToRead < 6) + { + Thread.Sleep(1); + } + byte[] receive = new byte[comPort.BytesToRead]; + comPort.Read(receive, 0, receive.Length); + if (receive.Length == 6) + return receive[4] == 1; + } + return false; + } + + /// + /// 获取果汁机状态 + /// + /// + /// + public int[] GetDeviceStatus() + { + List res = new List(); + byte[] buffers = new byte[5] { 0x7E, 0x02, 0x00, 0x13, 0xED }; + if (comPort.IsOpen) + { + comPort.Write(buffers, 0, buffers.Length); + DateTime newDate = DateTime.Now; + while (comPort.BytesToRead < 33) + { + Thread.Sleep(1); + if (DateTime.Now.Subtract(newDate).TotalSeconds >= 2) break; + } + byte[] receive = new byte[comPort.BytesToRead]; + comPort.Read(receive, 0, receive.Length); + if (receive.Length == 33) + { + res.Add(receive.Skip(24).Take(4).ToArray().BytesToInt()); + res.Add(receive.Skip(28).Take(4).ToArray().BytesToInt()); + } + return res.ToArray(); + } + return default; + } + } +} diff --git a/BPASmartClient.SerialPort/MCUSerialHelper.cs b/BPASmartClient.SerialPort/MCUSerialHelper.cs new file mode 100644 index 00000000..135e40c6 --- /dev/null +++ b/BPASmartClient.SerialPort/MCUSerialHelper.cs @@ -0,0 +1,140 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.IO; +using System.IO.Ports; +using System.Threading; +using System.Collections.Concurrent; +using BPASmartClient.Message; + +namespace BPASmartClient.SerialPort +{ + public class MCUSerialHelper + { + + //private volatile static MCUSerialHelper _Instance; + //public static MCUSerialHelper GetInstance => _Instance ?? (_Instance = new MCUSerialHelper()); + //private MCUSerialHelper() { } + + private System.IO.Ports.SerialPort comPort = new System.IO.Ports.SerialPort(); + public bool IsOpen => comPort.IsOpen; + + public bool Open(string portName, int baudRate) + { + while (!System.IO.Ports.SerialPort.GetPortNames().Contains(portName)) + { + Thread.Sleep(1000); + } + while (!comPort.IsOpen) + { + comPort.PortName = portName; + comPort.BaudRate = baudRate; + comPort.DataBits = 8; + comPort.Parity = Parity.None; + comPort.StopBits = StopBits.One; + comPort.ReadTimeout = 1000; + comPort.WriteTimeout = 1000; + //comPort.RtsEnable = true; //设置为 true后会读取不到数据 + //comPort.DtrEnable = true;//获取或设置一个值,该值在串行通信过程中启用数据终端就绪 (DTR) 信号。 + //comPort.RtsEnable = true;//获取或设置一个值,该值指示在串行通信中是否启用请求发送 (RTS) 信号 + try + { + comPort.Open(); + } + catch (Exception ex) + { + MessageLog.GetInstance.ShowEx(ex.ToString()); + Thread.Sleep(5000); + } + } + MessageLog.GetInstance.Show($"{portName} 串口打开成功"); + return comPort.IsOpen; + } + + private static readonly object OutPutLock = new object(); + /// + /// 单片机输出端口控制 + /// + /// 通道号 1 - 8 + /// 控制值 + public void OutputControl(byte index, bool value) + { + lock (OutPutLock) + { + byte NumValue = (byte)(value ? 0x01 : 0x00); + byte[] buffers = new byte[6] { 0xCC, 0x01, 0x01, index, NumValue, 0xDD }; + if (IsOpen) comPort.Write(buffers, 0, buffers.Length); + } + } + + /// + /// 舵机控制 + /// + /// 通道号 1 - 8 + /// 舵机位置 0 - 180 + public void ServoControl(byte index, byte value) + { + byte[] buffers = new byte[6] { 0xCC, 0x01, 0x02, index, value, 0xDD }; + if (IsOpen) comPort.Write(buffers, 0, buffers.Length); + } + + /// + /// 获取单片机输入端口状态 + /// + /// + /// 0:无意义 1:有信号 2:无信号 3:信号不正确 + public int GetInputStatus(byte index) + { + if (index <= 0 || index > 8) return 0; + byte[] buffers = new byte[6] { 0xCC, 0x01, 0x03, index, 0x00, 0xDD }; + if (IsOpen) + { + comPort.Write(buffers, 0, buffers.Length); + DateTime dt = DateTime.Now; + List receive = new List(); + while (true) + { + byte[] re = new byte[comPort.BytesToRead]; + comPort.Read(re, 0, re.Length); + if (re.Contains(0xcc) && re.Contains(0xDD)) receive.AddRange(re); + comPort.DiscardInBuffer(); + if (receive.Contains(0xcc) && receive.Contains(0xdd)) break; + if (DateTime.Now.Subtract(dt).TotalSeconds >= 2) break; + Thread.Sleep(1); + } + if (receive != null) + { + int Reindex = Array.FindIndex(receive.ToArray(), p => p == 0xcc); + if (Reindex < receive.Count && Reindex >= 0) + { + var res = receive.GetRange(Array.FindIndex(receive.ToArray(), p => p == 0xcc), 6); + if (res.ElementAt(2) == 0x03) + { + if (res != null && res.Count() == 6 && res.ElementAt(4) == 0x01) + { + return 1; + } + else if (res != null && res.Count() == 6 && res.ElementAt(4) == 0x00) + { + return 2; + } + + } + else + { + return 3; + } + + } + else + { + return 0; + } + } + } + return 0; + } + } +} diff --git a/SmartClient.sln b/SmartClient.sln index 58907647..724fab52 100644 --- a/SmartClient.sln +++ b/SmartClient.sln @@ -78,11 +78,19 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BPASmartClient.MorkF", "BPA EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BPASmartClient.LebaiRobot", "BPASmartClient.LebaiRobot\BPASmartClient.LebaiRobot.csproj", "{D40C3CC7-C07C-4882-93D3-7F9ABCD3B5F0}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BPASmartClient.MorkM", "BPASmartClient.MorkM\BPASmartClient.MorkM.csproj", "{74DB1F85-9B73-4113-8FE4-A63754BC7DF9}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BPASmartClient.MorkM", "BPASmartClient.MorkM\BPASmartClient.MorkM.csproj", "{74DB1F85-9B73-4113-8FE4-A63754BC7DF9}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BPASmartClient.MorkTLebaiJC", "BPASmartClient.MorkT.Lebai.JC\BPASmartClient.MorkTLebaiJC.csproj", "{0A06C9E5-5C42-4BCE-B6E6-D8054C72255D}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BPASmartClient.MorkTLebaiJC", "BPASmartClient.MorkT.Lebai.JC\BPASmartClient.MorkTLebaiJC.csproj", "{0A06C9E5-5C42-4BCE-B6E6-D8054C72255D}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BPASmartClient.MorkTJAKAJC", "BPASmartClient.Morkt.JAKA.JC\BPASmartClient.MorkTJAKAJC.csproj", "{6B0FD858-A60D-41B9-A923-358B0CE2A254}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BPASmartClient.MorkTJAKAJC", "BPASmartClient.Morkt.JAKA.JC\BPASmartClient.MorkTJAKAJC.csproj", "{6B0FD858-A60D-41B9-A923-358B0CE2A254}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BPASmartClient.MCU", "BPASmartClient.MCU\BPASmartClient.MCU.csproj", "{1C7E17B3-40E0-44ED-B8E0-C52D824604DB}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BPASmartClient.JakaRobot", "BPASmartClient.JakaRobot\BPASmartClient.JakaRobot.csproj", "{1055EA6E-6C10-4A0D-A053-85871AF8D7A9}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BPASmartClient.JAKA", "BPASmartClient.JAKA\BPASmartClient.JAKA.csproj", "{C935435D-6182-4A01-8E59-B832B2FF0D72}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BPASmartClient.Juicer", "BPASmartClient.Juicer\BPASmartClient.Juicer.csproj", "{C28A88B1-E449-484C-AC67-B5038FF2CA79}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -738,6 +746,86 @@ Global {6B0FD858-A60D-41B9-A923-358B0CE2A254}.Release|x64.Build.0 = Release|Any CPU {6B0FD858-A60D-41B9-A923-358B0CE2A254}.Release|x86.ActiveCfg = Release|Any CPU {6B0FD858-A60D-41B9-A923-358B0CE2A254}.Release|x86.Build.0 = Release|Any CPU + {1C7E17B3-40E0-44ED-B8E0-C52D824604DB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {1C7E17B3-40E0-44ED-B8E0-C52D824604DB}.Debug|Any CPU.Build.0 = Debug|Any CPU + {1C7E17B3-40E0-44ED-B8E0-C52D824604DB}.Debug|ARM.ActiveCfg = Debug|Any CPU + {1C7E17B3-40E0-44ED-B8E0-C52D824604DB}.Debug|ARM.Build.0 = Debug|Any CPU + {1C7E17B3-40E0-44ED-B8E0-C52D824604DB}.Debug|ARM64.ActiveCfg = Debug|Any CPU + {1C7E17B3-40E0-44ED-B8E0-C52D824604DB}.Debug|ARM64.Build.0 = Debug|Any CPU + {1C7E17B3-40E0-44ED-B8E0-C52D824604DB}.Debug|x64.ActiveCfg = Debug|Any CPU + {1C7E17B3-40E0-44ED-B8E0-C52D824604DB}.Debug|x64.Build.0 = Debug|Any CPU + {1C7E17B3-40E0-44ED-B8E0-C52D824604DB}.Debug|x86.ActiveCfg = Debug|Any CPU + {1C7E17B3-40E0-44ED-B8E0-C52D824604DB}.Debug|x86.Build.0 = Debug|Any CPU + {1C7E17B3-40E0-44ED-B8E0-C52D824604DB}.Release|Any CPU.ActiveCfg = Release|Any CPU + {1C7E17B3-40E0-44ED-B8E0-C52D824604DB}.Release|Any CPU.Build.0 = Release|Any CPU + {1C7E17B3-40E0-44ED-B8E0-C52D824604DB}.Release|ARM.ActiveCfg = Release|Any CPU + {1C7E17B3-40E0-44ED-B8E0-C52D824604DB}.Release|ARM.Build.0 = Release|Any CPU + {1C7E17B3-40E0-44ED-B8E0-C52D824604DB}.Release|ARM64.ActiveCfg = Release|Any CPU + {1C7E17B3-40E0-44ED-B8E0-C52D824604DB}.Release|ARM64.Build.0 = Release|Any CPU + {1C7E17B3-40E0-44ED-B8E0-C52D824604DB}.Release|x64.ActiveCfg = Release|Any CPU + {1C7E17B3-40E0-44ED-B8E0-C52D824604DB}.Release|x64.Build.0 = Release|Any CPU + {1C7E17B3-40E0-44ED-B8E0-C52D824604DB}.Release|x86.ActiveCfg = Release|Any CPU + {1C7E17B3-40E0-44ED-B8E0-C52D824604DB}.Release|x86.Build.0 = Release|Any CPU + {1055EA6E-6C10-4A0D-A053-85871AF8D7A9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {1055EA6E-6C10-4A0D-A053-85871AF8D7A9}.Debug|Any CPU.Build.0 = Debug|Any CPU + {1055EA6E-6C10-4A0D-A053-85871AF8D7A9}.Debug|ARM.ActiveCfg = Debug|Any CPU + {1055EA6E-6C10-4A0D-A053-85871AF8D7A9}.Debug|ARM.Build.0 = Debug|Any CPU + {1055EA6E-6C10-4A0D-A053-85871AF8D7A9}.Debug|ARM64.ActiveCfg = Debug|Any CPU + {1055EA6E-6C10-4A0D-A053-85871AF8D7A9}.Debug|ARM64.Build.0 = Debug|Any CPU + {1055EA6E-6C10-4A0D-A053-85871AF8D7A9}.Debug|x64.ActiveCfg = Debug|Any CPU + {1055EA6E-6C10-4A0D-A053-85871AF8D7A9}.Debug|x64.Build.0 = Debug|Any CPU + {1055EA6E-6C10-4A0D-A053-85871AF8D7A9}.Debug|x86.ActiveCfg = Debug|Any CPU + {1055EA6E-6C10-4A0D-A053-85871AF8D7A9}.Debug|x86.Build.0 = Debug|Any CPU + {1055EA6E-6C10-4A0D-A053-85871AF8D7A9}.Release|Any CPU.ActiveCfg = Release|Any CPU + {1055EA6E-6C10-4A0D-A053-85871AF8D7A9}.Release|Any CPU.Build.0 = Release|Any CPU + {1055EA6E-6C10-4A0D-A053-85871AF8D7A9}.Release|ARM.ActiveCfg = Release|Any CPU + {1055EA6E-6C10-4A0D-A053-85871AF8D7A9}.Release|ARM.Build.0 = Release|Any CPU + {1055EA6E-6C10-4A0D-A053-85871AF8D7A9}.Release|ARM64.ActiveCfg = Release|Any CPU + {1055EA6E-6C10-4A0D-A053-85871AF8D7A9}.Release|ARM64.Build.0 = Release|Any CPU + {1055EA6E-6C10-4A0D-A053-85871AF8D7A9}.Release|x64.ActiveCfg = Release|Any CPU + {1055EA6E-6C10-4A0D-A053-85871AF8D7A9}.Release|x64.Build.0 = Release|Any CPU + {1055EA6E-6C10-4A0D-A053-85871AF8D7A9}.Release|x86.ActiveCfg = Release|Any CPU + {1055EA6E-6C10-4A0D-A053-85871AF8D7A9}.Release|x86.Build.0 = Release|Any CPU + {C935435D-6182-4A01-8E59-B832B2FF0D72}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {C935435D-6182-4A01-8E59-B832B2FF0D72}.Debug|Any CPU.Build.0 = Debug|Any CPU + {C935435D-6182-4A01-8E59-B832B2FF0D72}.Debug|ARM.ActiveCfg = Debug|Any CPU + {C935435D-6182-4A01-8E59-B832B2FF0D72}.Debug|ARM.Build.0 = Debug|Any CPU + {C935435D-6182-4A01-8E59-B832B2FF0D72}.Debug|ARM64.ActiveCfg = Debug|Any CPU + {C935435D-6182-4A01-8E59-B832B2FF0D72}.Debug|ARM64.Build.0 = Debug|Any CPU + {C935435D-6182-4A01-8E59-B832B2FF0D72}.Debug|x64.ActiveCfg = Debug|Any CPU + {C935435D-6182-4A01-8E59-B832B2FF0D72}.Debug|x64.Build.0 = Debug|Any CPU + {C935435D-6182-4A01-8E59-B832B2FF0D72}.Debug|x86.ActiveCfg = Debug|Any CPU + {C935435D-6182-4A01-8E59-B832B2FF0D72}.Debug|x86.Build.0 = Debug|Any CPU + {C935435D-6182-4A01-8E59-B832B2FF0D72}.Release|Any CPU.ActiveCfg = Release|Any CPU + {C935435D-6182-4A01-8E59-B832B2FF0D72}.Release|Any CPU.Build.0 = Release|Any CPU + {C935435D-6182-4A01-8E59-B832B2FF0D72}.Release|ARM.ActiveCfg = Release|Any CPU + {C935435D-6182-4A01-8E59-B832B2FF0D72}.Release|ARM.Build.0 = Release|Any CPU + {C935435D-6182-4A01-8E59-B832B2FF0D72}.Release|ARM64.ActiveCfg = Release|Any CPU + {C935435D-6182-4A01-8E59-B832B2FF0D72}.Release|ARM64.Build.0 = Release|Any CPU + {C935435D-6182-4A01-8E59-B832B2FF0D72}.Release|x64.ActiveCfg = Release|Any CPU + {C935435D-6182-4A01-8E59-B832B2FF0D72}.Release|x64.Build.0 = Release|Any CPU + {C935435D-6182-4A01-8E59-B832B2FF0D72}.Release|x86.ActiveCfg = Release|Any CPU + {C935435D-6182-4A01-8E59-B832B2FF0D72}.Release|x86.Build.0 = Release|Any CPU + {C28A88B1-E449-484C-AC67-B5038FF2CA79}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {C28A88B1-E449-484C-AC67-B5038FF2CA79}.Debug|Any CPU.Build.0 = Debug|Any CPU + {C28A88B1-E449-484C-AC67-B5038FF2CA79}.Debug|ARM.ActiveCfg = Debug|Any CPU + {C28A88B1-E449-484C-AC67-B5038FF2CA79}.Debug|ARM.Build.0 = Debug|Any CPU + {C28A88B1-E449-484C-AC67-B5038FF2CA79}.Debug|ARM64.ActiveCfg = Debug|Any CPU + {C28A88B1-E449-484C-AC67-B5038FF2CA79}.Debug|ARM64.Build.0 = Debug|Any CPU + {C28A88B1-E449-484C-AC67-B5038FF2CA79}.Debug|x64.ActiveCfg = Debug|Any CPU + {C28A88B1-E449-484C-AC67-B5038FF2CA79}.Debug|x64.Build.0 = Debug|Any CPU + {C28A88B1-E449-484C-AC67-B5038FF2CA79}.Debug|x86.ActiveCfg = Debug|Any CPU + {C28A88B1-E449-484C-AC67-B5038FF2CA79}.Debug|x86.Build.0 = Debug|Any CPU + {C28A88B1-E449-484C-AC67-B5038FF2CA79}.Release|Any CPU.ActiveCfg = Release|Any CPU + {C28A88B1-E449-484C-AC67-B5038FF2CA79}.Release|Any CPU.Build.0 = Release|Any CPU + {C28A88B1-E449-484C-AC67-B5038FF2CA79}.Release|ARM.ActiveCfg = Release|Any CPU + {C28A88B1-E449-484C-AC67-B5038FF2CA79}.Release|ARM.Build.0 = Release|Any CPU + {C28A88B1-E449-484C-AC67-B5038FF2CA79}.Release|ARM64.ActiveCfg = Release|Any CPU + {C28A88B1-E449-484C-AC67-B5038FF2CA79}.Release|ARM64.Build.0 = Release|Any CPU + {C28A88B1-E449-484C-AC67-B5038FF2CA79}.Release|x64.ActiveCfg = Release|Any CPU + {C28A88B1-E449-484C-AC67-B5038FF2CA79}.Release|x64.Build.0 = Release|Any CPU + {C28A88B1-E449-484C-AC67-B5038FF2CA79}.Release|x86.ActiveCfg = Release|Any CPU + {C28A88B1-E449-484C-AC67-B5038FF2CA79}.Release|x86.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -775,6 +863,10 @@ Global {74DB1F85-9B73-4113-8FE4-A63754BC7DF9} = {9FB27073-61A0-4FE3-94DB-5FDDE062332F} {0A06C9E5-5C42-4BCE-B6E6-D8054C72255D} = {9FB27073-61A0-4FE3-94DB-5FDDE062332F} {6B0FD858-A60D-41B9-A923-358B0CE2A254} = {9FB27073-61A0-4FE3-94DB-5FDDE062332F} + {1C7E17B3-40E0-44ED-B8E0-C52D824604DB} = {666CB1A9-562E-453A-A2C7-FD9D77CFDFDD} + {1055EA6E-6C10-4A0D-A053-85871AF8D7A9} = {3D1D0E04-03FD-480A-8CF8-6E01A2E28625} + {C935435D-6182-4A01-8E59-B832B2FF0D72} = {666CB1A9-562E-453A-A2C7-FD9D77CFDFDD} + {C28A88B1-E449-484C-AC67-B5038FF2CA79} = {666CB1A9-562E-453A-A2C7-FD9D77CFDFDD} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {9AEC9B81-0222-4DE9-B642-D915C29222AC}