diff --git a/AGVEmulator/AGVEmulator.csproj b/AGVEmulator/AGVEmulator.csproj new file mode 100644 index 0000000..83f6feb --- /dev/null +++ b/AGVEmulator/AGVEmulator.csproj @@ -0,0 +1,139 @@ + + + + + Debug + AnyCPU + {9312AB43-72F6-4365-A266-E767215FA7F5} + WinExe + AGVEmulator + AGVEmulator + v4.8 + 512 + true + + + + x86 + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + false + + + AnyCPU + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + false + + + + ..\arControl.Net4.dll + + + ..\arFrameControl.dll + + + ..\ArLog.Net4.dll + + + ..\ArSetting.Net4.dll + + + + + + + + + + + + + + + + + + Form + + + fMain.cs + + + + + + Form + + + Form + + + Form + + + UserControl + + + SerialConn.cs + + + Component + + + AgvViewer.cs + + + fMain.cs + + + ResXFileCodeGenerator + Resources.Designer.cs + Designer + + + True + Resources.resx + True + + + SerialConn.cs + + + + PreserveNewest + + + PreserveNewest + + + SettingsSingleFileGenerator + Settings.Designer.cs + + + True + Settings.settings + True + + + + + {c5f7a8b2-8d3e-4a1b-9c6e-7f4d5e2a9b1c} + AGVNavigationCore + + + {9365803b-933d-4237-93c7-b502c855a71c} + ENIGProtocol + + + + \ No newline at end of file diff --git a/AGVEmulator/DevAGV.cs b/AGVEmulator/DevAGV.cs new file mode 100644 index 0000000..631c983 --- /dev/null +++ b/AGVEmulator/DevAGV.cs @@ -0,0 +1,587 @@ +using arCtl; +using System; +using System.Collections.Generic; +using System.Drawing; +using System.Linq; + +namespace AGVEmulator +{ + class DevAGV : AR.Dev.RS232 + { + //######### private variable + byte runtime = 0; + + //######### public variable + public UInt16 system0 = 0; + public UInt16 system1 = 0; + public UInt16 error = 0; + public byte signal = 0; + public char sts_bunki = 'S'; + public char sts_speed = 'L'; + public char sts_dir = 'F'; + public char sts_sensor = '1'; + + + public enum eCommand : byte + { + LOAD = 0, //EEPROM 불러오기 + SAVE, //EEPROM 저장 + RESET, //초기화 + PINGCHK, + SET_PINMODE, //PINMODE 설정 + SET_DOUTPUT, //디지털출력설정(포트번호,값[1,0]) + SET_AOUTPUT, //아날로그출력설정(포트GET_SETTING = 50, //셋팅값 요청 + SET_FLAG, + SET_EEPROM, + SET_MANUALSPEED, + GET_SETTING = 50, + GUIDE_MOT = 90, //가이드커버(양쪽) 0=멈춤,1=UP,2=DN 아스키코드표 90=Z + SET_EEP_DIREV, + }; + + public enum DOName + { + PINO_GUIDEMOTOR_LDIR, + PINO_GUIDEMOTOR_LRUN, + PINO_GUIDEMOTOR_RDIR, + PINO_GUIDEMOTOR_RRUN, + PINO_EMPTY_26, + PINO_EMPTY_27, + PINO_EMPTY_28, + PINO_EMPTY_29, + } + + public enum DIName + { + PINI_EMG, + PINI_BTN_1, + PINI_BTN_2, + PINI_BTN_3, + PINI_BTN_4, + PINI_OVERLOADL, + PINI_OVERLOADR, + PINI_EMPTY_36, + PINI_EMPTY_37, + PINI_EMPTY_38, + PINI_BTN_ZUP, + PINI_BTN_ZDN, + PINI_LIMIT_LU, + PINI_LIMIT_LD, + PINI_LIMIT_RU, + PINI_LIMIT_RD, + PINI_STOP, + } + public enum eerror + { + Emergency = 0, + Overcurrent, + Charger_run_error, + Charger_pos_error, + line_out_error = 4, + + /// + /// 기동시 자석 감지 에러 + /// + runerror_by_no_magent_line, + /// + /// 호출제어기 통신 오류 + /// + controller_comm_error = 11, + /// + /// 도착경보기 통신 오류 + /// + arrive_ctl_comm_error, + + /// + /// 자동문제어기 통신 오류 + /// + door_ctl_comm_error, + + /// + /// 자동충전기 통신 오류 + /// + charger_comm_error, + + /// + /// 교차로 제어기 통신 오류 + /// + cross_ctrl_comm_error, + } + public enum esignal + { + front_gate_out = 0, + rear_sensor_out, + mark_sensor_1, + mark_sensor_2, + front_left_sensor, + front_right_sensor, + front_center_sensor, + charger_align_sensor, + } + public enum esystemflag0 + { + Memory_RW_State = 5, + EXT_IO_Conn_State, + RFID_Conn_State, + M5E_Module_Run_State = 8, + Front_Ultrasonic_Conn_State, + Front_Untrasonic_Sensor_State, + Side_Ultrasonic_Conn_State, + Side_Ultrasonic_Sensor_State = 12, + Front_Guide_Sensor_State, + Rear_Guide_Sensor_State, + Battery_Level_Check + } + public enum esystemflag1 + { + Side_Detect_Ignore = 3, + Melody_check, + Mark2_check, + Mark1_check, + gateout_check, + Battery_charging = 8, + re_Start, + + /// + /// 전방 감지 무시 + /// + front_detect_ignore, + + /// + /// 전방장애물감지상태 + /// + front_detect_check, + + /// + /// 전방감지 후 정지 상태 + /// + stop_by_front_detect = 12, + /// + /// 교차로 진입 후 정지 상태 + /// + stop_by_cross_in, + agv_stop, + agv_run + } + + public enum evaluetype + { + system0, + system1, + error, + signal, + } + public enum estsvaluetype + { + bunki, + speed, + direction, + sensor + } + public class ValueChangedArgs : EventArgs + { + public int Idx { get; set; } + public bool Value { get; set; } + public evaluetype vtype { get; set; } + public ValueChangedArgs(int idx, bool val, evaluetype isOut) + { + this.Idx = idx; + this.Value = val; + this.vtype = isOut; + } + } + public class StsValueChangedArgs : EventArgs + { + public char Value { get; set; } + public estsvaluetype vtype { get; set; } + public StsValueChangedArgs(estsvaluetype vType, char val) + { + this.Value = val; + this.vtype = vType; + } + } + + public class RequestStatusDataArgs : EventArgs + { + public UInt16 system0 { get; set; } = 0; + public UInt16 system1 { get; set; } = 0; + public char speed { get; set; } = 'L'; + public char direction { get; set; } = 'F'; + public char bunki { get; set; } = 'S'; + + public byte signal { get; set; } = 0; + public float volt { get; set; } = 0f; + public UInt16 error { get; set; } = 0; + public char sensor { get; set; } = '0'; + public RequestStatusDataArgs() + { + + } + } + public event EventHandler RequestStatusData; + public event EventHandler ValueChanged; + public event EventHandler StsValueChanged; + + public class commandargs : EventArgs + { + public string Command { get; set; } + public commandargs(string cmd) + { + this.Command = cmd; + } + } + public event EventHandler Command; + public class FrameData + { + public string Checksum { get; set; } + public byte stx { get; set; } + public byte etx { get; set; } + public string cmd { get; set; } + public string data { get; set; } + public FrameData(byte[] data) + { + this.stx = data[0]; + this.etx = data[data.Length - 1]; + this.Checksum = System.Text.Encoding.Default.GetString(data, data.Length - 3, 2); + this.data = System.Text.Encoding.Default.GetString(data, 1, data.Length - 4); + this.cmd = this.data.Substring(0, 3); + this.data = this.data.Substring(3); + } + } + + + #region SetAGV/SetSTS/SetBIT/GetBIT + Boolean GetBit(ref UInt16 _value, int idx) + { + var offset = (UInt16)(1 << idx); + return (_value & offset) != 0; + } + + Boolean GetBit(ref byte _value, int idx) + { + var offset = (byte)(1 << idx); + return (_value & offset) != 0; + } + + bool SetBit(ref UInt16 _value, int idx, Boolean value) + { + var oldvalue = GetBit(ref _value, idx); + if (value) + { + var offset = (UInt16)(1 << idx); + _value = (UInt16)(_value | offset); + } + else + { + var offset = (UInt16)(~(1 << idx)); + _value = (UInt16)(_value & offset); + } + return oldvalue != value; + } + bool SetBit(ref byte _value, int idx, Boolean value) + { + var oldvalue = GetBit(ref _value, idx); + if (value) + { + var offset = (byte)(1 << idx); + _value = (byte)(_value | offset); + } + else + { + var offset = (byte)(~(1 << idx)); + _value = (byte)(_value & offset); + } + return oldvalue != value; + } + public bool GetAGV(DevAGV.esystemflag1 flag) + { + var idx = (int)flag; + return GetBit(ref system1, idx); + } + public void SetAGV(DevAGV.esystemflag0 flag, bool value) + { + var idx = (int)flag; + if (SetBit(ref system0, idx, value)) + ValueChanged?.Invoke(this, new ValueChangedArgs(idx, value, evaluetype.system0)); + } + public void SetAGV(DevAGV.esystemflag1 flag, bool value) + { + var idx = (int)flag; + if (SetBit(ref system1, idx, value)) + ValueChanged?.Invoke(this, new ValueChangedArgs(idx, value, evaluetype.system1)); + } + public void SetAGV(DevAGV.eerror flag, bool value) + { + var idx = (int)flag; + if (SetBit(ref error, idx, value)) + ValueChanged?.Invoke(this, new ValueChangedArgs(idx, value, evaluetype.error)); + } + public void SetAGV(DevAGV.esignal flag, bool value) + { + var idx = (int)flag; + if (SetBit(ref signal, idx, value)) + ValueChanged?.Invoke(this, new ValueChangedArgs(idx, value, evaluetype.signal)); + } + + public void SetSTS(estsvaluetype target, char value) + { + //bool changed = false; + switch (target) + { + case estsvaluetype.sensor: + //changed = this.sts_sensor.Equals(value); + sts_sensor = value; + break; + case estsvaluetype.direction: + //changed = this.sts_dir.Equals(value); + sts_dir = value; + break; + case estsvaluetype.speed: + //changed = this.sts_speed.Equals(value); + sts_speed = value; + break; + case estsvaluetype.bunki: + //changed = this.sts_bunki.Equals(value); + sts_bunki = value; + break; + } + //if(changed) + { + StsValueChanged?.Invoke(this, new StsValueChangedArgs(target, value)); + } + } + #endregion + + public override bool ProcessRecvData(byte[] data) + { + //dd로 시작하고 34개의 데이터 + //STS258FFFF40000000LSF0000003A + //02 53 54 53 32 35 38 46 46 46 46 34 30 30 30 30 30 30 30 4C 53 46 30 30 30 30 30 30 33 41 03 + var frame = new FrameData(data); + + switch (frame.cmd) + { + case "CRN": //기동명령 + //sts_dir = frame.data[0]; + SetSTS(estsvaluetype.direction, frame.data[0]); + SetAGV(esystemflag1.agv_stop, false); + SetAGV(esystemflag1.agv_run, true); + break; + case "CST": //중지명령 + //(바로 중지한다) + if (frame.data.StartsWith("M")) + { + Command?.Invoke(this, new commandargs("stopmark")); + } + else + { + SetAGV(esystemflag1.agv_run, false); + SetAGV(esystemflag1.agv_stop, true); + } + + break; + case "CBR": //분기명령 + //FSL + SetSTS(estsvaluetype.direction, frame.data[0]); + SetSTS(estsvaluetype.bunki, frame.data[1]); + SetSTS(estsvaluetype.speed, frame.data[2]); + SetSTS(estsvaluetype.sensor, frame.data[3]); + break; + case "CRT"://수동제어 + sts_dir = frame.data[0]; + sts_bunki = frame.data[1]; + sts_speed = frame.data[2]; + sts_sensor = frame.data[3]; + SetAGV(esystemflag1.agv_stop, false); + SetAGV(esystemflag1.agv_run, true); + break; + case "ACK": //응답ok + RaiseMessage(MessageType.Normal, $">> {frame.cmd} DATA={frame.data}"); + break; + case "SFR": //reset + SetAGV(DevAGV.eerror.Emergency, false); + SetAGV(DevAGV.eerror.line_out_error, false); + SetAGV(DevAGV.eerror.Overcurrent, false); + SetAGV(DevAGV.esystemflag1.agv_run, false); + SetAGV(DevAGV.esystemflag1.agv_stop, true); + break; + case "CBT"://충전작업 + SetAGV(DevAGV.esystemflag1.Battery_charging, true); + var id = frame.data.Substring(2, 2); + var cmd = frame.data[4]; + var delaytime = int.Parse(frame.data.Substring(5)); + if (cmd == 'I') SetAGV(DevAGV.esystemflag1.Battery_charging, true); + else SetAGV(esystemflag1.Battery_charging, false); + break; + case "SSH": + case "SSM": + case "SSL": + case "SSS": + case "SHS": + case "SLS": + case "SPK": + case "SPM": + case "SPL": + case "SPS": + case "SIK": + case "SIM": + case "SIH": + case "SIL": + case "SIS": + case "SDK": + case "SDW": + case "SDL": + case "SDS": + case "SRS": + case "SCK": + case "SSK": + case "STT": + case "SSI": + case "SMD": + case "SSC": + case "SPN": + case "SPH": + case "SCH": + case "SDH": + case "SDM": + case "SLB": + case "SGS": + SendCmd("ACK", frame.cmd); + break; + default: + RaiseMessage(MessageType.Normal, $"미처리명령 {frame.cmd} DATA={frame.data}"); + break; + } + + + + return true; + } + public void SendCmd(string cmd, string value) + { + + var barr = new List(); + barr.Add(0x02); + barr.AddRange(System.Text.Encoding.Default.GetBytes(cmd)); + barr.AddRange(System.Text.Encoding.Default.GetBytes(value)); + barr.Add((byte)'*'); + barr.Add((byte)'*'); + barr.Add(0x03); + var cmdstr = System.Text.Encoding.Default.GetString(barr.ToArray()); + RaiseMessage(MessageType.Normal, "Tx:" + barr.ToArray().HexString()); + WriteData(barr.ToArray()); + } + + public void SendTag(string tagno) + { + tagno = tagno.PadLeft(6, '0'); + if (tagno.Length > 6) tagno = tagno.Substring(0, 6); + var barr = new List(); + barr.Add(0x02); + barr.Add((byte)'T'); + barr.Add((byte)'A'); + barr.Add((byte)'G'); + barr.AddRange(System.Text.Encoding.Default.GetBytes(tagno)); + barr.Add((byte)'*'); + barr.Add((byte)'*'); + barr.Add(0x03); + var cmdstr = System.Text.Encoding.Default.GetString(barr.ToArray()); + RaiseMessage(MessageType.Normal, "Tx:" + barr.ToArray().HexString()); + WriteData(barr.ToArray()); + } + + public override void AutoSendData() + { + //if (_device.DtrEnable == false) return; + //STS258FFFF40000000LSF0000003A + //02 53 54 53 32 35 38 46 46 46 46 34 30 30 30 30 30 30 30 4C 53 46 30 30 30 30 30 30 33 41 03 + var sample = "02 53 54 53 32 35 38 46 46 46 46 34 30 30 30 30 30 30 30 4C 53 46 30 30 30 30 30 30 33 41 03"; + var barr = sample.Split(' ').ToList().Select(t => Convert.ToByte(t, 16)).ToArray(); + + //if (RequestStatusData != null) + //{ + //var p = new RequestStatusDataArgs(); + //RequestStatusData.Invoke(this, p); + + var voltstr = "255";// ((int)(p.volt * 10f)).ToString().PadRight(3, '0'); + var bufarr = System.Text.Encoding.Default.GetBytes(voltstr); + Array.Copy(bufarr, 0, barr, 4, bufarr.Length); + + bufarr = System.Text.Encoding.Default.GetBytes(system0.ToString("X2").PadLeft(4, '0')); + + Array.Copy(bufarr, 0, barr, 7, bufarr.Length); + + bufarr = System.Text.Encoding.Default.GetBytes(system1.ToString("X2").PadLeft(4, '0')); + Array.Copy(bufarr, 0, barr, 11, bufarr.Length); + + bufarr = System.Text.Encoding.Default.GetBytes(error.ToString("X2").PadLeft(4, '0')); + Array.Copy(bufarr, 0, barr, 15, bufarr.Length); + + + barr[19] = (byte)this.sts_speed; + barr[20] = (byte)this.sts_bunki; + barr[21] = (byte)this.sts_dir; + barr[22] = (byte)this.sts_sensor; + //bufarr = System.Text.Encoding.Default.GetBytes(p.sensor.ToString().PadLeft(2, '0')); + //Array.Copy(bufarr, 0, barr, 22, bufarr.Length); + bufarr = System.Text.Encoding.Default.GetBytes(signal.ToString("X2").PadLeft(2, '0')); + Array.Copy(bufarr, 0, barr, 23, bufarr.Length); + //barr[22] = (byte)'5'; + + barr[barr.Length - 3] = (byte)'*'; + barr[barr.Length - 2] = (byte)'*'; + + //} + + var cmdstr = System.Text.Encoding.Default.GetString(barr); + RaiseMessage(MessageType.Normal, "Tx:" + barr.ToArray().HexString()); + WriteData(barr.ToArray()); + } + + + protected override bool CustomParser(byte[] buf, out byte[] remainBuffer) + { + //DD A5 03 00 FF FD 77 0D + //remainBuffer = new byte[] { }; + List remain = new List(); + bool retval = false; + foreach (var b in buf) + { + if (retval) + { + remain.Add(b); + continue; + } + + + + if (b == 0x02) //stx + { + tempBuffer.Clear(); + tempBuffer.Add(b); + } + + else if (b == 0x03) //etx + { + tempBuffer.Add(b); + retval = true; + } + else + { + //데이터길이가 만족한 상태 + tempBuffer.Add(b); + var maxlen = 100; + if (tempBuffer.Count > maxlen) + { + RaiseMessage(MessageType.Error, $"buffer over({maxlen})"); + tempBuffer.Clear(); + } + } + + + } + remainBuffer = remain.ToArray(); + return retval; + } + } +} diff --git a/AGVEmulator/DevXBE.cs b/AGVEmulator/DevXBE.cs new file mode 100644 index 0000000..2bdfd5f --- /dev/null +++ b/AGVEmulator/DevXBE.cs @@ -0,0 +1,93 @@ +using ENIG; +using System; +using System.Collections.Generic; +using System.IO.Ports; +using System.Linq; +using System.Text; +using static System.Windows.Forms.VisualStyles.VisualStyleElement; + +namespace AGVEmulator +{ + public class DevXBE : AR.Dev.RS232 + { + private EEProtocol proto; + public event EventHandler ProtocReceived; + + public DevXBE() + { + proto = new EEProtocol(); + proto.OnDataReceived += Proto_OnDataReceived; + proto.OnMessage += Proto_OnMessage; + } + ~DevXBE() + { + proto.OnDataReceived -= Proto_OnDataReceived; + proto.OnMessage -= Proto_OnMessage; + } + + public override bool ProcessRecvData(byte[] data) + { + return true; + } + + protected override bool CustomParser(byte[] buf, out byte[] remainBuffer) + { + //여기서 최초데이터를 파싱한다 + remainBuffer = null; + this.proto.ProcessReceivedData(buf); + return false; + + } + + + private void Proto_OnDataReceived(object sender, EEProtocol.DataEventArgs e) + { + var hexstrRaw = e.ReceivedPacket.RawData.HexString(); + var hexstr = e.ReceivedPacket.Data.HexString(); + var cmd = e.ReceivedPacket.Command.ToString("X2"); + var id = e.ReceivedPacket.ID.ToString("X2"); + + var dataStr = System.Text.Encoding.Default.GetString(e.ReceivedPacket.Data); + RaiseMessage(MessageType.Recv, $"ID:{id},CMD:{cmd},DATA:{hexstr}"); + ProtocReceived?.Invoke(this, e); + } + private void Proto_OnMessage(object sender, EEProtocol.MessageEventArgs e) + { + RaiseMessage(e.IsError, e.Message); + } + + /// + /// 목적지 태그번호 전송 + /// + public void SendGotoTag(byte id, uint tag) + { + var idSTR = id.ToString("X2"); + var tagSTR = tag.ToString("0000"); + var dataStr = $"{idSTR}{tagSTR}"; + Send(ENIGProtocol.AGVCommandHE.Goto, dataStr); + } + public void SendCurrentPos(byte id, uint tag) + { + var idSTR = id.ToString("X2"); + var tagSTR = tag.ToString("0000"); + var dataStr = $"{idSTR}{tagSTR}"; + Send(ENIGProtocol.AGVCommandHE.SetCurrent, dataStr); + } + private void Send(ENIGProtocol.AGVCommandHE Command, string datastr) + { + byte id = 0; + byte cmd = (byte)Command; //move to target + byte[] data = null; + if (datastr != null && string.IsNullOrEmpty(datastr) == false) + data = System.Text.Encoding.Default.GetBytes(datastr); + var packet = proto.CreatePacket(id, cmd, data); + if (WriteData(packet, false)) + { + var hexstr = System.Text.Encoding.Default.GetString(data); + RaiseMessage(MessageType.Send, $"ID:{id},CMD:{cmd},DATA:{hexstr}"); + } + } + + + } +} diff --git a/AGVEmulator/Program.cs b/AGVEmulator/Program.cs new file mode 100644 index 0000000..f0256f5 --- /dev/null +++ b/AGVEmulator/Program.cs @@ -0,0 +1,34 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Windows.Forms; + +namespace AGVEmulator +{ + static class Program + { + /// + /// 해당 애플리케이션의 주 진입점입니다. + /// + [STAThread] + static void Main() + { + Application.EnableVisualStyles(); + Application.SetCompatibleTextRenderingDefault(false); + Application.Run(new fMain()); + } + } + public static class methodext + { + public static string HexString(this byte[] buf) + { + var sb = new System.Text.StringBuilder(); + foreach (var b in buf) + { + sb.Append(" " + b.ToString("X2")); + } + return sb.ToString(); + } + } + +} diff --git a/AGVEmulator/Properties/AssemblyInfo.cs b/AGVEmulator/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..11d780b --- /dev/null +++ b/AGVEmulator/Properties/AssemblyInfo.cs @@ -0,0 +1,36 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// 어셈블리에 대한 일반 정보는 다음 특성 집합을 통해 +// 제어됩니다. 어셈블리와 관련된 정보를 수정하려면 +// 이러한 특성 값을 변경하세요. +[assembly: AssemblyTitle("AGVEmulator")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("AGVEmulator")] +[assembly: AssemblyCopyright("Copyright © 2022")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// ComVisible을 false로 설정하면 이 어셈블리의 형식이 COM 구성 요소에 +// 표시되지 않습니다. COM에서 이 어셈블리의 형식에 액세스하려면 +// 해당 형식에 대해 ComVisible 특성을 true로 설정하세요. +[assembly: ComVisible(false)] + +// 이 프로젝트가 COM에 노출되는 경우 다음 GUID는 typelib의 ID를 나타냅니다. +[assembly: Guid("9312ab43-72f6-FF65-a266-e767215fa7f5")] + +// 어셈블리의 버전 정보는 다음 네 가지 값으로 구성됩니다. +// +// 주 버전 +// 부 버전 +// 빌드 번호 +// 수정 버전 +// +// 모든 값을 지정하거나 아래와 같이 '*'를 사용하여 빌드 번호 및 수정 번호를 +// 기본값으로 할 수 있습니다. +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion("1.0.0.1")] +[assembly: AssemblyFileVersion("1.0.0.1")] diff --git a/AGVEmulator/Properties/Resources.Designer.cs b/AGVEmulator/Properties/Resources.Designer.cs new file mode 100644 index 0000000..7f3da9f --- /dev/null +++ b/AGVEmulator/Properties/Resources.Designer.cs @@ -0,0 +1,63 @@ +//------------------------------------------------------------------------------ +// +// 이 코드는 도구를 사용하여 생성되었습니다. +// 런타임 버전:4.0.30319.42000 +// +// 파일 내용을 변경하면 잘못된 동작이 발생할 수 있으며, 코드를 다시 생성하면 +// 이러한 변경 내용이 손실됩니다. +// +//------------------------------------------------------------------------------ + +namespace AGVEmulator.Properties { + using System; + + + /// + /// 지역화된 문자열 등을 찾기 위한 강력한 형식의 리소스 클래스입니다. + /// + // 이 클래스는 ResGen 또는 Visual Studio와 같은 도구를 통해 StronglyTypedResourceBuilder + // 클래스에서 자동으로 생성되었습니다. + // 멤버를 추가하거나 제거하려면 .ResX 파일을 편집한 다음 /str 옵션을 사용하여 ResGen을 + // 다시 실행하거나 VS 프로젝트를 다시 빌드하십시오. + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "17.0.0.0")] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + internal class Resources { + + private static global::System.Resources.ResourceManager resourceMan; + + private static global::System.Globalization.CultureInfo resourceCulture; + + [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] + internal Resources() { + } + + /// + /// 이 클래스에서 사용하는 캐시된 ResourceManager 인스턴스를 반환합니다. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Resources.ResourceManager ResourceManager { + get { + if (object.ReferenceEquals(resourceMan, null)) { + global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("AGVEmulator.Properties.Resources", typeof(Resources).Assembly); + resourceMan = temp; + } + return resourceMan; + } + } + + /// + /// 이 강력한 형식의 리소스 클래스를 사용하여 모든 리소스 조회에 대해 현재 스레드의 CurrentUICulture 속성을 + /// 재정의합니다. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Globalization.CultureInfo Culture { + get { + return resourceCulture; + } + set { + resourceCulture = value; + } + } + } +} diff --git a/AGVEmulator/Properties/Resources.resx b/AGVEmulator/Properties/Resources.resx new file mode 100644 index 0000000..af7dbeb --- /dev/null +++ b/AGVEmulator/Properties/Resources.resx @@ -0,0 +1,117 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/AGVEmulator/Properties/Settings.Designer.cs b/AGVEmulator/Properties/Settings.Designer.cs new file mode 100644 index 0000000..a336a20 --- /dev/null +++ b/AGVEmulator/Properties/Settings.Designer.cs @@ -0,0 +1,26 @@ +//------------------------------------------------------------------------------ +// +// 이 코드는 도구를 사용하여 생성되었습니다. +// 런타임 버전:4.0.30319.42000 +// +// 파일 내용을 변경하면 잘못된 동작이 발생할 수 있으며, 코드를 다시 생성하면 +// 이러한 변경 내용이 손실됩니다. +// +//------------------------------------------------------------------------------ + +namespace AGVEmulator.Properties { + + + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "17.4.0.0")] + internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase { + + private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings()))); + + public static Settings Default { + get { + return defaultInstance; + } + } + } +} diff --git a/AGVEmulator/Properties/Settings.settings b/AGVEmulator/Properties/Settings.settings new file mode 100644 index 0000000..3964565 --- /dev/null +++ b/AGVEmulator/Properties/Settings.settings @@ -0,0 +1,7 @@ + + + + + + + diff --git a/AGVEmulator/RS232.cs b/AGVEmulator/RS232.cs new file mode 100644 index 0000000..9402b8d --- /dev/null +++ b/AGVEmulator/RS232.cs @@ -0,0 +1,485 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Linq; +using System.Text; +using System.Threading; + +namespace AR.Dev +{ + public abstract partial class RS232 : IDisposable + { + protected System.IO.Ports.SerialPort _device; + protected ManualResetEvent _mre; + protected byte[] LastReceiveBuffer; + + protected List tempBuffer = new List(); + protected Boolean findSTX = false; + + + public int WriteError = 0; + public string WriteErrorMessage = string.Empty; + public int WaitTimeout { get; set; } = 1000; + public int MinRecvLength { get; set; } = 1; + /// + /// 포트이름 + /// + [Description("시리얼 포트 이름")] + [Category("설정"), DisplayName("Port Name")] + public string PortName + { + get + { + if (_device == null) return string.Empty; + else return _device.PortName; + } + set + { + if (this.IsOpen) + { + Message?.Invoke(this, new MessageEventArgs("포트가 열려있어 포트이름을 변경할 수 없습니다", true)); + } + else if (String.IsNullOrEmpty(value) == false) + _device.PortName = value; + else + { + Message?.Invoke(this, new MessageEventArgs("No PortName", true)); + } + } + } + + public int BaudRate + { + get + { + if (_device == null) return 0; + else return _device.BaudRate; + } + set + { + if (this.IsOpen) + { + Message?.Invoke(this, new MessageEventArgs("포트가 열려있어 BaudRate(를) 변경할 수 없습니다", true)); + } + else if (value != 0) + _device.BaudRate = value; + else Message?.Invoke(this, new MessageEventArgs("No baud rate", true)); + } + } + + public string errorMessage { get; set; } + public DateTime LastConnTime { get; set; } + public DateTime LastConnTryTime { get; set; } + public DateTime lastSendTime; + /// + /// 메세지 수신시 사용하는 내부버퍼 + /// + protected List _buffer = new List(); + + /// + /// 최종 전송 메세지 + /// + public byte[] lastSendBuffer; + public byte[] LastRecvData; + public string LastRecvString + { + get + { + if (LastRecvData == null) return String.Empty; + else return System.Text.Encoding.Default.GetString(LastRecvData); + } + } + /// + /// 마지막으로 데이터를 받은 시간 + /// + public DateTime lastRecvTime; + + public RS232() + { + _device = new System.IO.Ports.SerialPort(); + this.BaudRate = 9600; + + _device.DataReceived += barcode_DataReceived; + _device.ErrorReceived += this.barcode_ErrorReceived; + _device.WriteTimeout = 1000; + _device.ReadTimeout = 1000; + _device.DtrEnable = false; + _device.RtsEnable = false; + _device.ReadBufferSize = 8192; + _device.WriteBufferSize = 8192; + + errorMessage = string.Empty; + lastRecvTime = DateTime.Parse("1982-11-23"); + LastConnTime = DateTime.Parse("1982-11-23"); + LastConnTryTime = DateTime.Parse("1982-11-23"); + lastRecvTime = DateTime.Parse("1982-11-23"); + this._mre = new ManualResetEvent(true); + } + + ~RS232() + { + Dispose(false); + } + + + // Flag: Has Dispose already been called? + bool disposed = false; + + // Public implementation of Dispose pattern callable by consumers. + public void Dispose() + { + Dispose(true); + GC.SuppressFinalize(this); + } + + // Protected implementation of Dispose pattern. + protected virtual void Dispose(bool disposing) + { + if (disposed) + return; + + if (disposing) + { + // Free any other managed objects here. + // + } + + _device.DataReceived -= barcode_DataReceived; + _device.ErrorReceived -= this.barcode_ErrorReceived; + + // Free any unmanaged objects here. + // + disposed = true; + } + + public Boolean Open() + { + try + { + _device.Open(); + Message?.Invoke(this, new MessageEventArgs(MessageType.Normal, $"port open:{_device.IsOpen}")); + return IsOpen; + } + catch (Exception ex) + { + errorMessage = ex.Message; + Message.Invoke(this, new MessageEventArgs(ex.Message, true)); + return false; + } + } + public string GetHexString(Byte[] input) + { + System.Text.StringBuilder sb = new System.Text.StringBuilder(); + foreach (byte b in input) + sb.Append(" " + b.ToString("X2")); + return sb.ToString(); + } + + /// + /// 포트가 열려있는지 확인 + /// + [Description("현재 시리얼포트가 열려있는지 확인합니다")] + [Category("정보"), DisplayName("Port Open")] + public Boolean IsOpen + { + get + { + if (_device == null) return false; + return _device.IsOpen; + } + } + + public virtual void Close(Boolean PortClose = true) + { + if (_device != null && _device.IsOpen) + { + _device.DiscardInBuffer(); + _device.DiscardOutBuffer(); + if (PortClose) _device.Close(); //dispose에서는 포트를 직접 클리어하지 않게 해뒀다. + } + } + + public Boolean RaiseRecvData() + { + return RaiseRecvData(LastReceiveBuffer.ToArray()); + } + /// + /// 수신받은 메세지를 발생 시킵니다 + /// + /// + /// + public virtual Boolean RaiseRecvData(byte[] Data) + { + //181206 - 최종수신 메세지 기록 + lastRecvTime = DateTime.Now; + LastRecvData = Data; + + try + { + Message?.Invoke(this, new MessageEventArgs(Data, true)); //recvmessage + if (ProcessRecvData(Data) == false) + { + //Message?.Invoke(this, new MessageEventArgs(Data, true)); //recvmessage + Message?.Invoke(this, new MessageEventArgs(this.errorMessage, true)); //errormessage + return false; + } + else + { + + return true; + } + } + catch (Exception ex) + { + this.errorMessage = ex.Message; + this.Message?.Invoke(this, new MessageEventArgs(ex.Message, true)); + return false; + } + } + + /// + /// 수신받은 자료를 처리한다 + /// + /// + /// + public abstract bool ProcessRecvData(byte[] data); + + #region "Internal Events" + + void barcode_ErrorReceived(object sender, System.IO.Ports.SerialErrorReceivedEventArgs e) + { + Message?.Invoke(this, new MessageEventArgs(e.ToString(), true)); + } + + void barcode_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e) + { + + try + { + int ReadCount = _device.BytesToRead; + + byte[] buffer = new byte[ReadCount]; + _device.Read(buffer, 0, buffer.Length); + + System.Text.StringBuilder LogMsg = new StringBuilder(); + + byte[] remainBuffer; + Repeat: + if (CustomParser(buffer, out remainBuffer)) + { + //parser ok + LastReceiveBuffer = tempBuffer.ToArray(); + RaiseRecvData(); + tempBuffer.Clear(); + if (remainBuffer != null && remainBuffer.Length > 0) + { + //버퍼를 변경해서 다시 전송을 해준다. + buffer = new byte[remainBuffer.Length]; + Array.Copy(remainBuffer, buffer, buffer.Length); + goto Repeat; //남은 버퍼가 있다면 진행을 해준다. + } + } + + } + catch (Exception ex) + { + if (IsOpen) + { + //_device.DiscardInBuffer(); + //_device.DiscardOutBuffer(); + } + errorMessage = ex.Message; + this.Message?.Invoke(this, new MessageEventArgs(ex.Message, true)); + } + + } + + + #endregion + + #region "External Events" + + + /// + /// 오류 및 기타 일반 메세지 + /// + public event EventHandler Message; + + public void RaiseMessage(bool iserr, string message) + { + Message?.Invoke(this, new MessageEventArgs(message, iserr)); + } + #endregion + + #region "Event Args" + + /// + /// 데이터를 수신할떄 사용함(RAW 포함) + /// + public class ReceiveDataEventArgs : EventArgs + { + private byte[] _buffer = null; + + /// + /// 바이트배열의 버퍼값 + /// + public byte[] Value { get { return _buffer; } } + + /// + /// 버퍼(바이트배열)의 데이터를 문자로 반환합니다. + /// + public string StrValue + { + get + { + //return string.Empty; + + if (_buffer == null || _buffer.Length < 1) return string.Empty; + else return System.Text.Encoding.Default.GetString(_buffer); + } + } + public ReceiveDataEventArgs(byte[] buffer) + { + _buffer = buffer; + } + } + + /// + /// 메세지를 강제 발생 + /// + /// + /// + protected virtual void RaiseMessage(MessageType mt, string message) + { + this.Message?.Invoke(this, new MessageEventArgs(mt, message)); + } + public enum MessageType + { + Normal, + Error, + Send, + Recv, + } + + public class MessageEventArgs : EventArgs + { + public MessageType MsgType { get; set; } + private string _message = string.Empty; + + /// + /// Recv,Send,Normal,Error 모두 지원 + /// + public string Message { get { return _message; } } + + private byte[] _data = null; + + /// + /// Recv,Send에서만 값이 존재 합니다 + /// + public byte[] Data { get { return _data; } } + public MessageEventArgs(string Message, bool isError = false) + { + if (isError) MsgType = MessageType.Error; + else MsgType = MessageType.Normal; + _message = Message; + } + public MessageEventArgs(MessageType msgtype, string Message) + { + MsgType = msgtype; + _message = Message; + _data = System.Text.Encoding.Default.GetBytes(Message); + } + + public MessageEventArgs(byte[] buffer, bool isRecv = true) + { + if (isRecv) MsgType = MessageType.Recv; + else MsgType = MessageType.Send; + _data = new byte[buffer.Length]; + Array.Copy(buffer, _data, Data.Length); + _message = System.Text.Encoding.Default.GetString(_data); + } + + } + + #endregion + + + public virtual void AutoSendData() + { + + } + + protected abstract bool CustomParser(byte[] buf, out byte[] remainBuffer); + + /// + /// 데이터수신시간이 설정값보다 x 2.5를 초과하면 false 가 반환됨 + /// + public Boolean IsValid + { + get + { + if (IsOpen == false) return false; + if (lastRecvTime.Year == 1982) return false; + var ts = DateTime.Now - lastRecvTime; + if (ts.TotalSeconds > 5) return false; + return true; + } + } + public bool WriteData(string cmd) + { + return WriteData(System.Text.Encoding.Default.GetBytes(cmd)); + } + /// + /// 포트에 쓰기(barcode_DataReceived 이벤트로 메세지수신) + /// + public Boolean WriteData(byte[] data, bool useLog = true) + { + Boolean bRet = false; + + //171205 : 타임아웃시간추가 + if (!_mre.WaitOne(WaitTimeout)) + { + errorMessage = $"WriteData:MRE:WaitOne:TimeOut {WaitTimeout}ms"; + this.Message?.Invoke(this, new MessageEventArgs(errorMessage, true)); + return false; + } + + _mre.Reset(); + + //Array.Resize(ref data, data.Length + 2); + + try + { + lastSendTime = DateTime.Now; + if (lastSendBuffer == null) lastSendBuffer = new byte[data.Length]; //171113 + else Array.Resize(ref lastSendBuffer, data.Length); + Array.Copy(data, lastSendBuffer, data.Length); + + for (int i = 0; i < data.Length; i++) + _device.Write(data, i, 1); + + //_device.Write(data, 0, data.Length); + + //171113 + if (useLog) this.Message?.Invoke(this, new MessageEventArgs(data, false)); + + bRet = true; + WriteError = 0; + WriteErrorMessage = string.Empty; + } + catch (Exception ex) + { + // this.isinit = false; + this.Message?.Invoke(this, new MessageEventArgs(ex.Message, true)); + bRet = false; + WriteError += 1; //연속쓰기오류횟수 + WriteErrorMessage = ex.Message; + } + finally + { + _mre.Set(); + } + return bRet; + } + } +} diff --git a/AGVEmulator/RunCode/_AGV.cs b/AGVEmulator/RunCode/_AGV.cs new file mode 100644 index 0000000..8305ab4 --- /dev/null +++ b/AGVEmulator/RunCode/_AGV.cs @@ -0,0 +1,214 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows.Forms; +using static AGVEmulator.DevAGV; + + +namespace AGVEmulator +{ + public partial class fMain + { + private void Agv_Command(object sender, commandargs e) + { + switch (e.Command.ToLower()) + { + case "stopmark": + agvViewer1.StopbyMark = true; + break; + } + } + private void Agv_StsValueChanged(object sender, DevAGV.StsValueChangedArgs e) + { + Console.WriteLine($"STS [{e.vtype}] VAL={e.Value}"); + if (this.InvokeRequired) + { + this.BeginInvoke(new EventHandler(Agv_StsValueChanged), sender, e); + return; + } + switch (e.vtype) + { + case DevAGV.estsvaluetype.direction: + foreach (RadioButton c in this.groupBox5.Controls) + { + if (c.Text[0].Equals(e.Value)) + { + c.Checked = true; + + } + else + { + c.Checked = false; + } + c.Refresh(); + } + groupBox5.Refresh(); + break; + case DevAGV.estsvaluetype.bunki: + foreach (RadioButton c in this.groupBox2.Controls) + { + if (c.Text[0].Equals(e.Value)) + { + c.Checked = true; + c.Refresh(); + break; + } + } + break; + case DevAGV.estsvaluetype.speed: + foreach (RadioButton c in this.groupBox4.Controls) + { + if (c.Text[0].Equals(e.Value)) + { + c.Checked = true; + c.Refresh(); + break; + } + } + break; + case DevAGV.estsvaluetype.sensor: + foreach (RadioButton c in this.groupBox8.Controls) + { + if (c.Text.Equals(e.Value)) + { + c.Checked = true; + c.Refresh(); + break; + } + } + break; + } + } + + private void Agv_ValueChanged(object sender, DevAGV.ValueChangedArgs e) + { + if (this.InvokeRequired) + { + this.Invoke(new EventHandler(Agv_ValueChanged), sender, e); + return; + } + + //내부값이 바뀌었다면 컨트롤을 변경해준다. + switch (e.vtype) + { + + case DevAGV.evaluetype.system0: + foreach (CheckBox c in panel6.Controls) + { + var idx = int.Parse(c.Tag.ToString()); + if (idx == e.Idx) + { + c.Checked = e.Value; + break; + } + } + break; + case DevAGV.evaluetype.system1: + + var v = (DevAGV.esystemflag1)e.Idx; + if (e.Value) + { + if (v == esystemflag1.agv_run) + { + agvViewer1.wat.Restart(); + } + if (v == esystemflag1.agv_stop) + { + agvViewer1.wat.Stop(); + } + } + + + foreach (CheckBox c in panel7.Controls) + { + var idx = int.Parse(c.Tag.ToString()); + if (idx == e.Idx) + { + c.Checked = e.Value; + break; + } + } + break; + case DevAGV.evaluetype.error: + foreach (CheckBox c in panel9.Controls) + { + var idx = int.Parse(c.Tag.ToString()); + if (idx == e.Idx) + { + c.Checked = e.Value; + break; + } + } + break; + case DevAGV.evaluetype.signal: + foreach (CheckBox c in panel8.Controls) + { + var idx = int.Parse(c.Tag.ToString()); + if (idx == e.Idx) + { + c.Checked = e.Value; + break; + } + } + break; + + + } + } + + private void Agv_RequestStatusData(object sender, DevAGV.RequestStatusDataArgs e) + { + //UInt16 system0 = 0xFFFF; + //UInt16 system1 = 0xFFFF; + //UInt16 error = 0xFFFF; + //byte signal = 0xFF; + + aaplycheckboxbit(ref AGV.system0, panel6); + aaplycheckboxbit(ref AGV.system1, panel7); + aaplycheckboxbit(ref AGV.error, panel9); + aaplycheckboxbit(ref AGV.signal, panel8); + + if (this.agvViewer1.StopbyMark) AGV.sts_speed = 'S'; + else AGV.sts_speed = GetGroupItemCheckbox(groupBox4); + AGV.sts_bunki = GetGroupItemCheckbox(groupBox2); + AGV.sts_dir = GetGroupItemCheckbox(groupBox5); + AGV.sts_sensor = GetGroupItemCheckbox(groupBox8); + + //this.Invoke(new Action(() => + //{ + // e.system0 = system0; + // e.system1 = system1; + // e.error = error; + // e.signal = signal; + // e.speed = GetGroupItemCheckbox(groupBox4); + // e.bunki = GetGroupItemCheckbox(groupBox2); + // e.direction = GetGroupItemCheckbox(groupBox5); + // e.sensor = GetGroupItemCheckbox(groupBox8); + + // e.volt = 23.4f; + //})); + } + private void AGV_Message(object sender, AR.Dev.RS232.MessageEventArgs e) + { + var dev = sender as AR.Dev.RS232; + if (dev is DevBMS) + { + logBMS.Add(e.Message); + } + else if (dev is DevAGV) + { + logAGV.Add(e.Message); + } + else if (dev is DevXBE) + { + if (e.MsgType == AR.Dev.RS232.MessageType.Send) + logCAL.Add(">> " + e.Data.HexString()); + else if (e.MsgType == AR.Dev.RS232.MessageType.Recv) + logCAL.Add("<< " + e.Data.HexString()); + else logCAL.Add(e.Message); + } + } + } +} diff --git a/AGVEmulator/RunCode/_BMS.cs b/AGVEmulator/RunCode/_BMS.cs new file mode 100644 index 0000000..e58fc8e --- /dev/null +++ b/AGVEmulator/RunCode/_BMS.cs @@ -0,0 +1,63 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows.Forms; + + +namespace AGVEmulator +{ + public partial class fMain + { + private void BMS_Message(object sender, AR.Dev.RS232.MessageEventArgs e) + { + + logBMS.Add(e.Message); + + } + + private void BMS_RequestVoltageData(object sender, DevBMS.RequestVoltageDataArgs e) + { + + //cell전압값추가 + for (int i = 0; i < cellvolt.Length; i++) + { + this.cellvolt[i] = (UInt16)rnd.Next(3300, 3350); + } + Array.Copy(this.cellvolt, 0, e.cellVolt, 0, 8); + + this.btc1.Invoke(new Action(() => + { + var idx = 0; + btc1.Text = (this.cellvolt[idx++] / 1000f).ToString(); + btc2.Text = (this.cellvolt[idx++] / 1000f).ToString(); + btc3.Text = (this.cellvolt[idx++] / 1000f).ToString(); + btc4.Text = (this.cellvolt[idx++] / 1000f).ToString(); + btc5.Text = (this.cellvolt[idx++] / 1000f).ToString(); + btc6.Text = (this.cellvolt[idx++] / 1000f).ToString(); + btc7.Text = (this.cellvolt[idx++] / 1000f).ToString(); + btc8.Text = (this.cellvolt[idx++] / 1000f).ToString(); + })); + + } + private void Bms_RequestBatteryData(object sender, DevBMS.RequestBatteryDataArgs e) + { + if (checkBox1.Checked) + this.trackBar1.Invoke(new Action(() => + { + this.trackBar1.Value -= 1; + trackBar1_Scroll(null, null); + })); + + e.CurA = (int)BMS_CurA; + e.MaxA = (int)BMS_MaxA; + e.Remain = BMS_Remain; + e.Volt = BMS_Volt; + e.Temp1 = this.Temp1; + e.Temp2 = this.Temp2; + + } + + } +} diff --git a/AGVEmulator/RunCode/_XBEE.cs b/AGVEmulator/RunCode/_XBEE.cs new file mode 100644 index 0000000..9d9696a --- /dev/null +++ b/AGVEmulator/RunCode/_XBEE.cs @@ -0,0 +1,40 @@ +using ENIG; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows.Forms; + + +namespace AGVEmulator +{ + public partial class fMain + { + + private void CAL_Message(object sender, AR.Dev.RS232.MessageEventArgs e) + { + + if (e.MsgType == AR.Dev.RS232.MessageType.Send) + logCAL.Add(">> " + System.Text.Encoding.Default.GetString(e.Data)); + else if (e.MsgType == AR.Dev.RS232.MessageType.Recv) + logCAL.Add("<< " + System.Text.Encoding.Default.GetString( e.Data)); + else logCAL.Add(e.Message); + + } + private void CAL_ProtocReceived(object sender, ENIG.EEProtocol.DataEventArgs e) + { + //throw new NotImplementedException(); + var dev = (DeviceType)e.ReceivedPacket.ID; + if (dev == DeviceType.AGV1 || dev == DeviceType.AGV2) + { + //agv에서 들어오는 데이터 + var cmd = e.ReceivedPacket.Command; + if(cmd == 3) + { + //status + } + } + } + } +} diff --git a/AGVEmulator/Sample/packetFC.bin b/AGVEmulator/Sample/packetFC.bin new file mode 100644 index 0000000..83dc36c Binary files /dev/null and b/AGVEmulator/Sample/packetFC.bin differ diff --git a/AGVEmulator/Sample/packetFD.bin b/AGVEmulator/Sample/packetFD.bin new file mode 100644 index 0000000..c861398 Binary files /dev/null and b/AGVEmulator/Sample/packetFD.bin differ diff --git a/AGVEmulator/UC/AgvViewer.Designer.cs b/AGVEmulator/UC/AgvViewer.Designer.cs new file mode 100644 index 0000000..de1c153 --- /dev/null +++ b/AGVEmulator/UC/AgvViewer.Designer.cs @@ -0,0 +1,37 @@ + +namespace AGVEmulator.UC +{ + partial class AgvViewer + { + /// + /// 필수 디자이너 변수입니다. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// 사용 중인 모든 리소스를 정리합니다. + /// + /// 관리되는 리소스를 삭제해야 하면 true이고, 그렇지 않으면 false입니다. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region 구성 요소 디자이너에서 생성한 코드 + + /// + /// 디자이너 지원에 필요한 메서드입니다. + /// 이 메서드의 내용을 코드 편집기로 수정하지 마세요. + /// + private void InitializeComponent() + { + components = new System.ComponentModel.Container(); + } + + #endregion + } +} diff --git a/AGVEmulator/UC/AgvViewer.cs b/AGVEmulator/UC/AgvViewer.cs new file mode 100644 index 0000000..e0963ee --- /dev/null +++ b/AGVEmulator/UC/AgvViewer.cs @@ -0,0 +1,272 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows.Forms; + +namespace AGVEmulator.UC +{ + public partial class AgvViewer : Control + { + + public AgvViewer() + { + InitializeComponent(); + + // Set Optimized Double Buffer to reduce flickering + this.SetStyle(ControlStyles.UserPaint, true); + this.SetStyle(ControlStyles.AllPaintingInWmPaint, true); + this.SetStyle(ControlStyles.OptimizedDoubleBuffer, true); + + // Redraw when resized + this.SetStyle(ControlStyles.ResizeRedraw, true); + } + + public class TagArgs : EventArgs + { + public string Data { get; set; } + public bool Active { get; set; } + public TagArgs(string tag,bool act) + { + this.Data = tag; + this.Active = act; + } + } + public event EventHandler TagTouched; + public event EventHandler MarkTouched; + public event EventHandler Command; + + public bool StopbyMark { get; set; } + public float mpos = 100; + public float posmax = 1200; + public float posmin = 0; + public float mspd = 10; + public System.Diagnostics.Stopwatch wat = new System.Diagnostics.Stopwatch(); + public Font FontTag { get; set; } + public Font FontMrk { get; set; } + public int dir = 1; + + public class ptdata + { + public float pos { get; set; } = 0f; + public string data { get; set; } = string.Empty; + public Boolean active { get; set; } = false; + } + public ptdata[] listMRK { get; set; } + public ptdata[] listTAG { get; set; } + + public string lasttag { get; set; } = string.Empty; + public string lasttagdir { get; set; } = string.Empty; + public string lastmark { get; set; } = string.Empty; + public string lastmarkdir { get; set; } = string.Empty; + + protected override void OnPaint(PaintEventArgs pe) + { + pe.Graphics.Clear(this.BackColor); + var r = new Rectangle(DisplayRectangle.Left + Padding.Left, + DisplayRectangle.Top + Padding.Top, + DisplayRectangle.Width - Padding.Right - Padding.Left - 1, + DisplayRectangle.Height - Padding.Top - Padding.Bottom - 1); + + + // pe.Graphics.FillRectangle(new SolidBrush(this.BackColor), DisplayRectangle); + pe.Graphics.DrawRectangle(Pens.Black, r); + + + var ptwidth = 25; + var ptheight = 35; + if (listMRK != null && listMRK.Any() && FontMrk != null) + { + foreach (var item in listMRK) + { + var x = r.Left + ((item.pos * 1f) / posmax) * r.Width; + var rr = new RectangleF(x - ptwidth, r.Top + r.Height / 2f - ptheight / 2f, ptwidth * 2, ptheight); + pe.Graphics.DrawLine(Pens.Gray, x, r.Top, x, r.Bottom); + pe.Graphics.FillRectangle(new SolidBrush(Color.FromArgb(120, Color.Gold)), rr); + pe.Graphics.DrawRectangle(Pens.DimGray, rr.Left, rr.Top, rr.Width, rr.Height); + pe.Graphics.DrawString(item.data, FontMrk, Brushes.Gray, rr, new StringFormat + { + Alignment = StringAlignment.Center, + LineAlignment = StringAlignment.Center, + }); + + } + } + + ptwidth = 15; + if (listTAG != null && listTAG.Any() && FontTag != null) + { + var lst = listTAG.Where(t => t.data.EndsWith("1")); + foreach (var item in lst) + { + var x = r.Left + ((item.pos * 1f) / posmax) * r.Width; + var rr = new RectangleF(x - ptwidth, r.Top + 5, ptwidth * 2, 15); + pe.Graphics.DrawLine(Pens.Orange, x, r.Top, x, rr.Top); + pe.Graphics.FillRectangle(Brushes.Orange, rr); + pe.Graphics.DrawRectangle(Pens.DimGray, rr.Left, rr.Top, rr.Width, rr.Height); + pe.Graphics.DrawString(item.data, FontTag, Brushes.Black, rr, new StringFormat + { + Alignment = StringAlignment.Center, + LineAlignment = StringAlignment.Center, + }); + } + + lst = listTAG.Where(t => t.data.EndsWith("0")); + foreach (var item in lst) + { + var x = r.Left + ((item.pos * 1f) / posmax) * r.Width; + var rr = new RectangleF(x - ptwidth, r.Bottom - 20, ptwidth * 2, 15); + pe.Graphics.DrawLine(Pens.Orange, x, rr.Bottom, x, r.Bottom); + pe.Graphics.FillRectangle(Brushes.Orange, rr); + pe.Graphics.DrawRectangle(Pens.DimGray, rr.Left, rr.Top, rr.Width, rr.Height); + pe.Graphics.DrawString(item.data, FontTag, Brushes.Black, rr, new StringFormat + { + Alignment = StringAlignment.Center, + LineAlignment = StringAlignment.Center, + }); + } + } + + var posX = r.Left + (mpos / posmax) * r.Width; + var posY = r.Top + r.Height / 2f; + var boxw = r.Width * 0.030f; + var boxh = r.Height * 0.15f; + var box = new RectangleF(posX - boxw, posY - boxh, boxw * 2, boxh * 2); + var box2 = new RectangleF(box.Left - 5, box.Top + 3, 10, box.Height - 6); + for (int i = 0; i < posmax; i += 100) + { + var x = r.Left + ((i * 1f) / posmax) * r.Width; + pe.Graphics.DrawLine(Pens.Black, x, r.Bottom - 3, x, r.Bottom); + if (i > 0) + pe.Graphics.DrawString($"{i / 10f}m", this.Font, Brushes.Black, x - 12, r.Bottom - 15); + } + pe.Graphics.FillRectangle(Brushes.LightSkyBlue, box); + pe.Graphics.DrawRectangle(Pens.Black, box.Left, box.Top, box.Width, box.Height); + pe.Graphics.DrawLine(new Pen(Color.Black, 4), posX, box.Top - 5, posX, box.Bottom + 5); + + pe.Graphics.FillRectangle(Brushes.Gold, box2); + pe.Graphics.DrawRectangle(Pens.Black, box2.Left, box2.Top, box2.Width, box2.Height); + //pe.Graphics.DrawString((mpos / 10f).ToString("N1") + "m", this.Font, Brushes.Black, box, new StringFormat + //{ + // Alignment = StringAlignment.Center, + // LineAlignment = StringAlignment.Center, + //}); + + if (StopbyMark) + pe.Graphics.DrawString("!MRK-STP!", this.Font, Brushes.Blue, r.Left+2, r.Top+2); + + if (wat.IsRunning) + { + var newpos = mspd * (wat.ElapsedMilliseconds / 1000f); + if (dir < 0) //forward + { + if (mpos - newpos < 0) + mpos = posmax; + else mpos -= newpos; + + //내위치주변에 마커가 있는지 본다 + var mlist = listMRK.Where(t => t.pos <= mpos && (mpos - t.pos) < 10); + var mrk = mlist.FirstOrDefault(); + if (mrk != null) + { + //대상마커가있다 + if (lastmark.Equals(mrk.data) == false || lastmarkdir.Equals("F") == false) + { + lastmark = mrk.data; + lastmarkdir = "F"; + mrk.active = true; + MarkTouched?.Invoke(this, new TagArgs(mrk.data,true)); + if(StopbyMark) + { + Command?.Invoke(this, new TagArgs("stop",true)); + StopbyMark = false; + } + } + } + else + { + if (string.IsNullOrEmpty(lastmark) == false) + { + foreach(var item in listMRK.Where(t=>t.active)) + { + item.active = false; + MarkTouched?.Invoke(this, new TagArgs(item.data,false)); + } + } + } + + //주변태그확인 + var tlist = listTAG.Where(t => t.pos <= mpos && (mpos - t.pos) < 10); + var tag = tlist.FirstOrDefault(); + if (tag != null) + { + //대상마커가있다 + if (lasttag.Equals(tag.data) == false || lasttagdir.Equals("F") == false) + { + lasttag = tag.data; + lasttagdir = "F"; + TagTouched?.Invoke(this, new TagArgs(tag.data, true)); + } + } + } + else //backward + { + if (mpos + newpos > posmax) + mpos = 0; + else mpos += newpos; + + //내위치주변에 마커가 있는지 본다 + var mlist = listMRK.Where(t => t.pos >= mpos && (t.pos - mpos) < 10); + var mrk = mlist.FirstOrDefault(); + if (mrk != null) + { + //대상마커가있다 + if (lastmark.Equals(mrk.data) == false || lastmarkdir.Equals("B") == false) + { + lastmark = mrk.data; + lastmarkdir = "B"; + mrk.active = true; + MarkTouched?.Invoke(this, new TagArgs(mrk.data, true)); + if (StopbyMark) + { + Command?.Invoke(this, new TagArgs("stop", true)); + StopbyMark = false; + } + } + } + else + { + if (string.IsNullOrEmpty(lastmark) == false) + { + foreach (var item in listMRK.Where(t => t.active)) + { + item.active = false; + MarkTouched?.Invoke(this, new TagArgs(item.data, false)); + } + } + } + + //주변태그확인 + var tlist = listTAG.Where(t => t.pos >= mpos && (t.pos - mpos) < 10); + var tag = tlist.FirstOrDefault(); + if (tag != null) + { + //대상마커가있다 + if (lasttag.Equals(tag.data) == false || lasttagdir.Equals("B") == false) + { + lasttag = tag.data; + lasttagdir = "B"; + TagTouched?.Invoke(this, new TagArgs(tag.data, true)); + } + } + } + + wat.Restart(); + } + } + } +} diff --git a/AGVEmulator/UC/SerialConn.Designer.cs b/AGVEmulator/UC/SerialConn.Designer.cs new file mode 100644 index 0000000..4c674ab --- /dev/null +++ b/AGVEmulator/UC/SerialConn.Designer.cs @@ -0,0 +1,162 @@ + +namespace AGVEmulator +{ + partial class SerialConn + { + /// + /// 필수 디자이너 변수입니다. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// 사용 중인 모든 리소스를 정리합니다. + /// + /// 관리되는 리소스를 삭제해야 하면 true이고, 그렇지 않으면 false입니다. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region 구성 요소 디자이너에서 생성한 코드 + + /// + /// 디자이너 지원에 필요한 메서드입니다. + /// 이 메서드의 내용을 코드 편집기로 수정하지 마세요. + /// + private void InitializeComponent() + { + this.cmbBaud = new System.Windows.Forms.ComboBox(); + this.cmbPOrt = new System.Windows.Forms.ComboBox(); + this.panel1 = new System.Windows.Forms.Panel(); + this.tableLayoutPanel1 = new System.Windows.Forms.TableLayoutPanel(); + this.lbrx = new System.Windows.Forms.Label(); + this.lbtx = new System.Windows.Forms.Label(); + this.button1 = new System.Windows.Forms.Button(); + this.panel1.SuspendLayout(); + this.tableLayoutPanel1.SuspendLayout(); + this.SuspendLayout(); + // + // cmbBaud + // + this.cmbBaud.Dock = System.Windows.Forms.DockStyle.Top; + this.cmbBaud.Font = new System.Drawing.Font("굴림", 15F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(129))); + this.cmbBaud.FormattingEnabled = true; + this.cmbBaud.Items.AddRange(new object[] { + "9600", + "12800", + "25600", + "38400", + "512000"}); + this.cmbBaud.Location = new System.Drawing.Point(0, 28); + this.cmbBaud.Name = "cmbBaud"; + this.cmbBaud.Size = new System.Drawing.Size(134, 28); + this.cmbBaud.TabIndex = 0; + this.cmbBaud.Text = "9600"; + // + // cmbPOrt + // + this.cmbPOrt.Dock = System.Windows.Forms.DockStyle.Top; + this.cmbPOrt.Font = new System.Drawing.Font("굴림", 15F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(129))); + this.cmbPOrt.FormattingEnabled = true; + this.cmbPOrt.Location = new System.Drawing.Point(0, 0); + this.cmbPOrt.Name = "cmbPOrt"; + this.cmbPOrt.Size = new System.Drawing.Size(134, 28); + this.cmbPOrt.TabIndex = 1; + // + // panel1 + // + this.panel1.Controls.Add(this.tableLayoutPanel1); + this.panel1.Controls.Add(this.cmbBaud); + this.panel1.Controls.Add(this.cmbPOrt); + this.panel1.Dock = System.Windows.Forms.DockStyle.Fill; + this.panel1.Location = new System.Drawing.Point(0, 0); + this.panel1.Name = "panel1"; + this.panel1.Size = new System.Drawing.Size(134, 96); + this.panel1.TabIndex = 2; + // + // tableLayoutPanel1 + // + this.tableLayoutPanel1.ColumnCount = 2; + this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 50F)); + this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 50F)); + this.tableLayoutPanel1.Controls.Add(this.lbrx, 0, 0); + this.tableLayoutPanel1.Controls.Add(this.lbtx, 1, 0); + this.tableLayoutPanel1.Dock = System.Windows.Forms.DockStyle.Fill; + this.tableLayoutPanel1.Location = new System.Drawing.Point(0, 56); + this.tableLayoutPanel1.Name = "tableLayoutPanel1"; + this.tableLayoutPanel1.RowCount = 1; + this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 50F)); + this.tableLayoutPanel1.Size = new System.Drawing.Size(134, 40); + this.tableLayoutPanel1.TabIndex = 4; + // + // lbrx + // + this.lbrx.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle; + this.lbrx.Dock = System.Windows.Forms.DockStyle.Fill; + this.lbrx.Font = new System.Drawing.Font("Microsoft Sans Serif", 15F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(129))); + this.lbrx.Location = new System.Drawing.Point(0, 0); + this.lbrx.Margin = new System.Windows.Forms.Padding(0); + this.lbrx.Name = "lbrx"; + this.lbrx.Size = new System.Drawing.Size(67, 40); + this.lbrx.TabIndex = 2; + this.lbrx.Text = "RX"; + this.lbrx.TextAlign = System.Drawing.ContentAlignment.MiddleCenter; + // + // lbtx + // + this.lbtx.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle; + this.lbtx.Dock = System.Windows.Forms.DockStyle.Fill; + this.lbtx.Font = new System.Drawing.Font("Microsoft Sans Serif", 15F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(129))); + this.lbtx.Location = new System.Drawing.Point(67, 0); + this.lbtx.Margin = new System.Windows.Forms.Padding(0); + this.lbtx.Name = "lbtx"; + this.lbtx.Size = new System.Drawing.Size(67, 40); + this.lbtx.TabIndex = 3; + this.lbtx.Text = "TX"; + this.lbtx.TextAlign = System.Drawing.ContentAlignment.MiddleCenter; + // + // button1 + // + this.button1.Dock = System.Windows.Forms.DockStyle.Right; + this.button1.FlatAppearance.BorderColor = System.Drawing.Color.DodgerBlue; + this.button1.FlatAppearance.BorderSize = 3; + this.button1.FlatStyle = System.Windows.Forms.FlatStyle.Flat; + this.button1.Font = new System.Drawing.Font("맑은 고딕", 18F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(129))); + this.button1.Location = new System.Drawing.Point(134, 0); + this.button1.Margin = new System.Windows.Forms.Padding(0); + this.button1.Name = "button1"; + this.button1.Size = new System.Drawing.Size(82, 96); + this.button1.TabIndex = 3; + this.button1.Text = "연결"; + this.button1.UseVisualStyleBackColor = true; + this.button1.Click += new System.EventHandler(this.button1_Click); + // + // SerialConn + // + this.AutoScaleDimensions = new System.Drawing.SizeF(7F, 12F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.Controls.Add(this.panel1); + this.Controls.Add(this.button1); + this.Name = "SerialConn"; + this.Size = new System.Drawing.Size(216, 96); + this.panel1.ResumeLayout(false); + this.tableLayoutPanel1.ResumeLayout(false); + this.ResumeLayout(false); + + } + + #endregion + + private System.Windows.Forms.ComboBox cmbBaud; + private System.Windows.Forms.ComboBox cmbPOrt; + private System.Windows.Forms.Panel panel1; + private System.Windows.Forms.Button button1; + private System.Windows.Forms.Label lbtx; + private System.Windows.Forms.Label lbrx; + private System.Windows.Forms.TableLayoutPanel tableLayoutPanel1; + } +} diff --git a/AGVEmulator/UC/SerialConn.cs b/AGVEmulator/UC/SerialConn.cs new file mode 100644 index 0000000..3cece47 --- /dev/null +++ b/AGVEmulator/UC/SerialConn.cs @@ -0,0 +1,130 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Linq; +using System.Text; +using System.Windows.Forms; + +namespace AGVEmulator +{ + public partial class SerialConn : UserControl + { + public AR.Dev.RS232 dev { get; set; } + public SerialConn() + { + InitializeComponent(); + } + + void AttachEvent() + { + dev.Message += Dev_Message; + } + void DetachEvent() + { + dev.Message -= Dev_Message; + } + private void Dev_Message(object sender, AR.Dev.RS232.MessageEventArgs e) + { + if (e.MsgType == AR.Dev.RS232.MessageType.Recv) + ToggleRX(); + else if (e.MsgType == AR.Dev.RS232.MessageType.Send) + ToggleTX(); + } + + public void SetPortList(string[] list) + { + cmbPOrt.Items.Clear(); + foreach (var item in list) + cmbPOrt.Items.Add(item); + } + public string PortName + { + get + { + return cmbPOrt.Text; + } + set { this.cmbPOrt.Text = value; } + } + public int BaudRate + { + get + { + return int.Parse(cmbBaud.Text); + } + set + { + cmbBaud.Text = value.ToString(); + } + } + public void ToggleTX() + { + if (lbtx.BackColor == Color.DeepSkyBlue) + lbtx.BackColor = Color.White; + else lbtx.BackColor = Color.DeepSkyBlue; + } + public void ToggleRX() + { + if (lbrx.BackColor == Color.Lime) + lbrx.BackColor = Color.White; + else lbrx.BackColor = Color.Lime; + } + public void Disconnect() + { + if (this.dev.IsOpen) + { + DetachEvent(); + dev.Close(); + } + if (dev.IsOpen) + button1.BackColor = Color.Lime; + else button1.BackColor = Color.Tomato; + } + public void Connect() + { + if (this.dev.IsOpen) + { + DetachEvent(); + dev.Close(); + } + else + { + this.dev.PortName = cmbPOrt.Text; + this.dev.BaudRate = int.Parse(cmbBaud.Text); + AttachEvent(); + try + { + dev.Open(); + } + catch (Exception ex) + { + button1.BackColor = Color.Red; + } + } + + if (dev.IsOpen) + button1.BackColor = Color.Lime; + else button1.BackColor = Color.Tomato; + } + + private void button1_Click(object sender, EventArgs e) + { + if (this.dev == null) + { + MessageBox.Show("시리얼 개체가 연결되지 않았습니다"); + return; + } + if(int.TryParse(cmbBaud.Text,out int baud)==false) + { + MessageBox.Show("Baudrate 값이 올바르지 않습니다"); + return; + } + Connect(); + + + + + } + } +} diff --git a/AGVEmulator/UC/SerialConn.resx b/AGVEmulator/UC/SerialConn.resx new file mode 100644 index 0000000..1af7de1 --- /dev/null +++ b/AGVEmulator/UC/SerialConn.resx @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/AGVEmulator/app.config b/AGVEmulator/app.config new file mode 100644 index 0000000..3e0e37c --- /dev/null +++ b/AGVEmulator/app.config @@ -0,0 +1,3 @@ + + + diff --git a/AGVEmulator/devBMS.cs b/AGVEmulator/devBMS.cs new file mode 100644 index 0000000..acd1057 --- /dev/null +++ b/AGVEmulator/devBMS.cs @@ -0,0 +1,243 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace AGVEmulator +{ + class DevBMS : AR.Dev.RS232 + { + public class RequestBatteryDataArgs : EventArgs + { + + public float Volt { get; set; } + public float Remain { get; set; } + public int CurA { get; set; } + public int MaxA { get; set; } + public UInt16 Temp1 { get; set; } + public UInt16 Temp2 { get; set; } + public RequestBatteryDataArgs() + { + this.Volt = 25; + this.Remain = 79f; + this.CurA = 40; + this.MaxA = 80; + Temp1 = 0; + Temp2 = 0; + } + } + public class RequestVoltageDataArgs : EventArgs + { + public UInt16[] cellVolt { get; set; } + public RequestVoltageDataArgs() + { + + cellVolt = new UInt16[] { 0, 0, 0, 0, 0, 0, 0, 0 }; + } + } + + public event EventHandler RequestBatteryData; + public event EventHandler RequestVoltageData; + public override bool ProcessRecvData(byte[] data) + { + //dd로 시작하고 34개의 데이터(명령이 0D로 끝나면 34이고, 77로 끝나면 34보다크다) + var sample000D = "DD 03 00 1B 0A 65 00 00 21 63 29 04 00 00 2C 92 00 00 00 00 00 00 28 51 03 08 02 0B 69 0B 66 FC 9C 77"; + var sampleFC77 = "DD 03 00 1B 0A 6E 0D DD 04 00 10 0D 0A 0D 09 0D 0C 0D 09 0D 0A 0D 09 0D 09 0D 0C FF 38 77 DD 04 00 10 0D 0A 0D 09 0D 0C 0D 09 0D 0A 0D 09 0D 09 0D 0C FF 38 77"; + var sampleFD77 = "DD 03 00 1B 0A 6E 00 00 1F 4A 29 04 00 4E 2C D7 00 00 00 00 00 00 28 4C 03 08 02 0B 9F 0B A9 FB A7 77 DD 03 00 1B 0A 6E 00 00 1F 4A 29 04 00 4E 2C D7 00 00 00 00 00 00 28 4C 03 08 02 0B 9F 0B AA FB A6 77"; + + //basic + var basicinfosmaple = "0A 65 00 00 21 63 29 04 00 00 2C 92 00 00 00 00 00 00 28 51 03 08 02 0B 69 0B 66"; + var basic_payload = basicinfosmaple.Split(' ').ToList().Select(t => Convert.ToByte(t, 16)).ToArray(); //old + + + + var barr0D = sample000D.Split(' ').ToList().Select(t => Convert.ToByte(t, 16)).ToArray(); //old + var barrFC77 = sampleFC77.Split(' ').ToList().Select(t => Convert.ToByte(t, 16)).ToArray(); //setting + var barrFD77 = sampleFD77.Split(' ').ToList().Select(t => Convert.ToByte(t, 16)).ToArray(); //normal + + if (data.First() != 0xDD || data.Last() != 0x77) + { + RaiseMessage(MessageType.Error, $"stx,etx error data={data.HexString()}"); + return false; + } + var sts = data[1]; + var cmd = data[2]; + + RaiseMessage(MessageType.Normal, "Rx:" + data.HexString()); + byte sendOld = 0; + + if (cmd == 0x03) //get basic info + { + if (RequestBatteryData != null) + { + var p = new RequestBatteryDataArgs(); + RequestBatteryData.Invoke(this, p); + + //전압 + var Volt = (UInt16)(p.Volt * 100); + var arr_volt = BitConverter.GetBytes(Volt).Reverse().ToArray(); + Array.Copy(arr_volt, 0, basic_payload, 0, arr_volt.Length); + + //잔량A + var CurA = (UInt16)p.CurA; + var arr_cura = BitConverter.GetBytes(CurA).Reverse().ToArray(); + Array.Copy(arr_cura, 0, basic_payload, 4, arr_cura.Length); + + + //최대A + var MaxA = (UInt16)p.MaxA; + var arr_maxa = BitConverter.GetBytes(MaxA).Reverse().ToArray(); + Array.Copy(arr_maxa, 0, basic_payload, 6, arr_maxa.Length); + + //% + var perc = (byte)(int)p.Remain; + Array.Copy(new byte[] { perc }, 0, basic_payload, 19, 1); + + //temp1 + var temp1 = BitConverter.GetBytes((UInt16)(p.Temp1 + 2731)).Reverse().ToArray(); + Array.Copy(temp1, 0, basic_payload, 23,2); + + //temp2 + var temp2 = BitConverter.GetBytes((UInt16)(p.Temp2 + 2731)).Reverse().ToArray(); + Array.Copy(temp2, 0, basic_payload, 25, 2); + + var datalen = (byte)basic_payload.Length; + var payload_cs = new List(); + payload_cs.Add(datalen); + payload_cs.AddRange(basic_payload); + var chks = MakeCheckSum(payload_cs); + + var buffer = new List(); + buffer.Add(0xdd); + buffer.Add(cmd); + buffer.Add(0x00); + buffer.Add(datalen); + buffer.AddRange(basic_payload); + buffer.AddRange(chks); + buffer.Add(0x77); + + + ////makechecksum + //UInt16 chksum = 0; + //for (int i = 3; i <= 19; i++) + //{ + // chksum += barrFD77[i]; + //} + //chksum = (UInt16)(0xFFFF - chksum + 1); + //Array.Copy(BitConverter.GetBytes(chksum).Reverse().ToArray(), 0, barrFD77, 20, 2); + + + RaiseMessage(MessageType.Normal, $"Volt:{p.Volt}v,Remain:{p.Remain}%,temp1:{p.Temp1/10f},Temp2:{p.Temp2/10f}"); + + var sendstr = System.Text.Encoding.Default.GetString(barr0D); + RaiseMessage(MessageType.Normal, "Tx:" + barr0D.HexString()); + WriteData(buffer.ToArray()); + } + } + else if (cmd == 0x04) //get cellvoltage + { + if (RequestVoltageData != null) + { + var p = new RequestVoltageDataArgs(); + RequestVoltageData.Invoke(this, p); + + //var sig = data.Skip(data.Length - 2).Take(1).First(); + + //cellvolt 240201 + var payload = new byte[8 * 2]; + for (int i = 0; i < 8; i++) + { + var volt = p.cellVolt[i]; + var arr_cellvolt = BitConverter.GetBytes(volt).Reverse().ToArray(); + Array.Copy(arr_cellvolt, 0, payload, (i * 2), arr_cellvolt.Length); + } + + //makechecksum + var datalen = (byte)payload.Length; + var payload_cs = new List(); + payload_cs.Add(datalen); + payload_cs.AddRange(payload); + var chksum = MakeCheckSum(payload_cs); + + var buffer = new List(); + buffer.Add(0xDD); + buffer.Add(cmd); + buffer.Add(0x00); + buffer.Add(datalen); + buffer.AddRange(payload); + buffer.AddRange(chksum); + buffer.Add(0x77); + WriteData(buffer.ToArray()); + RaiseMessage(MessageType.Normal, "Tx:" + buffer.ToArray().HexString()); + + + } + + } + + + + + return true; + } + public byte[] MakeCheckSum(IEnumerable payload) + { + UInt16 retval = 0; + var payloadsum = payload.Sum(t => t); + retval = (UInt16)(payloadsum); + retval = (UInt16)(0xFFFF - retval); + retval += 1; + + return BitConverter.GetBytes(retval).Reverse().ToArray(); + } + protected override bool CustomParser(byte[] buf, out byte[] remainBuffer) + { + //DD A5 03 00 FF FD 77 0D + //remainBuffer = new byte[] { }; + List remain = new List(); + bool retval = false; + foreach (var b in buf) + { + if (retval) + { + remain.Add(b); + continue; + } + + if (b == 0xDD) //stx + { + tempBuffer.Clear(); + tempBuffer.Add(b); + } + else if (b == 0x0D || b == 0x77) //etx + { + //과거데이터 34개이다 (DD A5 03 00 FF FD 77 0D) + //대쉬보드상태일때(DD A5 03 00 FF FD 77) + //설정상태일때-셀전압표시(DD A5 04 00 FF FC 77) + + tempBuffer.Add(b); + retval = true; + } + else + { + if (tempBuffer.Count > 0 && tempBuffer[0] == 0xDD) + { + tempBuffer.Add(b); + if (tempBuffer.Count > 10) + { + RaiseMessage(MessageType.Error, "buffer over"); + tempBuffer.Clear(); + retval = false; + } + } + else + { + //trash + } + } + } + remainBuffer = remain.ToArray(); + return retval; + } + } +} diff --git a/AGVEmulator/fMain.Designer.cs b/AGVEmulator/fMain.Designer.cs new file mode 100644 index 0000000..1757da5 --- /dev/null +++ b/AGVEmulator/fMain.Designer.cs @@ -0,0 +1,1711 @@ + +using System.Windows.Forms; + +namespace AGVEmulator +{ + partial class fMain + { + /// + /// 필수 디자이너 변수입니다. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// 사용 중인 모든 리소스를 정리합니다. + /// + /// 관리되는 리소스를 삭제해야 하면 true이고, 그렇지 않으면 false입니다. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form 디자이너에서 생성한 코드 + + /// + /// 디자이너 지원에 필요한 메서드입니다. + /// 이 메서드의 내용을 코드 편집기로 수정하지 마세요. + /// + private void InitializeComponent() + { + this.components = new System.ComponentModel.Container(); + System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(fMain)); + AGVEmulator.UC.AgvViewer.ptdata ptdata57 = new AGVEmulator.UC.AgvViewer.ptdata(); + AGVEmulator.UC.AgvViewer.ptdata ptdata58 = new AGVEmulator.UC.AgvViewer.ptdata(); + AGVEmulator.UC.AgvViewer.ptdata ptdata59 = new AGVEmulator.UC.AgvViewer.ptdata(); + AGVEmulator.UC.AgvViewer.ptdata ptdata60 = new AGVEmulator.UC.AgvViewer.ptdata(); + AGVEmulator.UC.AgvViewer.ptdata ptdata61 = new AGVEmulator.UC.AgvViewer.ptdata(); + AGVEmulator.UC.AgvViewer.ptdata ptdata62 = new AGVEmulator.UC.AgvViewer.ptdata(); + AGVEmulator.UC.AgvViewer.ptdata ptdata63 = new AGVEmulator.UC.AgvViewer.ptdata(); + AGVEmulator.UC.AgvViewer.ptdata ptdata64 = new AGVEmulator.UC.AgvViewer.ptdata(); + AGVEmulator.UC.AgvViewer.ptdata ptdata65 = new AGVEmulator.UC.AgvViewer.ptdata(); + AGVEmulator.UC.AgvViewer.ptdata ptdata66 = new AGVEmulator.UC.AgvViewer.ptdata(); + AGVEmulator.UC.AgvViewer.ptdata ptdata67 = new AGVEmulator.UC.AgvViewer.ptdata(); + AGVEmulator.UC.AgvViewer.ptdata ptdata68 = new AGVEmulator.UC.AgvViewer.ptdata(); + AGVEmulator.UC.AgvViewer.ptdata ptdata69 = new AGVEmulator.UC.AgvViewer.ptdata(); + AGVEmulator.UC.AgvViewer.ptdata ptdata70 = new AGVEmulator.UC.AgvViewer.ptdata(); + AGVEmulator.UC.AgvViewer.ptdata ptdata71 = new AGVEmulator.UC.AgvViewer.ptdata(); + AGVEmulator.UC.AgvViewer.ptdata ptdata72 = new AGVEmulator.UC.AgvViewer.ptdata(); + AGVEmulator.UC.AgvViewer.ptdata ptdata73 = new AGVEmulator.UC.AgvViewer.ptdata(); + AGVEmulator.UC.AgvViewer.ptdata ptdata74 = new AGVEmulator.UC.AgvViewer.ptdata(); + AGVEmulator.UC.AgvViewer.ptdata ptdata75 = new AGVEmulator.UC.AgvViewer.ptdata(); + AGVEmulator.UC.AgvViewer.ptdata ptdata76 = new AGVEmulator.UC.AgvViewer.ptdata(); + AGVEmulator.UC.AgvViewer.ptdata ptdata77 = new AGVEmulator.UC.AgvViewer.ptdata(); + AGVEmulator.UC.AgvViewer.ptdata ptdata78 = new AGVEmulator.UC.AgvViewer.ptdata(); + AGVEmulator.UC.AgvViewer.ptdata ptdata79 = new AGVEmulator.UC.AgvViewer.ptdata(); + AGVEmulator.UC.AgvViewer.ptdata ptdata80 = new AGVEmulator.UC.AgvViewer.ptdata(); + AGVEmulator.UC.AgvViewer.ptdata ptdata81 = new AGVEmulator.UC.AgvViewer.ptdata(); + AGVEmulator.UC.AgvViewer.ptdata ptdata82 = new AGVEmulator.UC.AgvViewer.ptdata(); + AGVEmulator.UC.AgvViewer.ptdata ptdata83 = new AGVEmulator.UC.AgvViewer.ptdata(); + AGVEmulator.UC.AgvViewer.ptdata ptdata84 = new AGVEmulator.UC.AgvViewer.ptdata(); + this.groupBox1 = new System.Windows.Forms.GroupBox(); + this.rtBMS = new arCtl.LogTextBox(); + this.panel1 = new System.Windows.Forms.Panel(); + this.label11 = new System.Windows.Forms.Label(); + this.label10 = new System.Windows.Forms.Label(); + this.label9 = new System.Windows.Forms.Label(); + this.label8 = new System.Windows.Forms.Label(); + this.trbT2 = new System.Windows.Forms.TrackBar(); + this.trbT1 = new System.Windows.Forms.TrackBar(); + this.btc8 = new System.Windows.Forms.Label(); + this.btc4 = new System.Windows.Forms.Label(); + this.btc7 = new System.Windows.Forms.Label(); + this.btc3 = new System.Windows.Forms.Label(); + this.btc6 = new System.Windows.Forms.Label(); + this.btc2 = new System.Windows.Forms.Label(); + this.btc5 = new System.Windows.Forms.Label(); + this.btc1 = new System.Windows.Forms.Label(); + this.checkBox1 = new System.Windows.Forms.CheckBox(); + this.label6 = new System.Windows.Forms.Label(); + this.label5 = new System.Windows.Forms.Label(); + this.label4 = new System.Windows.Forms.Label(); + this.label3 = new System.Windows.Forms.Label(); + this.label2 = new System.Windows.Forms.Label(); + this.label1 = new System.Windows.Forms.Label(); + this.trackBar1 = new System.Windows.Forms.TrackBar(); + this.rtAGV = new arCtl.LogTextBox(); + this.panel4 = new System.Windows.Forms.Panel(); + this.groupBox9 = new System.Windows.Forms.GroupBox(); + this.groupBox10 = new System.Windows.Forms.GroupBox(); + this.panel8 = new System.Windows.Forms.Panel(); + this.groupBox11 = new System.Windows.Forms.GroupBox(); + this.panel9 = new System.Windows.Forms.Panel(); + this.groupBox7 = new System.Windows.Forms.GroupBox(); + this.panel7 = new System.Windows.Forms.Panel(); + this.groupBox6 = new System.Windows.Forms.GroupBox(); + this.panel6 = new System.Windows.Forms.Panel(); + this.panel11 = new System.Windows.Forms.Panel(); + this.groupBox8 = new System.Windows.Forms.GroupBox(); + this.radioButton17 = new System.Windows.Forms.RadioButton(); + this.radioButton13 = new System.Windows.Forms.RadioButton(); + this.radioButton16 = new System.Windows.Forms.RadioButton(); + this.groupBox4 = new System.Windows.Forms.GroupBox(); + this.radioButton12 = new System.Windows.Forms.RadioButton(); + this.radioButton10 = new System.Windows.Forms.RadioButton(); + this.radioButton11 = new System.Windows.Forms.RadioButton(); + this.groupBox2 = new System.Windows.Forms.GroupBox(); + this.radioButton9 = new System.Windows.Forms.RadioButton(); + this.radioButton8 = new System.Windows.Forms.RadioButton(); + this.radioButton7 = new System.Windows.Forms.RadioButton(); + this.groupBox5 = new System.Windows.Forms.GroupBox(); + this.radioButton14 = new System.Windows.Forms.RadioButton(); + this.radioButton15 = new System.Windows.Forms.RadioButton(); + this.panel13 = new System.Windows.Forms.Panel(); + this.chkSimulation = new System.Windows.Forms.CheckBox(); + this.checkBox3 = new System.Windows.Forms.CheckBox(); + this.panel10 = new System.Windows.Forms.Panel(); + this.numericUpDown1 = new System.Windows.Forms.TextBox(); + this.button18 = new System.Windows.Forms.Button(); + this.button17 = new System.Windows.Forms.Button(); + this.button15 = new System.Windows.Forms.Button(); + this.button16 = new System.Windows.Forms.Button(); + this.button14 = new System.Windows.Forms.Button(); + this.button5 = new System.Windows.Forms.Button(); + this.button4 = new System.Windows.Forms.Button(); + this.groupBox3 = new System.Windows.Forms.GroupBox(); + this.rtCAL = new arCtl.LogTextBox(); + this.timer1 = new System.Windows.Forms.Timer(this.components); + this.tabControl1 = new System.Windows.Forms.TabControl(); + this.tabPage4 = new System.Windows.Forms.TabPage(); + this.tabPage1 = new System.Windows.Forms.TabPage(); + this.tableLayoutPanel3 = new System.Windows.Forms.TableLayoutPanel(); + this.rtAGVPro = new arCtl.LogTextBox(); + this.panel12 = new System.Windows.Forms.Panel(); + this.tabPage2 = new System.Windows.Forms.TabPage(); + this.tabPage3 = new System.Windows.Forms.TabPage(); + this.panel3 = new System.Windows.Forms.Panel(); + this.nudIDAgv = new System.Windows.Forms.NumericUpDown(); + this.label7 = new System.Windows.Forms.Label(); + this.numericUpDown2 = new System.Windows.Forms.NumericUpDown(); + this.button1 = new System.Windows.Forms.Button(); + this.nudTagNo = new System.Windows.Forms.NumericUpDown(); + this.btacsgoto = new System.Windows.Forms.Button(); + this.button7 = new System.Windows.Forms.Button(); + this.button8 = new System.Windows.Forms.Button(); + this.button9 = new System.Windows.Forms.Button(); + this.button10 = new System.Windows.Forms.Button(); + this.button11 = new System.Windows.Forms.Button(); + this.button12 = new System.Windows.Forms.Button(); + this.toolStrip1 = new System.Windows.Forms.ToolStrip(); + this.toolStripButton1 = new System.Windows.Forms.ToolStripButton(); + this.toolStripButton2 = new System.Windows.Forms.ToolStripButton(); + this.statusStrip1 = new System.Windows.Forms.StatusStrip(); + this.toolStripStatusLabel8 = new System.Windows.Forms.ToolStripStatusLabel(); + this.sbAGV = new System.Windows.Forms.ToolStripStatusLabel(); + this.toolStripStatusLabel4 = new System.Windows.Forms.ToolStripStatusLabel(); + this.sbBMS = new System.Windows.Forms.ToolStripStatusLabel(); + this.toolStripStatusLabel2 = new System.Windows.Forms.ToolStripStatusLabel(); + this.sbCAL = new System.Windows.Forms.ToolStripStatusLabel(); + this.toolStripSeparator1 = new System.Windows.Forms.ToolStripSeparator(); + this.toolStripButton3 = new System.Windows.Forms.ToolStripButton(); + this.agvViewer1 = new AGVEmulator.UC.AgvViewer(); + this.serAGV = new AGVEmulator.SerialConn(); + this.serBMS = new AGVEmulator.SerialConn(); + this.serCAL = new AGVEmulator.SerialConn(); + this.toolStripButton4 = new System.Windows.Forms.ToolStripButton(); + this.toolStripButton5 = new System.Windows.Forms.ToolStripButton(); + this.groupBox1.SuspendLayout(); + this.panel1.SuspendLayout(); + ((System.ComponentModel.ISupportInitialize)(this.trbT2)).BeginInit(); + ((System.ComponentModel.ISupportInitialize)(this.trbT1)).BeginInit(); + ((System.ComponentModel.ISupportInitialize)(this.trackBar1)).BeginInit(); + this.panel4.SuspendLayout(); + this.groupBox9.SuspendLayout(); + this.groupBox10.SuspendLayout(); + this.groupBox11.SuspendLayout(); + this.groupBox7.SuspendLayout(); + this.groupBox6.SuspendLayout(); + this.panel11.SuspendLayout(); + this.groupBox8.SuspendLayout(); + this.groupBox4.SuspendLayout(); + this.groupBox2.SuspendLayout(); + this.groupBox5.SuspendLayout(); + this.panel13.SuspendLayout(); + this.panel10.SuspendLayout(); + this.groupBox3.SuspendLayout(); + this.tabControl1.SuspendLayout(); + this.tabPage1.SuspendLayout(); + this.tableLayoutPanel3.SuspendLayout(); + this.panel12.SuspendLayout(); + this.tabPage2.SuspendLayout(); + this.tabPage3.SuspendLayout(); + this.panel3.SuspendLayout(); + ((System.ComponentModel.ISupportInitialize)(this.nudIDAgv)).BeginInit(); + ((System.ComponentModel.ISupportInitialize)(this.numericUpDown2)).BeginInit(); + ((System.ComponentModel.ISupportInitialize)(this.nudTagNo)).BeginInit(); + this.toolStrip1.SuspendLayout(); + this.statusStrip1.SuspendLayout(); + this.SuspendLayout(); + // + // groupBox1 + // + this.groupBox1.Controls.Add(this.rtBMS); + this.groupBox1.Controls.Add(this.panel1); + this.groupBox1.Controls.Add(this.serBMS); + this.groupBox1.Dock = System.Windows.Forms.DockStyle.Fill; + this.groupBox1.Location = new System.Drawing.Point(3, 3); + this.groupBox1.Name = "groupBox1"; + this.groupBox1.Size = new System.Drawing.Size(1140, 616); + this.groupBox1.TabIndex = 0; + this.groupBox1.TabStop = false; + this.groupBox1.Text = "BMS"; + // + // rtBMS + // + this.rtBMS.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(24)))), ((int)(((byte)(24)))), ((int)(((byte)(24))))); + this.rtBMS.ColorList = new arCtl.sLogMessageColor[0]; + this.rtBMS.DateFormat = "ss.fff"; + this.rtBMS.DefaultColor = System.Drawing.Color.LightGray; + this.rtBMS.Dock = System.Windows.Forms.DockStyle.Fill; + this.rtBMS.EnableDisplayTimer = false; + this.rtBMS.EnableGubunColor = true; + this.rtBMS.Font = new System.Drawing.Font("Consolas", 9F); + this.rtBMS.ListFormat = "[{0}] {1}"; + this.rtBMS.Location = new System.Drawing.Point(3, 204); + this.rtBMS.MaxListCount = ((ushort)(200)); + this.rtBMS.MaxTextLength = ((uint)(4000u)); + this.rtBMS.MessageInterval = 50; + this.rtBMS.Name = "rtBMS"; + this.rtBMS.Size = new System.Drawing.Size(1134, 409); + this.rtBMS.TabIndex = 2; + this.rtBMS.Text = ""; + // + // panel1 + // + this.panel1.Controls.Add(this.label11); + this.panel1.Controls.Add(this.label10); + this.panel1.Controls.Add(this.label9); + this.panel1.Controls.Add(this.label8); + this.panel1.Controls.Add(this.trbT2); + this.panel1.Controls.Add(this.trbT1); + this.panel1.Controls.Add(this.btc8); + this.panel1.Controls.Add(this.btc4); + this.panel1.Controls.Add(this.btc7); + this.panel1.Controls.Add(this.btc3); + this.panel1.Controls.Add(this.btc6); + this.panel1.Controls.Add(this.btc2); + this.panel1.Controls.Add(this.btc5); + this.panel1.Controls.Add(this.btc1); + this.panel1.Controls.Add(this.checkBox1); + this.panel1.Controls.Add(this.label6); + this.panel1.Controls.Add(this.label5); + this.panel1.Controls.Add(this.label4); + this.panel1.Controls.Add(this.label3); + this.panel1.Controls.Add(this.label2); + this.panel1.Controls.Add(this.label1); + this.panel1.Controls.Add(this.trackBar1); + this.panel1.Dock = System.Windows.Forms.DockStyle.Top; + this.panel1.Location = new System.Drawing.Point(3, 101); + this.panel1.Name = "panel1"; + this.panel1.Size = new System.Drawing.Size(1134, 103); + this.panel1.TabIndex = 4; + // + // label11 + // + this.label11.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(64)))), ((int)(((byte)(64)))), ((int)(((byte)(64))))); + this.label11.ForeColor = System.Drawing.Color.White; + this.label11.Location = new System.Drawing.Point(620, 68); + this.label11.Name = "label11"; + this.label11.Size = new System.Drawing.Size(75, 24); + this.label11.TabIndex = 19; + this.label11.Text = "Curr"; + this.label11.TextAlign = System.Drawing.ContentAlignment.MiddleCenter; + // + // label10 + // + this.label10.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(64)))), ((int)(((byte)(64)))), ((int)(((byte)(64))))); + this.label10.ForeColor = System.Drawing.Color.White; + this.label10.Location = new System.Drawing.Point(620, 12); + this.label10.Name = "label10"; + this.label10.Size = new System.Drawing.Size(75, 24); + this.label10.TabIndex = 18; + this.label10.Text = "Curr"; + this.label10.TextAlign = System.Drawing.ContentAlignment.MiddleCenter; + // + // label9 + // + this.label9.AutoSize = true; + this.label9.Location = new System.Drawing.Point(391, 72); + this.label9.Name = "label9"; + this.label9.Size = new System.Drawing.Size(44, 12); + this.label9.TabIndex = 17; + this.label9.Text = "Temp2"; + // + // label8 + // + this.label8.AutoSize = true; + this.label8.Location = new System.Drawing.Point(392, 18); + this.label8.Name = "label8"; + this.label8.Size = new System.Drawing.Size(44, 12); + this.label8.TabIndex = 16; + this.label8.Text = "Temp1"; + // + // trbT2 + // + this.trbT2.LargeChange = 10; + this.trbT2.Location = new System.Drawing.Point(442, 58); + this.trbT2.Maximum = 990; + this.trbT2.Name = "trbT2"; + this.trbT2.Size = new System.Drawing.Size(172, 45); + this.trbT2.SmallChange = 5; + this.trbT2.TabIndex = 15; + this.trbT2.Value = 200; + this.trbT2.Scroll += new System.EventHandler(this.trbT2_Scroll); + // + // trbT1 + // + this.trbT1.LargeChange = 10; + this.trbT1.Location = new System.Drawing.Point(442, 7); + this.trbT1.Maximum = 990; + this.trbT1.Name = "trbT1"; + this.trbT1.Size = new System.Drawing.Size(172, 45); + this.trbT1.SmallChange = 5; + this.trbT1.TabIndex = 14; + this.trbT1.Value = 200; + this.trbT1.Scroll += new System.EventHandler(this.trbT1_Scroll); + // + // btc8 + // + this.btc8.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(64)))), ((int)(((byte)(64)))), ((int)(((byte)(64))))); + this.btc8.ForeColor = System.Drawing.Color.White; + this.btc8.Location = new System.Drawing.Point(335, 69); + this.btc8.Name = "btc8"; + this.btc8.Size = new System.Drawing.Size(50, 24); + this.btc8.TabIndex = 12; + this.btc8.Text = "3338"; + this.btc8.TextAlign = System.Drawing.ContentAlignment.MiddleCenter; + // + // btc4 + // + this.btc4.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(64)))), ((int)(((byte)(64)))), ((int)(((byte)(64))))); + this.btc4.ForeColor = System.Drawing.Color.White; + this.btc4.Location = new System.Drawing.Point(279, 69); + this.btc4.Name = "btc4"; + this.btc4.Size = new System.Drawing.Size(50, 24); + this.btc4.TabIndex = 13; + this.btc4.Text = "3338"; + this.btc4.TextAlign = System.Drawing.ContentAlignment.MiddleCenter; + // + // btc7 + // + this.btc7.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(64)))), ((int)(((byte)(64)))), ((int)(((byte)(64))))); + this.btc7.ForeColor = System.Drawing.Color.White; + this.btc7.Location = new System.Drawing.Point(335, 50); + this.btc7.Name = "btc7"; + this.btc7.Size = new System.Drawing.Size(50, 24); + this.btc7.TabIndex = 10; + this.btc7.Text = "3338"; + this.btc7.TextAlign = System.Drawing.ContentAlignment.MiddleCenter; + // + // btc3 + // + this.btc3.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(64)))), ((int)(((byte)(64)))), ((int)(((byte)(64))))); + this.btc3.ForeColor = System.Drawing.Color.White; + this.btc3.Location = new System.Drawing.Point(279, 50); + this.btc3.Name = "btc3"; + this.btc3.Size = new System.Drawing.Size(50, 24); + this.btc3.TabIndex = 11; + this.btc3.Text = "3338"; + this.btc3.TextAlign = System.Drawing.ContentAlignment.MiddleCenter; + // + // btc6 + // + this.btc6.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(64)))), ((int)(((byte)(64)))), ((int)(((byte)(64))))); + this.btc6.ForeColor = System.Drawing.Color.White; + this.btc6.Location = new System.Drawing.Point(335, 27); + this.btc6.Name = "btc6"; + this.btc6.Size = new System.Drawing.Size(50, 24); + this.btc6.TabIndex = 8; + this.btc6.Text = "3338"; + this.btc6.TextAlign = System.Drawing.ContentAlignment.MiddleCenter; + // + // btc2 + // + this.btc2.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(64)))), ((int)(((byte)(64)))), ((int)(((byte)(64))))); + this.btc2.ForeColor = System.Drawing.Color.White; + this.btc2.Location = new System.Drawing.Point(279, 27); + this.btc2.Name = "btc2"; + this.btc2.Size = new System.Drawing.Size(50, 24); + this.btc2.TabIndex = 9; + this.btc2.Text = "3338"; + this.btc2.TextAlign = System.Drawing.ContentAlignment.MiddleCenter; + // + // btc5 + // + this.btc5.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(64)))), ((int)(((byte)(64)))), ((int)(((byte)(64))))); + this.btc5.ForeColor = System.Drawing.Color.White; + this.btc5.Location = new System.Drawing.Point(335, 7); + this.btc5.Name = "btc5"; + this.btc5.Size = new System.Drawing.Size(50, 24); + this.btc5.TabIndex = 7; + this.btc5.Text = "3338"; + this.btc5.TextAlign = System.Drawing.ContentAlignment.MiddleCenter; + // + // btc1 + // + this.btc1.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(64)))), ((int)(((byte)(64)))), ((int)(((byte)(64))))); + this.btc1.ForeColor = System.Drawing.Color.White; + this.btc1.Location = new System.Drawing.Point(279, 7); + this.btc1.Name = "btc1"; + this.btc1.Size = new System.Drawing.Size(50, 24); + this.btc1.TabIndex = 7; + this.btc1.Text = "3338"; + this.btc1.TextAlign = System.Drawing.ContentAlignment.MiddleCenter; + // + // checkBox1 + // + this.checkBox1.AutoSize = true; + this.checkBox1.Checked = true; + this.checkBox1.CheckState = System.Windows.Forms.CheckState.Checked; + this.checkBox1.Location = new System.Drawing.Point(14, 77); + this.checkBox1.Name = "checkBox1"; + this.checkBox1.Size = new System.Drawing.Size(70, 16); + this.checkBox1.TabIndex = 6; + this.checkBox1.Text = "decrese"; + this.checkBox1.UseVisualStyleBackColor = true; + // + // label6 + // + this.label6.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(64)))), ((int)(((byte)(64)))), ((int)(((byte)(64))))); + this.label6.ForeColor = System.Drawing.Color.White; + this.label6.Location = new System.Drawing.Point(14, 44); + this.label6.Name = "label6"; + this.label6.Size = new System.Drawing.Size(68, 24); + this.label6.TabIndex = 5; + this.label6.Text = "Curr"; + this.label6.TextAlign = System.Drawing.ContentAlignment.MiddleCenter; + // + // label5 + // + this.label5.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(64)))), ((int)(((byte)(64)))), ((int)(((byte)(64))))); + this.label5.ForeColor = System.Drawing.Color.White; + this.label5.Location = new System.Drawing.Point(189, 6); + this.label5.Name = "label5"; + this.label5.Size = new System.Drawing.Size(75, 24); + this.label5.TabIndex = 3; + this.label5.Text = "Curr"; + this.label5.TextAlign = System.Drawing.ContentAlignment.MiddleCenter; + // + // label4 + // + this.label4.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(64)))), ((int)(((byte)(64)))), ((int)(((byte)(64))))); + this.label4.ForeColor = System.Drawing.Color.White; + this.label4.Location = new System.Drawing.Point(213, 44); + this.label4.Name = "label4"; + this.label4.Size = new System.Drawing.Size(50, 24); + this.label4.TabIndex = 2; + this.label4.Text = "80"; + this.label4.TextAlign = System.Drawing.ContentAlignment.MiddleCenter; + // + // label3 + // + this.label3.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(64)))), ((int)(((byte)(64)))), ((int)(((byte)(64))))); + this.label3.ForeColor = System.Drawing.Color.White; + this.label3.Location = new System.Drawing.Point(123, 44); + this.label3.Name = "label3"; + this.label3.Size = new System.Drawing.Size(48, 24); + this.label3.TabIndex = 2; + this.label3.Text = "Curr"; + this.label3.TextAlign = System.Drawing.ContentAlignment.MiddleCenter; + // + // label2 + // + this.label2.AutoSize = true; + this.label2.Location = new System.Drawing.Point(177, 50); + this.label2.Name = "label2"; + this.label2.Size = new System.Drawing.Size(30, 12); + this.label2.TabIndex = 1; + this.label2.Text = "Max"; + // + // label1 + // + this.label1.AutoSize = true; + this.label1.Location = new System.Drawing.Point(88, 50); + this.label1.Name = "label1"; + this.label1.Size = new System.Drawing.Size(29, 12); + this.label1.TabIndex = 1; + this.label1.Text = "Curr"; + // + // trackBar1 + // + this.trackBar1.LargeChange = 10; + this.trackBar1.Location = new System.Drawing.Point(14, 6); + this.trackBar1.Maximum = 8000; + this.trackBar1.Name = "trackBar1"; + this.trackBar1.Size = new System.Drawing.Size(172, 45); + this.trackBar1.SmallChange = 5; + this.trackBar1.TabIndex = 0; + this.trackBar1.Value = 7000; + this.trackBar1.Scroll += new System.EventHandler(this.trackBar1_Scroll); + // + // rtAGV + // + this.rtAGV.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(24)))), ((int)(((byte)(24)))), ((int)(((byte)(24))))); + this.rtAGV.ColorList = new arCtl.sLogMessageColor[0]; + this.rtAGV.DateFormat = "ss.fff"; + this.rtAGV.DefaultColor = System.Drawing.Color.LightGray; + this.rtAGV.Dock = System.Windows.Forms.DockStyle.Fill; + this.rtAGV.EnableDisplayTimer = false; + this.rtAGV.EnableGubunColor = true; + this.rtAGV.Font = new System.Drawing.Font("Consolas", 8F); + this.rtAGV.ListFormat = "[{0}] {1}"; + this.rtAGV.Location = new System.Drawing.Point(3, 3); + this.rtAGV.MaxListCount = ((ushort)(200)); + this.rtAGV.MaxTextLength = ((uint)(4000u)); + this.rtAGV.MessageInterval = 50; + this.rtAGV.Name = "rtAGV"; + this.rtAGV.Size = new System.Drawing.Size(795, 210); + this.rtAGV.TabIndex = 2; + this.rtAGV.Text = ""; + // + // panel4 + // + this.panel4.Controls.Add(this.groupBox9); + this.panel4.Controls.Add(this.panel10); + this.panel4.Dock = System.Windows.Forms.DockStyle.Top; + this.panel4.Location = new System.Drawing.Point(3, 123); + this.panel4.Name = "panel4"; + this.panel4.Size = new System.Drawing.Size(1140, 280); + this.panel4.TabIndex = 3; + // + // groupBox9 + // + this.groupBox9.Controls.Add(this.groupBox10); + this.groupBox9.Controls.Add(this.groupBox11); + this.groupBox9.Controls.Add(this.groupBox7); + this.groupBox9.Controls.Add(this.groupBox6); + this.groupBox9.Controls.Add(this.panel11); + this.groupBox9.Controls.Add(this.panel13); + this.groupBox9.Dock = System.Windows.Forms.DockStyle.Fill; + this.groupBox9.Location = new System.Drawing.Point(0, 0); + this.groupBox9.Name = "groupBox9"; + this.groupBox9.Size = new System.Drawing.Size(982, 280); + this.groupBox9.TabIndex = 13; + this.groupBox9.TabStop = false; + this.groupBox9.Text = "Status"; + // + // groupBox10 + // + this.groupBox10.Controls.Add(this.panel8); + this.groupBox10.Dock = System.Windows.Forms.DockStyle.Left; + this.groupBox10.Location = new System.Drawing.Point(652, 44); + this.groupBox10.Name = "groupBox10"; + this.groupBox10.Size = new System.Drawing.Size(189, 233); + this.groupBox10.TabIndex = 12; + this.groupBox10.TabStop = false; + this.groupBox10.Text = "signal"; + // + // panel8 + // + this.panel8.AutoScroll = true; + this.panel8.AutoSize = true; + this.panel8.Dock = System.Windows.Forms.DockStyle.Fill; + this.panel8.Location = new System.Drawing.Point(3, 17); + this.panel8.Name = "panel8"; + this.panel8.Size = new System.Drawing.Size(183, 213); + this.panel8.TabIndex = 1; + this.panel8.Tag = "sg"; + // + // groupBox11 + // + this.groupBox11.Controls.Add(this.panel9); + this.groupBox11.Dock = System.Windows.Forms.DockStyle.Left; + this.groupBox11.Location = new System.Drawing.Point(430, 44); + this.groupBox11.Name = "groupBox11"; + this.groupBox11.Size = new System.Drawing.Size(222, 233); + this.groupBox11.TabIndex = 12; + this.groupBox11.TabStop = false; + this.groupBox11.Text = "error"; + // + // panel9 + // + this.panel9.AutoScroll = true; + this.panel9.AutoSize = true; + this.panel9.Dock = System.Windows.Forms.DockStyle.Fill; + this.panel9.Location = new System.Drawing.Point(3, 17); + this.panel9.Name = "panel9"; + this.panel9.Size = new System.Drawing.Size(216, 213); + this.panel9.TabIndex = 0; + this.panel9.Tag = "er"; + // + // groupBox7 + // + this.groupBox7.Controls.Add(this.panel7); + this.groupBox7.Dock = System.Windows.Forms.DockStyle.Left; + this.groupBox7.Location = new System.Drawing.Point(241, 44); + this.groupBox7.Name = "groupBox7"; + this.groupBox7.Size = new System.Drawing.Size(189, 233); + this.groupBox7.TabIndex = 12; + this.groupBox7.TabStop = false; + this.groupBox7.Text = "System 1"; + // + // panel7 + // + this.panel7.AutoScroll = true; + this.panel7.AutoSize = true; + this.panel7.Dock = System.Windows.Forms.DockStyle.Fill; + this.panel7.Location = new System.Drawing.Point(3, 17); + this.panel7.Name = "panel7"; + this.panel7.Size = new System.Drawing.Size(183, 213); + this.panel7.TabIndex = 1; + this.panel7.Tag = "s1"; + // + // groupBox6 + // + this.groupBox6.Controls.Add(this.panel6); + this.groupBox6.Dock = System.Windows.Forms.DockStyle.Left; + this.groupBox6.Location = new System.Drawing.Point(3, 44); + this.groupBox6.Name = "groupBox6"; + this.groupBox6.Size = new System.Drawing.Size(238, 233); + this.groupBox6.TabIndex = 12; + this.groupBox6.TabStop = false; + this.groupBox6.Text = "System 0"; + // + // panel6 + // + this.panel6.AutoScroll = true; + this.panel6.Dock = System.Windows.Forms.DockStyle.Fill; + this.panel6.Location = new System.Drawing.Point(3, 17); + this.panel6.Name = "panel6"; + this.panel6.Size = new System.Drawing.Size(232, 213); + this.panel6.TabIndex = 0; + this.panel6.Tag = "s0"; + // + // panel11 + // + this.panel11.Controls.Add(this.groupBox8); + this.panel11.Controls.Add(this.groupBox4); + this.panel11.Controls.Add(this.groupBox2); + this.panel11.Controls.Add(this.groupBox5); + this.panel11.Dock = System.Windows.Forms.DockStyle.Right; + this.panel11.Location = new System.Drawing.Point(846, 44); + this.panel11.Name = "panel11"; + this.panel11.Padding = new System.Windows.Forms.Padding(5); + this.panel11.Size = new System.Drawing.Size(133, 233); + this.panel11.TabIndex = 13; + // + // groupBox8 + // + this.groupBox8.Controls.Add(this.radioButton17); + this.groupBox8.Controls.Add(this.radioButton13); + this.groupBox8.Controls.Add(this.radioButton16); + this.groupBox8.Dock = System.Windows.Forms.DockStyle.Top; + this.groupBox8.Location = new System.Drawing.Point(5, 149); + this.groupBox8.Name = "groupBox8"; + this.groupBox8.Size = new System.Drawing.Size(123, 48); + this.groupBox8.TabIndex = 12; + this.groupBox8.TabStop = false; + this.groupBox8.Text = "PBS"; + // + // radioButton17 + // + this.radioButton17.AutoSize = true; + this.radioButton17.Checked = true; + this.radioButton17.Location = new System.Drawing.Point(6, 20); + this.radioButton17.Name = "radioButton17"; + this.radioButton17.Size = new System.Drawing.Size(29, 16); + this.radioButton17.TabIndex = 10; + this.radioButton17.TabStop = true; + this.radioButton17.Text = "0"; + this.radioButton17.UseVisualStyleBackColor = true; + // + // radioButton13 + // + this.radioButton13.AutoSize = true; + this.radioButton13.Location = new System.Drawing.Point(76, 20); + this.radioButton13.Name = "radioButton13"; + this.radioButton13.Size = new System.Drawing.Size(29, 16); + this.radioButton13.TabIndex = 9; + this.radioButton13.Text = "2"; + this.radioButton13.UseVisualStyleBackColor = true; + // + // radioButton16 + // + this.radioButton16.AutoSize = true; + this.radioButton16.Location = new System.Drawing.Point(41, 20); + this.radioButton16.Name = "radioButton16"; + this.radioButton16.Size = new System.Drawing.Size(29, 16); + this.radioButton16.TabIndex = 9; + this.radioButton16.Text = "1"; + this.radioButton16.UseVisualStyleBackColor = true; + // + // groupBox4 + // + this.groupBox4.Controls.Add(this.radioButton12); + this.groupBox4.Controls.Add(this.radioButton10); + this.groupBox4.Controls.Add(this.radioButton11); + this.groupBox4.Dock = System.Windows.Forms.DockStyle.Top; + this.groupBox4.Location = new System.Drawing.Point(5, 101); + this.groupBox4.Name = "groupBox4"; + this.groupBox4.Size = new System.Drawing.Size(123, 48); + this.groupBox4.TabIndex = 11; + this.groupBox4.TabStop = false; + this.groupBox4.Text = "속도"; + // + // radioButton12 + // + this.radioButton12.AutoSize = true; + this.radioButton12.Checked = true; + this.radioButton12.Location = new System.Drawing.Point(7, 20); + this.radioButton12.Name = "radioButton12"; + this.radioButton12.Size = new System.Drawing.Size(30, 16); + this.radioButton12.TabIndex = 10; + this.radioButton12.TabStop = true; + this.radioButton12.Text = "L"; + this.radioButton12.UseVisualStyleBackColor = true; + // + // radioButton10 + // + this.radioButton10.AutoSize = true; + this.radioButton10.Location = new System.Drawing.Point(83, 20); + this.radioButton10.Name = "radioButton10"; + this.radioButton10.Size = new System.Drawing.Size(31, 16); + this.radioButton10.TabIndex = 9; + this.radioButton10.Text = "H"; + this.radioButton10.UseVisualStyleBackColor = true; + // + // radioButton11 + // + this.radioButton11.AutoSize = true; + this.radioButton11.Location = new System.Drawing.Point(44, 20); + this.radioButton11.Name = "radioButton11"; + this.radioButton11.Size = new System.Drawing.Size(34, 16); + this.radioButton11.TabIndex = 9; + this.radioButton11.Text = "M"; + this.radioButton11.UseVisualStyleBackColor = true; + // + // groupBox2 + // + this.groupBox2.Controls.Add(this.radioButton9); + this.groupBox2.Controls.Add(this.radioButton8); + this.groupBox2.Controls.Add(this.radioButton7); + this.groupBox2.Dock = System.Windows.Forms.DockStyle.Top; + this.groupBox2.Location = new System.Drawing.Point(5, 53); + this.groupBox2.Name = "groupBox2"; + this.groupBox2.Size = new System.Drawing.Size(123, 48); + this.groupBox2.TabIndex = 10; + this.groupBox2.TabStop = false; + this.groupBox2.Text = "분기"; + // + // radioButton9 + // + this.radioButton9.AutoSize = true; + this.radioButton9.Location = new System.Drawing.Point(80, 20); + this.radioButton9.Name = "radioButton9"; + this.radioButton9.Size = new System.Drawing.Size(31, 16); + this.radioButton9.TabIndex = 9; + this.radioButton9.Text = "R"; + this.radioButton9.UseVisualStyleBackColor = true; + // + // radioButton8 + // + this.radioButton8.AutoSize = true; + this.radioButton8.Checked = true; + this.radioButton8.Location = new System.Drawing.Point(43, 20); + this.radioButton8.Name = "radioButton8"; + this.radioButton8.Size = new System.Drawing.Size(31, 16); + this.radioButton8.TabIndex = 9; + this.radioButton8.TabStop = true; + this.radioButton8.Text = "S"; + this.radioButton8.UseVisualStyleBackColor = true; + // + // radioButton7 + // + this.radioButton7.AutoSize = true; + this.radioButton7.Location = new System.Drawing.Point(7, 20); + this.radioButton7.Name = "radioButton7"; + this.radioButton7.Size = new System.Drawing.Size(30, 16); + this.radioButton7.TabIndex = 9; + this.radioButton7.Text = "L"; + this.radioButton7.UseVisualStyleBackColor = true; + // + // groupBox5 + // + this.groupBox5.Controls.Add(this.radioButton14); + this.groupBox5.Controls.Add(this.radioButton15); + this.groupBox5.Dock = System.Windows.Forms.DockStyle.Top; + this.groupBox5.Location = new System.Drawing.Point(5, 5); + this.groupBox5.Name = "groupBox5"; + this.groupBox5.Size = new System.Drawing.Size(123, 48); + this.groupBox5.TabIndex = 11; + this.groupBox5.TabStop = false; + this.groupBox5.Text = "방향"; + // + // radioButton14 + // + this.radioButton14.AutoSize = true; + this.radioButton14.Location = new System.Drawing.Point(43, 20); + this.radioButton14.Name = "radioButton14"; + this.radioButton14.Size = new System.Drawing.Size(31, 16); + this.radioButton14.TabIndex = 9; + this.radioButton14.Text = "B"; + this.radioButton14.UseVisualStyleBackColor = true; + // + // radioButton15 + // + this.radioButton15.AutoSize = true; + this.radioButton15.Checked = true; + this.radioButton15.Location = new System.Drawing.Point(7, 20); + this.radioButton15.Name = "radioButton15"; + this.radioButton15.Size = new System.Drawing.Size(30, 16); + this.radioButton15.TabIndex = 9; + this.radioButton15.TabStop = true; + this.radioButton15.Text = "F"; + this.radioButton15.UseVisualStyleBackColor = true; + // + // panel13 + // + this.panel13.Controls.Add(this.chkSimulation); + this.panel13.Controls.Add(this.checkBox3); + this.panel13.Dock = System.Windows.Forms.DockStyle.Top; + this.panel13.Location = new System.Drawing.Point(3, 17); + this.panel13.Name = "panel13"; + this.panel13.Size = new System.Drawing.Size(976, 27); + this.panel13.TabIndex = 14; + // + // chkSimulation + // + this.chkSimulation.Checked = true; + this.chkSimulation.CheckState = System.Windows.Forms.CheckState.Checked; + this.chkSimulation.Dock = System.Windows.Forms.DockStyle.Left; + this.chkSimulation.Location = new System.Drawing.Point(122, 0); + this.chkSimulation.Name = "chkSimulation"; + this.chkSimulation.Padding = new System.Windows.Forms.Padding(10, 0, 0, 0); + this.chkSimulation.Size = new System.Drawing.Size(122, 27); + this.chkSimulation.TabIndex = 9; + this.chkSimulation.Text = "Animation"; + this.chkSimulation.UseVisualStyleBackColor = true; + // + // checkBox3 + // + this.checkBox3.Checked = true; + this.checkBox3.CheckState = System.Windows.Forms.CheckState.Checked; + this.checkBox3.Dock = System.Windows.Forms.DockStyle.Left; + this.checkBox3.Location = new System.Drawing.Point(0, 0); + this.checkBox3.Name = "checkBox3"; + this.checkBox3.Padding = new System.Windows.Forms.Padding(10, 0, 0, 0); + this.checkBox3.Size = new System.Drawing.Size(122, 27); + this.checkBox3.TabIndex = 8; + this.checkBox3.Text = "Send Status"; + this.checkBox3.UseVisualStyleBackColor = true; + // + // panel10 + // + this.panel10.Controls.Add(this.numericUpDown1); + this.panel10.Controls.Add(this.button18); + this.panel10.Controls.Add(this.button17); + this.panel10.Controls.Add(this.button15); + this.panel10.Controls.Add(this.button16); + this.panel10.Controls.Add(this.button14); + this.panel10.Controls.Add(this.button5); + this.panel10.Controls.Add(this.button4); + this.panel10.Dock = System.Windows.Forms.DockStyle.Right; + this.panel10.Location = new System.Drawing.Point(982, 0); + this.panel10.Name = "panel10"; + this.panel10.Size = new System.Drawing.Size(158, 280); + this.panel10.TabIndex = 14; + // + // numericUpDown1 + // + this.numericUpDown1.Font = new System.Drawing.Font("굴림", 20F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(129))); + this.numericUpDown1.Location = new System.Drawing.Point(19, 220); + this.numericUpDown1.Name = "numericUpDown1"; + this.numericUpDown1.Size = new System.Drawing.Size(130, 38); + this.numericUpDown1.TabIndex = 9; + this.numericUpDown1.Text = "101"; + this.numericUpDown1.TextAlign = System.Windows.Forms.HorizontalAlignment.Center; + this.numericUpDown1.KeyDown += new System.Windows.Forms.KeyEventHandler(this.numericUpDown1_KeyDown); + // + // button18 + // + this.button18.Location = new System.Drawing.Point(19, 187); + this.button18.Name = "button18"; + this.button18.Size = new System.Drawing.Size(130, 28); + this.button18.TabIndex = 8; + this.button18.Tag = "--"; + this.button18.Text = "TAG"; + this.button18.UseVisualStyleBackColor = true; + this.button18.Click += new System.EventHandler(this.button18_Click); + // + // button17 + // + this.button17.Location = new System.Drawing.Point(87, 68); + this.button17.Name = "button17"; + this.button17.Size = new System.Drawing.Size(62, 54); + this.button17.TabIndex = 7; + this.button17.Text = "reset"; + this.button17.UseVisualStyleBackColor = true; + this.button17.Click += new System.EventHandler(this.button17_Click); + // + // button15 + // + this.button15.Location = new System.Drawing.Point(87, 128); + this.button15.Name = "button15"; + this.button15.Size = new System.Drawing.Size(62, 54); + this.button15.TabIndex = 6; + this.button15.Tag = "--"; + this.button15.Text = "PBS Of"; + this.button15.UseVisualStyleBackColor = true; + this.button15.Click += new System.EventHandler(this.button15_Click); + // + // button16 + // + this.button16.Location = new System.Drawing.Point(19, 126); + this.button16.Name = "button16"; + this.button16.Size = new System.Drawing.Size(62, 54); + this.button16.TabIndex = 5; + this.button16.Tag = "--"; + this.button16.Text = "PBS On"; + this.button16.UseVisualStyleBackColor = true; + this.button16.Click += new System.EventHandler(this.button16_Click); + // + // button14 + // + this.button14.Location = new System.Drawing.Point(19, 66); + this.button14.Name = "button14"; + this.button14.Size = new System.Drawing.Size(62, 54); + this.button14.TabIndex = 3; + this.button14.Text = "emg"; + this.button14.UseVisualStyleBackColor = true; + this.button14.Click += new System.EventHandler(this.button14_Click); + // + // button5 + // + this.button5.Location = new System.Drawing.Point(19, 6); + this.button5.Name = "button5"; + this.button5.Size = new System.Drawing.Size(62, 54); + this.button5.TabIndex = 2; + this.button5.Text = "ACK"; + this.button5.UseVisualStyleBackColor = true; + this.button5.Click += new System.EventHandler(this.button5_Click); + // + // button4 + // + this.button4.Location = new System.Drawing.Point(87, 6); + this.button4.Name = "button4"; + this.button4.Size = new System.Drawing.Size(62, 54); + this.button4.TabIndex = 1; + this.button4.Text = "NAK"; + this.button4.UseVisualStyleBackColor = true; + this.button4.Click += new System.EventHandler(this.button4_Click); + // + // groupBox3 + // + this.groupBox3.Controls.Add(this.rtCAL); + this.groupBox3.Controls.Add(this.serCAL); + this.groupBox3.Dock = System.Windows.Forms.DockStyle.Left; + this.groupBox3.Location = new System.Drawing.Point(0, 0); + this.groupBox3.Name = "groupBox3"; + this.groupBox3.Size = new System.Drawing.Size(782, 622); + this.groupBox3.TabIndex = 0; + this.groupBox3.TabStop = false; + this.groupBox3.Text = "ACS"; + // + // rtCAL + // + this.rtCAL.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(24)))), ((int)(((byte)(24)))), ((int)(((byte)(24))))); + this.rtCAL.ColorList = new arCtl.sLogMessageColor[0]; + this.rtCAL.DateFormat = "ss.fff"; + this.rtCAL.DefaultColor = System.Drawing.Color.LightGray; + this.rtCAL.Dock = System.Windows.Forms.DockStyle.Fill; + this.rtCAL.EnableDisplayTimer = false; + this.rtCAL.EnableGubunColor = true; + this.rtCAL.Font = new System.Drawing.Font("Consolas", 9F); + this.rtCAL.ListFormat = "[{0}] {1}"; + this.rtCAL.Location = new System.Drawing.Point(3, 101); + this.rtCAL.MaxListCount = ((ushort)(200)); + this.rtCAL.MaxTextLength = ((uint)(4000u)); + this.rtCAL.MessageInterval = 50; + this.rtCAL.Name = "rtCAL"; + this.rtCAL.Size = new System.Drawing.Size(776, 518); + this.rtCAL.TabIndex = 2; + this.rtCAL.Text = ""; + // + // timer1 + // + this.timer1.Interval = 200; + this.timer1.Tick += new System.EventHandler(this.timer1_Tick); + // + // tabControl1 + // + this.tabControl1.Controls.Add(this.tabPage4); + this.tabControl1.Controls.Add(this.tabPage1); + this.tabControl1.Controls.Add(this.tabPage2); + this.tabControl1.Controls.Add(this.tabPage3); + this.tabControl1.Dock = System.Windows.Forms.DockStyle.Fill; + this.tabControl1.Location = new System.Drawing.Point(0, 25); + this.tabControl1.Name = "tabControl1"; + this.tabControl1.SelectedIndex = 0; + this.tabControl1.Size = new System.Drawing.Size(1154, 648); + this.tabControl1.TabIndex = 3; + // + // tabPage4 + // + this.tabPage4.Location = new System.Drawing.Point(4, 22); + this.tabPage4.Name = "tabPage4"; + this.tabPage4.Size = new System.Drawing.Size(1146, 622); + this.tabPage4.TabIndex = 3; + this.tabPage4.Text = "Display"; + this.tabPage4.UseVisualStyleBackColor = true; + // + // tabPage1 + // + this.tabPage1.Controls.Add(this.tableLayoutPanel3); + this.tabPage1.Controls.Add(this.panel4); + this.tabPage1.Controls.Add(this.panel12); + this.tabPage1.Location = new System.Drawing.Point(4, 22); + this.tabPage1.Name = "tabPage1"; + this.tabPage1.Padding = new System.Windows.Forms.Padding(3); + this.tabPage1.Size = new System.Drawing.Size(1146, 622); + this.tabPage1.TabIndex = 0; + this.tabPage1.Text = "AGV"; + this.tabPage1.UseVisualStyleBackColor = true; + // + // tableLayoutPanel3 + // + this.tableLayoutPanel3.ColumnCount = 2; + this.tableLayoutPanel3.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 100F)); + this.tableLayoutPanel3.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Absolute, 339F)); + this.tableLayoutPanel3.Controls.Add(this.rtAGVPro, 1, 0); + this.tableLayoutPanel3.Controls.Add(this.rtAGV, 0, 0); + this.tableLayoutPanel3.Dock = System.Windows.Forms.DockStyle.Fill; + this.tableLayoutPanel3.Location = new System.Drawing.Point(3, 403); + this.tableLayoutPanel3.Name = "tableLayoutPanel3"; + this.tableLayoutPanel3.RowCount = 1; + this.tableLayoutPanel3.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100F)); + this.tableLayoutPanel3.Size = new System.Drawing.Size(1140, 216); + this.tableLayoutPanel3.TabIndex = 4; + // + // rtAGVPro + // + this.rtAGVPro.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(24)))), ((int)(((byte)(24)))), ((int)(((byte)(24))))); + this.rtAGVPro.ColorList = new arCtl.sLogMessageColor[0]; + this.rtAGVPro.DateFormat = "ss.fff"; + this.rtAGVPro.DefaultColor = System.Drawing.Color.LightGray; + this.rtAGVPro.Dock = System.Windows.Forms.DockStyle.Fill; + this.rtAGVPro.EnableDisplayTimer = false; + this.rtAGVPro.EnableGubunColor = true; + this.rtAGVPro.Font = new System.Drawing.Font("Consolas", 9F); + this.rtAGVPro.ListFormat = "[{0}] {1}"; + this.rtAGVPro.Location = new System.Drawing.Point(804, 3); + this.rtAGVPro.MaxListCount = ((ushort)(200)); + this.rtAGVPro.MaxTextLength = ((uint)(4000u)); + this.rtAGVPro.MessageInterval = 50; + this.rtAGVPro.Name = "rtAGVPro"; + this.rtAGVPro.Size = new System.Drawing.Size(333, 210); + this.rtAGVPro.TabIndex = 5; + this.rtAGVPro.Text = ""; + // + // panel12 + // + this.panel12.Controls.Add(this.agvViewer1); + this.panel12.Controls.Add(this.serAGV); + this.panel12.Dock = System.Windows.Forms.DockStyle.Top; + this.panel12.Location = new System.Drawing.Point(3, 3); + this.panel12.Name = "panel12"; + this.panel12.Size = new System.Drawing.Size(1140, 120); + this.panel12.TabIndex = 5; + // + // tabPage2 + // + this.tabPage2.Controls.Add(this.groupBox1); + this.tabPage2.Location = new System.Drawing.Point(4, 22); + this.tabPage2.Name = "tabPage2"; + this.tabPage2.Padding = new System.Windows.Forms.Padding(3); + this.tabPage2.Size = new System.Drawing.Size(1146, 622); + this.tabPage2.TabIndex = 1; + this.tabPage2.Text = "BMS"; + this.tabPage2.UseVisualStyleBackColor = true; + // + // tabPage3 + // + this.tabPage3.Controls.Add(this.panel3); + this.tabPage3.Controls.Add(this.groupBox3); + this.tabPage3.Location = new System.Drawing.Point(4, 22); + this.tabPage3.Name = "tabPage3"; + this.tabPage3.Size = new System.Drawing.Size(1146, 622); + this.tabPage3.TabIndex = 2; + this.tabPage3.Text = "ACS"; + this.tabPage3.UseVisualStyleBackColor = true; + // + // panel3 + // + this.panel3.Controls.Add(this.nudIDAgv); + this.panel3.Controls.Add(this.label7); + this.panel3.Controls.Add(this.numericUpDown2); + this.panel3.Controls.Add(this.button1); + this.panel3.Controls.Add(this.nudTagNo); + this.panel3.Controls.Add(this.btacsgoto); + this.panel3.Controls.Add(this.button7); + this.panel3.Controls.Add(this.button8); + this.panel3.Controls.Add(this.button9); + this.panel3.Controls.Add(this.button10); + this.panel3.Controls.Add(this.button11); + this.panel3.Controls.Add(this.button12); + this.panel3.Dock = System.Windows.Forms.DockStyle.Fill; + this.panel3.Location = new System.Drawing.Point(782, 0); + this.panel3.Name = "panel3"; + this.panel3.Size = new System.Drawing.Size(364, 622); + this.panel3.TabIndex = 15; + // + // nudIDAgv + // + this.nudIDAgv.Font = new System.Drawing.Font("굴림", 20F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(129))); + this.nudIDAgv.Location = new System.Drawing.Point(6, 249); + this.nudIDAgv.Maximum = new decimal(new int[] { + 9999999, + 0, + 0, + 0}); + this.nudIDAgv.Name = "nudIDAgv"; + this.nudIDAgv.Size = new System.Drawing.Size(98, 38); + this.nudIDAgv.TabIndex = 13; + this.nudIDAgv.TextAlign = System.Windows.Forms.HorizontalAlignment.Center; + this.nudIDAgv.Value = new decimal(new int[] { + 10, + 0, + 0, + 0}); + // + // label7 + // + this.label7.AutoSize = true; + this.label7.Location = new System.Drawing.Point(32, 220); + this.label7.Name = "label7"; + this.label7.Size = new System.Drawing.Size(45, 12); + this.label7.TabIndex = 12; + this.label7.Text = "AGV ID"; + // + // numericUpDown2 + // + this.numericUpDown2.Font = new System.Drawing.Font("굴림", 20F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(129))); + this.numericUpDown2.Location = new System.Drawing.Point(110, 207); + this.numericUpDown2.Maximum = new decimal(new int[] { + 9999999, + 0, + 0, + 0}); + this.numericUpDown2.Name = "numericUpDown2"; + this.numericUpDown2.Size = new System.Drawing.Size(130, 38); + this.numericUpDown2.TabIndex = 11; + this.numericUpDown2.TextAlign = System.Windows.Forms.HorizontalAlignment.Center; + this.numericUpDown2.Value = new decimal(new int[] { + 100, + 0, + 0, + 0}); + // + // button1 + // + this.button1.Location = new System.Drawing.Point(246, 207); + this.button1.Name = "button1"; + this.button1.Size = new System.Drawing.Size(86, 38); + this.button1.TabIndex = 10; + this.button1.Tag = "--"; + this.button1.Text = "Set"; + this.button1.UseVisualStyleBackColor = true; + this.button1.Click += new System.EventHandler(this.button1_Click); + // + // nudTagNo + // + this.nudTagNo.Font = new System.Drawing.Font("굴림", 20F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(129))); + this.nudTagNo.Location = new System.Drawing.Point(110, 251); + this.nudTagNo.Maximum = new decimal(new int[] { + 9999999, + 0, + 0, + 0}); + this.nudTagNo.Name = "nudTagNo"; + this.nudTagNo.Size = new System.Drawing.Size(130, 38); + this.nudTagNo.TabIndex = 9; + this.nudTagNo.TextAlign = System.Windows.Forms.HorizontalAlignment.Center; + this.nudTagNo.Value = new decimal(new int[] { + 405, + 0, + 0, + 0}); + // + // btacsgoto + // + this.btacsgoto.Location = new System.Drawing.Point(246, 251); + this.btacsgoto.Name = "btacsgoto"; + this.btacsgoto.Size = new System.Drawing.Size(86, 38); + this.btacsgoto.TabIndex = 8; + this.btacsgoto.Tag = "--"; + this.btacsgoto.Text = "Goto"; + this.btacsgoto.UseVisualStyleBackColor = true; + this.btacsgoto.Click += new System.EventHandler(this.button6_Click); + // + // button7 + // + this.button7.Location = new System.Drawing.Point(83, 72); + this.button7.Name = "button7"; + this.button7.Size = new System.Drawing.Size(62, 54); + this.button7.TabIndex = 7; + this.button7.Text = "--"; + this.button7.UseVisualStyleBackColor = true; + // + // button8 + // + this.button8.Location = new System.Drawing.Point(83, 132); + this.button8.Name = "button8"; + this.button8.Size = new System.Drawing.Size(62, 54); + this.button8.TabIndex = 6; + this.button8.Tag = "--"; + this.button8.Text = "--"; + this.button8.UseVisualStyleBackColor = true; + // + // button9 + // + this.button9.Location = new System.Drawing.Point(15, 130); + this.button9.Name = "button9"; + this.button9.Size = new System.Drawing.Size(62, 54); + this.button9.TabIndex = 5; + this.button9.Tag = "--"; + this.button9.Text = "--"; + this.button9.UseVisualStyleBackColor = true; + // + // button10 + // + this.button10.Location = new System.Drawing.Point(15, 70); + this.button10.Name = "button10"; + this.button10.Size = new System.Drawing.Size(62, 54); + this.button10.TabIndex = 3; + this.button10.Text = "--"; + this.button10.UseVisualStyleBackColor = true; + // + // button11 + // + this.button11.Location = new System.Drawing.Point(15, 10); + this.button11.Name = "button11"; + this.button11.Size = new System.Drawing.Size(62, 54); + this.button11.TabIndex = 2; + this.button11.Text = "--"; + this.button11.UseVisualStyleBackColor = true; + // + // button12 + // + this.button12.Location = new System.Drawing.Point(83, 10); + this.button12.Name = "button12"; + this.button12.Size = new System.Drawing.Size(62, 54); + this.button12.TabIndex = 1; + this.button12.Text = "--"; + this.button12.UseVisualStyleBackColor = true; + // + // toolStrip1 + // + this.toolStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { + this.toolStripButton1, + this.toolStripButton2, + this.toolStripSeparator1, + this.toolStripButton3, + this.toolStripButton4, + this.toolStripButton5}); + this.toolStrip1.Location = new System.Drawing.Point(0, 0); + this.toolStrip1.Name = "toolStrip1"; + this.toolStrip1.Size = new System.Drawing.Size(1154, 25); + this.toolStrip1.TabIndex = 4; + this.toolStrip1.Text = "toolStrip1"; + // + // toolStripButton1 + // + this.toolStripButton1.Image = ((System.Drawing.Image)(resources.GetObject("toolStripButton1.Image"))); + this.toolStripButton1.ImageTransparentColor = System.Drawing.Color.Magenta; + this.toolStripButton1.Name = "toolStripButton1"; + this.toolStripButton1.Size = new System.Drawing.Size(74, 22); + this.toolStripButton1.Text = "All Open"; + this.toolStripButton1.Click += new System.EventHandler(this.toolStripButton1_Click); + // + // toolStripButton2 + // + this.toolStripButton2.Image = ((System.Drawing.Image)(resources.GetObject("toolStripButton2.Image"))); + this.toolStripButton2.ImageTransparentColor = System.Drawing.Color.Magenta; + this.toolStripButton2.Name = "toolStripButton2"; + this.toolStripButton2.Size = new System.Drawing.Size(74, 22); + this.toolStripButton2.Text = "All Close"; + this.toolStripButton2.Click += new System.EventHandler(this.toolStripButton2_Click); + // + // statusStrip1 + // + this.statusStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { + this.toolStripStatusLabel8, + this.sbAGV, + this.toolStripStatusLabel4, + this.sbBMS, + this.toolStripStatusLabel2, + this.sbCAL}); + this.statusStrip1.Location = new System.Drawing.Point(0, 673); + this.statusStrip1.Name = "statusStrip1"; + this.statusStrip1.Size = new System.Drawing.Size(1154, 22); + this.statusStrip1.TabIndex = 5; + this.statusStrip1.Text = "statusStrip1"; + // + // toolStripStatusLabel8 + // + this.toolStripStatusLabel8.Name = "toolStripStatusLabel8"; + this.toolStripStatusLabel8.Size = new System.Drawing.Size(31, 17); + this.toolStripStatusLabel8.Text = "AGV"; + // + // sbAGV + // + this.sbAGV.Name = "sbAGV"; + this.sbAGV.Size = new System.Drawing.Size(19, 17); + this.sbAGV.Text = "●"; + // + // toolStripStatusLabel4 + // + this.toolStripStatusLabel4.Name = "toolStripStatusLabel4"; + this.toolStripStatusLabel4.Size = new System.Drawing.Size(32, 17); + this.toolStripStatusLabel4.Text = "BMS"; + // + // sbBMS + // + this.sbBMS.Name = "sbBMS"; + this.sbBMS.Size = new System.Drawing.Size(19, 17); + this.sbBMS.Text = "●"; + // + // toolStripStatusLabel2 + // + this.toolStripStatusLabel2.Name = "toolStripStatusLabel2"; + this.toolStripStatusLabel2.Size = new System.Drawing.Size(30, 17); + this.toolStripStatusLabel2.Text = "ACS"; + // + // sbCAL + // + this.sbCAL.Name = "sbCAL"; + this.sbCAL.Size = new System.Drawing.Size(19, 17); + this.sbCAL.Text = "●"; + // + // toolStripSeparator1 + // + this.toolStripSeparator1.Name = "toolStripSeparator1"; + this.toolStripSeparator1.Size = new System.Drawing.Size(6, 25); + // + // toolStripButton3 + // + this.toolStripButton3.Image = ((System.Drawing.Image)(resources.GetObject("toolStripButton3.Image"))); + this.toolStripButton3.ImageTransparentColor = System.Drawing.Color.Magenta; + this.toolStripButton3.Name = "toolStripButton3"; + this.toolStripButton3.Size = new System.Drawing.Size(84, 22); + this.toolStripButton3.Text = "Open Map"; + this.toolStripButton3.Click += new System.EventHandler(this.toolStripButton3_Click); + // + // agvViewer1 + // + this.agvViewer1.Dock = System.Windows.Forms.DockStyle.Fill; + this.agvViewer1.FontMrk = new System.Drawing.Font("Microsoft Sans Serif", 7F); + this.agvViewer1.FontTag = new System.Drawing.Font("Microsoft Sans Serif", 6.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this.agvViewer1.lastmark = ""; + this.agvViewer1.lastmarkdir = ""; + this.agvViewer1.lasttag = ""; + this.agvViewer1.lasttagdir = ""; + ptdata57.active = false; + ptdata57.data = "NOT"; + ptdata57.pos = 30F; + ptdata58.active = false; + ptdata58.data = "QA"; + ptdata58.pos = 200F; + ptdata59.active = false; + ptdata59.data = "CHG"; + ptdata59.pos = 300F; + ptdata60.active = false; + ptdata60.data = "QC"; + ptdata60.pos = 400F; + ptdata61.active = false; + ptdata61.data = "#FVI-1"; + ptdata61.pos = 500F; + ptdata62.active = false; + ptdata62.data = "#FVI-2"; + ptdata62.pos = 600F; + ptdata63.active = false; + ptdata63.data = "#FVI-3"; + ptdata63.pos = 700F; + ptdata64.active = false; + ptdata64.data = "#FVI-4"; + ptdata64.pos = 800F; + ptdata65.active = false; + ptdata65.data = "#FVI-5"; + ptdata65.pos = 900F; + ptdata66.active = false; + ptdata66.data = "POT"; + ptdata66.pos = 970F; + this.agvViewer1.listMRK = new AGVEmulator.UC.AgvViewer.ptdata[] { + ptdata57, + ptdata58, + ptdata59, + ptdata60, + ptdata61, + ptdata62, + ptdata63, + ptdata64, + ptdata65, + ptdata66}; + ptdata67.active = false; + ptdata67.data = "9000"; + ptdata67.pos = 80F; + ptdata68.active = false; + ptdata68.data = "9001"; + ptdata68.pos = 120F; + ptdata69.active = false; + ptdata69.data = "9010"; + ptdata69.pos = 180F; + ptdata70.active = false; + ptdata70.data = "9011"; + ptdata70.pos = 220F; + ptdata71.active = false; + ptdata71.data = "9020"; + ptdata71.pos = 280F; + ptdata72.active = false; + ptdata72.data = "9021"; + ptdata72.pos = 320F; + ptdata73.active = false; + ptdata73.data = "9030"; + ptdata73.pos = 380F; + ptdata74.active = false; + ptdata74.data = "9031"; + ptdata74.pos = 420F; + ptdata75.active = false; + ptdata75.data = "9040"; + ptdata75.pos = 480F; + ptdata76.active = false; + ptdata76.data = "9041"; + ptdata76.pos = 520F; + ptdata77.active = false; + ptdata77.data = "9050"; + ptdata77.pos = 580F; + ptdata78.active = false; + ptdata78.data = "9051"; + ptdata78.pos = 620F; + ptdata79.active = false; + ptdata79.data = "9060"; + ptdata79.pos = 680F; + ptdata80.active = false; + ptdata80.data = "9061"; + ptdata80.pos = 720F; + ptdata81.active = false; + ptdata81.data = "9070"; + ptdata81.pos = 780F; + ptdata82.active = false; + ptdata82.data = "9071"; + ptdata82.pos = 820F; + ptdata83.active = false; + ptdata83.data = "9000"; + ptdata83.pos = 10F; + ptdata84.active = false; + ptdata84.data = "9001"; + ptdata84.pos = 50F; + this.agvViewer1.listTAG = new AGVEmulator.UC.AgvViewer.ptdata[] { + ptdata67, + ptdata68, + ptdata69, + ptdata70, + ptdata71, + ptdata72, + ptdata73, + ptdata74, + ptdata75, + ptdata76, + ptdata77, + ptdata78, + ptdata79, + ptdata80, + ptdata81, + ptdata82, + ptdata83, + ptdata84}; + this.agvViewer1.Location = new System.Drawing.Point(241, 0); + this.agvViewer1.Name = "agvViewer1"; + this.agvViewer1.Size = new System.Drawing.Size(899, 120); + this.agvViewer1.StopbyMark = false; + this.agvViewer1.TabIndex = 0; + this.agvViewer1.Text = "agvViewer1"; + this.agvViewer1.MouseDown += new System.Windows.Forms.MouseEventHandler(this.agvViewer1_MouseDown); + // + // serAGV + // + this.serAGV.BaudRate = 9600; + this.serAGV.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle; + this.serAGV.dev = null; + this.serAGV.Dock = System.Windows.Forms.DockStyle.Left; + this.serAGV.Location = new System.Drawing.Point(0, 0); + this.serAGV.Name = "serAGV"; + this.serAGV.PortName = "COM20"; + this.serAGV.Size = new System.Drawing.Size(241, 120); + this.serAGV.TabIndex = 0; + // + // serBMS + // + this.serBMS.BaudRate = 9600; + this.serBMS.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle; + this.serBMS.dev = null; + this.serBMS.Dock = System.Windows.Forms.DockStyle.Top; + this.serBMS.Location = new System.Drawing.Point(3, 17); + this.serBMS.Name = "serBMS"; + this.serBMS.PortName = "COM40"; + this.serBMS.Size = new System.Drawing.Size(1134, 84); + this.serBMS.TabIndex = 1; + // + // serCAL + // + this.serCAL.BaudRate = 9600; + this.serCAL.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle; + this.serCAL.dev = null; + this.serCAL.Dock = System.Windows.Forms.DockStyle.Top; + this.serCAL.Location = new System.Drawing.Point(3, 17); + this.serCAL.Name = "serCAL"; + this.serCAL.PortName = "COM50"; + this.serCAL.Size = new System.Drawing.Size(776, 84); + this.serCAL.TabIndex = 1; + // + // toolStripButton4 + // + this.toolStripButton4.Image = ((System.Drawing.Image)(resources.GetObject("toolStripButton4.Image"))); + this.toolStripButton4.ImageTransparentColor = System.Drawing.Color.Magenta; + this.toolStripButton4.Name = "toolStripButton4"; + this.toolStripButton4.Size = new System.Drawing.Size(117, 22); + this.toolStripButton4.Text = "Change Rotation"; + this.toolStripButton4.Click += new System.EventHandler(this.toolStripButton4_Click); + // + // toolStripButton5 + // + this.toolStripButton5.Image = ((System.Drawing.Image)(resources.GetObject("toolStripButton5.Image"))); + this.toolStripButton5.ImageTransparentColor = System.Drawing.Color.Magenta; + this.toolStripButton5.Name = "toolStripButton5"; + this.toolStripButton5.Size = new System.Drawing.Size(87, 22); + this.toolStripButton5.Text = "SetPosition"; + this.toolStripButton5.Click += new System.EventHandler(this.toolStripButton5_Click); + // + // fMain + // + this.AutoScaleDimensions = new System.Drawing.SizeF(7F, 12F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.ClientSize = new System.Drawing.Size(1154, 695); + this.Controls.Add(this.tabControl1); + this.Controls.Add(this.statusStrip1); + this.Controls.Add(this.toolStrip1); + this.Name = "fMain"; + this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen; + this.Text = "Form1"; + this.Load += new System.EventHandler(this.Form1_Load); + this.groupBox1.ResumeLayout(false); + this.panel1.ResumeLayout(false); + this.panel1.PerformLayout(); + ((System.ComponentModel.ISupportInitialize)(this.trbT2)).EndInit(); + ((System.ComponentModel.ISupportInitialize)(this.trbT1)).EndInit(); + ((System.ComponentModel.ISupportInitialize)(this.trackBar1)).EndInit(); + this.panel4.ResumeLayout(false); + this.groupBox9.ResumeLayout(false); + this.groupBox10.ResumeLayout(false); + this.groupBox10.PerformLayout(); + this.groupBox11.ResumeLayout(false); + this.groupBox11.PerformLayout(); + this.groupBox7.ResumeLayout(false); + this.groupBox7.PerformLayout(); + this.groupBox6.ResumeLayout(false); + this.panel11.ResumeLayout(false); + this.groupBox8.ResumeLayout(false); + this.groupBox8.PerformLayout(); + this.groupBox4.ResumeLayout(false); + this.groupBox4.PerformLayout(); + this.groupBox2.ResumeLayout(false); + this.groupBox2.PerformLayout(); + this.groupBox5.ResumeLayout(false); + this.groupBox5.PerformLayout(); + this.panel13.ResumeLayout(false); + this.panel10.ResumeLayout(false); + this.panel10.PerformLayout(); + this.groupBox3.ResumeLayout(false); + this.tabControl1.ResumeLayout(false); + this.tabPage1.ResumeLayout(false); + this.tableLayoutPanel3.ResumeLayout(false); + this.panel12.ResumeLayout(false); + this.tabPage2.ResumeLayout(false); + this.tabPage3.ResumeLayout(false); + this.panel3.ResumeLayout(false); + this.panel3.PerformLayout(); + ((System.ComponentModel.ISupportInitialize)(this.nudIDAgv)).EndInit(); + ((System.ComponentModel.ISupportInitialize)(this.numericUpDown2)).EndInit(); + ((System.ComponentModel.ISupportInitialize)(this.nudTagNo)).EndInit(); + this.toolStrip1.ResumeLayout(false); + this.toolStrip1.PerformLayout(); + this.statusStrip1.ResumeLayout(false); + this.statusStrip1.PerformLayout(); + this.ResumeLayout(false); + this.PerformLayout(); + + } + + #endregion + + private System.Windows.Forms.GroupBox groupBox1; + private System.Windows.Forms.GroupBox groupBox3; + private SerialConn serAGV; + private SerialConn serBMS; + private SerialConn serCAL; + private arCtl.LogTextBox rtBMS; + private arCtl.LogTextBox rtAGV; + private arCtl.LogTextBox rtCAL; + private System.Windows.Forms.Panel panel4; + private System.Windows.Forms.Button button4; + private System.Windows.Forms.Button button5; + private System.Windows.Forms.Panel panel1; + private System.Windows.Forms.TrackBar trackBar1; + private System.Windows.Forms.Label label1; + private System.Windows.Forms.Label label2; + private System.Windows.Forms.Label label3; + private System.Windows.Forms.Label label5; + private System.Windows.Forms.Label label4; + private System.Windows.Forms.Label label6; + private System.Windows.Forms.CheckBox checkBox1; + private System.Windows.Forms.Timer timer1; + private System.Windows.Forms.TabControl tabControl1; + private System.Windows.Forms.TabPage tabPage1; + private System.Windows.Forms.TabPage tabPage2; + private System.Windows.Forms.CheckBox checkBox3; + private System.Windows.Forms.GroupBox groupBox2; + private System.Windows.Forms.RadioButton radioButton7; + private System.Windows.Forms.RadioButton radioButton9; + private System.Windows.Forms.RadioButton radioButton8; + private System.Windows.Forms.GroupBox groupBox5; + private System.Windows.Forms.RadioButton radioButton14; + private System.Windows.Forms.RadioButton radioButton15; + private System.Windows.Forms.GroupBox groupBox4; + private System.Windows.Forms.RadioButton radioButton10; + private System.Windows.Forms.RadioButton radioButton11; + private System.Windows.Forms.GroupBox groupBox6; + private System.Windows.Forms.GroupBox groupBox7; + private System.Windows.Forms.GroupBox groupBox8; + private System.Windows.Forms.RadioButton radioButton13; + private System.Windows.Forms.RadioButton radioButton16; + private System.Windows.Forms.RadioButton radioButton12; + private System.Windows.Forms.RadioButton radioButton17; + private System.Windows.Forms.TableLayoutPanel tableLayoutPanel3; + private arCtl.LogTextBox rtAGVPro; + private System.Windows.Forms.GroupBox groupBox9; + private System.Windows.Forms.Panel panel6; + private System.Windows.Forms.Panel panel7; + private System.Windows.Forms.GroupBox groupBox10; + private System.Windows.Forms.Panel panel8; + private System.Windows.Forms.GroupBox groupBox11; + private System.Windows.Forms.Panel panel9; + private System.Windows.Forms.Panel panel10; + private System.Windows.Forms.Panel panel11; + private System.Windows.Forms.Button button14; + private System.Windows.Forms.Button button16; + private System.Windows.Forms.Button button15; + private System.Windows.Forms.Button button17; + private System.Windows.Forms.Button button18; + private TextBox numericUpDown1; + private System.Windows.Forms.Panel panel12; + private UC.AgvViewer agvViewer1; + private System.Windows.Forms.Panel panel13; + private System.Windows.Forms.CheckBox chkSimulation; + private System.Windows.Forms.ToolStrip toolStrip1; + private System.Windows.Forms.ToolStripButton toolStripButton1; + private System.Windows.Forms.ToolStripButton toolStripButton2; + private System.Windows.Forms.StatusStrip statusStrip1; + private System.Windows.Forms.ToolStripStatusLabel toolStripStatusLabel8; + private System.Windows.Forms.ToolStripStatusLabel sbAGV; + private System.Windows.Forms.ToolStripStatusLabel toolStripStatusLabel4; + private System.Windows.Forms.ToolStripStatusLabel sbBMS; + private System.Windows.Forms.ToolStripStatusLabel toolStripStatusLabel2; + private System.Windows.Forms.ToolStripStatusLabel sbCAL; + private System.Windows.Forms.Label btc8; + private System.Windows.Forms.Label btc4; + private System.Windows.Forms.Label btc7; + private System.Windows.Forms.Label btc3; + private System.Windows.Forms.Label btc6; + private System.Windows.Forms.Label btc2; + private System.Windows.Forms.Label btc5; + private System.Windows.Forms.Label btc1; + private System.Windows.Forms.TabPage tabPage3; + private System.Windows.Forms.Panel panel3; + private System.Windows.Forms.NumericUpDown nudTagNo; + private System.Windows.Forms.Button btacsgoto; + private System.Windows.Forms.Button button7; + private System.Windows.Forms.Button button8; + private System.Windows.Forms.Button button9; + private System.Windows.Forms.Button button10; + private System.Windows.Forms.Button button11; + private System.Windows.Forms.Button button12; + private System.Windows.Forms.NumericUpDown numericUpDown2; + private System.Windows.Forms.Button button1; + private System.Windows.Forms.Label label7; + private System.Windows.Forms.NumericUpDown nudIDAgv; + private System.Windows.Forms.Label label9; + private System.Windows.Forms.Label label8; + private System.Windows.Forms.TrackBar trbT2; + private System.Windows.Forms.TrackBar trbT1; + private System.Windows.Forms.Label label11; + private System.Windows.Forms.Label label10; + private TabPage tabPage4; + private ToolStripSeparator toolStripSeparator1; + private ToolStripButton toolStripButton3; + private ToolStripButton toolStripButton4; + private ToolStripButton toolStripButton5; + } +} + diff --git a/AGVEmulator/fMain.cs b/AGVEmulator/fMain.cs new file mode 100644 index 0000000..6f4bfc4 --- /dev/null +++ b/AGVEmulator/fMain.cs @@ -0,0 +1,943 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Globalization; +using System.IO; +using System.Linq; +using System.Security.Cryptography.X509Certificates; +using System.Text; +using System.Windows.Forms; +using System.Windows.Forms.VisualStyles; +using static AGVEmulator.DevAGV; +using AGVNavigationCore.Controls; +using AGVNavigationCore.Models; + +namespace AGVEmulator +{ + public partial class fMain : Form + { + arUtil.Log logAGV, logBMS, logCAL; + DevBMS BMS; + DevAGV AGV; + DevXBE XBE; + + // Map Control + private UnifiedAGVCanvas _agvCanvas; + private List _mapNodes; + private VirtualAGV _visualAgv; + + // Emulator State + private MapNode _targetNode = null; + private bool _isTurning = false; + private double _targetAngle = 0; + private PointF _currentPosF; // For smooth movement + + float BMS_MaxA = 80f; + float BMS_Remain = 79f; + float BMS_CurA = 70f; + float BMS_Volt = 25.4f; + + UInt16[] cellvolt = new UInt16[] { 0, 0, 0, 0, 0, 0, 0, 0 }; + + + public fMain() + { + InitializeComponent(); + this.Text = $"{Application.ProductName} ver.{Application.ProductVersion}"; + // logPLC = new arUtil.Log(); + logAGV = new arUtil.Log(); + logBMS = new arUtil.Log(); + logCAL = new arUtil.Log(); + + // logPLC.FileNameFormat = "{yyyyMMdd}_PLC"; + logAGV.FileNameFormat = "{yyyyMMdd}_AGV"; + logBMS.FileNameFormat = "{yyyyMMdd}_BMS"; + logCAL.FileNameFormat = "{yyyyMMdd}_CAL"; + + // logPLC.RaiseMsg += (s1, e1, d1) => { this.rtPLC.AddMsg(s1, e1, d1); }; + logAGV.RaiseMsg += (s1, e1, d1) => + { + if (d1.StartsWith("Tx")) + this.rtAGV.AddMsg(s1, e1, d1); + else + this.rtAGVPro.AddMsg(s1, e1, d1); + }; + logBMS.RaiseMsg += (s1, e1, d1) => { this.rtBMS.AddMsg(s1, e1, d1); }; + logCAL.RaiseMsg += (s1, e1, d1) => { this.rtCAL.AddMsg(s1, e1, d1); }; + + + var logcolor = new arCtl.sLogMessageColor[] { + new arCtl.sLogMessageColor("NORM", Color.White), + new arCtl.sLogMessageColor("INF", Color.SkyBlue), + new arCtl.sLogMessageColor("WARN", Color.Tomato), + new arCtl.sLogMessageColor("ERR", Color.Red), + new arCtl.sLogMessageColor("RX", Color.Lime), + new arCtl.sLogMessageColor("TX", Color.Orange), + }; + + //rtPLC.ColorList = logcolor; + rtAGV.ColorList = logcolor; + rtBMS.ColorList = logcolor; + rtCAL.ColorList = logcolor; + rtAGVPro.ColorList = logcolor; + + this.FormClosed += Form1_FormClosed; + + BMS = new DevBMS(); + AGV = new DevAGV(); + XBE = new DevXBE(); + this.serAGV.dev = AGV; + this.serBMS.dev = BMS; + this.serCAL.dev = XBE; + + BMS.Message += BMS_Message; + AGV.Message += AGV_Message; + XBE.Message += CAL_Message; + + BMS.RequestBatteryData += Bms_RequestBatteryData; + BMS.RequestVoltageData += BMS_RequestVoltageData; + XBE.ProtocReceived += CAL_ProtocReceived; + AGV.RequestStatusData += Agv_RequestStatusData; + AGV.ValueChanged += Agv_ValueChanged; + AGV.StsValueChanged += Agv_StsValueChanged; + AGV.Command += Agv_Command; + } + + Random rnd; + private void Form1_Load(object sender, EventArgs e) + { + rnd = new Random(3000); + + serAGV.BaudRate = 57600; + // serPLC.BaudRate = 57600; + trackBar1_Scroll(null, null); + trbT2_Scroll(null, null); + trbT1_Scroll(null, null); + timer1.Start(); + + //plc inout 이름 설정 + List titles = new List(); + List values = new List(); + + + + + var arrs = Enum.GetNames(typeof(DevAGV.esystemflag0)); + foreach (var item in arrs) + { + var data = (DevAGV.esystemflag0)Enum.Parse(typeof(DevAGV.esystemflag0), item); + + var chk = new CheckBox(); + chk.Text = $"[{(int)data:00}] {item}"; + chk.AutoSize = true; + chk.Visible = true; + chk.Tag = (int)data; + chk.Dock = DockStyle.Top; + chk.CheckedChanged += Chk_CheckedChanged; + this.panel6.Controls.Add(chk); + chk.Checked = true; //기본값 rue + } + arrs = Enum.GetNames(typeof(DevAGV.esystemflag1)); + foreach (var item in arrs) + { + var data = (DevAGV.esystemflag1)Enum.Parse(typeof(DevAGV.esystemflag1), item); + + var chk = new CheckBox(); + chk.Text = $"[{(int)data:00}] {item}"; + chk.AutoSize = true; + chk.Visible = true; + chk.Tag = (int)data; + chk.Dock = DockStyle.Top; + chk.CheckedChanged += Chk_CheckedChanged; + this.panel7.Controls.Add(chk); + } + arrs = Enum.GetNames(typeof(DevAGV.esignal)); + foreach (var item in arrs) + { + var data = (DevAGV.esignal)Enum.Parse(typeof(DevAGV.esignal), item); + + var chk = new CheckBox(); + chk.Text = $"[{(int)data:00}] {item}"; + chk.AutoSize = true; + chk.Visible = true; + chk.Tag = (int)data; + chk.Dock = DockStyle.Top; + chk.CheckedChanged += Chk_CheckedChanged; + this.panel8.Controls.Add(chk); + } + arrs = Enum.GetNames(typeof(DevAGV.eerror)); + foreach (var item in arrs) + { + var data = (DevAGV.eerror)Enum.Parse(typeof(DevAGV.eerror), item); + + var chk = new CheckBox(); + chk.Text = $"[{(int)data:00}] {item}"; + chk.AutoSize = true; + chk.Visible = true; + chk.Tag = (int)data; + chk.Dock = DockStyle.Top; + chk.CheckedChanged += Chk_CheckedChanged; + this.panel9.Controls.Add(chk); + } + + //기본 중지상태로 변환 + AGV.SetAGV(DevAGV.esystemflag1.agv_stop, true); + + foreach (RadioButton rad in groupBox5.Controls) + { + rad.CheckedChanged += (s1, e1) => + { + if (rad.Checked) + { + AGV.sts_dir = rad.Text[0]; + } + }; + } + foreach (RadioButton rad in groupBox2.Controls) + { + rad.CheckedChanged += (s1, e1) => + { + if (rad.Checked) + { + AGV.sts_bunki = rad.Text[0]; + } + }; + } + foreach (RadioButton rad in groupBox4.Controls) + { + rad.CheckedChanged += (s1, e1) => + { + if (rad.Checked) + { + AGV.sts_speed = rad.Text[0]; + } + }; + } + foreach (RadioButton rad in groupBox8.Controls) + { + rad.CheckedChanged += (s1, e1) => + { + if (rad.Checked) + { + AGV.sts_sensor = rad.Text[0]; + } + }; + } + + MakeViewer(); + InitializeMapControl(); + + + agvViewer1.TagTouched += AgvViewer1_TagTouched; + agvViewer1.MarkTouched += AgvViewer1_MarkTouched; + agvViewer1.Command += AgvViewer1_Command; + } + + void MakeViewer() + { + //태그목록 + List listTAG = new List(); + //var strtag = new string[] { + // "9000", "9001", //not + // "9010", "9011", + // //"9020", "9021", + // "9030", "9031", + // // "9040", "9041", + // "9050", "9051", + // // "9060", "9061", + // "9070", "9071", + // "9080", "9081", + // "9090", "9091"}; + + //foreach(var tag in strtag) + //{ + // listTAG.Add(new UC.AgvViewer.ptdata { + // active=false, + // data = tag, + // pos = + // }); + //} + //agvViewer1.listTAG = listTAG.ToArray(); + + //마크지점 + List listMRK = new List(); + var strmark = new string[] { "NOT", "QC", "CHG", "{0}", "#1", "{1}", "#2", "{2}", "#3", "{3}", "#4", "POT" }; + var pos = 50; + var tagstart = 9000; + foreach (var item in strmark) + { + listMRK.Add(new UC.AgvViewer.ptdata + { + pos = pos, + data = item, + }); + + + if (item.Equals("CHG")) + { + pos += 100; + continue; + } + else if (item.Equals("{0}")) tagstart = 9350; + else if (item.Equals("{1}")) tagstart = 9450; + else if (item.Equals("{2}")) tagstart = 9550; + else if (item.Equals("{3}")) tagstart = 9650; + else if (item.Equals("#1")) tagstart = 9400; + else if (item.Equals("#2")) tagstart = 9500; + else if (item.Equals("#3")) tagstart = 9600; + else if (item.Equals("#4")) tagstart = 9700; + + + //지정위치 좌우에 태그를 심는다 + listTAG.Add(new UC.AgvViewer.ptdata + { + pos = pos - 20, + data = tagstart.ToString(), + }); + + if (item.Equals("NOT") == false && item.Equals("POT") == false && item.StartsWith("{") == false) + tagstart += 1; + + + listTAG.Add(new UC.AgvViewer.ptdata + { + pos = pos + 20, + data = tagstart.ToString(), + }); + + + pos += 100; + + if (item.Equals("NOT") == false && item.Equals("POT") == false && item.StartsWith("{") == false) + tagstart += 99; + else + tagstart += 100; + + + if (item.Equals("NOT")) + tagstart = 9300; + + //else + //{ + // pos += 100; + // tagstart += 10; + //} + + } + agvViewer1.listMRK = listMRK.ToArray(); + agvViewer1.listTAG = listTAG.ToArray(); + agvViewer1.Invalidate(); + + } + private void AgvViewer1_Command(object sender, UC.AgvViewer.TagArgs e) + { + if (e.Data == "stop") + { + AGV.SetAGV(esystemflag1.agv_run, false); + AGV.SetAGV(esystemflag1.agv_stop, true); + logAGV.Add("시뮬로부터 자동 중지"); + } + } + + private void AgvViewer1_MarkTouched(object sender, UC.AgvViewer.TagArgs e) + { + // throw new NotImplementedException(); + AGV.SetAGV(esignal.mark_sensor_1, e.Active); + logAGV.Add($"mark {e.Data} touch:{e.Active}"); + } + + private void AgvViewer1_TagTouched(object sender, UC.AgvViewer.TagArgs e) + { + logAGV.Add($"tag touch:{e.Data}"); + numericUpDown1.Text = e.Data;// decimal.Parse(e.Data); + button18.PerformClick(); + + UpdateVisualAgvPosition(e.Data); + } + + void InitializeMapControl() + { + _agvCanvas = new UnifiedAGVCanvas(); + _agvCanvas.Dock = DockStyle.Fill; + _agvCanvas.Mode = UnifiedAGVCanvas.CanvasMode.Emulator; // Enable Emulator Mode + _agvCanvas.NodeRightClicked += _agvCanvas_NodeRightClicked; + this.tabPage4.Controls.Add(_agvCanvas); + + // Load Map + // Try to find map file in standard location + string mapDir = Path.GetFullPath(Path.Combine(Application.StartupPath, @"..\..\..\..\Cs_HMI\Data")); + string mapPath = Path.Combine(mapDir, "NewMap.agvmap"); + + if (!File.Exists(mapPath)) + { + if (Directory.Exists(mapDir)) + { + var files = Directory.GetFiles(mapDir, "*.agvmap"); + if (files.Length > 0) mapPath = files[0]; + } + } + + if (File.Exists(mapPath)) + { + try + { + var mapresult = MapLoader.LoadMapFromFile(mapPath); + _mapNodes = mapresult.Nodes; + _agvCanvas.Nodes = _mapNodes; + _agvCanvas.FitToNodes(); + + // Initialize Visual AGV + if (_mapNodes.Count > 0) + { + _visualAgv = new VirtualAGV("AGV01", _mapNodes[0].Position); + _agvCanvas.AGVList = new List { _visualAgv }; + } + } + catch (Exception ex) + { + logAGV.Add($"Map Load Error: {ex.Message}"); + } + } + } + + void UpdateVisualAgvPosition(string tag) + { + if (_visualAgv == null || _mapNodes == null) return; + + // Find node by tag + // Assuming NodeId might be the tag or contain it + var node = _mapNodes.FirstOrDefault(n => n.NodeId == tag || n.NodeId.EndsWith(tag)); + + // If not found, try to parse tag as int and match + if (node == null && int.TryParse(tag, out int tagNum)) + { + node = _mapNodes.FirstOrDefault(n => n.NodeId == tagNum.ToString()); + } + + if (node != null) + { + _visualAgv.SetPosition(node, (AGV.sts_dir == 'F' ? AgvDirection.Forward : AgvDirection.Backward)); + UpdateVisualAGV(); + } + } + + + + + char GetGroupItemCheckbox(GroupBox grp) + { + foreach (var ctl in grp.Controls) + { + if (ctl is RadioButton) + { + var rad = ctl as RadioButton; + if (rad.Checked) return rad.Text[0]; + } + } + return '0'; + } + + + + + int PLC_LeftPosition = 0; + int PLC_RightPosition = 0; + int PLC_LeftDir = 0; + int PLC_RightDir = 0; + + + public void SetBit(ref UInt16 _value, int idx, Boolean value) + { + if (value) + { + var offset = (UInt16)(1 << idx); + _value = (UInt16)(_value | offset); + } + else + { + var offset = (UInt16)(~(1 << idx)); + _value = (UInt16)(_value & offset); + } + } + public void SetBit(ref byte _value, int idx, Boolean value) + { + if (value) + { + var offset = (byte)(1 << idx); + _value = (byte)(_value | offset); + } + else + { + var offset = (byte)(~(1 << idx)); + _value = (byte)(_value & offset); + } + } + + void aaplycheckboxbit(ref UInt16 v, Panel p) + { + foreach (CheckBox chk in p.Controls) + { + var idx = int.Parse(chk.Tag.ToString()); + SetBit(ref v, idx, chk.Checked); + } + } + void aaplycheckboxbit(ref byte v, Panel p) + { + foreach (CheckBox chk in p.Controls) + { + var idx = int.Parse(chk.Tag.ToString()); + SetBit(ref v, idx, chk.Checked); + } + } + + + + + + private void button5_Click(object sender, EventArgs e) + { + AGV.WriteData("ACK"); + } + + private void button4_Click(object sender, EventArgs e) + { + AGV.WriteData("NAK"); + } + + + + private void trackBar1_Scroll(object sender, EventArgs e) + { + BMS_MaxA = float.Parse(label4.Text); + BMS_CurA = (float)(trackBar1.Value / 100f); + BMS_Remain = 100f * (BMS_CurA / BMS_MaxA);// (trackBar1.Value / 10f); + var minvolt = 20.2f; + var maxvolt = 26.8f; + // BMS_CurA = (BMS_MaxA * (BMS_Remain / 100f)); + label3.Text = BMS_CurA.ToString("N0"); //curr amp + label5.Text = $"{BMS_Remain:N2}%"; + BMS_Volt = minvolt + ((maxvolt - minvolt) * (BMS_CurA / BMS_MaxA)); + label6.Text = $"{BMS_Volt:N2}v"; + } + + private void timer1_Tick(object sender, EventArgs e) + { + timer1.Stop(); + sbAGV.ForeColor = AGV.IsOpen ? Color.ForestGreen : Color.Red; + // sbPLC.ForeColor = PLC.IsOpen ? Color.ForestGreen : Color.Red; + sbBMS.ForeColor = BMS.IsOpen ? Color.ForestGreen : Color.Red; + sbCAL.ForeColor = XBE.IsOpen ? Color.ForestGreen : Color.Red; + + //if (checkBox2.Checked && PLC != null && PLC.IsOpen) PLC.AutoSendData(); //자동전송해야함 + if (checkBox3.Checked && AGV != null && AGV.IsOpen) AGV.AutoSendData(); //자동전송해야함 + if (BMS != null && BMS.IsOpen) BMS.AutoSendData(); //자동전송해야함 + if (XBE != null && XBE.IsOpen) XBE.AutoSendData(); //자동전송해야함 + + if (chkSimulation.Checked && AGV.GetAGV(esystemflag1.agv_run)) + { + if (radioButton15.Checked) + { + agvViewer1.dir = 1; + } + else + { + agvViewer1.dir = -1; + } + if (radioButton12.Checked) agvViewer1.mspd = 7; + else if (radioButton11.Checked) agvViewer1.mspd = 20; + else agvViewer1.mspd = 40; + agvViewer1.Invalidate(); + + UpdateEmulatorLogic(); + } + + + timer1.Start(); + } + + + + + +private void UpdateVisualAGV() + { + if (_visualAgv != null) + { + _agvCanvas.UpdateAGVPosition(_visualAgv.AgvId, _visualAgv.CurrentPosition); + // Update direction if needed, though UnifiedAGVCanvas uses Enum + // _agvCanvas.UpdateAGVDirection(_visualAgv.AgvId, _visualAgv.CurrentDirection); + _agvCanvas.Invalidate(); + } + } + + private void UpdateEmulatorLogic() + { + if (_visualAgv == null || _mapNodes == null) return; + + // Initialize float position if needed + if (_currentPosF.IsEmpty) _currentPosF = _visualAgv.CurrentPosition; + + // Movement Logic + double speed = (agvViewer1.mspd > 0 ? agvViewer1.mspd : 10) * 0.2; // Scale speed + + if (_isTurning) + { + // Turn Logic: 90 deg in 5 sec = 18 deg/sec + // Timer is likely 100ms? (Default WinForms timer) -> 1.8 deg/tick + double turnSpeed = 1.8; + + double diff = _targetAngle - _visualAgv.Angle; + // Normalize diff to -180 to 180 + while (diff > 180) diff -= 360; + while (diff <= -180) diff += 360; + + if (Math.Abs(diff) < turnSpeed) + { + _visualAgv.Angle = _targetAngle; + _isTurning = false; + } + else + { + _visualAgv.Angle += Math.Sign(diff) * turnSpeed; + } + } + else + { + // Move Forward + double rad = _visualAgv.Angle * Math.PI / 180.0; + _currentPosF.X += (float)(speed * Math.Cos(rad)); + _currentPosF.Y += (float)(speed * Math.Sin(rad)); + + _visualAgv.CurrentPosition = Point.Round(_currentPosF); + + // Check for Nodes (RFID Trigger) + foreach (var node in _mapNodes) + { + double dist = Math.Sqrt(Math.Pow(node.Position.X - _visualAgv.CurrentPosition.X, 2) + Math.Pow(node.Position.Y - _visualAgv.CurrentPosition.Y, 2)); + if (dist < 15) // Hit Node + { + // Send Tag + if (node.NodeId != numericUpDown1.Text) + { + if (int.TryParse(node.NodeId, out int tag)) + { + AGV.SendTag(node.NodeId); + numericUpDown1.Text = node.NodeId; + + // Snap to node + _currentPosF = node.Position; + _visualAgv.CurrentPosition = node.Position; + + // Decide Next Move (Turn/Straight) + DecideNextMove(node); + } + } + } + } + } + + UpdateVisualAGV(); + } + + private void DecideNextMove(MapNode currentNode) + { + // Simple logic: + // If AGV.sts_bunki == 'L', turn -90 + // If AGV.sts_bunki == 'R', turn +90 + // Else keep straight + + if (AGV.sts_bunki == 'L') + { + _targetAngle = _visualAgv.Angle - 90; + _isTurning = true; + } + else if (AGV.sts_bunki == 'R') + { + _targetAngle = _visualAgv.Angle + 90; + _isTurning = true; + } + + // Normalize Target Angle + while (_targetAngle >= 360) _targetAngle -= 360; + while (_targetAngle < 0) _targetAngle += 360; + } + + private void _agvCanvas_NodeRightClicked(object sender, MapNode e) + { + if (e != null && _visualAgv != null) + { + _visualAgv.CurrentPosition = e.Position; + _currentPosF = e.Position; + + if (int.TryParse(e.NodeId, out int tag)) + { + numericUpDown1.Text = tag.ToString(); + } + UpdateVisualAGV(); + + + private void button14_Click(object sender, EventArgs e) + { + //agv 정지 + //비상정지 에러 플래그 + AGV.SetAGV(DevAGV.eerror.Emergency, true); + AGV.SetAGV(DevAGV.esystemflag1.agv_run, false); + AGV.SetAGV(DevAGV.esystemflag1.agv_stop, true); + } + + + + private void button16_Click(object sender, EventArgs e) + { + AGV.SetAGV(DevAGV.esystemflag1.stop_by_front_detect, true); + } + + private void button15_Click(object sender, EventArgs e) + { + AGV.SetAGV(DevAGV.esystemflag1.stop_by_front_detect, false); + } + + private void button17_Click(object sender, EventArgs e) + { + //agv 정지 + //비상정지 에러 플래그 + AGV.SetAGV(DevAGV.eerror.Emergency, false); + AGV.SetAGV(DevAGV.eerror.line_out_error, false); + AGV.SetAGV(DevAGV.eerror.Overcurrent, false); + AGV.SetAGV(DevAGV.esystemflag1.agv_run, false); + AGV.SetAGV(DevAGV.esystemflag1.agv_stop, true); + } + + + + private void Chk_CheckedChanged(object sender, EventArgs e) + { + var chk = sender as CheckBox; + var idx = int.Parse(chk.Tag.ToString()); + + switch (chk.Parent.Tag.ToString().ToLower()) + { + case "s0": + var v0 = (DevAGV.esystemflag0)idx; + AGV.SetAGV(v0, chk.Checked); + break; + case "s1": + var v1 = (DevAGV.esystemflag1)idx; + AGV.SetAGV(v1, chk.Checked); + break; + case "er": + var v2 = (DevAGV.eerror)idx; + AGV.SetAGV(v2, chk.Checked); + break; + case "sg": + var v3 = (DevAGV.esignal)idx; + AGV.SetAGV(v3, chk.Checked); + break; + } + + chk.BackColor = chk.Checked ? Color.Lime : SystemColors.Window; + } + + private void button18_Click(object sender, EventArgs e) + { + if (int.TryParse(numericUpDown1.Text, out int tagno)) + { + AGV.SendTag(tagno.ToString()); + numericUpDown1.SelectAll(); + numericUpDown1.Focus(); + } + } + + private void agvViewer1_MouseDown(object sender, MouseEventArgs e) + { + if (e.Button == MouseButtons.Left) + { + agvViewer1.StopbyMark = !agvViewer1.StopbyMark; + } + else if (e.Button == MouseButtons.Right) + { + MakeViewer(); + } + } + + private void button6_Click(object sender, EventArgs e) + { + var target = (byte)nudIDAgv.Value; + var tagno = (uint)nudTagNo.Value; + this.XBE.SendGotoTag(target, tagno); + } + + private void button1_Click(object sender, EventArgs e) + { + var target = (byte)nudIDAgv.Value; + var tagno = (uint)numericUpDown2.Value; + this.XBE.SendCurrentPos(target, tagno); + } + + UInt16 Temp1, Temp2; + private void trbT1_Scroll(object sender, EventArgs e) + { + //값에 /10해서 표시한다. + Temp1 = (UInt16)trbT1.Value; + label10.Text = $"{Temp1 / 10f}º"; + + } + + private void numericUpDown1_KeyDown(object sender, KeyEventArgs e) + { + if (e.KeyCode == Keys.Enter) + button18.PerformClick(); + } + + private void toolStripButton3_Click(object sender, EventArgs e) + { + var file = @"C:\Data\Amkor\AGV4\route\NewMap.agvmap"; + LoadMapFile(file); + } + private string _currentMapFilePath; + private void LoadMapFile(string filePath) + { + try + { + var result = MapLoader.LoadMapFromFile(filePath); + + if (result.Success) + { + Console.WriteLine($"Map File Load : {filePath}"); + + _mapNodes = result.Nodes; + _currentMapFilePath = filePath; + + // RFID 자동 할당 제거 - 에디터에서 설정한 값 그대로 사용 + + // 시뮬레이터 캔버스에 맵 설정 + this._agvCanvas.Nodes = _mapNodes; + + // 맵 설정 적용 (배경색, 그리드 표시) + if (result.Settings != null) + { + _agvCanvas.BackColor = System.Drawing.Color.FromArgb(result.Settings.BackgroundColorArgb); + _agvCanvas.ShowGrid = result.Settings.ShowGrid; + } + + // 맵에 맞춤 + _agvCanvas.FitToNodes(); + } + else + { + throw new InvalidOperationException($"맵 파일 로드 실패: {result.ErrorMessage}"); + } + } + catch (Exception ex) + { + throw new InvalidOperationException($"맵 파일 로드 실패: {ex.Message}", ex); + } + } + + private void toolStripButton4_Click(object sender, EventArgs e) + { + // Change rotation (180 degrees) + if (_visualAgv != null) + { + _visualAgv.Angle = (_visualAgv.Angle + 180) % 360; + UpdateVisualAGV(); + } + } + + private void toolStripButton5_Click(object sender, EventArgs e) + { + // Set AGV Position by RFID + string input = ""; + using (Form form = new Form()) + { + form.Text = "Set AGV Position"; + form.Size = new Size(300, 150); + Label lbl = new Label() { Left = 20, Top = 20, Text = "Enter RFID (Node ID):", AutoSize = true }; + TextBox txt = new TextBox() { Left = 20, Top = 45, Width = 240 }; + Button btn = new Button() { Text = "OK", Left = 180, Width = 80, Top = 75, DialogResult = DialogResult.OK }; + form.Controls.Add(lbl); + form.Controls.Add(txt); + form.Controls.Add(btn); + form.AcceptButton = btn; + form.StartPosition = FormStartPosition.CenterParent; + + if (form.ShowDialog() == DialogResult.OK) + { + input = txt.Text; + } + } + + if (!string.IsNullOrEmpty(input) && _mapNodes != null && _visualAgv != null) + { + var node = _mapNodes.FirstOrDefault(n => n.NodeId == input); + if (node != null) + { + _visualAgv.CurrentPosition = node.Position; + _currentPosF = node.Position; + numericUpDown1.Text = node.NodeId; + + // Auto-orient: Prefer Right (0) or Up (270) + var neighbors = _mapNodes.Where(n => n != node && + Math.Sqrt(Math.Pow(n.Position.X - node.Position.X, 2) + Math.Pow(n.Position.Y - node.Position.Y, 2)) < 150) + .ToList(); + + if (neighbors.Any()) + { + var rightNeighbor = neighbors.FirstOrDefault(n => n.Position.X > node.Position.X && Math.Abs(n.Position.Y - node.Position.Y) < 50); + if (rightNeighbor != null) + { + _visualAgv.Angle = 0; + } + else + { + var upNeighbor = neighbors.FirstOrDefault(n => n.Position.Y < node.Position.Y && Math.Abs(n.Position.X - node.Position.X) < 50); + if (upNeighbor != null) + { + _visualAgv.Angle = 270; + } + else + { + var first = neighbors.First(); + double angle = Math.Atan2(first.Position.Y - node.Position.Y, first.Position.X - node.Position.X) * 180 / Math.PI; + if (angle < 0) angle += 360; + _visualAgv.Angle = angle; + } + } + } + + UpdateVisualAGV(); + } + else + { + MessageBox.Show($"Node '{input}' not found.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); + } + } + } + private void trbT2_Scroll(object sender, EventArgs e) + { + Temp2 = (UInt16)trbT2.Value; + label11.Text = $"{Temp2 / 10f}º"; + } + + private void toolStripButton1_Click(object sender, EventArgs e) + { + serAGV.Connect(); + serBMS.Connect(); + serCAL.Connect(); + } + + private void toolStripButton2_Click(object sender, EventArgs e) + { + serAGV.Disconnect(); + serBMS.Disconnect(); + serCAL.Disconnect(); + } + + + } +} + + diff --git a/AGVEmulator/fMain.resx b/AGVEmulator/fMain.resx new file mode 100644 index 0000000..9c0fd00 --- /dev/null +++ b/AGVEmulator/fMain.resx @@ -0,0 +1,205 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + 17, 17 + + + 104, 17 + + + + + iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8 + YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAIFSURBVDhPpZLtS1NhGMbPPxJmmlYSgqHiKzGU1EDxg4iK + YKyG2WBogqMYJQOtCEVRFBGdTBCJfRnkS4VaaWNT5sqx1BUxRXxDHYxAJLvkusEeBaPAB+5z4Jzn+t3X + /aLhnEfjo8m+dCoa+7/C3O2Hqe0zDC+8KG+cRZHZhdzaaWTVTCLDMIY0vfM04Nfh77/G/sEhwpEDbO3t + I7TxE8urEVy99fT/AL5gWDLrTB/hnF4XsW0khCu5ln8DmJliT2AXrcNBsU1gj/MH4nMeKwBrPktM28xM + cX79DFKrHHD5d9D26hvicx4pABt2lpg10zYzU0zr7+e3xXGcrkEB2O2TNec9nJFwB3alZn5jZorfeDZh + 6Q3g8s06BeCoKF4MRURoH1+BY2oNCbeb0TIclIYxOhzf8frTOuo7FxCbbVIAzpni0iceEc8vhzEwGkJD + lx83ymxifejdKjRNk/8PWnyIyTQqAJek0jqHwfEVscu31baIu8+90sTE4nY025dQ2/5FIPpnXlzKuK8A + HBUzHot52djqQ6HZhfR7IwK4mKpHtvEDMqvfCiQ6zaAAXM8x94aIWTNrLLG4kVUzgaTSPlzLtyJOZxbb + 1wtfyg4Q+AfA3aZlButjSfxGcUJBk4g5tuP3haQKRKXcUQDOmbvNTpPOJeFFjordZmbWTNvMTHFUcpUC + nOccAdABIDXXE1nzAAAAAElFTkSuQmCC + + + + + iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8 + YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAIFSURBVDhPpZLtS1NhGMbPPxJmmlYSgqHiKzGU1EDxg4iK + YKyG2WBogqMYJQOtCEVRFBGdTBCJfRnkS4VaaWNT5sqx1BUxRXxDHYxAJLvkusEeBaPAB+5z4Jzn+t3X + /aLhnEfjo8m+dCoa+7/C3O2Hqe0zDC+8KG+cRZHZhdzaaWTVTCLDMIY0vfM04Nfh77/G/sEhwpEDbO3t + I7TxE8urEVy99fT/AL5gWDLrTB/hnF4XsW0khCu5ln8DmJliT2AXrcNBsU1gj/MH4nMeKwBrPktM28xM + cX79DFKrHHD5d9D26hvicx4pABt2lpg10zYzU0zr7+e3xXGcrkEB2O2TNec9nJFwB3alZn5jZorfeDZh + 6Q3g8s06BeCoKF4MRURoH1+BY2oNCbeb0TIclIYxOhzf8frTOuo7FxCbbVIAzpni0iceEc8vhzEwGkJD + lx83ymxifejdKjRNk/8PWnyIyTQqAJek0jqHwfEVscu31baIu8+90sTE4nY025dQ2/5FIPpnXlzKuK8A + HBUzHot52djqQ6HZhfR7IwK4mKpHtvEDMqvfCiQ6zaAAXM8x94aIWTNrLLG4kVUzgaTSPlzLtyJOZxbb + 1wtfyg4Q+AfA3aZlButjSfxGcUJBk4g5tuP3haQKRKXcUQDOmbvNTpPOJeFFjordZmbWTNvMTHFUcpUC + nOccAdABIDXXE1nzAAAAAElFTkSuQmCC + + + + + iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8 + YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAIFSURBVDhPpZLtS1NhGMbPPxJmmlYSgqHiKzGU1EDxg4iK + YKyG2WBogqMYJQOtCEVRFBGdTBCJfRnkS4VaaWNT5sqx1BUxRXxDHYxAJLvkusEeBaPAB+5z4Jzn+t3X + /aLhnEfjo8m+dCoa+7/C3O2Hqe0zDC+8KG+cRZHZhdzaaWTVTCLDMIY0vfM04Nfh77/G/sEhwpEDbO3t + I7TxE8urEVy99fT/AL5gWDLrTB/hnF4XsW0khCu5ln8DmJliT2AXrcNBsU1gj/MH4nMeKwBrPktM28xM + cX79DFKrHHD5d9D26hvicx4pABt2lpg10zYzU0zr7+e3xXGcrkEB2O2TNec9nJFwB3alZn5jZorfeDZh + 6Q3g8s06BeCoKF4MRURoH1+BY2oNCbeb0TIclIYxOhzf8frTOuo7FxCbbVIAzpni0iceEc8vhzEwGkJD + lx83ymxifejdKjRNk/8PWnyIyTQqAJek0jqHwfEVscu31baIu8+90sTE4nY025dQ2/5FIPpnXlzKuK8A + HBUzHot52djqQ6HZhfR7IwK4mKpHtvEDMqvfCiQ6zaAAXM8x94aIWTNrLLG4kVUzgaTSPlzLtyJOZxbb + 1wtfyg4Q+AfA3aZlButjSfxGcUJBk4g5tuP3haQKRKXcUQDOmbvNTpPOJeFFjordZmbWTNvMTHFUcpUC + nOccAdABIDXXE1nzAAAAAElFTkSuQmCC + + + + + iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8 + YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAIFSURBVDhPpZLtS1NhGMbPPxJmmlYSgqHiKzGU1EDxg4iK + YKyG2WBogqMYJQOtCEVRFBGdTBCJfRnkS4VaaWNT5sqx1BUxRXxDHYxAJLvkusEeBaPAB+5z4Jzn+t3X + /aLhnEfjo8m+dCoa+7/C3O2Hqe0zDC+8KG+cRZHZhdzaaWTVTCLDMIY0vfM04Nfh77/G/sEhwpEDbO3t + I7TxE8urEVy99fT/AL5gWDLrTB/hnF4XsW0khCu5ln8DmJliT2AXrcNBsU1gj/MH4nMeKwBrPktM28xM + cX79DFKrHHD5d9D26hvicx4pABt2lpg10zYzU0zr7+e3xXGcrkEB2O2TNec9nJFwB3alZn5jZorfeDZh + 6Q3g8s06BeCoKF4MRURoH1+BY2oNCbeb0TIclIYxOhzf8frTOuo7FxCbbVIAzpni0iceEc8vhzEwGkJD + lx83ymxifejdKjRNk/8PWnyIyTQqAJek0jqHwfEVscu31baIu8+90sTE4nY025dQ2/5FIPpnXlzKuK8A + HBUzHot52djqQ6HZhfR7IwK4mKpHtvEDMqvfCiQ6zaAAXM8x94aIWTNrLLG4kVUzgaTSPlzLtyJOZxbb + 1wtfyg4Q+AfA3aZlButjSfxGcUJBk4g5tuP3haQKRKXcUQDOmbvNTpPOJeFFjordZmbWTNvMTHFUcpUC + nOccAdABIDXXE1nzAAAAAElFTkSuQmCC + + + + + iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8 + YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAIFSURBVDhPpZLtS1NhGMbPPxJmmlYSgqHiKzGU1EDxg4iK + YKyG2WBogqMYJQOtCEVRFBGdTBCJfRnkS4VaaWNT5sqx1BUxRXxDHYxAJLvkusEeBaPAB+5z4Jzn+t3X + /aLhnEfjo8m+dCoa+7/C3O2Hqe0zDC+8KG+cRZHZhdzaaWTVTCLDMIY0vfM04Nfh77/G/sEhwpEDbO3t + I7TxE8urEVy99fT/AL5gWDLrTB/hnF4XsW0khCu5ln8DmJliT2AXrcNBsU1gj/MH4nMeKwBrPktM28xM + cX79DFKrHHD5d9D26hvicx4pABt2lpg10zYzU0zr7+e3xXGcrkEB2O2TNec9nJFwB3alZn5jZorfeDZh + 6Q3g8s06BeCoKF4MRURoH1+BY2oNCbeb0TIclIYxOhzf8frTOuo7FxCbbVIAzpni0iceEc8vhzEwGkJD + lx83ymxifejdKjRNk/8PWnyIyTQqAJek0jqHwfEVscu31baIu8+90sTE4nY025dQ2/5FIPpnXlzKuK8A + HBUzHot52djqQ6HZhfR7IwK4mKpHtvEDMqvfCiQ6zaAAXM8x94aIWTNrLLG4kVUzgaTSPlzLtyJOZxbb + 1wtfyg4Q+AfA3aZlButjSfxGcUJBk4g5tuP3haQKRKXcUQDOmbvNTpPOJeFFjordZmbWTNvMTHFUcpUC + nOccAdABIDXXE1nzAAAAAElFTkSuQmCC + + + + 210, 17 + + \ No newline at end of file diff --git a/Cs_HMI/AGVLogic/AGVNavigationCore/Controls/UnifiedAGVCanvas.Events.cs b/Cs_HMI/AGVLogic/AGVNavigationCore/Controls/UnifiedAGVCanvas.Events.cs index a52514a..b238943 100644 --- a/Cs_HMI/AGVLogic/AGVNavigationCore/Controls/UnifiedAGVCanvas.Events.cs +++ b/Cs_HMI/AGVLogic/AGVNavigationCore/Controls/UnifiedAGVCanvas.Events.cs @@ -1775,6 +1775,11 @@ namespace AGVNavigationCore.Controls /// private Color GetAGVCenterColor(AGVState state) { + // Stop-Mark 상태 (Error 상태와 유사하게 처리하거나 별도 처리) + // 여기서는 AGVState에 StopMark가 없으므로, 외부에서 상태를 Error로 설정하거나 + // 별도의 플래그를 확인해야 함. 하지만 IAGV 인터페이스에는 플래그가 없음. + // 따라서 fMain에서 상태를 Error로 설정하는 것을 권장. + switch (state) { case AGVState.Moving: return Color.White; @@ -1794,7 +1799,7 @@ namespace AGVNavigationCore.Controls { case AGVState.Moving: return Color.DarkGreen; case AGVState.Charging: return Color.DarkBlue; - case AGVState.Error: return Color.DarkRed; + case AGVState.Error: return Color.DarkRed; // Stop-Mark 시 Error 상태 사용 case AGVState.Docking: return Color.DarkOrange; default: return Color.DarkGray; } diff --git a/Cs_HMI/AGVLogic/AGVNavigationCore/Controls/UnifiedAGVCanvas.Mouse.cs b/Cs_HMI/AGVLogic/AGVNavigationCore/Controls/UnifiedAGVCanvas.Mouse.cs index 15603e3..77e2aec 100644 --- a/Cs_HMI/AGVLogic/AGVNavigationCore/Controls/UnifiedAGVCanvas.Mouse.cs +++ b/Cs_HMI/AGVLogic/AGVNavigationCore/Controls/UnifiedAGVCanvas.Mouse.cs @@ -17,6 +17,16 @@ namespace AGVNavigationCore.Controls var worldPoint = ScreenToWorld(e.Location); var hitNode = GetNodeAt(worldPoint); + // 에뮬레이터 모드 처리 + if (_canvasMode == CanvasMode.Emulator) + { + if (e.Button == MouseButtons.Right && hitNode != null) + { + NodeRightClicked?.Invoke(this, hitNode); + } + return; + } + // 🔥 어떤 모드에서든 노드/빈 공간 클릭 시 선택 이벤트 발생 (속성창 업데이트) bool ctrlPressed = (ModifierKeys & Keys.Control) == Keys.Control; diff --git a/Cs_HMI/AGVLogic/AGVNavigationCore/Controls/UnifiedAGVCanvas.cs b/Cs_HMI/AGVLogic/AGVNavigationCore/Controls/UnifiedAGVCanvas.cs index ffcd7d4..337a42b 100644 --- a/Cs_HMI/AGVLogic/AGVNavigationCore/Controls/UnifiedAGVCanvas.cs +++ b/Cs_HMI/AGVLogic/AGVNavigationCore/Controls/UnifiedAGVCanvas.cs @@ -36,7 +36,8 @@ namespace AGVNavigationCore.Controls public enum CanvasMode { Edit, // 편집 가능 (맵 에디터) - Sync // 동기화 모드 (장비 설정 동기화) + Sync, // 동기화 모드 (장비 설정 동기화) + Emulator // 에뮬레이터 모드 } /// @@ -146,6 +147,9 @@ namespace AGVNavigationCore.Controls // 컨텍스트 메뉴 private ContextMenuStrip _contextMenu; + // 이벤트 + public event EventHandler NodeRightClicked; + #endregion #region Events diff --git a/Cs_HMI/AGVLogic/AGVNavigationCore/Models/VirtualAGV.cs b/Cs_HMI/AGVLogic/AGVNavigationCore/Models/VirtualAGV.cs index 5ae5442..f10fb46 100644 --- a/Cs_HMI/AGVLogic/AGVNavigationCore/Models/VirtualAGV.cs +++ b/Cs_HMI/AGVLogic/AGVNavigationCore/Models/VirtualAGV.cs @@ -81,6 +81,13 @@ namespace AGVNavigationCore.Models private List _detectedRfids = new List(); // 감지된 RFID 목록 private bool _isPositionConfirmed = false; // 위치 확정 여부 (RFID 2개 이상 감지) + // 에뮬레이터용 추가 속성 + public double Angle { get; set; } = 0; // 0 = Right, 90 = Down, 180 = Left, 270 = Up (Standard Math) + // But AGV Direction: Forward usually means "Front of AGV". + // Let's assume Angle is the orientation of the AGV in degrees. + + public bool IsStopMarkOn { get; set; } = false; + #endregion #region Properties @@ -433,6 +440,27 @@ namespace AGVNavigationCore.Models OnError("긴급 정지가 실행되었습니다."); } + /// + /// 일시 정지 (경로 유지) + /// + public void Pause() + { + _isMoving = false; + _currentSpeed = 0; + } + + /// + /// 이동 재개 + /// + public void Resume() + { + if (_currentPath != null && _remainingNodes != null && _remainingNodes.Count > 0) + { + _isMoving = true; + SetState(AGVState.Moving); + } + } + #endregion #region Public Methods - 프레임 업데이트 (외부에서 정기적으로 호출) diff --git a/Cs_HMI/AGVLogic/AGVSimulator/Forms/SimulatorForm.cs b/Cs_HMI/AGVLogic/AGVSimulator/Forms/SimulatorForm.cs index a318792..6c15b0e 100644 --- a/Cs_HMI/AGVLogic/AGVSimulator/Forms/SimulatorForm.cs +++ b/Cs_HMI/AGVLogic/AGVSimulator/Forms/SimulatorForm.cs @@ -15,6 +15,8 @@ using Newtonsoft.Json; using AGVNavigationCore.PathFinding.Planning; using AGVNavigationCore.PathFinding.Core; using AGVSimulator.Models; +using System.IO.Ports; +using System.Text; namespace AGVSimulator.Forms { @@ -25,6 +27,86 @@ namespace AGVSimulator.Forms { #region Fields + // Emulator Fields + private SerialPort _emulatorPort; + private ComboBox _portCombo; + private Button _connectButton; + private bool _isEmulatorConnected = false; + + // Emulator State Fields + private UInt16 _emu_system0 = 0; + private UInt16 _emu_system1 = 0; + private UInt16 _emu_error = 0; + private byte _emu_signal = 0; + private char _emu_sts_bunki = 'S'; + private char _emu_sts_speed = 'L'; + private char _emu_sts_dir = 'F'; + private char _emu_sts_sensor = '1'; + private string _lastSentNodeId = null; + + public enum esystemflag0 + { + Memory_RW_State = 5, + EXT_IO_Conn_State, + RFID_Conn_State, + M5E_Module_Run_State = 8, + Front_Ultrasonic_Conn_State, + Front_Untrasonic_Sensor_State, + Side_Ultrasonic_Conn_State, + Side_Ultrasonic_Sensor_State = 12, + Front_Guide_Sensor_State, + Rear_Guide_Sensor_State, + Battery_Level_Check + } + public enum esystemflag1 + { + Side_Detect_Ignore = 3, + Melody_check, + Mark2_check, + Mark1_check, + gateout_check, + Battery_charging = 8, + re_Start, + front_detect_ignore, + front_detect_check, + stop_by_front_detect = 12, + stop_by_cross_in, + agv_stop, + agv_run + } + public enum eerror + { + Emergency = 0, + Overcurrent, + Charger_run_error, + Charger_pos_error, + line_out_error = 4, + runerror_by_no_magent_line, + controller_comm_error = 11, + arrive_ctl_comm_error, + door_ctl_comm_error, + charger_comm_error, + cross_ctrl_comm_error, + } + public enum esignal + { + front_gate_out = 0, + rear_sensor_out, + mark_sensor_1, + mark_sensor_2, + front_left_sensor, + front_right_sensor, + front_center_sensor, + charger_align_sensor, + } + public enum estsvaluetype + { + bunki, + speed, + direction, + sensor + } + private UnifiedAGVCanvas _simulatorCanvas; private List _mapNodes; private AGVPathfinder _advancedPathfinder; @@ -92,6 +174,9 @@ namespace AGVSimulator.Forms // 방향 콤보박스 초기화 InitializeDirectionCombo(); + // 에뮬레이터 UI 초기화 + InitializeEmulatorUI(); + // 초기 상태 설정 UpdateUI(); @@ -716,12 +801,32 @@ namespace AGVSimulator.Forms foreach (var agv in _agvList) { agv.Update(100); // 100ms 간격으로 업데이트 + + // Emulator Tag Logic + if (_isEmulatorConnected && agv == _agvList.FirstOrDefault()) + { + if (agv.CurrentNodeId != null && agv.CurrentNodeId != _lastSentNodeId) + { + var rfid = GetRfidByNodeId(agv.CurrentNodeId); + if (!string.IsNullOrEmpty(rfid)) + { + SendTag(rfid); + _lastSentNodeId = agv.CurrentNodeId; + } + } + } } } // UI 업데이트 UpdateUI(); _simulatorCanvas.Invalidate(); // 화면 다시 그리기 + + // 에뮬레이터 상태 전송 + if (_isEmulatorConnected) + { + SendEmulatorStatus(); + } } #endregion @@ -2005,6 +2110,412 @@ namespace AGVSimulator.Forms MessageBoxButtons.OK, MessageBoxIcon.Error); } } + + #region Emulator Logic + + private void InitializeEmulatorUI() + { + // 에뮬레이터 제어 패널 생성 + var emulatorPanel = new GroupBox(); + emulatorPanel.Text = "AGV Emulator (RS232)"; + emulatorPanel.Height = 60; + emulatorPanel.Dock = DockStyle.Top; + + var layout = new FlowLayoutPanel(); + layout.Dock = DockStyle.Fill; + layout.Padding = new Padding(5); + layout.AutoSize = true; + + // 포트 선택 콤보박스 + _portCombo = new ComboBox(); + _portCombo.Width = 100; + _portCombo.DropDownStyle = ComboBoxStyle.DropDownList; + _portCombo.DropDown += (s, e) => { + _portCombo.Items.Clear(); + _portCombo.Items.AddRange(SerialPort.GetPortNames()); + }; + _portCombo.Items.AddRange(SerialPort.GetPortNames()); + if (_portCombo.Items.Count > 0) _portCombo.SelectedIndex = 0; + + // 연결 버튼 + _connectButton = new Button(); + _connectButton.Text = "Connect"; + _connectButton.Click += OnConnectEmulator_Click; + + layout.Controls.Add(new Label { Text = "Port:", AutoSize = true, Margin = new Padding(3, 8, 3, 3) }); + layout.Controls.Add(_portCombo); + layout.Controls.Add(_connectButton); + + emulatorPanel.Controls.Add(layout); + + // 폼의 최상단에 추가 + this.Controls.Add(emulatorPanel); + emulatorPanel.BringToFront(); + } + + private void OnConnectEmulator_Click(object sender, EventArgs e) + { + if (_isEmulatorConnected) + { + DisconnectEmulator(); + } + else + { + if (_portCombo.SelectedItem == null) + { + MessageBox.Show("포트를 선택해주세요."); + return; + } + ConnectEmulator(_portCombo.SelectedItem.ToString()); + } + } + + private void ConnectEmulator(string portName) + { + try + { + _emulatorPort = new SerialPort(portName, 115200, Parity.None, 8, StopBits.One); + _emulatorPort.DataReceived += OnEmulatorDataReceived; + _emulatorPort.Open(); + _isEmulatorConnected = true; + _connectButton.Text = "Disconnect"; + _portCombo.Enabled = false; + MessageBox.Show($"에뮬레이터 시작: {portName}"); + } + catch (Exception ex) + { + MessageBox.Show($"연결 실패: {ex.Message}"); + } + } + + private void DisconnectEmulator() + { + try + { + if (_emulatorPort != null && _emulatorPort.IsOpen) + { + _emulatorPort.Close(); + } + _isEmulatorConnected = false; + _connectButton.Text = "Connect"; + _portCombo.Enabled = true; + } + catch (Exception ex) + { + MessageBox.Show($"해제 실패: {ex.Message}"); + } + } + + private StringBuilder _recvBuffer = new StringBuilder(); + + private void OnEmulatorDataReceived(object sender, SerialDataReceivedEventArgs e) + { + try + { + string data = _emulatorPort.ReadExisting(); + _recvBuffer.Append(data); + + string buffer = _recvBuffer.ToString(); + int stxIndex = buffer.IndexOf((char)0x02); + + while (stxIndex >= 0) + { + int etxIndex = buffer.IndexOf((char)0x03, stxIndex); + if (etxIndex > stxIndex) + { + string packet = buffer.Substring(stxIndex + 1, etxIndex - stxIndex - 1); + ProcessEmulatorPacket(packet); + + // 처리된 패킷 제거 + buffer = buffer.Substring(etxIndex + 1); + stxIndex = buffer.IndexOf((char)0x02); + } + else + { + break; // ETX 아직 안옴 + } + } + + _recvBuffer.Clear(); + _recvBuffer.Append(buffer); + } + catch (Exception ex) + { + Console.WriteLine($"Emulator Recv Error: {ex.Message}"); + } + } + + #region Emulator Helpers + private bool GetBit(ref UInt16 _value, int idx) + { + var offset = (UInt16)(1 << idx); + return (_value & offset) != 0; + } + + private bool SetBit(ref UInt16 _value, int idx, bool value) + { + var oldvalue = GetBit(ref _value, idx); + if (value) + { + var offset = (UInt16)(1 << idx); + _value = (UInt16)(_value | offset); + } + else + { + var offset = (UInt16)(~(1 << idx)); + _value = (UInt16)(_value & offset); + } + return oldvalue != value; + } + + private bool SetBit(ref byte _value, int idx, bool value) + { + var offset = (byte)(1 << idx); + if (value) _value |= offset; + else _value &= (byte)~offset; + return true; + } + + private void SetAGV(esystemflag0 flag, bool value) + { + SetBit(ref _emu_system0, (int)flag, value); + } + private void SetAGV(esystemflag1 flag, bool value) + { + SetBit(ref _emu_system1, (int)flag, value); + } + private void SetAGV(eerror flag, bool value) + { + SetBit(ref _emu_error, (int)flag, value); + } + private void SetAGV(esignal flag, bool value) + { + SetBit(ref _emu_signal, (int)flag, value); + } + private void SetSTS(estsvaluetype target, char value) + { + switch (target) + { + case estsvaluetype.sensor: _emu_sts_sensor = value; break; + case estsvaluetype.direction: _emu_sts_dir = value; break; + case estsvaluetype.speed: _emu_sts_speed = value; break; + case estsvaluetype.bunki: _emu_sts_bunki = value; break; + } + } + #endregion + + private void ProcessEmulatorPacket(string packet) + { + // Packet: CMD(3) + DATA(...) + Checksum(2) + // But here packet is substring between STX and ETX. + // Example: STS...Checksum + + if (packet.Length < 3) return; + string cmd = packet.Substring(0, 3); + string data = ""; + if (packet.Length > 5) // CMD + Checksum(2) + { + data = packet.Substring(3, packet.Length - 5); + } + + // AGV 제어 (첫 번째 AGV 대상) + var agv = _agvList.FirstOrDefault(); + + this.Invoke(new Action(() => { + switch (cmd) + { + case "CRN": // 기동명령 + if (data.Length > 0) SetSTS(estsvaluetype.direction, data[0]); + SetAGV(esystemflag1.agv_stop, false); + SetAGV(esystemflag1.agv_run, true); + if (agv != null) agv.Resume(); + break; + + case "CST": // 중지명령 + if (data.StartsWith("M")) + { + // Mark Stop + // TODO: Implement Mark Stop logic in VirtualAGV if needed + // For now, just log it + Console.WriteLine("Mark Stop Command Received"); + } + else + { + SetAGV(esystemflag1.agv_run, false); + SetAGV(esystemflag1.agv_stop, true); + if (agv != null) agv.Pause(); + } + break; + + case "CBR": // 분기명령 + // FSL1 + if (data.Length >= 4) + { + SetSTS(estsvaluetype.direction, data[0]); + SetSTS(estsvaluetype.bunki, data[1]); + SetSTS(estsvaluetype.speed, data[2]); + SetSTS(estsvaluetype.sensor, data[3]); + } + break; + + case "CRT": // 수동제어 + if (data.Length >= 4) + { + _emu_sts_dir = data[0]; + _emu_sts_bunki = data[1]; + _emu_sts_speed = data[2]; + _emu_sts_sensor = data[3]; + SetAGV(esystemflag1.agv_stop, false); + SetAGV(esystemflag1.agv_run, true); + if (agv != null) agv.Resume(); + } + break; + + case "SFR": // Reset + SetAGV(eerror.Emergency, false); + SetAGV(eerror.line_out_error, false); + SetAGV(eerror.Overcurrent, false); + SetAGV(esystemflag1.agv_run, false); + SetAGV(esystemflag1.agv_stop, true); + if (agv != null) agv.Pause(); + break; + + case "CBT": // 충전 + SetAGV(esystemflag1.Battery_charging, true); + if (data.Length >= 5) + { + var cmdChar = data[4]; + if (cmdChar == 'I') SetAGV(esystemflag1.Battery_charging, true); + else SetAGV(esystemflag1.Battery_charging, false); + } + break; + + case "ACK": + // Log ACK + break; + + default: + // Send ACK for other commands + SendCmd("ACK", cmd); + break; + } + })); + } + + private void SendCmd(string cmd, string value) + { + if (_emulatorPort == null || !_emulatorPort.IsOpen) return; + + var barr = new List(); + barr.Add(0x02); + barr.AddRange(System.Text.Encoding.Default.GetBytes(cmd)); + barr.AddRange(System.Text.Encoding.Default.GetBytes(value)); + barr.Add((byte)'*'); + barr.Add((byte)'*'); + barr.Add(0x03); + + try + { + _emulatorPort.Write(barr.ToArray(), 0, barr.Count); + } + catch { } + } + + public void SendTag(string tagno) + { + if (_emulatorPort == null || !_emulatorPort.IsOpen) return; + + tagno = tagno.PadLeft(6, '0'); + if (tagno.Length > 6) tagno = tagno.Substring(0, 6); + + var barr = new List(); + barr.Add(0x02); + barr.Add((byte)'T'); + barr.Add((byte)'A'); + barr.Add((byte)'G'); + barr.AddRange(System.Text.Encoding.Default.GetBytes(tagno)); + barr.Add((byte)'*'); + barr.Add((byte)'*'); + barr.Add(0x03); + + try + { + _emulatorPort.Write(barr.ToArray(), 0, barr.Count); + } + catch { } + } + + private void SendEmulatorStatus() + { + if (_emulatorPort == null || !_emulatorPort.IsOpen) return; + + var agv = _agvList.FirstOrDefault(); + + // Sync state from VirtualAGV + if (agv != null) + { + // Update Battery + // Update Position/Tag? + } + + // STS Packet Construction + // STS(3) + Volt(3) + Sys0(4) + Sys1(4) + Err(4) + Spd(1) + Bunki(1) + Dir(1) + Sensor(1) + Signal(2) + Checksum(2) + + // Default buffer + var sample = "02 53 54 53 32 35 38 46 46 46 46 34 30 30 30 30 30 30 30 4C 53 46 30 30 30 30 30 30 33 41 03"; + var barr = sample.Split(' ').Select(t => Convert.ToByte(t, 16)).ToArray(); + + // Volt (255 for now) + var voltstr = "255"; + var bufarr = System.Text.Encoding.Default.GetBytes(voltstr); + Array.Copy(bufarr, 0, barr, 4, bufarr.Length); + + // System0 + bufarr = System.Text.Encoding.Default.GetBytes(_emu_system0.ToString("X2").PadLeft(4, '0')); + Array.Copy(bufarr, 0, barr, 7, bufarr.Length); + + // System1 + bufarr = System.Text.Encoding.Default.GetBytes(_emu_system1.ToString("X2").PadLeft(4, '0')); + Array.Copy(bufarr, 0, barr, 11, bufarr.Length); + + // Error + bufarr = System.Text.Encoding.Default.GetBytes(_emu_error.ToString("X2").PadLeft(4, '0')); + Array.Copy(bufarr, 0, barr, 15, bufarr.Length); + + // Status Chars + barr[19] = (byte)_emu_sts_speed; + barr[20] = (byte)_emu_sts_bunki; + barr[21] = (byte)_emu_sts_dir; + barr[22] = (byte)_emu_sts_sensor; + + // Signal + bufarr = System.Text.Encoding.Default.GetBytes(_emu_signal.ToString("X2").PadLeft(2, '0')); + Array.Copy(bufarr, 0, barr, 23, bufarr.Length); + + // Checksum (**) + barr[barr.Length - 3] = (byte)'*'; + barr[barr.Length - 2] = (byte)'*'; + + try + { + _emulatorPort.Write(barr, 0, barr.Length); + } + catch { } + } + + private string CalculateChecksum(string data) + { + int sum = 0; + foreach (char c in data) sum += c; + + // 16진수 변환 후 뒤 2자리 + string hex = sum.ToString("X"); + if (hex.Length >= 2) return hex.Substring(hex.Length - 2); + return hex.PadLeft(2, '0'); + } + + #endregion + } /// diff --git a/Cs_HMI/Project/AGV4.csproj b/Cs_HMI/Project/AGV4.csproj index 8673859..378687c 100644 --- a/Cs_HMI/Project/AGV4.csproj +++ b/Cs_HMI/Project/AGV4.csproj @@ -284,6 +284,24 @@ + + Form + + + Form + + + Form + + + Form + + + Form + + + Form + Form diff --git a/Cs_HMI/Project/Device/Xbee.cs b/Cs_HMI/Project/Device/Xbee.cs index 2310498..cd67b98 100644 --- a/Cs_HMI/Project/Device/Xbee.cs +++ b/Cs_HMI/Project/Device/Xbee.cs @@ -159,6 +159,13 @@ namespace Project.Device public bool BufferOutComplete { get; set; } public bool BufferReadyError { get; set; } + public bool LoaderInComplete { get; set; } + public bool LoaderOutComplete { get; set; } + public bool UnloaderInComplete { get; set; } + public bool UnloaderOutComplete { get; set; } + public bool CleanerInComplete { get; set; } + public bool CleanerOutComplete { get; set; } + /// /// AGV상태를 Xbee 로 전송한다 diff --git a/Cs_HMI/Project/StateMachine/Step/_SM_RUN.cs b/Cs_HMI/Project/StateMachine/Step/_SM_RUN.cs index 117a41f..d4f0070 100644 --- a/Cs_HMI/Project/StateMachine/Step/_SM_RUN.cs +++ b/Cs_HMI/Project/StateMachine/Step/_SM_RUN.cs @@ -171,7 +171,7 @@ namespace Project } break; - case ERunStep.MARKSTROPB: //후진방향으로 마크스탑 + case ERunStep.MARKSTOPB: //후진방향으로 마크스탑 case ERunStep.MARKSTOPF: //전진방향으로 마크스탑 //이동중이지 않다면 먼저 이동을 진행한다 @@ -249,6 +249,96 @@ namespace Project } } break; + case ERunStep.LOADER_OUT: //로더아웃 + if (_SM_RUN_LOADER_OUT(runStepisFirst, PUB.sm.GetRunSteptime)) + { + PUB.Speak(Lang.버퍼도킹해제완료); + + //도킹완료상태를 업데이트한다. + PUB.XBE.LoaderInComplete = false; + PUB.XBE.LoaderOutComplete = true; + + //대기상태로 전환 + PUB.sm.SetNewRunStep(ERunStep.READY); + return; + } + break; + + case ERunStep.LOADER_IN: //로더도킹 + if (_SM_RUN_LOADER_IN(runStepisFirst, PUB.sm.GetRunSteptime)) + { + PUB.Speak(Lang.버퍼도킹이완료되었습니다); + + //도킹완료상태를 업데이트한다. + PUB.XBE.LoaderInComplete = true; + + //로더아웃으로 자동 진행 합니다 + PUB.sm.ClearRunStep(); + PUB.sm.SetNewRunStep(ERunStep.LOADER_OUT); + return; + } + break; + + case ERunStep.UNLOADER_OUT: //언로더아웃 + if (_SM_RUN_UNLOADER_OUT(runStepisFirst, PUB.sm.GetRunSteptime)) + { + PUB.Speak(Lang.버퍼도킹해제완료); + + //도킹완료상태를 업데이트한다. + PUB.XBE.UnloaderInComplete = false; + PUB.XBE.UnloaderOutComplete = true; + + //대기상태로 전환 + PUB.sm.SetNewRunStep(ERunStep.READY); + return; + } + break; + + case ERunStep.UNLOADER_IN: //언로더도킹 + if (_SM_RUN_UNLOADER_IN(runStepisFirst, PUB.sm.GetRunSteptime)) + { + PUB.Speak(Lang.버퍼도킹이완료되었습니다); + + //도킹완료상태를 업데이트한다. + PUB.XBE.UnloaderInComplete = true; + + //언로더아웃으로 자동 진행 합니다 + PUB.sm.ClearRunStep(); + PUB.sm.SetNewRunStep(ERunStep.UNLOADER_OUT); + return; + } + break; + + case ERunStep.CLEANER_OUT: //클리너아웃 + if (_SM_RUN_CLEANER_OUT(runStepisFirst, PUB.sm.GetRunSteptime)) + { + PUB.Speak(Lang.버퍼도킹해제완료); + + //도킹완료상태를 업데이트한다. + PUB.XBE.CleanerInComplete = false; + PUB.XBE.CleanerOutComplete = true; + + //대기상태로 전환 + PUB.sm.SetNewRunStep(ERunStep.READY); + return; + } + break; + + case ERunStep.CLEANER_IN: //클리너도킹 + if (_SM_RUN_CLEANER_IN(runStepisFirst, PUB.sm.GetRunSteptime)) + { + PUB.Speak(Lang.버퍼도킹이완료되었습니다); + + //도킹완료상태를 업데이트한다. + PUB.XBE.CleanerInComplete = true; + + //클리너아웃으로 자동 진행 합니다 + PUB.sm.ClearRunStep(); + PUB.sm.SetNewRunStep(ERunStep.CLEANER_OUT); + return; + } + break; + case ERunStep.BUFFER_OUT: //버퍼아웃 if (_SM_RUN_BUFFER_OUT(runStepisFirst, PUB.sm.GetRunSteptime)) { diff --git a/Cs_HMI/Project/StateMachine/Step/_SM_RUN_BUFFER_IN.cs b/Cs_HMI/Project/StateMachine/Step/_SM_RUN_BUFFER_IN.cs index 1628658..d5be98b 100644 --- a/Cs_HMI/Project/StateMachine/Step/_SM_RUN_BUFFER_IN.cs +++ b/Cs_HMI/Project/StateMachine/Step/_SM_RUN_BUFFER_IN.cs @@ -22,40 +22,14 @@ namespace Project var funcname = "_SM_RUN_BUFFER_IN"; var idx = 1; - if (runStepisFirst) - { - //PUB.flag.set(EFlag.FLAG_NEXTSTOP_ALIGN, false); - VAR.BOOL[eVarBool.FLAG_NEXTSTOP_ALIGN] = false;// - //VAR.BOOL[eVarBool.FLAG_NEXTSTOP_MARK] = false;//); - } - - //HW 연결오류 - if (PUB.AGV.IsOpen == false) - { - PUB.Result.SetResultMessage(eResult.Hardware, eECode.AGVCONN, eNextStep.ERROR); - return false; - } - - //충전 상태가 OFF되어야 동작하게한다 - if (_SM_RUN_CHGOFF(isFirst, stepTime) == false) - return false; + if (_SM_RUN_CHGOFF(isFirst, stepTime) == false) return false; - //라이더멈춤이 설정되어있다면 음성으로 알려준다 200409 - if (PUB.AGV.system1.stop_by_front_detect == true) - { - var tsSpeak = DateTime.Now - LastSpeakTime; - if (tsSpeak.TotalSeconds >= PUB.setting.alarmSoundTerm) - { - PUB.Speak(Lang.전방에물체가감지되었습니다); - LastSpeakTime = DateTime.Now; - } - return false; - } + //라이더멈춤이 설정되어있다면 음성으로 알려준다 + if (CheckLiderStop() == false) return false; //현재 위치가 결정되어있는지 체크한다 - if (_SM_RUN_POSCHK(isFirst, stepTime) == false) - return false; + if (_SM_RUN_POSCHK(isFirst, stepTime) == false) return false; /* * 버퍼IN시퀀스 diff --git a/Cs_HMI/Project/StateMachine/Step/_SM_RUN_BUFFER_OUT.cs b/Cs_HMI/Project/StateMachine/Step/_SM_RUN_BUFFER_OUT.cs index 3c5991d..6de2b83 100644 --- a/Cs_HMI/Project/StateMachine/Step/_SM_RUN_BUFFER_OUT.cs +++ b/Cs_HMI/Project/StateMachine/Step/_SM_RUN_BUFFER_OUT.cs @@ -14,37 +14,15 @@ namespace Project public Boolean _SM_RUN_BUFFER_OUT(bool isFirst, TimeSpan stepTime) { - if (runStepisFirst) - { - - } - - //HW 연결오류 - if (PUB.AGV.IsOpen == false) - { - PUB.Result.SetResultMessage(eResult.Hardware, eECode.AGVCONN, eNextStep.ERROR); - return false; - } //충전 상태가 OFF되어야 동작하게한다 - if (_SM_RUN_CHGOFF(isFirst, stepTime) == false) - return false; + if (_SM_RUN_CHGOFF(isFirst, stepTime) == false) return false; - //라이더멈춤이 설정되어있다면 음성으로 알려준다 200409 - if (PUB.AGV.system1.stop_by_front_detect == true) - { - var tsSpeak = DateTime.Now - LastSpeakTime; - if (tsSpeak.TotalSeconds >= PUB.setting.alarmSoundTerm) - { - PUB.Speak(Lang.전방에물체가감지되었습니다); - LastSpeakTime = DateTime.Now; - } - return false; - } + //라이더멈춤이 설정되어있다면 음성으로 알려준다 + if (CheckLiderStop() == false) return false; //현재 위치가 결정되어있는지 체크한다 - if (_SM_RUN_POSCHK(isFirst, stepTime) == false) - return false; + if (_SM_RUN_POSCHK(isFirst, stepTime) == false) return false; var idx = 1; if (PUB.sm.RunStepSeq == idx++) diff --git a/Cs_HMI/Project/StateMachine/Step/_SM_RUN_CLEANER_IN.cs b/Cs_HMI/Project/StateMachine/Step/_SM_RUN_CLEANER_IN.cs new file mode 100644 index 0000000..7f21c0c --- /dev/null +++ b/Cs_HMI/Project/StateMachine/Step/_SM_RUN_CLEANER_IN.cs @@ -0,0 +1,155 @@ +using System; +using System.Collections.Generic; +using System.Drawing; +using System.Linq; +using System.Text; +using Project.StateMachine; +using COMM; +using AR; + +namespace Project +{ + public partial class fMain + { + /// + /// 클리너 진입 + /// + public Boolean _SM_RUN_CLEANER_IN(bool isFirst, TimeSpan stepTime) + { + var funcname = "_SM_RUN_CLEANER_IN"; + var idx = 1; + + //충전 상태가 OFF되어야 동작하게한다 + if (_SM_RUN_CHGOFF(isFirst, stepTime) == false) return false; + + //라이더멈춤이 설정되어있다면 음성으로 알려준다 + if (CheckLiderStop() == false) return false; + + //현재 위치가 결정되어있는지 체크한다 + if (_SM_RUN_POSCHK(isFirst, stepTime) == false) return false; + + /* + * 클리너 IN 시퀀스 (버퍼 복사 - 턴 제거) + * 1. LIFT DOWN + * 2. 후진-저속-마크다운 실행 + */ + + if (PUB.sm.RunStepSeq == idx++) + { + PUB.log.Add("클리너진입시작"); + PUB.Speak("클리너 작업을 시작합니다"); + PUB.sm.UpdateRunStepSeq(); + return false; + } + else if (PUB.sm.RunStepSeq == idx++) + { + //리프트를 내린다. + PUB.AGV.LiftControl(arDev.Narumi.LiftCommand.DN); + VAR.TIME.Update(eVarTime.LastTurnCommandTime); + PUB.sm.UpdateRunStepSeq(); + return false; + } + else if (PUB.sm.RunStepSeq == idx++) + { + //리프트다운센서를 확인한다. + var liftdown = true; + if (liftdown == false) + { + var ts = VAR.TIME.RUN(eVarTime.LastTurnCommandTime); + if (ts.TotalSeconds > 10) + { + PUB.AGV.LiftControl(arDev.Narumi.LiftCommand.STP); + PUB.log.AddE("리프트 하강이 확인되지 않습니다(10초)"); + PUB.sm.SetNewRunStep(ERunStep.ERROR); + return false; + } + } + PUB.log.Add("리프트 하강 완료"); + PUB.sm.UpdateRunStepSeq(); + return false; + } + else if (PUB.sm.RunStepSeq == idx++) + { + //마크스탑셋팅 + PUB.AGV.AGVMoveStop(funcname, arDev.Narumi.eStopOpt.MarkStop); + VAR.TIME.Update(eVarTime.LastTurnCommandTime); + PUB.sm.UpdateRunStepSeq(); + return false; + } + else if (PUB.sm.RunStepSeq == idx++) + { + //저속이동 + var moveset = PUB.AGV.AGVMoveSet(new arDev.Narumi.BunkiData + { + Bunki = arDev.Narumi.eBunki.Strate, + Direction = arDev.Narumi.eMoveDir.Backward, + PBSSensor = 0, + Speed = arDev.Narumi.eMoveSpd.Low, + }); + if (moveset == false) + { + var ts = VAR.TIME.RUN(eVarTime.LastTurnCommandTime); + if (ts.TotalSeconds > 10) + { + PUB.AGV.AGVMoveStop(funcname); + PUB.log.AddE("AGV속도설정이 완료되지 않았습니다"); + PUB.sm.SetNewRunStep(ERunStep.ERROR); + return false; + } + } + PUB.AGV.AGVMoveRun(arDev.Narumi.eRunOpt.Backward); + PUB.AGV.AGVMoveStop(funcname, arDev.Narumi.eStopOpt.MarkStop); + VAR.TIME.Update(eVarTime.LastTurnCommandTime); + PUB.sm.UpdateRunStepSeq(); + return false; + } + else if (PUB.sm.RunStepSeq == idx++) + { + //마크스탑신호가 3초이내로 들어와야 한다 + if (VAR.BOOL[eVarBool.NEXTSTOP_MARK] == false) + { + var ts = VAR.TIME.RUN(eVarTime.LastTurnCommandTime); + if (ts.TotalSeconds > 3) + { + PUB.AGV.AGVMoveStop(funcname); + PUB.log.AddE("MARK STOP신호가 확인되지 않습니다"); + PUB.sm.SetNewRunStep(ERunStep.ERROR); + return false; + } + } + VAR.TIME.Update(eVarTime.LastTurnCommandTime); + PUB.sm.UpdateRunStepSeq(); + return false; + } + else if (PUB.sm.RunStepSeq == idx++) + { + //AGV가 멈출때까지 기다린다. + if (PUB.AGV.system1.agv_run == true) + { + var ts = VAR.TIME.RUN(eVarTime.LastTurnCommandTime); + if (ts.TotalSeconds > 10) + { + PUB.AGV.AGVMoveStop(funcname); + PUB.log.AddE("AGV가 멈추지 않아 강제종료 합니다"); + PUB.sm.SetNewRunStep(ERunStep.ERROR); + return false; + } + return false; + } + VAR.TIME.Update(eVarTime.LastTurnCommandTime); + PUB.sm.UpdateRunStepSeq(); + return false; + } + else if (PUB.sm.RunStepSeq == idx++) + { + //완료되었다. + PUB.log.Add("클리너진입완료"); + PUB.sm.UpdateRunStepSeq(); + return false; + } + + PUB.AddEEDB($"클리너진입완료({PUB.Result.TargetPos})"); + return true; + } + } +} diff --git a/Cs_HMI/Project/StateMachine/Step/_SM_RUN_CLEANER_OUT.cs b/Cs_HMI/Project/StateMachine/Step/_SM_RUN_CLEANER_OUT.cs new file mode 100644 index 0000000..2a743ff --- /dev/null +++ b/Cs_HMI/Project/StateMachine/Step/_SM_RUN_CLEANER_OUT.cs @@ -0,0 +1,80 @@ +using System; +using System.Collections.Generic; +using System.Drawing; +using System.Linq; +using System.Text; +using Project.StateMachine; +using COMM; +using AR; + +namespace Project +{ + public partial class fMain + { + /// + /// 클리너 배출 + /// + public Boolean _SM_RUN_CLEANER_OUT(bool isFirst, TimeSpan stepTime) + { + //충전 상태가 OFF되어야 동작하게한다 + if (_SM_RUN_CHGOFF(isFirst, stepTime) == false) return false; + + //라이더멈춤이 설정되어있다면 음성으로 알려준다 + if (CheckLiderStop() == false) return false; + + //현재 위치가 결정되어있는지 체크한다 + if (_SM_RUN_POSCHK(isFirst, stepTime) == false) return false; + + var idx = 1; + if (PUB.sm.RunStepSeq == idx++) + { + //빈 상태로 아웃해야한다. + PUB.AGV.AGVMoveSet(new arDev.Narumi.BunkiData + { + Bunki = arDev.Narumi.eBunki.Strate, + Direction = arDev.Narumi.eMoveDir.Forward, + PBSSensor = 0, + Speed = arDev.Narumi.eMoveSpd.Low, + }); + PUB.sm.UpdateRunStepSeq(); + return false; + } + else if (PUB.sm.RunStepSeq == idx++) + { + //전진이동 + PUB.AGV.AGVMoveRun(arDev.Narumi.eRunOpt.Forward); + PUB.sm.UpdateRunStepSeq(); + return false; + } + else if (PUB.sm.RunStepSeq == idx++) + { + //마크스탑 + PUB.AGV.AGVMoveStop("cleaner out", arDev.Narumi.eStopOpt.MarkStop); + PUB.sm.UpdateRunStepSeq(); + return false; + } + else if (PUB.sm.RunStepSeq == idx++) + { + //이동확인 + if (PUB.AGV.system1.agv_run == false) + { + return false; + } + PUB.sm.UpdateRunStepSeq(); + return false; + } + else if (PUB.sm.RunStepSeq == idx++) + { + //멈춤확인 + if (PUB.AGV.system1.agv_run == true) + { + return false; + } + PUB.sm.UpdateRunStepSeq(); + return false; + } + + return true; + } + } +} diff --git a/Cs_HMI/Project/StateMachine/Step/_SM_RUN_LOADER_IN.cs b/Cs_HMI/Project/StateMachine/Step/_SM_RUN_LOADER_IN.cs new file mode 100644 index 0000000..e53980e --- /dev/null +++ b/Cs_HMI/Project/StateMachine/Step/_SM_RUN_LOADER_IN.cs @@ -0,0 +1,155 @@ +using System; +using System.Collections.Generic; +using System.Drawing; +using System.Linq; +using System.Text; +using Project.StateMachine; +using COMM; +using AR; + +namespace Project +{ + public partial class fMain + { + /// + /// 로더 진입 + /// + public Boolean _SM_RUN_LOADER_IN(bool isFirst, TimeSpan stepTime) + { + var funcname = "_SM_RUN_LOADER_IN"; + var idx = 1; + + //충전 상태가 OFF되어야 동작하게한다 + if (_SM_RUN_CHGOFF(isFirst, stepTime) == false) return false; + + //라이더멈춤이 설정되어있다면 음성으로 알려준다 + if (CheckLiderStop() == false) return false; + + //현재 위치가 결정되어있는지 체크한다 + if (_SM_RUN_POSCHK(isFirst, stepTime) == false) return false; + + /* + * 로더 IN 시퀀스 (버퍼 복사 - 턴 제거) + * 1. LIFT DOWN + * 2. 후진-저속-마크다운 실행 + */ + + if (PUB.sm.RunStepSeq == idx++) + { + PUB.log.Add("로더진입시작"); + PUB.Speak("로더 작업을 시작합니다"); // Lang resource might not exist, using string + PUB.sm.UpdateRunStepSeq(); + return false; + } + else if (PUB.sm.RunStepSeq == idx++) + { + //리프트를 내린다. + PUB.AGV.LiftControl(arDev.Narumi.LiftCommand.DN); + VAR.TIME.Update(eVarTime.LastTurnCommandTime); + PUB.sm.UpdateRunStepSeq(); + return false; + } + else if (PUB.sm.RunStepSeq == idx++) + { + //리프트다운센서를 확인한다. + var liftdown = true; // 센서 확인 로직이 주석처리되어 있거나 하드코딩되어 있었음 (버퍼 코드 참조) + if (liftdown == false) + { + var ts = VAR.TIME.RUN(eVarTime.LastTurnCommandTime); + if (ts.TotalSeconds > 10) + { + PUB.AGV.LiftControl(arDev.Narumi.LiftCommand.STP); + PUB.log.AddE("리프트 하강이 확인되지 않습니다(10초)"); + PUB.sm.SetNewRunStep(ERunStep.ERROR); + return false; + } + } + PUB.log.Add("리프트 하강 완료"); + PUB.sm.UpdateRunStepSeq(); + return false; + } + else if (PUB.sm.RunStepSeq == idx++) + { + //마크스탑셋팅 + PUB.AGV.AGVMoveStop(funcname, arDev.Narumi.eStopOpt.MarkStop); + VAR.TIME.Update(eVarTime.LastTurnCommandTime); + PUB.sm.UpdateRunStepSeq(); + return false; + } + else if (PUB.sm.RunStepSeq == idx++) + { + //저속이동 + var moveset = PUB.AGV.AGVMoveSet(new arDev.Narumi.BunkiData + { + Bunki = arDev.Narumi.eBunki.Strate, + Direction = arDev.Narumi.eMoveDir.Backward, + PBSSensor = 0, + Speed = arDev.Narumi.eMoveSpd.Low, + }); + if (moveset == false) + { + var ts = VAR.TIME.RUN(eVarTime.LastTurnCommandTime); + if (ts.TotalSeconds > 10) + { + PUB.AGV.AGVMoveStop(funcname); + PUB.log.AddE("AGV속도설정이 완료되지 않았습니다"); + PUB.sm.SetNewRunStep(ERunStep.ERROR); + return false; + } + } + PUB.AGV.AGVMoveRun(arDev.Narumi.eRunOpt.Backward); + PUB.AGV.AGVMoveStop(funcname, arDev.Narumi.eStopOpt.MarkStop); + VAR.TIME.Update(eVarTime.LastTurnCommandTime); + PUB.sm.UpdateRunStepSeq(); + return false; + } + else if (PUB.sm.RunStepSeq == idx++) + { + //마크스탑신호가 3초이내로 들어와야 한다 + if (VAR.BOOL[eVarBool.NEXTSTOP_MARK] == false) + { + var ts = VAR.TIME.RUN(eVarTime.LastTurnCommandTime); + if (ts.TotalSeconds > 3) + { + PUB.AGV.AGVMoveStop(funcname); + PUB.log.AddE("MARK STOP신호가 확인되지 않습니다"); + PUB.sm.SetNewRunStep(ERunStep.ERROR); + return false; + } + } + VAR.TIME.Update(eVarTime.LastTurnCommandTime); + PUB.sm.UpdateRunStepSeq(); + return false; + } + else if (PUB.sm.RunStepSeq == idx++) + { + //AGV가 멈출때까지 기다린다. + if (PUB.AGV.system1.agv_run == true) + { + var ts = VAR.TIME.RUN(eVarTime.LastTurnCommandTime); + if (ts.TotalSeconds > 10) + { + PUB.AGV.AGVMoveStop(funcname); + PUB.log.AddE("AGV가 멈추지 않아 강제종료 합니다"); + PUB.sm.SetNewRunStep(ERunStep.ERROR); + return false; + } + return false; + } + VAR.TIME.Update(eVarTime.LastTurnCommandTime); + PUB.sm.UpdateRunStepSeq(); + return false; + } + else if (PUB.sm.RunStepSeq == idx++) + { + //완료되었다. + PUB.log.Add("로더진입완료"); + PUB.sm.UpdateRunStepSeq(); + return false; + } + + PUB.AddEEDB($"로더진입완료({PUB.Result.TargetPos})"); + return true; + } + } +} diff --git a/Cs_HMI/Project/StateMachine/Step/_SM_RUN_LOADER_OUT.cs b/Cs_HMI/Project/StateMachine/Step/_SM_RUN_LOADER_OUT.cs new file mode 100644 index 0000000..2487ec0 --- /dev/null +++ b/Cs_HMI/Project/StateMachine/Step/_SM_RUN_LOADER_OUT.cs @@ -0,0 +1,82 @@ +using System; +using System.Collections.Generic; +using System.Drawing; +using System.Linq; +using System.Text; +using Project.StateMachine; +using COMM; +using AR; + +namespace Project +{ + public partial class fMain + { + /// + /// 로더 배출 + /// + public Boolean _SM_RUN_LOADER_OUT(bool isFirst, TimeSpan stepTime) + { + + //충전 상태가 OFF되어야 동작하게한다 + if (_SM_RUN_CHGOFF(isFirst, stepTime) == false) return false; + + //라이더멈춤이 설정되어있다면 음성으로 알려준다 + if (CheckLiderStop() == false) return false; + + //현재 위치가 결정되어있는지 체크한다 + if (_SM_RUN_POSCHK(isFirst, stepTime) == false) return false; + + var idx = 1; + if (PUB.sm.RunStepSeq == idx++) + { + //빈 상태로 아웃해야한다. + PUB.AGV.AGVMoveSet(new arDev.Narumi.BunkiData + { + Bunki = arDev.Narumi.eBunki.Strate, + Direction = arDev.Narumi.eMoveDir.Forward, + PBSSensor = 0, + Speed = arDev.Narumi.eMoveSpd.Low, + }); + PUB.sm.UpdateRunStepSeq(); + return false; + } + else if (PUB.sm.RunStepSeq == idx++) + { + //전진이동 + PUB.AGV.AGVMoveRun(arDev.Narumi.eRunOpt.Forward); + PUB.sm.UpdateRunStepSeq(); + return false; + } + else if (PUB.sm.RunStepSeq == idx++) + { + //마크스탑 + PUB.AGV.AGVMoveStop("loader out", arDev.Narumi.eStopOpt.MarkStop); + PUB.sm.UpdateRunStepSeq(); + return false; + } + else if (PUB.sm.RunStepSeq == idx++) + { + //이동확인 + if (PUB.AGV.system1.agv_run == false) + { + return false; + } + PUB.sm.UpdateRunStepSeq(); + return false; + } + else if (PUB.sm.RunStepSeq == idx++) + { + //멈춤확인 + if (PUB.AGV.system1.agv_run == true) + { + return false; + } + PUB.sm.UpdateRunStepSeq(); + return false; + } + // 턴 제거됨 + + return true; + } + } +} diff --git a/Cs_HMI/Project/StateMachine/Step/_SM_RUN_UNLOADER_IN.cs b/Cs_HMI/Project/StateMachine/Step/_SM_RUN_UNLOADER_IN.cs new file mode 100644 index 0000000..003d9dd --- /dev/null +++ b/Cs_HMI/Project/StateMachine/Step/_SM_RUN_UNLOADER_IN.cs @@ -0,0 +1,155 @@ +using System; +using System.Collections.Generic; +using System.Drawing; +using System.Linq; +using System.Text; +using Project.StateMachine; +using COMM; +using AR; + +namespace Project +{ + public partial class fMain + { + /// + /// 언로더 진입 + /// + public Boolean _SM_RUN_UNLOADER_IN(bool isFirst, TimeSpan stepTime) + { + var funcname = "_SM_RUN_UNLOADER_IN"; + var idx = 1; + + //충전 상태가 OFF되어야 동작하게한다 + if (_SM_RUN_CHGOFF(isFirst, stepTime) == false) return false; + + //라이더멈춤이 설정되어있다면 음성으로 알려준다 + if (CheckLiderStop() == false) return false; + + //현재 위치가 결정되어있는지 체크한다 + if (_SM_RUN_POSCHK(isFirst, stepTime) == false) return false; + + /* + * 언로더 IN 시퀀스 (버퍼 복사 - 턴 제거) + * 1. LIFT DOWN + * 2. 후진-저속-마크다운 실행 + */ + + if (PUB.sm.RunStepSeq == idx++) + { + PUB.log.Add("언로더진입시작"); + PUB.Speak("언로더 작업을 시작합니다"); + PUB.sm.UpdateRunStepSeq(); + return false; + } + else if (PUB.sm.RunStepSeq == idx++) + { + //리프트를 내린다. + PUB.AGV.LiftControl(arDev.Narumi.LiftCommand.DN); + VAR.TIME.Update(eVarTime.LastTurnCommandTime); + PUB.sm.UpdateRunStepSeq(); + return false; + } + else if (PUB.sm.RunStepSeq == idx++) + { + //리프트다운센서를 확인한다. + var liftdown = true; + if (liftdown == false) + { + var ts = VAR.TIME.RUN(eVarTime.LastTurnCommandTime); + if (ts.TotalSeconds > 10) + { + PUB.AGV.LiftControl(arDev.Narumi.LiftCommand.STP); + PUB.log.AddE("리프트 하강이 확인되지 않습니다(10초)"); + PUB.sm.SetNewRunStep(ERunStep.ERROR); + return false; + } + } + PUB.log.Add("리프트 하강 완료"); + PUB.sm.UpdateRunStepSeq(); + return false; + } + else if (PUB.sm.RunStepSeq == idx++) + { + //마크스탑셋팅 + PUB.AGV.AGVMoveStop(funcname, arDev.Narumi.eStopOpt.MarkStop); + VAR.TIME.Update(eVarTime.LastTurnCommandTime); + PUB.sm.UpdateRunStepSeq(); + return false; + } + else if (PUB.sm.RunStepSeq == idx++) + { + //저속이동 + var moveset = PUB.AGV.AGVMoveSet(new arDev.Narumi.BunkiData + { + Bunki = arDev.Narumi.eBunki.Strate, + Direction = arDev.Narumi.eMoveDir.Backward, + PBSSensor = 0, + Speed = arDev.Narumi.eMoveSpd.Low, + }); + if (moveset == false) + { + var ts = VAR.TIME.RUN(eVarTime.LastTurnCommandTime); + if (ts.TotalSeconds > 10) + { + PUB.AGV.AGVMoveStop(funcname); + PUB.log.AddE("AGV속도설정이 완료되지 않았습니다"); + PUB.sm.SetNewRunStep(ERunStep.ERROR); + return false; + } + } + PUB.AGV.AGVMoveRun(arDev.Narumi.eRunOpt.Backward); + PUB.AGV.AGVMoveStop(funcname, arDev.Narumi.eStopOpt.MarkStop); + VAR.TIME.Update(eVarTime.LastTurnCommandTime); + PUB.sm.UpdateRunStepSeq(); + return false; + } + else if (PUB.sm.RunStepSeq == idx++) + { + //마크스탑신호가 3초이내로 들어와야 한다 + if (VAR.BOOL[eVarBool.NEXTSTOP_MARK] == false) + { + var ts = VAR.TIME.RUN(eVarTime.LastTurnCommandTime); + if (ts.TotalSeconds > 3) + { + PUB.AGV.AGVMoveStop(funcname); + PUB.log.AddE("MARK STOP신호가 확인되지 않습니다"); + PUB.sm.SetNewRunStep(ERunStep.ERROR); + return false; + } + } + VAR.TIME.Update(eVarTime.LastTurnCommandTime); + PUB.sm.UpdateRunStepSeq(); + return false; + } + else if (PUB.sm.RunStepSeq == idx++) + { + //AGV가 멈출때까지 기다린다. + if (PUB.AGV.system1.agv_run == true) + { + var ts = VAR.TIME.RUN(eVarTime.LastTurnCommandTime); + if (ts.TotalSeconds > 10) + { + PUB.AGV.AGVMoveStop(funcname); + PUB.log.AddE("AGV가 멈추지 않아 강제종료 합니다"); + PUB.sm.SetNewRunStep(ERunStep.ERROR); + return false; + } + return false; + } + VAR.TIME.Update(eVarTime.LastTurnCommandTime); + PUB.sm.UpdateRunStepSeq(); + return false; + } + else if (PUB.sm.RunStepSeq == idx++) + { + //완료되었다. + PUB.log.Add("언로더진입완료"); + PUB.sm.UpdateRunStepSeq(); + return false; + } + + PUB.AddEEDB($"언로더진입완료({PUB.Result.TargetPos})"); + return true; + } + } +} diff --git a/Cs_HMI/Project/StateMachine/Step/_SM_RUN_UNLOADER_OUT.cs b/Cs_HMI/Project/StateMachine/Step/_SM_RUN_UNLOADER_OUT.cs new file mode 100644 index 0000000..eedea06 --- /dev/null +++ b/Cs_HMI/Project/StateMachine/Step/_SM_RUN_UNLOADER_OUT.cs @@ -0,0 +1,81 @@ +using System; +using System.Collections.Generic; +using System.Drawing; +using System.Linq; +using System.Text; +using Project.StateMachine; +using COMM; +using AR; + +namespace Project +{ + public partial class fMain + { + /// + /// 언로더 배출 + /// + public Boolean _SM_RUN_UNLOADER_OUT(bool isFirst, TimeSpan stepTime) + { + + //충전 상태가 OFF되어야 동작하게한다 + if (_SM_RUN_CHGOFF(isFirst, stepTime) == false) return false; + + //라이더멈춤이 설정되어있다면 음성으로 알려준다 + if (CheckLiderStop() == false) return false; + + //현재 위치가 결정되어있는지 체크한다 + if (_SM_RUN_POSCHK(isFirst, stepTime) == false) return false; + + var idx = 1; + if (PUB.sm.RunStepSeq == idx++) + { + //빈 상태로 아웃해야한다. + PUB.AGV.AGVMoveSet(new arDev.Narumi.BunkiData + { + Bunki = arDev.Narumi.eBunki.Strate, + Direction = arDev.Narumi.eMoveDir.Forward, + PBSSensor = 0, + Speed = arDev.Narumi.eMoveSpd.Low, + }); + PUB.sm.UpdateRunStepSeq(); + return false; + } + else if (PUB.sm.RunStepSeq == idx++) + { + //전진이동 + PUB.AGV.AGVMoveRun(arDev.Narumi.eRunOpt.Forward); + PUB.sm.UpdateRunStepSeq(); + return false; + } + else if (PUB.sm.RunStepSeq == idx++) + { + //마크스탑 + PUB.AGV.AGVMoveStop("unloader out", arDev.Narumi.eStopOpt.MarkStop); + PUB.sm.UpdateRunStepSeq(); + return false; + } + else if (PUB.sm.RunStepSeq == idx++) + { + //이동확인 + if (PUB.AGV.system1.agv_run == false) + { + return false; + } + PUB.sm.UpdateRunStepSeq(); + return false; + } + else if (PUB.sm.RunStepSeq == idx++) + { + //멈춤확인 + if (PUB.AGV.system1.agv_run == true) + { + return false; + } + PUB.sm.UpdateRunStepSeq(); + return false; + } + + return true; + } + } +} diff --git a/Cs_HMI/Project/StateMachine/Step/_Util.cs b/Cs_HMI/Project/StateMachine/Step/_Util.cs index 8cf66d4..ef53e25 100644 --- a/Cs_HMI/Project/StateMachine/Step/_Util.cs +++ b/Cs_HMI/Project/StateMachine/Step/_Util.cs @@ -17,6 +17,26 @@ namespace Project return true; } + /// + /// 라이더멈춤이 설정되어있다면 음성으로 알려준다 + /// + /// + public bool CheckLiderStop() + { + + if (PUB.AGV.system1.stop_by_front_detect == true) + { + var tsSpeak = DateTime.Now - LastSpeakTime; + if (tsSpeak.TotalSeconds >= PUB.setting.alarmSoundTerm) + { + PUB.Speak(Lang.전방에물체가감지되었습니다); + LastSpeakTime = DateTime.Now; + } + return false; + } + return true; + } + /// /// 설정된 목적지까지 이동을 완료 한 후 True를 반환합니다. /// 목적지 : PUB._virtualAGV.TargetNode diff --git a/Cs_HMI/Project/StateMachine/_TMDisplay.cs b/Cs_HMI/Project/StateMachine/_TMDisplay.cs index 17bcd9d..68a35ac 100644 --- a/Cs_HMI/Project/StateMachine/_TMDisplay.cs +++ b/Cs_HMI/Project/StateMachine/_TMDisplay.cs @@ -714,6 +714,30 @@ namespace Project } else UpdateStatusMessage(String.Format("상차 이동 중 ({0})", PUB.Result.TargetPos), Color.Lime, Color.Black); } + else if (PUB.sm.RunStep == ERunStep.LOADER_IN) + { + UpdateStatusMessage(String.Format("로더 진입 중 ({0})", PUB.Result.TargetPos), Color.Lime, Color.Black); + } + else if (PUB.sm.RunStep == ERunStep.LOADER_OUT) + { + UpdateStatusMessage(String.Format("로더 배출 중 ({0})", PUB.Result.TargetPos), Color.Lime, Color.Black); + } + else if (PUB.sm.RunStep == ERunStep.UNLOADER_IN) + { + UpdateStatusMessage(String.Format("언로더 진입 중 ({0})", PUB.Result.TargetPos), Color.Lime, Color.Black); + } + else if (PUB.sm.RunStep == ERunStep.UNLOADER_OUT) + { + UpdateStatusMessage(String.Format("언로더 배출 중 ({0})", PUB.Result.TargetPos), Color.Lime, Color.Black); + } + else if (PUB.sm.RunStep == ERunStep.CLEANER_IN) + { + UpdateStatusMessage(String.Format("클리너 진입 중 ({0})", PUB.Result.TargetPos), Color.Lime, Color.Black); + } + else if (PUB.sm.RunStep == ERunStep.CLEANER_OUT) + { + UpdateStatusMessage(String.Format("클리너 배출 중 ({0})", PUB.Result.TargetPos), Color.Lime, Color.Black); + } else if (PUB.sm.RunStep == ERunStep.GOCHARGE) { if (PUB.Result.result_message.isEmpty() == true) diff --git a/Cs_HMI/StateMachine/EnumStruct.cs b/Cs_HMI/StateMachine/EnumStruct.cs index f792428..0db3914 100644 --- a/Cs_HMI/StateMachine/EnumStruct.cs +++ b/Cs_HMI/StateMachine/EnumStruct.cs @@ -78,7 +78,12 @@ namespace Project.StateMachine /// BUFFER_IN, - + LOADER_IN, + LOADER_OUT, + UNLOADER_IN, + UNLOADER_OUT, + CLEANER_IN, + CLEANER_OUT, /// /// 목적지로 이동합니다 @@ -93,7 +98,7 @@ namespace Project.StateMachine /// /// 후진방향으로 마크스탑진행 /// - MARKSTROPB, + MARKSTOPB, /// /// 에러발생