initial commit

This commit is contained in:
chi
2025-01-07 16:08:02 +09:00
parent 9e657e2558
commit 0a93a54a6f
268 changed files with 50767 additions and 0 deletions

View File

@@ -0,0 +1,246 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ComponentModel;
using System.Threading;
using System.Threading.Tasks;
using System.Collections;
using COMM;
using System.Security.Cryptography.X509Certificates;
namespace arDev
{
public partial class Narumi : arRS232
{
public bool AGVMoveSet(BunkiData opt)
{
return AddCommand(eAgvCmd.MoveSet, opt.ToString());
}
public bool AGVMoveManual(ManulOpt opt, Speed spd, Sensor ss)
{
var param = opt.ToString() + spd.ToString()[0] + ((int)ss).ToString();
return AddCommand(eAgvCmd.ManualMove, param);
}
public bool AGVMoveRun(eRunOpt opt = eRunOpt.NotSet)
{
System.Text.StringBuilder sb = new StringBuilder();
if (opt == eRunOpt.Backward) sb.Append("B");
else if (opt == eRunOpt.Forward) sb.Append("F");
else sb.Append("0");
sb.Append("000");
return AddCommand(eAgvCmd.MoveStart, sb.ToString());
}
public bool AGVSetSpeed(eSetSpeed item, int speed)
{
string cmd = "SS";
if (item == eSetSpeed.Rotation) cmd = "SRS";
else cmd += item.ToString()[0];
cmd += speed.ToString("0000");
return AddCommand(cmd);
}
public bool AGVMoveStop(string Reason, eStopOpt opt = eStopOpt.Stop)
{
System.Text.StringBuilder sb = new StringBuilder();
if (opt == eStopOpt.MarkStop) sb.Append("MS");
else if (opt == eStopOpt.MarkRotateLeft) sb.Append("TL");
else if (opt == eStopOpt.MarkRotateRight) sb.Append("TR");
else if (opt == eStopOpt.MarkChangeDirection) sb.Append("BS");
else sb.Append("0S");
sb.Append("00");
sb.Append("0000"); //재기동시간
if (opt == eStopOpt.MarkStop)
VAR.BOOL[eVarBool.NEXTSTOP_MARK] = true;
//동작중이면 이 멈춤 명령을 기록으로 남긴다 230116
if (this.system1.agv_run)
RaiseMessage(MessageType.Normal, $"stop command from {Reason}");
return AddCommand(eAgvCmd.MoveStop, sb.ToString());
}
public bool AGVCommand(string cmd, string data)
{
return AddCommand(cmd + data);
}
public bool LiftControl(LiftCommand cmd)
{
return AddCommand(eAgvCmd.LiftControl, cmd.ToString());
}
public bool AGVCharge(int chargetID, bool on, int waittime = 3)
{
if (on)
return AddCommand(eAgvCmd.ChargeOn, chargetID.ToString("0000"));
else
return AddCommand(eAgvCmd.ChargeOf, chargetID.ToString("0000"));
}
public bool AGVErrorReset()
{
return AddCommand(eAgvCmd.ErrorReset, "FFFF");
}
public bool AGVTowerLamp(bool on)
{
return AddCommand(eAgvCmd.TowerLamp, (on ? "I" : "O"));
}
public bool AGVSetAddress(int value)
{
return AddCommand($"SAD{value:0000}");
}
public bool AGVSetPanID(string value)
{
value = value.PadLeft(4, '0');
return AddCommand($"SPN{value}");
}
public bool AGVSetChannel(string value)
{
value = value.PadLeft(4, '0');
return AddCommand($"SCH{value}");
}
public bool AGVGateOutTimer(int value)
{
return AddCommand($"SGT{value:0000}");
}
/// <summary>
/// 정지감속주기 및 상수
/// </summary>
/// <returns></returns>
public bool AGVSetStopAcc(int interval, int value)
{
var cmds = new string[] {
$"SSK{interval:0000}",
$"SCK{value:0000}"
};
return AddCommand(cmds);
}
public bool AGVSetTagReinputTime(int value)
{
return AddCommand($"STT{value:0000}");
}
public bool AGVSetPID(eSetPIDSpeed speed, int P, int I, int D)
{
var cmd = "S";
var cmd2 = "";
if (speed == eSetPIDSpeed.High) cmd2 = "K";
else if (speed == eSetPIDSpeed.Middle) cmd2 = "M";
else if (speed == eSetPIDSpeed.Low) cmd2 = "L";
else if (speed == eSetPIDSpeed.Stop) cmd2 = "S";
var cmds = new string[] {
$"{cmd}P{cmd2}{P:0000}",
$"{cmd}I{cmd2}{I:0000}",
$"{cmd}D{cmd2}{D:0000}",
};
return AddCommand(cmds);
}
protected bool AddCommand(params string[] cmds)
{
bool ret = true;
ACKData = string.Empty; //회신값 제거
foreach (var cmdline in cmds)
{
var fullcmd = MakeCheckSum(cmdline);
//commandQueue.Enqueue(fullcmd);
if (WriteData(fullcmd) == false) ret = false;
System.Threading.Thread.Sleep(1);
}
return ret;
}
protected bool AddCommand(eAgvCmd command, BunkiData param)
{
return AddCommand(command, param.ToString());
}
/// <summary>
/// CBR커맨드를 사용하여 옵션값을 전송 합니다
/// 11.분기명령 = CBR
/// </summary>
/// <param name="param"></param>
/// <param name="Repeat"></param>
protected bool AddCommand(BunkiData param)
{
return AddCommand(eAgvCmd.MoveSet, param.ToString());
}
protected bool AddCommand(eAgvCmd command, string param = "")
{
string cmdString;
bool retval = false;
switch (command)
{
case eAgvCmd.ErrorReset:
cmdString = $"SFR{param}";
retval = AddCommand(cmdString);
break;
case eAgvCmd.TowerLamp:
cmdString = $"CBZ" + $"0299{param}0000";
retval = AddCommand(cmdString);
break;
case eAgvCmd.MoveStop:
cmdString = $"CST{param}";
system1.agv_run_manual = false;
retval = AddCommand(cmdString);
break;
case eAgvCmd.MoveStart:
cmdString = $"CRN{param}";
retval = AddCommand(cmdString);
break;
case eAgvCmd.ChargeOf:
cmdString = $"CBT{param}O0003"; ///0003=충전대기시간
retval = AddCommand(cmdString);
RaiseMessage(arRS232.MessageType.Normal, "충전취소전송");
break;
case eAgvCmd.ChargeOn:
cmdString = $"CBT{param}I0003"; ///0003=충전대기시간
retval = AddCommand(cmdString);
RaiseMessage(arRS232.MessageType.Normal, "충전명령전송");
break;
case eAgvCmd.GoTurnLeft:
cmdString = $"CTL0000";
retval = AddCommand(cmdString);
break;
case eAgvCmd.GoTurnRight:
cmdString = $"CTR0000";
retval = AddCommand(cmdString);
break;
case eAgvCmd.goTurnBack:
cmdString = $"CTB0000";
retval = AddCommand(cmdString);
break;
case eAgvCmd.CallCancle:
cmdString = $"CCL0{param}010000";
retval = AddCommand(cmdString);
break;
case eAgvCmd.MoveSet:
cmdString = $"CBR{param}";
retval = AddCommand(cmdString);
break;
case eAgvCmd.ManualMove:
system1.agv_run_manual = true;
cmdString = $"CRT{param}";
retval = AddCommand(cmdString);
break;
case eAgvCmd.LiftControl:
cmdString = "CLF" + param.PadRight(6, '0');
retval = AddCommand(cmdString);
break;
}
return retval;
}
}
}

