using LB_SmartVisionCommon;
|
using LB_VisionControls;
|
using LB_VisionProcesses.Cameras;
|
using System;
|
using System.Collections.Concurrent;
|
using System.Collections.Generic;
|
using System.ComponentModel;
|
using System.Data;
|
using System.Diagnostics;
|
using System.Drawing;
|
using System.Linq;
|
using System.Text;
|
using System.Text.RegularExpressions;
|
using System.Threading.Tasks;
|
using System.Windows;
|
using System.Windows.Forms;
|
using System.Windows.Media.Media3D;
|
using static ZXing.QrCode.Internal.Mode;
|
|
namespace LB_SmartVision.Forms.Pages.MotionControlPage
|
{
|
public partial class MotionControlFormRead : Form
|
{
|
// 原始字典:Key是读取PLC地址,Value是的Key是写入PLC地址以及对应的值Float值
|
private Dictionary<string, Dictionary<string, float>> _plcDataDict;
|
|
// 用于绑定到DataGridView的可编辑列表
|
private BindingList<PlcDataItem> _plcDataList;
|
|
// DataGridView绑定的数据源
|
private BindingSource _bindingSource;
|
|
|
UserPictureBox onlinePictureBox { get; set; }
|
string communicatorsName { get; set; }
|
public MotionControlFormRead()
|
{
|
InitializeComponent();
|
}
|
string cameraSN = string.Empty;
|
|
public MotionControlFormRead(List<string> strCameraSN)
|
{
|
InitializeComponent();
|
|
if (strCameraSN == null || strCameraSN.Count == 0)
|
{
|
return;
|
}
|
|
//this.camera = camera;
|
//this.Text = camera.SN;
|
this.cmbSN.Items.Clear();
|
foreach (string strSN in strCameraSN)
|
{
|
this.cmbSN.Items.Add(strSN);
|
}
|
//cameraSN = camera.SN;
|
onlinePictureBox = new UserPictureBox(uiGroupBoxImage);
|
this.uiGroupBoxImage.Controls.Clear();
|
this.uiGroupBoxImage.Controls.Add(onlinePictureBox);
|
onlinePictureBox.Dock = DockStyle.Fill;
|
dataGridView1.Columns["SN"].HeaderText = "序列号";
|
dataGridView1.Columns["SN"].ReadOnly = true;
|
dataGridView1.Columns["ReadAddress"].HeaderText = "读取PLC地址";
|
//dataGridView1.Columns["ReadAddress"].ReadOnly = true;
|
dataGridView1.Columns["WriteAddress"].HeaderText = "写入PLC地址";
|
//dataGridView1.Columns["WriteAddress"].ReadOnly = true;
|
dataGridView1.Columns["Value"].HeaderText = "数值";
|
dataGridView1.Columns["Description"].HeaderText = "描述";
|
dataGridView1.Columns["Value"].DefaultCellStyle.Format = "F2"; // 保留两位小数
|
|
|
}
|
Dictionary<string, RecordMotionControlData> concurrentDictionary = new Dictionary<string, RecordMotionControlData>();
|
private void CameraForm_FormClosing(object sender, FormClosingEventArgs e)
|
{
|
if (GlobalVar.dicCameras[this.cmbSN.Text] == null)
|
{
|
return;
|
}
|
|
GlobalVar.dicCameras[this.cmbSN.Text].StopGrabbing();
|
|
GlobalVar.dicCameras[this.cmbSN.Text].StartGrabbing();
|
if (GlobalVar.dicMotionControlData.Keys.Contains(GlobalVar.strProductName))
|
{
|
concurrentDictionary = GlobalVar.dicMotionControlData[GlobalVar.strProductName];
|
double xAxisDetectLocationValue, xAxisOriginalLocationValue, yAxisDetectLocationValue, yAxisOriginalLocationValue, zAxisDetectLocationValue, zAxisOriginalLocationValue, wAxisDetectLocationValue, wAxisOriginalLocationValue, pulseMotionSpeedValue, angularVelocityValue;
|
//xAxisDetectLocationValue = double.Parse(this.textBoxXDetectLocation.Text);
|
//xAxisOriginalLocationValue = double.Parse(this.textBoxXOriginalLocation.Text);
|
//yAxisDetectLocationValue = double.Parse(this.textBoxYDetectLocation.Text);
|
//yAxisOriginalLocationValue = double.Parse(this.textBoxYOriginalLocation.Text);
|
//zAxisDetectLocationValue = double.Parse(this.textBoxZDetectLocation.Text);
|
//zAxisOriginalLocationValue = double.Parse(this.textBoxZOriginalLocation.Text);
|
//wAxisDetectLocationValue = double.Parse(this.textBoxWDetectLocation.Text);
|
//wAxisOriginalLocationValue = double.Parse(this.textBoxWOriginalLocation.Text);
|
//pulseMotionSpeedValue = double.Parse(this.textBoxPointSpeed.Text);
|
//angularVelocityValue = double.Parse(this.textBoxPointSpeed.Text);
|
if (concurrentDictionary.Keys.Contains(cameraSN))
|
{
|
//RecordMotionControlData recordMotionControlData = new RecordMotionControlData
|
//{
|
// ProductName = GlobalVar.strProductName,
|
// CommunicatorsName = communicatorsName,
|
// CameraSN = cameraSN,
|
// //XAxisAddress = this.textBoxXVarAddress.Text,
|
// //XAxisDetectLocationValue = xAxisDetectLocationValue,
|
// //XAxisOriginalLocationValue = xAxisOriginalLocationValue,
|
// //YAxisAddress = this.textBoxYVarAddress.Text,
|
// //YAxisDetectLocationValue = yAxisDetectLocationValue,
|
// //YAxisOriginalLocationValue = yAxisOriginalLocationValue,
|
// //ZAxisAddress = this.textBoxZVarAddress.Text,
|
// //ZAxisDetectLocationValue = zAxisDetectLocationValue,
|
// //ZAxisOriginalLocationValue = zAxisOriginalLocationValue,
|
// //WAxisAddress = this.textBoxWVarAddress.Text,
|
// //WAxisDetectLocationValue = wAxisDetectLocationValue,
|
// //WAxisOriginalLocationValue = wAxisOriginalLocationValue,
|
// //PulseMotionSpeedAddress = this.textBoxPulseMotionSpeedAddress.Text,
|
// //PulseMotionSpeedValue = pulseMotionSpeedValue,
|
// //AngularVelocityAddress = this.textBoxAngularVelocityAddress.Text,
|
// //AngularVelocityValue = angularVelocityValue
|
//};
|
//concurrentDictionary.TryAdd(cameraSN, recordMotionControlData);
|
}
|
else
|
{
|
//RecordMotionControlData recordMotionControlData = new RecordMotionControlData
|
//{
|
// ProductName = GlobalVar.strProductName,
|
// CommunicatorsName = communicatorsName,
|
// CameraSN = cameraSN,
|
// //XAxisAddress = this.textBoxXVarAddress.Text,
|
// //XAxisDetectLocationValue = xAxisDetectLocationValue,
|
// //XAxisOriginalLocationValue = xAxisOriginalLocationValue,
|
// //YAxisAddress = this.textBoxYVarAddress.Text,
|
// //YAxisDetectLocationValue = yAxisDetectLocationValue,
|
// //YAxisOriginalLocationValue = yAxisOriginalLocationValue,
|
// //ZAxisAddress = this.textBoxZVarAddress.Text,
|
// //ZAxisDetectLocationValue = zAxisDetectLocationValue,
|
// //ZAxisOriginalLocationValue = zAxisOriginalLocationValue,
|
// //WAxisAddress = this.textBoxWVarAddress.Text,
|
// //WAxisDetectLocationValue = wAxisDetectLocationValue,
|
// //WAxisOriginalLocationValue = wAxisOriginalLocationValue,
|
// //PulseMotionSpeedAddress = this.textBoxPulseMotionSpeedAddress.Text,
|
// //PulseMotionSpeedValue = pulseMotionSpeedValue,
|
// //AngularVelocityAddress = this.textBoxAngularVelocityAddress.Text,
|
// //AngularVelocityValue = angularVelocityValue
|
//};
|
//concurrentDictionary.TryAdd(cameraSN, recordMotionControlData);
|
}
|
}
|
else
|
{
|
double xAxisDetectLocationValue, xAxisOriginalLocationValue, yAxisDetectLocationValue, yAxisOriginalLocationValue, zAxisDetectLocationValue, zAxisOriginalLocationValue, wAxisDetectLocationValue, wAxisOriginalLocationValue, pulseMotionSpeedValue, angularVelocityValue;
|
//xAxisDetectLocationValue = double.Parse(this.textBoxXDetectLocation.Text);
|
//xAxisOriginalLocationValue = double.Parse(this.textBoxXOriginalLocation.Text);
|
//yAxisDetectLocationValue = double.Parse(this.textBoxYDetectLocation.Text);
|
//yAxisOriginalLocationValue = double.Parse(this.textBoxYOriginalLocation.Text);
|
//zAxisDetectLocationValue = double.Parse(this.textBoxZDetectLocation.Text);
|
//zAxisOriginalLocationValue = double.Parse(this.textBoxZOriginalLocation.Text);
|
//wAxisDetectLocationValue = double.Parse(this.textBoxWDetectLocation.Text);
|
//wAxisOriginalLocationValue = double.Parse(this.textBoxWOriginalLocation.Text);
|
//pulseMotionSpeedValue = double.Parse(this.textBoxPointSpeed.Text);
|
//angularVelocityValue = double.Parse(this.textBoxPointSpeed.Text);
|
if (concurrentDictionary.Keys.Contains(cameraSN))
|
{
|
//RecordMotionControlData recordMotionControlData = new RecordMotionControlData
|
//{
|
// ProductName = GlobalVar.strProductName,
|
// CommunicatorsName = communicatorsName,
|
// CameraSN = cameraSN,
|
// //XAxisAddress = this.textBoxXVarAddress.Text,
|
// //XAxisDetectLocationValue = xAxisDetectLocationValue,
|
// //XAxisOriginalLocationValue = xAxisOriginalLocationValue,
|
// //YAxisAddress = this.textBoxYVarAddress.Text,
|
// //YAxisDetectLocationValue = yAxisDetectLocationValue,
|
// //YAxisOriginalLocationValue = yAxisOriginalLocationValue,
|
// //ZAxisAddress = this.textBoxZVarAddress.Text,
|
// //ZAxisDetectLocationValue = zAxisDetectLocationValue,
|
// //ZAxisOriginalLocationValue = zAxisOriginalLocationValue,
|
// //WAxisAddress = this.textBoxWVarAddress.Text,
|
// //WAxisDetectLocationValue = wAxisDetectLocationValue,
|
// //WAxisOriginalLocationValue = wAxisOriginalLocationValue,
|
// //PulseMotionSpeedAddress = this.textBoxPulseMotionSpeedAddress.Text,
|
// //PulseMotionSpeedValue = pulseMotionSpeedValue,
|
// //AngularVelocityAddress = this.textBoxAngularVelocityAddress.Text,
|
// //AngularVelocityValue = angularVelocityValue
|
//};
|
//concurrentDictionary.TryAdd(cameraSN, recordMotionControlData);
|
}
|
else
|
{
|
//RecordMotionControlData recordMotionControlData = new RecordMotionControlData
|
//{
|
// ProductName = GlobalVar.strProductName,
|
// CommunicatorsName = communicatorsName,
|
// CameraSN = cameraSN,
|
// //XAxisAddress = this.textBoxXVarAddress.Text,
|
// //XAxisDetectLocationValue = xAxisDetectLocationValue,
|
// //XAxisOriginalLocationValue = xAxisOriginalLocationValue,
|
// //YAxisAddress = this.textBoxYVarAddress.Text,
|
// //YAxisDetectLocationValue = yAxisDetectLocationValue,
|
// //YAxisOriginalLocationValue = yAxisOriginalLocationValue,
|
// //ZAxisAddress = this.textBoxZVarAddress.Text,
|
// //ZAxisDetectLocationValue = zAxisDetectLocationValue,
|
// //ZAxisOriginalLocationValue = zAxisOriginalLocationValue,
|
// //WAxisAddress = this.textBoxWVarAddress.Text,
|
// //WAxisDetectLocationValue = wAxisDetectLocationValue,
|
// //WAxisOriginalLocationValue = wAxisOriginalLocationValue,
|
// //PulseMotionSpeedAddress = this.textBoxPulseMotionSpeedAddress.Text,
|
// //PulseMotionSpeedValue = pulseMotionSpeedValue,
|
// //AngularVelocityAddress = this.textBoxAngularVelocityAddress.Text,
|
// //AngularVelocityValue = angularVelocityValue
|
//};
|
//concurrentDictionary.TryAdd(cameraSN, recordMotionControlData);
|
}
|
}
|
GlobalVar.dicMotionControlData.TryAdd(GlobalVar.strProductName, concurrentDictionary);
|
ConfigManager<Dictionary<string, Dictionary<string, RecordMotionControlData>>>.SaveConfig<Dictionary<string, Dictionary<string, RecordMotionControlData>>>(GlobalVar.dicMotionControlData, GlobalVar.allMotionControlDataPath);
|
Unsubscribe();
|
}
|
|
public void Unsubscribe()
|
{
|
try
|
{
|
if (GlobalVar.dicCameras[this.cmbSN.Text] == null)
|
{
|
return;
|
|
}//取消回调函数
|
GlobalVar.dicCameras[this.cmbSN.Text].ImageGrabbed -= GetImageBllComplete;
|
}
|
catch (Exception ex)
|
{
|
// 记录错误信息
|
Debug.WriteLine($"错误: {ex.Message}");
|
}
|
|
}
|
|
public void Subscribe()
|
{
|
try
|
{
|
if (GlobalVar.dicCameras[this.cmbSN.Text] == null)
|
{
|
return;
|
}
|
|
//取消回调函数
|
GlobalVar.dicCameras[this.cmbSN.Text].ImageGrabbed -= GetImageBllComplete;
|
//加载回调函数
|
GlobalVar.dicCameras[this.cmbSN.Text].ImageGrabbed += GetImageBllComplete;
|
}
|
catch (Exception ex)
|
{
|
// 记录错误信息
|
Debug.WriteLine($"错误: {ex.Message}");
|
}
|
}
|
|
/// <summary>
|
/// 相机回调运行
|
/// </summary>
|
/// <param name="CCDName"></param>
|
/// <param name="image"></param>
|
private void GetImageBllComplete(object sender, CameraEventArgs e)
|
{
|
if (e.Bitmap == null)
|
{
|
return;
|
}
|
|
lock (e.Bitmap)
|
{
|
if (this.InvokeRequired) // 检查是否需要在UI线程上调用
|
{
|
this.Invoke(new Action(() =>
|
{
|
onlinePictureBox.Image = e.Bitmap;
|
})); // 递归调用自身,但这次在UI线程上
|
}
|
else
|
{
|
onlinePictureBox.Image = e.Bitmap;
|
}
|
}
|
}
|
|
private void uiButtonGrabOnce_Click(object sender, EventArgs e)
|
{
|
if (GlobalVar.dicCameras[this.cmbSN.Text] == null)
|
{
|
return;
|
}
|
|
Task.Factory.StartNew(() =>
|
{
|
GlobalVar.dicCameras[this.cmbSN.Text].SetTriggerMode(TriggerMode.On, TriggerSource.Software);
|
DateTime startTime = DateTime.Now; // 当前时间
|
GlobalVar.dicCameras[this.cmbSN.Text].GetImageWithSoftTrigger(out Bitmap bitmap);
|
});
|
}
|
|
private void uiButtonCloseSoftGrab_Click(object sender, EventArgs e)
|
{
|
if (GlobalVar.dicCameras[this.cmbSN.Text] == null)
|
{
|
return;
|
}
|
|
Task.Factory.StartNew(() =>
|
{
|
GlobalVar.dicCameras[this.cmbSN.Text].StopGrabbing();
|
GlobalVar.dicCameras[this.cmbSN.Text].SetTriggerMode(TriggerMode.On, TriggerSource.Software);
|
GlobalVar.dicCameras[this.cmbSN.Text].StartGrabbing();
|
});
|
}
|
|
private void uiButtonHardGrabWithPLC_Click(object sender, EventArgs e)
|
{
|
if (GlobalVar.dicCameras[this.cmbSN.Text] == null)
|
{
|
return;
|
}
|
Task.Factory.StartNew(() =>
|
{
|
GlobalVar.dicCameras[this.cmbSN.Text].SetTriggerMode(TriggerMode.On, TriggerSource.Line0);
|
GlobalVar.dicCameras[this.cmbSN.Text].StopGrabbing();
|
GlobalVar.dicCameras[this.cmbSN.Text].StartWith_HardTriggerModel();
|
});
|
}
|
|
|
private void cmbSN_SelectedIndexChanged(object sender, EventArgs e)
|
{
|
this.cameraSN = this.cmbSN.Text;
|
this.textBoxName.Text = "Camera" + GlobalVar.dicCameras[this.cmbSN.Text].SN;
|
//加载回调函数
|
Subscribe();
|
}
|
|
private void btnAdd_Click(object sender, EventArgs e)
|
{
|
// 创建新增数据的对话框(这里简化为直接创建默认数据)
|
PlcDataItem newData = new PlcDataItem
|
{
|
SN = (GlobalVar.dicMPlcData.Count()).ToString(),
|
ReadAddress = "DB1003.DBD1",
|
WriteAddress = "DB1003.DBD51",
|
Value = 0.0F,
|
Description = "请修改对应描述"
|
};
|
|
// 添加到嵌套字典
|
if (!GlobalVar.dicMPlcData.ContainsKey(newData.ReadAddress))
|
{
|
GlobalVar.dicMPlcData.TryAdd(newData.ReadAddress, new Dictionary<string, PlcDataItem> { [newData.ReadAddress] = newData });
|
}
|
else
|
{
|
newData.ReadAddress = newData.ReadAddress + GlobalVar.dicMPlcData.Count;
|
GlobalVar.dicMPlcData.TryAdd(newData.ReadAddress, new Dictionary<string, PlcDataItem> { [newData.ReadAddress] = newData });
|
}
|
|
// 更新DataGridView数据源
|
UpdateDataSource();
|
|
// 选中新增的行
|
dataGridView1.ClearSelection();
|
var newRow = dataGridView1.Rows[dataGridView1.Rows.Count - 1];
|
newRow.Selected = true;
|
dataGridView1.FirstDisplayedScrollingRowIndex = newRow.Index;
|
}
|
|
/// <summary>
|
/// 将嵌套字典转换为视图模型并更新数据源
|
/// </summary>
|
private void UpdateDataSource()
|
{
|
// 转换嵌套字典为扁平的视图模型列表
|
List<PlcDataItem> viewModelList = new List<PlcDataItem>();
|
foreach (var group in GlobalVar.dicMPlcData)
|
{
|
foreach (var device in group.Value)
|
{
|
var data = device.Value;
|
viewModelList.Add(new PlcDataItem
|
{
|
SN = (GlobalVar.dicMPlcData.Count()).ToString(),
|
ReadAddress = data.ReadAddress,
|
WriteAddress = data.WriteAddress,
|
Value = data.Value,
|
Description = data.Description
|
});
|
}
|
}
|
_bindingSource.DataSource = viewModelList;
|
}
|
|
|
private void dataGridView1_CellContentClick(object sender, DataGridViewCellEventArgs e)
|
{
|
if (e.RowIndex < 0 || e.ColumnIndex < 0)
|
{
|
return;
|
}
|
|
// 获取修改后的视图模型
|
var modifiedModel = (PlcDataItem)_bindingSource.List[e.RowIndex];
|
|
// 更新原始字典数据
|
if (GlobalVar.dicMPlcData.ContainsKey(modifiedModel.SN))
|
{
|
var originalData = GlobalVar.dicMPlcData[modifiedModel.SN][GlobalVar.dicMPlcData[modifiedModel.SN].Keys.ToList()[0]];
|
|
// 同步修改后的值
|
originalData.SN = modifiedModel.SN;
|
originalData.ReadAddress = modifiedModel.ReadAddress;
|
originalData.WriteAddress = modifiedModel.WriteAddress;
|
originalData.Value = modifiedModel.Value;
|
originalData.Description = modifiedModel.Description;
|
GlobalVar.dicMPlcData[modifiedModel.SN] = new Dictionary<string, PlcDataItem> { [originalData.SN] = originalData };
|
}
|
|
}
|
|
private void btnRemove_Click(object sender, EventArgs e)
|
{
|
if (dataGridView1.SelectedRows.Count == 0)
|
{
|
System.Windows.Forms.MessageBox.Show("请先选中要删除的行!");
|
return;
|
}
|
|
// 获取选中行的视图模型
|
var selectedModel = (PlcDataItem)dataGridView1.SelectedRows[0].DataBoundItem;
|
|
// 从嵌套字典中删除对应数据
|
if (GlobalVar.dicMPlcData.ContainsKey(selectedModel.SN))
|
{
|
GlobalVar.dicMPlcData.Remove(selectedModel.SN);
|
|
// 更新DataGridView数据源
|
UpdateDataSource();
|
System.Windows.Forms.MessageBox.Show("删除成功!");
|
}
|
else
|
{
|
System.Windows.MessageBox.Show("未找到对应数据,删除失败!");
|
}
|
}
|
|
private void btnOneClickRead_Click(object sender, EventArgs e)
|
{
|
|
}
|
|
private void btnOneClickSetting_Click(object sender, EventArgs e)
|
{
|
|
}
|
}
|
}
|