using DataEntity.Share; using DriverLib.Engine; using System; using System.Collections.Generic; using System.Data; using System.Linq; using System.Reflection; using System.Windows; using System.Xml; using XCommon; using XCommon.Log; using XCore; using XHandler.Controls.Run.Com; using XHandler.View; using XHandler.View.MethodProperty; using XImaging.Automation.Service.Interface; using XImagingXhandler.XDAL; using static HxEnum.OperationTypeEnum; using DataRWDAL; using NPOI.SS.Formula.Functions; using XHandler.Class; using DataRWDAL.Rack; using System.Configuration; using XHandler.Properties; using XHandler.View.Liquids; using DataEntity; using DriverLibrary; using HxEnum; using XHandler.Class.DataEx; using Newtonsoft.Json.Linq; using System.Collections.ObjectModel; using Newtonsoft.Json; namespace XHandler.Controls { public class AspirateControl { string strCurrentCulture = ""; WellCalc wellCalc = new WellCalc(); LatticeBll latticeBll = new LatticeBll(); AspirateBll aspirateBll = new AspirateBll(); public RunWnd launchView = null; LiquidAccuracyBll liquidAccuracyBll = new LiquidAccuracyBll(); public AspirateControl(string strCurrentCulture) { this.strCurrentCulture = strCurrentCulture; } #region 执行吸液,返回结果字符串 /// /// 执行吸液,返回结果字符串 /// /// 板位节点信息 /// 装载方法属性节点对象 /// 加载枪头后多出出来的长度 /// z轴安全距离 /// 0:连接谁;1:仿真 /// public bool ExecuteAspirate(XmlNode xmlEnv, XmlNode methodNode, float currentLengthOfTip, float zAxisVal, bool isSimulator) { bool result = true; HxResult ret = new HxResult(); if (launchView._cancelSource.IsCancellationRequested) { result = false; return result; } #region Start Log if (strCurrentCulture.Equals("zh-CN")) { launchView.AddLogs("【" + DateTime.Now.ToString("HH:mm:ss:fff") + "】> Xhandler: 【" + methodNode.SelectSingleNode("name").InnerText + "】" + Properties.MachineRunResource.strStart.ToString()); } else { launchView.AddLogs("【" + DateTime.Now.ToString("HH:mm:ss:fff") + "】> Xhandler: 【" + methodNode.SelectSingleNode("name").InnerText + "】start:"); } #endregion if (currentLengthOfTip == 0f)//枪上没有Tip不允许吸液 strWithTipInfo { if (strCurrentCulture.Equals("zh-CN")) { launchView.AddLogs("【" + DateTime.Now.ToString("HH:mm:ss:fff") + "】> Xhandler: 【" + methodNode.SelectSingleNode("name").InnerText + "】" + Properties.MachineRunResource.strProgress.ToString() + Properties.MachineRunResource.strWithTipInfo.ToString()); } else { launchView.AddLogs("【" + DateTime.Now.ToString("HH:mm:ss:fff") + "】> Xhandler: 【" + methodNode.SelectSingleNode("name").InnerText + "】progress: it seems without loaded tip! please check!"); } result = false; return result; } #region 数据准备 string labwareText = methodNode.SelectSingleNode("labware/text").InnerText; string strLabwareid = methodNode.SelectSingleNode("labware/value").InnerText; string channelNums = methodNode.SelectSingleNode("channels").InnerText; string armName = methodNode.SelectSingleNode("arm/text").InnerText; if(armName.Contains("泵")||armName.Contains("爪")) { if (strCurrentCulture.Equals("zh-CN")) { launchView.AddLogs("【" + DateTime.Now.ToString("HH:mm:ss:fff") + "】> Xhandler: 【" + methodNode.SelectSingleNode("name").InnerText + "】" + Properties.MachineRunResource.strProgress.ToString() + Properties.RunAspirateResource.strUnSupportArms.ToString()); } else { launchView.AddLogs("【" + DateTime.Now.ToString("HH:mm:ss:fff") + "】> Xhandler: 【" + methodNode.SelectSingleNode("name").InnerText + "】progress: arm is wrong! please check!"); } result = false; return result; } string armId = methodNode.SelectSingleNode("arm/value").InnerText; string latticenum = methodNode.SelectSingleNode("position/text").InnerText; string strWells = methodNode.SelectSingleNode("wellarray").InnerText; bool enableSingleWellvolume = methodNode.SelectSingleNode("enableSingleWellvolume").InnerText.ToLower() == "true" ? true : false; // 每孔体积 List dropdownNames = new List(); var drops = methodNode.SelectNodes("SingleWellvolume"); if (drops != null) { foreach (XmlNode x in drops) { DropdownName d = new DropdownName(); d.dropdown_id = x.SelectSingleNode("channel").InnerText; d.dropdown_name = x.SelectSingleNode("name").InnerText; dropdownNames.Add(d); } } double wellvolume = Convert.ToDouble(methodNode.SelectSingleNode("wellvolume").InnerText); string liquididText = methodNode.SelectSingleNode("liquidid/text").InnerText; string liquididValue = methodNode.SelectSingleNode("liquidid/value").InnerText; string liquidrangeidText = methodNode.SelectSingleNode("liquidrangeid/text").InnerText; string liquidrangeidValue = methodNode.SelectSingleNode("liquidrangeid/value").InnerText; string liquidpidText = methodNode.SelectSingleNode("liquidpid/text").InnerText; string liquidpidValue = methodNode.SelectSingleNode("liquidpid/value").InnerText; bool enableMix = methodNode.SelectSingleNode("enableMix").InnerText.ToLower() == "true" ? true : false; bool enableMultiMix = methodNode.SelectSingleNode("enableMultiMix").InnerText.ToLower() == "true" ? true : false; double mixvolume = Convert.ToDouble(methodNode.SelectSingleNode("mixvolume").InnerText); int mixcount = Convert.ToInt32(methodNode.SelectSingleNode("mixcount").InnerText); string mixAspiratePositionText = methodNode.SelectSingleNode("mixAspiratePosition/text").InnerText; string mixAspiratePositionValue = methodNode.SelectSingleNode("mixAspiratePosition/value").InnerText; double mixAspirateDistance = Convert.ToDouble(methodNode.SelectSingleNode("mixAspirateDistance").InnerText); double mixAspirateSpeed = Convert.ToDouble(methodNode.SelectSingleNode("mixAspirateSpeed").InnerText); string mixDispensePositionText = methodNode.SelectSingleNode("mixDispensePosition/text").InnerText; string mixDispensePositionValue = methodNode.SelectSingleNode("mixDispensePosition/value").InnerText; double mixDispenseDistance = Convert.ToDouble(methodNode.SelectSingleNode("mixDispenseDistance").InnerText); double mixDispenseSpeed = Convert.ToDouble(methodNode.SelectSingleNode("mixDispenseSpeed").InnerText); bool enableLiquidSensor = methodNode.SelectSingleNode("enableLiquidSensor").InnerText.ToLower() == "true" ? true : false; int liquidSensorCount = Convert.ToInt32(methodNode.SelectSingleNode("liquidSensorCount").InnerText); double liquidSensorDistance = Convert.ToDouble(methodNode.SelectSingleNode("liquidSensorDistance").InnerText); double liquidSensorEndDistance = Convert.ToDouble(methodNode.SelectSingleNode("liquidSensorEndDistance").InnerText); double liquidSensorSpeed = Convert.ToDouble(methodNode.SelectSingleNode("liquidSensorSpeed").InnerText); double liquidSensorRadio = Convert.ToDouble(methodNode.SelectSingleNode("liquidSensorRadio").InnerText); string liquidSensorDisIdText = methodNode.SelectSingleNode("liquidSensorDisId/text").InnerText; string liquidSensorDisIdValue = methodNode.SelectSingleNode("liquidSensorDisId/value").InnerText; bool enableLiquidFollow = methodNode.SelectSingleNode("enableLiquidFollow").InnerText.ToLower() == "true" ? true : false; int liquidFollowType = Convert.ToInt32(methodNode.SelectSingleNode("liquidFollowType/value").InnerText); string liquidFollowTypeName = methodNode.SelectSingleNode("liquidFollowType/text").InnerText; double liquidFollowSpeed = Convert.ToDouble(methodNode.SelectSingleNode("liquidFollowSpeed").InnerText); double liquidFollowDistance = Convert.ToDouble(methodNode.SelectSingleNode("liquidFollowDistance").InnerText); double liquidFollowArea = Convert.ToDouble(methodNode.SelectSingleNode("liquidFollowArea").InnerText); bool enableMixFollow = methodNode.SelectSingleNode("enableMixFollow").InnerText.ToLower() == "true" ? true : false; bool enableSensorBlock = methodNode.SelectSingleNode("enableSensorBlock").InnerText.ToLower() == "true" ? true : false; //double liquidSensorBlockDistance = Convert.ToDouble(methodNode.SelectSingleNode("liquidSensorBlockDistance").InnerText); string aspirateBlockDisIdText = methodNode.SelectSingleNode("aspirateBlockDisId/text").InnerText; int aspirateBlockDisIdValue = Convert.ToInt32(methodNode.SelectSingleNode("aspirateBlockDisId/value").InnerText); string aspirateAirDisIdText = methodNode.SelectSingleNode("aspirateAirDisId/text").InnerText; int aspirateAirDisIdValue = Convert.ToInt32(methodNode.SelectSingleNode("aspirateAirDisId/value").InnerText); liquidSensorDisIdValue = Convert.ToInt32(liquidSensorDisIdValue) >= 3 ? (Convert.ToInt32(liquidSensorDisIdValue) + 1).ToString() : Convert.ToInt32(liquidSensorDisIdValue).ToString(); #endregion #region 数据验证 if (channelNums == "") { if (strCurrentCulture.Equals("zh-CN")) { launchView.AddLogs("【" + DateTime.Now.ToString("HH:mm:ss:fff") + "】> Xhandler:" + Properties.MachineRunResource.strWithoutChannel.ToString()); } else { launchView.AddLogs("【" + DateTime.Now.ToString("HH:mm:ss:fff") + "】> Xhandler:Channel wasn't set, please check!"); } result = false; return result; } Labware labwares = LabwareDB.GetLabware(strLabwareid); string[] wells = new string[] { }; string wellVariable = string.Empty; if (!string.IsNullOrEmpty(strWells)) { //判断是否包含等号,如果是包含等号的,则是变量控制孔位 if (strWells.Contains(",")) { wells = strWells.Split(','); } else if (strWells.Contains("=")) { } } string[] chs = channelNums.Split(','); if (strWells.Contains(",")) { if (labwares.labware_type_id.Equals("3")) { } else { if (chs.Length != wells.Length)//排除试剂槽 { if (strCurrentCulture.Equals("zh-CN")) { launchView.AddLogs("【" + DateTime.Now.ToString("HH:mm:ss:fff") + "】> Xhandler:" + Properties.MachineRunResource.strOverWell.ToString()); } else { launchView.AddLogs("【" + DateTime.Now.ToString("HH:mm:ss:fff") + "】> Xhandler:Total of channel isn't same with total of wells, please check!"); } result = false; return result; } } } else if (strWells.Contains("=")) { wellVariable = strWells.Substring(strWells.LastIndexOf('=') + 1, (strWells.Length - strWells.LastIndexOf('=') - 1)); Variable variable = new Variable(); // 从当前变量字典中取出变量的值 for (int i = 0; i < launchView.gloadVariable.Count; i++) { Variable v = launchView.gloadVariable.Peek(); if (v.variablename == wellVariable) { variable = v; break; } } } // 给孔位排序 if (strWells.Contains(',')) { string suffix = wells[0].Substring(1, wells[0].Length - 1); List sortWellName = new List(); if (Shared.ChannelCount == 1) { for (int i = 0; i < labwares.number_row; i++) { string rowName = ComUtility.GetRowChar(i); string rowWellName = rowName + suffix; if (wells.Contains(rowWellName)) { sortWellName.Add(rowWellName); } } wells = sortWellName.ToArray(); } else if (Shared.ChannelCount > 1) { #region Del //List sortWellNameSH = new List();//用来按列的孔位名称 ////上海的移液枪正常排列,A1,B1,C1,D1,E1,F1,G1,H1 //for (int j = 1; j < labwares.number_column; j++) //{ // int countWell = 0;//当前选择的孔位数量 // sortWellNameSH.Clear(); // for (int i = 0; i < labwares.number_row; i++) // { // string rowName = ComUtility.GetRowChar(i);//创建行号 // string rowWellName = rowName + j; // if (wells.Contains(rowWellName)) // { // sortWellNameSH.Add(rowWellName); // countWell++; // } // } // if (wells.Length == countWell && countWell == chs.Length) // { // wells = sortWellNameSH.ToArray(); // break; // } // else // { // if (strCurrentCulture.Equals("zh-CN")) // { // launchView.AddLogs("【" + DateTime.Now.ToString("HH:mm:ss:fff") + "】> Xhandler:" + Properties.MachineRunResource.strError.ToString() + Properties.RunAspirateResource.strChannelMatch.ToString()); // } // else // { // launchView.AddLogs("【" + DateTime.Now.ToString("HH:mm:ss:fff") + "】> Xhandler:Channels aren't match with these wells, please check!"); // } // result = false; // return result; // } //} #endregion } } else if (!string.IsNullOrEmpty(strWells) && !strWells.Contains(',') && !strWells.Contains("=")) // 只有一个孔位 { wells = new string[] { strWells }; } else if (strWells.Contains("=")) // 利用循环 { Variable variable = new Variable(); string strvariable = strWells.Substring(strWells.LastIndexOf('=') + 1, (strWells.Length - strWells.LastIndexOf('=') - 1)); Variable globalVariable = null; globalVariable = ControlCom.SearchGlobalVariable(launchView, strvariable); if (!string.IsNullOrEmpty(globalVariable.variablename)) { variable = globalVariable; } //for (int i = 0; i < launchView.gloadVariable.Count; i++) //{ // Variable v = launchView.gloadVariable.Peek(); // if (strvariable == v.variablename) // { // variable = v; // break; // } //} if(string.IsNullOrEmpty(variable.variablename) && strvariable.Length >= 1) //if (variable.variablename.Equals(string.Empty) && strvariable.Length >= 1)//没有查找到变量名,看看是不是表达式,并求出表达式值 { Stack stackTem = new Stack();//临时存储变量过得对象 int totalLoop = launchView.gloadVariable.Count; // 从当前变量字典中取出变量的值 for (int i = 0; i < totalLoop; i++) { Variable v = launchView.gloadVariable.Pop(); //取出最近的一个匹配变量 stackTem.Push(v); if (strvariable.Contains(v.variablename)) { variable = v; break; } } int totalLoopTem = stackTem.Count; for (int i = 0; i < totalLoopTem; i++) { Variable v = stackTem.Pop(); launchView.gloadVariable.Push(v); } //for (int i = 0; i < launchView.gloadVariable.Count; i++) //{ // Variable v = launchView.gloadVariable.Peek(); //} Microsoft.JScript.Vsa.VsaEngine ve = Microsoft.JScript.Vsa.VsaEngine.CreateEngine(); string strExpress = strvariable.Replace(variable.variablename, variable.variablecurval); variable.variablecurval = Microsoft.JScript.Eval.JScriptEvaluate(strExpress, ve).ToString(); } List sortWellName = new List(); if (chs.Length == 8) { for (int i = 0; i < labwares.number_row; i++) { string rowName = ComUtility.GetRowChar(i); string rowWellName = rowName + variable.variablecurval; sortWellName.Add(rowWellName); } wells = sortWellName.ToArray(); } else if (chs.Length > 1 && chs.Length < 8) { //根据枪头通道计算在第几个孔位 int startNum = chs.Length * (Convert.ToInt32(variable.variablecurval) - 1); int columnCount = (int)(Math.Ceiling((double)startNum / (double)labwares.number_row)); if(columnCount==0) { columnCount++; } int totalCount = (int)labwares.number_row * columnCount; //选中列剩余多少个孔 int leftCount = totalCount - startNum; int startRowNum = (int)labwares.number_row - leftCount; if (leftCount == chs.Length) { for (int i = startRowNum; i < labwares.number_row; i++) { string rowName = ComUtility.GetRowChar(i); string rowWellName = rowName + columnCount.ToString(); sortWellName.Add(rowWellName); } } else { for (int i = startRowNum; i < labwares.number_row; i++) { string rowName = ComUtility.GetRowChar(i); string rowWellName = rowName + columnCount.ToString(); sortWellName.Add(rowWellName); } for (int i = 0; i < chs.Length - leftCount; i++) { string rowName = ComUtility.GetRowChar(i); string rowWellName = rowName + (columnCount + 1).ToString(); sortWellName.Add(rowWellName); } } wells = sortWellName.ToArray(); } else if (chs.Length == 1) { for (int j = 1; j <= labwares.number_column; j++) { for (int i = 0; i < labwares.number_row; i++) { string rowName = ComUtility.GetRowChar(i); string rowWellName = rowName + j; sortWellName.Add(rowWellName); } } wells = new string[1]; wells[0] = sortWellName[Convert.ToInt32(variable.variablecurval)-1]; } } // 判断方法中的板位和板子是否能对应上设置的台面 Lattice lattice = new Lattice(); if (Shared.ChannelCount >= 1) { TabletopTemplate tabletopTemplate = TabletopTemplateDB.GetCurrentAppTabletopTemplateCollectionFromdb(); //增加台面模板判断 if (tabletopTemplate == null) { lattice = LatticeDB.GetLatticeDataByIdFromdb(latticenum, Convert.ToInt32(armId), Shared.SoftwareInformation.software_device_number); } else { lattice = LatticeDB.GetLatticeDataByLatticeNumAndTempIdFromdb(latticenum, Convert.ToInt32(armId), Shared.SoftwareInformation.software_device_number, tabletopTemplate.tabletopid); } int xmlLatticeId = Convert.ToInt32(latticenum.Substring(1));//ControlCom.GetLatticeId(Convert.ToInt32(lattice.lattice_id), false); var latticeXn = xmlEnv.SelectSingleNode("platform[lattice_id='" + xmlLatticeId.ToString() + "']"); if (latticeXn != null) { labwares.labware_sname = latticeXn.SelectNodes("labware")[0].SelectSingleNode("labware_sname").InnerText; } else { if (strCurrentCulture.Equals("zh-CN")) { launchView.AddLogs("【" + DateTime.Now.ToString("HH:mm:ss:fff") + "】> Xhandler: 【" + methodNode.SelectSingleNode("name").InnerText + "】" + Properties.MachineRunResource.strProgress.ToString() + Properties.RunAspirateResource.strWithoutLattice.ToString()); } else { launchView.AddLogs("【" + DateTime.Now.ToString("HH:mm:ss:fff") + "】> Xhandler: 【" + methodNode.SelectSingleNode("name").InnerText + "】progress: the lattice of aspirate liquid is wrong! please check!"); } result = false; return result; } } #endregion try { // 获取当前台面的板子吸液列的坐标 string[] charray = chs; Lattice slattice = DataRWDAL.LatticeDB.GetLatticeDataByIdFromdb(lattice.lattice_id); // 获取板位孔的坐标数据 List dtWells = ControlCom.GenerateWellCoordinate(labwares, slattice); // 液体参数 Liquid liquid = LiquidDB.GetALiquidFromdb(liquidpidValue); //根据循环处理孔位 TipsTable tipsTable = null; tipsTable = dtWells.SingleOrDefault(t => t.lattice_id.Equals(lattice.lattice_id) && t.labware_id.Equals(strLabwareid) && t.wellname.Equals(wells[0])); if (tipsTable == null) { if (strCurrentCulture.Equals("zh-CN")) { launchView.AddLogs("【" + DateTime.Now.ToString("HH:mm:ss:fff") + "】> Xhandler: 【" + methodNode.SelectSingleNode("name").InnerText + "】" + Properties.MachineRunResource.strProgress.ToString() + Properties.RunAspirateResource.strWithoutWellInfo.ToString()); } else { launchView.AddLogs("【" + DateTime.Now.ToString("HH:mm:ss:fff") + "】> Xhandler: 【" + methodNode.SelectSingleNode("name").InnerText + "】progress: the well on lattice of aspirate liquid is wrong! please check!"); } result = false; return result; } if (Shared.ChannelCount.Equals(96)) { if (labwares.labware_type_id.Equals("3")) { if (!wells.Contains("A1")) { if (strCurrentCulture.Equals("zh-CN")) { launchView.AddLogs("【" + DateTime.Now.ToString("HH:mm:ss:fff") + "】> Xhandler: 【" + methodNode.SelectSingleNode("name").InnerText + "】" + Properties.MachineRunResource.strProgress.ToString() + Properties.RunAspirateResource.strWithoutWellInfo.ToString()); } else { launchView.AddLogs("【" + DateTime.Now.ToString("HH:mm:ss:fff") + "】> Xhandler: 【" + methodNode.SelectSingleNode("name").InnerText + "】progress: the wells on lattice of aspirate liquid is wrong! please check!"); } result = false; return result; } } else { if (!wells.Contains("A1") || !wells.Length.Equals(96)) { if (strCurrentCulture.Equals("zh-CN")) { launchView.AddLogs("【" + DateTime.Now.ToString("HH:mm:ss:fff") + "】> Xhandler: 【" + methodNode.SelectSingleNode("name").InnerText + "】" + Properties.MachineRunResource.strProgress.ToString() + Properties.RunAspirateResource.strWithoutWellInfo.ToString()); } else { launchView.AddLogs("【" + DateTime.Now.ToString("HH:mm:ss:fff") + "】> Xhandler: 【" + methodNode.SelectSingleNode("name").InnerText + "】progress: the wells on lattice of aspirate liquid is wrong! please check!"); } result = false; return result; } } } tipsTable.lattice_num = lattice.lattice_num; string strWell = string.Join(",", wells); if (Shared.ChannelCount == 1) { #region AspirateMParam AspirateMParam aspirateMParam = new AspirateMParam(); aspirateMParam.afterAirDelay = (int)liquid.after_aspirate_delay * 1000; aspirateMParam.armId = Convert.ToInt32(methodNode.SelectSingleNode("arm/value").InnerText); aspirateMParam.aspirateAcceleration = (float)liquid.aspirate_acceleration; aspirateMParam.aspirateDeceleration = (float)liquid.aspirate_deceleration; aspirateMParam.aspirateDelay = (int)liquid.aspirate_delay * 1000; aspirateMParam.aspirateEnterSpeed = (float)liquid.aspirate_enter_speed; aspirateMParam.aspirateOutSpeed = (float)liquid.aspirate_out_speed; aspirateMParam.aspirateSpeed = (float)liquid.aspirate_speed; aspirateMParam.basezAxisVal = zAxisVal; aspirateMParam.beforeAirDelay = (int)liquid.before_aspirate_delay; if ((float)liquid.after_aspirate_volume == 0f) { aspirateMParam.isAfterAir = false; } else { aspirateMParam.isAfterAir = true; aspirateMParam.afterAirpAxisVal = (float)liquid.after_aspirate_volume; } if (liquid.before_aspirate_volume == 0d) { aspirateMParam.isBeforeAir = false; } else { aspirateMParam.isBeforeAir = true; aspirateMParam.beforeAirpAxisVal = (float)liquid.before_aspirate_volume; } if (liquid.after_a_liquid_volume == 0d) { aspirateMParam.isIncLiquidAfter = false; } else { aspirateMParam.isIncLiquidAfter = true; aspirateMParam.IncLiquidAfterpAxisVal = (float)liquid.after_a_liquid_volume; } if (liquid.before_a_liquid_volume == 0d) { aspirateMParam.isIncLiquidBefore = false; } else { aspirateMParam.isIncLiquidBefore = true; aspirateMParam.IncLiquidBeforepAxisVal = (float)liquid.before_a_liquid_volume; } if (liquid.aspirate_is_knock_wall == 0) { aspirateMParam.isKnockWall = false; } else { aspirateMParam.isKnockWall = true; aspirateMParam.knockDirection = (int)liquid.knock_direction; aspirateMParam.knockSpeed = (float)liquid.knock_speed; aspirateMParam.knockWallDelay = (int)liquid.knock_wall_delay * 1000; aspirateMParam.knockWellxOryAxisVal = (float)liquid.knock_wall_length; aspirateMParam.knockWellzAxisVal = (float)liquid.knock_well_height; } aspirateMParam.liquidVolumeType = (int)Convert.ToInt32(liquid.liquid_volume_type); LiquidAccuracy liquidAccuracy = liquidAccuracyBll.GetLiquidAccuracyFromdb(Convert.ToInt32(liquidrangeidValue), Convert.ToInt32(armId), Convert.ToDouble(wellvolume), liquididValue); double targetVolume = liquidAccuracyBll.CalculateAspirateParamVolume(Convert.ToDouble(wellvolume), liquidAccuracy); aspirateMParam.pAxisVal = (float)targetVolume; launchView.fVolumeToNull = (float)Convert.ToDouble(wellvolume); aspirateMParam.wellzAxisVal = (float)liquid.well_top_length; aspirateMParam.xAxisVal = tipsTable.axis_b_X; aspirateMParam.yAxisVal = tipsTable.axis_b_Y; //如果有吸液位置高度的话,则减少高度 if(liquid.aspirate_position_type==0) { }else if(liquid.aspirate_position_type==1) { } else if(liquid.aspirate_position_type==2) { //aspirateMParam.zAxisVal== } // 如果有吸液位置高度的话,则减少高度 //float zVal = tipsTable.axis_b_Z - (float)liquid.aspirate_well_bottom_length; float zVal = 0f; if (liquid.aspirate_well_bottom_length != "") { string[] zOffsiteArray = liquid.aspirate_well_bottom_length.Split(','); if (liquid.aspirate_position_type == 0)//液体液面 { zVal = tipsTable.axis_b_Z - (float)Convert.ToDouble(zOffsiteArray[0]);//底层用探测到的液面一下用aspirateMParam.zAxisAspirateOffsetVal } else if (liquid.aspirate_position_type == 1)//孔口 { zVal = aspirateMParam.wellzAxisVal + (float)Convert.ToDouble(zOffsiteArray[0]); } else if (liquid.aspirate_position_type == 2)//孔底 { if (labwares.labware_type_id.Equals("4")) { if (labwares.labware_tubeshelf_type == 1) { ObservableCollection labwareWellInfoList = DataRWDAL.LabwareDB.GetSpecialLabwareWellInfo(labwares.labware_id); LabwareWellInfo currentWellInfo = labwareWellInfoList.FirstOrDefault(x => x.labware_well_name.Equals(tipsTable.wellname)); Labware currentWellLabware = DataRWDAL.LabwareDB.GetLabware(currentWellInfo.well_labware_id); zVal = tipsTable.axis_b_Z - (float)Convert.ToDouble(zOffsiteArray[0]) - ((float)currentWellLabware.labware_height-(float)currentWellLabware.well_height); } else { zVal = tipsTable.axis_b_Z - (float)Convert.ToDouble(zOffsiteArray[0]) - ControlCom.CalculateWellBottomThickness(labwares.piled_script); } } else { zVal = tipsTable.axis_b_Z - (float)Convert.ToDouble(zOffsiteArray[0]); } } } //if (liquid.aspirate_well_bottom_length != "") //{ // string[] zOffsiteArray = liquid.aspirate_well_bottom_length.Split(','); // //如果是管架,看里面的离心管底高度 // if (labwares.labware_type_id.Equals("4")) // { // zVal = tipsTable.axis_b_Z - (float)Convert.ToDouble(zOffsiteArray[0])-((float)labwares.labware_height-(float)labwares.well_height) - ControlCom.CalculateWellBottomThickness(labwares.piled_script); // } // else // { // zVal = tipsTable.axis_b_Z - (float)Convert.ToDouble(zOffsiteArray[0]); // } //} aspirateMParam.zAxisVal = zVal < 0 ? 0 : zVal; aspirateMParam.isMix = enableMix; if (aspirateMParam.isMix == true) { aspirateMParam.mixAspiratePositionValue = Convert.ToInt32(mixAspiratePositionValue); aspirateMParam.mixAspiratePositionText = mixAspiratePositionText; if (mixAspiratePositionValue == "0")//liquid { } else if (mixAspiratePositionValue == "1")//top { aspirateMParam.mixAspirateDistance = ((float)labwares.well_height - (float)mixAspirateDistance); } else if (mixAspiratePositionValue == "2")//bottom { aspirateMParam.mixAspirateDistance = (float)mixAspirateDistance; } aspirateMParam.mixAspirateSpeed = (float)Convert.ToDouble(mixAspirateSpeed); aspirateMParam.mixDispensePositionValue = Convert.ToInt32(mixDispensePositionValue); aspirateMParam.mixDispensePositionText = mixDispensePositionText; if (mixDispensePositionValue == "0")//liquid { } else if (mixDispensePositionValue == "1")//top { aspirateMParam.mixDispenseDistance = ((float)labwares.well_height - (float)mixDispenseDistance); } else if (mixDispensePositionValue == "2")//bottom { aspirateMParam.mixDispenseDistance = (float)mixDispenseDistance; } aspirateMParam.mixDispenseSpeed = (float)Convert.ToDouble(mixDispenseSpeed); aspirateMParam.mixvolume = (float)mixvolume; aspirateMParam.mixCount = mixcount; } else { aspirateMParam.mixAspirateDistance = 0; aspirateMParam.mixAspirateSpeed = 100; aspirateMParam.mixDispenseDistance = 0; aspirateMParam.mixDispenseSpeed = 100; } aspirateMParam.mixzAxisVal = (float)Convert.ToDouble(aspirateMParam.zAxisVal); #endregion launchView.UpdateLabwareWells(tipsTable, wells, 2); // 2:正在吸液红色 launchView.SetWaitOne();//暂停 if (strCurrentCulture.Equals("zh-CN")) { launchView.AddLogs("【" + DateTime.Now.ToString("HH:mm:ss:fff") + "】>Xhandler: 【" + methodNode.SelectSingleNode("name").InnerText + "】" + Properties.RunAspirateResource.strAspiratingExecute.ToString()); } else { launchView.AddLogs("【" + DateTime.Now.ToString("HH:mm:ss:fff") + "】> Xhandler: 【" + methodNode.SelectSingleNode("name").InnerText + "】" + "progress: Aspirate is executing,please wait for a moment."); } ret = aspirateBll.ExecuteAspirate(aspirateMParam, isSimulator); #region 错误处理 result = DoError(ret, methodNode, strWell, xmlEnv, currentLengthOfTip, zAxisVal, isSimulator, aspirateMParam.pAxisVal); #endregion } else if (Shared.ChannelCount > 1&&!Shared.ChannelCount.Equals(96)) { //挑菌设备 if (Shared.SoftwareInformation.software_device_number == DeviceCategory.DeviceChoice) { // 多个通道时候,判断是否需要分次吸液 if (labwares.number_row.Equals(8) && labwares.number_column.Equals(12) && charray.Length == 4) { List wellsPartOne = new List(); List wellsPartTwo = new List(); for (int q = 0; q < wells.Length - 1; q++) { string prefix = wells[q].Substring(0, 1); string suffix = wells[q].Substring(1, wells[q].Length - 1); string nextSuffix = wells[q + 1].Substring(1, wells[q + 1].Length - 1); if (Convert.ToInt32(suffix) + 2 == Convert.ToInt32(nextSuffix))//是连续的孔位 { wellsPartOne.Add(wells[q]); if (q == wells.Length - 2) { wellsPartOne.Add(wells[q + 1]); } } else //非连续的孔位 { wellsPartOne.Add(wells[q]); break; } } if (wells.Length - wellsPartOne.Count > 0) { for (int q = wellsPartOne.Count; q < wells.Length; q++) { wellsPartTwo.Add(wells[q]); } } if (wellsPartOne.Count != 0) { wells = wellsPartOne.ToArray(); #region AspirateMParamSH AspirateMParamSH aspirateMParam = new AspirateMParamSH(); aspirateMParam.afterAirDelay = (int)liquid.after_aspirate_delay; aspirateMParam.armId = Convert.ToInt32(armId); aspirateMParam.aspirateAcceleration = (float)liquid.aspirate_acceleration; aspirateMParam.aspirateDeceleration = (float)liquid.aspirate_deceleration; aspirateMParam.aspirateDelay = (int)liquid.aspirate_delay; aspirateMParam.aspirateEnterSpeed = (float)liquid.aspirate_enter_speed; aspirateMParam.aspirateOutSpeed = (float)liquid.aspirate_out_speed; aspirateMParam.aspirateSpeed = (float)liquid.aspirate_speed; aspirateMParam.basezAxisVal = zAxisVal; aspirateMParam.beforeAirDelay = (int)liquid.before_aspirate_delay; if ((float)liquid.after_aspirate_volume == 0f) { aspirateMParam.isAfterAir = false; } else { aspirateMParam.isAfterAir = true; aspirateMParam.afterAirpAxisVal = (float)liquid.after_aspirate_volume; } if (liquid.before_aspirate_volume == 0d) { aspirateMParam.isBeforeAir = false; } else { aspirateMParam.isBeforeAir = true; aspirateMParam.beforeAirpAxisVal = (float)liquid.before_aspirate_volume; } if (liquid.after_a_liquid_volume == 0d) { aspirateMParam.isIncLiquidAfter = false; } else { aspirateMParam.isIncLiquidAfter = true; aspirateMParam.IncLiquidAfterpAxisVal = (float)liquid.after_a_liquid_volume; } if (liquid.before_a_liquid_volume == 0d) { aspirateMParam.isIncLiquidBefore = false; } else { aspirateMParam.isIncLiquidBefore = true; aspirateMParam.IncLiquidBeforepAxisVal = (float)liquid.before_a_liquid_volume; } aspirateMParam.liquidVolumeType = (int)Convert.ToInt32((liquid.liquid_volume_type != null ? "1" : liquid.liquid_volume_type)); // 精度校准后的体积 LiquidAccuracy liquidAccuracy = liquidAccuracyBll.GetLiquidAccuracyFromdb(Convert.ToInt32(liquidrangeidValue), Convert.ToInt32(armId), Convert.ToDouble(wellvolume), liquididValue); double targetVolume = liquidAccuracyBll.CalculateAspirateParamVolume(Convert.ToDouble(wellvolume), liquidAccuracy); float[] pAxisVal = new float[wells.Length]; for (int i = 0; i < wells.Length; i++) { pAxisVal[i] = (float)targetVolume; } aspirateMParam.pAxisVal = pAxisVal; if (labwares.labware_type_id.Equals("4")) { aspirateMParam.wellzAxisVal = tipsTable.axis_b_Z - (((float)labwares.labware_height - (float)labwares.well_height) +(float)ControlCom.GetCentrifugalLabwer(labwares.piled_script).labware_height); } else { aspirateMParam.wellzAxisVal = tipsTable.axis_b_Z - ((float)labwares.labware_height - (float)liquid.well_top_length); } if (liquid.aspirate_is_knock_wall == 0) { aspirateMParam.isKnockWall = false; } else { aspirateMParam.isKnockWall = true; aspirateMParam.knockDirection = (int)liquid.knock_direction; aspirateMParam.knockSpeed = (int)Convert.ToInt32(liquid.knock_speed); aspirateMParam.knockWallDelay = (int)liquid.knock_wall_delay; aspirateMParam.knockWellxOryAxisVal = (float)liquid.knock_wall_length; aspirateMParam.knockWellzAxisVal = (float)liquid.knock_well_height; } aspirateMParam.isMix = enableMix; if (aspirateMParam.isMix == true) { aspirateMParam.mixAspiratePositionValue = Convert.ToInt32(mixAspiratePositionValue); aspirateMParam.mixAspiratePositionText = mixAspiratePositionText; if (labwares.labware_type_id.Equals("4")) { if (mixAspiratePositionValue == "0")//liquid { } else if (mixAspiratePositionValue == "1")//top { aspirateMParam.mixAspirateDistance = ((float)ControlCom.GetCentrifugalLabwer(labwares.piled_script).well_height - (float)mixAspirateDistance); } else if (mixAspiratePositionValue == "2")//bottom { aspirateMParam.mixAspirateDistance = (float)mixAspirateDistance; } } else { if (mixAspiratePositionValue == "0")//liquid { } else if (mixAspiratePositionValue == "1")//top { aspirateMParam.mixAspirateDistance = ((float)labwares.well_height - (float)mixAspirateDistance); } else if (mixAspiratePositionValue == "2")//bottom { aspirateMParam.mixAspirateDistance = (float)mixAspirateDistance; } } aspirateMParam.mixAspirateSpeed = (float)Convert.ToDouble(mixAspirateSpeed); aspirateMParam.mixDispensePositionValue = Convert.ToInt32(mixDispensePositionValue); aspirateMParam.mixDispensePositionText = mixDispensePositionText; if (labwares.labware_type_id.Equals("4")) { if (mixDispensePositionValue == "0")//liquid { } else if (mixDispensePositionValue == "1")//top { aspirateMParam.mixDispenseDistance = ((float)ControlCom.GetCentrifugalLabwer(labwares.piled_script).well_height - (float)mixDispenseDistance); } else if (mixDispensePositionValue == "2")//bottom { aspirateMParam.mixDispenseDistance = (float)mixDispenseDistance; } } else { if (mixDispensePositionValue == "0")//liquid { } else if (mixDispensePositionValue == "1")//top { aspirateMParam.mixDispenseDistance = ((float)labwares.well_height - (float)mixDispenseDistance); } else if (mixDispensePositionValue == "2")//bottom { aspirateMParam.mixDispenseDistance = (float)mixDispenseDistance; } } aspirateMParam.mixDispenseSpeed = (float)Convert.ToDouble(mixDispenseSpeed); aspirateMParam.mixvolume = (float)mixvolume; aspirateMParam.mixCount = mixcount; } else { aspirateMParam.mixAspirateDistance = 0; aspirateMParam.mixAspirateSpeed = 100; aspirateMParam.mixDispenseDistance = 0; aspirateMParam.mixDispenseSpeed = 100; } aspirateMParam.isSurvey = enableLiquidSensor; if (aspirateMParam.isSurvey == true) { aspirateMParam.surveyRetryCount = liquidSensorCount; if (labwares.labware_type_id.Equals("4")) { Labware centrifugalLabware = ControlCom.GetCentrifugalLabwer(labwares.piled_script); aspirateMParam.surveyInitzVal = tipsTable.axis_b_Z - (((float)labwares.labware_height - (float)labwares.well_height) + (float)ControlCom.GetCentrifugalLabwer(labwares.piled_script).labware_height - (float)liquidSensorDistance); aspirateMParam.surveyMaxzVal = tipsTable.axis_b_Z - (((float)labwares.labware_height - (float)labwares.well_height) + (float)ControlCom.GetCentrifugalLabwer(labwares.piled_script).labware_height - (float)liquidSensorEndDistance); aspirateMParam.surveySpeed = (float)liquidSensorSpeed; aspirateMParam.wellzAxisVal = tipsTable.axis_b_Z - ((float)((float)labwares.labware_height - (float)labwares.well_height) + (float)ControlCom.GetCentrifugalLabwer(labwares.piled_script).labware_height); aspirateMParam.wellBottomzAxisVal = tipsTable.axis_b_Z - ((float)labwares.labware_height - (float)labwares.well_height + (float)ControlCom.GetCentrifugalLabwer(labwares.piled_script).labware_height-(float)ControlCom.GetCentrifugalLabwer(labwares.piled_script).well_height); aspirateMParam.surveyFailHandleType = Convert.ToInt32(liquidSensorDisIdValue); if (enableLiquidFollow) { aspirateMParam.followupType = liquidFollowType; aspirateMParam.followupSpeed = (float)liquidFollowSpeed; aspirateMParam.followupDistance = (float)liquidFollowDistance; float area = 0.0f; if (labwares.well_shape == (int)WellSharpe.Round) { area = (float)(Math.PI * (float)ControlCom.GetCentrifugalLabwer(labwares.piled_script).well_mouth_radius * (float)ControlCom.GetCentrifugalLabwer(labwares.piled_script).well_mouth_radius); } else if (labwares.well_shape == (int)WellSharpe.Rectangle) { area = (float)((float)ControlCom.GetCentrifugalLabwer(labwares.piled_script).well_top_x * (float)ControlCom.GetCentrifugalLabwer(labwares.piled_script).well_top_y); } aspirateMParam.sectionalArea = area; aspirateMParam.isMixFollowup = enableMixFollow; } else { } } else { aspirateMParam.surveyInitzVal = tipsTable.axis_b_Z - ((float)labwares.labware_height - (float)liquidSensorDistance); aspirateMParam.surveyMaxzVal = tipsTable.axis_b_Z - ((float)labwares.labware_height - (float)liquidSensorEndDistance); aspirateMParam.surveySpeed = (float)liquidSensorSpeed; //aspirateMParam.surveyCoefficient =; aspirateMParam.wellzAxisVal = tipsTable.axis_b_Z - ((float)labwares.labware_height - (float)liquid.well_top_length); aspirateMParam.wellBottomzAxisVal = tipsTable.axis_b_Z - ((float)labwares.labware_height - (float)labwares.well_height); aspirateMParam.surveyFailHandleType = Convert.ToInt32(liquidSensorDisIdValue); if (enableLiquidFollow) { aspirateMParam.followupType = liquidFollowType; aspirateMParam.followupSpeed = (float)liquidFollowSpeed; aspirateMParam.followupDistance = (float)liquidFollowDistance; float area = 0.0f; if (labwares.well_shape == (int)WellSharpe.Round) { area = (float)(Math.PI * labwares.well_mouth_radius * labwares.well_mouth_radius); } else if (labwares.well_shape == (int)WellSharpe.Rectangle) { area = (float)(labwares.well_top_x * labwares.well_top_y); } aspirateMParam.sectionalArea = area; aspirateMParam.isMixFollowup = enableMixFollow; } else { } } } else { } aspirateMParam.xAxisVal = tipsTable.axis_b_X; aspirateMParam.yAxisVal = tipsTable.axis_b_Y; // 如果有吸液位置高度的话,则减少高度 //float zVal = tipsTable.axis_b_Z - (float)liquid.aspirate_well_bottom_length; float zVal = 0f; if (liquid.aspirate_well_bottom_length != "") { string[] zOffsiteArray = liquid.aspirate_well_bottom_length.Split(','); if (labwares.labware_type_id.Equals("4")) { zVal = tipsTable.axis_b_Z - (float)Convert.ToDouble(zOffsiteArray[0]) - ((float)labwares.labware_height - (float)labwares.well_height) - ControlCom.CalculateWellBottomThickness(labwares.piled_script); } else { zVal = tipsTable.axis_b_Z - (float)Convert.ToDouble(zOffsiteArray[0]); } } float[] fzAxisVal = new float[wells.Length]; int[] channelIds = new int[wells.Length]; for (int i = 0; i < wells.Length; i++) { fzAxisVal[i] = zVal < 0 ? 0 : zVal; channelIds[i] = Convert.ToInt32(charray[i]); } aspirateMParam.channelId = channelIds; aspirateMParam.channelCount = channelIds.Length; aspirateMParam.zAxisVal = fzAxisVal; aspirateMParam.mixzAxisVal = (float)Convert.ToDouble(aspirateMParam.zAxisVal[0]); launchView.UpdateLabwareWells(tipsTable, wells, 2); // 2:正在吸液红色 if (strCurrentCulture.Equals("zh-CN")) { launchView.AddLogs("【" + DateTime.Now.ToString("HH:mm:ss:fff") + "】>Xhandler: 【" + methodNode.SelectSingleNode("name").InnerText + "】" + Properties.RunAspirateResource.strAspiratingExecute.ToString()); } else { launchView.AddLogs("【" + DateTime.Now.ToString("HH:mm:ss:fff") + "】> Xhandler: 【" + methodNode.SelectSingleNode("name").InnerText + "】" + "progress: Aspirate is executing,please wait for a moment."); } aspirateMParam.yChannelGapVal = 9f; #endregion launchView.SetWaitOne();//暂停 ret = aspirateBll.ExecuteAspirate(aspirateMParam, isSimulator); #region 错误处理 result = DoError(ret, methodNode, strWell, xmlEnv, currentLengthOfTip, zAxisVal, isSimulator, (float)targetVolume); #endregion } if (result && wellsPartTwo.Count != 0) { wells = wellsPartTwo.ToArray(); #region AspirateMParamWH AspirateMParamWH aspirateMParam = new AspirateMParamWH(); aspirateMParam.afterAirDelay = (int)liquid.after_aspirate_delay; aspirateMParam.armId = Convert.ToInt32(armId); aspirateMParam.aspirateAcceleration = (float)liquid.aspirate_acceleration; aspirateMParam.aspirateDeceleration = (float)liquid.aspirate_deceleration; aspirateMParam.aspirateDelay = (int)liquid.aspirate_delay; aspirateMParam.aspirateEnterSpeed = (float)liquid.aspirate_enter_speed; aspirateMParam.aspirateOutSpeed = (float)liquid.aspirate_out_speed; aspirateMParam.aspirateSpeed = (float)liquid.aspirate_speed; aspirateMParam.basezAxisVal = zAxisVal; aspirateMParam.beforeAirDelay = (int)liquid.before_aspirate_delay; if ((float)liquid.after_aspirate_volume == 0f) { aspirateMParam.isAfterAir = false; } else { aspirateMParam.isAfterAir = true; aspirateMParam.afterAirpAxisVal = (float)liquid.after_aspirate_volume; } if (liquid.before_aspirate_volume == 0d) { aspirateMParam.isBeforeAir = false; } else { aspirateMParam.isBeforeAir = true; aspirateMParam.beforeAirpAxisVal = (float)liquid.before_aspirate_volume; } if (liquid.after_a_liquid_volume == 0d) { aspirateMParam.isIncLiquidAfter = false; } else { aspirateMParam.isIncLiquidAfter = true; aspirateMParam.IncLiquidAfterpAxisVal = (float)liquid.after_a_liquid_volume; } if (liquid.before_a_liquid_volume == 0d) { aspirateMParam.isIncLiquidBefore = false; } else { aspirateMParam.isIncLiquidBefore = true; aspirateMParam.IncLiquidBeforepAxisVal = (float)liquid.before_a_liquid_volume; } aspirateMParam.liquidVolumeType = (int)Convert.ToInt32((liquid.liquid_volume_type != null ? "1" : liquid.liquid_volume_type)); // 精度校准后的体积 LiquidAccuracy liquidAccuracy = liquidAccuracyBll.GetLiquidAccuracyFromdb(Convert.ToInt32(liquidrangeidValue), Convert.ToInt32(armId), Convert.ToDouble(wellvolume), liquididValue); double targetVolume = liquidAccuracyBll.CalculateAspirateParamVolume(Convert.ToDouble(wellvolume), liquidAccuracy); float[] pAxisVal = new float[wells.Length]; for (int i = 0; i < wells.Length; i++) { pAxisVal[i] = (float)targetVolume; } aspirateMParam.pAxisVal = pAxisVal; aspirateMParam.wellzAxisVal = (float)liquid.well_top_length; if (liquid.aspirate_is_knock_wall == 0) { aspirateMParam.isKnockWall = false; } else { aspirateMParam.isKnockWall = true; aspirateMParam.knockDirection = (int)liquid.knock_direction; aspirateMParam.knockSpeed = (float)liquid.knock_speed; aspirateMParam.knockWallDelay = (int)liquid.knock_wall_delay; aspirateMParam.knockWellxOryAxisVal = (float)liquid.knock_wall_length; aspirateMParam.knockWellzAxisVal = (float)liquid.knock_well_height; } aspirateMParam.isMix = enableMix; if (aspirateMParam.isMix == true) { aspirateMParam.mixAspiratePositionValue = Convert.ToInt32(mixAspiratePositionValue); aspirateMParam.mixAspiratePositionText = mixAspiratePositionText; if (labwares.labware_type_id.Equals("4")) { if (mixAspiratePositionValue == "0")//liquid { } else if (mixAspiratePositionValue == "1")//top { aspirateMParam.mixAspirateDistance = ((float)ControlCom.GetCentrifugalLabwer(labwares.piled_script).well_height - (float)mixAspirateDistance); } else if (mixAspiratePositionValue == "2")//bottom { aspirateMParam.mixAspirateDistance = (float)mixAspirateDistance; } } else { if (mixAspiratePositionValue == "0")//liquid { } else if (mixAspiratePositionValue == "1")//top { aspirateMParam.mixAspirateDistance = ((float)labwares.well_height - (float)mixAspirateDistance); } else if (mixAspiratePositionValue == "2")//bottom { aspirateMParam.mixAspirateDistance = (float)mixAspirateDistance; } } aspirateMParam.mixAspirateSpeed = (float)Convert.ToDouble(mixAspirateSpeed); aspirateMParam.mixDispensePositionValue = Convert.ToInt32(mixDispensePositionValue); aspirateMParam.mixDispensePositionText = mixDispensePositionText; if (labwares.labware_type_id.Equals("4")) { if (mixDispensePositionValue == "0")//liquid { } else if (mixDispensePositionValue == "1")//top { aspirateMParam.mixDispenseDistance = ((float)ControlCom.GetCentrifugalLabwer(labwares.piled_script).well_height - (float)mixDispenseDistance); } else if (mixDispensePositionValue == "2")//bottom { aspirateMParam.mixDispenseDistance = (float)mixDispenseDistance; } } else { if (mixDispensePositionValue == "0")//liquid { } else if (mixDispensePositionValue == "1")//top { aspirateMParam.mixDispenseDistance = ((float)labwares.well_height - (float)mixDispenseDistance); } else if (mixDispensePositionValue == "2")//bottom { aspirateMParam.mixDispenseDistance = (float)mixDispenseDistance; } } aspirateMParam.mixDispenseSpeed = (float)Convert.ToDouble(mixDispenseSpeed); aspirateMParam.mixvolume = (float)mixvolume; aspirateMParam.mixCount = mixcount; } else { aspirateMParam.mixAspirateDistance = 0; aspirateMParam.mixAspirateSpeed = 100; aspirateMParam.mixDispenseDistance = 0; aspirateMParam.mixDispenseSpeed = 100; } aspirateMParam.xAxisVal = tipsTable.axis_b_X; aspirateMParam.yAxisVal = tipsTable.axis_b_Y; //如果有吸液位置高度的话,则减少高度 //float zVal = tipsTable.axis_b_Z - (float)liquid.aspirate_well_bottom_length; float zVal = 0f; if (liquid.aspirate_well_bottom_length != "") { string[] zOffsiteArray = liquid.aspirate_well_bottom_length.Split(','); if (labwares.labware_type_id.Equals("4")) { zVal = tipsTable.axis_b_Z - (float)Convert.ToDouble(zOffsiteArray[0]) - ((float)labwares.labware_height - (float)labwares.well_height) - ControlCom.CalculateWellBottomThickness(labwares.piled_script); } else { zVal = tipsTable.axis_b_Z - (float)Convert.ToDouble(zOffsiteArray[0]); } } float[] fzAxisVal = new float[wells.Length]; int[] channelIds = new int[wells.Length]; for (int i = 0; i < wells.Length; i++) { fzAxisVal[i] = zVal < 0 ? 0 : zVal; channelIds[i] = Convert.ToInt32(charray[i + wellsPartOne.Count]); } aspirateMParam.channelId = channelIds; aspirateMParam.channelCount = channelIds.Length; aspirateMParam.zAxisVal = fzAxisVal; aspirateMParam.mixzAxisVal = (float)Convert.ToDouble(aspirateMParam.zAxisVal[0]); #endregion launchView.UpdateLabwareWells(tipsTable, wells, 2); // 2:正在吸液红色 if (strCurrentCulture.Equals("zh-CN")) { launchView.AddLogs("【" + DateTime.Now.ToString("HH:mm:ss:fff") + "】>Xhandler: 【" + methodNode.SelectSingleNode("name").InnerText + "】" + Properties.RunAspirateResource.strAspiratingExecute.ToString()); } else { launchView.AddLogs("【" + DateTime.Now.ToString("HH:mm:ss:fff") + "】> Xhandler: 【" + methodNode.SelectSingleNode("name").InnerText + "】" + "progress: Aspirate is executing,please wait for a moment."); } launchView.SetWaitOne();//暂停 ret = aspirateBll.ExecuteAspirate(aspirateMParam, isSimulator); #region 错误处理 result = DoError(ret, methodNode, strWell, xmlEnv, currentLengthOfTip, zAxisVal, isSimulator, (float)targetVolume); #endregion } } } else //移液设备 { #region 拆分目标孔位 List tipsTableList = new List(); for (int i = 0; i < charray.Length; i++) { tipsTable = dtWells.SingleOrDefault(t => t.lattice_id.Equals(lattice.lattice_id) && t.labware_id.Equals(strLabwareid) && t.wellname.Equals(wells[i])); if(tipsTable!=null) { tipsTableList.Add(tipsTable); } } List> tipsTablesArr = ControlCom.GetGroupTipsByColumn(tipsTableList); if ((float)labwares.a1_b1_distance < 20f && tipsTablesArr.Count > 1)//枪限制增加判断 { tipsTablesArr.Clear(); tipsTableList.Clear(); for (int i = 0; i < charray.Length; i++) { tipsTableList = new List(); tipsTable = dtWells.SingleOrDefault(t => t.lattice_id.Equals(lattice.lattice_id) && t.labware_id.Equals(strLabwareid) && t.wellname.Equals(wells[i])); if (tipsTable != null) { tipsTableList.Add(tipsTable); tipsTablesArr.Add(tipsTableList); } } } #endregion #region AspirateMParamSH for (int iTipChanelIndex = 0; iTipChanelIndex < tipsTablesArr.Count; iTipChanelIndex++) { AspirateMParamSH aspirateMParam = new AspirateMParamSH(); aspirateMParam.afterAirDelay = (int)liquid.after_aspirate_delay; aspirateMParam.armId = Convert.ToInt32(armId); aspirateMParam.aspirateAcceleration = (float)liquid.aspirate_acceleration; aspirateMParam.aspirateDeceleration = (float)liquid.aspirate_deceleration; aspirateMParam.aspirateDelay = (int)liquid.aspirate_delay; aspirateMParam.aspirateEnterSpeed = (float)liquid.aspirate_enter_speed; aspirateMParam.aspirateOutSpeed = (float)liquid.aspirate_out_speed; aspirateMParam.aspirateSpeed = (float)liquid.aspirate_speed; aspirateMParam.basezAxisVal = zAxisVal; aspirateMParam.beforeAirDelay = (int)liquid.before_aspirate_delay; if ((float)liquid.after_aspirate_volume == 0f) { aspirateMParam.isAfterAir = false; } else { aspirateMParam.isAfterAir = true; aspirateMParam.afterAirpAxisVal = (float)liquid.after_aspirate_volume; } if (liquid.before_aspirate_volume == 0d) { aspirateMParam.isBeforeAir = false; } else { aspirateMParam.isBeforeAir = true; aspirateMParam.beforeAirpAxisVal = (float)liquid.before_aspirate_volume; } if (liquid.after_a_liquid_volume == 0d) { aspirateMParam.isIncLiquidAfter = false; } else { aspirateMParam.isIncLiquidAfter = true; aspirateMParam.IncLiquidAfterpAxisVal = (float)liquid.after_a_liquid_volume; } if (liquid.before_a_liquid_volume == 0d) { aspirateMParam.isIncLiquidBefore = false; } else { aspirateMParam.isIncLiquidBefore = true; aspirateMParam.IncLiquidBeforepAxisVal = (float)liquid.before_a_liquid_volume; } aspirateMParam.liquidVolumeType = (int)Convert.ToInt32((liquid.liquid_volume_type != null ? "1" : liquid.liquid_volume_type)); // 精度校准后的体积 LiquidAccuracy liquidAccuracy = liquidAccuracyBll.GetLiquidAccuracyFromdb(Convert.ToInt32(liquidrangeidValue), Convert.ToInt32(armId), Convert.ToDouble(wellvolume), liquididValue); double targetVolume = liquidAccuracyBll.CalculateAspirateParamVolume(Convert.ToDouble(wellvolume), liquidAccuracy); float[] pAxisVal = new float[tipsTablesArr[iTipChanelIndex].Count]; for (int i = 0; i < tipsTablesArr[iTipChanelIndex].Count; i++) { pAxisVal[i] = (float)targetVolume; } aspirateMParam.pAxisVal = pAxisVal; if (labwares.labware_type_id.Equals("4")) { if (labwares.labware_tubeshelf_type == 1) { ObservableCollection labwareWellInfoList = DataRWDAL.LabwareDB.GetSpecialLabwareWellInfo(labwares.labware_id); LabwareWellInfo currentWellInfo = labwareWellInfoList.FirstOrDefault(x => x.labware_well_name.Equals(tipsTable.wellname)); Labware currentWellLabware = DataRWDAL.LabwareDB.GetLabware(currentWellInfo.well_labware_id); aspirateMParam.wellzAxisVal = tipsTable.axis_b_Z - ((float)currentWellLabware.labware_height); } else { aspirateMParam.wellzAxisVal = tipsTable.axis_b_Z - ((float)ControlCom.GetCentrifugalLabwer(labwares.piled_script).labware_height); } } else { aspirateMParam.wellzAxisVal = tipsTable.axis_b_Z - ((float)labwares.well_height);// - (float)liquid.well_top_length) ; } if (labwares.well_shape == 2) { aspirateMParam.wellDiameter = (float)labwares.well_top_x; } else if (labwares.well_shape == 1) { aspirateMParam.wellDiameter = (float)(labwares.well_mouth_radius * 2); } if (liquid.aspirate_is_knock_wall == 0) { aspirateMParam.isKnockWall = false; } else { aspirateMParam.isKnockWall = true; aspirateMParam.knockDirection = (int)liquid.knock_direction; aspirateMParam.knockSpeed = (int)Convert.ToInt32(liquid.knock_speed); aspirateMParam.knockWallDelay = (int)liquid.knock_wall_delay; aspirateMParam.knockWellxOryAxisVal = (float)liquid.knock_wall_length; aspirateMParam.knockWellzAxisVal = (float)liquid.knock_well_height; aspirateMParam.xAxisKnockOffsetVal = (float)liquid.knock_wall_x; aspirateMParam.yAxisKnockOffsetVal = (float)liquid.knock_wall_y; //aspirateMParam.wellDiameter=(float)labwares.well_mouth_radius; } //多点吸液 if (liquid.aspirate_well_bottom_length != "") { string[] strXoffset = liquid.aspirate_well_x.Split(','); string[] strYoffset = liquid.aspirate_well_y.Split(','); string[] strZoffset = liquid.aspirate_well_bottom_length.Split(','); if (liquid.aspirate_well_x.Contains(",")) { aspirateMParam.isMultiPointAspirate = true; aspirateMParam.multiPointAspirateCount = strXoffset.Length; aspirateMParam.xAxisAspirateOffsetVal = Utilities.GetFloatArrayFromStringArray(strXoffset); aspirateMParam.yAxisAspirateOffsetVal = Utilities.GetFloatArrayFromStringArray(strYoffset); aspirateMParam.zAxisAspirateOffsetVal = Utilities.GetFloatArrayFromStringArray(strZoffset); } else { aspirateMParam.isMultiPointAspirate = false; } //aspirateMParam.isMultiPointAspirate= } aspirateMParam.isMix = enableMix; if (aspirateMParam.isMix == true) { aspirateMParam.isMultiPointMix = enableMultiMix; aspirateMParam.mixAspiratePositionValue = Convert.ToInt32(mixAspiratePositionValue); aspirateMParam.mixAspiratePositionText = mixAspiratePositionText; if (labwares.labware_type_id.Equals("4")) { if (mixAspiratePositionValue == "0")//liquid { } else if (mixAspiratePositionValue == "1")//top { if (labwares.labware_tubeshelf_type == 1) { ObservableCollection labwareWellInfoList = DataRWDAL.LabwareDB.GetSpecialLabwareWellInfo(labwares.labware_id); LabwareWellInfo currentWellInfo = labwareWellInfoList.FirstOrDefault(x => x.labware_well_name.Equals(tipsTable.wellname)); Labware currentWellLabware = DataRWDAL.LabwareDB.GetLabware(currentWellInfo.well_labware_id); aspirateMParam.mixAspirateDistance = ((float)currentWellLabware.well_height - (float)mixAspirateDistance); } else { aspirateMParam.mixAspirateDistance = ((float)ControlCom.GetCentrifugalLabwer(labwares.piled_script).well_height - (float)mixAspirateDistance); } } else if (mixAspiratePositionValue == "2")//bottom { aspirateMParam.mixAspirateDistance = (float)mixAspirateDistance; } } else { if (mixAspiratePositionValue == "0")//liquid { } else if (mixAspiratePositionValue == "1")//top { aspirateMParam.mixAspirateDistance = ((float)labwares.well_height - (float)mixAspirateDistance); } else if (mixAspiratePositionValue == "2")//bottom { aspirateMParam.mixAspirateDistance = (float)mixAspirateDistance; } } aspirateMParam.mixAspirateSpeed = (float)Convert.ToDouble(mixAspirateSpeed); aspirateMParam.mixDispensePositionValue = Convert.ToInt32(mixDispensePositionValue); aspirateMParam.mixDispensePositionText = mixDispensePositionText; if (labwares.labware_type_id.Equals("4")) { if (mixDispensePositionValue == "0")//liquid { } else if (mixDispensePositionValue == "1")//top { if (labwares.labware_tubeshelf_type == 1) { ObservableCollection labwareWellInfoList = DataRWDAL.LabwareDB.GetSpecialLabwareWellInfo(labwares.labware_id); LabwareWellInfo currentWellInfo = labwareWellInfoList.FirstOrDefault(x => x.labware_well_name.Equals(tipsTable.wellname)); Labware currentWellLabware = DataRWDAL.LabwareDB.GetLabware(currentWellInfo.well_labware_id); aspirateMParam.mixDispenseDistance = ((float)currentWellLabware.well_height - (float)mixDispenseDistance); } else { aspirateMParam.mixDispenseDistance = ((float)ControlCom.GetCentrifugalLabwer(labwares.piled_script).well_height - (float)mixDispenseDistance); } } else if (mixDispensePositionValue == "2")//bottom { aspirateMParam.mixDispenseDistance = (float)mixDispenseDistance; } } else { if (mixDispensePositionValue == "0")//liquid { } else if (mixDispensePositionValue == "1")//top { aspirateMParam.mixDispenseDistance = ((float)labwares.well_height - (float)mixDispenseDistance); } else if (mixDispensePositionValue == "2")//bottom { aspirateMParam.mixDispenseDistance = (float)mixDispenseDistance; } } aspirateMParam.mixDispenseSpeed = (float)Convert.ToDouble(mixDispenseSpeed); aspirateMParam.mixvolume = (float)mixvolume; aspirateMParam.mixCount = mixcount; } else { aspirateMParam.mixAspirateDistance = 0; aspirateMParam.mixAspirateSpeed = 100; aspirateMParam.mixDispenseDistance = 0; aspirateMParam.mixDispenseSpeed = 100; } aspirateMParam.isSurvey = enableLiquidSensor; if (aspirateMParam.isSurvey == true) { if (labwares.labware_type_id.Equals("4")) { if (labwares.labware_tubeshelf_type == 1) { ObservableCollection labwareWellInfoList = DataRWDAL.LabwareDB.GetSpecialLabwareWellInfo(labwares.labware_id); LabwareWellInfo currentWellInfo = labwareWellInfoList.FirstOrDefault(x => x.labware_well_name.Equals(tipsTable.wellname)); Labware currentWellLabware = DataRWDAL.LabwareDB.GetLabware(currentWellInfo.well_labware_id); aspirateMParam.surveyInitzVal = tipsTable.axis_b_Z - ((float)currentWellLabware.labware_height - (float)liquidSensorDistance); aspirateMParam.surveyMaxzVal = tipsTable.axis_b_Z - ((float)currentWellLabware.labware_height - (float)liquidSensorEndDistance); aspirateMParam.surveySpeed = (float)liquidSensorSpeed; aspirateMParam.wellzAxisVal = tipsTable.axis_b_Z - ((float)currentWellLabware.labware_height); aspirateMParam.wellBottomzAxisVal = tipsTable.axis_b_Z; } else { Labware centrifugalLabware = ControlCom.GetCentrifugalLabwer(labwares.piled_script); aspirateMParam.surveyInitzVal = tipsTable.axis_b_Z - ((float)ControlCom.GetCentrifugalLabwer(labwares.piled_script).labware_height - (float)liquidSensorDistance); aspirateMParam.surveyMaxzVal = tipsTable.axis_b_Z - ((float)ControlCom.GetCentrifugalLabwer(labwares.piled_script).labware_height - (float)liquidSensorEndDistance); aspirateMParam.surveySpeed = (float)liquidSensorSpeed; aspirateMParam.wellzAxisVal = tipsTable.axis_b_Z - ((float)ControlCom.GetCentrifugalLabwer(labwares.piled_script).labware_height); aspirateMParam.wellBottomzAxisVal = tipsTable.axis_b_Z - ((float)ControlCom.GetCentrifugalLabwer(labwares.piled_script).labware_height - (float)ControlCom.GetCentrifugalLabwer(labwares.piled_script).well_height); } aspirateMParam.surveyFailHandleType = Convert.ToInt32(liquidSensorDisIdValue); if (enableLiquidFollow) { aspirateMParam.followupType = liquidFollowType; aspirateMParam.followupSpeed = (float)liquidFollowSpeed; aspirateMParam.followupDistance = (float)liquidFollowDistance; float area = 0.0f; if (labwares.well_shape == (int)WellSharpe.Round) { area = (float)(Math.PI * (float)ControlCom.GetCentrifugalLabwer(labwares.piled_script).well_mouth_radius * (float)ControlCom.GetCentrifugalLabwer(labwares.piled_script).well_mouth_radius); } else if (labwares.well_shape == (int)WellSharpe.Rectangle) { area = (float)((float)ControlCom.GetCentrifugalLabwer(labwares.piled_script).well_top_x * (float)ControlCom.GetCentrifugalLabwer(labwares.piled_script).well_top_y); } aspirateMParam.sectionalArea = area; aspirateMParam.isMixFollowup = enableMixFollow; } else { } } else { aspirateMParam.surveyRetryCount = liquidSensorCount; aspirateMParam.surveyInitzVal = tipsTable.axis_b_Z - ((float)labwares.well_height - (float)liquidSensorDistance); aspirateMParam.surveyMaxzVal = tipsTable.axis_b_Z - ((float)labwares.well_height - (float)liquidSensorEndDistance); aspirateMParam.surveySpeed = (float)liquidSensorSpeed; aspirateMParam.surveyCoefficient = Convert.ToInt32(liquidSensorRadio); aspirateMParam.wellzAxisVal = tipsTable.axis_b_Z - ((float)labwares.well_height);// - (float)liquid.well_top_length); aspirateMParam.wellBottomzAxisVal = tipsTable.axis_b_Z; aspirateMParam.surveyFailHandleType = Convert.ToInt32(liquidSensorDisIdValue); if (enableLiquidFollow) { aspirateMParam.followupType = liquidFollowType; aspirateMParam.followupSpeed = (float)liquidFollowSpeed; aspirateMParam.followupDistance = (float)liquidFollowDistance; float area = 0.0f; if (labwares.well_shape == (int)WellSharpe.Round) { area = (float)(Math.PI * labwares.well_mouth_radius * labwares.well_mouth_radius); } else if (labwares.well_shape == (int)WellSharpe.Rectangle) { area = (float)(labwares.well_top_x * labwares.well_top_y); } aspirateMParam.sectionalArea = area; aspirateMParam.isMixFollowup = enableMixFollow; } else { } } } else { } aspirateMParam.xAxisVal = tipsTablesArr[iTipChanelIndex][0].axis_b_X; aspirateMParam.yAxisVal = tipsTablesArr[iTipChanelIndex][0].axis_b_Y; // 如果有吸液位置高度的话,则减少高度 //float zVal = tipsTable.axis_b_Z - (float)liquid.aspirate_well_bottom_length; float zVal = 0f; if (liquid.aspirate_well_bottom_length != "") { string[] zOffsiteArray = liquid.aspirate_well_bottom_length.Split(','); if (liquid.aspirate_position_type == 0)//液体液面 { zVal = tipsTablesArr[iTipChanelIndex][0].axis_b_Z - (float)Convert.ToDouble(zOffsiteArray[0]);//底层用探测到的液面一下用aspirateMParam.zAxisAspirateOffsetVal } else if (liquid.aspirate_position_type == 1)//孔口 { zVal = aspirateMParam.wellzAxisVal + (float)Convert.ToDouble(zOffsiteArray[0]); } else if (liquid.aspirate_position_type == 2)//孔底 { if (labwares.labware_type_id.Equals("4")) { if (labwares.labware_tubeshelf_type == 1) { ObservableCollection labwareWellInfoList = DataRWDAL.LabwareDB.GetSpecialLabwareWellInfo(labwares.labware_id); LabwareWellInfo currentWellInfo = labwareWellInfoList.FirstOrDefault(x => x.labware_well_name.Equals(tipsTable.wellname)); Labware currentWellLabware = DataRWDAL.LabwareDB.GetLabware(currentWellInfo.well_labware_id); zVal = tipsTablesArr[iTipChanelIndex][0].axis_b_Z - (float)Convert.ToDouble(zOffsiteArray[0]) - ((float)currentWellLabware.labware_height-(float)currentWellLabware.well_height); } else { zVal = tipsTablesArr[iTipChanelIndex][0].axis_b_Z - (float)Convert.ToDouble(zOffsiteArray[0]) - ControlCom.CalculateWellBottomThickness(labwares.piled_script); } } else { zVal = tipsTablesArr[iTipChanelIndex][0].axis_b_Z - (float)Convert.ToDouble(zOffsiteArray[0]); } } } float[] fzAxisVal = new float[tipsTablesArr[iTipChanelIndex].Count]; int[] channelIds = new int[tipsTablesArr[iTipChanelIndex].Count]; //计算已用的通道号 int startChannelNum = 0; for(int k= 0;k< iTipChanelIndex; k++) { startChannelNum += tipsTablesArr[k].Count; } for (int k = 0; k < tipsTablesArr[iTipChanelIndex].Count; k++) { fzAxisVal[k] = zVal < 0 ? 0 : zVal; channelIds[k] = Convert.ToInt32(charray[k+ startChannelNum]); } aspirateMParam.channelId = channelIds; aspirateMParam.channelCount = channelIds.Length; aspirateMParam.zAxisVal = fzAxisVal; aspirateMParam.mixzAxisVal = (float)Convert.ToDouble(aspirateMParam.zAxisVal[0]); if (tipsTablesArr.Count > 1 && (float)labwares.a1_b1_distance < 20f) { aspirateMParam.yChannelGapVal = 25f; } else { aspirateMParam.yChannelGapVal = ((float)labwares.a1_b1_distance).Equals(0f) ? 9f : (float)labwares.a1_b1_distance; } #endregion wells = new string[tipsTablesArr[iTipChanelIndex].Count]; for (int k = 0; k < tipsTablesArr[iTipChanelIndex].Count;k++) { wells[k] = tipsTablesArr[iTipChanelIndex][k].wellname; } launchView.UpdateLabwareWells(tipsTablesArr[iTipChanelIndex][0], wells, 2); // 2:正在吸液红色 if (strCurrentCulture.Equals("zh-CN")) { launchView.AddLogs("【" + DateTime.Now.ToString("HH:mm:ss:fff") + "】>Xhandler: 【" + methodNode.SelectSingleNode("name").InnerText + "】" + Properties.RunAspirateResource.strAspiratingExecute.ToString()); } else { launchView.AddLogs("【" + DateTime.Now.ToString("HH:mm:ss:fff") + "】> Xhandler: 【" + methodNode.SelectSingleNode("name").InnerText + "】" + "progress: Aspirate is executing,please wait for a moment."); } launchView.SetWaitOne();//暂停 string strJson = JsonConvert.SerializeObject(aspirateMParam); LoggerHelper.InfoLog("吸液参数:" + strJson); ret = aspirateBll.ExecuteAspirate(aspirateMParam, isSimulator); #region 错误处理 //result = DoError(ret, methodNode, strWell, xmlEnv, currentLengthOfTip, zAxisVal, isSimulator, (float)targetVolume); if (ret.Result != ResultType.Success) { if (ret.AlarmCode == AlarmCodeType.吸堵)//吸液堵塞 { if (enableSensorBlock) { if (aspirateBlockDisIdValue == 0)//排掉样本到垃圾桶,更换枪头,重新吸样本 { #region 丢掉失败的枪头 List channels = ret.Details;//失败的枪头编号 UnloadTipsControl unloadTipsControl = new UnloadTipsControl(Shared.SoftwareInformation.currentculture); unloadTipsControl.launchView = launchView; //unloadTipsControl.socketTcpClientToRemote = socketTcpClientToRemote; //string strChannelBak = methodNode.SelectSingleNode("channels").InnerText; //methodNode.SelectSingleNode("channels").InnerText = string.Join(",", ret.Details); bool bUnloadResult = unloadTipsControl.ExecuteUnloadTipsInToTrash(xmlEnv.SelectNodes("platform"), methodNode, isSimulator); if (!bUnloadResult) { result = false; return result; } launchView.currentIsLoadingTips = false; #endregion #region 安装丢掉枪的通道 // 自动计算位置安装Tip var loadTipMethodNode = GetLoadTipMethod(); bool bLoadTipResult = ControlCom.LoadTipAutomation(xmlEnv.SelectNodes("platform"), loadTipMethodNode, isSimulator, launchView, null, 0); if (!bLoadTipResult) { return false; } //methodNode.SelectSingleNode("channels").InnerText = strChannelBak; #endregion #region 丢掉枪的通道重吸样本 AspirateMParamSH aspirateMParamSHBak = DeepCopyByReflection.Copy(aspirateMParam); int[] chArr = aspirateMParam.channelId; float xAxisVal = aspirateMParam.xAxisVal; float yAxisVal = aspirateMParam.yAxisVal; float yChannelGapVal = aspirateMParam.yChannelGapVal; bool bAspirateResult = ExecuteFailAfterAspirate(aspirateMParam, isSimulator, methodNode, strWell, slattice); #region 不支持失败的通道重新吸 /* //拆分丢掉枪的通道为一个一个重吸样本 for (int i = 0; i < ret.Details.Count; i++) { //重新计算通道和坐标 int chIndex = Utilities.GetArrayIndex(chArr, Convert.ToInt32(ret.Details[i])); aspirateMParam.yAxisVal = yAxisVal + yChannelGapVal * chIndex; aspirateMParam.channelCount = 1; aspirateMParam.channelId = new int[] { Convert.ToInt32(ret.Details[i]) }; aspirateMParam.pAxisVal = new float[] { aspirateMParamSHBak.pAxisVal[chIndex] }; //string[] currentSourceArray = new string[] { wells[chIndex] }; //string[] currentIndexArray = new string[] { indexArray[chIndex] }; bool bAspirateResult = ExecuteFailAfterAspirate(aspirateMParam, isSimulator, methodNode, strWell, slattice);//, //tipsTable, srcLabwareName, pVolumeOneBatchList[oneBatchIndex][0].ToString(), currentSourceArray, barcodeArray[0], currentIndexArray); //(aspirateMParamWH, isSimulator, liquidSensorDisIdValue, methodNode, //strWell, slattice, methodTransferFile, labwares, tipsTable, //srcLabwareName, pVolumeOneBatchList[oneBatchIndex][0].ToString(), sourceArray, barcodeArray[0], indexArray //, enableSensorBlock, aspirateBlockDisIdValue, //platformNodeList, xmlEnv, tipsTablesOneBatchList, pVolumeOneBatchList, oneBatchIndex); if (!bAspirateResult) { //return result; 再次失败不去处理了,继续做剩余的 } } */ #endregion #endregion } else if (aspirateBlockDisIdValue == 1)//排掉样本到垃圾桶,不换枪头,重新吸样本 { #region 堵塞的通道排样本到垃圾桶 // 获取当前垃圾桶台面板位信息 List lattices = LatticeDB.GetTrashLatticeDataByIdFromdb(Shared.ChanelArmId.ToString(), Shared.SoftwareInformation.software_device_number); Random random = new Random(); int index = random.Next(0, lattices.Count); DispenseMParamSH dispenseMParamWH = new DispenseMParamSH(); dispenseMParamWH = GenerateDispenseParamForTrashSH(methodNode, lattices[index], channelIds, targetVolume); dispenseMParamWH.yChannelGapVal = 20f; DispenseMParamSH dispenseMParamWHBak = DeepCopyByReflection.Copy(dispenseMParamWH); int[] chArr = dispenseMParamWH.channelId; float xAxisVal = dispenseMParamWH.xAxisVal; float yAxisVal = dispenseMParamWH.yAxisVal; float yChannelGapVal = dispenseMParamWH.yChannelGapVal; bool bDispenseResult = ExecuteDispenseIntoTrash(dispenseMParamWH, isSimulator, methodNode); #region X3不支持失败的通道排液 /* for (int i = 0; i < ret.Details.Count; i++) { //重新计算通道和坐标 int chIndex = Utilities.GetArrayIndex(chArr, Convert.ToInt32(ret.Details[i])); dispenseMParamWH.yAxisVal = yAxisVal + yChannelGapVal * chIndex; dispenseMParamWH.channelCount = 1; dispenseMParamWH.channelId = new int[] { Convert.ToInt32(ret.Details[i]) }; dispenseMParamWH.pAxisVal = new float[] { dispenseMParamWHBak.pAxisVal[chIndex] }; bool bDispenseResult = ExecuteDispenseIntoTrash(dispenseMParamWH, isSimulator, methodNode); //(dispenseMParamWH, isSimulator, liquidSensorDisIdValue, methodNode, //strWell, slattice, methodTransferFile, labwares, tipsTable, //srcLabwareName, pVolumeOneBatchList[oneBatchIndex][0].ToString(), sourceArray, barcodeArray[0], indexArray); if (!bDispenseResult) { //return result; 失败的就忽略了 } }*/ #endregion #endregion #region 堵塞的通道,重吸样本 AspirateMParamSH aspirateMParamSHBak = DeepCopyByReflection.Copy(aspirateMParam); chArr = aspirateMParam.channelId; xAxisVal = aspirateMParam.xAxisVal; yAxisVal = aspirateMParam.yAxisVal; yChannelGapVal = aspirateMParam.yChannelGapVal; bool bAspirateResult = ExecuteFailAfterAspirate(aspirateMParam, isSimulator, methodNode, strWell, slattice); #region 不支持失败的通道重新吸 /* //拆分丢掉枪的通道为一个一个重吸样本 for (int i = 0; i < ret.Details.Count; i++) { //重新计算通道和坐标 int chIndex = Utilities.GetArrayIndex(chArr, Convert.ToInt32(ret.Details[i])); aspirateMParam.yAxisVal = yAxisVal + yChannelGapVal * chIndex; aspirateMParam.channelCount = 1; aspirateMParam.channelId = new int[] { Convert.ToInt32(ret.Details[i]) }; aspirateMParam.pAxisVal = new float[] { aspirateMParamSHBak.pAxisVal[chIndex] }; bool bAspirateResult = ExecuteFailAfterAspirate(aspirateMParam, isSimulator, methodNode, strWell, slattice);//, //(aspirateMParamWH, isSimulator, liquidSensorDisIdValue, methodNode, //strWell, slattice, methodTransferFile, labwares, tipsTable, //srcLabwareName, pVolumeOneBatchList[oneBatchIndex][0].ToString(), sourceArray, barcodeArray[0], indexArray //, enableSensorBlock, aspirateBlockDisIdValue, //platformNodeList, xmlEnv, tipsTablesOneBatchList, pVolumeOneBatchList, oneBatchIndex); if (!bAspirateResult) { return result; } }*/ #endregion #endregion } else if (aspirateBlockDisIdValue == 2)//排掉样本到来源孔,不换枪头,吸空气 { #region 堵塞的通道排样本到来源孔 DispenseMParamSH dispenseMParamSH = new DispenseMParamSH(); dispenseMParamSH = GenerateDispenseParamForSH(methodNode, labwares, channelIds, targetVolume, tipsTable); dispenseMParamSH.yChannelGapVal = (float)labwares.a1_b1_distance; DispenseMParamSH dispenseMParamSHBak = DeepCopyByReflection.Copy(dispenseMParamSH); int[] chArr = dispenseMParamSH.channelId; float xAxisVal = dispenseMParamSH.xAxisVal; float yAxisVal = dispenseMParamSH.yAxisVal; float yChannelGapVal = dispenseMParamSH.yChannelGapVal; bool bDispenseResult = ExecuteDispenseIntoSource(dispenseMParamSH, isSimulator, liquidSensorDisIdValue, methodNode, strWell, slattice); #region 不支持失败的通道排 /* for (int i = 0; i < ret.Details.Count; i++) { //重新计算通道和坐标 int chIndex = Utilities.GetArrayIndex(chArr, Convert.ToInt32(ret.Details[i])); dispenseMParamSH.yAxisVal = yAxisVal + yChannelGapVal * chIndex; dispenseMParamSH.channelCount = 1; dispenseMParamSH.channelId = new int[] { Convert.ToInt32(ret.Details[i]) }; dispenseMParamSH.pAxisVal = new float[] { dispenseMParamSHBak.pAxisVal[chIndex] }; bool bDispenseResult = ExecuteDispenseIntoSource(dispenseMParamSH, isSimulator, liquidSensorDisIdValue, methodNode, strWell, slattice); if (!bDispenseResult) { //return result; 失败则继续执行后面的 } }*/ #endregion #endregion #region 堵塞的通道,吸空气 AspirateMParamSH aspirateMParamSHBak = DeepCopyByReflection.Copy(aspirateMParam); chArr = aspirateMParam.channelId; xAxisVal = aspirateMParam.xAxisVal; yAxisVal = aspirateMParam.yAxisVal; yChannelGapVal = aspirateMParam.yChannelGapVal; for (int k = 0; k < chArr.Length; k++) { aspirateMParam.zAxisVal[k] = 0f; } aspirateMParam.isSurvey = false; bool bAspirateResult = ExecuteFailAfterAspirate(aspirateMParam, isSimulator, methodNode, strWell, slattice); #region 不支持失败的通道吸 /* //拆分丢掉枪的通道为一个一个重吸样本 for (int i = 0; i < ret.Details.Count; i++) { //重新计算通道和坐标 int chIndex = Utilities.GetArrayIndex(chArr, Convert.ToInt32(ret.Details[i])); aspirateMParam.yAxisVal = yAxisVal + yChannelGapVal * chIndex; aspirateMParam.channelCount = 1; aspirateMParam.channelId = new int[] { Convert.ToInt32(ret.Details[i]) }; aspirateMParam.pAxisVal = new float[] { aspirateMParamSHBak.pAxisVal[chIndex] }; aspirateMParam.zAxisVal = new float[] { 0f }; //string[] currentSourceArray = new string[] { sourceArray[chIndex] }; //string[] currentIndexArray = new string[] { indexArray[chIndex] }; bool bAspirateResult = ExecuteFailAfterAspirate(aspirateMParam, isSimulator, methodNode, strWell, slattice);//, //ExecuteAspirate(aspirateMParamWH, isSimulator, liquidSensorDisIdValue, methodNode, //strWell, slattice, methodTransferFile, labwares, tipsTable, //srcLabwareName, pVolumeOneBatchList[oneBatchIndex][0].ToString(), sourceArray, barcodeArray[0], indexArray //, enableSensorBlock, aspirateBlockDisIdValue, //platformNodeList, xmlEnv, tipsTablesOneBatchList, pVolumeOneBatchList, oneBatchIndex); if (!bAspirateResult) { return result; } }*/ #endregion #endregion } else if (aspirateBlockDisIdValue == 3)//忽略此错误,继续执行后续操作 { if (strCurrentCulture.Equals("zh-CN")) { launchView.AddLogs("【" + DateTime.Now.ToString("HH:mm:ss:fff") + "】>Xhandler: 【" + methodNode.SelectSingleNode("name").InnerText + "】" + Properties.MachineRunResource.strProgress.ToString() + Properties.RunAspirateResource.strAspirateFail.ToString() + ret.AlarmInfo + " 体积 " + pAxisVal[0].ToString() + "ul 孔 " + strWell + " 板位 " + slattice.lattice_num); LoggerRunHelper.InfoLog("【" + DateTime.Now.ToString("HH:mm:ss:fff") + "】>Xhandler: 【" + methodNode.SelectSingleNode("name").InnerText + "】" + Properties.MachineRunResource.strProgress.ToString() + Properties.RunAspirateResource.strAspirateFail.ToString() + ret.AlarmInfo + " 体积 " + pAxisVal[0].ToString() + "ul 孔 " + strWell + " 板位 " + slattice.lattice_num); } else { launchView.AddLogs("【" + DateTime.Now.ToString("HH:mm:ss:fff") + "】>Xhandler: 【" + methodNode.SelectSingleNode("name").InnerText + "】progress: Aspirate was failed on " + strWell + " of " + slattice.lattice_num + " lattice! Error info:" + ret.AlarmInfo); LoggerRunHelper.InfoLog("【" + DateTime.Now.ToString("HH:mm:ss:fff") + "】>Xhandler: 【" + methodNode.SelectSingleNode("name").InnerText + "】progress: Aspirate was failed on " + strWell + " of " + slattice.lattice_num + " lattice! Error info:" + ret.AlarmInfo); } } else if (aspirateBlockDisIdValue == 4)//终止执行 { if (strCurrentCulture.Equals("zh-CN")) { launchView.AddLogs("【" + DateTime.Now.ToString("HH:mm:ss:fff") + "】>Xhandler: 【" + methodNode.SelectSingleNode("name").InnerText + "】" + Properties.MachineRunResource.strProgress.ToString() + Properties.RunAspirateResource.strAspirateFail.ToString() + ret.AlarmInfo + " 体积 " + pAxisVal[0].ToString() + "ul 孔 " + strWell + " 板位 " + slattice.lattice_num); LoggerRunHelper.InfoLog("【" + DateTime.Now.ToString("HH:mm:ss:fff") + "】>Xhandler: 【" + methodNode.SelectSingleNode("name").InnerText + "】" + Properties.MachineRunResource.strProgress.ToString() + Properties.RunAspirateResource.strAspirateFail.ToString() + ret.AlarmInfo + " 体积 " + pAxisVal[0].ToString() + "ul 孔 " + strWell + " 板位 " + slattice.lattice_num); } else { launchView.AddLogs("【" + DateTime.Now.ToString("HH:mm:ss:fff") + "】>Xhandler: 【" + methodNode.SelectSingleNode("name").InnerText + "】progress: Aspirate was failed on " + strWell + " of " + slattice.lattice_num + " lattice! Error info:" + ret.AlarmInfo); LoggerRunHelper.InfoLog("【" + DateTime.Now.ToString("HH:mm:ss:fff") + "】>Xhandler: 【" + methodNode.SelectSingleNode("name").InnerText + "】progress: Aspirate was failed on " + strWell + " of " + slattice.lattice_num + " lattice! Error info:" + ret.AlarmInfo); } result = false; //launchView.addDataIntoReport(srcLabwareName, pVolumeOneBatchList[oneBatchIndex][0].ToString(), sourceArray, "block", barcodeArray[0], indexArray); return result; } else if (aspirateBlockDisIdValue == 5)//弹窗选择 { OperateDialog plsConfirmOper = null; if (!launchView.isRemotingOper) { System.Windows.Application.Current.Dispatcher.Invoke(new Action(() => { plsConfirmOper = new OperateDialog(strCurrentCulture.Equals("zh-CN") ? Properties.RunAspirateResource.strFailWhatToDo + "失败通道号:" + string.Join(",", ret.Details) : "Aspirate are fail! What do you want to do? Failed channels:" + string.Join(",", ret.Details)); plsConfirmOper.ShowDialog(); })); } if (plsConfirmOper != null && plsConfirmOper.OperMark == NodeOperationTypeEnum.Retry) // 重试 { AspirateMParamSH aspirateMParamSHBak = DeepCopyByReflection.Copy(aspirateMParam); int[] chArr = aspirateMParam.channelId; float xAxisVal = aspirateMParam.xAxisVal; float yAxisVal = aspirateMParam.yAxisVal; float yChannelGapVal = aspirateMParam.yChannelGapVal; bool bAspirateResult = ExecuteFailAfterAspirate(aspirateMParam, isSimulator, methodNode, strWell, slattice); #region 不支持失败的通道吸 /* //拆分丢掉枪的通道为一个一个重吸样本 for (int i = 0; i < ret.Details.Count; i++) { //重新计算通道和坐标 int chIndex = Utilities.GetArrayIndex(chArr, Convert.ToInt32(ret.Details[i])); aspirateMParam.yAxisVal = yAxisVal + yChannelGapVal * chIndex; aspirateMParam.channelCount = 1; aspirateMParam.channelId = new int[] { Convert.ToInt32(ret.Details[i]) }; aspirateMParam.pAxisVal = new float[] { aspirateMParamSHBak.pAxisVal[chIndex] }; aspirateMParam.zAxisVal = new float[] { 0f }; //string[] currentSourceArray = new string[] { sourceArray[chIndex] }; //string[] currentIndexArray = new string[] { indexArray[chIndex] }; bool bAspirateResult = ExecuteFailAfterAspirate(aspirateMParam, isSimulator, methodNode, strWell, slattice);//, if (!bAspirateResult) { //return result; 再次失败就继续 } }*/ #endregion //ExecuteAspirate(aspirateMParamWH, isSimulator, liquidSensorDisIdValue, methodNode, // strWell, slattice, methodTransferFile, labwares, tipsTable, // srcLabwareName, pVolumeOneBatchList[oneBatchIndex][0].ToString(), sourceArray, barcodeArray[0], indexArray // , enableSensorBlock, aspirateBlockDisIdValue, // platformNodeList, xmlEnv, tipsTablesOneBatchList, pVolumeOneBatchList, oneBatchIndex); //return result; } else if (plsConfirmOper != null && plsConfirmOper.OperMark == NodeOperationTypeEnum.Cancel) // 终止 { if (strCurrentCulture.Equals("zh-CN")) { launchView.AddLogs("【" + DateTime.Now.ToString("HH:mm:ss:fff") + "】>Xhandler: 【" + methodNode.SelectSingleNode("name").InnerText + "】" + Properties.MachineRunResource.strProgress + Properties.RunAspirateResource.strLoadTipWasStopped); } else { launchView.AddLogs("【" + DateTime.Now.ToString("HH:mm:ss:fff") + "】>Xhandler: 【" + methodNode.SelectSingleNode("name").InnerText + "】progress:load tip was stopped!"); } result = false; return result; } else if (plsConfirmOper != null && plsConfirmOper.OperMark == NodeOperationTypeEnum.Continue) // 跳过 { if (strCurrentCulture.Equals("zh-CN")) { launchView.AddLogs("【" + DateTime.Now.ToString("HH:mm:ss:fff") + "】>Xhandler: 【" + methodNode.SelectSingleNode("name").InnerText + "】" + Properties.MachineRunResource.strProgress + Properties.RunAspirateResource.strLoadTipWasSkipped); } else { launchView.AddLogs("【" + DateTime.Now.ToString("HH:mm:ss:fff") + "】>Xhandler: 【" + methodNode.SelectSingleNode("name").InnerText + "】progress:load tip was skipped!"); } } } } else { if (strCurrentCulture.Equals("zh-CN")) { launchView.AddLogs("【" + DateTime.Now.ToString("HH:mm:ss:fff") + "】>Xhandler: 【" + methodNode.SelectSingleNode("name").InnerText + "】" + Properties.MachineRunResource.strProgress.ToString() + Properties.RunAspirateResource.strAspirateFail.ToString() + ret.AlarmInfo + " 体积 " + pAxisVal[0].ToString() + "ul 孔 " + strWell + " 板位 " + slattice.lattice_num); LoggerRunHelper.InfoLog("【" + DateTime.Now.ToString("HH:mm:ss:fff") + "】>Xhandler: 【" + methodNode.SelectSingleNode("name").InnerText + "】" + Properties.MachineRunResource.strProgress.ToString() + Properties.RunAspirateResource.strAspirateFail.ToString() + ret.AlarmInfo + " 体积 " + pAxisVal[0].ToString() + "ul 孔 " + strWell + " 板位 " + slattice.lattice_num); } else { launchView.AddLogs("【" + DateTime.Now.ToString("HH:mm:ss:fff") + "】>Xhandler: 【" + methodNode.SelectSingleNode("name").InnerText + "】progress: Aspirate was failed on " + strWell + " of " + slattice.lattice_num + " lattice! Error info:" + ret.AlarmInfo); LoggerRunHelper.InfoLog("【" + DateTime.Now.ToString("HH:mm:ss:fff") + "】>Xhandler: 【" + methodNode.SelectSingleNode("name").InnerText + "】progress: Aspirate was failed on " + strWell + " of " + slattice.lattice_num + " lattice! Error info:" + ret.AlarmInfo); } result = false; //launchView.addDataIntoReport(srcLabwareName, pVolumeOneBatchList[oneBatchIndex][0].ToString(), sourceArray, "block", barcodeArray[0], indexArray); return result; } } else if (ret.AlarmCode == AlarmCodeType.液面探测失败) { if (liquidSensorDisIdValue == "0")//终止 { if (strCurrentCulture.Equals("zh-CN")) { launchView.AddLogs("【" + DateTime.Now.ToString("HH:mm:ss:fff") + "】>Xhandler: 【" + methodNode.SelectSingleNode("name").InnerText + "】" + Properties.MachineRunResource.strProgress.ToString() + Properties.RunAspirateResource.strAspirateFail.ToString() + ret.AlarmInfo + " 体积 " + pAxisVal[0].ToString() + "ul 孔 " + strWell + " 板位 " + slattice.lattice_num); LoggerRunHelper.InfoLog("【" + DateTime.Now.ToString("HH:mm:ss:fff") + "】>Xhandler: 【" + methodNode.SelectSingleNode("name").InnerText + "】" + Properties.MachineRunResource.strProgress.ToString() + Properties.RunAspirateResource.strAspirateFail.ToString() + ret.AlarmInfo + " 体积 " + pAxisVal[0].ToString() + "ul 孔 " + strWell + " 板位 " + slattice.lattice_num); } else { launchView.AddLogs("【" + DateTime.Now.ToString("HH:mm:ss:fff") + "】>Xhandler: 【" + methodNode.SelectSingleNode("name").InnerText + "】progress: Aspirate was failed on " + strWell + " of " + slattice.lattice_num + " lattice! Error info:" + ret.AlarmInfo); LoggerRunHelper.InfoLog("【" + DateTime.Now.ToString("HH:mm:ss:fff") + "】>Xhandler: 【" + methodNode.SelectSingleNode("name").InnerText + "】progress: Aspirate was failed on " + strWell + " of " + slattice.lattice_num + " lattice! Error info:" + ret.AlarmInfo); } result = false; //launchView.addDataIntoReport(srcLabwareName, pVolumeOneBatchList[oneBatchIndex][0].ToString(), sourceArray, "block", barcodeArray[0], indexArray); return result; } else if (liquidSensorDisIdValue == "1")//从孔底继续执行--不处理 { } else if (liquidSensorDisIdValue == "2")//从孔口继续执行--不处理 { } else if (liquidSensorDisIdValue == "4")//弹框选择 { OperateDialog plsConfirmOper = null; if (!launchView.isRemotingOper) { System.Windows.Application.Current.Dispatcher.Invoke(new Action(() => { plsConfirmOper = new OperateDialog(strCurrentCulture.Equals("zh-CN") ? Properties.RunAspirateResource.strFailWhatToDo + " 失败通道:" + string.Join(",", ret.Details) : "Aspirate are fail, fialed channel:" + string.Join(",", ret.Details) + "! What do you want to do?"); plsConfirmOper.ShowDialog(); })); } if (plsConfirmOper != null && plsConfirmOper.OperMark == NodeOperationTypeEnum.Retry) // 重试 { AspirateMParamSH aspirateMParamSHBak = DeepCopyByReflection.Copy(aspirateMParam); int[] chArr = aspirateMParam.channelId; float xAxisVal = aspirateMParam.xAxisVal; float yAxisVal = aspirateMParam.yAxisVal; float yChannelGapVal = aspirateMParam.yChannelGapVal; bool bAspirateResult = ExecuteFailAfterAspirate(aspirateMParam, isSimulator, methodNode, strWell, slattice);// if (!bAspirateResult) { //return result; 再次失败就继续 } #region X3设备不支持失败的通道重试 /* //拆分丢掉枪的通道为一个一个重吸样本 for (int i = 0; i < ret.Details.Count; i++) { //重新计算通道和坐标 int chIndex = Utilities.GetArrayIndex(chArr, Convert.ToInt32(ret.Details[i])); aspirateMParam.yAxisVal = yAxisVal + yChannelGapVal * chIndex; aspirateMParam.channelCount = 1; aspirateMParam.channelId = new int[] { Convert.ToInt32(ret.Details[i]) }; aspirateMParam.pAxisVal = new float[] { aspirateMParamSHBak.pAxisVal[chIndex] }; aspirateMParam.zAxisVal = new float[] { 0f }; //string[] currentSourceArray = new string[] { sourceArray[chIndex] }; //string[] currentIndexArray = new string[] { indexArray[chIndex] }; bool bAspirateResult = ExecuteFailAfterAspirate(aspirateMParam, isSimulator, methodNode, strWell, slattice);// if (!bAspirateResult) { //return result; 再次失败就继续 } }*/ #endregion //ExecuteAspirate(aspirateMParamWH, isSimulator, liquidSensorDisIdValue, methodNode, // strWell, slattice, methodTransferFile, labwares, tipsTable, // srcLabwareName, pVolumeOneBatchList[oneBatchIndex][0].ToString(), sourceArray, barcodeArray[0], indexArray // , enableSensorBlock, aspirateBlockDisIdValue, // platformNodeList, xmlEnv, tipsTablesOneBatchList, pVolumeOneBatchList, oneBatchIndex); //return result; } else if (plsConfirmOper != null && plsConfirmOper.OperMark == NodeOperationTypeEnum.Cancel) // 终止 { if (strCurrentCulture.Equals("zh-CN")) { launchView.AddLogs("【" + DateTime.Now.ToString("HH:mm:ss:fff") + "】>Xhandler: 【" + methodNode.SelectSingleNode("name").InnerText + "】" + Properties.MachineRunResource.strProgress + Properties.RunAspirateResource.strLoadTipWasStopped); } else { launchView.AddLogs("【" + DateTime.Now.ToString("HH:mm:ss:fff") + "】>Xhandler: 【" + methodNode.SelectSingleNode("name").InnerText + "】progress:load tip was stopped!"); } result = false; return result; } else if (plsConfirmOper != null && plsConfirmOper.OperMark == NodeOperationTypeEnum.Continue) // 跳过 { if (strCurrentCulture.Equals("zh-CN")) { launchView.AddLogs("【" + DateTime.Now.ToString("HH:mm:ss:fff") + "】>Xhandler: 【" + methodNode.SelectSingleNode("name").InnerText + "】" + Properties.MachineRunResource.strProgress + Properties.RunAspirateResource.strLoadTipWasSkipped); } else { launchView.AddLogs("【" + DateTime.Now.ToString("HH:mm:ss:fff") + "】>Xhandler: 【" + methodNode.SelectSingleNode("name").InnerText + "】progress:load tip was skipped!"); } } } else if (liquidSensorDisIdValue == "5")//从当前继续执行--不处理 { //PlsConfirmOper } } else if (ret.AlarmCode == AlarmCodeType.吸空)//吸空 { string[] indexOfWell = new string[aspirateMParam.channelCount]; if (aspirateAirDisIdValue == 0)//从孔底再次吸液 { methodNode.SelectSingleNode("channels").InnerText = string.Join(",", ret.Details); int[] channelArray = new int[ret.Details.Count]; float[] wellBottomArray = new float[ret.Details.Count]; float[] wellVolumeArray = new float[ret.Details.Count]; int[] channelIndexArray = new int[ret.Details.Count];//通道在源数组中的下标 for (int q = 0; q < ret.Details.Count; q++) { channelArray[q] = Convert.ToInt32(ret.Details[q]); for (int p = 0; p < aspirateMParam.channelCount; p++) { if (aspirateMParam.channelId[p] == Convert.ToInt32(ret.Details[q])) { channelIndexArray[q] = p; break; } } wellBottomArray[q] = aspirateMParam.wellBottomzAxisVal; } if (ret.Details.Count > 0) //失败的孔继续执行 { aspirateMParam.channelId = channelArray; aspirateMParam.channelCount = channelArray.Length; aspirateMParam.zAxisVal = wellBottomArray; for (int q = 0; q < channelIndexArray.Length; q++) { wellVolumeArray[q] = aspirateMParam.pAxisVal[channelIndexArray[q]]; } aspirateMParam.pAxisVal = wellVolumeArray; AspirateMParamSH aspirateMParamSHBak = DeepCopyByReflection.Copy(aspirateMParam); int[] chArr = aspirateMParamSHBak.channelId; float yAxisVal = aspirateMParamSHBak.yAxisVal; float yChannelGapVal = aspirateMParamSHBak.yChannelGapVal; if (labwares.labware_height >= 22 && aspirateMParam.yChannelGapVal < 15) //拆分做 { List channelArrayFailed = new List();//记录下这次失败的通道 for (int q = 0; q < ret.Details.Count; q++) { //重新计算通道和坐标 int chIndex = Utilities.GetArrayIndex(chArr, Convert.ToInt32(ret.Details[q])); aspirateMParam.yAxisVal = yAxisVal + yChannelGapVal * chIndex; aspirateMParam.channelCount = 1; aspirateMParam.channelId = new int[] { Convert.ToInt32(ret.Details[q]) }; aspirateMParam.pAxisVal = new float[] { aspirateMParamSHBak.pAxisVal[chIndex] }; aspirateMParam.zAxisVal = new float[] { aspirateMParam.wellBottomzAxisVal }; //string[] currentSourceArray = new string[] { wells[chIndex] }; //string[] currentIndexArray = new string[] { indexArray[chIndex] }; aspirateMParam.yChannelGapVal = 20f; ret = aspirateBll.ExecuteAspirate(aspirateMParam, isSimulator); if (ret.Result != ResultType.Success) { channelArrayFailed.Add(aspirateMParam.channelId[0].ToString()); } else { } } string strWellArray = string.Empty; for (int q = 0; q < channelArrayFailed.Count; q++) { int chIndex = Utilities.GetArrayIndex(chArr, Convert.ToInt32(channelArrayFailed[q])); strWellArray += wells[chIndex] + ","; } if (strWellArray != string.Empty) { strWellArray = strWellArray.Substring(0, strWellArray.Length - 1); } if (channelArrayFailed.Count > 0) { if (strCurrentCulture.Equals("zh-CN")) { launchView.AddLogs("【" + DateTime.Now.ToString("HH:mm:ss:fff") + "】>Xhandler: 【" + methodNode.SelectSingleNode("name").InnerText + "】" + Properties.MachineRunResource.strProgress.ToString() + Properties.RunTransferFileResource.strFileAspirateFail.ToString() + ret.AlarmInfo + "孔 " + strWellArray + " 板位 " + slattice.lattice_num); LoggerRunHelper.InfoLog("【" + DateTime.Now.ToString("HH:mm:ss:fff") + "】>Xhandler: 【" + methodNode.SelectSingleNode("name").InnerText + "】" + Properties.MachineRunResource.strProgress.ToString() + Properties.RunTransferFileResource.strFileAspirateFail.ToString() + ret.AlarmInfo + "孔 " + strWellArray + " 板位 " + slattice.lattice_num); } else { launchView.AddLogs("【" + DateTime.Now.ToString("HH:mm:ss:fff") + "】>Xhandler: 【" + methodNode.SelectSingleNode("name").InnerText + "】progress: Aspirate was failed on " + strWellArray + " of " + slattice.lattice_num + " lattice! Error info:" + ret.AlarmInfo); LoggerRunHelper.InfoLog("【" + DateTime.Now.ToString("HH:mm:ss:fff") + "】>Xhandler: 【" + methodNode.SelectSingleNode("name").InnerText + "】progress: Aspirate was failed on " + strWellArray + " of " + slattice.lattice_num + " lattice! Error info:" + ret.AlarmInfo); } result = false; string[] strResultArray = new string[aspirateMParamSHBak.channelCount]; for (int q = 0; q < aspirateMParamSHBak.channelCount; q++) { strResultArray[q] = "pass"; for (int p = 0; p < channelArrayFailed.Count; p++) { int chIndex = Utilities.GetArrayIndex(chArr, Convert.ToInt32(channelArrayFailed[p])); if (q == chIndex) { strResultArray[q] = "block"; break; } } } //launchView.addDataIntoReport(latticenum, targetVolume.ToString(), wells, strResultArray, labwares.labware_barcode, 0); return result; } else { if (strCurrentCulture.Equals("zh-CN")) { launchView.AddLogs("【" + DateTime.Now.ToString("HH:mm:ss:fff") + "】>Xhandler: 【" + methodNode.SelectSingleNode("name").InnerText + "】" + Properties.MachineRunResource.strProgress.ToString() + Properties.RunTransferFileResource.strFileAspirateSuccess.ToString() + " 体积 " + targetVolume.ToString() + "ul 孔 " + strWellArray + " 板位 " + slattice.lattice_num); LoggerRunHelper.InfoLog("【" + DateTime.Now.ToString("HH:mm:ss:fff") + "】>Xhandler: 【" + methodNode.SelectSingleNode("name").InnerText + "】" + Properties.MachineRunResource.strProgress.ToString() + Properties.RunTransferFileResource.strFileAspirateSuccess.ToString() + " 体积 " + targetVolume.ToString() + "ul 孔 " + strWellArray + " 板位 " + slattice.lattice_num); } else { launchView.AddLogs("【" + DateTime.Now.ToString("HH:mm:ss:fff") + "】>Xhandler: 【" + methodNode.SelectSingleNode("name").InnerText + "】progress:Aspirate was successful on " + strWellArray + " of " + slattice.lattice_num + " lattice!"); LoggerRunHelper.InfoLog("【" + DateTime.Now.ToString("HH:mm:ss:fff") + "】>Xhandler: 【" + methodNode.SelectSingleNode("name").InnerText + "】progress:Aspirate was successful on " + strWellArray + " of " + slattice.lattice_num + " lattice!"); } if (labwares.labware_type_id == EnumManagement.GetEnumValue(ConsumableTypeEnum.Through).ToString()) // 试剂槽 { launchView.UpdateLabwareWells(tipsTable, strWellArray.Split(','), 1); // 无效孔白色 } launchView.addDataIntoReport(latticenum, targetVolume.ToString(), wells, "pass", labwares.labware_barcode, indexOfWell); } } else { string strWellArray = string.Empty; for (int q = 0; q < ret.Details.Count; q++) { int chIndex = Utilities.GetArrayIndex(chArr, Convert.ToInt32(ret.Details[q])); strWellArray += wells[chIndex] + ","; } if (strWellArray != string.Empty) { strWellArray = strWellArray.Substring(0, strWellArray.Length - 1); } ret = aspirateBll.ExecuteAspirate(aspirateMParam, isSimulator); if (ret.Result != ResultType.Success) { if (strCurrentCulture.Equals("zh-CN")) { launchView.AddLogs("【" + DateTime.Now.ToString("HH:mm:ss:fff") + "】>Xhandler: 【" + methodNode.SelectSingleNode("name").InnerText + "】" + Properties.MachineRunResource.strProgress.ToString() + Properties.RunTransferFileResource.strFileAspirateFail.ToString() + ret.AlarmInfo + "孔 " + strWellArray + " 板位 " + slattice.lattice_num); LoggerRunHelper.InfoLog("【" + DateTime.Now.ToString("HH:mm:ss:fff") + "】>Xhandler: 【" + methodNode.SelectSingleNode("name").InnerText + "】" + Properties.MachineRunResource.strProgress.ToString() + Properties.RunTransferFileResource.strFileAspirateFail.ToString() + ret.AlarmInfo + "孔 " + strWellArray + " 板位 " + slattice.lattice_num); } else { launchView.AddLogs("【" + DateTime.Now.ToString("HH:mm:ss:fff") + "】>Xhandler: 【" + methodNode.SelectSingleNode("name").InnerText + "】progress: Aspirate was failed on " + strWellArray + " of " + slattice.lattice_num + " lattice! Error info:" + ret.AlarmInfo); LoggerRunHelper.InfoLog("【" + DateTime.Now.ToString("HH:mm:ss:fff") + "】>Xhandler: 【" + methodNode.SelectSingleNode("name").InnerText + "】progress: Aspirate was failed on " + strWellArray + " of " + slattice.lattice_num + " lattice! Error info:" + ret.AlarmInfo); } result = false; string[] strResultArray = new string[aspirateMParamSHBak.channelCount]; for (int q = 0; q < aspirateMParamSHBak.channelCount; q++) { strResultArray[q] = "pass"; for (int p = 0; p < ret.Details.Count; p++) { int chIndex = Utilities.GetArrayIndex(chArr, Convert.ToInt32(ret.Details[p])); if (q == chIndex) { strResultArray[q] = "block"; break; } } } //launchView.addDataIntoReport(latticenum, targetVolume.ToString(), wells, strResultArray, labwares.labware_barcode, 0); return result; } else { if (strCurrentCulture.Equals("zh-CN")) { launchView.AddLogs("【" + DateTime.Now.ToString("HH:mm:ss:fff") + "】>Xhandler: 【" + methodNode.SelectSingleNode("name").InnerText + "】" + Properties.MachineRunResource.strProgress.ToString() + Properties.RunTransferFileResource.strFileAspirateSuccess.ToString() + " 体积 " + targetVolume.ToString() + "ul 孔 " + strWellArray + " 板位 " + slattice.lattice_num); LoggerRunHelper.InfoLog("【" + DateTime.Now.ToString("HH:mm:ss:fff") + "】>Xhandler: 【" + methodNode.SelectSingleNode("name").InnerText + "】" + Properties.MachineRunResource.strProgress.ToString() + Properties.RunTransferFileResource.strFileAspirateSuccess.ToString() + " 体积 " + targetVolume.ToString() + "ul 孔 " + strWellArray + " 板位 " + slattice.lattice_num); } else { launchView.AddLogs("【" + DateTime.Now.ToString("HH:mm:ss:fff") + "】>Xhandler: 【" + methodNode.SelectSingleNode("name").InnerText + "】progress:Aspirate was successful on " + strWellArray + " of " + slattice.lattice_num + " lattice!"); LoggerRunHelper.InfoLog("【" + DateTime.Now.ToString("HH:mm:ss:fff") + "】>Xhandler: 【" + methodNode.SelectSingleNode("name").InnerText + "】progress:Aspirate was successful on " + strWellArray + " of " + slattice.lattice_num + " lattice!"); } if (labwares.labware_type_id == EnumManagement.GetEnumValue(ConsumableTypeEnum.Through).ToString()) // 试剂槽 { launchView.UpdateLabwareWells(tipsTable, strWell.Split(','), 1); // 无效孔白色 } launchView.addDataIntoReport(latticenum, targetVolume.ToString(), wells, "pass", labwares.labware_barcode, indexOfWell); } } } } else if (aspirateAirDisIdValue == 1)//当前位置吸空气 { if (strCurrentCulture.Equals("zh-CN")) { launchView.AddLogs("【" + DateTime.Now.ToString("HH:mm:ss:fff") + "】>Xhandler: 【" + methodNode.SelectSingleNode("name").InnerText + "】" + Properties.MachineRunResource.strProgress.ToString() + Properties.RunTransferFileResource.strFileAspirateSuccess.ToString() + " 体积 " + targetVolume.ToString() + "ul 孔 " + strWell + " 板位 " + slattice.lattice_num); LoggerRunHelper.InfoLog("【" + DateTime.Now.ToString("HH:mm:ss:fff") + "】>Xhandler: 【" + methodNode.SelectSingleNode("name").InnerText + "】" + Properties.MachineRunResource.strProgress.ToString() + Properties.RunTransferFileResource.strFileAspirateSuccess.ToString() + " 体积 " + targetVolume.ToString() + "ul 孔 " + strWell + " 板位 " + slattice.lattice_num); } else { launchView.AddLogs("【" + DateTime.Now.ToString("HH:mm:ss:fff") + "】>Xhandler: 【" + methodNode.SelectSingleNode("name").InnerText + "】progress:Aspirate was successful on " + strWell + " of " + slattice.lattice_num + " lattice!"); LoggerRunHelper.InfoLog("【" + DateTime.Now.ToString("HH:mm:ss:fff") + "】>Xhandler: 【" + methodNode.SelectSingleNode("name").InnerText + "】progress:Aspirate was successful on " + strWell + " of " + slattice.lattice_num + " lattice!"); } if (labwares.labware_type_id == EnumManagement.GetEnumValue(ConsumableTypeEnum.Through).ToString()) // 试剂槽 { launchView.UpdateLabwareWells(tipsTable, strWell.Split(','), 1); // 无效孔白色 } launchView.addDataIntoReport(latticenum, targetVolume.ToString(), wells, "pass", labwares.labware_barcode, indexOfWell); } else if (aspirateAirDisIdValue == 2)//忽略 { if (strCurrentCulture.Equals("zh-CN")) { launchView.AddLogs("【" + DateTime.Now.ToString("HH:mm:ss:fff") + "】>Xhandler: 【" + methodNode.SelectSingleNode("name").InnerText + "】" + Properties.MachineRunResource.strProgress.ToString() + Properties.RunTransferFileResource.strFileAspirateFail.ToString() + ret.AlarmInfo + " 体积 " + targetVolume.ToString() + "ul 孔 " + strWell + " 板位 " + slattice.lattice_num); LoggerRunHelper.InfoLog("【" + DateTime.Now.ToString("HH:mm:ss:fff") + "】>Xhandler: 【" + methodNode.SelectSingleNode("name").InnerText + "】" + Properties.MachineRunResource.strProgress.ToString() + Properties.RunTransferFileResource.strFileAspirateFail.ToString() + ret.AlarmInfo + " 体积 " + targetVolume.ToString() + "ul 孔 " + strWell + " 板位 " + slattice.lattice_num); } else { launchView.AddLogs("【" + DateTime.Now.ToString("HH:mm:ss:fff") + "】>Xhandler: 【" + methodNode.SelectSingleNode("name").InnerText + "】progress: Aspirate was failed on " + strWell + " of " + slattice.lattice_num + " lattice! Error info:" + ret.AlarmInfo); LoggerRunHelper.InfoLog("【" + DateTime.Now.ToString("HH:mm:ss:fff") + "】>Xhandler: 【" + methodNode.SelectSingleNode("name").InnerText + "】progress: Aspirate was failed on " + strWell + " of " + slattice.lattice_num + " lattice! Error info:" + ret.AlarmInfo); } } else if (aspirateAirDisIdValue == 3)//终止 { if (strCurrentCulture.Equals("zh-CN")) { launchView.AddLogs("【" + DateTime.Now.ToString("HH:mm:ss:fff") + "】>Xhandler: 【" + methodNode.SelectSingleNode("name").InnerText + "】" + Properties.MachineRunResource.strProgress.ToString() + Properties.RunTransferFileResource.strFileAspirateFail.ToString() + ret.AlarmInfo + " 体积 " + targetVolume.ToString() + "ul 孔 " + strWell + " 板位 " + slattice.lattice_num); LoggerRunHelper.InfoLog("【" + DateTime.Now.ToString("HH:mm:ss:fff") + "】>Xhandler: 【" + methodNode.SelectSingleNode("name").InnerText + "】" + Properties.MachineRunResource.strProgress.ToString() + Properties.RunTransferFileResource.strFileAspirateFail.ToString() + ret.AlarmInfo + " 体积 " + targetVolume.ToString() + "ul 孔 " + strWell + " 板位 " + slattice.lattice_num); } else { launchView.AddLogs("【" + DateTime.Now.ToString("HH:mm:ss:fff") + "】>Xhandler: 【" + methodNode.SelectSingleNode("name").InnerText + "】progress: Aspirate was failed on " + strWell + " of " + slattice.lattice_num + " lattice! Error info:" + ret.AlarmInfo); LoggerRunHelper.InfoLog("【" + DateTime.Now.ToString("HH:mm:ss:fff") + "】>Xhandler: 【" + methodNode.SelectSingleNode("name").InnerText + "】progress: Aspirate was failed on " + strWell + " of " + slattice.lattice_num + " lattice! Error info:" + ret.AlarmInfo); } result = false; //launchView.addDataIntoReport(latticenum, targetVolume.ToString(), wells, "Block", labwares.labware_barcode, indexOfWell); return result; } } else { if (strCurrentCulture.Equals("zh-CN")) { launchView.AddLogs("【" + DateTime.Now.ToString("HH:mm:ss:fff") + "】>Xhandler: 【" + methodNode.SelectSingleNode("name").InnerText + "】" + Properties.MachineRunResource.strProgress.ToString() + Properties.RunAspirateResource.strAspirateFail.ToString() + ret.AlarmInfo + " 体积 " + pAxisVal[0].ToString() + "ul 孔 " + strWell + " 板位 " + latticenum); } else { launchView.AddLogs("【" + DateTime.Now.ToString("HH:mm:ss:fff") + "】>Xhandler: 【" + methodNode.SelectSingleNode("name").InnerText + "】progress: aspirate liquid is fail from " + strWell + " well on " + latticenum + " lattice! error information:" + ret.AlarmInfo); } result = false; return result; } } else { if (ret.AlarmCollection != null && ret.AlarmCollection.Count > 0)//有其它底层处理的失败 { if (strCurrentCulture.Equals("zh-CN")) { launchView.AddLogs("【" + DateTime.Now.ToString("HH:mm:ss:fff") + "】>Xhandler: 【" + methodNode.SelectSingleNode("name").InnerText + "】" + Properties.MachineRunResource.strProgress.ToString() + Properties.RunAspirateResource.strAspirateFail.ToString() + ret.AlarmInfo + " 体积 " + pAxisVal[0].ToString() + "ul 孔 " + strWell + " 板位 " + latticenum); } else { launchView.AddLogs("【" + DateTime.Now.ToString("HH:mm:ss:fff") + "】>Xhandler: 【" + methodNode.SelectSingleNode("name").InnerText + "】progress:aspirate " + pAxisVal[0].ToString() + "ul liquid is fail from " + strWell + " well on " + latticenum + " lattice!error information:" + ret.AlarmInfo); } } else { if (strCurrentCulture.Equals("zh-CN")) { launchView.AddLogs("【" + DateTime.Now.ToString("HH:mm:ss:fff") + "】>Xhandler: 【" + methodNode.SelectSingleNode("name").InnerText + "】" + Properties.MachineRunResource.strProgress.ToString() + Properties.RunAspirateResource.strAspirateSuccess.ToString() + " 体积 " + pAxisVal[0].ToString() + "ul 孔 " + strWell + " 板位 " + latticenum); } else { launchView.AddLogs("【" + DateTime.Now.ToString("HH:mm:ss:fff") + "】>Xhandler: 【" + methodNode.SelectSingleNode("name").InnerText + "】progress:aspirate " + pAxisVal[0].ToString() + "ul liquid is success from " + strWell + " well on " + latticenum + " lattice!"); } } } } #endregion } } else if (Shared.ChannelCount.Equals(96)) { #region AspirateMParam AspirateMParam aspirateMParam = new AspirateMParam(); aspirateMParam.afterAirDelay = (int)liquid.after_aspirate_delay * 1000; aspirateMParam.armId = Convert.ToInt32(methodNode.SelectSingleNode("arm/value").InnerText); aspirateMParam.aspirateAcceleration = (float)liquid.aspirate_acceleration; aspirateMParam.aspirateDeceleration = (float)liquid.aspirate_deceleration; aspirateMParam.aspirateDelay = (int)liquid.aspirate_delay * 1000; aspirateMParam.aspirateEnterSpeed = (float)liquid.aspirate_enter_speed; aspirateMParam.aspirateOutSpeed = (float)liquid.aspirate_out_speed; aspirateMParam.aspirateSpeed = (float)liquid.aspirate_speed; aspirateMParam.basezAxisVal = zAxisVal; aspirateMParam.beforeAirDelay = (int)liquid.before_aspirate_delay; if ((float)liquid.after_aspirate_volume == 0f) { aspirateMParam.isAfterAir = false; } else { aspirateMParam.isAfterAir = true; aspirateMParam.afterAirpAxisVal = (float)liquid.after_aspirate_volume; } if (liquid.before_aspirate_volume == 0d) { aspirateMParam.isBeforeAir = false; } else { aspirateMParam.isBeforeAir = true; aspirateMParam.beforeAirpAxisVal = (float)liquid.before_aspirate_volume; } if (liquid.after_a_liquid_volume == 0d) { aspirateMParam.isIncLiquidAfter = false; } else { aspirateMParam.isIncLiquidAfter = true; aspirateMParam.IncLiquidAfterpAxisVal = (float)liquid.after_a_liquid_volume; } if (liquid.before_a_liquid_volume == 0d) { aspirateMParam.isIncLiquidBefore = false; } else { aspirateMParam.isIncLiquidBefore = true; aspirateMParam.IncLiquidBeforepAxisVal = (float)liquid.before_a_liquid_volume; } if (liquid.aspirate_is_knock_wall == 0) { aspirateMParam.isKnockWall = false; } else { aspirateMParam.isKnockWall = true; aspirateMParam.knockDirection = (int)liquid.knock_direction; aspirateMParam.knockSpeed = (float)liquid.knock_speed; aspirateMParam.knockWallDelay = (int)liquid.knock_wall_delay * 1000; aspirateMParam.knockWellxOryAxisVal = (float)liquid.knock_wall_length; aspirateMParam.knockWellzAxisVal = (float)liquid.knock_well_height; } aspirateMParam.liquidVolumeType = (int)Convert.ToInt32(liquid.liquid_volume_type); LiquidAccuracy liquidAccuracy = liquidAccuracyBll.GetLiquidAccuracyFromdb(Convert.ToInt32(liquidrangeidValue), Convert.ToInt32(armId), Convert.ToDouble(wellvolume), liquididValue); double targetVolume = liquidAccuracyBll.CalculateAspirateParamVolume(Convert.ToDouble(wellvolume), liquidAccuracy); aspirateMParam.pAxisVal = (float)targetVolume; launchView.fVolumeToNull = (float)Convert.ToDouble(wellvolume); aspirateMParam.wellzAxisVal = (float)liquid.well_top_length; if(labwares.labware_type_id.Equals("3"))//如果是试剂槽,则需要返回一个96孔板的A1孔的坐标值 { tipsTable.axis_b_X=tipsTable.axis_b_X +3; tipsTable.axis_b_Y = tipsTable.axis_b_Y +3; } aspirateMParam.xAxisVal = tipsTable.axis_b_X; aspirateMParam.yAxisVal = tipsTable.axis_b_Y; //如果有吸液位置高度的话,则减少高度 //float zVal = tipsTable.axis_b_Z-currentLengthOfTip - (float)liquid.aspirate_well_bottom_length; float zVal = 0f; if (liquid.aspirate_well_bottom_length != "") { string[] zOffsiteArray = liquid.aspirate_well_bottom_length.Split(','); zVal = tipsTable.axis_b_Z - (float)Convert.ToDouble(zOffsiteArray[0]); } aspirateMParam.zAxisVal = zVal < 0 ? 0 : zVal; aspirateMParam.isMix = enableMix; if (aspirateMParam.isMix == true) { aspirateMParam.mixAspiratePositionValue = Convert.ToInt32(mixAspiratePositionValue); aspirateMParam.mixAspiratePositionText = mixAspiratePositionText; if (mixAspiratePositionValue == "0")//liquid { } else if (mixAspiratePositionValue == "1")//top { aspirateMParam.mixAspirateDistance = ((float)labwares.well_height - (float)mixAspirateDistance); } else if (mixAspiratePositionValue == "2")//bottom { aspirateMParam.mixAspirateDistance = (float)mixAspirateDistance; } aspirateMParam.mixAspirateSpeed = (float)Convert.ToDouble(mixAspirateSpeed); aspirateMParam.mixDispensePositionValue = Convert.ToInt32(mixDispensePositionValue); aspirateMParam.mixDispensePositionText = mixDispensePositionText; if (mixDispensePositionValue == "0")//liquid { } else if (mixDispensePositionValue == "1")//top { aspirateMParam.mixDispenseDistance = ((float)labwares.well_height - (float)mixDispenseDistance); } else if (mixDispensePositionValue == "2")//bottom { aspirateMParam.mixDispenseDistance = (float)mixDispenseDistance; } aspirateMParam.mixDispenseSpeed = (float)Convert.ToDouble(mixDispenseSpeed); aspirateMParam.mixvolume = (float)mixvolume; aspirateMParam.mixCount = mixcount; } else { aspirateMParam.mixAspirateDistance = 0; aspirateMParam.mixAspirateSpeed = 100; aspirateMParam.mixDispenseDistance = 0; aspirateMParam.mixDispenseSpeed = 100; } aspirateMParam.mixzAxisVal = (float)Convert.ToDouble(aspirateMParam.zAxisVal); #endregion launchView.UpdateLabwareWells(tipsTable, wells, 2); // 2:正在吸液红色 launchView.SetWaitOne();//暂停 if (strCurrentCulture.Equals("zh-CN")) { launchView.AddLogs("【" + DateTime.Now.ToString("HH:mm:ss:fff") + "】>Xhandler: 【" + methodNode.SelectSingleNode("name").InnerText + "】" + Properties.RunAspirateResource.strAspiratingExecute.ToString()); } else { launchView.AddLogs("【" + DateTime.Now.ToString("HH:mm:ss:fff") + "】> Xhandler: 【" + methodNode.SelectSingleNode("name").InnerText + "】" + "progress: Aspirate is executing,please wait for a moment."); } ret = aspirateBll.ExecuteAspirate(aspirateMParam, isSimulator); #region 错误处理 result = DoError(ret, methodNode, strWell, xmlEnv, currentLengthOfTip, zAxisVal, isSimulator, aspirateMParam.pAxisVal); #endregion } #region End Log if (strCurrentCulture.Equals("zh-CN")) { launchView.AddLogs("【" + DateTime.Now.ToString("HH:mm:ss:fff") + "】>Xhandler: 【" + methodNode.SelectSingleNode("name").InnerText + "】" + Properties.MachineRunResource.strEnd.ToString()); } else { launchView.AddLogs("【" + DateTime.Now.ToString("HH:mm:ss:fff") + "】>Xhandler: 【" + methodNode.SelectSingleNode("name").InnerText + "】complete;"); } #endregion } catch (Exception ex) { LoggerHelper.ErrorLog("ERROR:", ex); if (strCurrentCulture.Equals("zh-CN")) { launchView.AddLogs("【" + DateTime.Now.ToString("HH:mm:ss:fff") + "】>Xhandler: 【" + methodNode.SelectSingleNode("name").InnerText + "】" + Properties.MachineRunResource.strError.ToString() + " 源 " + ex.Source + " 错误信息 " + ex.Message + ";"); } else { launchView.AddLogs("【" + DateTime.Now.ToString("HH:mm:ss:fff") + "】>Xhandler: 【" + methodNode.SelectSingleNode("name").InnerText + "】error:source:" + ex.Source + ";error:" + ex.Message + ";"); } if (launchView.isRemotingOper) { launchView.OnError?.Invoke(launchView.remoteObjectCmd, "EC-1001", 5, "error:source:" + ex.Source + ";error:" + ex.Message + ";", 2); } result = false; } return result; } #endregion #region 创建安装枪头方法的xml public XmlNode GetLoadTipMethod() { MethodLoadTips methodLoadTips = new MethodLoadTips(); methodLoadTips.name = "安装枪头"; methodLoadTips.label = "安装枪头"; methodLoadTips.armText = "通道臂"; methodLoadTips.armValue = Shared.ChanelArmId.ToString(); methodLoadTips.channels = Shared.ChannelsId; methodLoadTips.labwaretipText = ControlCom.CurrentTipLabware.labware_name; methodLoadTips.labwaretipValue = ControlCom.CurrentTipLabware.labware_id; MethodEx mi = new MethodEx(); mi.method_isrun = ""; mi.isEnabled = true; mi.strIndex = "3"; XmlNode xmlNode = this.CreateLoadTipsXmlNode(0, methodLoadTips, mi); return xmlNode; } public XmlNode CreateLoadTipsXmlNode(int index, MethodLoadTips methodLoadTips, MethodEx mi) { XmlNode xmlNodeResult=null; XmlDocument xmlDoc = new XmlDocument(); XmlElement xeKey = xmlDoc.CreateElement("method");//创建子节点,并且设置子节点的属性 XmlAttribute xeType = xmlDoc.CreateAttribute("id"); xeType.InnerText = index.ToString(); xeKey.SetAttributeNode(xeType); XmlElement xeformX = xmlDoc.CreateElement("isrun"); xeformX.InnerText = mi.method_isrun; xeKey.AppendChild(xeformX); xeformX = xmlDoc.CreateElement("status"); //xeformX.InnerText = methodLoadTips.status; xeformX.InnerText = (mi.isEnabled ? "enable" : "disable"); xeKey.AppendChild(xeformX); xeformX = xmlDoc.CreateElement("name"); xeformX.InnerText = methodLoadTips.name; xeKey.AppendChild(xeformX); xeformX = xmlDoc.CreateElement("strIndex"); //xeformX.InnerText = methodLoadTips.strIndex; xeformX.InnerText = mi.strIndex; xeKey.AppendChild(xeformX); xeformX = xmlDoc.CreateElement("label"); xeformX.InnerText = methodLoadTips.label; xeKey.AppendChild(xeformX); xeformX = xmlDoc.CreateElement("arm"); xeKey.AppendChild(xeformX); XmlElement xeformX1 = xmlDoc.CreateElement("text"); xeformX1.InnerText = methodLoadTips.armText; xeformX.AppendChild(xeformX1); xeformX1 = xmlDoc.CreateElement("value"); xeformX1.InnerText = methodLoadTips.armValue; xeformX.AppendChild(xeformX1); xeformX = xmlDoc.CreateElement("channels"); string chs = string.Empty; if (methodLoadTips.channels.Length != 0) { for (int i = 0; i < methodLoadTips.channels.Length; i++) { chs += methodLoadTips.channels[i] + ","; } chs = chs.Substring(0, chs.Length - 1); } xeformX.InnerText = chs; xeKey.AppendChild(xeformX); xeformX = xmlDoc.CreateElement("labwaretip"); xeKey.AppendChild(xeformX); xeformX1 = xmlDoc.CreateElement("text"); xeformX1.InnerText = methodLoadTips.labwaretipText; xeformX.AppendChild(xeformX1); xeformX1 = xmlDoc.CreateElement("value"); xeformX1.InnerText = methodLoadTips.labwaretipValue; xeformX.AppendChild(xeformX1); xmlNodeResult = xeKey; return xmlNodeResult; } #endregion #region 出错处理的吸液方法 public bool ExecuteFailAfterAspirate(AspirateMParamSH aspirateMParamSH, bool isSimulator, XmlNode methodNode, string strWell, Lattice slattice)//, MethodAspirate methodAspirate)//, //TipsTable tipsTable, string srcLabwareName, string volumn, string[] sourceArray, string barcode, string[] indexArray) { bool result = true; HxResult ret = aspirateBll.ExecuteAspirate(aspirateMParamSH, isSimulator); if (ret.Result != ResultType.Success) { if (strCurrentCulture.Equals("zh-CN")) { launchView.AddLogs("【" + DateTime.Now.ToString("HH:mm:ss:fff") + "】>Xhandler: 【" + methodNode.SelectSingleNode("name").InnerText + "】" + Properties.MachineRunResource.strProgress.ToString() + Properties.RunAspirateResource.strAspirateFail.ToString() + ret.AlarmInfo + " 体积 " + aspirateMParamSH.pAxisVal[0].ToString() + "ul 孔 " + strWell + " 板位 " + slattice.lattice_num); LoggerRunHelper.InfoLog("【" + DateTime.Now.ToString("HH:mm:ss:fff") + "】>Xhandler: 【" + methodNode.SelectSingleNode("name").InnerText + "】" + Properties.MachineRunResource.strProgress.ToString() + Properties.RunAspirateResource.strAspirateFail.ToString() + ret.AlarmInfo + " 体积 " + aspirateMParamSH.pAxisVal[0].ToString() + "ul 孔 " + strWell + " 板位 " + slattice.lattice_num); } else { launchView.AddLogs("【" + DateTime.Now.ToString("HH:mm:ss:fff") + "】>Xhandler: 【" + methodNode.SelectSingleNode("name").InnerText + "】progress: Aspirate was failed on " + strWell + " of " + slattice.lattice_num + " lattice! Error info:" + ret.AlarmInfo); LoggerRunHelper.InfoLog("【" + DateTime.Now.ToString("HH:mm:ss:fff") + "】>Xhandler: 【" + methodNode.SelectSingleNode("name").InnerText + "】progress: Aspirate was failed on " + strWell + " of " + slattice.lattice_num + " lattice! Error info:" + ret.AlarmInfo); } result = false; if (launchView.isRemotingOper) { launchView.OnError?.Invoke(launchView.remoteObjectCmd, "EC-1022", 5, Properties.RunAspirateResource.strAspirateFail+ ret.AlarmInfo + " 体积 " + aspirateMParamSH.pAxisVal[0].ToString() + "ul 孔 " + strWell + " 板位 " + slattice.lattice_num, 2); } //launchView.addDataIntoReport(srcLabwareName, volumn, sourceArray, "block", barcode, indexArray); return result; } else { if (strCurrentCulture.Equals("zh-CN")) { launchView.AddLogs("【" + DateTime.Now.ToString("HH:mm:ss:fff") + "】>Xhandler: 【" + methodNode.SelectSingleNode("name").InnerText + "】" + Properties.MachineRunResource.strProgress.ToString() + Properties.RunAspirateResource.strAspirateSuccess.ToString() + " 体积 " + aspirateMParamSH.pAxisVal[0].ToString() + "ul 孔 " + strWell + " 板位 " + slattice.lattice_num); LoggerRunHelper.InfoLog("【" + DateTime.Now.ToString("HH:mm:ss:fff") + "】>Xhandler: 【" + methodNode.SelectSingleNode("name").InnerText + "】" + Properties.MachineRunResource.strProgress.ToString() + Properties.RunAspirateResource.strAspirateSuccess.ToString() + " 体积 " + aspirateMParamSH.pAxisVal[0].ToString() + "ul 孔 " + strWell + " 板位 " + slattice.lattice_num); } else { launchView.AddLogs("【" + DateTime.Now.ToString("HH:mm:ss:fff") + "】>Xhandler: 【" + methodNode.SelectSingleNode("name").InnerText + "】progress:Aspirate was successful on " + strWell + " of " + slattice.lattice_num + " lattice!"); LoggerRunHelper.InfoLog("【" + DateTime.Now.ToString("HH:mm:ss:fff") + "】>Xhandler: 【" + methodNode.SelectSingleNode("name").InnerText + "】progress:Aspirate was successful on " + strWell + " of " + slattice.lattice_num + " lattice!"); } //if (aspirateMParamWH.zAxisVal[0] == 0f) //{ // launchView.addDataIntoReport(srcLabwareName, volumn, sourceArray, "block", barcode, indexArray); //} //else //{ // launchView.addDataIntoReport(srcLabwareName, volumn, sourceArray, "pass", barcode, indexArray); //} } return result; } #endregion #region 出错处理的放液到垃圾桶参数 public DispenseMParamSH GenerateDispenseParamForTrashSH(XmlNode methodNode, Lattice latticeTrash, int[] channelIds,double targetVolume) { #region 数据准备 string liquididText = methodNode.SelectSingleNode("liquidid/text").InnerText; string liquididValue = methodNode.SelectSingleNode("liquidid/value").InnerText; string liquidrangeidText = methodNode.SelectSingleNode("liquidrangeid/text").InnerText; string liquidrangeidValue = methodNode.SelectSingleNode("liquidrangeid/value").InnerText; string liquidpidText = methodNode.SelectSingleNode("liquidpid/text").InnerText; string liquidpidValue = methodNode.SelectSingleNode("liquidpid/value").InnerText; bool enableLiquidSensor = methodNode.SelectSingleNode("enableLiquidSensor").InnerText.ToLower() == "true" ? true : false; int liquidSensorCount = Convert.ToInt32(methodNode.SelectSingleNode("liquidSensorCount").InnerText); double liquidSensorDistance = Convert.ToDouble(methodNode.SelectSingleNode("liquidSensorDistance").InnerText); double liquidSensorEndDistance = Convert.ToDouble(methodNode.SelectSingleNode("liquidSensorEndDistance").InnerText); double liquidSensorSpeed = Convert.ToDouble(methodNode.SelectSingleNode("liquidSensorSpeed").InnerText); double liquidSensorRadio = Convert.ToDouble(methodNode.SelectSingleNode("liquidSensorRadio").InnerText); string liquidSensorDisIdText = methodNode.SelectSingleNode("liquidSensorDisId/text").InnerText; string liquidSensorDisIdValue = methodNode.SelectSingleNode("liquidSensorDisId/value").InnerText; bool enableLiquidFollow = methodNode.SelectSingleNode("enableLiquidFollow").InnerText.ToLower() == "true" ? true : false; int liquidFollowType = Convert.ToInt32(methodNode.SelectSingleNode("liquidFollowType/value").InnerText); string liquidFollowTypeName = methodNode.SelectSingleNode("liquidFollowType/text").InnerText; double liquidFollowSpeed = Convert.ToDouble(methodNode.SelectSingleNode("liquidFollowSpeed").InnerText); double liquidFollowDistance = Convert.ToDouble(methodNode.SelectSingleNode("liquidFollowDistance").InnerText); double liquidFollowArea = Convert.ToDouble(methodNode.SelectSingleNode("liquidFollowArea").InnerText); bool enableMixFollow = methodNode.SelectSingleNode("enableMixFollow").InnerText.ToLower() == "true" ? true : false; string channelNums = methodNode.SelectSingleNode("channels").InnerText; int[] chs = new int[channelIds.Length]; for (int m = 0; m < channelIds.Length; m++) { chs[m] = channelIds[m]; } float[] zAxisVals = new float[channelIds.Length]; float[] pVolmunVals = new float[channelIds.Length]; #endregion // 液体参数 Liquid liquid = LiquidDB.GetALiquidFromdb(liquidpidValue); DispenseMParamSH dispenseMParam = new DispenseMParamSH(); dispenseMParam.channelCount = channelIds.Length; dispenseMParam.channelId = chs; dispenseMParam.afterAirDelay = (int)liquid.after_dispense_delay; dispenseMParam.armId = Convert.ToInt32(methodNode.SelectSingleNode("arm/value").InnerText); dispenseMParam.dispenseAcceleration = (float)liquid.dispense_acceleration; dispenseMParam.dispenseDeceleration = (float)liquid.dispense_deceleration; dispenseMParam.dispenseDelay = (int)liquid.dispense_delay; dispenseMParam.dispenseEnterSpeed = (float)liquid.dispense_enter_speed; dispenseMParam.dispenseOutSpeed = (float)liquid.dispense_out_speed; dispenseMParam.dispenseSpeed = (float)liquid.dispense_speed; dispenseMParam.basezAxisVal = (float)Convert.ToDouble(ConfigurationManager.AppSettings["zAxisSafeVal"]); dispenseMParam.beforeAirDelay = (int)liquid.before_dispense_delay; #region 后吸空气 if ((float)liquid.after_dispense_volume == 0f) { dispenseMParam.isAfterAir = false; } else { dispenseMParam.isAfterAir = true; dispenseMParam.afterAirpAxisVal = (float)liquid.after_dispense_volume; } #endregion #region 前吸空气 if (liquid.before_dispense_volume == 0d) { dispenseMParam.isBeforeAir = false; } else { dispenseMParam.isBeforeAir = true; dispenseMParam.beforeAirpAxisVal = (float)liquid.before_dispense_volume; } #endregion dispenseMParam.liquidVolumeType = (int)Convert.ToInt32((liquid.liquid_volume_type != null ? "1" : liquid.liquid_volume_type)); dispenseMParam.wellzAxisVal = (float)liquid.well_top_length; // 孔位平面的z轴 #region 碰壁 dispenseMParam.isKnockWall = false; #endregion dispenseMParam.isSurvey = false; dispenseMParam.isMix = false; dispenseMParam.mixAspirateDistance = 0; dispenseMParam.mixAspirateSpeed = 100; dispenseMParam.mixDispenseDistance = 0; dispenseMParam.mixDispenseSpeed = 100; dispenseMParam.enableVolumeToNull = true; dispenseMParam.zAxisVal = zAxisVals; dispenseMParam.pAxisVal = pVolmunVals; dispenseMParam.mixzAxisVal = 0f; float pVolumnVas = 0f; for (int k = 0; k < channelIds.Length; k++) { pVolumnVas = (float)targetVolume; // 体积 if (k == 0) { dispenseMParam.xAxisVal = (float)latticeTrash.lattice_X - 50f;//tipsTableRemoteArrayList[n][k].axis_b_X; dispenseMParam.yAxisVal = (float)latticeTrash.lattice_Y + 10f;//tipsTableRemoteArrayList[n][k].axis_b_Y; } // 孔位平面的z轴 float zVal = (float)latticeTrash.lattice_Z - ControlCom.CurrentLengthOfTip - 50 ;//tipsTableRemoteArrayList[n][k].axis_b_Z + ControlCom.CurrentLengthOfTipOffSetVal; dispenseMParam.wellzAxisVal = zVal;// - (float)labware.well_height; #region 孔位的z轴 if (liquid.dispense_position_type == 0) { } else if (liquid.dispense_position_type == 2) { zVal = zVal - (float)liquid.dispense_well_bottom_length; } else if (liquid.dispense_position_type == 1) { zVal = dispenseMParam.wellzAxisVal;// + (float)liquid.dispense_well_bottom_length; } zAxisVals[k] = zVal < 0 ? 0 : zVal; #endregion // 精度校准后的体积 //LiquidAccuracy liquidAccuracy = liquidAccuracyBll.GetLiquidAccuracyFromdb(Convert.ToInt32(liquidrangeidValue), Convert.ToInt32(dispenseMParam.armId), Convert.ToDouble(pVolumeArrayList[n][0]), liquididValue); //double targetVolume = liquidAccuracyBll.CalculateAspirateParamVolume(Convert.ToDouble(pVolumnVas), liquidAccuracy); pVolmunVals[k] = (float)targetVolume == 0f ? 20f : (float)targetVolume; } return dispenseMParam; } #endregion #region 执行因堵塞失败的通道到垃圾桶放液 public bool ExecuteDispenseIntoTrash(DispenseMParamSH dispenseMParamWH, bool isSimulator, XmlNode methodNode) { bool result = true; DispenseBll dispenseBll = new DispenseBll(); HxResult ret = dispenseBll.ExecuteDispense(dispenseMParamWH, isSimulator); DateTime endTime = DateTime.Now; if (ret.Result != ResultType.Success) { if (strCurrentCulture.Equals("zh-CN")) { launchView.AddLogs("【" + DateTime.Now.ToString("HH:mm:ss:fff") + "】>Xhandler: 【" + methodNode.SelectSingleNode("name").InnerText + "】" + Properties.MachineRunResource.strProgress + Properties.RunCoatingFileResource.strDispenseErrorExec + " 在垃圾桶 " + Properties.MachineRunResource.strError + ret.AlarmInfo); LoggerRunHelper.InfoLog("【" + DateTime.Now.ToString("HH:mm:ss:fff") + "】>Xhandler: 【" + methodNode.SelectSingleNode("name").InnerText + "】" + Properties.MachineRunResource.strProgress + Properties.RunCoatingFileResource.strDispenseErrorExec + " 在垃圾桶 " + Properties.MachineRunResource.strError + ret.AlarmInfo); } else { launchView.AddLogs("【" + DateTime.Now.ToString("HH:mm:ss:fff") + "】>Xhandler: 【" + methodNode.SelectSingleNode("name").InnerText + "】progress: Dispense was failed on the trash bin! Error info:" + ret.AlarmInfo); LoggerRunHelper.InfoLog("【" + DateTime.Now.ToString("HH:mm:ss:fff") + "】>Xhandler: 【" + methodNode.SelectSingleNode("name").InnerText + "】progress: Dispense was failed on the trash bin! Error info:" + ret.AlarmInfo); } if (launchView.isRemotingOper) { launchView.OnError?.Invoke(launchView.remoteObjectCmd, "EC-1024", 5, Properties.RunCoatingFileResource.strDispenseErrorExec + " 在垃圾桶 " + Properties.MachineRunResource.strError + ret.AlarmInfo, 2); } result = false; return result; } else { if (strCurrentCulture.Equals("zh-CN")) { launchView.AddLogs("【" + DateTime.Now.ToString("HH:mm:ss:fff") + "】>Xhandler: 【" + methodNode.SelectSingleNode("name").InnerText + "】" + Properties.MachineRunResource.strProgress + Properties.RunCoatingFileResource.strDispenseSuccessExec + " 在垃圾桶。 "); LoggerRunHelper.InfoLog("【" + DateTime.Now.ToString("HH:mm:ss:fff") + "】>Xhandler: 【" + methodNode.SelectSingleNode("name").InnerText + "】" + Properties.MachineRunResource.strProgress + Properties.RunCoatingFileResource.strDispenseSuccessExec + " 在垃圾桶。 "); } else { launchView.AddLogs("【" + DateTime.Now.ToString("HH:mm:ss:fff") + "】>Xhandler: 【" + methodNode.SelectSingleNode("name").InnerText + "】progress:Dispense was successful on the trash bin!"); LoggerRunHelper.InfoLog("【" + DateTime.Now.ToString("HH:mm:ss:fff") + "】>Xhandler: 【" + methodNode.SelectSingleNode("name").InnerText + "】progress:Dispense was successful on the trash bin!"); } } return result; } #endregion #region 执行因堵塞失败的通道到来源孔位放液 public bool ExecuteDispenseIntoSource(DispenseMParamSH dispenseMParamSH, bool isSimulator, string liquidSensorDisIdValue, XmlNode methodNode, string strWell, Lattice slattice) { bool result = true; DispenseBll dispenseBll = new DispenseBll(); HxResult ret = dispenseBll.ExecuteDispense(dispenseMParamSH, isSimulator); DateTime endTime = DateTime.Now; if (ret.Result != ResultType.Success) { if (strCurrentCulture.Equals("zh-CN")) { launchView.AddLogs("【" + DateTime.Now.ToString("HH:mm:ss:fff") + "】>Xhandler: 【" + methodNode.SelectSingleNode("name").InnerText + "】" + Properties.MachineRunResource.strProgress + Properties.RunCoatingFileResource.strDispenseErrorExec + " 孔位 " + strWell + " 板位 " + slattice.lattice_num + Properties.MachineRunResource.strError + ret.AlarmInfo); LoggerRunHelper.InfoLog("【" + DateTime.Now.ToString("HH:mm:ss:fff") + "】>Xhandler: 【" + methodNode.SelectSingleNode("name").InnerText + "】" + Properties.MachineRunResource.strProgress + Properties.RunCoatingFileResource.strDispenseErrorExec + " 孔位 " + strWell + " 板位 " + slattice.lattice_num + Properties.MachineRunResource.strError + ret.AlarmInfo); } else { launchView.AddLogs("【" + DateTime.Now.ToString("HH:mm:ss:fff") + "】>Xhandler: 【" + methodNode.SelectSingleNode("name").InnerText + "】progress: Dispense was failed on " + strWell + " of " + slattice.lattice_num + " lattice! Error info:" + ret.AlarmInfo); LoggerRunHelper.InfoLog("【" + DateTime.Now.ToString("HH:mm:ss:fff") + "】>Xhandler: 【" + methodNode.SelectSingleNode("name").InnerText + "】progress: Dispense was failed on " + strWell + " of " + slattice.lattice_num + " lattice! Error info:" + ret.AlarmInfo); } if (launchView.isRemotingOper) { launchView.OnError?.Invoke(launchView.remoteObjectCmd, "EC-1024", 5, Properties.RunCoatingFileResource.strDispenseErrorExec + " 孔位 " + strWell + " 板位 " + slattice.lattice_num + Properties.MachineRunResource.strError + ret.AlarmInfo, 2); } result = false; return result; } else { if (strCurrentCulture.Equals("zh-CN")) { launchView.AddLogs("【" + DateTime.Now.ToString("HH:mm:ss:fff") + "】>Xhandler: 【" + methodNode.SelectSingleNode("name").InnerText + "】" + Properties.MachineRunResource.strProgress + Properties.RunCoatingFileResource.strDispenseSuccessExec + " 孔位 " + strWell + " 板位 " + slattice.lattice_num); LoggerRunHelper.InfoLog("【" + DateTime.Now.ToString("HH:mm:ss:fff") + "】>Xhandler: 【" + methodNode.SelectSingleNode("name").InnerText + "】" + Properties.MachineRunResource.strProgress + Properties.RunCoatingFileResource.strDispenseSuccessExec + " 孔位 " + strWell + " 板位 " + slattice.lattice_num); } else { launchView.AddLogs("【" + DateTime.Now.ToString("HH:mm:ss:fff") + "】>Xhandler: 【" + methodNode.SelectSingleNode("name").InnerText + "】progress:Coating was successful on " + strWell + " of " + slattice.lattice_num + " lattice!"); LoggerRunHelper.InfoLog("【" + DateTime.Now.ToString("HH:mm:ss:fff") + "】>Xhandler: 【" + methodNode.SelectSingleNode("name").InnerText + "】progress:Coating was successful on " + strWell + " of " + slattice.lattice_num + " lattice!"); } } return result; } #endregion #region 放液 public DispenseMParamSH GenerateDispenseParamForSH(XmlNode methodNode, Labware labware, int[] channelIds, double targetVolume,TipsTable tipsTable) { #region 数据准备 string liquididText = methodNode.SelectSingleNode("liquidid/text").InnerText; string liquididValue = methodNode.SelectSingleNode("liquidid/value").InnerText; string liquidrangeidText = methodNode.SelectSingleNode("liquidrangeid/text").InnerText; string liquidrangeidValue = methodNode.SelectSingleNode("liquidrangeid/value").InnerText; string liquidpidText = methodNode.SelectSingleNode("liquidpid/text").InnerText; string liquidpidValue = methodNode.SelectSingleNode("liquidpid/value").InnerText; bool enableLiquidSensor = methodNode.SelectSingleNode("enableLiquidSensor").InnerText.ToLower() == "true" ? true : false; int liquidSensorCount = Convert.ToInt32(methodNode.SelectSingleNode("liquidSensorCount").InnerText); double liquidSensorDistance = Convert.ToDouble(methodNode.SelectSingleNode("liquidSensorDistance").InnerText); double liquidSensorEndDistance = Convert.ToDouble(methodNode.SelectSingleNode("liquidSensorEndDistance").InnerText); double liquidSensorSpeed = Convert.ToDouble(methodNode.SelectSingleNode("liquidSensorSpeed").InnerText); double liquidSensorRadio = Convert.ToDouble(methodNode.SelectSingleNode("liquidSensorRadio").InnerText); string liquidSensorDisIdText = methodNode.SelectSingleNode("liquidSensorDisId/text").InnerText; string liquidSensorDisIdValue = methodNode.SelectSingleNode("liquidSensorDisId/value").InnerText; bool enableLiquidFollow = methodNode.SelectSingleNode("enableLiquidFollow").InnerText.ToLower() == "true" ? true : false; int liquidFollowType = Convert.ToInt32(methodNode.SelectSingleNode("liquidFollowType/value").InnerText); string liquidFollowTypeName = methodNode.SelectSingleNode("liquidFollowType/text").InnerText; double liquidFollowSpeed = Convert.ToDouble(methodNode.SelectSingleNode("liquidFollowSpeed").InnerText); double liquidFollowDistance = Convert.ToDouble(methodNode.SelectSingleNode("liquidFollowDistance").InnerText); double liquidFollowArea = Convert.ToDouble(methodNode.SelectSingleNode("liquidFollowArea").InnerText); bool enableMixFollow = methodNode.SelectSingleNode("enableMixFollow").InnerText.ToLower() == "true" ? true : false; string channelNums = methodNode.SelectSingleNode("channels").InnerText; int[] chs = new int[channelIds.Length]; for (int m = 0; m < channelIds.Length; m++) { chs[m] = channelIds[m]; } float[] zAxisVals = new float[channelIds.Length]; float[] pVolmunVals = new float[channelIds.Length]; #endregion // 液体参数 Liquid liquid = LiquidDB.GetALiquidFromdb(liquidpidValue); DispenseMParamSH dispenseMParam = new DispenseMParamSH(); dispenseMParam.channelCount = channelIds.Length; dispenseMParam.channelId = chs; dispenseMParam.afterAirDelay = (int)liquid.after_dispense_delay; dispenseMParam.armId = Convert.ToInt32(methodNode.SelectSingleNode("arm/value").InnerText); dispenseMParam.dispenseAcceleration = (float)liquid.dispense_acceleration; dispenseMParam.dispenseDeceleration = (float)liquid.dispense_deceleration; dispenseMParam.dispenseDelay = (int)liquid.dispense_delay; dispenseMParam.dispenseEnterSpeed = (float)liquid.dispense_enter_speed; dispenseMParam.dispenseOutSpeed = (float)liquid.dispense_out_speed; dispenseMParam.dispenseSpeed = (float)liquid.dispense_speed; dispenseMParam.basezAxisVal = (float)Convert.ToDouble(ConfigurationManager.AppSettings["zAxisSafeVal"]); dispenseMParam.beforeAirDelay = (int)liquid.before_dispense_delay; #region 后吸空气 if ((float)liquid.after_dispense_volume == 0f) { dispenseMParam.isAfterAir = false; } else { dispenseMParam.isAfterAir = true; dispenseMParam.afterAirpAxisVal = (float)liquid.after_dispense_volume; } #endregion #region 前吸空气 if (liquid.before_dispense_volume == 0d) { dispenseMParam.isBeforeAir = false; } else { dispenseMParam.isBeforeAir = true; dispenseMParam.beforeAirpAxisVal = (float)liquid.before_dispense_volume; } #endregion dispenseMParam.liquidVolumeType = (int)Convert.ToInt32((liquid.liquid_volume_type != null ? "1" : liquid.liquid_volume_type)); dispenseMParam.wellzAxisVal = (float)liquid.well_top_length; // 孔位平面的z轴 #region 碰壁 if (liquid.dispense_is_knock_wall == 0) { dispenseMParam.isKnockWall = false; } else { dispenseMParam.isKnockWall = true; dispenseMParam.knockDirection = (int)liquid.knock_direction; dispenseMParam.knockSpeed = (float)liquid.knock_speed; dispenseMParam.knockWallDelay = (int)liquid.knock_wall_delay; dispenseMParam.knockWellxOryAxisVal = (float)liquid.knock_wall_length; dispenseMParam.knockWellzAxisVal = (float)liquid.knock_well_height; } #endregion dispenseMParam.isSurvey = enableLiquidSensor; if (dispenseMParam.isSurvey == true) { //dispenseMParam.surveyRetryCount = liquidSensorCount; dispenseMParam.surveyInitzVal = tipsTable.axis_b_Z - ((float)labware.labware_height - (float)liquidSensorDistance); dispenseMParam.surveyMaxzVal = tipsTable.axis_b_Z - ((float)labware.labware_height - (float)liquidSensorEndDistance); dispenseMParam.surveySpeed = (float)liquidSensorSpeed; //aspirateMParam.surveyCoefficient =; dispenseMParam.wellzAxisVal = tipsTable.axis_b_Z - ((float)labware.labware_height - (float)liquid.well_top_length); //dispenseMParam.wellBottomzAxisVal = tipsTableRemoteArrayList[n][0].axis_b_Z - ((float)labwares.labware_height - (float)labwares.well_height); //dispenseMParam.surveyFailHandlType = Convert.ToInt32(liquidSensorDisIdValue); if (enableLiquidFollow) { //dispenseMParam.followupType = liquidFollowType; dispenseMParam.followupSpeed = (float)liquidFollowSpeed; dispenseMParam.followupDistance = (float)liquidFollowDistance; float area = 0.0f; if (labware.well_shape == (int)WellSharpe.Round) { area = (float)(Math.PI * labware.well_mouth_radius * labware.well_mouth_radius); } else if (labware.well_shape == (int)WellSharpe.Rectangle) { area = (float)(labware.well_top_x * labware.well_top_y); } dispenseMParam.sectionalArea = area; dispenseMParam.isMixFollowup = enableMixFollow; } else { } } else { } dispenseMParam.isMix = false; dispenseMParam.mixAspirateDistance = 0; dispenseMParam.mixAspirateSpeed = 100; dispenseMParam.mixDispenseDistance = 0; dispenseMParam.mixDispenseSpeed = 100; dispenseMParam.enableVolumeToNull = true; dispenseMParam.zAxisVal = zAxisVals; dispenseMParam.pAxisVal = pVolmunVals; dispenseMParam.mixzAxisVal = 0f; float pVolumnVas = 0f; for (int k = 0; k < channelIds.Length; k++) { pVolumnVas = (float)targetVolume; // 体积 if (k == 0) { dispenseMParam.xAxisVal = tipsTable.axis_b_X; dispenseMParam.yAxisVal = tipsTable.axis_b_Y; } // 孔位平面的z轴 float zVal = tipsTable.axis_b_Z + ControlCom.CurrentLengthOfTipOffSetVal; dispenseMParam.wellzAxisVal = zVal - (float)labware.well_height; #region 孔位的z轴 if (liquid.dispense_position_type == 0) { } else if (liquid.dispense_position_type == 2) { zVal = zVal - (float)liquid.dispense_well_bottom_length; } else if (liquid.dispense_position_type == 1) { zVal = dispenseMParam.wellzAxisVal + (float)liquid.dispense_well_bottom_length; } zAxisVals[k] = zVal < 0 ? 0 : zVal; #endregion //// 精度校准后的体积 //LiquidAccuracy liquidAccuracy = liquidAccuracyBll.GetLiquidAccuracyFromdb(Convert.ToInt32(liquidrangeidValue), Convert.ToInt32(dispenseMParam.armId), Convert.ToDouble(pVolumeArrayList[n][0]), liquididValue); //double targetVolume = liquidAccuracyBll.CalculateAspirateParamVolume(Convert.ToDouble(pVolumnVas), liquidAccuracy); pVolmunVals[k] = (float)targetVolume == 0f ? 20f : (float)targetVolume; } return dispenseMParam; } #endregion #region 根据输入的行数,取得对应的字符串名称 /// /// /// /// /// 要加上的值 /// private static string GetNextColumnChar(int col, int iaddVal) { var a = (col + 1 - 65) / 26; if (a > 0) return GetNextColumnChar(a - 1, iaddVal) + (char)(col + iaddVal); return ((char)(col + iaddVal)).ToString(); } #endregion #region 转换孔位行符号为行号 private int GetNumByWellLine(string noWell) { int num = 0; num = Convert.ToInt32(noWell) - 64; return num; } #endregion #region 错误处理 private bool DoError(HxResult ret, XmlNode methodNode, string strWell, XmlNode xmlEnv, float currentLengthOfTip, float zAxisVal, bool isSimulator, float pAxisVal) { bool result = true; string methodName = methodNode.SelectSingleNode("name").InnerText; string position = methodNode.SelectSingleNode("position/text").InnerText; #region 错误处理 if (ret.Result != ResultType.Success) { if (strCurrentCulture.Equals("zh-CN")) { launchView.AddLogs("【" + DateTime.Now.ToString("HH:mm:ss:fff") + "】>Xhandler: 【" + methodName + "】" + Properties.MachineRunResource.strProgress.ToString() + Properties.RunAspirateResource.strAspirateFail.ToString() + ret.AlarmInfo + " 孔 " + strWell + " 板位 " + position); } else { launchView.AddLogs("【" + DateTime.Now.ToString("HH:mm:ss:fff") + "】>Xhandler: 【" + methodName + "】progress: aspirate liquid is fail from " + strWell + " well on " + position + " lattice! error information:" + ret.AlarmInfo); } OperateDialog plsConfirmOper = null; if (!launchView.isRemotingOper) { System.Windows.Application.Current.Dispatcher.Invoke(new Action(() => { plsConfirmOper = new OperateDialog(strCurrentCulture.Equals("zh-CN") ? Properties.RunAspirateResource.strFailWhatToDo : "aspirate liquid is fail! What do you want to do?"); plsConfirmOper.ShowDialog(); })); } else { launchView.OnError?.Invoke(launchView.remoteObjectCmd, "EC-1050", 5, Properties.RunAspirateResource.strFailWhatToDo, 2); plsConfirmOper = new OperateDialog(strCurrentCulture.Equals("zh-CN") ? Properties.RunAspirateResource.strFailWhatToDo : "aspirate liquid is fail! What do you want to do?"); plsConfirmOper.ShowDialog(); } if (plsConfirmOper != null && plsConfirmOper.OperMark == NodeOperationTypeEnum.Retry) // 重试 { return ExecuteAspirate(xmlEnv, methodNode, currentLengthOfTip, zAxisVal, isSimulator); } else if (plsConfirmOper != null && plsConfirmOper.OperMark == NodeOperationTypeEnum.Cancel) // 终止 { if (strCurrentCulture.Equals("zh-CN")) { launchView.AddLogs("【" + DateTime.Now.ToString("HH:mm:ss:fff") + "】>Xhandler: 【" + methodName + "】" + Properties.MachineRunResource.strProgress + Properties.RunAspirateResource.strLoadTipWasStopped); } else { launchView.AddLogs("【" + DateTime.Now.ToString("HH:mm:ss:fff") + "】>Xhandler: 【" + methodName + "】progress:aspirate liquid was stopped!"); } if (launchView.isRemotingOper) { launchView.OnError?.Invoke(launchView.remoteObjectCmd, "EC-1051", 5, Properties.RunAspirateResource.strLoadTipWasStopped, 2); } result = false; return result; } else if (plsConfirmOper != null && plsConfirmOper.OperMark == NodeOperationTypeEnum.Continue) // 跳过 { if (strCurrentCulture.Equals("zh-CN")) { launchView.AddLogs("【" + DateTime.Now.ToString("HH:mm:ss:fff") + "】>Xhandler: 【" + methodName + "】" + Properties.MachineRunResource.strProgress + Properties.RunAspirateResource.strLoadTipWasSkipped); } else { launchView.AddLogs("【" + DateTime.Now.ToString("HH:mm:ss:fff") + "】>Xhandler: 【" + methodName + "】progress:mixing liquid was skipped!"); } } } else { if (strCurrentCulture.Equals("zh-CN")) { launchView.AddLogs("【" + DateTime.Now.ToString("HH:mm:ss:fff") + "】>Xhandler: 【" + methodName + "】" + Properties.MachineRunResource.strProgress.ToString() + Properties.RunAspirateResource.strAspirateSuccess.ToString() + " 体积 " + pAxisVal.ToString() + "ul 孔 " + strWell + " 板位 " + position); } else { launchView.AddLogs("【" + DateTime.Now.ToString("HH:mm:ss:fff") + "】>Xhandler: 【" + methodName + "】progress:aspirate " + pAxisVal.ToString() + "ul liquid is success from " + strWell + " well on " + position + " lattice!"); } } #endregion return result; } #endregion } }