RfPowerBase.cs 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Runtime.Serialization;
  5. using System.Text;
  6. using System.Threading.Tasks;
  7. using System.Xml;
  8. using Aitex.Core.Common.DeviceData;
  9. using Aitex.Core.RT.DataCenter;
  10. using Aitex.Core.RT.Device;
  11. using Aitex.Core.RT.Event;
  12. using Aitex.Core.RT.OperationCenter;
  13. using Aitex.Core.RT.SCCore;
  14. using Aitex.Core.RT.Tolerance;
  15. using Aitex.Core.Util;
  16. using MECF.Framework.Common.CommonData;
  17. namespace MECF.Framework.Common.Device.Bases
  18. {
  19. public abstract class RfPowerBase : BaseDevice, IDevice
  20. {
  21. public virtual bool IsConnected => true;
  22. public virtual bool IsPowerOn { get; set; }
  23. public virtual bool IsSetPowerOn { get; set; }
  24. public virtual bool IsError { get; set; }
  25. public virtual bool IsHighFrequentQueryMode { get; set; }
  26. public virtual EnumRfPowerClockMode ClockMode { get; set; }
  27. public virtual EnumRfPowerWorkMode WorkMode { get; set; }
  28. public virtual EnumRfPowerRegulationMode RegulationMode { get; set; }
  29. public virtual float ForwardPower { get; set; }
  30. public virtual float ReflectPower { get; set; }// 硬件反馈,反射功率
  31. public virtual float PowerSetPoint
  32. {
  33. get
  34. {
  35. return _PowerSetPoint;
  36. }
  37. set
  38. {
  39. if (value.LessThanOrEqual(0))
  40. {
  41. _originalPowerSetPoint = 0;
  42. _PowerSetPoint = 0;
  43. }
  44. else
  45. {
  46. _originalPowerSetPoint = value;
  47. _PowerSetPoint = CalibrationData(value, true);
  48. }
  49. }
  50. }
  51. protected float _originalPowerSetPoint = 0;
  52. protected float _PowerSetPoint; // 下发到硬件
  53. public virtual float Frequency { get; set; }
  54. public virtual float PulsingFrequency { get; set; }
  55. public virtual float PulsingDutyCycle { get; set; }
  56. public virtual float PulsingReverseTime { get; set; }
  57. public virtual AITRfPowerData DeviceData { get; set; }
  58. private float _currentWarningRange;
  59. private float _currentAlarmRange;
  60. protected SCConfigItem _scEnableAlarm;
  61. protected SCConfigItem _scAlarmTime;
  62. protected SCConfigItem _scAlarmRange;
  63. protected SCConfigItem _scWarningTime;
  64. protected SCConfigItem _scWarningRange;
  65. protected SCConfigItem _scReflectedPowerMonitorTime;
  66. protected SCConfigItem _scRecipeIgnoreTime;
  67. protected SCConfigItem _scPowerScale;
  68. protected ToleranceChecker _toleranceAlarmChecker = new ToleranceChecker();
  69. protected ToleranceChecker _toleranceWarningChecker = new ToleranceChecker();
  70. protected ToleranceChecker _prThresholdChecker = new ToleranceChecker();
  71. protected double _currentFineTuningValue;
  72. protected SCConfigItem _scFineTuningEnable;
  73. protected SCConfigItem _scFineTuningValue;
  74. protected float _PrThreshold;
  75. protected DeviceTimer _recipeIgnoreTimer = new DeviceTimer();
  76. protected DeviceTimer _rampTimer = new DeviceTimer();
  77. protected float _rampTarget;
  78. protected float _rampInitValue;
  79. protected int _rampTime;//unit ms
  80. private DeviceTimer _rampInternalTimer = new DeviceTimer();
  81. private readonly int _rampInterval = 200;
  82. //calibration
  83. protected SCConfigItem _scEnableCalibration;
  84. protected SCConfigItem _scCalibrationTable;
  85. private List<CalibrationItem> _calibrationTable = new List<CalibrationItem>();
  86. private string _previousSetting;
  87. public virtual bool EnableAlarm
  88. {
  89. get
  90. {
  91. if (_scEnableAlarm != null)
  92. return _scEnableAlarm.BoolValue;
  93. return false;
  94. }
  95. }
  96. public virtual double AlarmTime
  97. {
  98. get
  99. {
  100. if (_scAlarmTime != null)
  101. return _scAlarmTime.DoubleValue;
  102. return 0;
  103. }
  104. }
  105. public virtual double AlarmRange
  106. {
  107. get
  108. {
  109. if (_currentAlarmRange > 0)
  110. return _currentAlarmRange;
  111. if (_scAlarmRange != null)
  112. return _scAlarmRange.DoubleValue;
  113. return 0;
  114. }
  115. }
  116. public virtual double WarningTime
  117. {
  118. get
  119. {
  120. if (_scWarningTime != null)
  121. return _scWarningTime.DoubleValue;
  122. return 0;
  123. }
  124. }
  125. public virtual double WarningRange
  126. {
  127. get
  128. {
  129. if (_currentWarningRange > 0)
  130. return _currentWarningRange;
  131. if (_scWarningRange != null)
  132. return _scWarningRange.DoubleValue;
  133. return 0;
  134. }
  135. }
  136. //unit second
  137. public virtual double PrThresholdMonitorTime
  138. {
  139. get
  140. {
  141. if (_scReflectedPowerMonitorTime != null)
  142. return _scReflectedPowerMonitorTime.DoubleValue;
  143. return 0;
  144. }
  145. }
  146. //unit second
  147. public virtual double RecipeIgnoreTime
  148. {
  149. get
  150. {
  151. if (_scRecipeIgnoreTime != null)
  152. return _scRecipeIgnoreTime.DoubleValue;
  153. return 0;
  154. }
  155. }
  156. public virtual double FineTuningValue
  157. {
  158. get
  159. {
  160. if (_scFineTuningEnable == null || !_scFineTuningEnable.BoolValue)
  161. return 1;
  162. if (_currentFineTuningValue != 0)
  163. return 1 + _currentFineTuningValue / 100;
  164. return _scFineTuningValue != null ? 1 + _scFineTuningValue.DoubleValue / 100 : 1;
  165. }
  166. }
  167. public virtual int PowerRange
  168. {
  169. get
  170. {
  171. if (_scPowerScale == null)
  172. return 1000;
  173. return _scPowerScale.IntValue;
  174. }
  175. }
  176. protected RfPowerBase(string module, string name) : base(module, name, name, name)
  177. {
  178. _scEnableAlarm = SC.GetConfigItem($"{Module}.{Name}.EnableAlarm");
  179. _scAlarmTime = SC.GetConfigItem($"{Module}.{Name}.AlarmTime");
  180. _scAlarmRange = SC.GetConfigItem($"{Module}.{Name}.AlarmRange");
  181. _scWarningTime = SC.GetConfigItem($"{Module}.{Name}.WarningTime");
  182. _scWarningRange = SC.GetConfigItem($"{Module}.{Name}.WarningRange");
  183. _scReflectedPowerMonitorTime = SC.GetConfigItem($"{Module}.{Name}.ReflectedPowerMonitorTime");
  184. _scEnableCalibration = SC.GetConfigItem($"{Module}.{Name}.EnableCalibration");
  185. _scCalibrationTable = SC.GetConfigItem($"{Module}.{Name}.CalibrationTable");
  186. _scRecipeIgnoreTime = SC.GetConfigItem($"{Module}.{Name}.RecipeIgnoreTime");
  187. _scFineTuningValue = SC.GetConfigItem($"{Module}.FineTuning.{Name}");
  188. _scFineTuningEnable = SC.GetConfigItem($"{Module}.FineTuning.IsEnable");
  189. }
  190. protected RfPowerBase() : base()
  191. {
  192. }
  193. protected RfPowerBase(string module, string name, XmlElement node = null, string ioModule = "") : base(module, name, name, name)
  194. {
  195. if (node != null)
  196. {
  197. _scEnableAlarm = ParseScNode("scEnableAlarm", node, ioModule, $"{Module}.{Name}.EnableAlarm");
  198. _scAlarmTime = ParseScNode("scAlarmTime", node, ioModule, $"{Module}.{Name}.AlarmTime");
  199. _scAlarmRange = ParseScNode("scAlarmRange", node, ioModule, $"{Module}.{Name}.AlarmRange");
  200. _scWarningTime = ParseScNode("scWarningTime", node, ioModule, $"{Module}.{Name}.WarningTime");
  201. _scWarningRange = ParseScNode("scWarningRange", node, ioModule, $"{Module}.{Name}.WarningRange");
  202. _scRecipeIgnoreTime = ParseScNode("scRecipeIgnoreTime", node, ioModule, $"{Module}.{Name}.RecipeIgnoreTime");
  203. _scReflectedPowerMonitorTime = ParseScNode("scReflectedPowerMonitorTime", node, ioModule, $"{Module}.{Name}.ReflectedPowerMonitorTime");
  204. _scEnableCalibration = ParseScNode("scCalibrationTable", node, ioModule, $"{Module}.{Name}.EnableCalibration");
  205. _scCalibrationTable = ParseScNode("scCalibrationTable", node, ioModule, $"{Module}.{Name}.CalibrationTable");
  206. _scFineTuningValue = ParseScNode("scFineTuningValue", node, ioModule, $"{Module}.FineTuning.{Name}");
  207. _scFineTuningEnable = ParseScNode("scFineTuningEnable", node, ioModule, $"{Module}.FineTuning.IsEnable");
  208. }
  209. }
  210. public virtual bool Initialize()
  211. {
  212. DATA.Subscribe($"{Module}.{Name}.DeviceData", () => DeviceData);
  213. DATA.Subscribe($"{Module}.{Name}.WorkMode", () => WorkMode.ToString());
  214. DATA.Subscribe($"{Module}.{Name}.RegulationMode", () => RegulationMode.ToString());
  215. DATA.Subscribe($"{Module}.{Name}.ForwardPower", () => ForwardPower);
  216. DATA.Subscribe($"{Module}.{Name}.ReflectPower", () => ReflectPower);
  217. DATA.Subscribe($"{Module}.{Name}.PowerSetPoint", () => PowerSetPoint);
  218. DATA.Subscribe($"{Module}.{Name}.Frequency", () => Frequency);
  219. DATA.Subscribe($"{Module}.{Name}.PulsingFrequency", () => PulsingFrequency);
  220. DATA.Subscribe($"{Module}.{Name}.PulsingDutyCycle", () => PulsingDutyCycle);
  221. DATA.Subscribe($"{Module}.{Name}.PulsingReverseTime", () => PulsingReverseTime);
  222. OP.Subscribe($"{Module}.{Name}.SetPowerOn", (function, args) =>
  223. {
  224. if (!SetPowerOnOff(true, out string reason))
  225. {
  226. EV.PostWarningLog(Module, $"{Module} {Name} RF on failed, for {reason}");
  227. return false;
  228. }
  229. return true;
  230. });
  231. OP.Subscribe($"{Module}.{Name}.SetPowerOff", (function, args) =>
  232. {
  233. if (!SetPowerOnOff(false, out string reason))
  234. {
  235. EV.PostWarningLog(Module, $"{Module} {Name} RF off failed, for {reason}");
  236. return false;
  237. }
  238. return true;
  239. });
  240. OP.Subscribe($"{Module}.{Name}.SetPowerOnOff", (function, args) =>
  241. {
  242. if (!SetPowerOnOff(Convert.ToBoolean(args[0].ToString()), out string reason))
  243. {
  244. EV.PostWarningLog(Module, $"{Module} {Name} RF off failed, for {reason}");
  245. return false;
  246. }
  247. return true;
  248. });
  249. OP.Subscribe($"{Module}.{Name}.SetPower", (function, args) =>
  250. {
  251. SetPower(Convert.ToSingle(args[0].ToString()));
  252. return true;
  253. });
  254. OP.Subscribe($"{Module}.{Name}.SetRegulationMode", (function, args) =>
  255. {
  256. if (!Enum.TryParse((string)args[0], out EnumRfPowerRegulationMode mode))
  257. {
  258. EV.PostWarningLog(Module, $"Argument {args[0]}not valid");
  259. return false;
  260. }
  261. SetRegulationMode(mode);
  262. return true;
  263. });
  264. //for recipe
  265. OP.Subscribe($"{Module}.{Name}.SetRFParameters", (out string reason, int time, object[] param) =>
  266. {
  267. reason = string.Empty;
  268. SetRFParameters(param);
  269. return true;
  270. });
  271. //for recipe
  272. OP.Subscribe($"{Module}.{Name}.SetTolerance", (out string reason, int time, object[] param) =>
  273. {
  274. reason = string.Empty;
  275. var warning = Convert.ToSingle(param[0]);
  276. var alarm = Convert.ToSingle(param[1]);
  277. SetTolerance((float)warning, (float)alarm);
  278. return true;
  279. });
  280. //for recipe
  281. OP.Subscribe($"{Module}.{Name}.SetFineTuning", (out string reason, int time, object[] param) =>
  282. {
  283. reason = string.Empty;
  284. SetFineTuning(Convert.ToSingle(param[0]));
  285. return true;
  286. });
  287. InitSc();
  288. UpdateCalibrationTable();
  289. return true;
  290. }
  291. public virtual void InitSc()
  292. {
  293. }
  294. public virtual void SetFineTuning(float fineTuning)
  295. {
  296. _currentFineTuningValue = fineTuning;
  297. }
  298. public virtual void SetTolerance(float warning, float alarm)
  299. {
  300. _currentWarningRange = warning;
  301. _currentAlarmRange = alarm;
  302. _toleranceAlarmChecker.Reset(AlarmTime);
  303. _toleranceWarningChecker.Reset(WarningTime);
  304. if (RecipeIgnoreTime > 0)
  305. _recipeIgnoreTimer.Start(0);
  306. }
  307. public virtual void CheckTolerance()
  308. {
  309. if (!EnableAlarm || PowerSetPoint == 0 || (RecipeIgnoreTime > 0 && _recipeIgnoreTimer.GetElapseTime() < RecipeIgnoreTime * 1000))
  310. return;
  311. _toleranceAlarmChecker.Monitor(ForwardPower, (PowerSetPoint * (1 - AlarmRange / 100)), (PowerSetPoint * (1 + AlarmRange / 100)), AlarmTime);
  312. _toleranceWarningChecker.Monitor(ForwardPower, (PowerSetPoint * (1 - WarningRange / 100)), (PowerSetPoint * (1 + WarningRange / 100)), WarningTime);
  313. if (_PrThreshold > 0)
  314. _prThresholdChecker.Monitor(ReflectPower, 0, _PrThreshold, PrThresholdMonitorTime);
  315. }
  316. public virtual bool CheckToleranceAlarm()
  317. {
  318. if (!EnableAlarm)
  319. return false;
  320. return _toleranceAlarmChecker.Result;
  321. }
  322. public virtual bool CheckToleranceWarning()
  323. {
  324. if (!EnableAlarm)
  325. return false;
  326. return _toleranceWarningChecker.Result;
  327. }
  328. public virtual bool CheckPrThreshold()
  329. {
  330. if (!EnableAlarm)
  331. return false;
  332. return _prThresholdChecker.Result;
  333. }
  334. public virtual void SetRegulationMode(EnumRfPowerRegulationMode enumRfPowerControlMode)
  335. {
  336. }
  337. public virtual void SetWorkMode(EnumRfPowerWorkMode enumRfPowerWorkMode)
  338. {
  339. }
  340. public virtual void SetClockMode(EnumRfPowerClockMode clockMode)
  341. {
  342. }
  343. public virtual bool SetPowerOnOff(bool isOn, out string reason)
  344. {
  345. reason = string.Empty;
  346. return true;
  347. }
  348. public virtual void SetPower(float power)
  349. {
  350. }
  351. public virtual void SetPower(float power, float rampTime, bool isCalibration = false)
  352. {
  353. }
  354. public virtual void SetFreq(float freq)
  355. {
  356. }
  357. public virtual void SetRFParameters(object[] param)
  358. {
  359. }
  360. public virtual void SetPrThreshold(float threshold)
  361. {
  362. _PrThreshold = threshold;
  363. _prThresholdChecker.Reset(PrThresholdMonitorTime);
  364. }
  365. public virtual void SetRampTime(float rampTime)
  366. {
  367. }
  368. public virtual void Terminate()
  369. {
  370. }
  371. public virtual void Monitor()
  372. {
  373. CheckTolerance();
  374. if (_scCalibrationTable != null)
  375. {
  376. if (string.IsNullOrEmpty(_previousSetting) || _previousSetting != _scCalibrationTable.StringValue)
  377. UpdateCalibrationTable();
  378. }
  379. }
  380. public virtual void Reset()
  381. {
  382. }
  383. protected virtual void UpdateCalibrationTable()
  384. {
  385. if (_scCalibrationTable == null)
  386. return;
  387. if (_previousSetting == _scCalibrationTable.StringValue)
  388. return;
  389. _previousSetting = _scCalibrationTable.StringValue;
  390. if (string.IsNullOrEmpty(_previousSetting))
  391. {
  392. _calibrationTable = new List<CalibrationItem>();
  393. return;
  394. }
  395. var table = new List<Tuple<float, float>>();
  396. string[] items = _previousSetting.Split(';');
  397. for (int i = 0; i < items.Length; i++)
  398. {
  399. string itemValue = items[i];
  400. if (!string.IsNullOrEmpty(itemValue))
  401. {
  402. string[] pairValue = itemValue.Split('#');
  403. if (pairValue.Length == 2)
  404. {
  405. if (float.TryParse(pairValue[0], out float rawData)
  406. && float.TryParse(pairValue[1], out float calibrationData))
  407. {
  408. table.Add(Tuple.Create(rawData, calibrationData));
  409. }
  410. }
  411. }
  412. }
  413. table = table.OrderBy(x => x.Item1).ToList();
  414. var calibrationTable = new List<CalibrationItem>();
  415. for (int i = 0; i < table.Count; i++)
  416. {
  417. if (i == 0 && table[0].Item1 > 0.001)
  418. {
  419. calibrationTable.Add(new CalibrationItem()
  420. {
  421. RawFrom = 0,
  422. CalibrationFrom = 0,
  423. RawTo = table[0].Item1,
  424. CalibrationTo = table[0].Item2,
  425. });
  426. }
  427. if (i == table.Count - 1)
  428. {
  429. float maxValue = (float)PowerRange;
  430. calibrationTable.Add(new CalibrationItem()
  431. {
  432. RawFrom = table[i].Item1,
  433. RawTo = table[i].Item2,
  434. CalibrationFrom = maxValue,
  435. CalibrationTo = maxValue,
  436. });
  437. continue;
  438. }
  439. calibrationTable.Add(new CalibrationItem()
  440. {
  441. RawFrom = table[i].Item1,
  442. CalibrationFrom = table[i].Item2,
  443. RawTo = table[i + 1].Item1,
  444. CalibrationTo = table[i + 1].Item2,
  445. });
  446. }
  447. _calibrationTable = calibrationTable;
  448. }
  449. protected virtual float CalibrationData(float value, bool output)
  450. {
  451. if (value.IsZero()) return value;
  452. //default enable
  453. if (_scEnableCalibration != null && !_scEnableCalibration.BoolValue)
  454. return value;
  455. if (_scCalibrationTable == null || !_calibrationTable.Any())
  456. return value;
  457. float ret = value;
  458. if (output)
  459. {
  460. var item = _calibrationTable.FirstOrDefault(x => x.RawFrom <= value && x.RawTo >= value);
  461. if (item != null && Math.Abs(item.RawTo - item.RawFrom) > 0.01)
  462. {
  463. var slope = (item.CalibrationTo - item.CalibrationFrom) / (item.RawTo - item.RawFrom);
  464. ret = (ret - item.RawFrom) * slope + item.CalibrationFrom;
  465. }
  466. }
  467. else
  468. {
  469. var item = _calibrationTable.FirstOrDefault(x => x.CalibrationFrom <= value && x.CalibrationTo >= value);
  470. if (item != null && Math.Abs(item.CalibrationTo - item.CalibrationFrom) > 0.01)
  471. {
  472. var slope = (item.RawTo - item.RawFrom) / (item.CalibrationTo - item.CalibrationFrom);
  473. ret = (ret - item.CalibrationFrom) * slope + item.RawFrom;
  474. }
  475. }
  476. if (ret < 0)
  477. return 0;
  478. if (ret >= float.MaxValue || ret > PowerRange)
  479. ret = value;
  480. return ret;
  481. }
  482. protected void MonitorRamping()
  483. {
  484. if (_originalPowerSetPoint == 0 && Math.Abs(PowerSetPoint - _rampTarget) < 0.000001) return;
  485. if (_rampTimer == null || _rampTime == 0) return;
  486. if (_rampTimer.IsTimeout())
  487. {
  488. if (Math.Abs(PowerSetPoint - _rampTarget) > 0.000001) SetRampPower(_rampTarget);
  489. _rampTimer = null;
  490. }
  491. else
  492. {
  493. float target = (float)(_rampInitValue + (_rampTarget - _rampInitValue) * _rampTimer.GetElapseTime() / _rampTime);
  494. if (_rampInternalTimer.IsIdle())
  495. _rampInternalTimer.Start(_rampInterval);
  496. if (Math.Abs(PowerSetPoint - target) > 0.000001 && _rampInternalTimer.IsTimeout())
  497. {
  498. SetRampPower(target);
  499. _rampInternalTimer.Start(_rampInterval);
  500. }
  501. if (target.GreaterThanOrEqual(_rampTarget))
  502. {
  503. _rampTimer = null;
  504. }
  505. }
  506. }
  507. protected virtual void SetRampPower(float power)
  508. {
  509. }
  510. public virtual void ResetToleranceAlarm()
  511. {
  512. _toleranceAlarmChecker.Reset(AlarmTime);
  513. }
  514. public virtual void ResetToleranceWarning()
  515. {
  516. _toleranceWarningChecker.Reset(WarningTime);
  517. }
  518. public virtual void ResetPrThreshold()
  519. {
  520. _prThresholdChecker.Reset(PrThresholdMonitorTime);
  521. }
  522. }
  523. }