using DataEntity.Rack;
|
using DataEntity.Share;
|
using DataRWDAL;
|
using DriverLib.Engine;
|
using HxEnum;
|
using HxSocket;
|
using Newtonsoft.Json;
|
using System;
|
using System.Collections.Generic;
|
using System.Configuration;
|
using System.Data;
|
using System.Linq;
|
using System.Windows;
|
using System.Windows.Media;
|
using System.Xml;
|
using XCommon;
|
using XCommon.Log;
|
using XCore;
|
using XHandler.Class;
|
using XHandler.Controls.Run.Com;
|
using XHandler.View;
|
using XHandler.View.MethodProperty;
|
using XImagingXhandler.XDAL;
|
using static HxEnum.OtherEnum;
|
|
namespace XHandler.Controls
|
{
|
/// <summary>
|
/// 涂布文件控制类
|
/// </summary>
|
public class CoatingFileControl
|
{
|
#region 变量
|
private string strCurrentCulture = "";
|
private WellCalc wellCalc = new WellCalc();
|
|
#region BLL
|
private LatticeBll latticeBll = new LatticeBll();
|
private AspirateBll aspirateBll = new AspirateBll();
|
private DispenseBll dispenseBll = new DispenseBll();
|
private UltrasonicBll ultrasonicBll = new UltrasonicBll();
|
#endregion
|
|
private MethodFrame methodFrame = new MethodFrame();
|
private CoatingFileBll coatingFileBll = new CoatingFileBll();
|
private CoatingBll coatingBll = new CoatingBll();
|
private LoadTipsBll loadTipsBll = new LoadTipsBll();
|
private string circularBarcode = string.Empty; // 记录下当前圆皿
|
private string plate1Barcode = string.Empty; // 记录下当前涂布的皿号
|
private string plate2Barcode = string.Empty;
|
private string choiceCenterPointVal = string.Empty; // 挑菌中心点位
|
private List<string> listCoatingCoverLatticeId = new List<string>(); // 涂布的板放盖位号:P2,P3
|
|
public RunWnd launchView = null;
|
public HxSocketClient socketTcpClientToRemote = null;
|
#endregion
|
|
/// <summary>
|
/// 构造函数
|
/// </summary>
|
public CoatingFileControl(string strCurrentCulture)
|
{
|
this.strCurrentCulture = strCurrentCulture;
|
// 挑菌中心点位
|
choiceCenterPointVal = ConfigurationManager.AppSettings["choiceCenterPointVal"].ToString();
|
|
// 涂布的板放盖位号:P2,P3
|
listCoatingCoverLatticeId = ComUtility.GetPlateCoverLatticeName();
|
}
|
|
#region 执行涂布文件,返回结果字符串
|
/// <summary>
|
/// 执行涂布文件,返回结果字符串
|
/// </summary>
|
/// <param name="xmlEnv"></param>
|
/// <param name="methodNode"></param>
|
/// <param name="zAxisVal"></param>
|
/// <param name="isSimulator"></param>
|
/// <returns></returns>
|
public bool ExecuteCoatingFile(XmlNode xmlEnv, XmlNode methodNode, float zAxisVal, bool isSimulator)
|
{
|
bool result = true;
|
var platformNodeList = xmlEnv.SelectNodes("platform");
|
string strMethodName = methodNode.SelectSingleNode("name").InnerText;
|
|
if (launchView._cancelSource.IsCancellationRequested)
|
{
|
result = false;
|
return result;
|
}
|
if (strCurrentCulture.Equals("zh-CN"))
|
{
|
launchView.AddLogs("【" + DateTime.Now.ToString("HH:mm:ss:fff") + "】> Xhandler: 【" + strMethodName + "】" + Properties.MachineRunResource.strStart.ToString());
|
}
|
else
|
{
|
launchView.AddLogs("【" + DateTime.Now.ToString("HH:mm:ss:fff") + "】> Xhandler: 【" + strMethodName + "】start:");
|
}
|
|
try
|
{
|
#region 数据准备
|
if (strCurrentCulture.Equals("zh-CN"))
|
{
|
launchView.AddLogs("【" + DateTime.Now.ToString("HH:mm:ss:fff") + "】> Xhandler: 【" + strMethodName + "】" + Properties.MachineRunResource.strProgress.ToString() + Properties.MachineRunResource.strPrepareData);
|
}
|
else
|
{
|
launchView.AddLogs("【" + DateTime.Now.ToString("HH:mm:ss:fff") + "】> Xhandler: 【" + strMethodName + "】progress: prepare data;");
|
}
|
MethodCoatingFile methodCoatingFile = coatingFileBll.GenerateMethodCoatingFileDataByXmlNode(methodNode);//获取涂布移液表
|
methodCoatingFile.transferDataTable = SelectFile(methodNode.SelectSingleNode("filePath").InnerText);
|
|
LoggerHelper.InfoLog($"[CoatingFileControl]:Args: {JsonConvert.SerializeObject(methodCoatingFile)}");
|
|
//从Excel文件读取当前挑选参数数据
|
string filePath = ConfigurationManager.AppSettings["choiceFilePath"];
|
DataTable dtParam = null;
|
|
if (!launchView.isRemotingOper)
|
{
|
// 单机运行时,作成 挑菌下发参数.xls
|
dtParam = DoUpdateCoatingMode(methodNode, filePath);
|
}
|
else
|
{
|
dtParam = ExcelAndCsvHelper.GetDataTableFromExcelFile(filePath, true);
|
}
|
|
int choice_category = Convert.ToInt32(dtParam.Rows[29][2].ToString()); // 挑选类别:0:点选; 1:穿刺
|
int choice_distance_mode = Convert.ToInt32((dtParam.Rows[10][2] != "") ? dtParam.Rows[10][2].ToString() : "0"); // 挑菌时离底或离菌表面,目前是离底
|
float choice_distance_value = (float)Convert.ToDouble((dtParam.Rows[11][2] != "") ? dtParam.Rows[11][2].ToString() : "0"); // 离底或菌表面距离
|
|
// 挑菌x、y轴偏移距离(毫米)
|
float choice_xAxis_offsite = (float)Convert.ToDouble((dtParam.Rows[12][2] != "") ? dtParam.Rows[12][2].ToString() : "0"); // 挑菌时x坐标偏移
|
float choice_yAxis_offsite = (float)Convert.ToDouble((dtParam.Rows[13][2] != "") ? dtParam.Rows[13][2].ToString() : "0"); // 挑菌时y坐标偏移
|
float coating_bottom_distance = (float)Convert.ToDouble((dtParam.Rows[14][2] != "") ? dtParam.Rows[14][2].ToString() : "0"); // 涂布离底或菌表面距离
|
float coating_xAxis_offsite = (float)Convert.ToDouble((dtParam.Rows[15][2] != "") ? dtParam.Rows[15][2].ToString() : "0"); // 涂布时x坐标偏移
|
float coating_yAxis_offsite = (float)Convert.ToDouble((dtParam.Rows[16][2] != "") ? dtParam.Rows[16][2].ToString() : "0"); // 涂布时y坐标偏移
|
int coating_mode = Convert.ToInt32((dtParam.Rows[17][2] != "") ? dtParam.Rows[17][2].ToString() : "0"); // 涂布方式 1:回字型; 2:Z字型; 3:上下移动; 4:吸放液; 5:放液
|
float press_distance = (float)Convert.ToDouble((dtParam.Rows[30][2] != "") ? dtParam.Rows[30][2].ToString() : "0"); // 挑菌时下压距离
|
float coatingspeed = (float)Convert.ToDouble((dtParam.Rows[18][2] != "") ? dtParam.Rows[18][2].ToString() : "0"); // 涂布动作速度
|
float fCircularDishMount = (float)Convert.ToDouble(ConfigurationManager.AppSettings["circularDishMount"]); // 圆形皿底托高度
|
|
int[] charray = Shared.ChannelsId;
|
string channelNums = Shared.ChannelsId.Count().ToString();
|
|
methodNode.SelectSingleNode("channels").InnerText = channelNums; // 更新一下枪通道数据
|
int iChioceTotal = methodCoatingFile.transferDataTable.Rows.Count; // 待涂布的数据总条目数
|
int realChioceTotal = iChioceTotal / launchView.choiceTimes; // 实际菌落的个数
|
#endregion
|
|
#region 数据验证
|
if (strCurrentCulture.Equals("zh-CN"))
|
{
|
launchView.AddLogs("【" + DateTime.Now.ToString("HH:mm:ss:fff") + "】> Xhandler: 【" + strMethodName + "】" + Properties.MachineRunResource.strProgress.ToString() + Properties.MachineRunResource.strCheckData);
|
}
|
else
|
{
|
launchView.AddLogs("【" + DateTime.Now.ToString("HH:mm:ss:fff") + "】> Xhandler: 【" + strMethodName + "】progress: check data;");
|
}
|
#endregion
|
|
//判断是否是双涂布的文件,如果是双涂布的文件数据则分通道的处理方式不同;如果是单涂布的文件数据则正常分通道涂布即可
|
#region 挑菌+涂布
|
|
#region Lite_Choice、T200
|
if (Shared.ChannelCount == 1)
|
{
|
if (methodCoatingFile.transferDataTable.Rows.Count == 0)
|
{
|
// 文件涂布不执行,继续执行后面的动作方法
|
result = true;
|
return result;
|
}
|
|
#region 准备参数
|
// 转移目标板到涂布位方法
|
string strTransferDesPlateMethodFileName = AppDomain.CurrentDomain.BaseDirectory +
|
"\\" + ConfigurationManager.AppSettings["transferDesPlateMethod"].ToString();
|
// 转移目标板盖到涂布放盖位方法
|
string strTransferDesPlateCoverMethodFileName = AppDomain.CurrentDomain.BaseDirectory +
|
"\\" + ConfigurationManager.AppSettings["transferDesPlateCoverMethod"].ToString();
|
|
// 待涂布的数据总条目数
|
iChioceTotal = methodCoatingFile.transferDataTable.Rows.Count;
|
|
DataTable dtCoatingFile = methodCoatingFile.transferDataTable;
|
string targetWellName = dtCoatingFile.Rows[0][methodCoatingFile.destinationWell].ToString(); // 目标板孔位: A1
|
List<CoatingLabware> lstDesPlateInfo = new List<CoatingLabware>(); // 目标板已开盖的点位名称
|
|
// 所有目标板
|
DataView dvCoatingFile = new DataView(dtCoatingFile);
|
DataTable dtDistinct = dvCoatingFile.ToTable(true, methodCoatingFile.destinationLabware);
|
|
// 前回涂布板位
|
List<string> lstCoatingLastLabwareName = new List<string>();
|
string strLog = string.Empty;
|
|
// 拍照点位名称
|
string strSrcPlateName = ConfigurationManager.AppSettings["choiceLatticeId"].ToString();
|
#endregion
|
|
launchView.SetWaitOne();//暂停
|
|
#region 圆形皿超声
|
int nRtn = ControlCom.DoUltrasonicForFileCoating(launchView, xmlEnv, methodNode, methodCoatingFile, strSrcPlateName, isSimulator);
|
// 0:正常;1:继续;2:停止
|
if (nRtn == 2)
|
{
|
return false;
|
}
|
#endregion
|
|
#region 循环挑菌数量
|
for (int iChoiceIndex = 0; iChoiceIndex < iChioceTotal; iChoiceIndex++) // 循环控制待挑选的所有菌落
|
{
|
DataRow rowItem = dtCoatingFile.Rows[iChoiceIndex];
|
string strSrcRealPlateName = rowItem[methodCoatingFile.sourceLabware].ToString(); // 来源板真实点位名称
|
string strSrcPlateBarcode = rowItem["SourceBarcode"].ToString(); // 来源板Barcode
|
string strChoiceWellXYZ = rowItem[methodCoatingFile.sourceWell].ToString(); // 挑菌板孔位坐标
|
string strDesPlateName = rowItem[methodCoatingFile.destinationLabware].ToString(); // 目标板名称:P4
|
string strDesWell = rowItem[methodCoatingFile.destinationWell].ToString(); // 目标板孔位
|
bool isNewPlateBatch = bool.Parse(rowItem["IsNewPlateBatch"].ToString()); // 是否是新一批次的目标板(目标板不够用时,需要弹窗,人工补充耗材后点击继续)
|
bool isPlateLastWell = bool.Parse(rowItem["IsPlateLastWell"].ToString()); // 是否是一个板子最后的一个有效孔
|
bool isOpenCover = !lstDesPlateInfo.Exists(it => it.LabwarePositon.Equals(strDesPlateName));// 是否开盖
|
int diff = ((iChoiceIndex + 1) % launchView.choiceTimes);
|
|
launchView.SetWaitOne();//暂停
|
|
#region 是否为当前挑菌点的第一次涂布动作; 是否为当前挑菌点的最后一次涂布动作
|
bool isPointFirstTime = false;
|
bool isPointLastTime = false;
|
|
if (launchView.choiceTimes == 1)
|
{
|
isPointFirstTime = true;
|
isPointLastTime = true;
|
}
|
else
|
{
|
isPointFirstTime = ((iChoiceIndex + 1) % launchView.choiceTimes) != 0 ? true : false;
|
isPointLastTime = ((iChoiceIndex + 1) % launchView.choiceTimes) == 0 ? true : false;
|
}
|
#endregion
|
|
if (isPointFirstTime)
|
{
|
#region 判断台面上目标板是否够用
|
if ((isNewPlateBatch && iChoiceIndex != 0))
|
{
|
// 状态6 报错/急停 红闪/蜂鸣5S
|
CommonBll.StatusLamp(6, isSimulator);
|
|
SetBarcodeDlgForAddConsumables setBarcodeDlg = null;
|
bool bIsBreak = false;
|
Application.Current.Dispatcher.Invoke(new Action(() =>
|
{
|
string strMsg = string.Format(Properties.CoatingResource.strNoValidConsumables, Environment.NewLine);
|
setBarcodeDlg = new SetBarcodeDlgForAddConsumables(strMsg);
|
setBarcodeDlg.launchView = launchView;
|
setBarcodeDlg.dtCoatingFile = dtCoatingFile;
|
setBarcodeDlg.StartIndex = iChoiceIndex;
|
|
SolidColorBrush mybtn1_Brush = new SolidColorBrush(System.Windows.Media.Color.FromArgb(70, 0, 0, 0));
|
setBarcodeDlg.Background = (System.Windows.Media.Brush)mybtn1_Brush;
|
setBarcodeDlg.ShowDialog();
|
|
if (setBarcodeDlg.DialogResult == true)
|
{
|
foreach (DataRow rowItemDes in dtDistinct.Rows)
|
{
|
// 更新已使用的涂布目标孔的颜色
|
ControlCom.UpdateDesPlateWellsColor(xmlEnv, rowItemDes[methodCoatingFile.destinationLabware].ToString(), launchView);
|
}
|
|
// 继续执行
|
|
// 状态4 运行 绿色
|
CommonBll.StatusLamp(4, isSimulator);
|
}
|
else
|
{
|
bIsBreak = true;
|
}
|
}));
|
|
if (bIsBreak)
|
{
|
result = true;
|
break;
|
}
|
}
|
#endregion
|
|
#region 目标板 开盖
|
// 涂布板位自动开关盖
|
if (isOpenCover && methodCoatingFile.autoOpenCloseCoverCoating)
|
{
|
for (int choiceTimeIndex = 0; choiceTimeIndex < launchView.choiceTimes; choiceTimeIndex++)
|
{
|
#region Del
|
//// 转移目标板到涂布位:PX->P10
|
//result =ControlCom.DoReadMethodFileAndActionTransfer(strTransferDesPlateMethodFileName, strDesPlateName, coatingLatticeId, isSimulator, launchView);
|
//if (!result)
|
//{
|
// return result;
|
//}
|
//coatingPlate.LatticeNum = strDesPlateName;
|
#endregion
|
|
CoatingLabware coatingLabware = new CoatingLabware();
|
coatingLabware.LabwarePositon = choiceTimeIndex == 0 ?
|
strDesPlateName :
|
dtCoatingFile.Rows[iChoiceIndex + 1][methodCoatingFile.destinationLabware].ToString(); // 耗材所在的位置
|
coatingLabware.LabwareCoverPositon = listCoatingCoverLatticeId[choiceTimeIndex]; // 耗材开盖放置的位置
|
lstDesPlateInfo.Add(coatingLabware);
|
|
// 转移目标板的盖到涂布位放盖位:P10->P2
|
result = ControlCom.DoReadMethodFileAndActionTransfer(strTransferDesPlateCoverMethodFileName, xmlEnv, coatingLabware.LabwarePositon, PositonTypeEnum.Desktop, GripperModelEnum.Right,
|
coatingLabware.LabwareCoverPositon, PositonTypeEnum.Desktop, GripperModelEnum.Right, isSimulator, launchView, TransferTypeEnum.Open);
|
if (!result)
|
{
|
return result;
|
}
|
}
|
}
|
#endregion
|
|
#region 超声探测
|
if (methodCoatingFile.isEnableultrasonic && isOpenCover) // 已开启超声 && 开盖
|
{
|
// N个目标板 先超声探测
|
bool bIsOk = DoUltrasonic(xmlEnv, methodNode, lstDesPlateInfo, methodCoatingFile, isSimulator);
|
if (!bIsOk)
|
{
|
return false;
|
}
|
}
|
#endregion
|
}
|
|
#region 安装涂布头
|
// 当前挑菌点的第一次涂布动作
|
// 多块目标板挑菌前要换枪头
|
if (isPointFirstTime || methodCoatingFile.pickAgoChangeTipEveryTime)
|
{
|
// 先去安装枪头
|
float tipoffsetLength = float.Parse(methodNode.SelectSingleNode("coatingOffset").InnerText);
|
bool bLoadTipResult = ControlCom.LoadTipAutomation(xmlEnv.SelectNodes("platform"), methodNode,
|
isSimulator, launchView, socketTcpClientToRemote, tipoffsetLength);
|
if (!bLoadTipResult)
|
{
|
return false;
|
}
|
}
|
#endregion
|
|
#region 挑菌前吸液
|
MethodChoiceAgoAspirateChild aspirateData = methodCoatingFile.choiceAgoAspirateData;
|
aspirateData.armValue = methodCoatingFile.armValue;
|
|
if ((isPointFirstTime || methodCoatingFile.pickAgoChangeTipEveryTime) &&
|
aspirateData.bEnableBeforeAspirate)
|
{
|
// 获取吸液耗材板位
|
var latticeAspirateNode = xmlEnv.SelectSingleNode("platform[labware_id='" + aspirateData.labwareValue + "']");
|
// 获取当前台面板位信息
|
int nLatticeIdAspirate = ControlCom.GetLatticeId(Convert.ToInt32(latticeAspirateNode.SelectSingleNode("lattice_id").InnerText));
|
Lattice latticeAspirate = LatticeDB.GetLatticeDataByIdFromdb(nLatticeIdAspirate.ToString());
|
|
bool bBeforeAspirate = ControlCom.DoBeforeAspirate(launchView, xmlEnv, strMethodName, aspirateData, latticeAspirate,
|
aspirateData.wellarray, aspirateData.labwareValue, "None", isSimulator);
|
if (!bBeforeAspirate)
|
{
|
return false;
|
}
|
}
|
#endregion
|
|
#region 挑选
|
// 当前挑菌点的第一次涂布动作
|
// 每次涂布前都挑菌
|
if (isPointFirstTime || methodCoatingFile.pickEveryTime)
|
{
|
string strScrlabwareid = ""; // 来源板耗材ID;
|
string strScrLatticeid = ""; // 来源板位置ID
|
|
// 用来源板名字取查找来源板的类型
|
var latticeXn = xmlEnv.SelectSingleNode("platform[labware_sname='" + strSrcPlateName + "']");
|
if (latticeXn != null)
|
{
|
strScrlabwareid = latticeXn.SelectSingleNode("labware_id").InnerText;
|
strScrLatticeid = latticeXn.SelectSingleNode("lattice_id").InnerText;
|
|
// 获取拍照位的坐标
|
Labware labwareSrc = LabwareDB.GetLabware(strScrlabwareid);
|
int latticeIdSrc = ControlCom.GetLatticeId(Convert.ToInt32(strScrLatticeid));
|
Lattice latticeSrc = LatticeDB.GetLatticeDataByIdFromdb(latticeIdSrc.ToString());
|
|
if (labwareSrc != null)
|
{
|
string[] vChoiceWellXYZSplit = strChoiceWellXYZ.Split(','); // 分割后的挑菌板孔位坐标
|
ChoiceMParam choiceMParam = new ChoiceMParam();
|
choiceMParam.xAxisVal = (float)Convert.ToDouble(vChoiceWellXYZSplit[0]) + choice_xAxis_offsite;
|
choiceMParam.yAxisVal = (float)Convert.ToDouble(vChoiceWellXYZSplit[1]) + choice_yAxis_offsite;
|
|
choiceMParam.xAxisOffsetVal = 0; // x轴移动到的坐标点距后再次动作偏移的x距离
|
choiceMParam.yAxisOffsetVal = 0; // y轴移动到的坐标点距后再次动作偏移的y距离
|
choiceMParam.armId = Convert.ToInt32(methodCoatingFile.armValue); // 挑选所用机械臂Id
|
choiceMParam.channelId = 1; // 挑选所用通道Id
|
choiceMParam.choiceMode = choice_category; // 挑菌模式:1:单选; 2:穿刺
|
choiceMParam.basezAxisVal = zAxisVal; // z轴默认安全坐标点距
|
choiceMParam.enableSupersonic = methodCoatingFile.isEnableultrasonic; // 挑菌时是否开启超声波探测值作为Z轴值:true:用;false:不用
|
choiceMParam.currentLengthOfTip = ControlCom.CurrentLengthOfTip; // 当前挑菌安装枪头后,枪增加的长度
|
choiceMParam.choiceTimeOnSameplace = 1; // 同一个菌落点第几次挑选
|
choiceMParam.latticeName = strSrcPlateName; // 挑菌板位名称
|
|
if (methodCoatingFile.choiceCategory == EnumManagement.GetEnumValue(ChoiceModeEnum.SigleSelectMode)) // 单选
|
{
|
choiceMParam.xAxisOffsetVal = 0;
|
choiceMParam.yAxisOffsetVal = 0;
|
choiceMParam.zAxisVal = (float)Convert.ToDouble(vChoiceWellXYZSplit[2]) - choice_distance_value;
|
}
|
else if (methodCoatingFile.choiceCategory == EnumManagement.GetEnumValue(ChoiceModeEnum.PricksMode)) // 穿刺
|
{
|
choiceMParam.xAxisOffsetVal = choice_xAxis_offsite;
|
choiceMParam.yAxisOffsetVal = choice_yAxis_offsite;
|
|
// 丝状真菌:固定高度挑菌
|
choiceMParam.zAxisVal = (float)latticeSrc.lattice_Z - (float)Convert.ToDouble(labwareSrc.well_bottom_height) -
|
ControlCom.CurrentLengthOfTip - choice_distance_value - fCircularDishMount;
|
}
|
|
choiceMParam.zPressDownVal = press_distance;
|
|
// 执行挑菌动作
|
bool bIsOk = ControlCom.RunChoice(launchView, strMethodName, choiceMParam, strChoiceWellXYZ,
|
strSrcRealPlateName, strSrcPlateBarcode, isSimulator);
|
if (!bIsOk)
|
{
|
return false;
|
}
|
}
|
}
|
else
|
{
|
if (strCurrentCulture.Equals("zh-CN"))
|
{
|
launchView.AddLogs("【" + DateTime.Now.ToString("HH:mm:ss:fff") + "】> Xhandler: 【" + methodCoatingFile.name + "】" + Properties.MachineRunResource.strProgress + Properties.RunCoatingFileResource.strChoiceLatticeWithout);
|
}
|
else
|
{
|
launchView.AddLogs("【" + DateTime.Now.ToString("HH:mm:ss:fff") + "】> Xhandler: 【" + methodCoatingFile.name + "】progress:Can't find lattice!");
|
}
|
result = false;
|
return result;
|
}
|
}
|
else
|
{
|
DateTime startTime = DateTime.Now;
|
DateTime endTime = DateTime.Now;
|
launchView.addChoiceDataIntoReport(null, strSrcRealPlateName, "0", new string[] { strChoiceWellXYZ }, "pass", "",
|
startTime, endTime, "Choice", strSrcPlateBarcode);
|
}
|
#endregion
|
|
#region 涂布
|
string strDesLabwareName = strDesPlateName; // 目标板名称:P10
|
string strDeslabwareid = ""; // 目标板耗材id;
|
string strDesLatticeid = ""; // 目标板位置Id
|
string strDesLabwareBarcode = ""; // 目标板条码
|
|
var latticeDesXn = xmlEnv.SelectSingleNode("platform[labware_sname='" + strDesLabwareName + "']");
|
if (latticeDesXn != null)
|
{
|
strDeslabwareid = latticeDesXn.SelectSingleNode("labware_id").InnerText;
|
strDesLatticeid = latticeDesXn.SelectSingleNode("lattice_id").InnerText;
|
//strDesLabwareBarcode = latticeDesXn.SelectSingleNode("labware_barcode").InnerText;
|
strDesLabwareBarcode = rowItem["TargetBarcode"].ToString(); // 目标板条码
|
|
// 获取待涂布板位的坐标
|
Labware labwareDes = LabwareDB.GetLabware(strDeslabwareid);
|
int latticeIdDes = ControlCom.GetLatticeId(Convert.ToInt32(strDesLatticeid));
|
|
Lattice latticeDes = LatticeDB.GetLatticeDataByIdFromdb(latticeIdDes.ToString());
|
|
if (labwareDes != null)
|
{
|
// 获取孔位信息
|
TipsTable targetWellInfo = ControlCom.GetWellInfo(labwareDes, latticeDes, latticeIdDes, strDeslabwareid, strDesWell);
|
|
if (targetWellInfo != null)
|
{
|
#region 涂布方式 1:回字型 2:Z字型;3:上下移动
|
if (methodCoatingFile.coatingModeValue == EnumManagement.GetEnumValue(CoatingModeEnum.HuiziMode) ||
|
methodCoatingFile.coatingModeValue == EnumManagement.GetEnumValue(CoatingModeEnum.ZMode) ||
|
methodCoatingFile.coatingModeValue == EnumManagement.GetEnumValue(CoatingModeEnum.UpDownMode))
|
{
|
#region 涂布参数设置
|
CoatingMParam coatingMParam = new CoatingMParam();
|
coatingMParam.xAxisVal = (float)Convert.ToDouble(targetWellInfo.axis_b_X.ToString()) + coating_xAxis_offsite;
|
coatingMParam.yAxisVal = (float)Convert.ToDouble(targetWellInfo.axis_b_Y.ToString()) + coating_yAxis_offsite;
|
coatingMParam.armId = Convert.ToInt32(methodCoatingFile.armValue);
|
coatingMParam.channelId = 1;
|
float zVal = targetWellInfo.axis_b_Z - (float)coating_bottom_distance;
|
coatingMParam.zAxisVal = zVal < 0 ? 0 : zVal; // 涂布主z轴移动坐标点距
|
coatingMParam.zChAxisVal = coatingMParam.zAxisVal; // 涂布通道z轴移动坐标点距
|
coatingMParam.coatingShape = coating_mode; // 涂布方式 1:回字型 2:Z字型;3:上下移动
|
// 孔洞形状,1:圆柱体;2:立方体
|
// 涂布范围值:如果是圆形孔值为半径;如是方形孔值为边长一半
|
coatingMParam.rangeVal = labwareDes.well_shape == 1 ?
|
((float)labwareDes.well_mouth_radius) : ((float)(labwareDes.well_top_x / 2.0d));
|
coatingMParam.basezAxisVal = zAxisVal; // 主z轴默认安全坐标点距
|
coatingMParam.coatingSpeed = coatingspeed; // 涂布电机速度
|
coatingMParam.coatingTipsOutWidth = ControlCom.OutWidthOfTip; // 涂布枪头头部外宽度
|
coatingMParam.coatingTipsInWidth = ControlCom.InWidthOfTip; // 涂布枪头头部内宽度
|
// isFirstSupersonic = true:本耗材第一次超声探测
|
if (isNewPlateBatch && isPointFirstTime)
|
{
|
lstCoatingLastLabwareName.Clear();
|
}
|
coatingMParam.isFirstSupersonic = !lstCoatingLastLabwareName.Contains(strDesLabwareName);
|
// 当前涂布板位更新到【前回涂布板位】
|
if (!lstCoatingLastLabwareName.Contains(strDesLabwareName))
|
{
|
lstCoatingLastLabwareName.Add(strDesLabwareName);
|
}
|
|
coatingMParam.enableSupersonic = methodCoatingFile.isEnableultrasonic; // 是否使用超声数据:true:是;false:否
|
coatingMParam.currentLengthOfTip = ControlCom.CurrentLengthOfTip; // 当前涂布安装枪头后,枪增加的长度
|
// 单孔板中心坐标x,y,z 字符串,逗号分割
|
coatingMParam.centerPointVal = ((float)latticeDes.lattice_X + ((float)latticeDes.lattice_length / 2)).ToString() + "," + ((float)latticeDes.lattice_Y + ((float)latticeDes.lattice_width / 2)).ToString() + "," + coatingMParam.zAxisVal.ToString();
|
//coatingMParam.xLengthOfGap = 10.0f; // 超声波x方向间隙
|
//coatingMParam.yLengthOfGap = 10.0f; // 超声波y方向间隙
|
coatingMParam.latticeName = strDesLabwareName; // 超声波探测涂布的板位名称
|
#endregion
|
|
// 执行涂布动作
|
bool bIsOk = ControlCom.RunCoating(launchView, strMethodName, coatingMParam, targetWellInfo, strDesWell,
|
strDesLabwareName, strDesLabwareBarcode, isSimulator);
|
if (!bIsOk)
|
{
|
return false;
|
}
|
}
|
#endregion
|
|
#region 涂布方式 4:吸放液
|
else if (methodCoatingFile.coatingModeValue == EnumManagement.GetEnumValue(CoatingModeEnum.AspirateDispenseMode))
|
{
|
#region 混合参数设置
|
MixMParam mixMParam = new MixMParam();
|
mixMParam.xAxisVal = (float)Convert.ToDouble(targetWellInfo.axis_b_X.ToString()); // x轴移动到的坐标点距
|
mixMParam.yAxisVal = (float)Convert.ToDouble(targetWellInfo.axis_b_Y.ToString()); // y轴移动到的坐标点距
|
mixMParam.armId = Convert.ToInt32(methodCoatingFile.armValue); // 吸液所用机械臂Id
|
mixMParam.isSurvey = false; // 是否需要探测
|
mixMParam.mixCount = methodCoatingFile.mixcount; // 混合次数
|
mixMParam.mixvolume = (float)methodCoatingFile.mixvolume; // 混合时体积
|
mixMParam.mixAspiratePositionText = methodCoatingFile.mixAspiratePositionText; // 吸液距离类型名称
|
mixMParam.mixAspiratePositionValue = methodCoatingFile.mixAspiratePositionValue; // 吸液距离类型Id,0:液面; 1顶部;2:底部
|
|
if (methodCoatingFile.mixAspiratePositionValue == EnumManagement.GetEnumValue(MixPositionEnum.Top) ||
|
methodCoatingFile.mixAspiratePositionValue == EnumManagement.GetEnumValue(MixPositionEnum.Bottom)) // top、bottom
|
{
|
mixMParam.mixAspirateDistance = (float)methodCoatingFile.mixAspirateDistance; // 吸液距离
|
}
|
mixMParam.mixAspirateSpeed = (float)methodCoatingFile.mixAspirateSpeed; // 吸液速度
|
|
// 液体参数
|
string liquidpidValue = methodCoatingFile.liquidpidValue;
|
Liquid liquid = LiquidDB.GetALiquidFromdb(liquidpidValue);
|
mixMParam.beforeAirpAxisVal = (float)liquid.before_aspirate_volume;
|
|
mixMParam.mixDispensePositionText = methodCoatingFile.mixDispensePositionText; // 排液距离类型名称
|
mixMParam.mixDispensePositionValue = methodCoatingFile.mixDispensePositionValue; // 排液距离类型Id,0:液面; 1顶部;2:底部
|
mixMParam.mixDispenseDistance = (float)methodCoatingFile.mixDispenseDistance; // 排液距离
|
mixMParam.mixDispenseSpeed = (float)methodCoatingFile.mixDispenseSpeed; // 排液速度
|
//liquidVolumeType 未传值
|
|
float zVal = targetWellInfo.axis_b_Z + ControlCom.CurrentLengthOfTipOffSetVal;
|
mixMParam.zAxisVal = zVal; // 混合时z轴移动坐标点距
|
mixMParam.wellzAxisVal = zVal - (float)labwareDes.well_height;
|
mixMParam.basezAxisVal = (float)Convert.ToDouble(ConfigurationManager.AppSettings["zAxisSafeVal"]);
|
#endregion
|
|
// 执行混合动作
|
bool bIsOk = ControlCom.RunMix(launchView, strMethodName, mixMParam, targetWellInfo, strDesWell,
|
strDesLabwareName, strDesLabwareBarcode, isSimulator);
|
if (!bIsOk)
|
{
|
return false;
|
}
|
}
|
#endregion
|
|
#region 涂布方式 5:放液
|
else if (methodCoatingFile.coatingModeValue == EnumManagement.GetEnumValue(CoatingModeEnum.DispenseMode))
|
{
|
// 放液
|
bool bDispense = ControlCom.DoDispense(launchView, strMethodName, methodCoatingFile.choiceAgoAspirateData, labwareDes, latticeDes, targetWellInfo, strDesLabwareBarcode, isSimulator);
|
if (!bDispense)
|
{
|
return false;
|
}
|
}
|
#endregion
|
}
|
}
|
else
|
{
|
if (strCurrentCulture.Equals("zh-CN"))
|
{
|
launchView.AddLogs("【" + DateTime.Now.ToString("HH:mm:ss:fff") + "】> Xhandler: 【" + methodCoatingFile.name + "】" + Properties.MachineRunResource.strProgress + Properties.RunCoatingFileResource.strChoiceLatticeWithout);
|
}
|
else
|
{
|
launchView.AddLogs("【" + DateTime.Now.ToString("HH:mm:ss:fff") + "】> Xhandler: 【" + methodCoatingFile.name + "】progress:Can't find lattice!");
|
}
|
result = false;
|
return result;
|
}
|
}
|
else
|
{
|
if (strCurrentCulture.Equals("zh-CN"))
|
{
|
launchView.AddLogs("【" + DateTime.Now.ToString("HH:mm:ss:fff") + "】> Xhandler: 【" + strMethodName + "】" + Properties.MachineRunResource.strProgress + Properties.RunCoatingFileResource.strCoatingLatticeWithout);
|
}
|
else
|
{
|
launchView.AddLogs("【" + DateTime.Now.ToString("HH:mm:ss:fff") + "】> Xhandler: 【" + strMethodName + "】progress: lattice was wrong!");
|
}
|
result = false;
|
return result;
|
}
|
#endregion
|
|
#region 卸载Tip,丢在垃圾桶
|
if (isPointLastTime || methodCoatingFile.pickAgoChangeTipEveryTime)
|
{
|
UnloadTipsControl unloadTipsControl = new UnloadTipsControl(Shared.SoftwareInformation.currentculture);
|
unloadTipsControl.launchView = launchView;
|
unloadTipsControl.socketTcpClientToRemote = socketTcpClientToRemote;
|
bool bUnloadResult = unloadTipsControl.ExecuteUnloadTipsInToTrash(platformNodeList, methodNode, isSimulator);
|
launchView.currentIsLoadingTips = false;
|
}
|
#endregion
|
|
if (isPointLastTime)
|
{
|
#region 计算当前挑菌的个数
|
decimal dTemp = ((decimal)(iChoiceIndex + 1)) / (decimal)launchView.choiceTimes;
|
decimal realCurrentChioceCnt = Math.Ceiling(dTemp);
|
|
if (strCurrentCulture.Equals("zh-CN"))
|
{
|
strLog = string.Format("【{0}】>Xhandler: 【{1}】{2} {3}:{4}/{5}",
|
DateTime.Now.ToString("HH:mm:ss:fff"), methodCoatingFile.name,
|
Properties.MachineRunResource.strProgress, Properties.RunCoatingFileResource.strPickingBacteria, realCurrentChioceCnt, realChioceTotal);
|
}
|
else
|
{
|
strLog = string.Format("【{0}】>Xhandler: 【{1}】progress: picking bacteria:{2}/{3}",
|
DateTime.Now.ToString("HH:mm:ss:fff"), methodCoatingFile.name, realCurrentChioceCnt, realChioceTotal);
|
}
|
|
launchView.AddLogs(strLog);
|
#endregion
|
}
|
|
#region 目标板 关盖
|
// 不论是单板涂布还是双板涂布,都是在最后块目标板涂布之后再关盖
|
if (isPlateLastWell && isPointLastTime && methodCoatingFile.autoOpenCloseCoverCoating)
|
{
|
for (int choiceTimeIndex = 0; choiceTimeIndex < lstDesPlateInfo.Count; choiceTimeIndex++)
|
{
|
// 转移耗材盖到目标位:P11->P10
|
result = ControlCom.DoReadMethodFileAndActionTransfer(strTransferDesPlateCoverMethodFileName, xmlEnv, lstDesPlateInfo[choiceTimeIndex].LabwareCoverPositon, PositonTypeEnum.Desktop, GripperModelEnum.Right,
|
lstDesPlateInfo[choiceTimeIndex].LabwarePositon, PositonTypeEnum.Desktop, GripperModelEnum.Right, isSimulator, launchView, TransferTypeEnum.Close);
|
if (!result)
|
{
|
return result;
|
}
|
|
#region Del
|
//// 转移涂布位耗材到原来位置:P10->PX
|
//result = ControlCom.DoReadMethodFileAndActionTransfer(strTransferDesPlateMethodFileName, coatingLatticeId, coatingPlate.LatticeNum, isSimulator, launchView);
|
//if (!result)
|
//{
|
// return result;
|
//}
|
#endregion
|
}
|
|
lstDesPlateInfo.Clear();
|
// 继续执行
|
}
|
|
#endregion
|
}
|
#endregion
|
}
|
#endregion
|
|
#endregion
|
}
|
catch (Exception ex)
|
{
|
LoggerHelper.ErrorLog("ERROR:", ex);
|
|
#region Exception
|
launchView.AddLogs("【" + DateTime.Now.ToString("HH:mm:ss:fff") + "】>Xhandler: 【" + strMethodName + "】error:source:" + ex.Source + ";error:" + ex.Message + ";");
|
|
result = false;
|
MethodMsg methodMsg = new MethodMsg(
|
Guid.NewGuid().ToString(),
|
"ID202_Choice_machine",
|
5,
|
"",
|
"ExecuteCoatingFile",
|
"1001",
|
"error source:" + ex.Source + ";error:" + ex.Message,
|
6,
|
0
|
);
|
if (socketTcpClientToRemote != null)
|
{
|
socketTcpClientToRemote.sendmessageError(socketTcpClientToRemote.CreateSendMsgContent(methodMsg, false), launchView.isRemotingOper);
|
}
|
#endregion
|
}
|
|
return result;
|
}
|
|
/// <summary>
|
/// 执行超声探测
|
/// </summary>
|
/// <param name="plateNode"></param>
|
/// <param name="methodNode"></param>
|
/// <param name="lstDesPlateInfo"></param>
|
/// <param name="methodCoatingFile"></param>
|
/// <param name="isSimulator"></param>
|
/// <returns></returns>
|
private bool DoUltrasonic(XmlNode plateNode, XmlNode methodNode, List<CoatingLabware> lstDesPlateInfo, MethodCoatingFile methodCoatingFile, bool isSimulator)
|
{
|
// 1、2
|
for (int choiceTimeIndex = 0; choiceTimeIndex < lstDesPlateInfo.Count; choiceTimeIndex++)
|
{
|
// 执行超声单步操作
|
string labwarePositon = lstDesPlateInfo[choiceTimeIndex].LabwarePositon;
|
int nRtn = ControlCom.DoUltrasonicForFileCoating(launchView, plateNode, methodNode, methodCoatingFile, labwarePositon, isSimulator);
|
// 0:正常;1:继续;2:停止
|
if (nRtn == 2)
|
{
|
return false;
|
}
|
}
|
|
return true;
|
}
|
|
/// <summary>
|
/// 单机运行时,作成 挑菌下发参数.xls
|
/// </summary>
|
/// <param name="xmlNode"></param>
|
/// <param name="filePath"></param>
|
private DataTable DoUpdateCoatingMode(XmlNode xmlNode, string filePath)
|
{
|
DataTable dtCoatingParams = ExcelAndCsvHelper.GetDataTableFromExcelFile(filePath, true);
|
string strValName = "属性值";
|
|
#region 数据准备
|
if (dtCoatingParams.Rows.Count > 29)
|
{
|
// 挑菌方式:0:单选; 1:穿刺; 2:吸放液; 3:放液
|
dtCoatingParams.Rows[29][strValName] = xmlNode.SelectSingleNode("choiceCategory").InnerText;
|
}
|
// 涂布方式
|
dtCoatingParams.Rows[17][strValName] = xmlNode.SelectSingleNode("coatingmodeValue").InnerText; // 画面上涂布方式 0:回字型 1:Z字型;2:上下移动
|
#endregion
|
|
ExcelAndCsvHelper.WriteDataTableToExcelFile(dtCoatingParams, filePath);
|
|
return dtCoatingParams;
|
}
|
#endregion
|
|
#region 重新加载文件数据
|
private DataTable SelectFile(string file)
|
{
|
string ext = System.IO.Path.GetExtension(file);
|
DataTable transferData = null;
|
if (string.Compare(ext, ".csv", true) == 0)
|
transferData = ExcelAndCsvHelper.GetDataTableFromCsvFile(file, false);
|
else
|
transferData = ExcelAndCsvHelper.GetDataTableFromExcelFile(file, true);
|
|
|
if (transferData == null)
|
{
|
transferData = new DataTable();
|
}
|
return transferData;
|
}
|
#endregion
|
}
|
}
|