Vehicle.cs 76 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211
  1. using System;
  2. using System.Collections;
  3. using System.Collections.Generic;
  4. using System.Linq;
  5. using System.Security.Cryptography.X509Certificates;
  6. using System.Threading;
  7. using System.Threading.Tasks;
  8. using FluentResults;
  9. using GSG.NET.Concurrent;
  10. using GSG.NET.Extensions;
  11. using GSG.NET.LINQ;
  12. using GSG.NET.Logging;
  13. using GSG.NET.Quartz;
  14. using GSG.NET.Utils;
  15. using OHV.Common.Events;
  16. using OHV.Common.Model;
  17. using OHV.Common.Shareds;
  18. using OHV.SqliteDAL;
  19. using Prism.Events;
  20. using VehicleControlSystem.ControlLayer.Actuator.Cylinder;
  21. using VehicleControlSystem.ControlLayer.Drive;
  22. using VehicleControlSystem.ControlLayer.IO;
  23. using VehicleControlSystem.ControlLayer.MQ;
  24. using VehicleControlSystem.ControlLayer.Serial.BatteryTabos;
  25. using VehicleControlSystem.ControlLayer.Serial.DataModel;
  26. using VehicleControlSystem.Managers;
  27. using static VehicleControlSystem.ControlLayer.Drive.GSIDrive;
  28. namespace VehicleControlSystem.ControlLayer
  29. {
  30. public class VehicleRefObjects
  31. {
  32. public GSIDrive Drive { get; set; }
  33. public Clamp Clamp { get; set; }
  34. public Conveyor Conveyor { get; set; }
  35. public EzIO IO { get; set; }
  36. public Steering Steering { get; set; }
  37. public BMUManager BMUManager { get; set; }
  38. public ZmqManager ZmqManager { get; set; }
  39. }
  40. /// <summary>
  41. /// Control Layer 의 자원을 여기서 사용하자.
  42. /// </summary>
  43. public class Vehicle : ControlObjectBase, IDisposable
  44. {
  45. /// <summary>
  46. /// OCS Report Code
  47. /// 목적지에 도착해서 Load, Unload 시 발생하는 Alarm
  48. /// </summary>
  49. public enum eFailCode
  50. {
  51. Load_PortHasNotCarrier = 1,
  52. Load_VehicleHasCarrier,
  53. Unload_PortHasCarrier,
  54. Unload_VehicleHasNotCarrier,
  55. LoadPIOInterlockTimeout,
  56. UnlaodPIOInterlockTimeout,
  57. }
  58. static Logger logger = Logger.GetLogger();
  59. static Logger loggerPIO = Logger.GetLogger( "PIO" );
  60. #region Properties
  61. /// <summary>
  62. /// Tag 위치
  63. /// </summary>
  64. private int currentTag = 0;
  65. public int CurrentTag
  66. {
  67. get { return currentTag; }
  68. set
  69. {
  70. if ( SetField( ref this.currentTag, value ) )
  71. {
  72. var info = sql.VehicleInfoDAL.GetAll().FirstOrDefault();
  73. info.CurrentTag = value.ToString();
  74. sql.VehicleInfoDAL.Update( info );
  75. this.OnCurrentTagChanged?.Invoke( value );
  76. }
  77. }
  78. }
  79. /// <summary>
  80. /// Scale Value
  81. /// </summary>
  82. private double currentPosition;
  83. public double CurrentPosition
  84. {
  85. get { return currentPosition; }
  86. set
  87. {
  88. if ( SetField( ref this.currentPosition, value ) )
  89. {
  90. }
  91. }
  92. }
  93. private double currentSpeed;
  94. public double CurrentSpeed
  95. {
  96. get { return currentSpeed; }
  97. set { SetField( ref this.currentSpeed, value ); }
  98. }
  99. private double currentTorque;
  100. public double CurrentTorque
  101. {
  102. get { return currentTorque; }
  103. set { SetField( ref this.currentTorque, value ); }
  104. }
  105. private bool isContain;
  106. public bool IsContain
  107. {
  108. get { return isContain; }
  109. set { SetField( ref this.isContain, value ); }
  110. }
  111. eClampState _clampState;
  112. public eClampState ClampState
  113. {
  114. get { return this._clampState; }
  115. set { this.SetField( ref this._clampState, value ); }
  116. }
  117. private eSteeringState steeringState;
  118. public eSteeringState SteeringState
  119. {
  120. get { return steeringState; }
  121. set
  122. {
  123. if ( SetField( ref this.steeringState, value ) )
  124. {
  125. this.refObjects.ZmqManager.SetCurrentSteeringState( value );
  126. }
  127. }
  128. }
  129. private int _obstacleDrive;
  130. public int ObstacleDrive { get { return this._obstacleDrive; } set { SetField( ref this._obstacleDrive, value ); } }
  131. private int _obstacleCurve;
  132. public int ObstacleCurve { get { return this._obstacleCurve; } set { SetField( ref this._obstacleCurve, value ); } }
  133. private int obstacleCurrent;
  134. public int ObstacleCurrent { get { return this.ObstacleCurrent; } set { SetField( ref this.obstacleCurrent, value ); } }
  135. private eObstacleState obstacleState = eObstacleState.Normal;
  136. public eObstacleState ObstacleStateProperty
  137. {
  138. get { return obstacleState; }
  139. set
  140. {
  141. if ( SetField( ref this.obstacleState, value ) )
  142. {
  143. if ( value == eObstacleState.Blocked )
  144. this.VehicleStateProperty = eVehicleState.Blocked;
  145. }
  146. }
  147. }
  148. private eVehicleState vehicleState = eVehicleState.None;
  149. public eVehicleState VehicleStateProperty
  150. {
  151. get { return vehicleState; }
  152. set
  153. {
  154. if ( SetField( ref this.vehicleState, value ) )
  155. {
  156. var info = sql.VehicleInfoDAL.GetAll().FirstOrDefault();
  157. info.VehicleState = value;
  158. sql.VehicleInfoDAL.Update( info );
  159. }
  160. }
  161. }
  162. private eMachineMode machineMode = eMachineMode.LocalMode;
  163. public eMachineMode MachineMode
  164. {
  165. get { return machineMode; }
  166. set
  167. {
  168. if ( SetField( ref this.machineMode, value ) )
  169. {
  170. var info = sql.VehicleInfoDAL.GetAll().FirstOrDefault();
  171. info.MachineMode = value;
  172. sql.VehicleInfoDAL.Update( info );
  173. }
  174. }
  175. }
  176. private int obstaclePattern;
  177. public int ObstaclePattern
  178. {
  179. get { return obstaclePattern; }
  180. set { SetField( ref this.obstaclePattern, value ); }
  181. }
  182. private DriveState frontDriveState;
  183. public DriveState FrontDriveState
  184. {
  185. get { return frontDriveState; }
  186. set { SetField( ref this.frontDriveState, value ); }
  187. }
  188. private DriveState rearDriveState;
  189. public DriveState RearDriveState
  190. {
  191. get { return rearDriveState; }
  192. set { SetField( ref this.rearDriveState, value ); }
  193. }
  194. //이동
  195. public bool Busy
  196. {
  197. get
  198. {
  199. return this.CurrentSubCommand == null ? false : true;
  200. }
  201. set { }
  202. }
  203. public bool IsMoving { get => this.refObjects.Drive.IsDriveMoving(); }
  204. #region Battery Property
  205. double batteryVoltage;
  206. public double BatteryVoltage
  207. {
  208. get { return this.batteryVoltage; }
  209. set
  210. {
  211. //var d = Math.Truncate( value * 10 ) / 10;
  212. //this.SetField( ref this.batteryVoltage, d );
  213. this.SetField( ref this.batteryVoltage, value );
  214. }
  215. }
  216. double batteryCurrent;
  217. public double BatteryCurrent
  218. {
  219. get { return this.batteryCurrent; }
  220. set { this.SetField( ref this.batteryCurrent, value ); }
  221. }
  222. double batteryState;
  223. public double BatteryState
  224. {
  225. get { return this.batteryState; }
  226. set { this.SetField( ref this.batteryState, value ); }
  227. }
  228. double batteryChargeTime;
  229. public double BatteryChargeTime
  230. {
  231. get { return this.batteryChargeTime; }
  232. set { this.SetField( ref this.batteryChargeTime, value ); }
  233. }
  234. double batteryDisChargeTime;
  235. public double BatteryDisChargeTime
  236. {
  237. get { return this.batteryDisChargeTime; }
  238. set { this.SetField( ref this.batteryDisChargeTime, value ); }
  239. }
  240. double batteryStateOfCharge;
  241. public double BatteryStateOfCharge
  242. {
  243. get { return this.batteryStateOfCharge; }
  244. set { this.SetField( ref this.batteryStateOfCharge, value ); }
  245. }
  246. double batteryStateOfHealth;
  247. public double BatteryStateOfHealth
  248. {
  249. get { return this.batteryStateOfHealth; }
  250. set { this.SetField( ref this.batteryStateOfHealth, value ); }
  251. }
  252. double batteryCapacity;
  253. public double BatteryCapacity
  254. {
  255. get { return this.batteryCapacity; }
  256. set { this.SetField( ref this.batteryCapacity, value ); }
  257. }
  258. double batteryEnergy;
  259. public double BatteryEnergy
  260. {
  261. get { return this.batteryEnergy; }
  262. set
  263. {
  264. var d = Math.Truncate( value * 10 ) / 10;
  265. this.SetField( ref this.batteryEnergy, d );
  266. }
  267. }
  268. double batteryTemperature;
  269. public double BatteryTemperature
  270. {
  271. get { return this.batteryTemperature; }
  272. set { this.SetField( ref this.batteryTemperature, value ); }
  273. }
  274. bool batteryIsConnect;
  275. public bool BatteryIsConnect
  276. {
  277. get
  278. {
  279. return batteryIsConnect;
  280. }
  281. set { this.SetField( ref this.batteryIsConnect, value ); }
  282. }
  283. #endregion
  284. public bool IsError { get; set; }
  285. public SubCmd CurrentSubCommand { get; private set; }
  286. double frontLoadFactor = 0;
  287. public double FrontLoadFactor
  288. {
  289. get { return this.frontLoadFactor; }
  290. set { SetField( ref this.frontLoadFactor, value ); }
  291. }
  292. double frontRpm = 0;
  293. public double FrontRpm
  294. {
  295. get { return this.frontRpm; }
  296. set { SetField( ref this.frontRpm, value ); }
  297. }
  298. double frontSpeed = 0;
  299. public double FrontSpeed
  300. {
  301. get { return this.frontSpeed; }
  302. set { SetField( ref this.frontSpeed, value ); }
  303. }
  304. double frontTorque = 0;
  305. public double FrontTorque
  306. {
  307. get { return this.frontTorque; }
  308. set { SetField( ref this.frontTorque, value ); }
  309. }
  310. double rearLoadFactor = 0;
  311. public double RearLoadFactor
  312. {
  313. get { return this.rearLoadFactor; }
  314. set { SetField( ref this.rearLoadFactor, value ); }
  315. }
  316. double rearRpm = 0;
  317. public double RearRpm
  318. {
  319. get { return this.rearRpm; }
  320. set { SetField( ref this.rearRpm, value ); }
  321. }
  322. double rearSpeed = 0;
  323. public double RearSpeed
  324. {
  325. get { return this.rearSpeed; }
  326. set { SetField( ref this.rearSpeed, value ); }
  327. }
  328. double rearTorque = 0;
  329. public double RearTorque
  330. {
  331. get { return this.rearTorque; }
  332. set { SetField( ref this.rearTorque, value ); }
  333. }
  334. #endregion
  335. #region Event
  336. public event Action OnMoveReady;
  337. public event Action OnMoving;
  338. public event Action OnMoveFinish;
  339. public event Action OnChargingStart;
  340. public event Action OnCharging;
  341. public event Action OnChargingFull;
  342. public event Action<double> OnBatteryVelueChanged;
  343. public event Action<bool> OnPIOStart;
  344. public event Action<bool> OnConveyorStart;
  345. public event Action<bool> OnConveyorStop;
  346. public event Action<bool> OnCarrierDetected;
  347. public event Action OnLoadComplete;
  348. public event Action OnUnloadComplete;
  349. public event Action<int> OnCurrentTagChanged;
  350. public event Action OnManualMove;
  351. public event Action OnManualLoad;
  352. public event Action OnManualUnload;
  353. public event Action OnManualCharging;
  354. public event Action<eFailCode> OnFailReport;
  355. #endregion
  356. #region List.
  357. List<ICylinder> cylinders = new List<ICylinder>();
  358. List<string> obstacleBitList = new List<string>();
  359. #endregion
  360. VehicleRefObjects refObjects = null;
  361. SqliteManager sql = null;
  362. AutoManager autoManager = null;
  363. ThreadCancel cancel = new ThreadCancel();
  364. TaskCancel taskCancel = new TaskCancel();
  365. TaskCancel taskMoveCancel = new TaskCancel();
  366. IEventAggregator eventAggregator;
  367. public Vehicle( VehicleRefObjects vehicleRef, IIO io, SqliteManager sqliteManager, IEventAggregator ea, AutoManager auto )
  368. {
  369. this.refObjects = vehicleRef;
  370. this.refObjects.IO.OnChangedIO += IO_OnChangedIO;
  371. this.refObjects.BMUManager.OnConnect += BMUManager_OnConnect;
  372. this.refObjects.BMUManager.OnDisconnect += BMUManager_OnDisconnect;
  373. this.refObjects.BMUManager.OnChangedReceivedData += BMUManager_OnChangedReceivedData;
  374. this.refObjects.BMUManager.OnFirstColtd += BMUManager_OnFirstColtd;
  375. this.refObjects.Drive.PropertyChanged += Motion_PropertyChanged;
  376. this.refObjects.Clamp.PropertyChanged += Clamp_PropertyChanged;
  377. this.refObjects.Steering.OnSteeringError += Steering_OnSteeringError;
  378. this.refObjects.Steering.PropertyChanged += Steering_PropertyChanged;
  379. this.refObjects.ZmqManager.PropertyChanged += ZmqManager_PropertyChanged;
  380. this.sql = sqliteManager;
  381. this.autoManager = auto;
  382. this.autoManager.OnOperationModeChanged += AutoManager_OnOperationModeChanged;
  383. this.obstacleBitList.AddRange( new string[]
  384. {
  385. "OUT_OBSTRUCTION_PATTERN_00",
  386. "OUT_OBSTRUCTION_PATTERN_01",
  387. "OUT_OBSTRUCTION_PATTERN_02",
  388. "OUT_OBSTRUCTION_PATTERN_03",
  389. "OUT_OBSTRUCTION_PATTERN_04",
  390. } );
  391. this.eventAggregator = ea;
  392. this.eventAggregator.GetEvent<DriveControlPubSubEvent>().Unsubscribe( ReceiveDriveControlEvent );
  393. this.eventAggregator.GetEvent<DriveControlPubSubEvent>().Subscribe( ReceiveDriveControlEvent );
  394. this.eventAggregator.GetEvent<ObstacleControlPubSubEvent>().Unsubscribe( ObstacleReceiveEvent );
  395. this.eventAggregator.GetEvent<ObstacleControlPubSubEvent>().Subscribe( ObstacleReceiveEvent );
  396. }
  397. private void ObstacleReceiveEvent( ObstacleControlEventArgs obj )
  398. {
  399. if ( this.autoManager.OperationModeProperty != eOperatationMode.ManualMode )
  400. return;
  401. if ( obj.EventDir == ObstacleControlEventArgs.eEventDir.ToBack )
  402. {
  403. switch ( obj.ControlKind )
  404. {
  405. case ObstacleControlEventArgs.eControlKind.NONE:
  406. break;
  407. case ObstacleControlEventArgs.eControlKind.DRIVE:
  408. //this.ChgObstacleDetectPattern( new Random().Next( 0 , 40 ) );
  409. break;
  410. case ObstacleControlEventArgs.eControlKind.CURVE:
  411. //this.ChgObstacleDetectPattern( new Random().Next( 0 , 40 ) );
  412. break;
  413. case ObstacleControlEventArgs.eControlKind.STATE:
  414. //var value = this.GetObstacleDetectPattern();
  415. break;
  416. case ObstacleControlEventArgs.eControlKind.INFO:
  417. {
  418. var msg = new ObstacleControlEventArgs
  419. {
  420. ControlKind = ObstacleControlEventArgs.eControlKind.INFO,
  421. Drive = this.ObstacleDrive,
  422. Curve = this.ObstacleCurve,
  423. Current = this.GetObstacleDetectPattern(),
  424. ObstacleState = this.ObstacleStateProperty.ToString()
  425. };
  426. this.ObstacleControlEventPublish( msg );
  427. }
  428. break;
  429. case ObstacleControlEventArgs.eControlKind.SAVE:
  430. {
  431. this.ObstacleCurve = obj.Curve;
  432. this.ObstacleDrive = obj.Drive;
  433. var reply = new ObstacleControlEventArgs
  434. {
  435. ControlKind = ObstacleControlEventArgs.eControlKind.SAVE
  436. };
  437. reply.Result = Results.Ok( ObstacleControlEventArgs.eControlKind.SAVE );
  438. this.ObstacleControlEventPublish( reply );
  439. }
  440. break;
  441. }
  442. }
  443. }
  444. private void ObstacleControlEventPublish( ObstacleControlEventArgs args )
  445. {
  446. args.EventDir = ObstacleControlEventArgs.eEventDir.ToFront;
  447. this.eventAggregator.GetEvent<ObstacleControlPubSubEvent>().Publish( args );
  448. }
  449. private void ReceiveDriveControlEvent( DriveControlEventArgs _args )
  450. {
  451. var msg = _args;
  452. if ( msg.EventDir == DriveControlEventArgs.eEventDir.ToBack )
  453. {
  454. switch ( msg.ControlKind )
  455. {
  456. case DriveControlEventArgs.eControlKind.MOVE:
  457. this.ReqMoveToPos( _args );
  458. break;
  459. case DriveControlEventArgs.eControlKind.STOP:
  460. break;
  461. case DriveControlEventArgs.eControlKind.Steering:
  462. if ( msg.MoveDir == DriveControlEventArgs.eMoveDir.LEFT )
  463. this.refObjects.Steering.ControlSteering( true );
  464. else
  465. this.refObjects.Steering.ControlSteering();
  466. break;
  467. case DriveControlEventArgs.eControlKind.SteeringState:
  468. {
  469. var reply = new DriveControlEventArgs();
  470. reply.ControlKind = DriveControlEventArgs.eControlKind.SteeringState;
  471. if ( this.refObjects.Steering.IsLeft() )
  472. {
  473. reply.Args = eSteeringState.Left;
  474. reply.Result = FluentResults.Results.Ok();
  475. }
  476. else if ( this.refObjects.Steering.IsRight() )
  477. {
  478. reply.Args = eSteeringState.Right;
  479. reply.Result = FluentResults.Results.Ok();
  480. }
  481. else
  482. reply.Result = FluentResults.Results.Fail( new Error() );
  483. this.DriveControlEventPublish( reply );
  484. }
  485. break;
  486. case DriveControlEventArgs.eControlKind.ReqCurrentPos:
  487. //this.ReqCurrentPos();
  488. break;
  489. case DriveControlEventArgs.eControlKind.ReqStopCurrentPos:
  490. //this.taskCancel.Cancel();
  491. //this.taskCancel.WaitAll();
  492. break;
  493. case DriveControlEventArgs.eControlKind.FaultReset:
  494. this.ReqFaultReset( _args );
  495. break;
  496. case DriveControlEventArgs.eControlKind.DriveON:
  497. this.ReqDriveOn( _args );
  498. break;
  499. case DriveControlEventArgs.eControlKind.DriveOFF:
  500. this.ReqDriveOff( _args );
  501. break;
  502. case DriveControlEventArgs.eControlKind.JOG:
  503. this.ReqJog( _args );
  504. break;
  505. case DriveControlEventArgs.eControlKind.VehicleState:
  506. ReqVehicleState( _args );
  507. break;
  508. default:
  509. break;
  510. }
  511. }
  512. }
  513. public void ReqConveyorMove( string dir )
  514. {
  515. if ( dir.Equals( "CW" ) )
  516. this.refObjects.Conveyor.OnOffConveyor( true, false );
  517. else if ( dir.Equals( "CCW" ) )
  518. this.refObjects.Conveyor.OnOffConveyor( true, true );
  519. else if ( dir.Equals( "STOP" ) )
  520. this.refObjects.Conveyor.OnOffConveyor( false, false );
  521. }
  522. private void DriveControlEventPublish( DriveControlEventArgs args )
  523. {
  524. args.EventDir = DriveControlEventArgs.eEventDir.ToFront;
  525. this.eventAggregator.GetEvent<DriveControlPubSubEvent>().Publish( args );
  526. }
  527. public void Init()
  528. {
  529. ThreadStart();
  530. //TimerUtils.Once(5000, () => { this.CurrentPosition = 1000; });
  531. var v = sql.VehicleInfoDAL.GetAll().FirstOrDefault();
  532. v.CurrentTag = "0000";
  533. v.VehicleState = eVehicleState.None;
  534. v.MachineMode = eMachineMode.LocalMode;
  535. sql.VehicleInfoDAL.Update( v );
  536. }
  537. public int InitializationVehicle()
  538. {
  539. #if SIMULATION
  540. this.VehicleStateProperty = eVehicleState.Idle;
  541. return 0;
  542. #else
  543. int result = 0;
  544. if ( this.refObjects.Conveyor.IsDetectedCenter() ) //자제가 있으면 Lock
  545. result = this.refObjects.Clamp.Lock_Sync();
  546. else
  547. result = this.refObjects.Clamp.Unlock_Sync();
  548. if ( result != 0 )
  549. {
  550. this.VehicleStateProperty = eVehicleState.Abnormal;
  551. return result;
  552. }
  553. if ( this.refObjects.Drive.IsErrorOn )
  554. return 22;
  555. this.VehicleStateProperty = eVehicleState.Idle;
  556. return result;
  557. #endif
  558. }
  559. public void Dispose()
  560. {
  561. this.taskCancel.Cancel();
  562. this.cancel.Cancel();
  563. this.cancel.StopWaitAll();
  564. //this.bMUManager.Disconnect();
  565. //this.drive.Dispose();
  566. }
  567. #region Request Method
  568. private void ReqVehicleState( DriveControlEventArgs args )
  569. {
  570. VehicleInfo state = new VehicleInfo();
  571. state.CurrentPosition = this.CurrentPosition;
  572. state.CurrentSpeed = this.CurrentSpeed;
  573. state.CurrentTag = this.CurrentTag.ToString();
  574. state.CurrentTorque = this.CurrentTorque;
  575. var msg = new DriveControlEventArgs();
  576. msg.ControlKind = args.ControlKind;
  577. msg.Args = state;
  578. DriveControlEventPublish( msg );
  579. }
  580. private void ReqMoveToPos( DriveControlEventArgs args )
  581. {
  582. //var result = drive.Move( args.PositionTag );
  583. //this.MoveTo( "1111" );
  584. var reply = new DriveControlEventArgs();
  585. int targetTag = args.TargetRouteID;
  586. var route = sql.RouteDal.Get( x => x.Name.Equals( targetTag ) ).FirstOrDefault();
  587. if ( route == null )
  588. {
  589. reply.Result = Results.Fail( "Not Found Route" );
  590. this.DriveControlEventPublish( reply );
  591. return;
  592. }
  593. var subCommand = new SubCmd();
  594. subCommand.TargetID = route.Name;
  595. this.MoveTo( subCommand );
  596. reply.Result = Results.Ok( "Position Move" );
  597. this.DriveControlEventPublish( reply );
  598. }
  599. void ReqFaultReset( DriveControlEventArgs _args )
  600. {
  601. var drive = 0;
  602. //var result = drive.ResetAmpFault();
  603. var msg = new DriveControlEventArgs
  604. {
  605. ControlKind = DriveControlEventArgs.eControlKind.FaultReset
  606. };
  607. msg.Result = Results.Ok( "Drive On" );
  608. this.DriveControlEventPublish( msg );
  609. }
  610. void ReqJog( DriveControlEventArgs _args )
  611. {
  612. if ( _args.JogDir == DriveControlEventArgs.eJogMoveDir.Positive )
  613. {
  614. //this.drive.JogForWard();
  615. }
  616. else
  617. {
  618. //this.drive.JogBackward();
  619. }
  620. }
  621. Logger batteryLogger = Logger.GetLogger( "BatteryLogger" );
  622. void ReqCurrentPos()
  623. {
  624. var task = Task.Factory.StartNew( () =>
  625. {
  626. while ( !this.taskCancel.Canceled )
  627. {
  628. LockUtils.Wait( 1000 );
  629. batteryLogger.I( $"SOC - {this.BatteryStateOfCharge} / Current - {this.BatteryCurrent} / Voltage - {this.BatteryVoltage} / Capacity - {this.BatteryCapacity} / Energy - {this.BatteryEnergy}" );
  630. //var msg = new DriveControlEventArgs
  631. //{
  632. // EventDir = DriveControlEventArgs.eEventDir.ToFront,
  633. // ControlKind = DriveControlEventArgs.eControlKind.ReqCurrentPos,
  634. // CurrentPosition = new Random().Next( 0, 1000 ),
  635. //};
  636. //this.DriveControlEventPublish( msg );
  637. }
  638. } );
  639. this.taskCancel.Add( task );
  640. }
  641. void ReqDriveOn( DriveControlEventArgs _args )
  642. {
  643. var drive = "Drive Name";
  644. //drive.On();
  645. var msg = new DriveControlEventArgs
  646. {
  647. ControlKind = DriveControlEventArgs.eControlKind.DriveON
  648. };
  649. msg.Result = Results.Ok( "Drive On" );
  650. this.DriveControlEventPublish( msg );
  651. }
  652. void ReqDriveOff( DriveControlEventArgs _args )
  653. {
  654. var drive = "Drive Name";
  655. //drive.Off();
  656. var msg = new DriveControlEventArgs
  657. {
  658. ControlKind = DriveControlEventArgs.eControlKind.DriveOFF
  659. };
  660. msg.Result = Results.Ok( "Drive On" );
  661. this.DriveControlEventPublish( msg );
  662. }
  663. #endregion
  664. #region Thread
  665. void ThreadStart()
  666. {
  667. this.cancel.AddGo( new Action( this._ThSubCmdWorker ) );
  668. this.cancel.AddGo( new Action( this._ThVehicleStateCheck ) );
  669. }
  670. //장애물 감지 Thread
  671. //장애물 감지 패턴 변경도 여기 하자.
  672. private void _ThVehicleStateCheck()
  673. {
  674. while ( !this.cancel.Canceled )
  675. {
  676. try
  677. {
  678. //if ( this.autoManager.OperationModeProperty == eOperatationMode.AutoMode )
  679. //this.CheckObstacle();
  680. //this.CheckIOState();
  681. }
  682. catch ( ThreadInterruptedException threadInterruptedException )
  683. {
  684. }
  685. catch ( Exception exception )
  686. {
  687. logger.E( exception );
  688. }
  689. finally
  690. {
  691. LockUtils.Wait( 5 );
  692. }
  693. }
  694. logger.D( "Vehicle - _ThObstacleChecker Dispose" );
  695. }
  696. /// <summary>
  697. /// Scheduler 가 주는 Sub Command 를 이용하여 동작하자.
  698. /// </summary>
  699. public void _ThSubCmdWorker()
  700. {
  701. while ( !this.cancel.Canceled )
  702. {
  703. try
  704. {
  705. if ( this.ObstacleStateProperty != eObstacleState.Normal ) //장애물 감지 상태 시 조그 동작만 가능하게.
  706. continue;
  707. if ( this.autoManager.AutoModeStateProperty != eAutoModeState.Run ) //
  708. continue;
  709. var subCmd = sql.SubCmdDAL.GetAll().FirstOrDefault();
  710. if ( subCmd == null ) continue;
  711. if ( !sql.CommandDAL.GetAll().Any( x => x.CommandID.Equals( subCmd.CmdID ) ) )
  712. {
  713. if ( subCmd.CmdType == SubCmd.eCmdType.Auto ) //자동 명령중 Main Command 가 없으면 삭제.
  714. {
  715. sql.SubCmdDAL.Delete( subCmd.ID );
  716. logger.I( $"SubCmd Deleted - ID={subCmd.ID}, CommandID={subCmd.CmdID}" );
  717. }
  718. }
  719. switch ( subCmd.Type )
  720. {
  721. case eSubCommandType.Move:
  722. this.CurrentSubCommand = subCmd;
  723. this.Move( subCmd );
  724. break;
  725. case eSubCommandType.Load:
  726. this.CurrentSubCommand = subCmd;
  727. this.LoadCarrier( subCmd );
  728. break;
  729. case eSubCommandType.Unload:
  730. this.CurrentSubCommand = subCmd;
  731. this.UnloadCarrier( subCmd );
  732. break;
  733. case eSubCommandType.Charge:
  734. this.CurrentSubCommand = subCmd;
  735. this.BatteryCharge( subCmd );
  736. break;
  737. default:
  738. break;
  739. }
  740. }
  741. catch ( Exception exception )
  742. {
  743. logger.E( exception );
  744. }
  745. finally
  746. {
  747. LockUtils.Wait( 500 );
  748. }
  749. }
  750. logger.D( "Vehicle - _ThSubCmdWorker Dispose" );
  751. }
  752. #endregion
  753. #region Control Action Method
  754. public void EStop()
  755. {
  756. this.refObjects.Conveyor.OnOffConveyor( false );
  757. //Clamp EStop
  758. this.refObjects.Clamp.ClampEStop();
  759. //this.drive.EStop();
  760. this.OccurVehicleAlarm( 23 );
  761. }
  762. #region For Moving
  763. void Move( SubCmd sub )
  764. {
  765. //Move 시작 시 충전 중이면 충전 중지 실행.
  766. int result = 0;
  767. if ( this.IsCharging() || this.VehicleStateProperty == eVehicleState.Charge )
  768. {
  769. result = this.StopBatteryCharge();
  770. if ( result != 0 )
  771. {
  772. OccurVehicleAlarm( result );
  773. return;
  774. }
  775. }
  776. var iTarget = Convert.ToInt32( sub.TargetID );
  777. if ( iTarget != CurrentTag ) //하나의 목표 위치로 왔을때 현재 위치와 동일 하면 이동안함.
  778. {
  779. result = this.MoveTo( sub );
  780. if ( result != ConstInt.EXECUTE_SUCCESS )
  781. {
  782. OccurVehicleAlarm( result );
  783. }
  784. }
  785. this.taskMoveCancel.Cancel();
  786. this.taskMoveCancel.WaitAll();
  787. sql.SubCmdDAL.Clean();
  788. }
  789. int MoveTo( SubCmd sub )
  790. {
  791. if ( this.VehicleStateProperty == eVehicleState.Idle )
  792. {
  793. this.OnMoveReady?.Invoke();
  794. var moveReadyBuzzerTime = Convert.ToInt32( sql.ConfigDal.GetById( ConstString.BuzzerStartReadyTime ).Value );
  795. Thread.Sleep( moveReadyBuzzerTime );
  796. this.VehicleStateProperty = eVehicleState.Move;
  797. }
  798. this.OnMoving?.Invoke();
  799. //이전에 있던 작업들 종료 및 삭제
  800. this.taskMoveCancel.Cancel();
  801. this.taskMoveCancel.WaitAll();
  802. this.taskMoveCancel.Add( CheckCrossPoint() );
  803. this.VehicleStateProperty = eVehicleState.Move;
  804. int result = this.refObjects.Drive.MoveToPoint( sub, 100 );
  805. if ( result != ConstInt.EXECUTE_SUCCESS )
  806. return result;
  807. result = this.Wait4MoveDone();
  808. if ( result != ConstInt.EXECUTE_SUCCESS )
  809. return result;
  810. //Drive 에서 정지 확인 후 상태 변경
  811. if ( this.refObjects.Drive.IsDriveStop() )
  812. {
  813. this.OnMoveFinish?.Invoke();
  814. this.VehicleStateProperty = eVehicleState.Idle;
  815. logger.D( "Move Finish" );
  816. }
  817. return result;
  818. }
  819. int Wait4MoveDone()
  820. {
  821. int waitTime = ConstUtils.ONE_HOUR; //설정 할 수있게.
  822. long st = SwUtils.CurrentTimeMillis;
  823. //Todo: 이동시 확인 사항들.
  824. while ( true )
  825. {
  826. Thread.Sleep( 5 );
  827. if ( SwUtils.Gt( st, waitTime ) )
  828. {
  829. //Todo: 이동시간 초과 시 동작들.
  830. logger.D( "Wait4MoveDone Time Over" );
  831. return 39;
  832. }
  833. //Todo: 이동중 명령이 삭제 되면 처리 할일들.
  834. //이동중 메인 명력이 없어진다면 정지 후
  835. if ( null == sql.CommandDAL.GetById( this.CurrentSubCommand.CmdID ) )
  836. {
  837. logger.D( "[Wait Move Done] - 메인 명령 사라짐" );
  838. var cmd = sql.CommandDAL.GetAll();
  839. if ( cmd == null )
  840. {
  841. logger.D( "[Wait Move Done] - Main Command not Exist Motion Stop" );
  842. this.refObjects.Drive.Stop();
  843. return 40;
  844. }
  845. else
  846. {
  847. logger.D( "[Wait Move Done] - Main Command not Exist Motion command, New Command Exist" );
  848. break;
  849. }
  850. }
  851. if ( this.refObjects.Drive.IsDriveStop() ) //Move Stop
  852. break;
  853. }
  854. return ConstInt.EXECUTE_SUCCESS;
  855. }
  856. Task CheckCrossPoint()
  857. {
  858. var task = Task.Run( () =>
  859. {
  860. long sTime = SwUtils.CurrentTimeMillis;
  861. while ( !this.taskMoveCancel.Canceled )
  862. {
  863. Thread.Sleep( 10 );
  864. //ToDo: approach Cross Point Check
  865. //ToDo: Obstacle Laser Sensor Pattern Change Method 구현 필요.
  866. }
  867. } );
  868. return task;
  869. }
  870. #endregion
  871. public bool LoadCarrier( SubCmd sub )
  872. {
  873. this.VehicleStateProperty = eVehicleState.Load;
  874. //var route = sql.RouteDal.GetRoute( sub.TargetID );
  875. //if ( !CorrectPosition( route, this.CurrentPosition ) )
  876. //{
  877. // this.OccurVehicleAlarm( 20 );
  878. // return false; //Alarm
  879. //}
  880. int result = 0;
  881. result = this.PIOAndLoad( sub.TargetID );
  882. if ( result != 0 )
  883. {
  884. this.PIOSensorOff();
  885. this.OccurVehicleAlarm( result );
  886. return false;
  887. }
  888. this.PIOSensorOff();
  889. //Load, Unload 가 끝나면 메인 Command 를 완료 했다고 판단.
  890. var cmd = sql.CommandDAL.GetById( sub.CmdID );
  891. cmd.State = eCommandState.Complete;
  892. sql.CommandDAL.Update( cmd );
  893. sql.SubCmdDAL.Clean();
  894. LockUtils.Wait( 1000 );
  895. this.OnLoadComplete?.Invoke(); //일찍 주면 다음 명령을 500ms 안에 주는 현상 있음. 그러니까 천천히 주자
  896. this.VehicleStateProperty = eVehicleState.Idle;
  897. return true;
  898. }
  899. public bool UnloadCarrier( SubCmd sub )
  900. {
  901. this.VehicleStateProperty = eVehicleState.Unload;
  902. var targetNo = Convert.ToInt32( sub.TargetID );
  903. if ( this.CurrentTag != targetNo )
  904. {
  905. this.OccurVehicleAlarm( 21 );
  906. return false; //Alarm
  907. }
  908. //var route = sql.RouteDal.GetRoute( sub.TargetID );
  909. //if ( !CorrectPosition( route, this.CurrentPosition ) )
  910. //{
  911. // this.OccurVehicleAlarm( 21 );
  912. // return false; //Alarm
  913. //}
  914. //PIO 내부로 이동.
  915. //int result = this.clamp.Unlock_Sync();
  916. //if ( result != 0 )
  917. //{
  918. // this.OccurVehicleAlarm( result );
  919. // return false;
  920. //}
  921. int result = 0;
  922. result = this.PIOAndUnload( sub.TargetID );
  923. if ( result != 0 )
  924. {
  925. this.refObjects.IO.OutputOn( "OUT_PIO_SENSOR_ONOFF" );
  926. this.OccurVehicleAlarm( result );
  927. return false;
  928. }
  929. this.PIOSensorOff();
  930. var cmd = sql.CommandDAL.GetById( sub.CmdID );
  931. cmd.State = eCommandState.Complete;
  932. sql.CommandDAL.Update( cmd );
  933. sql.SubCmdDAL.Clean();
  934. LockUtils.Wait( 1000 );
  935. this.OnUnloadComplete?.Invoke(); //일찍 주면 다음 명령을 500ms 안에 주는 현상 있음. 그러니까 천천히 주자
  936. this.VehicleStateProperty = eVehicleState.Idle;
  937. logger.D( $"[Unloading End]--------------------------------------" );
  938. return true;
  939. }
  940. public void BatteryCharge( SubCmd subCmd )
  941. {
  942. int result = 0;
  943. result = this.StartBatteryCharge();
  944. if ( result != ConstInt.EXECUTE_SUCCESS )
  945. this.OccurVehicleAlarm( result );
  946. var cmd = sql.CommandDAL.GetById( subCmd.CmdID );
  947. cmd.State = eCommandState.Complete;
  948. sql.CommandDAL.Update( cmd );
  949. sql.SubCmdDAL.Clean();
  950. }
  951. /// <summary>
  952. /// Battery Charge
  953. /// 충전 시 PIO 를 해야 함.
  954. /// </summary>
  955. /// <param name="sub"></param>
  956. /// <returns></returns>
  957. int PIOBatteryCharge( SubCmd sub )
  958. {
  959. var route = sql.RouteDal.GetById( sub.TargetID );
  960. if ( !CorrectPosition( route, this.CurrentPosition ) )
  961. {
  962. this.OccurVehicleAlarm( 21 );
  963. return 0; //Alarm
  964. }
  965. var pioTimeout = CastTo<int>.From<string>( sql.ConfigDal.GetById( ConstString.PIOTimeOut ).Value );
  966. PIOClear();
  967. loggerPIO.I( $"Start Charge PIO - [{sub.TargetID}]" );
  968. if ( !this.refObjects.IO.IsOn( "IN_PIO_READY" ) )
  969. {
  970. loggerPIO.E( "[Port] - 1 Ready not On" );
  971. this.OccurVehicleAlarm( 25 );
  972. return 0;
  973. }
  974. this.refObjects.IO.WriteOutputIO( "OUT_PIO_READY", true );
  975. loggerPIO.I( "[Vehicle] - 1 Ready On" );
  976. if ( !this.refObjects.IO.WaitChangeInputIO( true, pioTimeout, "IN_PIO_RECEIVE_RUN" ) )
  977. {
  978. PIOClear();
  979. loggerPIO.E( "[Port] - 2 Receive CV Run Timeout" );
  980. this.OccurVehicleAlarm( 26 );
  981. return 0;
  982. }
  983. this.refObjects.IO.WriteOutputIO( "OUT_PIO_SENDING_RUN", true );
  984. loggerPIO.I( "[Vehicle] - 2 Send Run On" );
  985. var sTime = SwUtils.CurrentTimeMillis;
  986. while ( true )
  987. {
  988. Thread.Sleep( 5 );
  989. if ( !this.refObjects.IO.IsOn( "IN_PIO_READY" ) || this.refObjects.IO.IsOn( "IN_PIO_RECEIVE_RUN" ) )
  990. break;
  991. if ( null == sql.CommandDAL.GetById( this.CurrentSubCommand.CmdID ) )
  992. {
  993. PIOClear();
  994. logger.D( "[Wait Charging] - 메인 명령 사라짐" );
  995. break;
  996. }
  997. }
  998. if ( !this.refObjects.IO.WaitChangeInputIO( true, pioTimeout, "IN_PIO_RECEIVE_COMPLITE" ) )
  999. {
  1000. PIOClear();
  1001. loggerPIO.E( "[Port] - 3 Receive Complete Timeout" );
  1002. this.OccurVehicleAlarm( 26 );
  1003. return 0;
  1004. }
  1005. PIOClear();
  1006. this.refObjects.IO.WriteOutputIO( "OUT_PIO_SEND_COMPLITE", true );
  1007. Thread.Sleep( 1000 );
  1008. this.refObjects.IO.WriteOutputIO( "OUT_PIO_SEND_COMPLITE", false );
  1009. return 0;
  1010. }
  1011. public int StartBatteryCharge()
  1012. {
  1013. #if SIMULATION
  1014. this.PIOSensorOn();
  1015. var pioTimeout = CastTo<int>.From<string>( sql.ConfigDal.GetById( ConstString.PIOTimeOut ).Value );
  1016. PIOClear();
  1017. loggerPIO.I( $"Start Battery Charge PIO" );
  1018. //if ( !this.iO.WaitChangeInputIO( true, pioTimeout, "IN_PIO_SENDABLE" ) )
  1019. //{
  1020. // PIOClear();
  1021. // loggerPIO.E( "[Port] - 4 Ready Time Out" );
  1022. // return 34;
  1023. //}
  1024. Thread.Sleep( 1000 );
  1025. loggerPIO.E( "[Port] - 4 Ready On" );
  1026. this.refObjects.IO.WriteOutputIO( "OUT_PIO_RECEIVABLE", true );
  1027. loggerPIO.I( "[Vehicle] - 4 Receivable" );
  1028. //if ( !this.iO.WaitChangeInputIO( true, 20000, "IN_PIO_SEND_RUN" ) )
  1029. //{
  1030. // PIOClear();
  1031. // loggerPIO.E( "[Port] - 5 Sending Run Time Out" );
  1032. // return 35;
  1033. //}
  1034. Thread.Sleep( 1000 );
  1035. loggerPIO.I( "[Port] - 5 Sending Run On" );
  1036. this.refObjects.IO.WriteOutputIO( "OUT_PIO_RECEIVE_RUN", true );
  1037. loggerPIO.I( "[Vehicle] - 5 Receive Run On" );
  1038. this.VehicleStateProperty = eVehicleState.Charge;
  1039. this.OnChargingStart?.Invoke();
  1040. Thread.Sleep( 1000 );
  1041. this.OnCharging?.Invoke();
  1042. return 0;
  1043. #else
  1044. this.PIOSensorOn();
  1045. var pioTimeout = Convert.ToInt32( sql.ConfigDal.GetById( ConstString.PIOTimeOut ).Value );
  1046. PIOClear();
  1047. loggerPIO.I( $"Start Battery Charge PIO" );
  1048. if ( !this.refObjects.IO.WaitChangeInputIO( true, pioTimeout, "IN_PIO_SENDABLE" ) )
  1049. {
  1050. PIOClear();
  1051. loggerPIO.E( "[Port] - 4 Ready Time Out" );
  1052. return 34;
  1053. }
  1054. loggerPIO.E( "[Port] - 4 Ready On" );
  1055. this.refObjects.IO.WriteOutputIO( "OUT_PIO_RECEIVABLE", true );
  1056. loggerPIO.I( "[Vehicle] - 4 Receivable" );
  1057. if ( !this.refObjects.IO.WaitChangeInputIO( true, 20000, "IN_PIO_SEND_RUN" ) )
  1058. {
  1059. PIOClear();
  1060. loggerPIO.E( "[Port] - 5 Sending Run Time Out" );
  1061. return 35;
  1062. }
  1063. loggerPIO.I( "[Port] - 5 Sending Run On" );
  1064. this.refObjects.IO.WriteOutputIO( "OUT_PIO_RECEIVE_RUN", true );
  1065. loggerPIO.I( "[Vehicle] - 5 Receive Run On" );
  1066. this.VehicleStateProperty = eVehicleState.Charge;
  1067. return 0;
  1068. #endif
  1069. }
  1070. public int StopBatteryCharge()
  1071. {
  1072. #if SIMULATION
  1073. loggerPIO.I( $"Stop Battery Charge PIO" );
  1074. var pioTimeout = CastTo<int>.From<string>( sql.ConfigDal.GetById( ConstString.PIOTimeOut ).Value );
  1075. this.PIOClear();
  1076. this.refObjects.IO.WriteOutputIO( "OUT_PIO_RECIVE_COMPLITE", true );
  1077. loggerPIO.I( "[Vehicle] Receive Complete On" );
  1078. //if ( !this.iO.WaitChangeInputIO( true, 20000, "IN_PIO_SEND_COMPLITE" ) )
  1079. //{
  1080. // this.iO.WriteOutputIO( "OUT_PIO_RECIVE_COMPLITE", false );
  1081. // loggerPIO.E( "[Port] IN_PIO_SEND_COMPLITE On Time Out" );
  1082. // return 36;
  1083. //}
  1084. Thread.Sleep( 1000 );
  1085. loggerPIO.I( "[Port] Send Complete On" );
  1086. Thread.Sleep( 1000 );
  1087. this.refObjects.IO.WriteOutputIO( "OUT_PIO_RECIVE_COMPLITE", false );
  1088. this.OnChargingFull?.Invoke();
  1089. this.PIOSensorOff();
  1090. this.VehicleStateProperty = eVehicleState.Idle;
  1091. return 0;
  1092. #else
  1093. loggerPIO.I( $"Stop Battery Charge PIO" );
  1094. var pioTimeout = Convert.ToInt32( sql.ConfigDal.GetById( ConstString.PIOTimeOut ).Value );
  1095. this.PIOClear();
  1096. this.refObjects.IO.WriteOutputIO( "OUT_PIO_RECIVE_COMPLITE", true );
  1097. loggerPIO.I( "[Vehicle] Receive Complete On" );
  1098. if ( !this.refObjects.IO.WaitChangeInputIO( true, 10000, "IN_PIO_SEND_COMPLITE" ) )
  1099. {
  1100. this.refObjects.IO.WriteOutputIO( "OUT_PIO_RECIVE_COMPLITE", false );
  1101. loggerPIO.E( "[Port] IN_PIO_SEND_COMPLITE On Time Out" );
  1102. return 36;
  1103. }
  1104. loggerPIO.I( "[Port] Send Complete On" );
  1105. Thread.Sleep( 1000 );
  1106. this.refObjects.IO.WriteOutputIO( "OUT_PIO_RECIVE_COMPLITE", false );
  1107. this.PIOSensorOff();
  1108. this.VehicleStateProperty = eVehicleState.Idle;
  1109. return 0;
  1110. #endif
  1111. }
  1112. #endregion
  1113. #region Check Method
  1114. bool CheckObstacle()
  1115. {
  1116. if ( this.refObjects.IO.IsOff( "IN_OBSTRUCTION_DETECT_SAFETY" ) || this.refObjects.IO.IsOff( "IN_OBSTRUCTION_DETECT_ERROR" ) )
  1117. {
  1118. this.ObstacleStateProperty = eObstacleState.Abnormal;
  1119. this.OccurVehicleAlarm( 9999 );
  1120. }
  1121. else if ( this.refObjects.IO.IsOff( "IN_OBSTRUCTION_DETECT_STOP" ) )
  1122. {
  1123. this.ObstacleStateProperty = eObstacleState.Blocked;
  1124. }
  1125. else if ( this.refObjects.IO.IsOff( "IN_OBSTRUCTION_DETECT_SLOW" ) )
  1126. {
  1127. this.ObstacleStateProperty = eObstacleState.Decelerate;
  1128. }
  1129. else
  1130. {
  1131. this.ObstacleStateProperty = eObstacleState.Normal;
  1132. }
  1133. this.refObjects.Drive.SetObstacleState( this.ObstacleStateProperty );
  1134. return false;
  1135. }
  1136. void CheckIOState()
  1137. {
  1138. //이미 알람이면 체크 안함.
  1139. if ( this.VehicleStateProperty == eVehicleState.Abnormal ) return;
  1140. if ( this.refObjects.IO.IsConnectError ) return;
  1141. //if ( this.iO.IsOn( "IN_EMS_SW" ) ) this.OccurVehicleAlarm( 28 );
  1142. //if ( !this.iO.IsOn( "IN_CP_ON_SAFETY" ) ) this.OccurVehicleAlarm( 31 );
  1143. //if ( !this.iO.IsOn( "IN_CP_ON_24V" ) ) this.OccurVehicleAlarm( 30 );
  1144. //if ( !this.iO.IsOn( "IN_MC_ON" ) ) this.OccurVehicleAlarm( 29 );
  1145. }
  1146. #endregion
  1147. #region Mechanical Method
  1148. #region IO
  1149. /// <summary>
  1150. /// Out Put 을 On 이면 Sensor Off
  1151. /// </summary>
  1152. public void PIOSensorOn() => this.refObjects.IO.OutputOff( "OUT_PIO_SENSOR_ONOFF" );
  1153. /// <summary>
  1154. /// Out Put 을 Off 이면 Sensor On
  1155. /// </summary>
  1156. public void PIOSensorOff() => this.refObjects.IO.OutputOn( "OUT_PIO_SENSOR_ONOFF" );
  1157. /// <summary>
  1158. /// 충전 중일때 MTL PIO Bit 가 살아 있다
  1159. /// 이걸 보고 판단 하자. 충전 단자 전진 상태임.
  1160. /// </summary>
  1161. /// <returns></returns>
  1162. public bool IsCharging() => this.refObjects.IO.IsOn( "IN_PIO_SEND_RUN" ) && this.refObjects.IO.IsOn( "IN_PIO_SENDABLE" );
  1163. #endregion
  1164. #region Drive
  1165. //public void DriveServoOff() => this.drive.ServoOff();
  1166. //public void DriveServoOn() => this.drive.ServoOn();
  1167. #endregion
  1168. #region Conveyor
  1169. public void ConveyorOff() => this.refObjects.Conveyor.OnOffConveyor( false );
  1170. public int ConveyorLoad() => this.refObjects.Conveyor.ConveyorLoad();
  1171. public int ConveyorUnload() => this.refObjects.Conveyor.ConveyorUnload();
  1172. public int PIOAndLoad( string targetName )
  1173. {
  1174. #if SIMULATION
  1175. PIOClear();
  1176. loggerPIO.I( $"Start Load PIO - [{targetName}]" );
  1177. this.OnPIOStart?.Invoke( true );
  1178. this.refObjects.IO.WriteOutputIO( "OUT_PIO_RECEIVE_RUN", true );
  1179. loggerPIO.I( "[Vehicle] - 4 Receive Run On" );
  1180. Thread.Sleep( 1000 );//상대 IO 기다린다 생각.
  1181. loggerPIO.E( "[Port] - 4 Ready On" );
  1182. //Conveyor Start
  1183. loggerPIO.I( "[Vehicle] - Conveyor Run" );
  1184. this.OnConveyorStart?.Invoke( true );
  1185. Thread.Sleep( 10000 );//Conveyor 구동
  1186. this.OnCarrierDetected?.Invoke( true );
  1187. PIOClear();
  1188. Thread.Sleep( 1000 );
  1189. this.OnConveyorStop?.Invoke( true );
  1190. Thread.Sleep( 1000 );
  1191. this.OnLoadComplete?.Invoke();
  1192. #else
  1193. this.PIOSensorOn();
  1194. LockUtils.Wait( 500 );
  1195. int result = 0;
  1196. var pioTimeout = Convert.ToInt32( sql.ConfigDal.GetById( ConstString.PIOTimeOut ).Value );
  1197. result = this.refObjects.Clamp.Unlock_Sync();
  1198. if ( result != 0 )
  1199. {
  1200. this.OccurVehicleAlarm( result );
  1201. return result;
  1202. }
  1203. if ( this.refObjects.Conveyor.IsInverterError() )
  1204. return 16;
  1205. if ( !this.refObjects.Conveyor.IsLifterPositinCheck() )
  1206. return 14;
  1207. //Todo: Sensor Setting 이 후 주석 풀기.
  1208. //if ( !this.IsLifterDuplication() )
  1209. //{
  1210. // this.OnFailReport?.Invoke( eFailCode.Load_PortHasNotCarrier );
  1211. // return 0;
  1212. //}
  1213. if ( this.refObjects.Conveyor.IsDetectedCenter() )
  1214. {
  1215. this.OnFailReport?.Invoke( eFailCode.Load_VehicleHasCarrier );
  1216. return 0;
  1217. }
  1218. PIOClear();
  1219. loggerPIO.I( $"Start Load PIO - [{targetName}]" );
  1220. this.OnPIOStart?.Invoke( true );
  1221. this.refObjects.IO.WriteOutputIO( "OUT_PIO_RECEIVABLE", true );
  1222. loggerPIO.I( "[Vehicle] - 4 Receivable" );
  1223. if ( !this.refObjects.IO.WaitChangeInputIO( true, pioTimeout, "IN_PIO_SENDABLE" ) )
  1224. {
  1225. PIOClear();
  1226. loggerPIO.E( "[Port] - 4 Ready Time Out" );
  1227. this.OnFailReport?.Invoke( eFailCode.LoadPIOInterlockTimeout );
  1228. return 0;
  1229. }
  1230. loggerPIO.E( "[Port] - 4 Ready On" );
  1231. //this.conveyor.SetConveyorSpeed( true );
  1232. this.refObjects.Conveyor.OnOffConveyor( true, true );
  1233. this.refObjects.IO.WriteOutputIO( "OUT_PIO_RECEIVE_RUN", true, 1000 ); //1Sec 이후 On
  1234. loggerPIO.I( "[Vehicle] - Conveyor Run" );
  1235. this.OnConveyorStart?.Invoke( true );
  1236. if ( !this.refObjects.IO.WaitChangeInputIO( true, pioTimeout, "IN_PIO_SEND_RUN" ) )
  1237. {
  1238. this.refObjects.Conveyor.OnOffConveyor( false, true );
  1239. PIOClear();
  1240. loggerPIO.E( "[Port] - 5 Sending Run Time Out" );
  1241. this.OnFailReport?.Invoke( eFailCode.LoadPIOInterlockTimeout );
  1242. return 0;
  1243. }
  1244. loggerPIO.I( "[Port] - 5 Sending Run On" );
  1245. bool isStartDetected = false;
  1246. var sTime = SwUtils.CurrentTimeMillis;
  1247. while ( true )
  1248. {
  1249. LockUtils.Wait( 10 );
  1250. if ( SwUtils.Gt( sTime, 20 * ConstUtils.ONE_SECOND ) )
  1251. {
  1252. PIOClear();
  1253. this.refObjects.Conveyor.OnOffConveyor( false, true );
  1254. loggerPIO.E( "[Vehicle] Conveyor Wait Time Out" );
  1255. this.OnFailReport?.Invoke( eFailCode.LoadPIOInterlockTimeout );
  1256. if ( this.refObjects.Conveyor.IsDetectedLoadStart() ) // 감지가 시작 되었으면 이동중 Error 로 판단 설비를 정지 상태로
  1257. return 10; //Conveyor Moving Timeout
  1258. else
  1259. return 0;
  1260. }
  1261. if ( this.refObjects.Conveyor.IsDetectedLoadStart() && !isStartDetected )
  1262. isStartDetected = true;
  1263. if ( !this.refObjects.Conveyor.IsDetectedLoadStart() && isStartDetected ) { }
  1264. //this.conveyor.SetConveyorSpeed( false );
  1265. if ( this.refObjects.Conveyor.IsDetectedLoadStop() ) break;
  1266. if ( this.refObjects.Conveyor.IsPIOInterLockOn() )
  1267. {
  1268. PIOClear();
  1269. this.refObjects.Conveyor.OnOffConveyor( false ); //Stop
  1270. loggerPIO.E( "[Port] PIO InterLock On " );
  1271. return 19; //
  1272. }
  1273. }
  1274. if ( this.refObjects.Conveyor.IsDetectedCenter() )
  1275. this.OnCarrierDetected?.Invoke( true );
  1276. this.refObjects.Conveyor.OnOffConveyor( false ); //Stop
  1277. PIOClear();
  1278. this.OnConveyorStop?.Invoke( true );
  1279. loggerPIO.I( "[Vehicle] Conveyor Stop" );
  1280. this.refObjects.IO.WriteOutputIO( "OUT_PIO_RECIVE_COMPLITE", true );
  1281. loggerPIO.I( "[Vehicle] Receive Complete On" );
  1282. if ( !this.refObjects.IO.WaitChangeInputIO( true, pioTimeout, "IN_PIO_SEND_COMPLITE" ) )
  1283. {
  1284. this.refObjects.IO.WriteOutputIO( "OUT_PIO_RECIVE_COMPLITE", false );
  1285. loggerPIO.E( "[Port] IN_PIO_SEND_COMPLITE On Time Out" );
  1286. }
  1287. loggerPIO.I( "[Port] Send Complete On" );
  1288. this.refObjects.IO.WriteOutputIO( "OUT_PIO_RECIVE_COMPLITE", false, 1000 );
  1289. loggerPIO.I( $"End Load PIO - [{targetName}]" );
  1290. result = this.refObjects.Clamp.Lock_Sync();
  1291. if ( result != 0 )
  1292. {
  1293. this.OccurVehicleAlarm( result );
  1294. return result;
  1295. }
  1296. #endif
  1297. return 0;
  1298. }
  1299. public int PIOAndUnload( string targetName )
  1300. {
  1301. #if SIMULATION
  1302. PIOClear();
  1303. loggerPIO.I( $"Start Unload PIO - [{targetName}]" );
  1304. this.OnPIOStart?.Invoke( false );
  1305. Thread.Sleep( 1000 );
  1306. this.refObjects.IO.WriteOutputIO( "OUT_PIO_READY", true );
  1307. loggerPIO.I( "[Vehicle] - 1 Ready On" );
  1308. Thread.Sleep( 1000 );
  1309. this.OnConveyorStart?.Invoke( false );
  1310. Thread.Sleep( 10000 );
  1311. this.refObjects.Conveyor.OnOffConveyor( false ); //Stop
  1312. this.OnConveyorStop?.Invoke( false );
  1313. PIOClear();
  1314. Thread.Sleep( 1000 );
  1315. this.OnUnloadComplete?.Invoke();
  1316. #else
  1317. this.PIOSensorOn();
  1318. LockUtils.Wait( 500 );
  1319. int result = 0;
  1320. var pioTimeout = Convert.ToInt32( sql.ConfigDal.GetById( ConstString.PIOTimeOut ).Value );
  1321. if ( this.refObjects.Conveyor.IsInverterError() )
  1322. return 16;
  1323. //if ( this.refObjects.Conveyor.IsLifterDuplication() )
  1324. //{
  1325. // this.OnFailReport?.Invoke( eFailCode.Unload_PortHasCarrier );
  1326. // return 0;
  1327. //}
  1328. if ( !this.refObjects.Conveyor.IsDetectedCenter() )
  1329. {
  1330. this.OnFailReport?.Invoke( eFailCode.Unload_VehicleHasNotCarrier );
  1331. return 0;
  1332. }
  1333. if ( !this.refObjects.Conveyor.IsLifterPositinCheck() )
  1334. return 13;
  1335. PIOClear();
  1336. loggerPIO.I( $"Start Unload PIO - [{targetName}]" );
  1337. this.OnPIOStart?.Invoke( false );
  1338. if ( !this.refObjects.IO.IsOn( "IN_PIO_READY" ) )
  1339. {
  1340. loggerPIO.E( "[Port] - 1 Ready not On" );
  1341. this.OnFailReport?.Invoke( eFailCode.UnlaodPIOInterlockTimeout );
  1342. return 0;
  1343. }
  1344. this.refObjects.IO.WriteOutputIO( "OUT_PIO_READY", true );
  1345. loggerPIO.I( "[Vehicle] - 1 Ready On" );
  1346. if ( !this.refObjects.IO.WaitChangeInputIO( true, pioTimeout, "IN_PIO_RECEIVE_RUN" ) )
  1347. {
  1348. PIOClear();
  1349. loggerPIO.E( "[Port] - 2 Receive CV Run Timeout" );
  1350. this.OnFailReport?.Invoke( eFailCode.UnlaodPIOInterlockTimeout );
  1351. return 0;
  1352. }
  1353. loggerPIO.E( "[Port] - 2 Receive CV Run On" );
  1354. result = this.refObjects.Clamp.Unlock_Sync();
  1355. if ( result != 0 )
  1356. {
  1357. this.OccurVehicleAlarm( result );
  1358. return result;
  1359. }
  1360. this.refObjects.IO.WriteOutputIO( "OUT_PIO_SENDING_RUN", true );
  1361. loggerPIO.I( "[Vehicle] - 2 Send Run On" );
  1362. //this.conveyor.SetConveyorSpeed( true );
  1363. this.refObjects.Conveyor.OnOffConveyor( true );
  1364. this.OnConveyorStart?.Invoke( false );
  1365. var sTime = SwUtils.CurrentTimeMillis;
  1366. while ( true )
  1367. {
  1368. if ( SwUtils.Gt( sTime, 20 * ConstUtils.ONE_SECOND ) )
  1369. {
  1370. PIOClear();
  1371. this.refObjects.Conveyor.OnOffConveyor( false, true );
  1372. loggerPIO.E( "[Port] Conveyor Wait Time Out" );
  1373. this.OnFailReport?.Invoke( eFailCode.UnlaodPIOInterlockTimeout );
  1374. if ( this.refObjects.Conveyor.IsDetectedLoadStart() || this.refObjects.Conveyor.IsDetectedCenter() ) //중간에 걸려 있다고 생각해서 알람 처리.
  1375. return 12; //Conveyor Moving Timeout
  1376. else
  1377. return 0;
  1378. }
  1379. if ( !this.refObjects.Conveyor.IsDetectedLoadStart() && !this.refObjects.Conveyor.IsDetectedCenter() )
  1380. {
  1381. if ( this.refObjects.IO.IsOn( "IN_PIO_RECEIVE_COMPLITE" ) )
  1382. {
  1383. loggerPIO.I( "[Port] - 3 Receive Complete On" );
  1384. break;
  1385. }
  1386. }
  1387. }
  1388. if ( !this.refObjects.Conveyor.IsDetectedCenter() )
  1389. this.OnCarrierDetected?.Invoke( false );
  1390. this.refObjects.Conveyor.OnOffConveyor( false ); //Stop
  1391. this.OnConveyorStop?.Invoke( false );
  1392. PIOClear();
  1393. this.refObjects.IO.WriteOutputIO( "OUT_PIO_SEND_COMPLITE", true );
  1394. Thread.Sleep( 1000 );
  1395. this.refObjects.IO.WriteOutputIO( "OUT_PIO_SEND_COMPLITE", false );
  1396. loggerPIO.I( "[Vehicle] - 3 Send Complete OnOff" );
  1397. #endif
  1398. loggerPIO.I( $"End Unload PIO - [{targetName}]" );
  1399. return 0;
  1400. }
  1401. void PIOClear()
  1402. {
  1403. string[] pio = { "OUT_PIO_READY", "OUT_PIO_SENDING_RUN", "OUT_PIO_SEND_COMPLITE", "OUT_PIO_RECEIVABLE", "OUT_PIO_RECEIVE_RUN", "OUT_PIO_RECIVE_COMPLITE", "OUT_PIO_INTERLOCK" };
  1404. pio.FwEach( x => { this.refObjects.IO.OutputOff( x ); } );
  1405. }
  1406. #endregion
  1407. #endregion
  1408. #region Help Method
  1409. /// <summary>
  1410. /// 현재 Point 가 변경될때 장애물 감지 센서의 패턴을 변경한다.
  1411. /// </summary>
  1412. /// <param name="v"></param>
  1413. private void ObstaclePatternChange( int v )
  1414. {
  1415. if ( !RouteManager.Instance.Segments.Any( s => s.ID == v ) )
  1416. {
  1417. logger.E( "Current Tag Not Exist RouteManager Point List" );
  1418. return;
  1419. }
  1420. //Todo: 현재 Segment ID 를 가져 와서 변경하는 방식으로 변경 필요.
  1421. var obstacle = RouteManager.Instance.Obstacles.Where( o => o.segmentID == v ).Single();
  1422. this.ChgObstacleDetectPattern( obstacle.fieldset );
  1423. }
  1424. /// <summary>
  1425. /// 현재 좌표 값이 등록된 Route 에 맞는 위치인지 확인한다.
  1426. /// 판단 기준은 Route 에 Tolerance 범위를 사용.
  1427. /// </summary>
  1428. /// <param name="route"></param>
  1429. /// <param name="currentPosition"></param>
  1430. /// <returns></returns>
  1431. bool CorrectPosition( Route route, double currentPosition )
  1432. {
  1433. var rScale = route.ScaleValue;
  1434. var rTolerance = route.ScaleTolerance;
  1435. var result = currentPosition - rScale;
  1436. if ( rTolerance < Math.Abs( result ) )
  1437. return false;
  1438. return true;
  1439. }
  1440. /// <summary>
  1441. /// if no is zero, Laser Off
  1442. /// bit Off, On, On, On,On Area1
  1443. /// </summary>
  1444. /// <param name="no"> 0 == Off Laser</param>
  1445. /// <returns></returns>
  1446. public bool ChgObstacleDetectPattern( int no )
  1447. {
  1448. var bitArray = BitUtils.ChgBitArray( no );
  1449. int bitIndex = 0;
  1450. this.obstacleBitList.ForEach( b =>
  1451. {
  1452. if ( bitArray[bitIndex] )
  1453. this.refObjects.IO.OutputOff( b );
  1454. else
  1455. this.refObjects.IO.OutputOn( b );
  1456. bitIndex++;
  1457. } );
  1458. ObstaclePattern = no;
  1459. return true;
  1460. }
  1461. public int GetObstacleDetectPattern()
  1462. {
  1463. int bitIndex = 0;
  1464. BitArray bitArray = new BitArray( this.obstacleBitList.Count );
  1465. this.obstacleBitList.ForEach( b =>
  1466. {
  1467. if ( this.refObjects.IO.IsOn( b, false ) )
  1468. bitArray.Set( bitIndex, false );
  1469. else
  1470. bitArray.Set( bitIndex, true );
  1471. bitIndex++;
  1472. } );
  1473. return BitUtils.ChgInt32( bitArray );
  1474. }
  1475. /// <summary>
  1476. /// Vehicle 이동 및 동작 중 Alarm 발생 시 처리
  1477. /// </summary>
  1478. /// <param name="alarmID"></param>
  1479. public void OccurVehicleAlarm( int alarmID )
  1480. {
  1481. this.MachineMode = eMachineMode.LocalMode;
  1482. this.VehicleStateProperty = eVehicleState.Abnormal;
  1483. this.ConveyorOff();
  1484. this.autoManager.ProcessAlarm( alarmID );
  1485. }
  1486. public void SetObstaclePattern( ObstacleControlEventArgs.eControlKind state, int value )
  1487. {
  1488. if ( state == ObstacleControlEventArgs.eControlKind.DRIVE )
  1489. {
  1490. this.ObstacleDrive = value;
  1491. ChgObstacleDetectPattern( this.ObstacleDrive );
  1492. }
  1493. else if ( state == ObstacleControlEventArgs.eControlKind.CURVE )
  1494. {
  1495. this.ObstacleCurve = value;
  1496. ChgObstacleDetectPattern( this.ObstacleCurve );
  1497. }
  1498. else
  1499. return;
  1500. }
  1501. public eSteeringState GetESteeringState() => this.refObjects.Steering.GetSteeringState();
  1502. #endregion
  1503. #region Event Subscribe
  1504. private void BMUManager_OnDisconnect( string obj )
  1505. {
  1506. this.BatteryIsConnect = false;
  1507. this.OccurVehicleAlarm( 32 );
  1508. }
  1509. private void BMUManager_OnConnect( string obj )
  1510. {
  1511. this.BatteryIsConnect = true;
  1512. //ReqCurrentPos();
  1513. }
  1514. private void BMUManager_OnFirstColtd( List<ReceivedData> obj )
  1515. {
  1516. }
  1517. private void BMUManager_OnChangedReceivedData( Serial.DataModel.ReceivedData obj )
  1518. {
  1519. var kind = CastTo<eDataKind>.From<Enum>( obj.DataKind );
  1520. switch ( kind )
  1521. {
  1522. case eDataKind.Voltage:
  1523. this.BatteryVoltage = (double)obj.Value;
  1524. break;
  1525. case eDataKind.Current:
  1526. this.BatteryCurrent = (double)obj.Value;
  1527. break;
  1528. case eDataKind.BatteryState:
  1529. if ( obj.Value == null )
  1530. return;
  1531. this.BatteryState = (double)obj.Value;
  1532. break;
  1533. case eDataKind.ChargeCompleteTime:
  1534. if ( obj.Value == null /*|| obj.Value <= 0 */)
  1535. return;
  1536. this.BatteryChargeTime = (double)obj.Value;
  1537. if ( this.BatteryChargeTime > 0 )
  1538. this.VehicleStateProperty = eVehicleState.Charge;
  1539. break;
  1540. case eDataKind.DisChargeCompleteTime:
  1541. if ( obj.Value == null || obj.Value <= 0 )
  1542. return;
  1543. this.BatteryDisChargeTime = (double)obj.Value;
  1544. break;
  1545. case eDataKind.SOC:
  1546. this.BatteryStateOfCharge = (double)obj.Value;
  1547. if ( this.BatteryStateOfCharge >= 80 )
  1548. {
  1549. if ( this.autoManager.AutoModeStateProperty != eAutoModeState.Run )
  1550. return;
  1551. if ( this.VehicleStateProperty == eVehicleState.Charge || this.IsCharging() )
  1552. {
  1553. int result = ConstInt.EXECUTE_SUCCESS;
  1554. result = this.StopBatteryCharge();
  1555. if ( result != ConstInt.EXECUTE_SUCCESS )
  1556. this.OccurVehicleAlarm( result );
  1557. }
  1558. }
  1559. break;
  1560. case eDataKind.SOH:
  1561. this.BatteryStateOfHealth = (double)obj.Value;
  1562. break;
  1563. case eDataKind.ResidualCapacity:
  1564. this.BatteryCapacity = (double)obj.Value;
  1565. break;
  1566. case eDataKind.ResidualEnergy:
  1567. this.BatteryEnergy = (double)obj.Value;
  1568. break;
  1569. case eDataKind.Temperature:
  1570. this.BatteryTemperature = (double)obj.Value;
  1571. break;
  1572. default:
  1573. break;
  1574. }
  1575. }
  1576. private void AutoManager_OnOperationModeChanged( eOperatationMode obj )
  1577. {
  1578. this.refObjects.Drive.SetDriveOperationMode( obj );
  1579. }
  1580. private void ZmqManager_PropertyChanged( object sender, System.ComponentModel.PropertyChangedEventArgs e )
  1581. {
  1582. var property = sender.GetType().GetProperty( e.PropertyName );
  1583. var newValue = property.GetValue( sender, null );
  1584. switch ( e.PropertyName )
  1585. {
  1586. case "SegmentID":
  1587. {
  1588. var v = CastTo<int>.From<object>( newValue );
  1589. this.ObstaclePatternChange( v );
  1590. }
  1591. break;
  1592. case "RequestSteering":
  1593. {
  1594. var v = CastTo<eSteeringState>.From<object>( newValue );
  1595. switch ( v )
  1596. {
  1597. case eSteeringState.None:
  1598. break;
  1599. case eSteeringState.Left:
  1600. this.refObjects.Steering.ControlSteering( true );
  1601. break;
  1602. case eSteeringState.Right:
  1603. this.refObjects.Steering.ControlSteering();
  1604. break;
  1605. default:
  1606. break;
  1607. }
  1608. }
  1609. break;
  1610. case "CurrentPointNo":
  1611. {
  1612. var v = CastTo<int>.From<object>( newValue );
  1613. logger.D( $"{this.CurrentTag} -> {v}" );
  1614. this.CurrentTag = v;
  1615. }
  1616. break;
  1617. case "RearDriveState":
  1618. {
  1619. var v = CastTo<DriveState>.From<object>( newValue );
  1620. this.RearDriveState = v;
  1621. }
  1622. break;
  1623. case "FrontLoadFactor":
  1624. {
  1625. var v = CastTo<double>.From<object>( newValue );
  1626. this.FrontLoadFactor = v;
  1627. this.FrontTorque = Math.Truncate( ( ( v * 1.9 ) / 1000 ) * 100 ) / 100;
  1628. }
  1629. break;
  1630. case "FrontRPM":
  1631. {
  1632. var v = CastTo<double>.From<object>( newValue );
  1633. this.FrontRpm = v;
  1634. var ll = ( ( ( ( v / 60 ) * ( 2 * Math.PI ) ) * 0.06 ) / 10 );
  1635. this.FrontSpeed = Math.Truncate( ll * 100 ) / 100;
  1636. }
  1637. break;
  1638. case "RearLoadFactor":
  1639. {
  1640. var v = CastTo<double>.From<object>( newValue );
  1641. this.RearLoadFactor = v;
  1642. this.RearTorque = Math.Truncate( ( ( v * 1.9 ) / 1000 ) * 100 ) / 100;
  1643. }
  1644. break;
  1645. case "RearRPM":
  1646. {
  1647. var v = CastTo<double>.From<object>( newValue );
  1648. this.RearRpm = v;
  1649. var ll = ( ( ( ( v / 60 ) * ( 2 * Math.PI ) ) * 0.06 ) / 10 );
  1650. this.RearSpeed = Math.Truncate( ll * 100 ) / 100;
  1651. }
  1652. break;
  1653. default:
  1654. break;
  1655. }
  1656. }
  1657. private void Motion_PropertyChanged( object sender, System.ComponentModel.PropertyChangedEventArgs e )
  1658. {
  1659. var property = sender.GetType().GetProperty( e.PropertyName );
  1660. var newValue = property.GetValue( sender, null );
  1661. switch ( e.PropertyName )
  1662. {
  1663. case "CurrentPos":
  1664. {
  1665. var v = CastTo<double>.From<object>( newValue );
  1666. this.CurrentPosition = v;
  1667. }
  1668. break;
  1669. //case "CurrentTag":
  1670. // {
  1671. // var v = CastTo<int>.From<object>( newValue );
  1672. // logger.D( $"{this.CurrentTag} -> {v}" );
  1673. // this.CurrentTag = v;
  1674. // }
  1675. // break;
  1676. case "CurrentSpeed":
  1677. {
  1678. var v = CastTo<double>.From<object>( newValue );
  1679. this.CurrentSpeed = v;
  1680. }
  1681. break;
  1682. case "CurrentTorque":
  1683. {
  1684. var v = CastTo<double>.From<object>( newValue );
  1685. this.CurrentTorque = v;
  1686. }
  1687. break;
  1688. case "ReqSteeringState":
  1689. //{
  1690. // var v = CastTo<eSteeringState>.From<object>( newValue );
  1691. // switch ( v )
  1692. // {
  1693. // case eSteeringState.None:
  1694. // break;
  1695. // case eSteeringState.Left:
  1696. // this.refObjects.Steering.ControlSteering( true );
  1697. // break;
  1698. // case eSteeringState.Right:
  1699. // this.refObjects.Steering.ControlSteering();
  1700. // break;
  1701. // default:
  1702. // break;
  1703. // }
  1704. //}
  1705. break;
  1706. case "DriveServoState":
  1707. {
  1708. var v = CastTo<eDriveServoState>.From<object>( newValue );
  1709. if ( v == eDriveServoState.ServoOn )
  1710. this.refObjects.IO.OutputOn( "OUT_DRIVE_BRAKE_OFF" );
  1711. else
  1712. this.refObjects.IO.OutputOff( "OUT_DRIVE_BRAKE_OFF" );
  1713. }
  1714. break;
  1715. case "FrontDriveState":
  1716. {
  1717. var v = CastTo<DriveState>.From<object>( newValue );
  1718. this.FrontDriveState = v;
  1719. }
  1720. break;
  1721. case "RearDriveState":
  1722. {
  1723. var v = CastTo<DriveState>.From<object>( newValue );
  1724. this.RearDriveState = v;
  1725. }
  1726. break;
  1727. //case "FrontLoadFactor":
  1728. // {
  1729. // var v = CastTo<double>.From<object>( newValue );
  1730. // this.FrontLoadFactor = v;
  1731. // this.FrontTorque = Math.Truncate( ( ( v * 1.9 ) / 1000 ) * 100 ) / 100;
  1732. // }
  1733. // break;
  1734. //case "FrontRpm":
  1735. // {
  1736. // var v = CastTo<double>.From<object>( newValue );
  1737. // this.FrontRpm = v;
  1738. // var ll = ( ( ( ( v / 60 ) * ( 2 * Math.PI ) ) * 0.06 ) / 10 );
  1739. // this.FrontSpeed = Math.Truncate( ll * 100 ) / 100;
  1740. // }
  1741. // break;
  1742. //case "RearLoadFactor":
  1743. // {
  1744. // var v = CastTo<double>.From<object>( newValue );
  1745. // this.RearLoadFactor = v;
  1746. // this.RearTorque = Math.Truncate( ( ( v * 1.9 ) / 1000 ) * 100 ) / 100;
  1747. // }
  1748. // break;
  1749. //case "RearRpm":
  1750. // {
  1751. // var v = CastTo<double>.From<object>( newValue );
  1752. // this.RearRpm = v;
  1753. // var ll = ( ( ( ( v / 60 ) * ( 2 * Math.PI ) ) * 0.06 ) / 10 );
  1754. // this.RearSpeed = Math.Truncate( ll * 100 ) / 100;
  1755. // }
  1756. break;
  1757. default:
  1758. break;
  1759. }
  1760. }
  1761. private void Steering_PropertyChanged( object sender, System.ComponentModel.PropertyChangedEventArgs e )
  1762. {
  1763. var property = sender.GetType().GetProperty( e.PropertyName );
  1764. var newValue = property.GetValue( sender, null );
  1765. //Todo: 나중에 Test 하자
  1766. //var ownPropperty = this.GetType().GetProperty(e.PropertyName);
  1767. if ( e.PropertyName.Equals( "SteeringState" ) )
  1768. {
  1769. var v = CastTo<eSteeringState>.From<object>( newValue );
  1770. this.SteeringState = v;
  1771. logger.D( $"steering - {v}" );
  1772. }
  1773. }
  1774. private void Clamp_PropertyChanged( object sender, System.ComponentModel.PropertyChangedEventArgs e )
  1775. {
  1776. var property = sender.GetType().GetProperty( e.PropertyName );
  1777. var newValue = property.GetValue( sender, null );
  1778. if ( e.PropertyName.Equals( "ClampState" ) )
  1779. {
  1780. var v = CastTo<eClampState>.From<object>( newValue );
  1781. this.ClampState = v;
  1782. }
  1783. }
  1784. private void IO_OnChangedIO( BitBlock bit )
  1785. {
  1786. switch ( bit.Tag )
  1787. {
  1788. case "IN_CV_DETECT_01":
  1789. this.IsContain = bit.IsBitOn;
  1790. this.refObjects.ZmqManager.Publish( "Contain", this.IsContain.ToString() );
  1791. break;
  1792. case "IN_MC_ON":
  1793. if ( bit.IsBitOn )
  1794. {
  1795. if ( !this.refObjects.IO.IsOn( "IN_EMS_SW" ) && this.refObjects.IO.IsOn( "IN_CP_ON_SAFETY" ) && this.refObjects.IO.IsOn( "IN_CP_ON_24V" ) )
  1796. this.VehicleStateProperty = eVehicleState.Idle;
  1797. }
  1798. else
  1799. this.OccurVehicleAlarm( 29 );
  1800. break;
  1801. case "IN_EMS_SW":
  1802. if ( bit.IsBitOn )
  1803. this.OccurVehicleAlarm( 28 );
  1804. break;
  1805. case "IN_CP_ON_SAFETY":
  1806. if ( !bit.IsBitOn )
  1807. this.OccurVehicleAlarm( 31 );
  1808. break;
  1809. case "IN_CP_ON_24V":
  1810. if ( !bit.IsBitOn )
  1811. this.OccurVehicleAlarm( 30 );
  1812. break;
  1813. case "IN_OBSTRUCTION_DETECT_ERROR":
  1814. case "IN_OBSTRUCTION_DETECT_SAFETY":
  1815. case "IN_OBSTRUCTION_DETECT_STOP":
  1816. case "IN_OBSTRUCTION_DETECT_SLOW":
  1817. CheckObstacle();
  1818. break;
  1819. default:
  1820. break;
  1821. }
  1822. }
  1823. private void Steering_OnSteeringError( object sender, int e )
  1824. {
  1825. if ( e != 0 )
  1826. {
  1827. logger.E( $"[Steering] - Control Error {e}" );
  1828. this.OccurVehicleAlarm( e );
  1829. }
  1830. else
  1831. {
  1832. var msg = new DriveControlEventArgs()
  1833. {
  1834. EventDir = DriveControlEventArgs.eEventDir.ToFront,
  1835. ControlKind = DriveControlEventArgs.eControlKind.Steering,
  1836. Result = FluentResults.Results.Ok<DriveControlEventArgs.eMoveDir>( DriveControlEventArgs.eMoveDir.LEFT ),
  1837. };
  1838. this.eventAggregator.GetEvent<DriveControlPubSubEvent>().Publish( msg );
  1839. }
  1840. }
  1841. #endregion
  1842. }
  1843. }