View File

@@ -0,0 +1,19 @@
using System;
namespace arDev
{
public partial class Narumi
{
public class DataEventArgs : EventArgs
{
public DataType DataType { get; set; }
public DataEventArgs(DataType type)
{
DataType = type;
}
}
}
}

View File

@@ -0,0 +1,213 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace arDev
{
public partial class Narumi
{
public enum eMoveDir
{
Forward,
Backward,
}
public enum eMoveSpd
{
High,
Middle,
Low,
}
public enum eSetPIDSpeed
{
High,
Middle,
Low,
Stop,
}
public enum eSetSpeed
{
High,
Middle,
Low,
Stop,
Rotation,
}
public enum eBunki
{
Right,
Strate,
Left,
}
public enum Messagetype
{
Normal,
Error,
Send,
Recv,
}
public enum DataType
{
UNKNOWN,
TAG,
CALL,
STS,
ACK,
NAK,
CCA,
}
public class BunkiData
{
public BunkiData()
{
}
public BunkiData(char dir, char bunki, char speed)
{
if (dir == 'F') Direction = eMoveDir.Forward;
else if (dir == 'B') Direction = eMoveDir.Backward;
if (bunki == 'S') Bunki = eBunki.Strate;
else if (bunki == 'L') Bunki = eBunki.Left;
else if (bunki == 'R') Bunki = eBunki.Right;
if (speed == 'H') this.Speed = eMoveSpd.High;
else if (speed == 'M') this.Speed = eMoveSpd.Middle;
else if (speed == 'L') this.Speed = eMoveSpd.Low;
}
public eMoveDir Direction { get; set; } = eMoveDir.Forward;
public eBunki Bunki { get; set; } = eBunki.Strate;
public eMoveSpd Speed { get; set; } = eMoveSpd.Middle;
public int PBSSensor { get; set; } = 1;
public override string ToString()
{
System.Text.StringBuilder sb = new StringBuilder();
sb.Append(Direction.ToString()[0]);
sb.Append(Bunki.ToString()[0]);
sb.Append(Speed.ToString()[0]);
sb.Append(PBSSensor.ToString()[0]);
return sb.ToString();
}
}
public enum eAgvCmd
{
/// <summary>
/// 충전시작
/// CMD : CBT02{nBatteryNo}I0103
/// </summary>
ChargeOn,
/// <summary>
/// 충전취소
/// CMD : CBT02{nBatteryNo}O0103
/// </summary>
ChargeOf,
/// <summary>
/// 이동명령(파라미터필요)
/// 이동대상,속도(H,M,L),센서사용여부(1,0)
/// ex) BSLTH0
/// CMD : CRT{param}
/// </summary>
ManualMove,
/// <summary>
/// 기동명령
/// CMD : CRN0000
/// </summary>
MoveStart,
/// <summary>
/// 분기명령
/// CMD : CBR{param}
/// </summary>
MoveSet,
/// <summary>
/// 정지 명령
/// CMD : CST0S000000
/// </summary>
MoveStop,
/// <summary>
/// 콜 취소,
/// Param : 번호 char(1)
/// CMD : CCL0{param}010000
/// </summary>
CallCancle,
/// <summary>
/// CMD : CTL0000
/// </summary>
GoTurnLeft,
/// <summary>
/// CMD : CTR0000
/// </summary>
GoTurnRight,
/// <summary>
/// CMD : CTB0000
/// </summary>
goTurnBack,
/// <summary>
/// CMD : CBZ
/// </summary>
TowerLamp,
/// <summary>
/// CMD : SFR
/// </summary>
ErrorReset,
/// <summary>
/// CMD : CLF
/// </summary>
LiftControl,
/// <summary>
/// SS(H/M/L/S)
/// SRS
/// </summary>
SetSpeed,
}
public enum eForm
{
DriveControl,
ManualControl,
RouteSelect,
Setting,
ModeChange,
}
public enum eNotify
{
ReadTag,
IpAddresschanged,
NameChanged,
ReadViewStep,
ReadViewCall,
WatchError,
/// <summary>
/// 통신에서받은 AGV의 상태값이며, 속도 진행 방향을 가지고 있음
/// Dashboardform 하단에 상태 표시 함
/// </summary>
StatusDisplay,
StatusComm,
StatusRiv,
StatusETC,
ChangeMode,
/// <summary>
/// 편집대상경로는 아래 변수에 저장되어잇음
/// datamanager.sEditrRoute
/// </summary>
EditRoute,
}
}
}

