Vehicle.cs 75 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188
  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. this.MoveTo( route.Name );
  594. reply.Result = Results.Ok( "Position Move" );
  595. this.DriveControlEventPublish( reply );
  596. }
  597. void ReqFaultReset( DriveControlEventArgs _args )
  598. {
  599. var drive = 0;
  600. //var result = drive.ResetAmpFault();
  601. var msg = new DriveControlEventArgs
  602. {
  603. ControlKind = DriveControlEventArgs.eControlKind.FaultReset
  604. };
  605. msg.Result = Results.Ok( "Drive On" );
  606. this.DriveControlEventPublish( msg );
  607. }
  608. void ReqJog( DriveControlEventArgs _args )
  609. {
  610. if ( _args.JogDir == DriveControlEventArgs.eJogMoveDir.Positive )
  611. {
  612. //this.drive.JogForWard();
  613. }
  614. else
  615. {
  616. //this.drive.JogBackward();
  617. }
  618. }
  619. Logger batteryLogger = Logger.GetLogger( "BatteryLogger" );
  620. void ReqCurrentPos()
  621. {
  622. var task = Task.Factory.StartNew( () =>
  623. {
  624. while ( !this.taskCancel.Canceled )
  625. {
  626. LockUtils.Wait( 1000 );
  627. batteryLogger.I( $"SOC - {this.BatteryStateOfCharge} / Current - {this.BatteryCurrent} / Voltage - {this.BatteryVoltage} / Capacity - {this.BatteryCapacity} / Energy - {this.BatteryEnergy}" );
  628. //var msg = new DriveControlEventArgs
  629. //{
  630. // EventDir = DriveControlEventArgs.eEventDir.ToFront,
  631. // ControlKind = DriveControlEventArgs.eControlKind.ReqCurrentPos,
  632. // CurrentPosition = new Random().Next( 0, 1000 ),
  633. //};
  634. //this.DriveControlEventPublish( msg );
  635. }
  636. } );
  637. this.taskCancel.Add( task );
  638. }
  639. void ReqDriveOn( DriveControlEventArgs _args )
  640. {
  641. var drive = "Drive Name";
  642. //drive.On();
  643. var msg = new DriveControlEventArgs
  644. {
  645. ControlKind = DriveControlEventArgs.eControlKind.DriveON
  646. };
  647. msg.Result = Results.Ok( "Drive On" );
  648. this.DriveControlEventPublish( msg );
  649. }
  650. void ReqDriveOff( DriveControlEventArgs _args )
  651. {
  652. var drive = "Drive Name";
  653. //drive.Off();
  654. var msg = new DriveControlEventArgs
  655. {
  656. ControlKind = DriveControlEventArgs.eControlKind.DriveOFF
  657. };
  658. msg.Result = Results.Ok( "Drive On" );
  659. this.DriveControlEventPublish( msg );
  660. }
  661. #endregion
  662. #region Thread
  663. void ThreadStart()
  664. {
  665. this.cancel.AddGo( new Action( this._ThSubCmdWorker ) );
  666. this.cancel.AddGo( new Action( this._ThVehicleStateCheck ) );
  667. }
  668. //장애물 감지 Thread
  669. //장애물 감지 패턴 변경도 여기 하자.
  670. private void _ThVehicleStateCheck()
  671. {
  672. while ( !this.cancel.Canceled )
  673. {
  674. try
  675. {
  676. //if ( this.autoManager.OperationModeProperty == eOperatationMode.AutoMode )
  677. //this.CheckObstacle();
  678. //this.CheckIOState();
  679. }
  680. catch ( ThreadInterruptedException threadInterruptedException )
  681. {
  682. }
  683. catch ( Exception exception )
  684. {
  685. logger.E( exception );
  686. }
  687. finally
  688. {
  689. LockUtils.Wait( 5 );
  690. }
  691. }
  692. logger.D( "Vehicle - _ThObstacleChecker Dispose" );
  693. }
  694. /// <summary>
  695. /// Scheduler 가 주는 Sub Command 를 이용하여 동작하자.
  696. /// </summary>
  697. public void _ThSubCmdWorker()
  698. {
  699. while ( !this.cancel.Canceled )
  700. {
  701. try
  702. {
  703. if ( this.ObstacleStateProperty != eObstacleState.Normal ) //장애물 감지 상태 시 조그 동작만 가능하게.
  704. continue;
  705. if ( this.autoManager.AutoModeStateProperty != eAutoModeState.Run ) //
  706. continue;
  707. var subCmd = sql.SubCmdDAL.GetAll().FirstOrDefault();
  708. if ( subCmd == null ) continue;
  709. if ( !sql.CommandDAL.GetAll().Any( x => x.CommandID.Equals( subCmd.CmdID ) ) )
  710. {
  711. if ( subCmd.CmdType == SubCmd.eCmdType.Auto ) //자동 명령중 Main Command 가 없으면 삭제.
  712. {
  713. sql.SubCmdDAL.Delete( subCmd.ID );
  714. logger.I( $"SubCmd Deleted - ID={subCmd.ID}, CommandID={subCmd.CmdID}" );
  715. }
  716. }
  717. switch ( subCmd.Type )
  718. {
  719. case eSubCommandType.Move:
  720. this.CurrentSubCommand = subCmd;
  721. this.Move( subCmd );
  722. break;
  723. case eSubCommandType.Load:
  724. this.CurrentSubCommand = subCmd;
  725. this.LoadCarrier( subCmd );
  726. break;
  727. case eSubCommandType.Unload:
  728. this.CurrentSubCommand = subCmd;
  729. this.UnloadCarrier( subCmd );
  730. break;
  731. case eSubCommandType.Charge:
  732. this.CurrentSubCommand = subCmd;
  733. this.BatteryCharge( subCmd );
  734. break;
  735. default:
  736. break;
  737. }
  738. }
  739. catch ( Exception exception )
  740. {
  741. logger.E( exception );
  742. }
  743. finally
  744. {
  745. LockUtils.Wait( 500 );
  746. }
  747. }
  748. logger.D( "Vehicle - _ThSubCmdWorker Dispose" );
  749. }
  750. #endregion
  751. #region Control Action Method
  752. public void EStop()
  753. {
  754. this.refObjects.Conveyor.OnOffConveyor( false );
  755. //Clamp EStop
  756. this.refObjects.Clamp.ClampEStop();
  757. //this.drive.EStop();
  758. this.OccurVehicleAlarm( 23 );
  759. }
  760. #region For Moving
  761. void Move( SubCmd sub )
  762. {
  763. //Move 시작 시 충전 중이면 충전 중지 실행.
  764. int result = 0;
  765. if ( this.IsCharging() || this.VehicleStateProperty == eVehicleState.Charge )
  766. {
  767. result = this.StopBatteryCharge();
  768. if ( result != 0 )
  769. {
  770. OccurVehicleAlarm( result );
  771. return;
  772. }
  773. }
  774. result = this.MoveTo( sub.TargetID );
  775. if ( result != ConstInt.EXECUTE_SUCCESS )
  776. {
  777. OccurVehicleAlarm( result );
  778. }
  779. this.taskMoveCancel.Cancel();
  780. this.taskMoveCancel.WaitAll();
  781. sql.SubCmdDAL.Clean();
  782. }
  783. int MoveTo( string pointID )
  784. {
  785. if ( this.VehicleStateProperty == eVehicleState.Idle )
  786. {
  787. this.OnMoveReady?.Invoke();
  788. var moveReadyBuzzerTime = Convert.ToInt32( sql.ConfigDal.GetById( ConstString.BuzzerStartReadyTime ).Value );
  789. Thread.Sleep( moveReadyBuzzerTime );
  790. this.VehicleStateProperty = eVehicleState.Move;
  791. }
  792. this.OnMoving?.Invoke();
  793. //이전에 있던 작업들 종료 및 삭제
  794. this.taskMoveCancel.Cancel();
  795. this.taskMoveCancel.WaitAll();
  796. this.taskMoveCancel.Add( CheckCrossPoint() );
  797. this.VehicleStateProperty = eVehicleState.Move;
  798. int result = this.refObjects.Drive.MoveToPoint( pointID, 100 );
  799. if ( result != ConstInt.EXECUTE_SUCCESS )
  800. return result;
  801. result = this.Wait4MoveDone();
  802. if ( result != ConstInt.EXECUTE_SUCCESS )
  803. return result;
  804. //Drive 에서 정지 확인 후 상태 변경
  805. if ( this.refObjects.Drive.IsDriveStop() )
  806. {
  807. this.OnMoveFinish?.Invoke();
  808. this.VehicleStateProperty = eVehicleState.Idle;
  809. logger.D( "Move Finish" );
  810. }
  811. return result;
  812. }
  813. int Wait4MoveDone()
  814. {
  815. int waitTime = ConstUtils.ONE_HOUR; //설정 할 수있게.
  816. long st = SwUtils.CurrentTimeMillis;
  817. //Todo: 이동시 확인 사항들.
  818. while ( true )
  819. {
  820. Thread.Sleep( 5 );
  821. if ( SwUtils.Gt( st, waitTime ) )
  822. {
  823. //Todo: 이동시간 초과 시 동작들.
  824. logger.D( "Wait4MoveDone Time Over" );
  825. return 39;
  826. }
  827. //Todo: 이동중 명령이 삭제 되면 처리 할일들.
  828. //이동중 메인 명력이 없어진다면 정지 후
  829. if ( null == sql.CommandDAL.GetById( this.CurrentSubCommand.CmdID ) )
  830. {
  831. logger.D( "[Wait Move Done] - 메인 명령 사라짐" );
  832. var cmd = sql.CommandDAL.GetAll();
  833. if ( cmd == null )
  834. {
  835. logger.D( "[Wait Move Done] - Main Command not Exist Motion Stop" );
  836. this.refObjects.Drive.Stop();
  837. return 40;
  838. }
  839. else
  840. {
  841. logger.D( "[Wait Move Done] - Main Command not Exist Motion command 없음" );
  842. return 41;
  843. }
  844. }
  845. if ( this.refObjects.Drive.IsDriveStop() ) //Move Stop
  846. break;
  847. }
  848. return ConstInt.EXECUTE_SUCCESS;
  849. }
  850. Task CheckCrossPoint()
  851. {
  852. var task = Task.Run( () =>
  853. {
  854. long sTime = SwUtils.CurrentTimeMillis;
  855. while ( !this.taskMoveCancel.Canceled )
  856. {
  857. Thread.Sleep( 10 );
  858. //ToDo: approach Cross Point Check
  859. //ToDo: Obstacle Laser Sensor Pattern Change Method 구현 필요.
  860. }
  861. } );
  862. return task;
  863. }
  864. #endregion
  865. public bool LoadCarrier( SubCmd sub )
  866. {
  867. this.VehicleStateProperty = eVehicleState.Load;
  868. //var route = sql.RouteDal.GetRoute( sub.TargetID );
  869. //if ( !CorrectPosition( route, this.CurrentPosition ) )
  870. //{
  871. // this.OccurVehicleAlarm( 20 );
  872. // return false; //Alarm
  873. //}
  874. int result = 0;
  875. result = this.PIOAndLoad( sub.TargetID );
  876. if ( result != 0 )
  877. {
  878. this.PIOSensorOff();
  879. this.OccurVehicleAlarm( result );
  880. return false;
  881. }
  882. this.PIOSensorOff();
  883. //Load, Unload 가 끝나면 메인 Command 를 완료 했다고 판단.
  884. var cmd = sql.CommandDAL.GetById( sub.CmdID );
  885. cmd.State = eCommandState.Complete;
  886. sql.CommandDAL.Update(cmd);
  887. sql.SubCmdDAL.Clean();
  888. LockUtils.Wait( 1000 );
  889. this.OnLoadComplete?.Invoke(); //일찍 주면 다음 명령을 500ms 안에 주는 현상 있음. 그러니까 천천히 주자
  890. this.VehicleStateProperty = eVehicleState.Idle;
  891. return true;
  892. }
  893. public bool UnloadCarrier( SubCmd sub )
  894. {
  895. this.VehicleStateProperty = eVehicleState.Unload;
  896. var targetNo = Convert.ToInt32( sub.TargetID );
  897. if ( this.CurrentTag != targetNo )
  898. {
  899. this.OccurVehicleAlarm( 21 );
  900. return false; //Alarm
  901. }
  902. //var route = sql.RouteDal.GetRoute( sub.TargetID );
  903. //if ( !CorrectPosition( route, this.CurrentPosition ) )
  904. //{
  905. // this.OccurVehicleAlarm( 21 );
  906. // return false; //Alarm
  907. //}
  908. //PIO 내부로 이동.
  909. //int result = this.clamp.Unlock_Sync();
  910. //if ( result != 0 )
  911. //{
  912. // this.OccurVehicleAlarm( result );
  913. // return false;
  914. //}
  915. int result = 0;
  916. result = this.PIOAndUnload( sub.TargetID );
  917. if ( result != 0 )
  918. {
  919. this.refObjects.IO.OutputOn( "OUT_PIO_SENSOR_ONOFF" );
  920. this.OccurVehicleAlarm( result );
  921. return false;
  922. }
  923. this.PIOSensorOff();
  924. var cmd = sql.CommandDAL.GetById( sub.CmdID );
  925. cmd.State = eCommandState.Complete;
  926. sql.CommandDAL.Update(cmd);
  927. sql.SubCmdDAL.Clean();
  928. LockUtils.Wait( 1000 );
  929. this.OnUnloadComplete?.Invoke(); //일찍 주면 다음 명령을 500ms 안에 주는 현상 있음. 그러니까 천천히 주자
  930. this.VehicleStateProperty = eVehicleState.Idle;
  931. return true;
  932. }
  933. public void BatteryCharge( SubCmd subCmd )
  934. {
  935. int result = 0;
  936. result = this.StartBatteryCharge();
  937. var cmd = sql.CommandDAL.GetById( subCmd.CmdID );
  938. cmd.State = eCommandState.Complete;
  939. sql.CommandDAL.Update( cmd );
  940. sql.SubCmdDAL.Clean();
  941. }
  942. /// <summary>
  943. /// Battery Charge
  944. /// 충전 시 PIO 를 해야 함.
  945. /// </summary>
  946. /// <param name="sub"></param>
  947. /// <returns></returns>
  948. int PIOBatteryCharge( SubCmd sub )
  949. {
  950. var route = sql.RouteDal.GetById( sub.TargetID );
  951. if ( !CorrectPosition( route, this.CurrentPosition ) )
  952. {
  953. this.OccurVehicleAlarm( 21 );
  954. return 0; //Alarm
  955. }
  956. var pioTimeout = CastTo<int>.From<string>( sql.ConfigDal.GetById( ConstString.PIOTimeOut ).Value );
  957. PIOClear();
  958. loggerPIO.I( $"Start Charge PIO - [{sub.TargetID}]" );
  959. if ( !this.refObjects.IO.IsOn( "IN_PIO_READY" ) )
  960. {
  961. loggerPIO.E( "[Port] - 1 Ready not On" );
  962. this.OccurVehicleAlarm( 25 );
  963. return 0;
  964. }
  965. this.refObjects.IO.WriteOutputIO( "OUT_PIO_READY", true );
  966. loggerPIO.I( "[Vehicle] - 1 Ready On" );
  967. if ( !this.refObjects.IO.WaitChangeInputIO( true, pioTimeout, "IN_PIO_RECEIVE_RUN" ) )
  968. {
  969. PIOClear();
  970. loggerPIO.E( "[Port] - 2 Receive CV Run Timeout" );
  971. this.OccurVehicleAlarm( 26 );
  972. return 0;
  973. }
  974. this.refObjects.IO.WriteOutputIO( "OUT_PIO_SENDING_RUN", true );
  975. loggerPIO.I( "[Vehicle] - 2 Send Run On" );
  976. var sTime = SwUtils.CurrentTimeMillis;
  977. while ( true )
  978. {
  979. Thread.Sleep( 5 );
  980. if ( !this.refObjects.IO.IsOn( "IN_PIO_READY" ) || this.refObjects.IO.IsOn( "IN_PIO_RECEIVE_RUN" ) )
  981. break;
  982. if ( null == sql.CommandDAL.GetById( this.CurrentSubCommand.CmdID ) )
  983. {
  984. PIOClear();
  985. logger.D( "[Wait Charging] - 메인 명령 사라짐" );
  986. break;
  987. }
  988. }
  989. if ( !this.refObjects.IO.WaitChangeInputIO( true, pioTimeout, "IN_PIO_RECEIVE_COMPLITE" ) )
  990. {
  991. PIOClear();
  992. loggerPIO.E( "[Port] - 3 Receive Complete Timeout" );
  993. this.OccurVehicleAlarm( 26 );
  994. return 0;
  995. }
  996. PIOClear();
  997. this.refObjects.IO.WriteOutputIO( "OUT_PIO_SEND_COMPLITE", true );
  998. Thread.Sleep( 1000 );
  999. this.refObjects.IO.WriteOutputIO( "OUT_PIO_SEND_COMPLITE", false );
  1000. return 0;
  1001. }
  1002. public int StartBatteryCharge()
  1003. {
  1004. #if SIMULATION
  1005. this.PIOSensorOn();
  1006. var pioTimeout = CastTo<int>.From<string>( sql.ConfigDal.GetById( ConstString.PIOTimeOut ).Value );
  1007. PIOClear();
  1008. loggerPIO.I( $"Start Battery Charge PIO" );
  1009. //if ( !this.iO.WaitChangeInputIO( true, pioTimeout, "IN_PIO_SENDABLE" ) )
  1010. //{
  1011. // PIOClear();
  1012. // loggerPIO.E( "[Port] - 4 Ready Time Out" );
  1013. // return 34;
  1014. //}
  1015. Thread.Sleep( 1000 );
  1016. loggerPIO.E( "[Port] - 4 Ready On" );
  1017. this.refObjects.IO.WriteOutputIO( "OUT_PIO_RECEIVABLE", true );
  1018. loggerPIO.I( "[Vehicle] - 4 Receivable" );
  1019. //if ( !this.iO.WaitChangeInputIO( true, 20000, "IN_PIO_SEND_RUN" ) )
  1020. //{
  1021. // PIOClear();
  1022. // loggerPIO.E( "[Port] - 5 Sending Run Time Out" );
  1023. // return 35;
  1024. //}
  1025. Thread.Sleep( 1000 );
  1026. loggerPIO.I( "[Port] - 5 Sending Run On" );
  1027. this.refObjects.IO.WriteOutputIO( "OUT_PIO_RECEIVE_RUN", true );
  1028. loggerPIO.I( "[Vehicle] - 5 Receive Run On" );
  1029. this.VehicleStateProperty = eVehicleState.Charge;
  1030. this.OnChargingStart?.Invoke();
  1031. Thread.Sleep( 1000 );
  1032. this.OnCharging?.Invoke();
  1033. return 0;
  1034. #else
  1035. this.PIOSensorOn();
  1036. var pioTimeout = sql.ConfigDal.GetValueToInt( ConstString.PIOTimeOut );
  1037. PIOClear();
  1038. loggerPIO.I( $"Start Battery Charge PIO" );
  1039. if ( !this.refObjects.IO.WaitChangeInputIO( true, pioTimeout, "IN_PIO_SENDABLE" ) )
  1040. {
  1041. PIOClear();
  1042. loggerPIO.E( "[Port] - 4 Ready Time Out" );
  1043. return 34;
  1044. }
  1045. loggerPIO.E( "[Port] - 4 Ready On" );
  1046. this.refObjects.IO.WriteOutputIO( "OUT_PIO_RECEIVABLE", true );
  1047. loggerPIO.I( "[Vehicle] - 4 Receivable" );
  1048. if ( !this.refObjects.IO.WaitChangeInputIO( true, 20000, "IN_PIO_SEND_RUN" ) )
  1049. {
  1050. PIOClear();
  1051. loggerPIO.E( "[Port] - 5 Sending Run Time Out" );
  1052. return 35;
  1053. }
  1054. loggerPIO.I( "[Port] - 5 Sending Run On" );
  1055. this.refObjects.IO.WriteOutputIO( "OUT_PIO_RECEIVE_RUN", true );
  1056. loggerPIO.I( "[Vehicle] - 5 Receive Run On" );
  1057. this.VehicleStateProperty = eVehicleState.Charge;
  1058. return 0;
  1059. #endif
  1060. }
  1061. public int StopBatteryCharge()
  1062. {
  1063. #if SIMULATION
  1064. loggerPIO.I( $"Stop Battery Charge PIO" );
  1065. var pioTimeout = CastTo<int>.From<string>( sql.ConfigDal.GetById( ConstString.PIOTimeOut ).Value );
  1066. this.PIOClear();
  1067. this.refObjects.IO.WriteOutputIO( "OUT_PIO_RECIVE_COMPLITE", true );
  1068. loggerPIO.I( "[Vehicle] Receive Complete On" );
  1069. //if ( !this.iO.WaitChangeInputIO( true, 20000, "IN_PIO_SEND_COMPLITE" ) )
  1070. //{
  1071. // this.iO.WriteOutputIO( "OUT_PIO_RECIVE_COMPLITE", false );
  1072. // loggerPIO.E( "[Port] IN_PIO_SEND_COMPLITE On Time Out" );
  1073. // return 36;
  1074. //}
  1075. Thread.Sleep( 1000 );
  1076. loggerPIO.I( "[Port] Send Complete On" );
  1077. Thread.Sleep( 1000 );
  1078. this.refObjects.IO.WriteOutputIO( "OUT_PIO_RECIVE_COMPLITE", false );
  1079. this.OnChargingFull?.Invoke();
  1080. this.PIOSensorOff();
  1081. this.VehicleStateProperty = eVehicleState.Idle;
  1082. return 0;
  1083. #else
  1084. loggerPIO.I( $"Stop Battery Charge PIO" );
  1085. var pioTimeout = sql.ConfigDal.GetValueToInt( ConstString.PIOTimeOut );
  1086. this.PIOClear();
  1087. this.refObjects.IO.WriteOutputIO( "OUT_PIO_RECIVE_COMPLITE", true );
  1088. loggerPIO.I( "[Vehicle] Receive Complete On" );
  1089. if ( !this.refObjects.IO.WaitChangeInputIO( true, 20000, "IN_PIO_SEND_COMPLITE" ) )
  1090. {
  1091. this.refObjects.IO.WriteOutputIO( "OUT_PIO_RECIVE_COMPLITE", false );
  1092. loggerPIO.E( "[Port] IN_PIO_SEND_COMPLITE On Time Out" );
  1093. return 36;
  1094. }
  1095. loggerPIO.I( "[Port] Send Complete On" );
  1096. Thread.Sleep( 1000 );
  1097. this.refObjects.IO.WriteOutputIO( "OUT_PIO_RECIVE_COMPLITE", false );
  1098. this.PIOSensorOff();
  1099. this.VehicleStateProperty = eVehicleState.Idle;
  1100. return 0;
  1101. #endif
  1102. }
  1103. #endregion
  1104. #region Check Method
  1105. bool CheckObstacle()
  1106. {
  1107. if ( this.refObjects.IO.IsOff( "IN_OBSTRUCTION_DETECT_SAFETY" ) || this.refObjects.IO.IsOff( "IN_OBSTRUCTION_DETECT_ERROR" ) )
  1108. {
  1109. this.ObstacleStateProperty = eObstacleState.Abnormal;
  1110. this.OccurVehicleAlarm( 9999 );
  1111. }
  1112. else if ( this.refObjects.IO.IsOff( "IN_OBSTRUCTION_DETECT_STOP" ) )
  1113. {
  1114. this.ObstacleStateProperty = eObstacleState.Blocked;
  1115. }
  1116. else if ( this.refObjects.IO.IsOff( "IN_OBSTRUCTION_DETECT_SLOW" ) )
  1117. {
  1118. this.ObstacleStateProperty = eObstacleState.Decelerate;
  1119. }
  1120. else
  1121. {
  1122. this.ObstacleStateProperty = eObstacleState.Normal;
  1123. }
  1124. this.refObjects.Drive.SetObstacleState( this.ObstacleStateProperty );
  1125. return false;
  1126. }
  1127. void CheckIOState()
  1128. {
  1129. //이미 알람이면 체크 안함.
  1130. if ( this.VehicleStateProperty == eVehicleState.Abnormal ) return;
  1131. if ( this.refObjects.IO.IsConnectError ) return;
  1132. //if ( this.iO.IsOn( "IN_EMS_SW" ) ) this.OccurVehicleAlarm( 28 );
  1133. //if ( !this.iO.IsOn( "IN_CP_ON_SAFETY" ) ) this.OccurVehicleAlarm( 31 );
  1134. //if ( !this.iO.IsOn( "IN_CP_ON_24V" ) ) this.OccurVehicleAlarm( 30 );
  1135. //if ( !this.iO.IsOn( "IN_MC_ON" ) ) this.OccurVehicleAlarm( 29 );
  1136. }
  1137. #endregion
  1138. #region Mechanical Method
  1139. #region IO
  1140. /// <summary>
  1141. /// Out Put 을 On 이면 Sensor Off
  1142. /// </summary>
  1143. public void PIOSensorOn() => this.refObjects.IO.OutputOff( "OUT_PIO_SENSOR_ONOFF" );
  1144. /// <summary>
  1145. /// Out Put 을 Off 이면 Sensor On
  1146. /// </summary>
  1147. public void PIOSensorOff() => this.refObjects.IO.OutputOn( "OUT_PIO_SENSOR_ONOFF" );
  1148. /// <summary>
  1149. /// 충전 중일때 MTL PIO Bit 가 살아 있다
  1150. /// 이걸 보고 판단 하자. 충전 단자 전진 상태임.
  1151. /// </summary>
  1152. /// <returns></returns>
  1153. public bool IsCharging() => this.refObjects.IO.IsOn( "IN_PIO_SEND_RUN" ) && this.refObjects.IO.IsOn( "IN_PIO_SENDABLE" );
  1154. #endregion
  1155. #region Drive
  1156. //public void DriveServoOff() => this.drive.ServoOff();
  1157. //public void DriveServoOn() => this.drive.ServoOn();
  1158. #endregion
  1159. #region Conveyor
  1160. public void ConveyorOff() => this.refObjects.Conveyor.OnOffConveyor( false );
  1161. public int ConveyorLoad() => this.refObjects.Conveyor.ConveyorLoad();
  1162. public int ConveyorUnload() => this.refObjects.Conveyor.ConveyorUnload();
  1163. public int PIOAndLoad( string targetName )
  1164. {
  1165. #if SIMULATION
  1166. PIOClear();
  1167. loggerPIO.I( $"Start Load PIO - [{targetName}]" );
  1168. this.OnPIOStart?.Invoke( true );
  1169. this.refObjects.IO.WriteOutputIO( "OUT_PIO_RECEIVE_RUN", true );
  1170. loggerPIO.I( "[Vehicle] - 4 Receive Run On" );
  1171. Thread.Sleep( 1000 );//상대 IO 기다린다 생각.
  1172. loggerPIO.E( "[Port] - 4 Ready On" );
  1173. //Conveyor Start
  1174. loggerPIO.I( "[Vehicle] - Conveyor Run" );
  1175. this.OnConveyorStart?.Invoke( true );
  1176. Thread.Sleep( 10000 );//Conveyor 구동
  1177. this.OnCarrierDetected?.Invoke( true );
  1178. PIOClear();
  1179. Thread.Sleep( 1000 );
  1180. this.OnConveyorStop?.Invoke( true );
  1181. Thread.Sleep( 1000 );
  1182. this.OnLoadComplete?.Invoke();
  1183. #else
  1184. this.PIOSensorOn();
  1185. LockUtils.Wait( 500 );
  1186. int result = 0;
  1187. var pioTimeout = sql.ConfigDal.GetValueToInt( ConstString.PIOTimeOut );
  1188. result = this.refObjects.Clamp.Unlock_Sync();
  1189. if ( result != 0 )
  1190. {
  1191. this.OccurVehicleAlarm( result );
  1192. return result;
  1193. }
  1194. if ( this.refObjects.Conveyor.IsInverterError() )
  1195. return 16;
  1196. if ( !this.refObjects.Conveyor.IsLifterPositinCheck() )
  1197. return 14;
  1198. //Todo: Sensor Setting 이 후 주석 풀기.
  1199. //if ( !this.IsLifterDuplication() )
  1200. //{
  1201. // this.OnFailReport?.Invoke( eFailCode.Load_PortHasNotCarrier );
  1202. // return 0;
  1203. //}
  1204. if ( this.refObjects.Conveyor.IsDetectedCenter() )
  1205. {
  1206. this.OnFailReport?.Invoke( eFailCode.Load_VehicleHasCarrier );
  1207. return 0;
  1208. }
  1209. PIOClear();
  1210. loggerPIO.I( $"Start Load PIO - [{targetName}]" );
  1211. this.OnPIOStart?.Invoke( true );
  1212. this.refObjects.IO.WriteOutputIO( "OUT_PIO_RECEIVABLE", true );
  1213. loggerPIO.I( "[Vehicle] - 4 Receivable" );
  1214. if ( !this.refObjects.IO.WaitChangeInputIO( true, pioTimeout, "IN_PIO_SENDABLE" ) )
  1215. {
  1216. PIOClear();
  1217. loggerPIO.E( "[Port] - 4 Ready Time Out" );
  1218. this.OnFailReport?.Invoke( eFailCode.LoadPIOInterlockTimeout );
  1219. return 0;
  1220. }
  1221. loggerPIO.E( "[Port] - 4 Ready On" );
  1222. //this.conveyor.SetConveyorSpeed( true );
  1223. this.refObjects.Conveyor.OnOffConveyor( true, true );
  1224. this.refObjects.IO.WriteOutputIO( "OUT_PIO_RECEIVE_RUN", true, 1000 ); //1Sec 이후 On
  1225. loggerPIO.I( "[Vehicle] - Conveyor Run" );
  1226. this.OnConveyorStart?.Invoke( true );
  1227. if ( !this.refObjects.IO.WaitChangeInputIO( true, pioTimeout, "IN_PIO_SEND_RUN" ) )
  1228. {
  1229. this.refObjects.Conveyor.OnOffConveyor( false, true );
  1230. PIOClear();
  1231. loggerPIO.E( "[Port] - 5 Sending Run Time Out" );
  1232. this.OnFailReport?.Invoke( eFailCode.LoadPIOInterlockTimeout );
  1233. return 0;
  1234. }
  1235. loggerPIO.I( "[Port] - 5 Sending Run On" );
  1236. bool isStartDetected = false;
  1237. var sTime = SwUtils.CurrentTimeMillis;
  1238. while ( true )
  1239. {
  1240. LockUtils.Wait( 10 );
  1241. if ( SwUtils.Gt( sTime, 20 * ConstUtils.ONE_SECOND ) )
  1242. {
  1243. PIOClear();
  1244. this.refObjects.Conveyor.OnOffConveyor( false, true );
  1245. loggerPIO.E( "[Vehicle] Conveyor Wait Time Out" );
  1246. this.OnFailReport?.Invoke( eFailCode.LoadPIOInterlockTimeout );
  1247. if ( this.refObjects.Conveyor.IsDetectedLoadStart() ) // 감지가 시작 되었으면 이동중 Error 로 판단 설비를 정지 상태로
  1248. return 10; //Conveyor Moving Timeout
  1249. else
  1250. return 0;
  1251. }
  1252. if ( this.refObjects.Conveyor.IsDetectedLoadStart() && !isStartDetected )
  1253. isStartDetected = true;
  1254. if ( !this.refObjects.Conveyor.IsDetectedLoadStart() && isStartDetected ) { }
  1255. //this.conveyor.SetConveyorSpeed( false );
  1256. if ( this.refObjects.Conveyor.IsDetectedLoadStop() ) break;
  1257. if ( this.refObjects.Conveyor.IsPIOInterLockOn() )
  1258. {
  1259. PIOClear();
  1260. this.refObjects.Conveyor.OnOffConveyor( false ); //Stop
  1261. loggerPIO.E( "[Port] PIO InterLock On " );
  1262. return 19; //
  1263. }
  1264. }
  1265. if ( this.refObjects.Conveyor.IsDetectedCenter() )
  1266. this.OnCarrierDetected?.Invoke( true );
  1267. this.refObjects.Conveyor.OnOffConveyor( false ); //Stop
  1268. PIOClear();
  1269. this.OnConveyorStop?.Invoke( true );
  1270. loggerPIO.I( "[Vehicle] Conveyor Stop" );
  1271. this.refObjects.IO.WriteOutputIO( "OUT_PIO_RECIVE_COMPLITE", true );
  1272. loggerPIO.I( "[Vehicle] Receive Complete On" );
  1273. if ( !this.refObjects.IO.WaitChangeInputIO( true, pioTimeout, "IN_PIO_SEND_COMPLITE" ) )
  1274. {
  1275. this.refObjects.IO.WriteOutputIO( "OUT_PIO_RECIVE_COMPLITE", false );
  1276. loggerPIO.E( "[Port] IN_PIO_SEND_COMPLITE On Time Out" );
  1277. }
  1278. loggerPIO.I( "[Port] Send Complete On" );
  1279. this.refObjects.IO.WriteOutputIO( "OUT_PIO_RECIVE_COMPLITE", false, 1000 );
  1280. loggerPIO.I( $"End Load PIO - [{targetName}]" );
  1281. result = this.refObjects.Clamp.Lock_Sync();
  1282. if ( result != 0 )
  1283. {
  1284. this.OccurVehicleAlarm( result );
  1285. return result;
  1286. }
  1287. #endif
  1288. return 0;
  1289. }
  1290. public int PIOAndUnload( string targetName )
  1291. {
  1292. #if SIMULATION
  1293. PIOClear();
  1294. loggerPIO.I( $"Start Unload PIO - [{targetName}]" );
  1295. this.OnPIOStart?.Invoke( false );
  1296. Thread.Sleep( 1000 );
  1297. this.refObjects.IO.WriteOutputIO( "OUT_PIO_READY", true );
  1298. loggerPIO.I( "[Vehicle] - 1 Ready On" );
  1299. Thread.Sleep( 1000 );
  1300. this.OnConveyorStart?.Invoke( false );
  1301. Thread.Sleep( 10000 );
  1302. this.refObjects.Conveyor.OnOffConveyor( false ); //Stop
  1303. this.OnConveyorStop?.Invoke( false );
  1304. PIOClear();
  1305. Thread.Sleep( 1000 );
  1306. this.OnUnloadComplete?.Invoke();
  1307. #else
  1308. this.PIOSensorOn();
  1309. LockUtils.Wait( 500 );
  1310. int result = 0;
  1311. var pioTimeout = sql.ConfigDal.GetValueToInt( ConstString.PIOTimeOut );
  1312. if ( this.refObjects.Conveyor.IsInverterError() )
  1313. return 16;
  1314. //if ( this.refObjects.Conveyor.IsLifterDuplication() )
  1315. //{
  1316. // this.OnFailReport?.Invoke( eFailCode.Unload_PortHasCarrier );
  1317. // return 0;
  1318. //}
  1319. if ( !this.refObjects.Conveyor.IsDetectedCenter() )
  1320. {
  1321. this.OnFailReport?.Invoke( eFailCode.Unload_VehicleHasNotCarrier );
  1322. return 0;
  1323. }
  1324. if ( !this.refObjects.Conveyor.IsLifterPositinCheck() )
  1325. return 13;
  1326. PIOClear();
  1327. loggerPIO.I( $"Start Unload PIO - [{targetName}]" );
  1328. this.OnPIOStart?.Invoke( false );
  1329. if ( !this.refObjects.IO.IsOn( "IN_PIO_READY" ) )
  1330. {
  1331. loggerPIO.E( "[Port] - 1 Ready not On" );
  1332. this.OnFailReport?.Invoke( eFailCode.UnlaodPIOInterlockTimeout );
  1333. return 0;
  1334. }
  1335. this.refObjects.IO.WriteOutputIO( "OUT_PIO_READY", true );
  1336. loggerPIO.I( "[Vehicle] - 1 Ready On" );
  1337. if ( !this.refObjects.IO.WaitChangeInputIO( true, pioTimeout, "IN_PIO_RECEIVE_RUN" ) )
  1338. {
  1339. PIOClear();
  1340. loggerPIO.E( "[Port] - 2 Receive CV Run Timeout" );
  1341. this.OnFailReport?.Invoke( eFailCode.UnlaodPIOInterlockTimeout );
  1342. return 0;
  1343. }
  1344. loggerPIO.E( "[Port] - 2 Receive CV Run On" );
  1345. result = this.refObjects.Clamp.Unlock_Sync();
  1346. if ( result != 0 )
  1347. {
  1348. this.OccurVehicleAlarm( result );
  1349. return result;
  1350. }
  1351. this.refObjects.IO.WriteOutputIO( "OUT_PIO_SENDING_RUN", true );
  1352. loggerPIO.I( "[Vehicle] - 2 Send Run On" );
  1353. //this.conveyor.SetConveyorSpeed( true );
  1354. this.refObjects.Conveyor.OnOffConveyor( true );
  1355. this.OnConveyorStart?.Invoke( false );
  1356. var sTime = SwUtils.CurrentTimeMillis;
  1357. while ( true )
  1358. {
  1359. if ( SwUtils.Gt( sTime, 20 * ConstUtils.ONE_SECOND ) )
  1360. {
  1361. PIOClear();
  1362. this.refObjects.Conveyor.OnOffConveyor( false, true );
  1363. loggerPIO.E( "[Port] Conveyor Wait Time Out" );
  1364. this.OnFailReport?.Invoke( eFailCode.UnlaodPIOInterlockTimeout );
  1365. if ( this.refObjects.Conveyor.IsDetectedLoadStart() || this.refObjects.Conveyor.IsDetectedCenter() ) //중간에 걸려 있다고 생각해서 알람 처리.
  1366. return 12; //Conveyor Moving Timeout
  1367. else
  1368. return 0;
  1369. }
  1370. if ( !this.refObjects.Conveyor.IsDetectedLoadStart() && !this.refObjects.Conveyor.IsDetectedCenter() )
  1371. {
  1372. if ( this.refObjects.IO.IsOn( "IN_PIO_RECEIVE_COMPLITE" ) )
  1373. {
  1374. loggerPIO.I( "[Port] - 3 Receive Complete On" );
  1375. break;
  1376. }
  1377. }
  1378. }
  1379. if ( !this.refObjects.Conveyor.IsDetectedCenter() )
  1380. this.OnCarrierDetected?.Invoke( false );
  1381. this.refObjects.Conveyor.OnOffConveyor( false ); //Stop
  1382. this.OnConveyorStop?.Invoke( false );
  1383. PIOClear();
  1384. this.refObjects.IO.WriteOutputIO( "OUT_PIO_SEND_COMPLITE", true );
  1385. Thread.Sleep( 1000 );
  1386. this.refObjects.IO.WriteOutputIO( "OUT_PIO_SEND_COMPLITE", false );
  1387. loggerPIO.I( "[Vehicle] - 3 Send Complete OnOff" );
  1388. #endif
  1389. loggerPIO.I( $"End Unload PIO - [{targetName}]" );
  1390. return 0;
  1391. }
  1392. void PIOClear()
  1393. {
  1394. 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" };
  1395. pio.FwEach( x => { this.refObjects.IO.OutputOff( x ); } );
  1396. }
  1397. #endregion
  1398. #endregion
  1399. #region Help Method
  1400. /// <summary>
  1401. /// 현재 Point 가 변경될때 장애물 감지 센서의 패턴을 변경한다.
  1402. /// </summary>
  1403. /// <param name="v"></param>
  1404. private void ObstaclePatternChange( int v )
  1405. {
  1406. if ( !RouteManager.Instance.Segments.Any( s => s.ID == v ) )
  1407. {
  1408. logger.E( "Current Tag Not Exist RouteManager Point List" );
  1409. return;
  1410. }
  1411. //Todo: 현재 Segment ID 를 가져 와서 변경하는 방식으로 변경 필요.
  1412. var obstacle = RouteManager.Instance.Obstacles.Where( o => o.segmentID == v ).Single();
  1413. this.ChgObstacleDetectPattern( obstacle.fieldset );
  1414. }
  1415. /// <summary>
  1416. /// 현재 좌표 값이 등록된 Route 에 맞는 위치인지 확인한다.
  1417. /// 판단 기준은 Route 에 Tolerance 범위를 사용.
  1418. /// </summary>
  1419. /// <param name="route"></param>
  1420. /// <param name="currentPosition"></param>
  1421. /// <returns></returns>
  1422. bool CorrectPosition( Route route, double currentPosition )
  1423. {
  1424. var rScale = route.ScaleValue;
  1425. var rTolerance = route.ScaleTolerance;
  1426. var result = currentPosition - rScale;
  1427. if ( rTolerance < Math.Abs( result ) )
  1428. return false;
  1429. return true;
  1430. }
  1431. /// <summary>
  1432. /// if no is zero, Laser Off
  1433. /// bit Off, On, On, On,On Area1
  1434. /// </summary>
  1435. /// <param name="no"> 0 == Off Laser</param>
  1436. /// <returns></returns>
  1437. public bool ChgObstacleDetectPattern( int no )
  1438. {
  1439. var bitArray = BitUtils.ChgBitArray( no );
  1440. int bitIndex = 0;
  1441. this.obstacleBitList.ForEach( b =>
  1442. {
  1443. if ( bitArray[bitIndex] )
  1444. this.refObjects.IO.OutputOff( b );
  1445. else
  1446. this.refObjects.IO.OutputOn( b );
  1447. bitIndex++;
  1448. } );
  1449. ObstaclePattern = no;
  1450. return true;
  1451. }
  1452. public int GetObstacleDetectPattern()
  1453. {
  1454. int bitIndex = 0;
  1455. BitArray bitArray = new BitArray( this.obstacleBitList.Count );
  1456. this.obstacleBitList.ForEach( b =>
  1457. {
  1458. if ( this.refObjects.IO.IsOn( b, false ) )
  1459. bitArray.Set( bitIndex, false );
  1460. else
  1461. bitArray.Set( bitIndex, true );
  1462. bitIndex++;
  1463. } );
  1464. return BitUtils.ChgInt32( bitArray );
  1465. }
  1466. /// <summary>
  1467. /// Vehicle 이동 및 동작 중 Alarm 발생 시 처리
  1468. /// </summary>
  1469. /// <param name="alarmID"></param>
  1470. public void OccurVehicleAlarm( int alarmID )
  1471. {
  1472. this.MachineMode = eMachineMode.LocalMode;
  1473. this.VehicleStateProperty = eVehicleState.Abnormal;
  1474. this.ConveyorOff();
  1475. this.autoManager.ProcessAlarm( alarmID );
  1476. }
  1477. public void SetObstaclePattern( ObstacleControlEventArgs.eControlKind state, int value )
  1478. {
  1479. if ( state == ObstacleControlEventArgs.eControlKind.DRIVE )
  1480. {
  1481. this.ObstacleDrive = value;
  1482. ChgObstacleDetectPattern( this.ObstacleDrive );
  1483. }
  1484. else if ( state == ObstacleControlEventArgs.eControlKind.CURVE )
  1485. {
  1486. this.ObstacleCurve = value;
  1487. ChgObstacleDetectPattern( this.ObstacleCurve );
  1488. }
  1489. else
  1490. return;
  1491. }
  1492. public eSteeringState GetESteeringState() => this.refObjects.Steering.GetSteeringState();
  1493. #endregion
  1494. #region Event Subscribe
  1495. private void BMUManager_OnDisconnect( string obj )
  1496. {
  1497. this.BatteryIsConnect = false;
  1498. this.OccurVehicleAlarm( 32 );
  1499. }
  1500. private void BMUManager_OnConnect( string obj )
  1501. {
  1502. this.BatteryIsConnect = true;
  1503. //ReqCurrentPos();
  1504. }
  1505. private void BMUManager_OnFirstColtd( List<ReceivedData> obj )
  1506. {
  1507. }
  1508. private void BMUManager_OnChangedReceivedData( Serial.DataModel.ReceivedData obj )
  1509. {
  1510. var kind = CastTo<eDataKind>.From<Enum>( obj.DataKind );
  1511. switch ( kind )
  1512. {
  1513. case eDataKind.Voltage:
  1514. //this.BatteryVoltage = (double)obj.Value * obj.Scale;
  1515. this.BatteryVoltage = (double)obj.Value;
  1516. break;
  1517. case eDataKind.Current:
  1518. this.BatteryCurrent = (double)obj.Value;
  1519. break;
  1520. case eDataKind.BatteryState:
  1521. if ( obj.Value == null )
  1522. return;
  1523. this.BatteryState = (double)obj.Value;
  1524. break;
  1525. case eDataKind.ChargeCompleteTime:
  1526. if ( obj.Value == null /*|| obj.Value <= 0 */)
  1527. return;
  1528. //this.BatteryChargeTime = (double)obj.Value / obj.Scale;
  1529. this.BatteryChargeTime = (double)obj.Value;
  1530. break;
  1531. case eDataKind.DisChargeCompleteTime:
  1532. if ( obj.Value == null || obj.Value <= 0 )
  1533. return;
  1534. //this.BatteryDisChargeTime = (double)obj.Value / obj.Scale;
  1535. this.BatteryDisChargeTime = (double)obj.Value;
  1536. break;
  1537. case eDataKind.SOC:
  1538. this.BatteryStateOfCharge = (double)obj.Value;
  1539. break;
  1540. case eDataKind.SOH:
  1541. this.BatteryStateOfHealth = (double)obj.Value;
  1542. break;
  1543. case eDataKind.ResidualCapacity:
  1544. this.BatteryCapacity = (double)obj.Value;
  1545. break;
  1546. case eDataKind.ResidualEnergy:
  1547. this.BatteryEnergy = (double)obj.Value;
  1548. break;
  1549. case eDataKind.Temperature:
  1550. this.BatteryTemperature = (double)obj.Value;
  1551. break;
  1552. default:
  1553. break;
  1554. }
  1555. }
  1556. private void AutoManager_OnOperationModeChanged( eOperatationMode obj )
  1557. {
  1558. this.refObjects.Drive.SetDriveOperationMode( obj );
  1559. }
  1560. private void ZmqManager_PropertyChanged( object sender, System.ComponentModel.PropertyChangedEventArgs e )
  1561. {
  1562. var property = sender.GetType().GetProperty( e.PropertyName );
  1563. var newValue = property.GetValue( sender, null );
  1564. switch ( e.PropertyName )
  1565. {
  1566. case "SegmentID":
  1567. {
  1568. var v = CastTo<int>.From<object>( newValue );
  1569. this.ObstaclePatternChange( v );
  1570. }
  1571. break;
  1572. case "RequestSteering":
  1573. {
  1574. var v = CastTo<eSteeringState>.From<object>( newValue );
  1575. switch ( v )
  1576. {
  1577. case eSteeringState.None:
  1578. break;
  1579. case eSteeringState.Left:
  1580. this.refObjects.Steering.ControlSteering( true );
  1581. break;
  1582. case eSteeringState.Right:
  1583. this.refObjects.Steering.ControlSteering();
  1584. break;
  1585. default:
  1586. break;
  1587. }
  1588. }
  1589. break;
  1590. case "CurrentPointNo":
  1591. {
  1592. var v = CastTo<int>.From<object>( newValue );
  1593. logger.D( $"{this.CurrentTag} -> {v}" );
  1594. this.CurrentTag = v;
  1595. }
  1596. break;
  1597. case "RearDriveState":
  1598. {
  1599. var v = CastTo<DriveState>.From<object>( newValue );
  1600. this.RearDriveState = v;
  1601. }
  1602. break;
  1603. case "FrontLoadFactor":
  1604. {
  1605. var v = CastTo<double>.From<object>( newValue );
  1606. this.FrontLoadFactor = v;
  1607. this.FrontTorque = Math.Truncate( ( ( v * 1.9 ) / 1000 ) * 100 ) / 100;
  1608. }
  1609. break;
  1610. case "FrontRPM":
  1611. {
  1612. var v = CastTo<double>.From<object>( newValue );
  1613. this.FrontRpm = v;
  1614. var ll = ( ( ( ( v / 60 ) * ( 2 * Math.PI ) ) * 0.06 ) / 10 );
  1615. this.FrontSpeed = Math.Truncate( ll * 100 ) / 100;
  1616. }
  1617. break;
  1618. case "RearLoadFactor":
  1619. {
  1620. var v = CastTo<double>.From<object>( newValue );
  1621. this.RearLoadFactor = v;
  1622. this.RearTorque = Math.Truncate( ( ( v * 1.9 ) / 1000 ) * 100 ) / 100;
  1623. }
  1624. break;
  1625. case "RearRPM":
  1626. {
  1627. var v = CastTo<double>.From<object>( newValue );
  1628. this.RearRpm = v;
  1629. var ll = ( ( ( ( v / 60 ) * ( 2 * Math.PI ) ) * 0.06 ) / 10 );
  1630. this.RearSpeed = Math.Truncate( ll * 100 ) / 100;
  1631. }
  1632. break;
  1633. default:
  1634. break;
  1635. }
  1636. }
  1637. private void Motion_PropertyChanged( object sender, System.ComponentModel.PropertyChangedEventArgs e )
  1638. {
  1639. var property = sender.GetType().GetProperty( e.PropertyName );
  1640. var newValue = property.GetValue( sender, null );
  1641. switch ( e.PropertyName )
  1642. {
  1643. case "CurrentPos":
  1644. {
  1645. var v = CastTo<double>.From<object>( newValue );
  1646. this.CurrentPosition = v;
  1647. }
  1648. break;
  1649. //case "CurrentTag":
  1650. // {
  1651. // var v = CastTo<int>.From<object>( newValue );
  1652. // logger.D( $"{this.CurrentTag} -> {v}" );
  1653. // this.CurrentTag = v;
  1654. // }
  1655. // break;
  1656. case "CurrentSpeed":
  1657. {
  1658. var v = CastTo<double>.From<object>( newValue );
  1659. this.CurrentSpeed = v;
  1660. }
  1661. break;
  1662. case "CurrentTorque":
  1663. {
  1664. var v = CastTo<double>.From<object>( newValue );
  1665. this.CurrentTorque = v;
  1666. }
  1667. break;
  1668. case "ReqSteeringState":
  1669. //{
  1670. // var v = CastTo<eSteeringState>.From<object>( newValue );
  1671. // switch ( v )
  1672. // {
  1673. // case eSteeringState.None:
  1674. // break;
  1675. // case eSteeringState.Left:
  1676. // this.refObjects.Steering.ControlSteering( true );
  1677. // break;
  1678. // case eSteeringState.Right:
  1679. // this.refObjects.Steering.ControlSteering();
  1680. // break;
  1681. // default:
  1682. // break;
  1683. // }
  1684. //}
  1685. break;
  1686. case "DriveServoState":
  1687. {
  1688. var v = CastTo<eDriveServoState>.From<object>( newValue );
  1689. if ( v == eDriveServoState.ServoOn )
  1690. this.refObjects.IO.OutputOn( "OUT_DRIVE_BRAKE_OFF" );
  1691. else
  1692. this.refObjects.IO.OutputOff( "OUT_DRIVE_BRAKE_OFF" );
  1693. }
  1694. break;
  1695. case "FrontDriveState":
  1696. {
  1697. var v = CastTo<DriveState>.From<object>( newValue );
  1698. this.FrontDriveState = v;
  1699. }
  1700. break;
  1701. case "RearDriveState":
  1702. {
  1703. var v = CastTo<DriveState>.From<object>( newValue );
  1704. this.RearDriveState = v;
  1705. }
  1706. break;
  1707. //case "FrontLoadFactor":
  1708. // {
  1709. // var v = CastTo<double>.From<object>( newValue );
  1710. // this.FrontLoadFactor = v;
  1711. // this.FrontTorque = Math.Truncate( ( ( v * 1.9 ) / 1000 ) * 100 ) / 100;
  1712. // }
  1713. // break;
  1714. //case "FrontRpm":
  1715. // {
  1716. // var v = CastTo<double>.From<object>( newValue );
  1717. // this.FrontRpm = v;
  1718. // var ll = ( ( ( ( v / 60 ) * ( 2 * Math.PI ) ) * 0.06 ) / 10 );
  1719. // this.FrontSpeed = Math.Truncate( ll * 100 ) / 100;
  1720. // }
  1721. // break;
  1722. //case "RearLoadFactor":
  1723. // {
  1724. // var v = CastTo<double>.From<object>( newValue );
  1725. // this.RearLoadFactor = v;
  1726. // this.RearTorque = Math.Truncate( ( ( v * 1.9 ) / 1000 ) * 100 ) / 100;
  1727. // }
  1728. // break;
  1729. //case "RearRpm":
  1730. // {
  1731. // var v = CastTo<double>.From<object>( newValue );
  1732. // this.RearRpm = v;
  1733. // var ll = ( ( ( ( v / 60 ) * ( 2 * Math.PI ) ) * 0.06 ) / 10 );
  1734. // this.RearSpeed = Math.Truncate( ll * 100 ) / 100;
  1735. // }
  1736. break;
  1737. default:
  1738. break;
  1739. }
  1740. }
  1741. private void Steering_PropertyChanged( object sender, System.ComponentModel.PropertyChangedEventArgs e )
  1742. {
  1743. var property = sender.GetType().GetProperty( e.PropertyName );
  1744. var newValue = property.GetValue( sender, null );
  1745. //Todo: 나중에 Test 하자
  1746. //var ownPropperty = this.GetType().GetProperty(e.PropertyName);
  1747. if ( e.PropertyName.Equals( "SteeringState" ) )
  1748. {
  1749. var v = CastTo<eSteeringState>.From<object>( newValue );
  1750. this.SteeringState = v;
  1751. logger.D( $"steering - {v}" );
  1752. }
  1753. }
  1754. private void Clamp_PropertyChanged( object sender, System.ComponentModel.PropertyChangedEventArgs e )
  1755. {
  1756. var property = sender.GetType().GetProperty( e.PropertyName );
  1757. var newValue = property.GetValue( sender, null );
  1758. if ( e.PropertyName.Equals( "ClampState" ) )
  1759. {
  1760. var v = CastTo<eClampState>.From<object>( newValue );
  1761. this.ClampState = v;
  1762. }
  1763. }
  1764. private void IO_OnChangedIO( BitBlock bit )
  1765. {
  1766. switch ( bit.Tag )
  1767. {
  1768. case "IN_CV_DETECT_01":
  1769. this.IsContain = bit.IsBitOn;
  1770. break;
  1771. case "IN_MC_ON":
  1772. if ( bit.IsBitOn )
  1773. {
  1774. if ( !this.refObjects.IO.IsOn( "IN_EMS_SW" ) && this.refObjects.IO.IsOn( "IN_CP_ON_SAFETY" ) && this.refObjects.IO.IsOn( "IN_CP_ON_24V" ) )
  1775. this.VehicleStateProperty = eVehicleState.Idle;
  1776. }
  1777. else
  1778. this.OccurVehicleAlarm( 29 );
  1779. break;
  1780. case "IN_EMS_SW":
  1781. if ( bit.IsBitOn )
  1782. this.OccurVehicleAlarm( 28 );
  1783. break;
  1784. case "IN_CP_ON_SAFETY":
  1785. if ( !bit.IsBitOn )
  1786. this.OccurVehicleAlarm( 31 );
  1787. break;
  1788. case "IN_CP_ON_24V":
  1789. if ( !bit.IsBitOn )
  1790. this.OccurVehicleAlarm( 30 );
  1791. break;
  1792. case "IN_OBSTRUCTION_DETECT_ERROR":
  1793. case "IN_OBSTRUCTION_DETECT_SAFETY":
  1794. case "IN_OBSTRUCTION_DETECT_STOP":
  1795. case "IN_OBSTRUCTION_DETECT_SLOW":
  1796. CheckObstacle();
  1797. break;
  1798. default:
  1799. break;
  1800. }
  1801. }
  1802. private void Steering_OnSteeringError( object sender, int e )
  1803. {
  1804. if ( e != 0 )
  1805. {
  1806. logger.E( $"[Steering] - Control Error {e}" );
  1807. this.OccurVehicleAlarm( e );
  1808. }
  1809. else
  1810. {
  1811. var msg = new DriveControlEventArgs()
  1812. {
  1813. EventDir = DriveControlEventArgs.eEventDir.ToFront,
  1814. ControlKind = DriveControlEventArgs.eControlKind.Steering,
  1815. Result = FluentResults.Results.Ok<DriveControlEventArgs.eMoveDir>( DriveControlEventArgs.eMoveDir.LEFT ),
  1816. };
  1817. this.eventAggregator.GetEvent<DriveControlPubSubEvent>().Publish( msg );
  1818. }
  1819. }
  1820. #endregion
  1821. }
  1822. }