TitrationExecute.cs 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530
  1. using System.Diagnostics;
  2. using System.Runtime.Intrinsics.Arm;
  3. using NPOI.SS.Formula.Eval;
  4. using shjxCamera;
  5. using SHJX.Service.Control.Common.Assets;
  6. namespace SHJX.Service.Control.Execute.TitrationController
  7. {
  8. public class TitrationExecute
  9. {
  10. private static readonly ILogger logger = LogFactory.BuildLogger(typeof(TitrationExecute));
  11. public static bool Running = true;
  12. private static int titrationCount = 0;
  13. private static int slowSpeedCount = 0;
  14. private static int signalTimeLen = 10;
  15. private static int arriveRangeCount = 0; //突跃次数
  16. private static List<ColorDataPoint> currSignals = new(); // 信号队列
  17. private static List<ColorDataPoint> currSignalsCompare = new(); // 信号队列
  18. private static ColorDataGraber _graber = Globals.Graber;
  19. private static double balanceVal = 0;
  20. private static bool IsClean = true;
  21. private static readonly string titrationCamera = "D1_camera";
  22. #region 滴定
  23. /// <summary>
  24. /// 滴定
  25. /// </summary>
  26. /// <param name="rangeValue">阈值</param>
  27. /// <param name="amount">体积</param>
  28. public static void Start(TitrationArg arg, ref double amount)
  29. {
  30. Messager<object>.Send("TitrationStart");
  31. if (Globals.Camera is null)
  32. {
  33. logger.LogDebug("11111111未找到摄像头,无法进行滴定操作");
  34. return;
  35. }
  36. int threshold_gray = 5; // 色点过滤阈值
  37. int threshold_hue = (int)arg.RangeValue; // 色相偏移阈值
  38. int threshold_stable_check = arg.ArriveCheckCount; // 稳定检测时长
  39. //string taskTag = $"{arg.BatchName}/{arg.TaskName}";
  40. //Directory.CreateDirectory($"Data/{taskTag}");
  41. //var csvWriter = new StreamWriter($"Data/{taskTag}.csv");
  42. //csvWriter.Write("滴数,体积,红,绿,蓝,灰度,色调,饱和度,亮度\n");
  43. //csvWriter.Flush();
  44. // 滴定
  45. int titrationCount = 0;
  46. List<ColorPoint> samplePoints = []; // 采样点
  47. logger.LogCritical($"<11111111> 滴定开始(色相偏移阈值: {threshold_hue,2}, 稳定检测时长: {threshold_stable_check})");
  48. // 快速滴定(一般用于标定)
  49. if (arg.WhetherQuicklyTitration)
  50. {
  51. bool quicklyTitrationRes = LiquidPipeSwitchTitration1.StartNew.SetLiquidName(EquipmentNames.Titration1PotassiumPermanganate).CheckWhetherArriveEndPoint().Execute(Convert.ToInt32(Math.Round(arg.QuicklyTitrationValue / arg.LiquidAmount * arg.LiquidConvertRatio)));
  52. if (quicklyTitrationRes)
  53. {
  54. amount += arg.QuicklyTitrationValue;
  55. logger.LogCritical("11111111快速滴定下发成功,等待15秒后继续滴定操作!");
  56. Thread.Sleep(5 * 1000);
  57. }
  58. }
  59. if (!ConfigInstance.IsAutomaticInLiquid)//滴定1有自动吸液,滴定2无自动吸液
  60. {
  61. int distance = Convert.ToInt32(Math.Round(arg.PumpCapacity / arg.LiquidAmount * arg.LiquidConvertRatio));
  62. LiquidPipeSwitchTitration1.StartNew.SetLiquidName(EquipmentNames.Titration1PotassiumPermanganate).CheckWhetherArriveEndPoint().Execute(LiquidSwitchPattern.In, distance);
  63. }
  64. // 滴定前等待
  65. logger.LogCritical($"<11111111> 滴定前等待({arg.BeforeWaitTime}s)");
  66. Thread.Sleep(arg.BeforeWaitTime * 1000);
  67. // 第0滴颜色采样(背景采样)
  68. ColorPoint cp = Globals.Camera.SampleBackground(titrationCamera, threshold_gray, threshold_hue);
  69. if (cp.Hue < 10)
  70. { Messager<object>.Send("TitrationStop");
  71. logger.LogCritical($"<11111111> 采集信号有误,退出滴定"); return; }
  72. logger.LogCritical($"<11111111> 第{titrationCount:D3}滴({amount:F3}), HSB({cp.Hue,3},{cp.Saturation:F3},{cp.Brightness:F3}), RGBL({cp.R,3},{cp.G,3},{cp.B,3},{cp.Gray,3})");
  73. //csvWriter.Write($"{titrationCount:D3},{amount:F3},{cp.R,3},{cp.G,3},{cp.B,3},{cp.Gray,3},{cp.Hue,3},{cp.Saturation:F3},{cp.Brightness:F3}\n");
  74. //csvWriter.Flush();
  75. samplePoints.Add(cp);
  76. Messager<TitrationValueArgs>.Send("TitrationValueChange", new TitrationValueArgs(titrationCount, amount, cp.Hue));
  77. Messager<object>.Send("GraberColorValue", cp.Hue);
  78. while (true)
  79. {
  80. // 达到最大滴定体积,结束滴定
  81. if (amount >= arg.MaxDropVolume)
  82. {
  83. logger.LogCritical($"<11111111> 滴定结束(最大滴定量)");
  84. break;
  85. }
  86. bool arriveEndPoint = LiquidPipeSwitchTitration1.StartNew.SetLiquidName(EquipmentNames.Titration1PotassiumPermanganate).IsArriveEndPoint;
  87. if (arriveEndPoint)
  88. {
  89. int distance = Convert.ToInt32(Math.Round(arg.PumpCapacity / arg.LiquidAmount * arg.LiquidConvertRatio));
  90. LiquidPipeSwitchTitration1.StartNew.SetLiquidName(EquipmentNames.Titration1PotassiumPermanganate).Execute(LiquidSwitchPattern.In, distance);
  91. }
  92. // 滴入试剂
  93. LiquidPipeSwitchTitration1.StartNew.SetLiquidName(EquipmentNames.Titration1PotassiumPermanganate).Execute(LiquidSwitchPattern.Out, arg.LiquidConvertRatio);
  94. titrationCount += 1;
  95. amount += arg.LiquidAmount;
  96. // 第N滴颜色采样
  97. Thread.Sleep(1000);
  98. cp = Globals.Camera.Sample($"11111111/{titrationCount:D3}S", threshold_gray, threshold_hue);
  99. //csvWriter.Write($"{titrationCount:D3},{amount:F3},{cp.R,3},{cp.G,3},{cp.B,3},{cp.Gray,3},{cp.Hue,3},{cp.Saturation:F3},{cp.Brightness:F3}\n");
  100. //csvWriter.Flush();
  101. samplePoints.Add(cp);
  102. logger.LogCritical($"<11111111> 第{titrationCount:D3}滴({amount:F3}), HSB({cp.Hue,3},{cp.Saturation:F3},{cp.Brightness:F3}), RGBL({cp.R,3},{cp.G,3},{cp.B,3},{cp.Gray,3})");
  103. //Application.Current.Dispatcher.BeginInvoke(delegate ()
  104. //{
  105. // ChartHelper.SaveGraph(samplePoints, taskTag);
  106. //});
  107. Messager<TitrationValueArgs>.Send("TitrationValueChange", new TitrationValueArgs(titrationCount, amount, cp.Hue));
  108. Messager<object>.Send("GraberColorValue", cp.Hue);
  109. if (ColorPoint.HueDiff(samplePoints.First(), samplePoints.Last()) < threshold_hue)
  110. {
  111. continue;
  112. }
  113. // 稳定判断: 达到阈值设定,进入稳定(褪色)检测
  114. logger.LogCritical($"<11111111> 稳定检测(开始)");
  115. bool stable = false;
  116. int chkCnt = 0;
  117. int retCnt = 0;
  118. Stopwatch sw = new();
  119. sw.Start();
  120. while (true)
  121. {
  122. // 到达稳定检测截止时限,完成检测
  123. if (sw.ElapsedMilliseconds / 1000 >= threshold_stable_check)
  124. {
  125. logger.LogCritical($"11111111 稳定检测(完成)");
  126. sw.Stop();
  127. stable = true;
  128. break;
  129. }
  130. // 第N滴第i次稳定检测颜色采样
  131. chkCnt++;
  132. Thread.Sleep(1000);
  133. cp = Globals.Camera.Sample($"11111111/{titrationCount:D3}T-{chkCnt:D2}", threshold_gray, threshold_hue);
  134. //csvWriter.Write($"{titrationCount:D3},{amount:F3},{cp.R,3},{cp.G,3},{cp.B,3},{cp.Gray,3},{cp.Hue,3},{cp.Saturation:F3},{cp.Brightness:F3}\n");
  135. //csvWriter.Flush();
  136. samplePoints.Add(cp);
  137. logger.LogCritical($"11111111 稳定检测({chkCnt:D2}), HSB({cp.Hue,3},{cp.Saturation:F3},{cp.Brightness:F3}), RGBL({cp.R,3},{cp.G,3},{cp.B,3},{cp.Gray,3})");
  138. Messager<TitrationValueArgs>.Send("TitrationValueChange", new TitrationValueArgs(titrationCount, amount, cp.Hue));
  139. Messager<object>.Send("GraberColorValue", cp.Hue);
  140. if (ColorPoint.HueDiff(samplePoints.First(), samplePoints.Last()) < threshold_hue)
  141. {
  142. if (retCnt == 0)
  143. {
  144. retCnt++;
  145. continue;
  146. }
  147. logger.LogCritical($"11111111稳定检测(中止)");
  148. break;
  149. }
  150. else
  151. retCnt = 0;
  152. }
  153. // 稳定检测通过,滴定完成
  154. if (stable)
  155. {
  156. logger.LogCritical($"11111111滴定结束(共{titrationCount:D3}滴, {amount:F3}ml)");
  157. break;
  158. }
  159. }
  160. //csvWriter.Close();
  161. //// 保存图表
  162. //string chartTitle = $"{taskTag} ({amount:F3}ml)";
  163. //Application.Current.Dispatcher.BeginInvoke(delegate ()
  164. //{
  165. // ChartHelper.SaveGraph(samplePoints, $"{taskTag}", chartTitle);
  166. //});
  167. Messager<object>.Send("TitrationStop");
  168. logger.LogCritical($"******************************11111111滴定结束******************************");
  169. //try
  170. //{
  171. // Messager<object>.Send("TitrationStart");
  172. // if (Globals.Camera is null)
  173. // {
  174. // logger.LogDebug("11111111未找到摄像头,无法进行滴定操作");
  175. // return;
  176. // }
  177. // Running = true;
  178. // titrationCount = 0;
  179. // slowSpeedCount = 0;
  180. // signalTimeLen = 10;
  181. // arriveRangeCount = 0; //突跃次数
  182. // currSignals = new(); // 信号队列
  183. // currSignalsCompare = new(); // 信号队列
  184. ////_graber = Globals.Graber;
  185. // balanceVal = -1 * arg.RangeValue;
  186. // if (!Globals.Camera.IsOpened)
  187. // {
  188. // Globals.Camera.OpenCamera();
  189. // }
  190. // logger.LogCritical($"******************************11111111滴定开始******************************");
  191. // if (arg.WhetherQuicklyTitration) //快速滴定判断
  192. // {
  193. // bool quicklyTitrationRes = LiquidPipeSwitchTitration1.StartNew.SetLiquidName(EquipmentNames.Titration1PotassiumPermanganate).CheckWhetherArriveEndPoint().Execute(Convert.ToInt32(Math.Round(arg.QuicklyTitrationValue / arg.LiquidAmount * arg.LiquidConvertRatio)));
  194. // if (quicklyTitrationRes)
  195. // {
  196. // amount += arg.QuicklyTitrationValue;
  197. // logger.LogCritical("11111111快速滴定下发成功,等待15秒后继续滴定操作!");
  198. // Thread.Sleep(5 * 1000);
  199. // }
  200. // }
  201. // Thread.Sleep(arg.BeforeWaitTime * 1000);
  202. // int distance = 0;
  203. // if (!ConfigInstance.IsAutomaticInLiquid)//滴定1有自动吸液,滴定2无自动吸液
  204. // {
  205. // distance = Convert.ToInt32(Math.Round(arg.PumpCapacity / arg.LiquidAmount * arg.LiquidConvertRatio));
  206. // LiquidPipeSwitchTitration1.StartNew.SetLiquidName(EquipmentNames.Titration1PotassiumPermanganate).CheckWhetherArriveEndPoint().Execute(LiquidSwitchPattern.In, distance);
  207. // }
  208. // _graber.PresetLightParammanual(arg.explosion, 10);
  209. // _graber.PresetLightParam(-9);
  210. // Thread.Sleep(2000);
  211. // for (int i = 0; i < 7; i++) // 采集7段信号作为背景
  212. // {
  213. // currSignals.Add(_graber.GrabSignal(500));
  214. // currSignalsCompare.Add(currSignals[i]);
  215. // }
  216. // int times = 3;
  217. // while ( JudgeManualTitration(currSignals))
  218. // {
  219. // if (times == 0)
  220. // {
  221. // logger.LogCritical($"*******************11111111检测到异常样本!请尝试手工滴定*******************");
  222. // return;
  223. // }
  224. // _graber.PresetLightParammanual(arg.explosion, 10);
  225. // _graber.PresetLightParam(-9);
  226. // Thread.Sleep(2000);
  227. // for (int i = 0; i < 7; i++) // 采集7段信号作为背景
  228. // {
  229. // currSignals[i] = _graber.GrabSignal(500);
  230. // currSignalsCompare[i] = currSignals[i];
  231. // }
  232. // times--;
  233. // }
  234. // if (IsClean)
  235. // {
  236. // logger.LogCritical($"*******************11111111干净样本滴定算法*******************");
  237. // CleanSampleTitration(arg, ref amount);
  238. // }
  239. // else
  240. // {
  241. // logger.LogCritical($"*******************11111111复杂样本滴定算法*******************");
  242. // ComplexSampleTitration(arg, ref amount);
  243. // }
  244. // //CalibrationTitrationColor(arg, ref amount, titrationCount, balanceVal);
  245. //}
  246. //catch (Exception ex)
  247. //{
  248. // logger.LogError($"11111111滴定异常{DateTime.Now},ErrorInfo:{ex}");
  249. //}
  250. //finally
  251. //{
  252. // Messager<object>.Send("TitrationStop");
  253. // logger.LogCritical($"******************************11111111滴定结束******************************");
  254. //}
  255. }
  256. private static bool JudgeManualTitration(List<ColorDataPoint> currSignals)
  257. {
  258. double max = currSignals[0].GetRSV() ;
  259. double min = currSignals[0].GetRSV();
  260. for (int i = 1; i < currSignals.Count; i++)
  261. {
  262. if (currSignals[i].GetRSV() > max)
  263. max = currSignals[i].GetRSV();
  264. if (currSignals[i].GetRSV() < min)
  265. min = currSignals[i].GetRSV();
  266. }
  267. IsClean = max - min < 1.5 ? true : false;
  268. if (max - min == 0 || min < 110 || max > 120)
  269. return true;
  270. else
  271. return false;
  272. }
  273. private static void CleanSampleTitration(TitrationArg arg, ref double amount)
  274. {
  275. ColorDataPoint subRcurrSignals = new ColorDataPoint();
  276. while (true)
  277. {
  278. if (currSignals.Count >= 7) // 信号判断
  279. {
  280. double subR = 0.0;
  281. int currpt = currSignals.Count - 6;
  282. subRcurrSignals = _graber.GrabSignal(signalTimeLen);
  283. currSignalsCompare.Add(subRcurrSignals);
  284. subR = (subRcurrSignals.GetRSV() - ((currSignals[currpt - 1].GetRSV() + currSignals[currpt].GetRSV()) / 2)) * 100 / subRcurrSignals.GetRSV();
  285. if (subR > 0)
  286. {
  287. currSignals.Add(subRcurrSignals);
  288. }
  289. logger.LogCritical($"11111111当前第{titrationCount:D3}滴,体积:{amount:F3},阈值:{subR:F2}");
  290. Messager<TitrationValueArgs>.Send("TitrationValueChange", new TitrationValueArgs(titrationCount, amount, subR));
  291. if (subR <= balanceVal)
  292. {
  293. arriveRangeCount++;
  294. Stopwatch swten = new();
  295. swten.Start();
  296. int retreatCount = 1; //后退次数
  297. int flag = 0;
  298. while (true) //继续采集信号,监测是否褪色
  299. {
  300. currpt = currSignals.Count - 6;
  301. subRcurrSignals = _graber.GrabSignal(signalTimeLen);
  302. currSignalsCompare.Add(subRcurrSignals);
  303. subR = (subRcurrSignals.GetRSV() - ((currSignals[currpt - 1].GetRSV() + currSignals[currpt].GetRSV()) / 2)) * 100 / subRcurrSignals.GetRSV();
  304. if (subR > 0)
  305. {
  306. currSignals.Add(subRcurrSignals);
  307. }
  308. logger.LogCritical($"11111111已达设定阈值,观察是否褪色,阈值为:{subR:F2}");
  309. if (subR <= balanceVal)
  310. {
  311. flag = 0;
  312. retreatCount++;
  313. if (swten.ElapsedMilliseconds / 1000 > arg.ArriveCheckCount )
  314. {
  315. break;
  316. }
  317. Running = false;
  318. Thread.Sleep(1000);
  319. continue; //颜色比较红,继续观察是否到30秒
  320. }
  321. else if (++flag > 1)
  322. {
  323. Running = true;
  324. if (retreatCount > 2)
  325. {
  326. slowSpeedCount = 5; //如果回退超过三次判定,则给定慢速10次
  327. logger.LogCritical($"11111111回退超过三次,给定慢速5次");
  328. }
  329. break;//当检测到的信号值 大于阈值时,则滴定未结束,需要继续滴定
  330. }
  331. else
  332. {
  333. retreatCount++;
  334. Running = false;
  335. Thread.Sleep(1000);
  336. continue; //颜色比较红,继续观察是否到30秒
  337. }
  338. }
  339. swten.Stop();
  340. }
  341. else
  342. {
  343. arriveRangeCount = arriveRangeCount > 0 ? arriveRangeCount - 1 : 0;
  344. slowSpeedCount = slowSpeedCount > 0 ? slowSpeedCount - 1 : slowSpeedCount;
  345. }
  346. if (amount >= arg.MaxDropVolume) break;
  347. if (!Running) break;
  348. bool arriveEndPoint = LiquidPipeSwitchTitration1.StartNew.SetLiquidName(EquipmentNames.Titration1PotassiumPermanganate).IsArriveEndPoint;
  349. if (arriveEndPoint)
  350. {
  351. int distance = Convert.ToInt32(Math.Round(arg.PumpCapacity / arg.LiquidAmount * arg.LiquidConvertRatio));
  352. LiquidPipeSwitchTitration1.StartNew.SetLiquidName(EquipmentNames.Titration1PotassiumPermanganate).Execute(LiquidSwitchPattern.In, distance);
  353. }
  354. bool res = LiquidPipeSwitchTitration1.StartNew.SetLiquidName(EquipmentNames.Titration1PotassiumPermanganate).Execute(LiquidSwitchPattern.Out, arg.LiquidConvertRatio);
  355. if (!res)
  356. {
  357. logger.LogError("11111111写入失败,等待两秒后再次写入");
  358. Thread.Sleep(2000);
  359. continue;
  360. }
  361. titrationCount += 1;
  362. amount += arg.LiquidAmount;
  363. Thread.Sleep((arriveRangeCount < 1 && slowSpeedCount < 1) ? arg.IntervalTime : 2000);
  364. }
  365. }
  366. for (int i = 0; i < currSignals.Count; i++)
  367. {
  368. logger.LogCritical($"11111111currSignals r={currSignals[i].GetRSV()},g={currSignals[i].GetGSV()},num={i}");
  369. }
  370. for (int i = 0; i < currSignalsCompare.Count; i++)
  371. {
  372. logger.LogCritical($"11111111currSignalsCompare r={currSignalsCompare[i].GetRSV()},g={currSignalsCompare[i].GetGSV()},num={i}");
  373. }
  374. }
  375. private static void ComplexSampleTitration(TitrationArg arg, ref double amount)
  376. {
  377. ColorDataPoint subRcurrSignals = new ColorDataPoint();
  378. while (true)
  379. {
  380. if (currSignals.Count >= 7) // 信号判断
  381. {
  382. double subR = 0.0;
  383. int currpt = currSignals.Count - 6;
  384. subRcurrSignals = _graber.GrabSignal(signalTimeLen);
  385. //currSignalsCompare.Add(subRcurrSignals);
  386. subR = (subRcurrSignals.GetRSV() - ((currSignals[currpt - 1].GetRSV() + currSignals[currpt].GetRSV()) / 2)) * 100 / subRcurrSignals.GetRSV();
  387. //if (subR > 0)
  388. //{
  389. currSignals.Add(subRcurrSignals);
  390. //}
  391. logger.LogCritical($"11111111当前第{titrationCount:D3}滴,体积:{amount:F3},阈值:{subR:F2}");
  392. Messager<TitrationValueArgs>.Send("TitrationValueChange", new TitrationValueArgs(titrationCount, amount, subR));
  393. if (subR <= balanceVal)
  394. {
  395. arriveRangeCount++;
  396. Stopwatch swten = new();
  397. swten.Start();
  398. int retreatCount = 1; //后退次数
  399. int flag = 0;
  400. while (true) //继续采集信号,监测是否褪色
  401. {
  402. currpt = currSignals.Count - 6;
  403. subRcurrSignals = _graber.GrabSignal(signalTimeLen);
  404. //currSignalsCompare.Add(subRcurrSignals);
  405. subR = (subRcurrSignals.GetRSV() - ((currSignals[currpt - 1].GetRSV() + currSignals[currpt].GetRSV()) / 2)) * 100 / subRcurrSignals.GetRSV();
  406. //if (subR > 0)
  407. //{
  408. currSignals.Add(subRcurrSignals);
  409. //}
  410. logger.LogCritical($"11111111已达设定阈值,观察是否褪色,阈值为:{subR:F2}");
  411. if (subR <= balanceVal*0.7)
  412. {
  413. flag = 0;
  414. retreatCount++;
  415. if (swten.ElapsedMilliseconds / 1000 > arg.ArriveCheckCount )
  416. {
  417. break;
  418. }
  419. Running = false;
  420. Thread.Sleep(1000);
  421. continue; //颜色比较红,继续观察是否到30秒
  422. }
  423. else if (++flag > 1)
  424. {
  425. Running = true;
  426. if (retreatCount > 2)
  427. {
  428. slowSpeedCount = 5; //如果回退超过三次判定,则给定慢速10次
  429. logger.LogCritical($"11111111回退超过三次,给定慢速5次");
  430. }
  431. break;//当检测到的信号值 大于阈值时,则滴定未结束,需要继续滴定
  432. }
  433. else
  434. {
  435. retreatCount++;
  436. Running = false;
  437. Thread.Sleep(1000);
  438. continue; //颜色比较红,继续观察是否到30秒
  439. }
  440. }
  441. swten.Stop();
  442. }
  443. else
  444. {
  445. arriveRangeCount = arriveRangeCount > 0 ? arriveRangeCount - 1 : 0;
  446. slowSpeedCount = slowSpeedCount > 0 ? slowSpeedCount - 1 : slowSpeedCount;
  447. }
  448. if (amount >= arg.MaxDropVolume) break;
  449. if (!Running) break;
  450. bool arriveEndPoint = LiquidPipeSwitchTitration1.StartNew.SetLiquidName(EquipmentNames.Titration1PotassiumPermanganate).IsArriveEndPoint;
  451. if (arriveEndPoint)
  452. {
  453. int distance = Convert.ToInt32(Math.Round(arg.PumpCapacity / arg.LiquidAmount * arg.LiquidConvertRatio));
  454. LiquidPipeSwitchTitration1.StartNew.SetLiquidName(EquipmentNames.Titration1PotassiumPermanganate).Execute(LiquidSwitchPattern.In, distance);
  455. }
  456. bool res = LiquidPipeSwitchTitration1.StartNew.SetLiquidName(EquipmentNames.Titration1PotassiumPermanganate).Execute(LiquidSwitchPattern.Out, arg.LiquidConvertRatio);
  457. if (!res)
  458. {
  459. logger.LogError("11111111写入失败,等待两秒后再次写入");
  460. Thread.Sleep(2000);
  461. continue;
  462. }
  463. titrationCount += 1;
  464. amount += arg.LiquidAmount;
  465. Thread.Sleep((arriveRangeCount < 1 && slowSpeedCount < 1) ? arg.IntervalTime : 2000);
  466. }
  467. }
  468. for (int i = 0; i < currSignals.Count; i++)
  469. {
  470. logger.LogCritical($"11111111currSignals r={currSignals[i].GetRSV()},g={currSignals[i].GetGSV()},num={i}");
  471. }
  472. }
  473. private static void CalibrationTitrationColor(TitrationArg arg, ref double amount,int titrationCount,double balanceVal)
  474. {
  475. int count = 0;
  476. if (amount >= 4 && amount < 6)
  477. { count = 1; }
  478. else if (amount >= 6 && amount < 8)
  479. { count = 2; }
  480. else if (amount >= 8 && amount < 9)
  481. { count = 3; }
  482. else if (amount >= 9)
  483. { count = 4; }
  484. for (int i = 0; i < count; i++)
  485. {
  486. bool arriveEndPoint = LiquidPipeSwitchTitration1.StartNew.SetLiquidName(EquipmentNames.Titration1PotassiumPermanganate).IsArriveEndPoint;
  487. if (arriveEndPoint)
  488. {
  489. int distance = Convert.ToInt32(Math.Round(arg.PumpCapacity / arg.LiquidAmount * arg.LiquidConvertRatio));
  490. LiquidPipeSwitchTitration1.StartNew.SetLiquidName(EquipmentNames.Titration1PotassiumPermanganate).Execute(LiquidSwitchPattern.In, distance);
  491. }
  492. bool res = LiquidPipeSwitchTitration1.StartNew.SetLiquidName(EquipmentNames.Titration1PotassiumPermanganate).Execute(LiquidSwitchPattern.Out, arg.LiquidConvertRatio);
  493. if (!res)
  494. {
  495. logger.LogError("11111111写入失败,等待两秒后再次写入");
  496. Thread.Sleep(2000);
  497. }
  498. titrationCount += 1;
  499. amount += arg.LiquidAmount;
  500. Messager<TitrationValueArgs>.Send("TitrationValueChange", new TitrationValueArgs(titrationCount, amount, balanceVal));
  501. logger.LogCritical($"11111111-------加入校准{i+1}滴");
  502. Thread.Sleep(300);
  503. }
  504. }
  505. #endregion
  506. }
  507. }