View File

@@ -0,0 +1,64 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{8BAE0EAC-3D25-402F-9A65-2BA1ECFE28B7}</ProjectGuid>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>arDevice</RootNamespace>
<AssemblyName>Narumi</AssemblyName>
<TargetFrameworkVersion>v4.8</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<Deterministic>true</Deterministic>
<TargetFrameworkProfile />
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<Prefer32Bit>false</Prefer32Bit>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<Prefer32Bit>false</Prefer32Bit>
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.Data" />
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="DataEventArgs.cs" />
<Compile Include="EnumData.cs" />
<Compile Include="Command.cs" />
<Compile Include="Structure\ErrorFlag.cs" />
<Compile Include="Narumi.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Structure\SystemFlag0.cs" />
<Compile Include="Structure\AgvData.cs" />
<Compile Include="Structure\Signals.cs" />
<Compile Include="Structure\SystemFlag1.cs" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\CommData\CommData.csproj">
<Project>{14e8c9a5-013e-49ba-b435-efefc77dd623}</Project>
<Name>CommData</Name>
</ProjectReference>
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
</Project>

View File

@@ -0,0 +1,586 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ComponentModel;
using System.Threading;
using System.Threading.Tasks;
using System.Collections;
using COMM;
using System.Security.Cryptography.X509Certificates;
namespace arDev
{
public partial class Narumi : arRS232
{
Hashtable SystemCheck, ErrorCheck;
private Queue Errlog; // 에러발생시 코드 임시 저장용(쓰레드 동기화용)
public int nBatteryNo { get; set; } = 0;
public Narumi()
{
SystemCheck = new Hashtable();
SystemCheck.Add(15, "100");
SystemCheck.Add(14, "9");
SystemCheck.Add(13, "8");
SystemCheck.Add(12, "53");
SystemCheck.Add(11, "3");
//SystemCheck.Add(10, "66");
//SystemCheck.Add(9, "56");
SystemCheck.Add(8, "6");
SystemCheck.Add(7, "5");
SystemCheck.Add(6, "60");
SystemCheck.Add(5, "1");
SystemCheck.Add(4, "2");
//SystemCheck.Add(3, "65");
//SystemCheck.Add(2, "55");
//SystemCheck.Add(1, "11");
//SystemCheck.Add(0, "22");
ErrorCheck = new Hashtable();
ErrorCheck.Add(15, "17");
ErrorCheck.Add(14, "15");
ErrorCheck.Add(13, "18");
ErrorCheck.Add(12, "19");
//ErrorCheck.Add(11, "300");
ErrorCheck.Add(10, "299");
ErrorCheck.Add(9, "298");
ErrorCheck.Add(8, "297");
ErrorCheck.Add(7, "296");
//ErrorCheck.Add(6,"");
ErrorCheck.Add(5, "12");
ErrorCheck.Add(4, "13");
ErrorCheck.Add(3, "14");
ErrorCheck.Add(2, "16");
ErrorCheck.Add(1, "11");
ErrorCheck.Add(0, "10");
Errlog = new Queue();
MinRecvLength = 4;
COMM.VAR.Init(128);
}
#region "External Events"
/// <summary>
/// 분석완료된 데이터 이벤트
/// </summary>
public event EventHandler<DataEventArgs> DataReceive;
#endregion
protected override bool CustomParser(byte[] buf, out byte[] remainBuffer)
{
List<byte> remain = new List<byte>();
//데이터는 총 34byt 이며 , DD~77로 구성됨
Boolean bComplete = false;
for (int i = 0; i < buf.Length; i++)
{
var incomByte = buf[i];
if (bComplete == true)
{
remain.Add(incomByte);
}
else
{
if (incomByte == 0x02)
{
findSTX = true;
tempBuffer.Clear();
tempBuffer.Add(incomByte);
}
else if (incomByte == 0x03)
{
//데이터가 맞게 수신됨
//tempBuffer.Add(incomByte);
tempBuffer.Add(incomByte);
findSTX = false;
bComplete = true;
}
else
{
tempBuffer.Add(incomByte);
if (tempBuffer.Count == 150) //data overload
{
findSTX = false;
tempBuffer.Clear();
bComplete = false;
RaiseMessage(MessageType.Error, "Buffer Over");
}
}
}
}
remainBuffer = remain.ToArray();
return bComplete;
}
public class Dataframe
{
public byte STX { get; private set; }
public byte ETX { get; private set; }
public byte[] Data { get; private set; }
public string DataString { get; private set; }
public byte[] checksum { get; private set; } = new byte[2];
public bool Valid { get; private set; } = false;
public string Message { get; private set; } = string.Empty;
public byte[] Buffer { get; private set; }
public string Cmd { get; private set; } = string.Empty;
public bool Parse(byte[] data, int MinRecvLength = 0)
{
if (data == null || data.Any() == false)
{
this.Message = string.Format("수신 데이터가 없습니다");
return false;
}
else if (data.Length < 5)
{
this.Message = $"데이터의 길이가 5보다 작습니다 길이={data.Length}";
return false;
}
else if (MinRecvLength > 0 && data.Length < MinRecvLength)
{
this.Message = $"데이터의 길이가 {MinRecvLength}보다 작습니다 길이={data.Length}";
return false;
}
else if (data[0] != 0x02 || data[data.Length - 1] != 0x03)
{
this.Message = $"STX/ETX Error";
return false;
}
Buffer = new byte[data.Length];
Array.Copy(data, Buffer, data.Length);
STX = data[0];
ETX = data[data.Length - 1];
Array.Copy(data, data.Length - 3, checksum, 0, 2);
Data = new byte[data.Length - 4];
Array.Copy(data, 1, Data, 0, data.Length - 4);
if (data.Length > 2) Cmd = System.Text.Encoding.Default.GetString(Data, 0, 3);
this.DataString = System.Text.Encoding.Default.GetString(Data);
Valid = true;
return true;
}
public Dataframe(byte[] buffer = null, int minlen = 0)
{
if (buffer != null) Parse(buffer);
}
}
public override bool ProcessRecvData(byte[] data)
{
//LastReceiveBuffer
var frame = new Dataframe(data, MinRecvLength);
if (frame.Valid == false)
{
RaiseMessage(arRS232.MessageType.Error, frame.Message);
return false;
}
else if (frame.DataString.StartsWith("$") == false && CheckSum(data) == false)
{
RaiseMessage(arRS232.MessageType.Error, "Checksum Error MSG=" + frame.DataString);
return false;
}
var retval = true;
///////////////////////////////////////////////////////////////////////////////
if (frame.Cmd.Equals("ACK") || frame.Cmd.Equals("NAK"))
{ // 응답확인값 수신 : Header(ACX), Length(9), CheckSum 확인
RevACK(frame);
}
///////////////////////////////////////////////////////////////////////////////
else if (frame.Cmd.Equals("STS"))
{ // AGV 상태 정보 : Header(STS), Length(30), CheckSum 확인
RevSTS(frame);
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
else if ((frame.Cmd.Equals("TAG") || frame.Cmd.Equals("CAL") || frame.Cmd.Equals("CCA")))
{ // TAG ID 정보 : Header(STX), Length(13), CheckSum 확인
RevTAG(frame);
}
else if (frame.DataString.StartsWith("$"))
{
// $로 시작되는 AGV 상태 표시
//var text_Sts_Etc = Encoding.Default.GetString(bRcvData, 3, bRcvData.Length - 2).TrimStart(' '); //20210311 김정만 - SmartX FrameWork 사용 안함으로 주석처리
//var sMessageOther = Encoding.Default.GetString(bRcvData, 3, bRcvData.Length - 2).TrimStart(' ');
RaiseMessage(arRS232.MessageType.Normal, "$메세지수신:" + frame.DataString);
}
else
{
try
{
DataReceive?.Invoke(this, new DataEventArgs(DataType.UNKNOWN));
}
catch (Exception ex)
{
RaiseMessage(arRS232.MessageType.Error, ex.Message);
retval = false;
}
}
return retval;
}
#region [] ACK()
public string ACKData { get; set; } = string.Empty;
public DateTime ACKtime { get; set; } = DateTime.Now;
private void RevACK(Dataframe frame)
{
//ACKSADA7
var rcvdNow = frame.DataString;
var bRcvData = frame.Buffer;
ACKData = rcvdNow.Substring(3);
ACKtime = DateTime.Now;
if (rcvdNow.StartsWith("ACK"))
{
//RaiseMessage("get ack");
DataReceive?.Invoke(this, new DataEventArgs(DataType.ACK));
//if (datamanager.commandQueue.Count != 0)
//{
// byte[] bCmdData = encoding.GetBytes((String)datamanager.commandQueue.Peek());
// if (bCmdData[1] == bRcvData[4] && bCmdData[2] == bRcvData[5] && bCmdData[3] == bRcvData[6]) //보낸값이 맞는지 확인후 Dequeue
// {
// nSendCount = 0;
// datamanager.commandQueue.Dequeue();
// sSendCommandString = "";
// }
//}
}
else if (rcvdNow.StartsWith("NAK"))
{
//RaiseMessage("get nak");
DataReceive?.Invoke(this, new DataEventArgs(DataType.NAK));
//nSendCount = 0; //NAK - 재전송이 날아왔을때 nSendCommandCounter 초기화
}
}
#endregion
public SystemFlag0 system0 = new SystemFlag0();
public SystemFlag1 system1 = new SystemFlag1();
public ErrorFlag error = new ErrorFlag();
public AgvData data = new AgvData();
public Signal signal = new Signal();
#region [] STS(AGV상태정보)
public string LastSTS { get; set; } = string.Empty;
private void RevSTS(Dataframe frame)
{
LastSTS = frame.DataString;
string rcvdNow = frame.DataString;
byte[] bRcvData = frame.Buffer;
var encoding = System.Text.Encoding.Default;
try
{
// AGV 베터리 잔량 표시 flag (4~6) /////////////////////////////////////////////////////////////////////////////////////////////////////////////
var idx = 3;
var battery = int.Parse(rcvdNow.Substring(idx, 3)) / 10f;// Convert.ToDouble(encoding.GetString(rcvdNow, 3, 3)) / 10;
idx += 3;
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// AGV 장치연결상태 flag (7~10) ////////////////////////////////////////////////////////////////////////////////////////////////////////////
var nDataTemp = Convert.ToInt16(rcvdNow.Substring(idx, 4), 16);
system0.SetValue(nDataTemp);
idx += 4;
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// AGV Sts(현재 상태) flag (11~14) ////////////////////////////////////////////////////////////////////////////////////////////////////////////
nDataTemp = Convert.ToInt16(rcvdNow.Substring(idx, 4), 16);
system1.SetValue(nDataTemp);
idx += 4;
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// AGV Error flag (15~18)////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
nDataTemp = Convert.ToInt16(rcvdNow.Substring(idx, 4), 16);
error.SetValue(nDataTemp);
idx += 4;
data.Speed = rcvdNow.Substring(idx, 1)[0]; idx += 1; //L,M.H
data.Sts = rcvdNow.Substring(idx, 1)[0]; idx += 1; //S(직진),L(좌분기),R(우분기)
data.Direction = rcvdNow.Substring(idx, 1)[0]; idx += 1; //F,B,L,R
data.guidesensor = int.Parse(rcvdNow.Substring(idx, 1)); idx += 1; //가이드 좌측부터 1~9
nDataTemp = Convert.ToByte(rcvdNow.Substring(idx, 2), 16);
signal.SetValue(nDataTemp);
//data.Sts = encoding.GetString(bRcvData, 19, 3); //20210311 김정만 - SmartX FrameWork 사용 안함으로 주석처리
//var Sts_cSpeed = encoding.GetString(bRcvData, 19, 1)[0];
//var Sts_cDirection = encoding.GetString(bRcvData, 20, 1)[0];
//var Sts_cFB = encoding.GetString(bRcvData, 21, 1)[0];
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
////가이드센서 정보 (22)//////////////////////////////////////////////////////////////////////////////////////////////////////////
//var Sts_nGuide = 0;
//if (bRcvData[22] > 47 && bRcvData[22] < 58) { Sts_nGuide = Convert.ToInt32(encoding.GetString(bRcvData, 22, 1)); }
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
////마크센서 & 포토센서 정보 (23~24)////////////////////////////////////////////////////////////////////////////////////////////////////
//nDataTemp = Convert.ToInt32(encoding.GetString(bRcvData, 23, 2), 16);
//data.Sts_bMark1 = Convert.ToBoolean(nDataTemp & 0x4);
//data.Sts_bMark2 = Convert.ToBoolean(nDataTemp & 0x8);
//data.Sts_bCargo = Convert.ToBoolean(nDataTemp & 0x10);
////포토센서
//if (Sts_cFB == 'F')
//{
// system.Sts_nSenser = Convert.ToInt32(encoding.GetString(bRcvData, 26, 1));
//}
//else if (Sts_cFB == 'B')
//{
// system.Sts_nSenser = Convert.ToInt32(encoding.GetString(bRcvData, 27, 1));
//}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//AGV 속도/분기/방향 (19~21)//////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
DataReceive?.Invoke(this, new DataEventArgs(DataType.STS));
}
catch (Exception ex)
{
RaiseMessage(MessageType.Error, $"Parse Error(STS) = {ex.Message}");
}
}
#endregion
#region [] TAG()
System.Text.Encoding encoding = System.Text.Encoding.Default;
string old_TagString = string.Empty;
string old_CALString = string.Empty;
string old_CCAString = string.Empty;
private void RevTAG(Dataframe frame)
{
string rcvdNow = frame.DataString;
byte[] bRcvData = frame.Buffer;
if (rcvdNow.StartsWith("TAG"))
{
//221123 chi 숫자로변경
var tagnostr = rcvdNow.Substring(3);
if (int.TryParse(tagnostr, out int tagnoint))
{
var Changed = !old_TagString.Equals(tagnostr);
data.TagString = tagnostr;
data.TagNo = tagnoint;
old_TagString = tagnostr;
DataReceive?.Invoke(this, new DataEventArgs(DataType.TAG));
}
WriteData(MakeCheckSum("ACKTAG"));
}
else if (rcvdNow.StartsWith("CAL"))
{
var tagnostr = encoding.GetString(bRcvData, 4, 4);
if (int.TryParse(tagnostr, out int tagnoint))
{
var Changed = !old_CALString.Equals(tagnostr);
data.CallString = tagnostr;
data.CallNo = tagnoint;
old_CALString = tagnostr;
if (Changed) DataReceive?.Invoke(this, new DataEventArgs(DataType.CALL));
}
WriteData(MakeCheckSum("ACKCAL"));
}
else if (rcvdNow.StartsWith("CCA")) //능동형 Call에 의하여 들어 오는 구문
{
var tagnostr = encoding.GetString(bRcvData, 4, 4);
if (int.TryParse(tagnostr, out int tagnoint))
{
var Changed = !old_CCAString.Equals(tagnostr);
data.CCAString = tagnostr;
data.CCANo = tagnoint;
old_CCAString = tagnostr;
if (Changed) DataReceive?.Invoke(this, new DataEventArgs(DataType.CCA));
}
WriteData(MakeCheckSum("ACKCCA"));
}
}
#endregion
private string MakeCheckSum(string sCommand)
{
//sCommand = sCommand.ToUpper();
List<byte> buffer = new List<byte>();
buffer.Add(0x02);
//byte[] bCommand = System.Text.ASCIIEncoding.ASCII.GetBytes(sCommand);
buffer.AddRange(System.Text.ASCIIEncoding.ASCII.GetBytes(sCommand));
//make sum
int nSum = 0;
for (int nCnt = 1; nCnt < buffer.Count; nCnt++)
nSum += buffer[nCnt];
string sSum = nSum.ToString("X2").ToUpper();// Convert.ToString(nSum, 16).ToUpper();
if (sSum.Length < 2) sSum = "0" + sSum;
sSum = sSum.Substring(sSum.Length - 2);
//if (sSum.Length == 3)
// sSum = sSum.Remove(0, 1);
//else if (sSum.Length == 4)
// sSum = sSum.Remove(0, 2);
buffer.AddRange(System.Text.ASCIIEncoding.Default.GetBytes(sSum));
buffer.Add(0x03);
// byte[] bStxEtx = { 0x02, 0x03 };
//var orgstr = (System.Text.ASCIIEncoding.ASCII.GetString(bStxEtx, 0, 1) + sCommand + sSum + System.Text.ASCIIEncoding.ASCII.GetString(bStxEtx, 1, 1));
var newstr = System.Text.Encoding.Default.GetString(buffer.ToArray());
return newstr;
}
///// <summary>
///// commandQueue에 명령을 추가합니다(체크섬은 자동 추가됨)
///// </summary>
///// <param name="cmd">체크섬을 제외한 평문</param>
///// <param name="addlog">sendlog 에 추가할 경우 true를 입력하세요</param>
//public void AddCommand(string cmd, bool addlog = true, int Repeat = 1)
//{
// var fullcmd = MakeCheckSum(cmd);
// for (int i = 0; i < Repeat; i++)
// commandQueue.Enqueue(fullcmd);
// if (addlog)
// {
// Message?.Invoke(this, new MessageEventArgs()
// }
//}
public enum eStopOpt
{
Stop = 0,
MarkStop,
MarkRotateLeft,
MarkRotateRight,
MarkChangeDirection,
}
public enum eRunOpt
{
NotSet,
Forward,
Backward,
}
public enum ManulOpt
{
FS,
BS,
RT,
LT,
FL,
FR,
BL,
BR,
}
public enum Sensor
{
PBSOff = 0,
PBSOn,
AllOn,
}
public enum Speed
{
High,
Mid,
Low,
}
public enum LiftCommand
{
/// <summary>
/// lift up
/// </summary>
UP,
/// <summary>
/// lift down
/// </summary>
DN,
/// <summary>
/// lift 동작 정지
/// </summary>
STP,
/// <summary>
/// magnet holder on
/// </summary>
ON,
/// <summary>
/// magnet holder off
/// </summary>
OFF
}
private bool CheckSum(byte[] bData)
{
if (bData.Length < 2) // 데이터 길이가 2이하일 경우 비정상 처리
return false;
int nSum = 0;
// byte[] bData = encoding.GetBytes(sData);
for (int nCnt = 1; nCnt < bData.Length - 3; nCnt++)
{
nSum += bData[nCnt];
}
string sSum = Convert.ToString(nSum, 16).ToUpper();
string sCSTemp = string.Empty;
if (sSum.Length == 3)
sCSTemp = sSum.Remove(0, 1);
else if (sSum.Length == 4)
sCSTemp = sSum.Remove(0, 2);
if (bData[bData.Length - 2] == '*' && bData[bData.Length - 3] == '*')
return true;
if (sCSTemp[0] == (char)(bData[bData.Length - 3]) && sCSTemp[1] == (char)(bData[bData.Length - 2]))
return true;
else
return false;
}
}
}

View File

@@ -0,0 +1,36 @@
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
// 어셈블리에 대한 일반 정보는 다음 특성 집합을 통해
// 제어됩니다. 어셈블리와 관련된 정보를 수정하려면
// 이러한 특성 값을 변경하세요.
[assembly: AssemblyTitle("BMS Commnunication Module")]
[assembly: AssemblyDescription("BMS Commnunication Module")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("ATK4")]
[assembly: AssemblyProduct("BMS Commnunication Module")]
[assembly: AssemblyCopyright("Copyright ©ATK4 2020")]
[assembly: AssemblyTrademark("ATK4")]
[assembly: AssemblyCulture("")]
// ComVisible을 false로 설정하면 이 어셈블리의 형식이 COM 구성 요소에
// 표시되지 않습니다. COM에서 이 어셈블리의 형식에 액세스하려면
// 해당 형식에 대해 ComVisible 특성을 true로 설정하세요.
[assembly: ComVisible(false)]
// 이 프로젝트가 COM에 노출되는 경우 다음 GUID는 typelib의 ID를 나타냅니다.
[assembly: Guid("7a94c30c-6772-4f71-bf9c-111071a1bc70")]
// 어셈블리의 버전 정보는 다음 네 가지 값으로 구성됩니다.
//
// 주 버전
// 부 버전
// 빌드 번호
// 수정 버전
//
// 모든 값을 지정하거나 아래와 같이 '*'를 사용하여 빌드 번호 및 수정 번호를
// 기본값으로 할 수 있습니다.
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("20.03.09.0000")]
[assembly: AssemblyFileVersion("20.03.09.0000")]

