1436 lines
52 KiB
C#
1436 lines
52 KiB
C#
using ControlBeanExDll;
|
||
using MvCamCtrl.NET;
|
||
using MvCameraControl;
|
||
using OfficeOpenXml;
|
||
using System;
|
||
using System.Collections.Generic;
|
||
using System.Data;
|
||
using System.Drawing;
|
||
using System.IO;
|
||
using System.Linq;
|
||
using System.Net;
|
||
using System.Net.Sockets;
|
||
using System.Threading;
|
||
using System.Windows.Forms;
|
||
using TcpserverExDll;
|
||
|
||
namespace HitBotCSharpDemo
|
||
{
|
||
public partial class ShowForm : Form
|
||
{
|
||
Thread thread_Jog_Move;//创建按钮长按,连续移动模式的线程。 与点击事件冲突处理
|
||
bool moveFlag;//开始结束寸动标志
|
||
bool isInit = false;
|
||
Button btn;//声明按钮对象。
|
||
Label lbl;
|
||
int offset = 2;//寸动距离
|
||
int offset_jog = 2;//连续移动单次距离
|
||
static int io_Count = 6;//IO数量
|
||
int[] io_In = new int[io_Count];
|
||
int[] io_Out = new int[io_Count];
|
||
Label[] lbl_Current_Input;//IO显示控件数组
|
||
Label[] lbl_Current_Output;
|
||
bool output_State_Flag0 = true;
|
||
bool output_State_Flag1 = true;
|
||
bool output_State_Flag2 = true;
|
||
bool output_State_Flag3 = true;
|
||
bool output_State_Flag4 = true;
|
||
bool output_State_Flag5 = true;
|
||
float[] pos0;//点位1
|
||
int posHand0;
|
||
float[] pos1;//点位2
|
||
int posHand1;
|
||
float[] pos2;//点位3
|
||
int posHand2;
|
||
Thread thread_PosMove;
|
||
private float[][] cameraPositions;
|
||
private string filePath = "Cam_pos_path.txt";
|
||
|
||
private TcpClient tcpClient;
|
||
private NetworkStream networkStream;
|
||
private Thread detectionThread;
|
||
private bool isDetectionRunning = false;
|
||
private const int SERVER_PORT = 8888; // Python服务器端口
|
||
private const string SERVER_IP = "127.0.0.1"; // 本机IP
|
||
private float receivedWidth = 0;
|
||
private float receivedHeight = 0;
|
||
|
||
private bool isCycleRunning = false;
|
||
private Thread cycleThread;
|
||
|
||
private List<float[]> detectionData = new List<float[]>(); // 存储每轮检测数据
|
||
private int currentCycle = 0;
|
||
|
||
private List<int> selectedPositions = new List<int>(); // 存储选中的点位
|
||
private int dwellTimeMinutes = 1; // 停留时间(分钟)
|
||
private string cycleStartTime = ""; // 循环开始时间
|
||
|
||
private CameraManager cameraManager;
|
||
private tempControl tempControl;
|
||
private ControlBeanEx robot;
|
||
public ShowForm()
|
||
{
|
||
InitializeComponent();
|
||
TcpserverEx.net_port_initial();
|
||
robot = TcpserverEx.get_robot(74);//替换为自己的机器的id号
|
||
SDKSystem.Initialize(); // 初始化SDK
|
||
//InitializeCamera(); // 初始化相机
|
||
Control.CheckForIllegalCrossThreadCalls = false;
|
||
}
|
||
protected override void OnFormClosing(FormClosingEventArgs e)
|
||
{
|
||
// 停止循环检测
|
||
if (isCycleRunning)
|
||
{
|
||
StopCycle();
|
||
// 恢复控件状态
|
||
SetControlsEnabled(true);
|
||
}
|
||
// 停止相机
|
||
cameraManager?.StopCamera();
|
||
|
||
StopDetection();
|
||
// 终结SDK
|
||
SDKSystem.Finalize();
|
||
base.OnFormClosing(e);
|
||
}
|
||
|
||
private void LoadCameraPositions()
|
||
{
|
||
try
|
||
{
|
||
if (File.Exists(filePath))
|
||
{
|
||
string[] lines = File.ReadAllLines(filePath);
|
||
cameraPositions = new float[5][]; // 存储5个点位
|
||
|
||
int positionIndex = 0;
|
||
foreach (string line in lines)
|
||
{
|
||
// 跳过注释行(以#开头)和空行
|
||
if (string.IsNullOrWhiteSpace(line) || line.StartsWith("#"))
|
||
continue;
|
||
|
||
if (positionIndex < 5)
|
||
{
|
||
string[] coords = line.Split(',');
|
||
if (coords.Length == 4)
|
||
{
|
||
cameraPositions[positionIndex] = new float[4];
|
||
for (int i = 0; i < 4; i++)
|
||
{
|
||
if (float.TryParse(coords[i].Trim(), out float value))
|
||
{
|
||
cameraPositions[positionIndex][i] = value;
|
||
}
|
||
else
|
||
{
|
||
MessageBox.Show($"解析第{positionIndex + 1}行第{i + 1}个坐标时出错:{coords[i]}");
|
||
return;
|
||
}
|
||
}
|
||
positionIndex++;
|
||
}
|
||
else
|
||
{
|
||
MessageBox.Show($"第{positionIndex + 1}行坐标格式错误,应该包含4个值(X,Y,Z,R)");
|
||
return;
|
||
}
|
||
}
|
||
}
|
||
//if (positionIndex == 5)
|
||
//{
|
||
// MessageBox.Show("成功加载5个相机位置点位");
|
||
//}
|
||
//else
|
||
//{
|
||
// MessageBox.Show($"只加载了{positionIndex}个点位,需要5个点位");
|
||
//}
|
||
}
|
||
else
|
||
{
|
||
MessageBox.Show($"未找到文件:{filePath}");
|
||
}
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
MessageBox.Show($"加载点位文件时出错:{ex.Message}");
|
||
}
|
||
}
|
||
private void MoveToPosition(int positionIndex)
|
||
{
|
||
if (!isInit)
|
||
{
|
||
MessageBox.Show("机械臂未初始化");
|
||
return;
|
||
}
|
||
if (cameraPositions == null || positionIndex >= cameraPositions.Length || cameraPositions[positionIndex] == null)
|
||
{
|
||
MessageBox.Show($"点位{positionIndex + 1}数据未加载或无效");
|
||
return;
|
||
}
|
||
try
|
||
{
|
||
// 获取当前位置参数
|
||
robot.get_scara_param();
|
||
int currentHand = robot.get_lr(); // 使用当前手系
|
||
|
||
float x = cameraPositions[positionIndex][0];
|
||
float y = cameraPositions[positionIndex][1];
|
||
float z = cameraPositions[positionIndex][2];
|
||
float r = cameraPositions[positionIndex][3];
|
||
|
||
// 设置运动参数
|
||
robot.new_set_acc(30, 30, 30, 30);
|
||
|
||
// 移动到指定位置
|
||
int result = robot.new_movej_xyz_lr(x, y, z, r, 100, 0, currentHand);
|
||
|
||
if (result != 1)
|
||
{
|
||
MessageBox.Show($"移动到点位{positionIndex + 1}失败,返回值:{result}");
|
||
}
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
MessageBox.Show($"移动到点位{positionIndex + 1}时出错:{ex.Message}");
|
||
}
|
||
}
|
||
|
||
private void ShowForm_Load(object sender, EventArgs e)
|
||
{
|
||
lbl_Current_Input = new Label[] { lbl_InputState_0, lbl_InputState_1, lbl_InputState_2, lbl_InputState_3, lbl_InputState_4, lbl_InputState_5 };//输入信号数组
|
||
lbl_Current_Output = new Label[] { lbl_OutputState_0, lbl_OutputState_1, lbl_OutputState_2, lbl_OutputState_3, lbl_OutputState_4, lbl_OutputState_5 };//输出信号数组
|
||
|
||
LoadCameraPositions();
|
||
|
||
cameraManager = new CameraManager(cam_feed);
|
||
cameraManager.LoadConfiguration();
|
||
cameraManager.Initialize();
|
||
|
||
Label[] temperatureLabels = new Label[] { label4, label11, label16, label21 };
|
||
Label[] setting_temperatureLabels = new Label[] { label7, label8, label13, label18 };
|
||
|
||
tempControl = new tempControl(temperatureLabels, setting_temperatureLabels);
|
||
tempControl.LoadAvailablePorts(comboBox1);
|
||
|
||
textBox6.Click += TextBox_Click;
|
||
textBox7.Click += TextBox_Click;
|
||
textBox8.Click += TextBox_Click;
|
||
textBox9.Click += TextBox_Click;
|
||
|
||
}
|
||
|
||
private void TextBox_Click(object sender, EventArgs e)
|
||
{
|
||
TextBox textBox = sender as TextBox;
|
||
if (textBox == null) return;
|
||
// 检查串口是否打开
|
||
if (tempControl == null || !tempControl.IsSerialPortOpen())
|
||
{
|
||
MessageBox.Show("串口未打开,无法设置参数");
|
||
return;
|
||
}
|
||
// 根据控件名称确定下位机编号和显示名称
|
||
int deviceNumber = -1;
|
||
string parameterName = "";
|
||
switch (textBox.Name)
|
||
{
|
||
case "textBox6":
|
||
deviceNumber = 0;
|
||
parameterName = "下位机1 RAMPSPEED";
|
||
break;
|
||
case "textBox7":
|
||
deviceNumber = 1;
|
||
parameterName = "下位机2 RAMPSPEED";
|
||
break;
|
||
case "textBox8":
|
||
deviceNumber = 2;
|
||
parameterName = "下位机3 RAMPSPEED";
|
||
break;
|
||
case "textBox9":
|
||
deviceNumber = 3;
|
||
parameterName = "下位机4 RAMPSPEED";
|
||
break;
|
||
}
|
||
if (deviceNumber >= 0)
|
||
{
|
||
// 创建并显示输入窗口
|
||
ParameterInputForm inputForm = new ParameterInputForm(parameterName, textBox.Text);
|
||
if (inputForm.ShowDialog(this) == DialogResult.OK)
|
||
{
|
||
// 用户点击了保存按钮
|
||
string newValue = inputForm.InputValue;
|
||
|
||
// 检查输入是否为有效数字
|
||
if (double.TryParse(newValue, out double inputValue))
|
||
{
|
||
// 更新textbox显示
|
||
textBox.Text = newValue;
|
||
|
||
// 构建并发送命令
|
||
string command = $"TC1:TCRAMPSPEED={inputValue}@{deviceNumber}\r";
|
||
tempControl.SendCommand(command);
|
||
}
|
||
else
|
||
{
|
||
MessageBox.Show("请输入有效的数字", "输入错误",
|
||
MessageBoxButtons.OK, MessageBoxIcon.Warning);
|
||
}
|
||
}
|
||
inputForm.Dispose();
|
||
}
|
||
}
|
||
|
||
private void cob_Robot_ID_Click(object sender, EventArgs e)
|
||
{
|
||
cob_Robot_ID.Items.Clear();
|
||
for (int i = 0; i < 255; i++)
|
||
{
|
||
robot = TcpserverEx.get_robot(i);//替换为自己的机器的id号
|
||
if (robot.is_connected())
|
||
{
|
||
cob_Robot_ID.Items.Add(i.ToString());
|
||
}
|
||
}
|
||
}
|
||
|
||
private void btn_Init_Click(object sender, EventArgs e)
|
||
{
|
||
rit_Coord.Clear();
|
||
if (robot == null) return;
|
||
robot = TcpserverEx.get_robot(int.Parse(cob_Robot_ID.Text));
|
||
robot.check_joint(4, false);
|
||
if (robot.is_connected())
|
||
{
|
||
int ret = robot.initial(1, 240); //修改自己机器的型号,参数具体意义参考sdk说明文档
|
||
if (ret == 1)
|
||
{
|
||
robot.unlock_position();
|
||
isInit = true;
|
||
MessageBox.Show("robot" + "初始化完成");
|
||
}
|
||
else
|
||
{
|
||
MessageBox.Show("robot" + "初始化失败,返回值 = " + ret.ToString());
|
||
}
|
||
}
|
||
else
|
||
{
|
||
MessageBox.Show("robot" + "未连接");
|
||
}
|
||
}
|
||
|
||
private void btn_Move_Click(object sender, EventArgs e) //点击按钮,寸动事件。
|
||
{
|
||
if (!isInit)
|
||
{
|
||
MessageBox.Show("机械臂未初始化");
|
||
return;
|
||
}
|
||
#region 按钮移动事件
|
||
if (chb_Inching.Checked == true)//寸动
|
||
{
|
||
|
||
robot.get_scara_param();
|
||
int hand = robot.get_lr();
|
||
float speed = 2;
|
||
robot.new_set_acc(30, 30, 30, 30);
|
||
#region 轴动
|
||
if (btn == btn_XP)//X正向移动
|
||
{
|
||
robot.new_movej_xyz_lr(robot.x + offset, robot.y, robot.z, robot.rotation, speed, 0, hand);//以 movej(直线模式) 的运动方式,并以指定手系达目标点
|
||
}
|
||
else if (btn == btn_XN)//X负向移动
|
||
{
|
||
robot.new_movej_xyz_lr(robot.x - offset, robot.y, robot.z, robot.rotation, speed, 0, hand);
|
||
}
|
||
if (btn == btn_YP)//Y正向移动
|
||
{
|
||
robot.new_movej_xyz_lr(robot.x, robot.y + offset, robot.z, robot.rotation, speed, 0, hand);//以 movej(直线模式) 的运动方式,并以指定手系达目标点
|
||
}
|
||
else if (btn == btn_YN)//Y负向移动
|
||
{
|
||
robot.new_movej_xyz_lr(robot.x, robot.y - offset, robot.z, robot.rotation, speed, 0, hand);
|
||
}
|
||
if (btn == btn_ZP)//Z正向移动
|
||
{
|
||
robot.new_movej_xyz_lr(robot.x, robot.y, robot.z + offset, robot.rotation, speed, 0, hand);//以 movej(直线模式) 的运动方式,并以指定手系达目标点
|
||
}
|
||
else if (btn == btn_ZN)//Z负向移动
|
||
{
|
||
robot.new_movej_xyz_lr(robot.x, robot.y, robot.z - offset, robot.rotation, speed, 0, hand);
|
||
}
|
||
if (btn == btn_RP)//R正向旋转
|
||
{
|
||
robot.new_movej_xyz_lr(robot.x, robot.y, robot.z, robot.rotation + offset, speed, 0, hand);//以 movej(直线模式) 的运动方式,并以指定手系达目标点
|
||
}
|
||
else if (btn == btn_RN)//R负向旋转
|
||
{
|
||
robot.new_movej_xyz_lr(robot.x, robot.y, robot.z, robot.rotation - offset, speed, 0, hand);
|
||
}
|
||
#endregion
|
||
|
||
}
|
||
else
|
||
{
|
||
|
||
}
|
||
#endregion
|
||
}
|
||
|
||
public void jog_Move()//连续移动方法
|
||
{
|
||
moveFlag = true;
|
||
while (moveFlag && chb_Inching.Checked == false && btn != null)
|
||
{
|
||
|
||
//robot.new_set_acc(100, 100, 100, 100);
|
||
if (btn == btn_XP)//X正向移动
|
||
{
|
||
robot.jog_move2(offset_jog, 0, 0, 0, 1);
|
||
//robot.jog_move2(robot.x - 1, robot.y, robot.z, robot.rotation,1);
|
||
//type: 1:是以xyz坐标系为准移动固定距离。 2是以关节轴为基准移动固定距离
|
||
}
|
||
else if (btn == btn_XN)//X负向移动
|
||
{
|
||
robot.jog_move2(-offset_jog, 0, 0, 0, 1);
|
||
}
|
||
if (btn == btn_YP)//Y正向移动
|
||
{
|
||
robot.jog_move2(0, offset_jog, 0, 0, 1);
|
||
}
|
||
else if (btn == btn_YN)//Y负向移动
|
||
{
|
||
robot.jog_move2(0, -offset_jog, 0, 0, 1);
|
||
}
|
||
if (btn == btn_ZP)//Z正向移动
|
||
{
|
||
robot.jog_move2(0, 0, offset_jog, 0, 1);
|
||
}
|
||
else if (btn == btn_ZN)//Z负向移动
|
||
{
|
||
robot.jog_move2(0, 0, -offset_jog, 0, 1);
|
||
}
|
||
if (btn == btn_RP)//R正向旋转
|
||
{
|
||
robot.jog_move2(0, 0, 0, offset_jog, 1);
|
||
}
|
||
else if (btn == btn_RN)//R负向旋转
|
||
{
|
||
robot.jog_move2(0, 0, 0, offset_jog, 1);
|
||
}
|
||
Thread.Sleep(200);
|
||
}
|
||
robot.wait_stop();
|
||
}
|
||
|
||
|
||
private void btn_gainJointState_Click(object sender, EventArgs e)//获取关节状态
|
||
{
|
||
if (!isInit)
|
||
{
|
||
MessageBox.Show("机械臂未初始化");
|
||
return;
|
||
}
|
||
int jointNumber = int.Parse(cob_Joint_Number.SelectedItem.ToString());
|
||
int ret = robot.get_joint_state(jointNumber);
|
||
switch (ret)
|
||
{
|
||
case 1:
|
||
rit_showJointState.Clear();
|
||
rit_showJointState.SelectedText = "关节" + jointNumber + "正常";
|
||
break;
|
||
default:
|
||
rit_showJointState.Clear();
|
||
rit_showJointState.SelectedText = "关节" + jointNumber + "异常!异常代码:" + ret + ".(详情请查看API文档)"; //可具体
|
||
break;
|
||
}
|
||
}
|
||
|
||
private void btn_Jog_MouseDown(object sender, MouseEventArgs e)
|
||
{
|
||
btn = (Button)sender;
|
||
if (btn == null)
|
||
{
|
||
return;
|
||
}
|
||
thread_Jog_Move = new Thread(jog_Move);
|
||
thread_Jog_Move.IsBackground = true;
|
||
thread_Jog_Move.Start();
|
||
|
||
}
|
||
|
||
private void tim_IO_Refresh_Tick(object sender, EventArgs e)//刷新IO和坐标定时器
|
||
{
|
||
robot.get_scara_param();
|
||
if (isInit)
|
||
{
|
||
rit_Coord.Text = "Coord: X:" + robot.x + "mm " + "Y:" + robot.y + "mm " + "Z:" + robot.z + "mm " + "R:" + robot.rotation + "°" + "Hand:" + (robot.get_lr() == 1 ? "R" : "L") + " ";
|
||
}
|
||
for (int i = 0; i < io_Count; i++)
|
||
{
|
||
io_In[i] = robot.get_digital_in(i);
|
||
io_Out[i] = robot.get_digital_out(i);
|
||
}
|
||
for (int i = 0; i < io_Count; i++)//输入
|
||
{
|
||
int ret_Input = io_In[i];
|
||
Label lbl_Current_IO = lbl_Current_Input[i];
|
||
switch (ret_Input)//• -1:io_number 参数错误 • 0:io 输入点没有被触发 • 1:io 输入点被触发 • 3:未初始化
|
||
{
|
||
case -1:
|
||
if (lbl_Current_Input[i].BackColor != Color.Gray)
|
||
lbl_Current_Input[i].BackColor = Color.Gray;
|
||
break;
|
||
case 0:
|
||
if (lbl_Current_Input[i].BackColor != Color.Green)
|
||
lbl_Current_Input[i].BackColor = Color.Green;
|
||
break;
|
||
case 1:
|
||
if (lbl_Current_Input[i].BackColor != Color.Red)
|
||
lbl_Current_Input[i].BackColor = Color.Red;
|
||
break;
|
||
case 3:
|
||
if (lbl_Current_Input[i].BackColor != Color.Gray)
|
||
lbl_Current_Input[i].BackColor = Color.Gray;
|
||
break;
|
||
}
|
||
}
|
||
for (int i = 0; i < io_Count; i++)//输出
|
||
{
|
||
int ret_Output = io_Out[i];
|
||
Label lbl_Current_IO = lbl_Current_Output[i];
|
||
switch (ret_Output)//• -1:io_number 参数错误 • 0:io 输入点没有被触发 • 1:io 输入点被触发 • 3:未初始化
|
||
{
|
||
case -1:
|
||
if (lbl_Current_Output[i].BackColor != Color.Gray)
|
||
lbl_Current_Output[i].BackColor = Color.Gray;
|
||
break;
|
||
case 0:
|
||
if (lbl_Current_Output[i].BackColor != Color.Green)
|
||
lbl_Current_Output[i].BackColor = Color.Green;
|
||
break;
|
||
case 1:
|
||
if (lbl_Current_Output[i].BackColor != Color.Red)
|
||
lbl_Current_Output[i].BackColor = Color.Red;
|
||
break;
|
||
case 3:
|
||
if (lbl_Current_Output[i].BackColor != Color.Gray)
|
||
lbl_Current_Output[i].BackColor = Color.Gray;
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
private void lbl_Output_Click(object sender, EventArgs e)//设置输出事件
|
||
{
|
||
#region 判断输出编号
|
||
int output_Num = 0;
|
||
lbl = (Label)sender;
|
||
if (lbl == lbl_OutputState_0)
|
||
{
|
||
output_Num = 0;
|
||
robot.set_digital_out(output_Num, output_State_Flag0);
|
||
output_State_Flag0 = !output_State_Flag0;
|
||
}
|
||
else if (lbl == lbl_OutputState_1)
|
||
{
|
||
output_Num = 1;
|
||
robot.set_digital_out(output_Num, output_State_Flag1);
|
||
output_State_Flag1 = !output_State_Flag1;
|
||
}
|
||
else if (lbl == lbl_OutputState_2)
|
||
{
|
||
output_Num = 2;
|
||
robot.set_digital_out(output_Num, output_State_Flag2);
|
||
output_State_Flag2 = !output_State_Flag2;
|
||
}
|
||
else if (lbl == lbl_OutputState_3)
|
||
{
|
||
output_Num = 3;
|
||
robot.set_digital_out(output_Num, output_State_Flag3);
|
||
output_State_Flag3 = !output_State_Flag3;
|
||
}
|
||
else if (lbl == lbl_OutputState_4)
|
||
{
|
||
output_Num = 4;
|
||
robot.set_digital_out(output_Num, output_State_Flag4);
|
||
output_State_Flag4 = !output_State_Flag4;
|
||
}
|
||
else if (lbl == lbl_OutputState_5)
|
||
{
|
||
output_Num = 5;
|
||
robot.set_digital_out(output_Num, output_State_Flag5);
|
||
output_State_Flag5 = !output_State_Flag5;
|
||
}
|
||
#endregion
|
||
}
|
||
|
||
private void btn_MouseUp(object sender, MouseEventArgs e)//停止连续移动
|
||
{
|
||
if (robot != null&&!chb_Inching.Checked)
|
||
{
|
||
robot.new_stop_move();
|
||
}
|
||
btn = null;
|
||
moveFlag = false;
|
||
}
|
||
|
||
private void btn_Position0_Click(object sender, EventArgs e)
|
||
{
|
||
if (!isInit)
|
||
{
|
||
MessageBox.Show("机械臂未初始化");
|
||
return;
|
||
}
|
||
rit_Position0.Clear();
|
||
rit_Position0.Text = "Coord: X:" + robot.x + "mm " + "Y:" + robot.y + "mm " + "Z:" + robot.z + "mm " + "R:" + robot.rotation + "°" + "Hand:" + (robot.get_lr() == 1 ? "R" : "L") + " ";
|
||
pos0 = new float[] { robot.x, robot.y, robot.z, robot.rotation };
|
||
posHand0 = robot.get_lr()/* == 1 ? "R" : "L"*/;
|
||
}
|
||
|
||
private void btn_Position1_Click(object sender, EventArgs e)
|
||
{
|
||
if (!isInit)
|
||
{
|
||
MessageBox.Show("机械臂未初始化");
|
||
return;
|
||
}
|
||
rit_Position1.Clear();
|
||
rit_Position1.Text = "Coord: X:" + robot.x + "mm " + "Y:" + robot.y + "mm " + "Z:" + robot.z + "mm " + "R:" + robot.rotation + "°" + "Hand:" + (robot.get_lr() == 1 ? "R" : "L") + " ";
|
||
pos1 = new float[] { robot.x, robot.y, robot.z, robot.rotation };
|
||
posHand1 = robot.get_lr()/* == 1 ? "R" : "L"*/;
|
||
}
|
||
|
||
private void btn_Position2_Click(object sender, EventArgs e)
|
||
{
|
||
if (!isInit)
|
||
{
|
||
MessageBox.Show("机械臂未初始化");
|
||
return;
|
||
}
|
||
rit_Position2.Clear();
|
||
rit_Position2.Text = "Coord: X:" + robot.x + "mm " + "Y:" + robot.y + "mm " + "Z:" + robot.z + "mm " + "R:" + robot.rotation + "°" + "Hand:" + (robot.get_lr() == 1 ? "R" : "L") + " ";
|
||
pos2 = new float[] { robot.x, robot.y, robot.z, robot.rotation };
|
||
posHand2 = robot.get_lr() /*== 1 ? "R" : "L"*/;
|
||
}
|
||
|
||
private void btn_Start_Click(object sender, EventArgs e)
|
||
{
|
||
btn_Pause.Enabled = true;
|
||
btn_Resume.Enabled = true;
|
||
if (pos0==null|| pos1 == null|| pos2 == null)
|
||
{
|
||
MessageBox.Show("请先设置3个点位!");
|
||
return;
|
||
}
|
||
thread_PosMove = new Thread(PosMove);
|
||
thread_PosMove.IsBackground = false;
|
||
thread_PosMove.Start();
|
||
}
|
||
|
||
private static object locker_PosMove = new object();
|
||
public void PosMove()
|
||
{
|
||
lock (locker_PosMove)
|
||
{
|
||
while (true)
|
||
{
|
||
robot.resume_move();
|
||
robot.get_scara_param();
|
||
robot.new_movej_xyz_lr(pos0[0], pos0[1], pos0[2], pos0[3], 50, 0, posHand0);
|
||
robot.wait_stop();
|
||
robot.new_movej_xyz_lr(pos1[0], pos1[1], pos1[2], pos1[3], 50, 0, posHand1);
|
||
robot.wait_stop();
|
||
robot.new_movej_xyz_lr(pos2[0], pos2[1], pos2[2], pos2[3], 50, 0, posHand2);
|
||
robot.wait_stop();
|
||
}
|
||
}
|
||
}
|
||
|
||
private void btn_Pause_Click(object sender, EventArgs e)
|
||
{
|
||
btn_Stop.Enabled = false;
|
||
robot.pause_move();
|
||
}
|
||
|
||
private void btn_Resume_Click(object sender, EventArgs e)
|
||
{
|
||
btn_Stop.Enabled = true;
|
||
robot.resume_move();
|
||
}
|
||
|
||
private void btn_Stop_Click(object sender, EventArgs e)
|
||
{
|
||
btn_Pause.Enabled = false;
|
||
btn_Resume.Enabled = false;
|
||
robot.new_stop_move();
|
||
thread_PosMove.Abort();
|
||
}
|
||
|
||
private void btn_Joint_Click(object sender, EventArgs e)
|
||
{
|
||
if (!isInit)
|
||
{
|
||
MessageBox.Show("机械臂未初始化");
|
||
return;
|
||
}
|
||
#region 关节回零
|
||
btn = (Button)sender;
|
||
if (btn == null)
|
||
{
|
||
return;
|
||
}
|
||
if (btn == btn_joint1)
|
||
{
|
||
robot.joint_home(1);//使轴回到零位
|
||
|
||
}
|
||
else if (btn == btn_joint2)
|
||
{
|
||
robot.joint_home(2);
|
||
}
|
||
else if (btn == btn_joint3)
|
||
{
|
||
robot.joint_home(3);
|
||
}
|
||
else if (btn == btn_joint4)
|
||
{
|
||
|
||
robot.joint_home(4);
|
||
}
|
||
#endregion
|
||
}
|
||
|
||
private void rit_Coord_TextChanged(object sender, EventArgs e)
|
||
{
|
||
|
||
}
|
||
|
||
private void cob_Robot_ID_SelectedIndexChanged(object sender, EventArgs e)
|
||
{
|
||
|
||
}
|
||
|
||
private void tap_Move_Click(object sender, EventArgs e)
|
||
{
|
||
|
||
}
|
||
|
||
private void button1_Click(object sender, EventArgs e)
|
||
{
|
||
MoveToPosition(0);
|
||
}
|
||
|
||
private void button3_Click(object sender, EventArgs e)
|
||
{
|
||
MoveToPosition(2);
|
||
}
|
||
|
||
private void button2_Click(object sender, EventArgs e)
|
||
{
|
||
MoveToPosition(1);
|
||
}
|
||
|
||
private void button4_Click(object sender, EventArgs e)
|
||
{
|
||
MoveToPosition(3);
|
||
}
|
||
|
||
private void init_pos_btn_Click(object sender, EventArgs e)
|
||
{
|
||
MoveToPosition(4);
|
||
}
|
||
|
||
private void button2_Click_1(object sender, EventArgs e)
|
||
{
|
||
|
||
}
|
||
private void button1_Click_1(object sender, EventArgs e)
|
||
{
|
||
cameraManager.TakePhoto();
|
||
}
|
||
|
||
private void cam_feed_Click(object sender, EventArgs e)
|
||
{
|
||
cameraManager.ShowParameterDialog();
|
||
}
|
||
|
||
private void button1_Click_2(object sender, EventArgs e)
|
||
{
|
||
if (!isDetectionRunning)
|
||
{
|
||
// 连接到Python服务器
|
||
if (ConnectToServer())
|
||
{
|
||
isDetectionRunning = true;
|
||
detectionThread = new Thread(DetectionProcess);
|
||
detectionThread.IsBackground = true;
|
||
detectionThread.Start();
|
||
|
||
((Button)sender).Text = "停止检测";
|
||
MessageBox.Show("目标检测已开始");
|
||
}
|
||
else
|
||
{
|
||
MessageBox.Show("连接服务器失败");
|
||
}
|
||
}
|
||
else
|
||
{
|
||
// 停止检测
|
||
StopDetection();
|
||
((Button)sender).Text = "开始检测";
|
||
MessageBox.Show("目标检测已停止");
|
||
}
|
||
}
|
||
|
||
private void pictureBox1_Click(object sender, EventArgs e)
|
||
{
|
||
if (pictureBox1.Image != null)
|
||
{
|
||
// 创建一个新窗口显示大图
|
||
Form imageForm = new Form();
|
||
imageForm.Text = "检测结果";
|
||
imageForm.StartPosition = FormStartPosition.CenterParent;
|
||
imageForm.Size = new Size(800, 600);
|
||
|
||
PictureBox largePictureBox = new PictureBox();
|
||
largePictureBox.Dock = DockStyle.Fill;
|
||
largePictureBox.SizeMode = PictureBoxSizeMode.Zoom;
|
||
largePictureBox.Image = new Bitmap(pictureBox1.Image);
|
||
|
||
imageForm.Controls.Add(largePictureBox);
|
||
imageForm.ShowDialog(this);
|
||
|
||
largePictureBox.Image.Dispose();
|
||
}
|
||
}
|
||
private bool ConnectToServer()
|
||
{
|
||
try
|
||
{
|
||
tcpClient = new TcpClient();
|
||
tcpClient.Connect(SERVER_IP, SERVER_PORT);
|
||
networkStream = tcpClient.GetStream();
|
||
return true;
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
MessageBox.Show("连接服务器失败: " + ex.Message);
|
||
return false;
|
||
}
|
||
}
|
||
|
||
// 检测处理线程
|
||
private void DetectionProcess()
|
||
{
|
||
while (isDetectionRunning)
|
||
{
|
||
try
|
||
{
|
||
// 保存当前图像
|
||
string imagePath = cameraManager.SaveCurrentImageForDetection();
|
||
if (!string.IsNullOrEmpty(imagePath))
|
||
{
|
||
// 发送图像到Python服务器
|
||
SendImageToServer(imagePath);
|
||
|
||
// 接收处理后的图像
|
||
string receivedImagePath = ReceiveImageFromServer();
|
||
if (!string.IsNullOrEmpty(receivedImagePath))
|
||
{
|
||
// 在UI线程中显示图像
|
||
this.Invoke(new Action(() => DisplayDetectionResult(receivedImagePath)));
|
||
}
|
||
}
|
||
|
||
// 等待1分钟
|
||
Thread.Sleep(60000);
|
||
//File.Delete(imagePath);
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
this.Invoke(new Action(() => MessageBox.Show("检测过程出错: " + ex.Message)));
|
||
break;
|
||
}
|
||
|
||
}
|
||
}
|
||
|
||
// 发送图像到服务器
|
||
private void SendImageToServer(string imagePath)
|
||
{
|
||
try
|
||
{
|
||
byte[] imageData = File.ReadAllBytes(imagePath);
|
||
byte[] imageSize = new byte[4];
|
||
imageSize[0] = (byte)((imageData.Length >> 24) & 0xFF);
|
||
imageSize[1] = (byte)((imageData.Length >> 16) & 0xFF);
|
||
imageSize[2] = (byte)((imageData.Length >> 8) & 0xFF);
|
||
imageSize[3] = (byte)(imageData.Length & 0xFF);
|
||
|
||
// 先发送图像大小
|
||
networkStream.Write(imageSize, 0, 4);
|
||
// 再发送图像数据
|
||
networkStream.Write(imageData, 0, imageData.Length);
|
||
networkStream.Flush();
|
||
//MessageBox.Show($"发送图像成功,大小: {imageData.Length} 字节");
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
throw new Exception("发送图像失败: " + ex.Message);
|
||
}
|
||
}
|
||
// 从服务器接收处理后的图像
|
||
private string ReceiveImageFromServer()
|
||
{
|
||
try
|
||
{
|
||
// 接收图像大小
|
||
byte[] sizeBuffer = new byte[4];
|
||
int bytesRead = ReceiveExactly(sizeBuffer, 4);
|
||
if (bytesRead != 4) throw new Exception("接收图像大小失败");
|
||
|
||
int imageSize = (sizeBuffer[0] << 24) | (sizeBuffer[1] << 16) |
|
||
(sizeBuffer[2] << 8) | sizeBuffer[3];
|
||
|
||
//MessageBox.Show($"准备接收处理结果图像,大小: {imageSize} 字节");
|
||
|
||
// 接收width
|
||
byte[] widthBuffer = new byte[4];
|
||
bytesRead = ReceiveExactly(widthBuffer, 4);
|
||
if (bytesRead != 4) throw new Exception("接收width失败");
|
||
|
||
// 将字节数组转换为浮点数(大端序)
|
||
if (BitConverter.IsLittleEndian)
|
||
Array.Reverse(widthBuffer);
|
||
receivedWidth = BitConverter.ToSingle(widthBuffer, 0);
|
||
|
||
// 接收height
|
||
byte[] heightBuffer = new byte[4];
|
||
bytesRead = ReceiveExactly(heightBuffer, 4);
|
||
if (bytesRead != 4) throw new Exception("接收height失败");
|
||
|
||
// 将字节数组转换为浮点数(大端序)
|
||
if (BitConverter.IsLittleEndian)
|
||
Array.Reverse(heightBuffer);
|
||
receivedHeight = BitConverter.ToSingle(heightBuffer, 0);
|
||
|
||
//MessageBox.Show($"width:{receivedWidth}, height:{receivedHeight}");
|
||
|
||
// 接收图像数据
|
||
byte[] imageBuffer = new byte[imageSize];
|
||
bytesRead = ReceiveExactly(imageBuffer, imageSize);
|
||
if (bytesRead != imageSize) throw new Exception("接收图像数据不完整");
|
||
|
||
// 保存接收到的图像
|
||
string receivedImagePath = Path.Combine(Application.StartupPath,
|
||
"received_detection_" + DateTime.Now.ToString("yyyyMMddHHmmss") + ".jpg");
|
||
File.WriteAllBytes(receivedImagePath, imageBuffer);
|
||
|
||
return receivedImagePath;
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
throw new Exception("接收图像失败: " + ex.Message);
|
||
}
|
||
}
|
||
// 辅助方法:确保接收指定字节数的数据
|
||
private int ReceiveExactly(byte[] buffer, int size)
|
||
{
|
||
int totalBytesRead = 0;
|
||
while (totalBytesRead < size)
|
||
{
|
||
int bytesRead = networkStream.Read(buffer, totalBytesRead, size - totalBytesRead);
|
||
if (bytesRead == 0)
|
||
throw new Exception("连接断开");
|
||
totalBytesRead += bytesRead;
|
||
}
|
||
return totalBytesRead;
|
||
}
|
||
|
||
// 在pictureBox1中显示检测结果
|
||
private void DisplayDetectionResult(string imagePath)
|
||
{
|
||
try
|
||
{
|
||
if (File.Exists(imagePath))
|
||
{
|
||
// 如果pictureBox1之前有图像,先释放资源
|
||
if (pictureBox1.Image != null)
|
||
{
|
||
pictureBox1.Image.Dispose();
|
||
}
|
||
|
||
// 加载并显示新图像
|
||
using (var fs = new FileStream(imagePath, FileMode.Open, FileAccess.Read))
|
||
{
|
||
pictureBox1.Image = Image.FromStream(fs);
|
||
}
|
||
pictureBox1.SizeMode = PictureBoxSizeMode.Zoom;
|
||
}
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
MessageBox.Show("显示检测结果失败: " + ex.Message);
|
||
}
|
||
}
|
||
// 停止检测
|
||
private void StopDetection()
|
||
{
|
||
isDetectionRunning = false;
|
||
|
||
if (detectionThread != null && detectionThread.IsAlive)
|
||
{
|
||
detectionThread.Join(2000); // 等待2秒
|
||
}
|
||
|
||
|
||
// 关闭网络连接
|
||
try
|
||
{
|
||
networkStream?.Close();
|
||
tcpClient?.Close();
|
||
}
|
||
catch { }
|
||
|
||
networkStream = null;
|
||
tcpClient = null;
|
||
}
|
||
|
||
private void tap_Axis_Click(object sender, EventArgs e)
|
||
{
|
||
|
||
}
|
||
|
||
private void tap_Cam_Click(object sender, EventArgs e)
|
||
{
|
||
|
||
}
|
||
|
||
private void button2_Click_2(object sender, EventArgs e)
|
||
{
|
||
if (!isCycleRunning)
|
||
{
|
||
// 检查是否选择了点位
|
||
UpdateSelectedPositions();
|
||
if (selectedPositions.Count == 0)
|
||
{
|
||
MessageBox.Show("请至少选择一个点位进行检测");
|
||
return;
|
||
}
|
||
|
||
// 开始循环
|
||
if (!isInit)
|
||
{
|
||
MessageBox.Show("机械臂未初始化");
|
||
return;
|
||
}
|
||
if (cameraPositions == null || cameraPositions.Length < 5)
|
||
{
|
||
MessageBox.Show("点位数据未正确加载");
|
||
return;
|
||
}
|
||
// 连接到检测服务器
|
||
if (!ConnectToServer())
|
||
{
|
||
MessageBox.Show("连接检测服务器失败");
|
||
return;
|
||
}
|
||
|
||
// 记录循环开始时间
|
||
cycleStartTime = DateTime.Now.ToString("yyyyMMdd_HHmmss");
|
||
|
||
SetControlsEnabled(false);
|
||
|
||
isCycleRunning = true;
|
||
currentCycle = 0;
|
||
detectionData.Clear();
|
||
|
||
cycleThread = new Thread(CycleProcess);
|
||
cycleThread.IsBackground = true;
|
||
cycleThread.Start();
|
||
|
||
((Button)sender).Text = "停止循环";
|
||
MessageBox.Show($"循环检测已开始,选中点位:{string.Join(",", selectedPositions.Select(p => (p + 1).ToString()))},停留时间:{dwellTimeMinutes}分钟");
|
||
|
||
}
|
||
else
|
||
{
|
||
// 停止循环
|
||
StopCycle();
|
||
SetControlsEnabled(true);
|
||
((Button)sender).Text = "开始循环";
|
||
MessageBox.Show("循环检测已停止");
|
||
}
|
||
}
|
||
private void SetControlsEnabled(bool enabled)
|
||
{
|
||
// 在UI线程中执行控件状态修改
|
||
if (this.InvokeRequired)
|
||
{
|
||
this.Invoke(new Action<bool>(SetControlsEnabled), enabled);
|
||
return;
|
||
}
|
||
// 禁用/启用复选框
|
||
checkBox1.Enabled = enabled;
|
||
checkBox2.Enabled = enabled;
|
||
checkBox3.Enabled = enabled;
|
||
checkBox4.Enabled = enabled;
|
||
|
||
// 禁用/启用停留时间文本框
|
||
textBox1.Enabled = enabled;
|
||
}
|
||
|
||
// 修改后的循环处理方法
|
||
private void CycleProcess()
|
||
{
|
||
try
|
||
{
|
||
while (isCycleRunning)
|
||
{
|
||
// 创建一个字典来存储本轮循环的检测结果
|
||
Dictionary<int, float[]> cycleResults = new Dictionary<int, float[]>();
|
||
// 按照选中的点位顺序移动
|
||
foreach (int positionIndex in selectedPositions)
|
||
{
|
||
if (!isCycleRunning) break;
|
||
// 移动到指定点位
|
||
this.Invoke(new Action(() => {
|
||
MoveToPosition(positionIndex);
|
||
}));
|
||
// 等待移动完成并稳定3秒
|
||
WaitForRobotStopAndDelay(3000);
|
||
if (!isCycleRunning)
|
||
{
|
||
WaitForRobotStop();
|
||
break;
|
||
}
|
||
// 拍照并进行检测
|
||
string detectionResult = CaptureAndDetect(positionIndex);
|
||
if (!string.IsNullOrEmpty(detectionResult))
|
||
{
|
||
// 在UI线程中显示检测结果
|
||
this.Invoke(new Action(() => DisplayDetectionResult(detectionResult)));
|
||
// 存储检测到的width和height数据
|
||
cycleResults[positionIndex] = new float[] { receivedWidth, receivedHeight };
|
||
}
|
||
else
|
||
{
|
||
// 如果检测失败,存储0值
|
||
cycleResults[positionIndex] = new float[] { 0f, 0f };
|
||
}
|
||
// 在当前点位停留剩余时间(总时间 - 稳定时间3秒)
|
||
if (isCycleRunning)
|
||
{
|
||
int remainingTimeMs = (dwellTimeMinutes * 60 - 3) * 1000;
|
||
if (remainingTimeMs > 0)
|
||
{
|
||
// 分解为多个小的睡眠,每100ms检查一次停止标志
|
||
int sleptTime = 0;
|
||
while (sleptTime < remainingTimeMs && isCycleRunning)
|
||
{
|
||
int sleepDuration = Math.Min(100, remainingTimeMs - sleptTime);
|
||
Thread.Sleep(sleepDuration);
|
||
sleptTime += sleepDuration;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
// 保存本轮循环的数据
|
||
if (isCycleRunning && cycleResults.Count > 0)
|
||
{
|
||
currentCycle++;
|
||
|
||
// 更新Excel文件
|
||
this.Invoke(new Action(() => UpdateExcelFileWithSelectedPositions(cycleResults)));
|
||
}
|
||
}
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
this.Invoke(new Action(() => MessageBox.Show("循环过程出错: " + ex.Message)));
|
||
}
|
||
finally
|
||
{
|
||
// 移动到归位点位(第5个点位)
|
||
if (isInit)
|
||
{
|
||
WaitForRobotStop();
|
||
this.Invoke(new Action(() => {
|
||
MoveToPosition(4); // 第5个点位(索引4)
|
||
}));
|
||
|
||
// 确保在循环结束时恢复控件状态
|
||
this.Invoke(new Action(() => {
|
||
if (isCycleRunning == false) // 只有在正常结束时才恢复
|
||
{
|
||
SetControlsEnabled(true);
|
||
}
|
||
}));
|
||
|
||
}
|
||
}
|
||
}
|
||
|
||
// Excel文件更新方法
|
||
private void UpdateExcelFileWithSelectedPositions(Dictionary<int, float[]> cycleResults)
|
||
{
|
||
try
|
||
{
|
||
ExcelPackage.LicenseContext = LicenseContext.NonCommercial;
|
||
// 根据开始时间和选中点位创建文件名
|
||
string selectedPosStr = string.Join("_", selectedPositions.Select(p => (p + 1).ToString()));
|
||
string fileName = $"DetectionResults_Pos{selectedPosStr}_{cycleStartTime}.xlsx";
|
||
string filePath = Path.Combine(Application.StartupPath, fileName);
|
||
FileInfo file = new FileInfo(filePath);
|
||
using (ExcelPackage package = new ExcelPackage(file))
|
||
{
|
||
ExcelWorksheet worksheet;
|
||
if (package.Workbook.Worksheets.Count == 0)
|
||
{
|
||
// 创建新的工作表
|
||
worksheet = package.Workbook.Worksheets.Add("检测结果");
|
||
// 设置表头
|
||
worksheet.Cells[1, 1].Value = "循环次数";
|
||
worksheet.Cells[1, 2].Value = "检测时间";
|
||
|
||
int headerCol = 3;
|
||
foreach (int pos in selectedPositions)
|
||
{
|
||
worksheet.Cells[1, headerCol].Value = $"pos{pos + 1}_width";
|
||
worksheet.Cells[1, headerCol + 1].Value = $"pos{pos + 1}_height";
|
||
headerCol += 2;
|
||
}
|
||
}
|
||
else
|
||
{
|
||
worksheet = package.Workbook.Worksheets[0];
|
||
}
|
||
// 添加数据行
|
||
int row = worksheet.Dimension?.Rows + 1 ?? 2;
|
||
|
||
worksheet.Cells[row, 1].Value = currentCycle;
|
||
worksheet.Cells[row, 2].Value = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
|
||
|
||
int dataCol = 3;
|
||
foreach (int pos in selectedPositions)
|
||
{
|
||
if (cycleResults.ContainsKey(pos))
|
||
{
|
||
worksheet.Cells[row, dataCol].Value = cycleResults[pos][0]; // width
|
||
worksheet.Cells[row, dataCol + 1].Value = cycleResults[pos][1]; // height
|
||
}
|
||
else
|
||
{
|
||
worksheet.Cells[row, dataCol].Value = 0; // width
|
||
worksheet.Cells[row, dataCol + 1].Value = 0; // height
|
||
}
|
||
dataCol += 2;
|
||
}
|
||
package.Save();
|
||
}
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
MessageBox.Show("更新Excel文件失败: " + ex.Message);
|
||
}
|
||
}
|
||
|
||
private void WaitForRobotStop()
|
||
{
|
||
if (!isInit) return;
|
||
while (true)
|
||
{
|
||
robot.get_scara_param();
|
||
if (!robot.move_flag) // 机械臂处于静止状态
|
||
{
|
||
break;
|
||
}
|
||
Thread.Sleep(100); // 每100ms检查一次
|
||
}
|
||
}
|
||
|
||
private void WaitForRobotStopAndDelay(int additionalDelayMs)
|
||
{
|
||
// 先等待机械臂停止运动
|
||
WaitForRobotStop();
|
||
|
||
// 然后额外等待指定时间
|
||
if (isCycleRunning)
|
||
{
|
||
Thread.Sleep(additionalDelayMs);
|
||
}
|
||
}
|
||
|
||
private string CaptureAndDetect(int positionIndex)
|
||
{
|
||
try
|
||
{
|
||
// 重置检测结果
|
||
receivedWidth = 0;
|
||
receivedHeight = 0;
|
||
// 保存当前图像到对应文件夹
|
||
string imagePath = SaveImageToPositionFolder(positionIndex);
|
||
if (string.IsNullOrEmpty(imagePath))
|
||
{
|
||
return null;
|
||
}
|
||
// 发送图像到服务器进行检测
|
||
SendImageToServer(imagePath);
|
||
// 接收处理后的图像
|
||
string receivedImagePath = ReceiveImageFromServer();
|
||
// 将检测结果图像保存到对应文件夹
|
||
if (!string.IsNullOrEmpty(receivedImagePath))
|
||
{
|
||
string targetFolder = Path.Combine(Application.StartupPath, $"Position{positionIndex + 1}_Results_{cycleStartTime}");
|
||
if (!Directory.Exists(targetFolder))
|
||
{
|
||
Directory.CreateDirectory(targetFolder);
|
||
}
|
||
|
||
string finalPath = Path.Combine(targetFolder,
|
||
$"Detection_Pos{positionIndex + 1}_Cycle{currentCycle}_{DateTime.Now:yyyyMMddHHmmss}.jpg");
|
||
File.Copy(receivedImagePath, finalPath, true);
|
||
return finalPath;
|
||
}
|
||
return receivedImagePath;
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
this.Invoke(new Action(() => MessageBox.Show($"点位{positionIndex + 1}检测失败: " + ex.Message)));
|
||
return null;
|
||
}
|
||
}
|
||
|
||
private string SaveImageToPositionFolder(int positionIndex)
|
||
{
|
||
return cameraManager.SaveImageToPositionFolder(positionIndex, currentCycle, cycleStartTime);
|
||
}
|
||
|
||
private void StopCycle()
|
||
{
|
||
isCycleRunning = false;
|
||
if (cycleThread != null && cycleThread.IsAlive)
|
||
{
|
||
cycleThread.Join(5000); // 等待5秒
|
||
}
|
||
// 关闭网络连接
|
||
StopDetection();
|
||
}
|
||
|
||
private void checkBox1_CheckedChanged_1(object sender, EventArgs e)
|
||
{
|
||
UpdateSelectedPositions();
|
||
}
|
||
|
||
private void checkBox2_CheckedChanged(object sender, EventArgs e)
|
||
{
|
||
UpdateSelectedPositions();
|
||
}
|
||
|
||
private void checkBox3_CheckedChanged(object sender, EventArgs e)
|
||
{
|
||
UpdateSelectedPositions();
|
||
}
|
||
|
||
private void checkBox4_CheckedChanged(object sender, EventArgs e)
|
||
{
|
||
UpdateSelectedPositions();
|
||
}
|
||
|
||
private void textBox1_TextChanged(object sender, EventArgs e)
|
||
{
|
||
// 更新停留时间
|
||
if (int.TryParse(textBox1.Text, out int minutes) && minutes > 0)
|
||
{
|
||
dwellTimeMinutes = minutes;
|
||
}
|
||
else if (!string.IsNullOrEmpty(textBox1.Text))
|
||
{
|
||
MessageBox.Show("请输入有效的停留时间(分钟数)");
|
||
textBox1.Text = dwellTimeMinutes.ToString();
|
||
}
|
||
}
|
||
private void UpdateSelectedPositions()
|
||
{
|
||
selectedPositions.Clear();
|
||
|
||
if (checkBox1.Checked) selectedPositions.Add(0); // 点位1
|
||
if (checkBox2.Checked) selectedPositions.Add(1); // 点位2
|
||
if (checkBox3.Checked) selectedPositions.Add(2); // 点位3
|
||
if (checkBox4.Checked) selectedPositions.Add(3); // 点位4
|
||
}
|
||
|
||
private void button3_Click_1(object sender, EventArgs e)
|
||
{
|
||
tempControl.ToggleSerialPort(button3, comboBox1);
|
||
}
|
||
|
||
private void tabPage1_Click(object sender, EventArgs e)
|
||
{
|
||
|
||
}
|
||
private void comboBox1_SelectedIndexChanged(object sender, EventArgs e)
|
||
{
|
||
tempControl.OnComboBoxSelectedIndexChanged(comboBox1, button3);
|
||
}
|
||
|
||
private void Form1_FormClosing(object sender, FormClosingEventArgs e)
|
||
{
|
||
tempControl.OnFormClosing();
|
||
}
|
||
|
||
private void groupBox1_Enter(object sender, EventArgs e)
|
||
{
|
||
|
||
}
|
||
|
||
private void label6_Click(object sender, EventArgs e)
|
||
{
|
||
|
||
}
|
||
|
||
private void textBox2_TextChanged(object sender, EventArgs e)
|
||
{
|
||
|
||
}
|
||
|
||
private void groupBox1_Enter_1(object sender, EventArgs e)
|
||
{
|
||
|
||
}
|
||
|
||
private void label4_Click(object sender, EventArgs e)
|
||
{
|
||
|
||
}
|
||
|
||
private void button4_Click_1(object sender, EventArgs e)
|
||
{
|
||
|
||
}
|
||
|
||
private void button7_Click(object sender, EventArgs e)
|
||
{
|
||
|
||
}
|
||
|
||
private void button9_Click(object sender, EventArgs e)
|
||
{
|
||
|
||
}
|
||
|
||
private void button11_Click(object sender, EventArgs e)
|
||
{
|
||
|
||
}
|
||
|
||
private void label26_Click(object sender, EventArgs e)
|
||
{
|
||
|
||
}
|
||
}
|
||
}
|