using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Windows.Forms; using HalconDotNet; using System.IO; using System.Threading; namespace M423project { public partial class ImageForm : Form { MainForm mf; public ImageForm(OPC Opc, ConfigStruct Config) { mf = CommonUtil.mainForm; InitializeComponent(); this.config = Config; this.opc = Opc; CheckForIllegalCrossThreadCalls = false; } OPC opc; ConfigStruct config = new ConfigStruct(); ToolKit.FileToolkit.SerializeFileTool sftConfig = new ToolKit.FileToolkit.SerializeFileTool(); //uint CameraSN = 0; HObject Image = new HObject(); HTuple startCamParam = new HTuple(), cameraParam = new HTuple(), ImagesPath = new HTuple(), nFinalPoses = new HTuple(), error = new HTuple(), pixScale = new HTuple(); HTuple threshold = new HTuple(), ImageRows = new HTuple(), ImageColumns = new HTuple(), RobotRows = new HTuple(), RobotColumns = new HTuple(); string CaltabFileName = ""; //uint loadCamSN = 14050791;//上料相机的序列号 //uint unloadCamSN = 14150928;//下料相机的序列号 //uint datacodeCamSN = 14150932;//读码相机的序列号 //uint xyCamSN = 14103341;//测电池长宽相机的序列号 //string CameraDeviceXY = "[0] Point Grey Camera"; HTuple AcqHandle = new HTuple(); string local = Directory.GetCurrentDirectory(); //PointGreyAndHalcon.PointGreyAndHalcon pga = new PointGreyAndHalcon.PointGreyAndHalcon(); VisionDetect vd = new VisionDetect(); int num; int count; bool isHandGrab = false; bool isCalibrateOK = false; bool performDotCalib = false; bool isDotCalibrateOK = false; bool isOK = false; int RowCount = 0; int ColumnCount = 0;//点阵行列数 ImageToRobotHomat2d imageToRobotH = new ImageToRobotHomat2d(); HTuple Row = new HTuple(), Column = new HTuple(), Angle = new HTuple(); //int SuckerIndex=0;//代表机械手末端执行器吸盘的索引 //int CalibTableIndex = 0;//代表上料Tray盘需要标定的盘位索引 #region 方法 void Initialize() { tbThreshold.Text = config.Threshold.ToString(); } void pga_GrabImageDone(string recData, HImage recImage) { tbSN.Text = recData; //throw new NotImplementedException(); } private void DisplayDotCalibrate(HObject image, HTuple windowHandle, HTuple rows, HTuple columns, bool isCalibOK) { VisionDetect.DisplayImage(image, windowHandle); if (isCalibOK) { HOperatorSet.SetColor(windowHandle, "green"); HOperatorSet.DispCross(windowHandle, rows, columns, 30, 0); } } private void StartCamParam() { startCamParam[0] = cbTelecentricLens.Checked ? 0 : (Convert.ToDouble(tbF.Text)) * 0.001; //镜头焦距 startCamParam[1] = Convert.ToDouble(tbKappa.Text); //镜头畸变系数 startCamParam[2] = (Convert.ToDouble(tbSx.Text)) * (0.000001); //单个像元宽 startCamParam[3] = (Convert.ToDouble(tbSy.Text)) * (0.000001); //单个像元高 startCamParam[4] = Convert.ToDouble(tbCx.Text); //图像中心坐标Cx; startCamParam[5] = Convert.ToDouble(tbCy.Text); //图像中心坐标Cy; startCamParam[6] = (Convert.ToDouble(tbCx.Text)) * 2; //图像宽; startCamParam[7] = (Convert.ToDouble(tbCy.Text)) * 2; //图像高; } //可以使用string.Split方法 private void SeparateStr(string str, out string str1, out string str2) { int first = str.IndexOf(",", 0); str1 = str.Substring(0, first); str2 = str.Substring(first + 1, str.Length - first - 1); } private void SetValuesToDGV(DataGridView dgv, HTuple rows, HTuple columns) { for (int i = 0; i < dgv.RowCount; i++) { for (int j = 0; j < dgv.ColumnCount; j++) { dgv.Rows[i].Cells[j].Value = rows[i * dgv.ColumnCount + j].D.ToString("f3") + "," + columns[i * dgv.ColumnCount + j].D.ToString("f3"); } } } private void SetValuesFromDGV(DataGridView dgv, out HTuple rows, out HTuple columns) { rows = new HTuple(); columns = new HTuple(); for (int i = 0; i < dgv.RowCount; i++) { for (int j = 0; j < dgv.ColumnCount; j++) { string[] strValue = dgv.Rows[i].Cells[j].Value.ToString().Split(','); rows[i * dgv.ColumnCount + j] = strValue[0]; columns[i * dgv.ColumnCount + j] = strValue[1]; } } } private void ChangeControl(int x, bool flag) { switch (x) { case 0: cbxCamera.Enabled = flag; btnOpenVideo.Enabled = flag; btnCloseVideo.Enabled = !flag; panelMode.Enabled = flag; break; case 1: cbxCamera.Enabled = flag; btnOpenVideo.Enabled = !flag; btnCloseVideo.Enabled = flag; panelMode.Enabled = flag; break; case 2: cbxCamera.Enabled = flag; btnOpenVideo.Enabled = !flag; btnCloseVideo.Enabled = !flag; panelMode.Enabled = flag; break; default: break; } } private void ClearDGV(DataGridView dgv) { for (int i = 0; i < dgv.RowCount; i++) { for (int j = 0; j < dgv.ColumnCount; j++) { dgv.Rows[i].Cells[j].Value = null; } } } private void SetH() { switch (cbRobotIndex.SelectedIndex) { case 0: switch (cbSuckerIndex.SelectedIndex) { case 0: switch (cbxCalibTable.SelectedIndex) { case 0: imageToRobotH = config.loadRobotHomat2d.left.one; break; case 1: imageToRobotH = config.loadRobotHomat2d.left.two; break; case 2: imageToRobotH = config.loadRobotHomat2d.left.three; break; case 3: imageToRobotH = config.loadRobotHomat2d.left.four; break; case 4: imageToRobotH = config.loadRobotHomat2d.left.five; break; case 5: imageToRobotH = config.loadRobotHomat2d.left.six; break; case 6: imageToRobotH = config.loadRobotHomat2d.left.seven; break; case 7: imageToRobotH = config.loadRobotHomat2d.left.eight; break; case 8: imageToRobotH = config.loadRobotHomat2d.left.nine; break; case 9: imageToRobotH = config.loadRobotHomat2d.left.ten; break; default: break; } break; case 1: switch (cbxCalibTable.SelectedIndex) { case 0: imageToRobotH = config.loadRobotHomat2d.right.one; break; case 1: imageToRobotH = config.loadRobotHomat2d.right.two; break; case 2: imageToRobotH = config.loadRobotHomat2d.right.three; break; case 3: imageToRobotH = config.loadRobotHomat2d.right.four; break; case 4: imageToRobotH = config.loadRobotHomat2d.right.five; break; case 5: imageToRobotH = config.loadRobotHomat2d.right.six; break; case 6: imageToRobotH = config.loadRobotHomat2d.right.seven; break; case 7: imageToRobotH = config.loadRobotHomat2d.right.eight; break; case 8: imageToRobotH = config.loadRobotHomat2d.right.nine; break; case 9: imageToRobotH = config.loadRobotHomat2d.right.ten; break; default: break; } break; } break; case 1: switch (cbSuckerIndex.SelectedIndex) { case 0: switch (cbxCalibTable.SelectedIndex) { case 0: imageToRobotH = config.unloadRobotHomat2d.left.one; break; case 1: imageToRobotH = config.unloadRobotHomat2d.left.two; break; case 2: imageToRobotH = config.unloadRobotHomat2d.left.three; break; case 3: imageToRobotH = config.unloadRobotHomat2d.left.four; break; case 4: imageToRobotH = config.unloadRobotHomat2d.left.five; break; case 5: imageToRobotH = config.unloadRobotHomat2d.left.six; break; case 6: imageToRobotH = config.unloadRobotHomat2d.left.seven; break; case 7: imageToRobotH = config.unloadRobotHomat2d.left.eight; break; case 8: imageToRobotH = config.unloadRobotHomat2d.left.nine; break; case 9: imageToRobotH = config.unloadRobotHomat2d.left.ten; break; default: break; } break; case 1: switch (cbxCalibTable.SelectedIndex) { case 0: imageToRobotH = config.unloadRobotHomat2d.right.one; break; case 1: imageToRobotH = config.unloadRobotHomat2d.right.two; break; case 2: imageToRobotH = config.unloadRobotHomat2d.right.three; break; case 3: imageToRobotH = config.unloadRobotHomat2d.right.four; break; case 4: imageToRobotH = config.unloadRobotHomat2d.right.five; break; case 5: imageToRobotH = config.unloadRobotHomat2d.right.six; break; case 6: imageToRobotH = config.unloadRobotHomat2d.right.seven; break; case 7: imageToRobotH = config.unloadRobotHomat2d.right.eight; break; case 8: imageToRobotH = config.unloadRobotHomat2d.right.nine; break; case 9: imageToRobotH = config.unloadRobotHomat2d.right.ten; break; default: break; } break; } break; default: break; } } private void SetHValue(HTuple tuple) { imageToRobotH.t1 = tuple[0].D; imageToRobotH.t2 = tuple[1].D; imageToRobotH.t3 = tuple[2].D; imageToRobotH.t4 = tuple[3].D; imageToRobotH.t5 = tuple[4].D; imageToRobotH.t6 = tuple[5].D; } #endregion #region 事件 private void btnOpenVideo_Click(object sender, EventArgs e) { try { //if (cbxCamera.SelectedIndex != 2) pga.OpenCamera(CameraSN); //else HOperatorSet.OpenFramegrabber("DirectShow", 1, 1, 0, 0, 0, 0, "default", 8, "gray", -1, "false", "default", CameraDeviceXY, 0, -1, out AcqHandleXY); HTuple ExposureTime = new HTuple(); tmVideo.Enabled = true; ChangeControl(0, false); //if (cbxCamera.SelectedIndex < 2) //{ // HOperatorSet.GetFramegrabberParam(AcqHandle, "ExposureTime", out ExposureTime); // tbExposure.Text = ExposureTime.D.ToString(); //} //if (cbxCamera.SelectedIndex == 2) //{ // HOperatorSet.GetFramegrabberParam(AcqHandle, "exposure", out ExposureTime); // tbExposure.Text = ExposureTime.D.ToString(); //} } catch (Exception) { } } private void btnCloseVideo_Click(object sender, EventArgs e) { try { tmVideo.Enabled = false; //if (cbxCamera.SelectedIndex != 2) pga.CloseCamera(); //else HOperatorSet.CloseFramegrabber(AcqHandleXY); ChangeControl(0, true); HOperatorSet.ClearWindow(hWindowControl1.HalconWindow); } catch (Exception) { //tmVideo.Enabled = false; //ChangeControl(0, true); //HOperatorSet.ClearWindow(hWindowControl1.HalconWindow); } } private void tmVideo_Tick(object sender, EventArgs e) { try { Image.Dispose(); //if (cbxCamera.SelectedIndex != 2) //{ // pga.GrabImage(CameraSN.ToString()); // Image = pga.hoImage; //} //else //{ VisionDetect.GrabImage(AcqHandle, out Image); //} VisionDetect.DisplayImage(Image, hWindowControl1.HalconWindow); if (rbCreateModel.Checked) { tmVideo.Enabled = false; } if (rbCamCalibrate.Checked && isOK) { vd.IsCaltabCalibrate(Image, CaltabFileName, startCamParam, hWindowControl1.HalconWindow, out isCalibrateOK); if (isCalibrateOK && isHandGrab) { ImagesPath[num] = "D:\\Image\\" + cbxCamera.SelectedItem.ToString() + "\\" + num.ToString() + ".tif"; VisionDetect.SaveImage(Image, "tiff", "D:\\Image\\" + cbxCamera.SelectedItem.ToString(), num); num++; lbGrabbed.Text = num.ToString(); if (num == numericUpDown1.Value) { isOK = false; MessageBox.Show("图像数量已满足,请关闭视频流。", "Information", MessageBoxButtons.OK, MessageBoxIcon.Information); } isHandGrab = false; } } if (rbRobotCalibrate.Checked) { HTuple rows = new HTuple(), columns = new HTuple(); vd.isDotCalibrate(Image, threshold, 6, 4, ref rows, ref columns, out isDotCalibrateOK); if (isDotCalibrateOK && performDotCalib) { ClearDGV(dgvImageStatistics); DisplayDotCalibrate(Image, hWindowControl1.HalconWindow, rows, columns, isDotCalibrateOK); HOperatorSet.TupleConcat(ImageRows, rows, out ImageRows); HOperatorSet.TupleConcat(ImageColumns, columns, out ImageColumns); SetValuesToDGV(dgvImageStatistics, rows, columns); VisionDetect.SaveImage(Image, "tiff", "D:\\Image\\NineSquare\\" + (count + 1).ToString()); } performDotCalib = false; } } catch (Exception) { } } private void btnSelectCaltabFile_Click(object sender, EventArgs e) { OpenFileDialog ofd = new OpenFileDialog(); ofd.InitialDirectory = local; if (ofd.ShowDialog() == DialogResult.OK) { CaltabFileName = ofd.FileName; } } private void btnCamCalibrate_Click(object sender, EventArgs e) { try { vd.CameraCalibrate(ImagesPath, CaltabFileName, startCamParam, hWindowControl1.HalconWindow, ref cameraParam, ref nFinalPoses, ref error, ref pixScale); tbPixscale.Text = pixScale.D.ToString(); MessageBox.Show("相机标定成功!", "Information", MessageBoxButtons.OK, MessageBoxIcon.Information); } catch (Exception ee) { MessageBox.Show(ee.ToString(), "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); } } private void HandGrab_Click(object sender, EventArgs e) { isHandGrab = true; } private void btnCamParamSave_Click(object sender, EventArgs e) { SaveFileDialog sfd = new SaveFileDialog(); sfd.InitialDirectory = local; if (sfd.ShowDialog() == DialogResult.OK) { vd.SaveCamParam(cameraParam, sfd.FileName); MessageBox.Show("保存成功!", "Information", MessageBoxButtons.OK, MessageBoxIcon.Information); } } private void ImageForm_Load(object sender, EventArgs e) { rbCamDebug.Checked = true; gbCamCalibrate.Enabled = false; gbRobotCalibrate.Enabled = false; gbCreateModel.Enabled = false; gbPosition.Enabled = false; ChangeControl(2, true); dgvRobotStatistics.TopLeftHeaderCell.Value = "Robot Data"; dgvImageStatistics.TopLeftHeaderCell.Value = "Image Data"; //pga.GrabImageDone += new PointGreyAndHalcon.GrabImageDoneDelegate(pga_GrabImageDone); Initialize(); } private void rbCamDebug_CheckedChanged(object sender, EventArgs e) { gbCamCalibrate.Enabled = rbCamCalibrate.Checked; gbRobotCalibrate.Enabled = rbRobotCalibrate.Checked; gbCreateModel.Enabled = rbCreateModel.Checked; gbPosition.Enabled = rbPosition.Checked; //switch (rbn.Name) //{ // case "rbCamDebug": // //gbDebug.Enabled = true; // gbCamCalibrate.Enabled = false; // gbRobotCalibrate.Enabled = false; // break; // case "rbCamCalibrate": // //gbDebug.Enabled = true; // gbCamCalibrate.Enabled = true; // gbRobotCalibrate.Enabled = false; // break; // case "rbRobotCalibrate": // //gbDebug.Enabled = true; // gbCamCalibrate.Enabled = false; // gbRobotCalibrate.Enabled = true; // break; // case "rbCreateModel": // //gbDebug.Enabled = true; // gbCamCalibrate.Enabled = false; // gbRobotCalibrate.Enabled = false; // break; // default: // break; //} } private void cbTelecentricLens_CheckedChanged(object sender, EventArgs e) { tbF.Enabled = !cbTelecentricLens.Checked; } private void tbExposure_TextChanged(object sender, EventArgs e) { try { HOperatorSet.SetFramegrabberParam(AcqHandle, "ExposureTime", Convert.ToDouble(tbExposure.Text)); } catch (Exception) { } } private void dgvImageStatistics_CellClick(object sender, DataGridViewCellEventArgs e) { if (e.RowIndex > -1 && e.ColumnIndex == 9) { count = e.RowIndex; } } private void btnTransform_Click(object sender, EventArgs e) { //执行机械手坐标与图像坐标之间的转换矩阵,vector_to_hom_mat2d/3d //分清楚是哪个机械手(load,unload)的末端执行器上哪个吸盘(left,right)吸Tray盘的哪个盘位(1...10) HTuple H; double[] hlist = new double[6]; try { SetH(); HOperatorSet.VectorToHomMat2d(ImageColumns, ImageRows, RobotColumns, RobotRows, out H); SetHValue(H); sftConfig.SetConfig(local + "\\Config\\M423Config.xml", config); //计算完成后清空图像坐标与机械手坐标 ImageRows = new HTuple(); ImageColumns = new HTuple(); RobotRows = new HTuple(); RobotColumns = new HTuple(); MessageBox.Show("矩阵计算完成!", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information); } catch (Exception) { ImageRows = new HTuple(); ImageColumns = new HTuple(); RobotRows = new HTuple(); RobotColumns = new HTuple(); MessageBox.Show("矩阵计算失败!", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error); } } private void ImageForm_FormClosing(object sender, FormClosingEventArgs e) { try { tmVideo.Enabled = false; this.DialogResult = DialogResult.OK; //pga.CloseCamera(); } catch (Exception) { //HOperatorSet.CloseAllFramegrabbers(); } } private void tbThreshold_TextChanged(object sender, EventArgs e) { try { threshold = (HTuple)tbThreshold.Text; } catch (Exception) { } } private void btnOK_Click(object sender, EventArgs e) { StartCamParam(); isOK = true; num = 0; lbGrabbed.Text = "0"; } private void cbAutoCx_CheckedChanged(object sender, EventArgs e) { HTuple w, h; CheckBox cb = (CheckBox)sender; if (cb.Checked) { Image.Dispose(); //if (cbxCamera.SelectedIndex!=2) //{ // pga.hoImage.Dispose(); // pga.GrabImage(CameraSN.ToString()); // Image = pga.hoImage; //} //else //{ VisionDetect.GrabImage(AcqHandle, out Image); //} HOperatorSet.GetImageSize(Image, out w, out h); if (cb.Name == "cbAutoCx") tbCx.Text = (w.D * 0.5).ToString(); if (cb.Name == "cbAutoCy") tbCy.Text = (h.D * 0.5).ToString(); } tbCx.Enabled = !cbAutoCx.Checked; tbCy.Enabled = !cbAutoCy.Checked; } private void btnSaveConfig_Click(object sender, EventArgs e) { config.Exposure = Convert.ToDouble(tbExposure.Text); config.Threshold = Convert.ToInt32(tbThreshold.Text); sftConfig.SetConfig(local + "\\Config\\M423Config.xml", config); } private void btnPixscaleSave_Click(object sender, EventArgs e) { switch (cbxCamera.SelectedIndex) { case 0: config.LoadCameraScale = Convert.ToDouble(tbPixscale.Text); break; case 1: config.DataCodeCameraScale = Convert.ToDouble(tbPixscale.Text); break; case 2: config.XyCameraScale = Convert.ToDouble(tbPixscale.Text); break; case 3: config.UnloadCameraScale = Convert.ToDouble(tbPixscale.Text); break; default: break; } sftConfig.SetConfig(local + "\\Config\\M423Config.xml", config); } private void cbxModel_SelectedIndexChanged(object sender, EventArgs e) { if (rbCreateModel.Checked) { try { string SN = ""; switch (cbxModel.SelectedIndex) { case 0: vd.CreateLoadModel(Image, hWindowControl1.HalconWindow, local + "\\Model\\ModelThreeRects.shm"); break; case 1: vd.CreateLoadModel(Image, hWindowControl1.HalconWindow, local + "\\Model\\ModelTriangle.shm"); break; case 2: vd.Create2DDataCodeModel(Image, hWindowControl1.HalconWindow, local + "\\Model", out SN); tbSN.Text = SN; break; default: break; } MessageBox.Show("模板创建成功!", "Information", MessageBoxButtons.OK, MessageBoxIcon.Information); } catch (Exception ex) { MessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); } } } #endregion private void btnRCOK_Click(object sender, EventArgs e) { RowCount = Int32.Parse(tbRowCount.Text); ColumnCount = Int32.Parse(tbColumnCount.Text); dgvImageStatistics.RowCount = RowCount; dgvImageStatistics.ColumnCount = ColumnCount; dgvRobotStatistics.RowCount = RowCount; dgvRobotStatistics.ColumnCount = ColumnCount; btnDotCalibrate.Enabled = true; btnTransform.Enabled = true; } private void btnDotCalibrate_Click(object sender, EventArgs e) { //执行点阵图像标定 performDotCalib = true; } private void btnSaveRobotCoordinate_Click(object sender, EventArgs e) { HTuple rows = new HTuple(), columns = new HTuple(); ClearDGV(dgvRobotStatistics); SetValuesFromDGV(dgvRobotStatistics, out rows, out columns); HOperatorSet.TupleConcat(RobotRows, rows, out RobotRows); HOperatorSet.TupleConcat(RobotColumns, columns, out RobotColumns); } private void cbxPositionStart_SelectedIndexChanged(object sender, EventArgs e) { tmVideo.Enabled = false; //switch (cbxPositionStart.SelectedIndex) //{ // case 0: Image.Dispose(); VisionDetect.GrabImage(AcqHandle, out Image); VisionDetect.DisplayImage(Image, hWindowControl1.HalconWindow); //位置初始化函数 vd.LoadLocation(Image, ref Row, ref Column, ref Angle); // break; //default: // break; //} if ((Row.TupleLength() == 2) && (Column.TupleLength() == 2) && (Angle.TupleLength() == 2)) { SetPosition(); MessageBox.Show("位置"+(cbxPositionStart.SelectedIndex+1).ToString()+"初始化成功!"); } else MessageBox.Show("位置初始化失敗!"); } private void SetPosition() { switch (cbxPositionStart.SelectedIndex) { case 0: config.loadPosition11.x = Column[1].D; config.loadPosition11.y = Row[1].D; config.loadPosition11.angle = Angle[1].D; config.loadPosition12.x = Column[0].D; config.loadPosition12.y = Row[0].D; config.loadPosition12.angle = Angle[0].D; break; case 1: config.loadPosition21.x = Column[1].D; config.loadPosition21.y = Row[1].D; config.loadPosition21.angle = Angle[1].D; config.loadPosition22.x = Column[0].D; config.loadPosition22.y = Row[0].D; config.loadPosition22.angle = Angle[0].D; break; case 2: config.loadPosition31.x = Column[1].D; config.loadPosition31.y = Row[1].D; config.loadPosition31.angle = Angle[1].D; config.loadPosition32.x = Column[0].D; config.loadPosition32.y = Row[0].D; config.loadPosition32.angle = Angle[0].D; break; case 3: config.loadPosition41.x = Column[1].D; config.loadPosition41.y = Row[1].D; config.loadPosition41.angle = Angle[1].D; config.loadPosition42.x = Column[0].D; config.loadPosition42.y = Row[0].D; config.loadPosition42.angle = Angle[0].D; break; case 4: config.loadPosition51.x = Column[1].D; config.loadPosition51.y = Row[1].D; config.loadPosition51.angle = Angle[1].D; config.loadPosition52.x = Column[0].D; config.loadPosition52.y = Row[0].D; config.loadPosition52.angle = Angle[0].D; break; case 5: config.loadPosition61.x = Column[1].D; config.loadPosition61.y = Row[1].D; config.loadPosition61.angle = Angle[1].D; config.loadPosition62.x = Column[0].D; config.loadPosition62.y = Row[0].D; config.loadPosition62.angle = Angle[0].D; break; case 6: config.loadPosition71.x = Column[1].D; config.loadPosition71.y = Row[1].D; config.loadPosition71.angle = Angle[1].D; config.loadPosition72.x = Column[0].D; config.loadPosition72.y = Row[0].D; config.loadPosition72.angle = Angle[0].D; break; case 7: config.loadPosition81.x = Column[1].D; config.loadPosition81.y = Row[1].D; config.loadPosition81.angle = Angle[1].D; config.loadPosition82.x = Column[0].D; config.loadPosition82.y = Row[0].D; config.loadPosition82.angle = Angle[0].D; break; case 8: config.loadPosition91.x = Column[1].D; config.loadPosition91.y = Row[1].D; config.loadPosition91.angle = Angle[1].D; config.loadPosition92.x = Column[0].D; config.loadPosition92.y = Row[0].D; config.loadPosition92.angle = Angle[0].D; break; case 9: config.loadPosition101.x = Column[1].D; config.loadPosition101.y = Row[1].D; config.loadPosition101.angle = Angle[1].D; config.loadPosition102.x = Column[0].D; config.loadPosition102.y = Row[0].D; config.loadPosition102.angle = Angle[0].D; break; default: break; } } } }