View File

@@ -0,0 +1,50 @@
using System;
namespace arDev
{
public partial class Narumi
{
public class AgvData
{
public char Sts { get; set; }
public char Speed { get; set; }
public char Direction { get; set; }
public int guidesensor { get; set; }
public string TagString { get; set; } = string.Empty;
public int TagNo { get; set; } = -1;
public string CallString { get; set; } = string.Empty;
public int CallNo { get; set; } = -1;
public string CCAString { get; set; } = string.Empty;
public int CCANo { get; set; } = -1;
public override string ToString()
{
//모든사태값을 탭으로 구분하여 문자를 생성한다
var sb = new System.Text.StringBuilder();
sb.AppendLine($"[Sts] : {Sts}");
sb.AppendLine($"[Speed] : {Speed}");
sb.AppendLine($"[Direction] : {Direction}");
sb.AppendLine($"[guidesensor] : {guidesensor}");
sb.AppendLine($"[TagNo] : {TagNo}");
sb.AppendLine($"[CallNo] : {CallNo}");
sb.AppendLine($"[CCANo] : {CCANo}");
return sb.ToString();
}
}
}
}

View File

@@ -0,0 +1,99 @@
using System;
namespace arDev
{
public partial class Narumi
{
public class ErrorFlag
{
private COMM.Flag _value { get; set; } = new COMM.Flag(16);
public void SetValue(Int16 value) { this._value.writeValue(value); }
public UInt16 Value
{
get
{
return (UInt16)_value.Value;
}
}
public enum eflag
{
Emergency = 0,
Overcurrent,
Charger_run_error,
Charger_pos_error,
line_out_error = 4,
/// <summary>
/// 기동시 자석 감지 에러
/// </summary>
runerror_by_no_magent_line,
/// <summary>
/// 호출제어기 통신 오류
/// </summary>
controller_comm_error = 11,
/// <summary>
/// 도착경보기 통신 오류
/// </summary>
arrive_ctl_comm_error,
/// <summary>
/// 자동문제어기 통신 오류
/// </summary>
door_ctl_comm_error,
/// <summary>
/// 자동충전기 통신 오류
/// </summary>
charger_comm_error,
/// <summary>
/// 교차로 제어기 통신 오류
/// </summary>
cross_ctrl_comm_error,
}
public bool GetValue(eflag idx)
{
return _value.Get((int)idx);
}
public bool GetChanged(eflag idx)
{
return _value.GetChanged((int)idx);
}
public bool Emergency { get { return GetValue(eflag.Emergency); } }
public bool Overcurrent { get { return GetValue(eflag.Overcurrent); } }
public bool Charger_run_error { get { return GetValue(eflag.Charger_run_error); } }
public bool Charger_pos_error { get { return GetValue(eflag.Charger_pos_error); } }
public bool line_out_error { get { return GetValue(eflag.line_out_error); } }
public bool runerror_by_no_magent_line { get { return GetValue(eflag.runerror_by_no_magent_line); } }
public bool controller_comm_error { get { return GetValue(eflag.controller_comm_error); } }
public bool arrive_ctl_comm_error { get { return GetValue(eflag.arrive_ctl_comm_error); } }
public bool door_ctl_comm_error { get { return GetValue(eflag.door_ctl_comm_error); } }
public bool charger_comm_error { get { return GetValue(eflag.charger_comm_error); } }
public bool cross_ctrl_comm_error { get { return GetValue(eflag.cross_ctrl_comm_error); } }
public override string ToString()
{
//모든사태값을 탭으로 구분하여 문자를 생성한다
var sb = new System.Text.StringBuilder();
for (int i = 0; i < 16; i++)
{
var def = Enum.IsDefined(typeof(eflag), i);
if (def)
{
var flag = (eflag)i;
var value = _value.Get(i);
sb.AppendLine($"[{i:00}][{flag}] : {value}");
}
}
return sb.ToString();
}
}
}
}

