Vision Template.cs 30 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607
  1. //using Cognex.VisionPro.ToolBlock;
  2. //using Cognex.VisionPro;
  3. //using MathNet.Numerics.LinearAlgebra;
  4. //using MathNet.Numerics.RootFinding;
  5. //using NPOI.SS.Formula.Functions;
  6. //using NPOI.Util;
  7. //using OpenCvSharp;
  8. //using OpenCvSharp.Flann;
  9. //using Prism.Events;
  10. //using Prism.Ioc;
  11. //using Prism.Mvvm;
  12. //using Prism.Regions;
  13. //using Prism.Services.Dialogs;
  14. //using System;
  15. //using System.Collections.Generic;
  16. //using System.Collections.ObjectModel;
  17. //using System.IO;
  18. //using System.Linq;
  19. //using System.Net.Sockets;
  20. //using System.Security.Cryptography;
  21. //using System.Text;
  22. //using System.Threading;
  23. //using System.Threading.Tasks;
  24. //using System.Windows;
  25. //using System.Windows.Documents;
  26. //using System.Windows.Interop;
  27. //using System.Windows.Media;
  28. //using System.Windows.Media.Media3D;
  29. //using Team.FFFeederService;
  30. //using Team.FFFeederService.Interfaces;
  31. //using TeamAAS_VP;
  32. //using TeamAAS_VP.Data;
  33. //using TeamAAS_VP.Enums;
  34. //using TeamAAS_VP.Events;
  35. //using TeamAAS_VP.Models;
  36. //using TeamAAS_VP.ViewModels.Home;
  37. //using TouchSocket.Core;
  38. //using TouchSocket.Sockets;
  39. //using TeamAAS_VP.Core;
  40. //using TeamAAS_VP.Interfaces;
  41. //public class UserScript:IVisionScripting
  42. //{
  43. // public IRegionManager regionManager { get; set; }
  44. // public IEventAggregator eventAggregator { get; set; }
  45. // public IContainerProvider container { get; set; }
  46. // public Management management { get; set; }
  47. // public ProductModel CurrentProduct { get; set; }
  48. // public async Task Execute(ProcedureModel procedure, string[] items, Action<Tuple<bool, string[]>> callback)
  49. // {
  50. // IVoiceCoilMotorFeeder Feeder = null;
  51. // if (procedure.FeederId != Guid.Empty)
  52. // {
  53. // Feeder = management.FeederService.GetFeeder(procedure.FeederId);
  54. // await RunProcedureFeeder(Feeder, procedure, items, rst =>
  55. // {
  56. // callback.Invoke(rst);
  57. // });
  58. // }
  59. // else
  60. // {
  61. // RunProcedureOther(procedure, items, rst =>
  62. // {
  63. // callback.Invoke(rst);
  64. // });
  65. // }
  66. // }
  67. // /// <summary>
  68. // /// Feeder相机引导模式
  69. // /// </summary>
  70. // /// <param name="Feeder"></param>
  71. // /// <param name="procedure"></param>
  72. // /// <param name="items"></param>
  73. // /// <param name="callback"></param>
  74. // /// <returns></returns>
  75. // private async Task RunProcedureFeeder(IVoiceCoilMotorFeeder Feeder, ProcedureModel procedure, string[] items, Action<Tuple<bool, string[]>> callback)
  76. // {
  77. // //是否检测上次的点位,相同点位排除
  78. // bool IsCheckLastPoints = false;
  79. // if (items.Length >= 2)
  80. // {
  81. // if (items[1] == "CheckLastPoints")
  82. // {
  83. // IsCheckLastPoints = true;
  84. // }
  85. // }
  86. // //Feeder光源亮度设置
  87. // if (procedure.LightValue > 3)
  88. // {
  89. // var light = await Feeder.GetLightBrightnessAsync();
  90. // if (procedure.LightValue != light)
  91. // {
  92. // await Feeder.SetLightValueAsync((ushort)procedure.LightValue);
  93. // }
  94. // //打开光源
  95. // await Feeder.OpenLightAsync();
  96. // }
  97. // //先振后拍时
  98. // if (procedure.VibrationModel == VibrationModel.VibrationPhoto)
  99. // {
  100. // if (procedure.FeederWorks != null && procedure.FeederWorks.FeederWorkList != null)
  101. // {
  102. // bool flog = false;
  103. // Dictionary<Guid, double> tuple;
  104. // if (management.feederCurentBlobArea.TryGetValue(management.CurrentProduct.ID, out tuple))
  105. // {
  106. // //首先判断是否是当前流程
  107. // if (tuple.TryGetValue(procedure.Id, out double minArea))
  108. // {
  109. // //如果上次的Blob面积小于设定的最小值,则触发供料
  110. // if (minArea <= procedure.MinArea)
  111. // {
  112. // flog = true;
  113. // SendTaskMessage($"执行料仓供料...", MessageLevel.Info);
  114. // await management.ExecuteFeederStockWorks(Feeder, procedure.FeederStockWorks);
  115. // await Task.Delay(procedure.WaitFeederStop);
  116. // SendTaskMessage($"料仓供料结束", MessageLevel.Info);
  117. // }
  118. // }
  119. // }
  120. // if (!flog)
  121. // {
  122. // //执行配置的Feeder振动任务
  123. // foreach (var feederwork in procedure.FeederWorks.FeederWorkList)
  124. // {
  125. // if (feederwork.Function == VibrationFunction.Delay)
  126. // {
  127. // await Task.Delay(feederwork.Duration);
  128. // }
  129. // else
  130. // {
  131. // await Feeder.StartAction((int)feederwork.Function, feederwork.Duration);
  132. // await Task.Delay(feederwork.Duration);
  133. // }
  134. // }
  135. // }
  136. // await Task.Delay(procedure.WaitFeederStop);
  137. // }
  138. // }
  139. // else
  140. // {
  141. // if (procedure.LightValue != 0)
  142. // {
  143. // await Task.Delay(procedure.WaitPhoto);
  144. // }
  145. // Dictionary<Guid, double> tuple;
  146. // if (management.feederCurentBlobArea.TryGetValue(management.CurrentProduct.ID, out tuple))
  147. // {
  148. // //首先判断是否是当前流程
  149. // if (tuple.TryGetValue(procedure.Id, out double minArea))
  150. // {
  151. // //如果上次的Blob面积小于设定的最小值,则触发供料
  152. // if (minArea <= procedure.MinArea)
  153. // {
  154. // SendTaskMessage($"执行料仓供料...", MessageLevel.Info);
  155. // await management.ExecuteFeederStockWorks(Feeder, procedure.FeederStockWorks);
  156. // await Task.Delay(procedure.WaitFeederStop);
  157. // SendTaskMessage($"料仓供料结束", MessageLevel.Info);
  158. // //执行配置的Feeder振动任务
  159. // /*foreach (var feederwork in procedure.FeederWorks.FeederWorkList)
  160. // {
  161. // if (feederwork.Function == VibrationFunction.Delay)
  162. // {
  163. // await Task.Delay(feederwork.Duration);
  164. // }
  165. // else
  166. // {
  167. // await Feeder.StartAction((int)feederwork.Function, feederwork.Duration);
  168. // await Task.Delay(feederwork.Duration);
  169. // }
  170. // }*/
  171. // await Task.Delay(procedure.WaitFeederStop);
  172. // }
  173. // }
  174. // }
  175. // }
  176. // DateTime nowtime = DateTime.Now;
  177. // //多次拍照
  178. // for (int i = 0; i < procedure.FeederFailLimit; i++)
  179. // {
  180. // SendTaskMessage($"开始执行【{i + 1}】视觉流程[{procedure.Name}]......", MessageLevel.Info);
  181. // //采集图像
  182. // var camera = management.CameraService.GetCamera(procedure.CameraId);
  183. // camera.SetExposureTime(procedure.ExposureTime);
  184. // camera.SetGain(procedure.Gain);
  185. // nowtime = DateTime.Now;
  186. // LogHelper.WriteLogInfo("开始采集图像");
  187. // procedure.ToolBlock.Inputs["InputImage"].Value = camera.Grab();
  188. // LogHelper.WriteLogInfo($"采集图像完成;用时:{(DateTime.Now - nowtime).Milliseconds}ms");
  189. // //运行视觉工具
  190. // LogHelper.WriteLogInfo("开始运行视觉工具");
  191. // procedure.ToolBlock.Run();
  192. // SendTaskMessage($"视觉流程[{procedure.Name}]执行结束!耗时:{procedure.ToolBlock.RunStatus.ProcessingTime:F1}ms", MessageLevel.Info);
  193. // CogToolBlockTerminalCollection outputCollection = procedure.ToolBlock.Outputs;
  194. // eventAggregator.GetEvent<RenderUpdateNotification>().Publish(new ShowRender()
  195. // {
  196. // CameraName = procedure.CameraName,
  197. // Id = procedure.CameraId,
  198. // Image = (ICogImage)procedure.ToolBlock.Inputs["InputImage"].Value,
  199. // Graphic = outputCollection["Graphic"].Value as CogGraphicCollection,
  200. // Result = (bool)(outputCollection["Found"].Value),
  201. // IsShow = true
  202. // });
  203. // DatabaseHelper.AddCameraRecords(management.CurrentProduct.Name, procedure.Name, outputCollection);
  204. // var BlobTotalArea = (double)outputCollection["BlobTotalArea"].Value;
  205. // //记录当前的blob面积
  206. // Dictionary<Guid, double> tuple;
  207. // if (management.feederCurentBlobArea.TryGetValue(management.CurrentProduct.ID, out tuple))
  208. // {
  209. // //如股票当前已经存在此流程的记录
  210. // if (tuple.ContainsKey(procedure.Id))
  211. // {
  212. // tuple[procedure.Id] = BlobTotalArea;
  213. // }
  214. // else
  215. // {
  216. // tuple.Add(procedure.Id, BlobTotalArea);
  217. // }
  218. // }
  219. // else
  220. // {
  221. // management.feederCurentBlobArea.Add(management.CurrentProduct.ID, new Dictionary<Guid, double>());
  222. // management.feederCurentBlobArea[management.CurrentProduct.ID].Add(procedure.Id, BlobTotalArea);
  223. // }
  224. // if (!outputCollection.Contains("Found"))
  225. // {
  226. // callback.Invoke(new Tuple<bool, string[]>(true, new string[] { "NG,NoOut[Found]" }));
  227. // return;
  228. // }
  229. // bool Found = (bool)(outputCollection["Found"].Value);
  230. // //拍照OK
  231. // if (Found)
  232. // {
  233. // SendTaskMessage($"拍照OK", MessageLevel.Debug);
  234. // if (procedure.ProcedureOutputs == null)
  235. // {
  236. // SendTaskMessage($"视觉流程未配置输出项!", MessageLevel.Alarm);
  237. // callback.Invoke(new Tuple<bool, string[]>(true, new string[] { "NG,NotOutputs" }));
  238. // return;
  239. // }
  240. // List<string> SendResults = new List<string>();
  241. // //SendResults.Add(new StringBuilder());
  242. // //SendResults[SendResults.Count - 1].Append("OK,");
  243. // bool isOk = true;
  244. // foreach (var output in procedure.ProcedureOutputs) //遍历配置的所有需要输出项
  245. // {
  246. // //根据输出类型进行区分输出
  247. // if (output.ValueType == typeof(string))
  248. // {
  249. // string[] strpoints = outputCollection[output.Name].Value.ToString().Split(";");
  250. // if (strpoints.Length <= 0)
  251. // {
  252. // continue;
  253. // //callback.Invoke(new Tuple<bool, string[]>(true, new string[] { $"Not[{output.Name}]" }));
  254. // //return;
  255. // }
  256. // //需要点位转换时,进行点位提取
  257. // if (output.IsPointTran)
  258. // {
  259. // List<Vector<double>> currentPointsForFeeder = new List<Vector<double>>();
  260. // int index = 0;
  261. // //获取相机校准
  262. // var calib = management.DeviceConfig.Calibrations.FirstOrDefault(cal => cal.Id == procedure.CalibrationId);
  263. // if (calib == null)
  264. // {
  265. // SendTaskMessage($"没有发现关联校准!", MessageLevel.Alarm);
  266. // callback.Invoke(new Tuple<bool, string[]>(true, new string[] { "NG,NotCalibrations" }));
  267. // return;
  268. // }
  269. // List<string> SendDtat = new List<string>();
  270. // //得到校准矩阵
  271. // Matrix<double> matrix = Matrix<double>.Build.DenseOfArray(calib.AffineTransformationMaterial);
  272. // List<string> points = new List<string>();
  273. // //遍历所有的输出点位
  274. // foreach (var pos in strpoints)
  275. // {
  276. // string[] spl = pos.Split(',');
  277. // double x = double.Parse(spl[0]);
  278. // double y = double.Parse(spl[1]);
  279. // double angle = double.Parse(spl[2]);
  280. // if (calib.CameraMount == CameraMount.FixedDown || calib.CameraMount == CameraMount.MobileJ2 || calib.CameraMount == CameraMount.MobileJ4)
  281. // {
  282. // angle *= -1;
  283. // }
  284. // //将像素坐标转换成机器人坐标
  285. // var rpos = matrix * Vector<double>.Build.Dense(new double[] { x, y, 1 });
  286. // currentPointsForFeeder.Add(rpos);
  287. // //判断是否有重复的点位,防止机器人重复取同一个物料,陷入死循环
  288. // if (IsCheckLastPoints)
  289. // {
  290. // if (management.LastPointsForFeeder.ContainsKey(Feeder.Id))
  291. // {
  292. // var repeated = management.LastPointsForFeeder[Feeder.Id].FirstOrDefault(p => Math.Abs(p[0] - rpos[0]) < 1 && Math.Abs(p[1] - rpos[1]) < 1);
  293. // if (repeated != null) continue;
  294. // }
  295. // }
  296. // index++;
  297. // if (index >= procedure.OutputPointCountMax)
  298. // {
  299. // points.Add($"{rpos[0]:F3},{rpos[1]:F3},{angle:F3}");
  300. // break;
  301. // }
  302. // else
  303. // {
  304. // points.Add($"{rpos[0]:F3},{rpos[1]:F3},{angle:F3}");
  305. // }
  306. // }
  307. // if (management.LastPointsForFeeder.ContainsKey(Feeder.Id))
  308. // {
  309. // management.LastPointsForFeeder[Feeder.Id] = currentPointsForFeeder; //将本次点位结果记录至最后一次
  310. // }
  311. // else
  312. // {
  313. // management.LastPointsForFeeder.Add(Feeder.Id, currentPointsForFeeder); //将本次点位结果记录至最后一次
  314. // }
  315. // SendTaskMessage($"可用的点位个数:{points.Count}", MessageLevel.Debug);
  316. // //如果可用的点位个数为0,则触发振动盘振动
  317. // if (points.Count == 0)
  318. // {
  319. // isOk = false;
  320. // break;
  321. // }
  322. // SendResults.Add($"{points.Count},{string.Join(",", points)}");
  323. // }
  324. // //直接输出字符串
  325. // else
  326. // {
  327. // List<string> bu = new List<string>();
  328. // foreach (var item in strpoints)
  329. // {
  330. // bu.Add(item);
  331. // }
  332. // SendResults.Add($"{string.Join(",", bu)}");
  333. // }
  334. // }
  335. // else
  336. // {
  337. // SendResults.Add(outputCollection[output.Name].Value.ToString());
  338. // }
  339. // }
  340. // if (!isOk)
  341. // {
  342. // //根据斑点面积决定是否料仓供料
  343. // if (BlobTotalArea <= procedure.MinArea)
  344. // {
  345. // SendTaskMessage($"执行料仓供料...", MessageLevel.Info);
  346. // await management.ExecuteFeederStockWorks(Feeder, procedure.FeederStockWorks, true);
  347. // await Task.Delay(procedure.WaitFeederStop);
  348. // SendTaskMessage($"料仓供料结束", MessageLevel.Info);
  349. // }
  350. // else
  351. // {
  352. // if (procedure.FeederWorks != null && procedure.FeederWorks.FeederWorkList != null)
  353. // {
  354. // SendTaskMessage($"执行Feeder振动", MessageLevel.Info);
  355. // //执行配置的Feeder振动任务
  356. // await management.ExecuteFeederWorks(Feeder, procedure.FeederWorks, true);
  357. // await Task.Delay(procedure.WaitFeederStop);
  358. // SendTaskMessage($"Feeder振动结束", MessageLevel.Info);
  359. // }
  360. // }
  361. // continue;
  362. // }
  363. // if (Feeder != null)
  364. // {
  365. // await Feeder.CloseLightAsync();
  366. // }
  367. // callback.Invoke(new Tuple<bool, string[]>(true, new string[] { $"OK,{string.Join(";", SendResults)}" }));
  368. // return;
  369. // }
  370. // //拍照NG
  371. // else
  372. // {
  373. // SendTaskMessage($"拍照NG", MessageLevel.Error);
  374. // //根据斑点面积决定是否料仓供料
  375. // if (BlobTotalArea <= procedure.MinArea)
  376. // {
  377. // SendTaskMessage($"执行料仓供料...", MessageLevel.Info);
  378. // await management.ExecuteFeederStockWorks(Feeder, procedure.FeederStockWorks);
  379. // await Task.Delay(procedure.WaitFeederStop);
  380. // SendTaskMessage($"料仓供料结束", MessageLevel.Info);
  381. // }
  382. // else
  383. // {
  384. // if (procedure.FeederWorks != null && procedure.FeederWorks.FeederWorkList != null)
  385. // {
  386. // SendTaskMessage($"执行Feeder振动", MessageLevel.Info);
  387. // //执行配置的Feeder振动任务
  388. // await management.ExecuteFeederWorks(Feeder, procedure.FeederWorks);
  389. // await Task.Delay(procedure.WaitFeederStop);
  390. // SendTaskMessage($"Feeder振动结束", MessageLevel.Info);
  391. // }
  392. // }
  393. // continue;
  394. // }
  395. // }
  396. // SendTaskMessage($"多次拍照失败,达到设定上限!", MessageLevel.Alarm);
  397. // callback.Invoke(new Tuple<bool, string[]>(true, new string[] { "NG,NoFind" }));
  398. // }
  399. // /// <summary>
  400. // /// 相机拍照,其他模式
  401. // /// </summary>
  402. // /// <param name="procedure"></param>
  403. // /// <param name="items"></param>
  404. // /// <param name="callback"></param>
  405. // private void RunProcedureOther(ProcedureModel procedure, string[] items, Action<Tuple<bool, string[]>> callback)
  406. // {
  407. // DateTime nowtime = DateTime.Now;
  408. // for (int i = 0; i < procedure.FeederFailLimit; i++)
  409. // {
  410. // SendTaskMessage($"开始执行【{i + 1}】视觉流程[{procedure.Name}]......", MessageLevel.Info);
  411. // //采集图像
  412. // var camera = management.CameraService.GetCamera(procedure.CameraId);
  413. // camera.SetExposureTime(procedure.ExposureTime);
  414. // camera.SetGain(procedure.Gain);
  415. // nowtime = DateTime.Now;
  416. // LogHelper.WriteLogInfo("开始采集图像");
  417. // procedure.ToolBlock.Inputs["InputImage"].Value = camera.Grab();
  418. // LogHelper.WriteLogInfo($"采集图像完成;用时:{(DateTime.Now - nowtime).Milliseconds}ms");
  419. // //运行视觉工具
  420. // procedure.ToolBlock.Run();
  421. // SendTaskMessage($"视觉流程[{procedure.Name}]执行结束!耗时:{procedure.ToolBlock.RunStatus.ProcessingTime:F1}ms", MessageLevel.Info);
  422. // CogToolBlockTerminalCollection outputCollection = procedure.ToolBlock.Outputs;
  423. // eventAggregator.GetEvent<RenderUpdateNotification>().Publish(new ShowRender()
  424. // {
  425. // CameraName = procedure.CameraName,
  426. // Id = procedure.CameraId,
  427. // Image = (ICogImage)procedure.ToolBlock.Inputs["InputImage"].Value,
  428. // Graphic = outputCollection["Graphic"].Value as CogGraphicCollection,
  429. // Result = (bool)(outputCollection["Found"].Value),
  430. // IsShow = true
  431. // });
  432. // DatabaseHelper.AddCameraRecords(management.CurrentProduct.Name, procedure.Name, outputCollection);
  433. // if (!outputCollection.Contains("Found"))
  434. // {
  435. // callback.Invoke(new Tuple<bool, string[]>(true, new string[] { "NG,NoOut[Found]" }));
  436. // return;
  437. // }
  438. // bool Found = (bool)(outputCollection["Found"].Value);
  439. // //拍照OK
  440. // if (Found)
  441. // {
  442. // SendTaskMessage($"拍照OK", MessageLevel.Debug);
  443. // if (procedure.ProcedureOutputs == null)
  444. // {
  445. // SendTaskMessage($"视觉流程未配置输出项!", MessageLevel.Alarm);
  446. // callback.Invoke(new Tuple<bool, string[]>(true, new string[] { "NG,NotOutputs" }));
  447. // return;
  448. // }
  449. // List<string> SendResults = new List<string>();
  450. // foreach (var output in procedure.ProcedureOutputs) //遍历配置的所有需要输出项
  451. // {
  452. // //根据输出类型进行区分输出
  453. // if (output.ValueType == typeof(string))
  454. // {
  455. // string[] strpoints = outputCollection[output.Name].Value.ToString().Split(";");
  456. // if (strpoints.Length <= 0)
  457. // {
  458. // continue;
  459. // }
  460. // //需要点位转换时,进行点位提取
  461. // if (output.IsPointTran)
  462. // {
  463. // int index = 0;
  464. // //获取校准
  465. // var calib = management.DeviceConfig.Calibrations.FirstOrDefault(cal => cal.Id == procedure.CalibrationId);
  466. // if (calib == null)
  467. // {
  468. // SendTaskMessage($"没有发现关联校准!", MessageLevel.Alarm);
  469. // callback.Invoke(new Tuple<bool, string[]>(true, new string[] { "NG,NotCalibrations" }));
  470. // return;
  471. // }
  472. // //得到校准的变换矩阵
  473. // Matrix<double> matrix = Matrix<double>.Build.DenseOfArray(calib.AffineTransformationMaterial);
  474. // StringBuilder sbpoints = new StringBuilder();
  475. // List<string> points = new List<string>();
  476. // foreach (var pos in strpoints)
  477. // {
  478. // string[] spl = pos.Split(',');
  479. // double x = double.Parse(spl[0]);
  480. // double y = double.Parse(spl[1]);
  481. // double angle = double.Parse(spl[2]);
  482. // if (calib.CameraMount == CameraMount.FixedDown || calib.CameraMount == CameraMount.MobileJ2 || calib.CameraMount == CameraMount.MobileJ4)
  483. // {
  484. // angle *= -1;
  485. // }
  486. // //将像素坐标转换成机器人坐标
  487. // var rpos = matrix * Vector<double>.Build.Dense(new double[] { x, y, 1 });
  488. // if (calib.CameraMount == TeamAAS_VP.Enums.CameraMount.MobileJ4)
  489. // {
  490. // if (items.Length < 4)
  491. // {
  492. // SendTaskMessage($"J4移动相机校准转换需要给入X,Y,U!", MessageLevel.Alarm);
  493. // callback.Invoke(new Tuple<bool, string[]>(true, new string[] { "NG,DataError" }));
  494. // return;
  495. // }
  496. // //像素直接转换成mm时的点位
  497. // double Robot_X, Robot_Y;
  498. // Robot_X = rpos[0];
  499. // Robot_Y = rpos[1];
  500. // //机器人当前TOOL 0下的坐标
  501. // double curpos_x = 0, curpos_y = 0, curpos_u = 0;
  502. // curpos_x = double.Parse(items[1]);
  503. // curpos_y = double.Parse(items[2]);
  504. // curpos_u = double.Parse(items[3]);
  505. // //得到旋转矩阵
  506. // double angle1 = Math.PI * (curpos_u - calib.MarkPoint.U) / 180;
  507. // // 创建T矩阵
  508. // Matrix<double> rotationMatrix = Matrix<double>.Build.DenseOfArray(new double[,]
  509. // {
  510. // { Math.Cos(angle1), -Math.Sin(angle1) },
  511. // { Math.Sin(angle1), Math.Cos(angle1) }
  512. // });
  513. // Vector<double> p3 = Vector<double>.Build.Dense(new double[] { Robot_X - calib.CalibPoints[0].Robot.X, Robot_Y - calib.CalibPoints[0].Robot.Y });
  514. // Vector<double> phere = Vector<double>.Build.Dense(new double[] { curpos_x, curpos_y });
  515. // var cc = rotationMatrix * p3 + phere;
  516. // rpos = Vector<double>.Build.Dense(new double[] { cc[0], cc[1] });
  517. // }
  518. // else
  519. // {
  520. // //当需要直接转换工具坐标时
  521. // if (items.Length == 4)
  522. // {
  523. // //根据机器人当前的点位计算工具坐标
  524. // ToolCoord tool = new ToolCoord();
  525. // tool.ComputeTool(double.Parse(items[1]), double.Parse(items[2]), double.Parse(items[3]), rpos[0], rpos[1]);
  526. // rpos = Vector<double>.Build.Dense(new double[] { tool.X, tool.Y });
  527. // }
  528. // }
  529. // index++;
  530. // if (index >= procedure.OutputPointCountMax)
  531. // {
  532. // points.Add($"{rpos[0]:F3},{rpos[1]:F3},{angle:F3}");
  533. // break;
  534. // }
  535. // else
  536. // {
  537. // points.Add($"{rpos[0]:F3},{rpos[1]:F3},{angle:F3}");
  538. // sbpoints.Append($"{rpos[0]:F3},{rpos[1]:F3},{angle:F3},");
  539. // }
  540. // }
  541. // SendResults.Add($"{points.Count},{string.Join(",", points)}");
  542. // }
  543. // //直接输出字符串
  544. // else
  545. // {
  546. // List<string> bu = new List<string>();
  547. // foreach (var item in strpoints)
  548. // {
  549. // bu.Add(item);
  550. // }
  551. // SendResults.Add($"{string.Join(",", bu)}");
  552. // }
  553. // }
  554. // else
  555. // {
  556. // SendResults.Add(outputCollection[output.Name].Value.ToString());
  557. // }
  558. // }
  559. // callback.Invoke(new Tuple<bool, string[]>(true, new string[] { $"OK,{string.Join(";", SendResults)}" }));
  560. // return;
  561. // }
  562. // //拍照NG
  563. // else
  564. // {
  565. // SendTaskMessage($"拍照NG", MessageLevel.Error);
  566. // continue;
  567. // }
  568. // }
  569. // SendTaskMessage($"多次拍照失败,达到设定上限!", MessageLevel.Alarm);
  570. // callback.Invoke(new Tuple<bool, string[]>(true, new string[] { "NG,NoFind" }));
  571. // }
  572. // public void SendTaskMessage(string msg, MessageLevel level)
  573. // {
  574. // eventAggregator.GetEvent<TaskMessageNotification>().Publish(new TeamAAS_VP.Models.MessageStruct() { Message = msg, level = level });
  575. // }
  576. //}