View File

@@ -0,0 +1,72 @@
using System;
namespace arDev
{
public partial class Narumi
{
public class Signal
{
private COMM.Flag _value { get; set; } = new COMM.Flag(16);
public void SetValue(Int16 value) { this._value.writeValue(value); }
public UInt16 Value
{
get
{
return (UInt16)_value.Value;
}
}
public enum eflag
{
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 bool GetValue(eflag idx)
{
return _value.Get((int)idx);
}
public bool GetChanged(eflag idx)
{
return _value.GetChanged((int)idx);
}
public Boolean front_gate_out { get { return GetValue(eflag.front_gate_out); } }
public Boolean rear_sensor_out { get { return GetValue(eflag.rear_sensor_out); } }
public Boolean mark_sensor_1 { get { return GetValue(eflag.mark_sensor_1); } }
public Boolean mark_sensor_2 { get { return GetValue(eflag.mark_sensor_2); } }
public Boolean mark_sensor { get { return mark_sensor_1 || mark_sensor_2; } }
public Boolean front_left_sensor { get { return GetValue(eflag.front_left_sensor); } }
public Boolean front_right_sensor { get { return GetValue(eflag.front_right_sensor); } }
public Boolean front_center_sensor { get { return GetValue(eflag.front_center_sensor); } }
public Boolean charger_align_sensor { get { return GetValue(eflag.charger_align_sensor); } }
public override string ToString()
{
//모든사태값을 탭으로 구분하여 문자를 생성한다
var sb = new System.Text.StringBuilder();
for (int i = 0; i < 16; i++)
{
var def = Enum.IsDefined(typeof(eflag), i);
if(def)
{
var flag = (eflag)i;
var value = _value.Get(i);
sb.AppendLine($"[{i:00}][{flag}] : {value}");
}
}
return sb.ToString();
}
}
}
}

View File

@@ -0,0 +1,77 @@
using System;
namespace arDev
{
public partial class Narumi
{
public class SystemFlag0
{
private COMM.Flag _value { get; set; } = new COMM.Flag(16);
public void SetValue(Int16 value) { this._value.writeValue(value); }
public UInt16 Value
{
get
{
return (UInt16)_value.Value;
}
}
public enum eflag
{
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 bool GetValue(eflag idx)
{
return _value.Get((int)idx);
}
public bool GetChanged(eflag idx)
{
return _value.GetChanged((int)idx);
}
public bool Memory_RW_State { get { return GetValue(eflag.Memory_RW_State); } }
public bool EXT_IO_Conn_State { get { return GetValue(eflag.EXT_IO_Conn_State); } }
public bool RFID_Conn_State { get { return GetValue(eflag.RFID_Conn_State); } }
public bool M5E_Module_Run_State { get { return GetValue(eflag.M5E_Module_Run_State); } }
public bool Front_Ultrasonic_Conn_State { get { return GetValue(eflag.Front_Ultrasonic_Conn_State); } }
public bool Front_Untrasonic_Sensor_State { get { return GetValue(eflag.Front_Untrasonic_Sensor_State); } }
public bool Side_Ultrasonic_Conn_State { get { return GetValue(eflag.Side_Ultrasonic_Conn_State); } }
public bool Side_Ultrasonic_Sensor_State { get { return GetValue(eflag.Side_Ultrasonic_Sensor_State); } }
public bool Front_Guide_Sensor_State { get { return GetValue(eflag.Front_Guide_Sensor_State); } }
public bool Rear_Guide_Sensor_State { get { return GetValue(eflag.Rear_Guide_Sensor_State); } }
public bool Battery_Level_Check { get { return GetValue(eflag.Battery_Level_Check); } }
public override string ToString()
{
//모든사태값을 탭으로 구분하여 문자를 생성한다
var sb = new System.Text.StringBuilder();
for(int i = 0; i < 16; i++)
{
var def = Enum.IsDefined(typeof(eflag), i);
if (def)
{
var flag = (eflag)i;
var value = _value.Get(i);
sb.AppendLine($"[{i:00}][{flag}] : {value}");
}
}
return sb.ToString();
}
}
}
}

View File

@@ -0,0 +1,97 @@
using System;
namespace arDev
{
public partial class Narumi
{
public class SystemFlag1
{
private COMM.Flag _value { get; set; } = new COMM.Flag(16);
public void SetValue(Int16 value) { this._value.writeValue(value); }
public UInt16 Value
{
get
{
return (UInt16)_value.Value;
}
}
public enum eflag
{
Side_Detect_Ignore = 3,
Melody_check,
Mark2_check,
Mark1_check,
gateout_check,
Battery_charging = 8,
re_Start,
/// <summary>
/// 전방 감지 무시
/// </summary>
front_detect_ignore,
/// <summary>
/// 전방장애물감지상태
/// </summary>
front_detect_check,
/// <summary>
/// 전방감지 후 정지 상태
/// </summary>
stop_by_front_detect = 12,
/// <summary>
/// 교차로 진입 후 정지 상태
/// </summary>
stop_by_cross_in,
agv_stop,
agv_run
}
public bool GetValue(eflag idx)
{
return _value.Get((int)idx);
}
public bool GetChanged(eflag idx)
{
return _value.GetChanged((int)idx);
}
public bool Side_Detect_Ignore { get { return GetValue(eflag.Side_Detect_Ignore); } }
public bool Melody_check { get { return GetValue(eflag.Melody_check); } }
public bool Mark2_check { get { return GetValue(eflag.Mark2_check); } }
public bool Mark1_check { get { return GetValue(eflag.Mark1_check); } }
public bool gateout_check { get { return GetValue(eflag.gateout_check); } }
public bool Battery_charging { get { return GetValue(eflag.Battery_charging); } }
public bool re_Start { get { return GetValue(eflag.re_Start); } }
public bool front_detect_ignore { get { return GetValue(eflag.front_detect_ignore); } }
public bool front_detect_check { get { return GetValue(eflag.front_detect_check); } }
public bool stop_by_front_detect { get { return GetValue(eflag.stop_by_front_detect); } }
public bool stop_by_cross_in { get { return GetValue(eflag.stop_by_cross_in); } }
public bool agv_stop { get { return GetValue(eflag.agv_stop); } }
public bool agv_run { get { return GetValue(eflag.agv_run); } }
public bool agv_run_manual { get; set; }
public override string ToString()
{
//모든사태값을 탭으로 구분하여 문자를 생성한다
var sb = new System.Text.StringBuilder();
for (int i = 0; i < 16; i++)
{
var def = Enum.IsDefined(typeof(eflag), i);
if (def)
{
var flag = (eflag)i;
var value = _value.Get(i);
sb.AppendLine($"[{i:00}][{flag}] : {value}");
}
}
return sb.ToString();
}
}
}
}