arm/WindowsFormsApp1/Form1.cs

2221 lines
85 KiB
C#
Raw Permalink Normal View History

2025-02-04 20:09:10 +08:00
using System;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using ABB.Robotics.Controllers;
using ABB.Robotics.Controllers.Discovery;
using ABB.Robotics.Controllers.EventLogDomain;
using ABB.Robotics.Controllers.RapidDomain;
using ABB.Robotics.Controllers.MotionDomain;
using ABB.Robotics.Controllers.FileSystemDomain;
using ABB.Robotics.Controllers.IOSystemDomain;
using System.Threading;
using System.IO;
using System.IO.Ports;
using Emgu.CV.Structure;
using Intel.RealSense;
using Emgu.CV;
using Image = System.Drawing.Image;
using RealSence_PathMove;
using System.Numerics;
using System.Collections.Generic;
using System.Threading.Tasks;
using OpenCvSharp;
using OpenCvSharp.Extensions;
using Point = System.Drawing.Point;
namespace WindowsFormsApp1
{
public partial class Form1 : Form
{
public static Form1 Instance { get; private set; }
// 用來保存相機讀取執行緒
private Thread cameraThread;
private OpenCvSharp.VideoCapture capture; // 相機裝置
[Obsolete]
public Form1()
{
InitializeComponent();
intelRealSense = new IntelRealSense(this); // 初始化 IntelRealSense實例
ABBrobot = new ABBrobot(this); //初始化 ABBrobo實例
Form.CheckForIllegalCrossThreadCalls = false;//讓跨執行續可以執行UI
Instance = this; // 設定實例
}
//=================全域變數宣告==================
string[] type = { "RS232", "TCP" };
Modbus modbus = new Modbus();
private NetworkScanner scanner = null;
public static Controller controller = null;
public static ABB.Robotics.Controllers.RapidDomain.Task[] tasks = null;
public static bool isConnect;
public static bool isconnecttask;
private bool isconnectmodule;
public int taskint;
public string taskstring;
public int moduleint;
public string modulestring;
public int routineunt;
public string routinestring;
private bool iscanchangetext;
private string[] alllines;
private int postionindex;
private int motionindex;
private string m_fileName;
private string m_filePath;
private ThreadStart Run2;
Thread thread2;
private string[] imageFiles;
private int currentImageIndex = 0;
//RealSenseL515相機中心點與手臂法蘭面中心的位置差 mm
public float camoffset_x = 88f;
public float camoffset_y = 0;
public float camoffset_z = -17f;
//工具末端與手臂法蘭面中心的位置差 mm
public float CCDoffset_x = 125f;
public float CCDoffset_z = 120f;
//手臂的拍攝影像當前姿態法蘭面位置
public float ArmOrg_x = 468.70f;
public float ArmOrg_y = -6.58f;
public float ArmOrg_z = 380.53f;
public double camera_distance;
internal ABBrobot ABBrobot { get; }
public Vector3 firstCameraPoint { get; private set; }
public PointF Compare_yolo { get; private set; }
public bool ROI;
public bool GoldStandard = false;
public event EventHandler Button6StateChanged;
public int left, top, right, bottom;
public double Gx, Gy, Gz, GRx, GRy, GRz,dx,dy, newGx, newGy, newGz;
public string gx, gy, gz, gRx, gRy, gRz;
private Bitmap drawingBitmap;
//================視窗載入 初始宣告===============
private void Form1_Load(object sender, EventArgs e)
{
pictureBox_PLC.BackColor = Color.Silver;
gpb_Type_TCP.Enabled = false;
gpb_RS232.Enabled = false;
btn_Connect.Enabled = false;
btn_Disconnect.Enabled = false;
cmb_Type.Items.AddRange(type);
timer2.Enabled = true;
timer2.Interval = 100;
StartCamera(); // 啟動相機
}
//================視窗關閉==========================
private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
cts?.Cancel(); // 當按鈕被按下時,取消所有等待操作
cts?.Dispose(); // 釋放資源
cts = null; // 重置為 null以便下次使用時重新初始化
// 停止之前的背景任務(如果有的話)
backgroundCts?.Cancel();
backgroundCts?.Dispose();
backgroundCts = null;
backgroundCts1?.Cancel();
backgroundCts1?.Dispose();
backgroundCts1 = null;
this.Invoke((Action)(() =>
{
pictureBox4.Image = null;
pictureBox4.Refresh();
pictureBox5.Image = null;
pictureBox5.Refresh();
}));
modbus.Disconnect();
//取消任务
if (cam == true || cam != false)
{
intelRealSense.cts.Cancel();
}
if (isConnect == true)
{
MessageBox.Show("ABB手臂斷開連線");
}
// 關閉相機執行緒
if (cameraThread != null && cameraThread.IsAlive)
{
cameraThread.Abort(); // 停止執行緒
}
// 釋放相機資源
if (capture != null)
{
capture.Release();
capture.Dispose();
}
}
#region PLC部分
public void ComportName()//============= ComPort_Name載入combobox ====================
{
cmb_Comport.Items.Clear();
cmb_Comport.Items.AddRange(SerialPort.GetPortNames());
}
private void timer2_Tick(object sender, EventArgs e)//Timer掃描內容(PLC)
{
//============= Comport狀態 ==========================
modbus.IsOpen();
if (modbus.isopen)
{
pictureBox_PLC.BackColor = Color.GreenYellow;
modbus.Command("010205000001", cmb_Type.Text);
}
else
{
pictureBox_PLC.BackColor = Color.Silver;
}
//====================== 按鈕權限 ========================
if (cmb_Comport.Text != "" || txb_Tcp_Ip.Text != "" && txb_Tcp_Port.Text != "")
{
btn_Connect.Enabled = true;
btn_Disconnect.Enabled = true;
}
else
{
btn_Connect.Enabled = false;
btn_Disconnect.Enabled = false;
}
}
private void btn_Connect_Click(object sender, EventArgs e)//連線PLC
{
if (cmb_Type.Text == "TCP")
{
modbus.Connert(cmb_Type.Text, txb_Tcp_Ip.Text, txb_Tcp_Port.Text);
}
else if (cmb_Type.Text == "RS232")
modbus.Connert(cmb_Type.Text, cmb_Comport.Text);
}
private void btn_Restart_Click(object sender, EventArgs e)//重置comport
{
ComportName();
}
private void cmb_Type_SelectedIndexChanged(object sender, EventArgs e)//TCP/RS232區域是否開啟
{
{
modbus.Disconnect();
if (cmb_Type.Text == "TCP")
{
gpb_Type_TCP.Enabled = true;
gpb_RS232.Enabled = false;
}
else if (cmb_Type.Text == "RS232")
{
ComportName();
gpb_Type_TCP.Enabled = false;
gpb_RS232.Enabled = true;
}
}
}
private void btn_Disconnect_Click(object sender, EventArgs e)//中斷連線
{
modbus.Disconnect();
}
private void btn_Command_Click(object sender, EventArgs e)//命令輸出
{
rtb_response.Text = modbus.Command(rtb_Command.Text, cmb_Type.Text);
rtb_response.Text = modbus.Command(rtb_Command.Text, cmb_Type.Text);
}
private void btn_Command_clear_Click(object sender, EventArgs e)//命令欄清除
{
rtb_Command.Clear();
}
public static string HexStringToASCII(string hexstring)//string to ascii
{
byte[] bt = HexStringToBinary(hexstring);
string lin = "";
for (int i = 0; i < bt.Length; i++)
{
lin = lin + bt[i] + " ";
}
string[] ss = lin.Trim().Split(new char[] { ' ' });
char[] c = new char[ss.Length];
int a;
for (int i = 0; i < c.Length; i++)
{
a = Convert.ToInt32(ss[i]);
c[i] = Convert.ToChar(a);
}
string b = new string(c);
return b;
}
public static byte[] HexStringToBinary(string hexstring)
{
string[] tmpary = hexstring.Trim().Split(' ');
byte[] buff = new byte[tmpary.Length];
for (int i = 0; i < buff.Length; i++)
{
buff[i] = Convert.ToByte(tmpary[i], 16);
}
return buff;
}
#endregion
#region
//=====================================ABB 連線部分=================================
private void button1_Click(object sender, EventArgs e)//搜尋機器人
{
if (scanner == null)
{
scanner = new NetworkScanner();
}
scanner.Scan();
ControllerInfoCollection controls = scanner.Controllers;
this.listView1.Items.Clear();
foreach (ControllerInfo info in controls)
{
ListViewItem item = new ListViewItem(info.SystemName);
item.SubItems.Add(info.IPAddress.ToString()); //顯示IP地址
item.SubItems.Add(info.Version.ToString()); //顯示robotware版本
item.SubItems.Add(info.IsVirtual.ToString()); //顯示是否為虛擬控制
item.SubItems.Add(info.ControllerName.ToString()); //顯示控制器名稱
item.Tag = info;
this.listView1.Items.Add(item);
}
}
[Obsolete]
private void connectrobot(object sender, EventArgs e)//選擇連接機器人
{
if (this.listView1.Items.Count > 0)
{
ListViewItem item = this.listView1.SelectedItems[0];
if (item != null)
{
ControllerInfo info = (ControllerInfo)item.Tag;
if (info.Availability == Availability.Available)
{
if (controller != null)
{
controller.Logoff();
controller.Dispose();
controller = null;
}
controller = ControllerFactory.CreateFrom(info);
controller.Logon(UserInfo.DefaultUser);
ABBrobot.Motorstatus();
MessageBox.Show("已經登陸控制器" + info.SystemName);
//botClient.SendTextMessageAsync(
//chatId: "-1001758058968",
//text: "ABB手臂連線成功",
//disableNotification: false);
isConnect = true;
timer1.Enabled = true;
}
}
}
hScrollBar1.Value = controller.MotionSystem.SpeedRatio; //獲取控制器速度率
tasks = controller.Rapid.GetTasks();
radioButton1.Checked = true;
}
public void timer1_Tick(object sender, EventArgs e)
{
//讀取當前程式指針與手臂位置
Run2 = new ThreadStart(Test_thread2);//先把test_thread2變成ThreadStart的物件
thread2 = new Thread(Run2);//用ThreadStart的物件建立一個執行緒
thread2.Start(); //開始掃描狀態
//label1.Text = controller.MotionSystem.SpeedRatio.ToString()+ "%";//將ABB速度與滑動塊實時連接並控制速率。
//關節座標
if (radioButton1.Checked)
{
JointTarget RJ = controller.MotionSystem.ActiveMechanicalUnit.GetPosition();
px.Text = "J1";
py.Text = "J2";
pz.Text = "J3";
rx.Text = "J4";
ry.Text = "J5";
rz.Text = "J6";
textBox3.Text = RJ.RobAx.Rax_1.ToString(format: "0.00");
textBox4.Text = RJ.RobAx.Rax_2.ToString(format: "0.00");
textBox5.Text = RJ.RobAx.Rax_3.ToString(format: "0.00");
textBox6.Text = RJ.RobAx.Rax_4.ToString(format: "0.00");
textBox7.Text = RJ.RobAx.Rax_5.ToString(format: "0.00");
textBox8.Text = RJ.RobAx.Rax_6.ToString(format: "0.00");
}
//基座標
if (radioButton2.Checked)
{
double tx;
double ty;
double tz;
RobTarget robTarget = controller.MotionSystem.ActiveMechanicalUnit.GetPosition(CoordinateSystemType.World);
px.Text = "PX";
py.Text = "PY";
pz.Text = "PZ";
rx.Text = "RX";
ry.Text = "RY";
rz.Text = "RZ";
textBox3.Text = robTarget.Trans.X.ToString(format: "0.00");
textBox4.Text = robTarget.Trans.Y.ToString(format: "0.00");
textBox5.Text = robTarget.Trans.Z.ToString(format: "0.00");
robTarget.Rot.ToEulerAngles(out tx, out ty, out tz);
textBox6.Text = tx.ToString(format: "0.00");
textBox7.Text = ty.ToString(format: "0.00");
textBox8.Text = tz.ToString(format: "0.00");
}
}
private void button6_Click(object sender, EventArgs e)//電機開關
{
if (isConnect == true && controller.OperatingMode == ControllerOperatingMode.Auto)//判斷是否連接機器人
{
if (controller.State == ControllerState.MotorsOn)
{
ABBrobot.Closemotor();
}
else if (controller.State == ControllerState.MotorsOff)
{
ABBrobot.Openmotor();
}
}
else
{
MessageBox.Show("未識別到機器人,請連接機器人!!或開啟自動模式!!");
}
}
private void button2_Click(object sender, EventArgs e)//選擇任務
{
ABBrobot.Isconnectrobot();
if (isConnect == true)
{
comboBox1.Items.Clear();
for (int i = 0; i < (int)tasks.Count(); i++)
{
comboBox1.Items.Add(tasks[i].Name);
}
isconnecttask = true;
}
else
{
MessageBox.Show("未識別到機器人,請連接機器人!");
}
}
private void button3_Click(object sender, EventArgs e)//選擇模塊
{
comboBox2.Items.Clear();
if (isconnecttask == true)
{
int taskint = comboBox1.SelectedIndex;
Module[] modules = controller.Rapid.GetTasks()[taskint].GetModules();
for (int i = 0; i < (int)modules.Count(); i++)
{
comboBox2.Items.Add(modules[i].Name);
};
isconnectmodule = true;
}
else
{
MessageBox.Show("請指定某個任務");
isconnectmodule = false;
}
}
private void button4_Click(object sender, EventArgs e)//選擇程序
{
comboBox3.Items.Clear();
if (isconnectmodule == true)
{
int taskint = comboBox1.SelectedIndex;
int moduleint = comboBox2.SelectedIndex;
Routine[] routines1 = controller.Rapid.GetTasks()[taskint].GetModules()[moduleint].GetRoutines();
for (int i = 0; i < (int)routines1.Count(); i++)
{
comboBox3.Items.Add(routines1[i].Name);
}
}
else
{
MessageBox.Show("請指定某個模塊");
}
}
private void button5_Click(object sender, EventArgs e)//確認將所选的任務、模塊、程序保存
{
taskint = comboBox1.SelectedIndex;
taskstring = comboBox1.SelectedItem.ToString();
moduleint = comboBox2.SelectedIndex;
modulestring = comboBox2.SelectedItem.ToString();
routineunt = comboBox3.SelectedIndex;
routinestring = comboBox3.SelectedItem.ToString();
}
private void MyScrollBar1_Scroll(object sender, ScrollEventArgs e)//機器人控速比
{
if (isConnect == true)
{
if (controller.OperatingMode == ControllerOperatingMode.Auto)
{
controller.MotionSystem.SpeedRatio = Convert.ToInt32(hScrollBar1.Value);//myScrollBar1為滑塊控件名
label9.Text = "速度設定值" + controller.MotionSystem.SpeedRatio.ToString() + "%";
}
else
{
MessageBox.Show("請打開自動模式");
}
}
}
private void button8_Click(object sender, EventArgs e)//查看座標值
{
RapidSymbolSearchProperties date = RapidSymbolSearchProperties.CreateDefault();
date.Types = SymbolTypes.Data;
date.SearchMethod = SymbolSearchMethod.Block;
date.Recursive = true;
date.InUse = false;
date.LocalSymbols = false;
RapidSymbol[] symbols = tasks[taskint].SearchRapidSymbol(date, "robtarget", string.Empty);
this.comboBox4.Items.Clear();
foreach (RapidSymbol symbol in symbols)
{
try
{
RapidData rD = tasks[taskint].GetRapidData(symbol);
comboBox4.Items.Add(rD.Name);
}
catch (Exception)
{
return;
}
}
if (comboBox4.Items == null)
{
comboBox4.Text = "沒有座標變量";
}
else
{
comboBox4.SelectedIndex = 0;
}
}
private void button11_Click(object sender, EventArgs e)//日誌
{
try
{
EventLog log = controller.EventLog;
EventLogCategory cat = log.GetCategory(0);
this.textBox10.Text = "";
{
foreach (EventLogMessage emsg in cat.Messages)
{
int alarmNo;
alarmNo = emsg.CategoryId * 1000 + emsg.Number;
this.textBox10.Text = this.textBox10.Text + "" + alarmNo.ToString() + "" + emsg.Title + "" + emsg.Timestamp + "\r\n";
}
}
}
catch (Exception ex)
{
MessageBox.Show("出現錯誤" + ex.Message);
}
}
private void button9_Click(object sender, EventArgs e)//查看座標值(確定)
{
if (comboBox1.SelectedItem.ToString() != null || comboBox4.SelectedItem.ToString() != null)
{
RapidSymbolSearchProperties date = RapidSymbolSearchProperties.CreateDefault();
date.Types = SymbolTypes.Data;
date.SearchMethod = SymbolSearchMethod.Block;
date.Recursive = true;
date.InUse = false;
date.LocalSymbols = false;
RapidSymbol[] symbols = tasks[taskint].SearchRapidSymbol(date, "robtarget", string.Empty);
this.listView2.Items.Clear();
foreach (RapidSymbol symbol in symbols)
{
try
{
RapidData rD = tasks[taskint].GetRapidData(symbol);
if (rD.Name == comboBox4.SelectedItem.ToString())
{
ListViewItem item2 = new ListViewItem(symbol.Name);
if (rD.Value != null)
{
item2.SubItems.Add(rD.Value.ToString());
}
else
{
item2.SubItems.Add("0");
}
item2.Tag = symbol;
this.listView2.Items.Add(item2);
}
else
{
continue;
}
}
catch (Exception)
{
return;
}
}
}
else
{
MessageBox.Show("請選擇任務!");
}
}
[Obsolete]
private void button10_Click_1(object sender, EventArgs e)//修改點座標
{
string strvariable = comboBox4.SelectedItem.ToString();
Form2 form2 = new Form2();//實例化Form2
form2.ShowDialog();//展示Form2
if (form2.oKorCancel == true)
{
try
{
using (Mastership.Request(controller.Rapid))//獲得訪問示教器內部管理權限
{
RapidData rd = controller.Rapid.GetRapidData(taskstring, modulestring, strvariable);//設定座標
RobTarget rob = (RobTarget)rd.Value;
rob.Trans.X = form2.dx;
rob.Trans.Y = form2.dy;
rob.Trans.Z = form2.dz;
rob.Rot.Q1 = form2.dq1;
rob.Rot.Q2 = form2.dq2;
rob.Rot.Q3 = form2.dq3;
rob.Rot.Q4 = form2.dq4;
rd.Value = rob;
MessageBox.Show(strvariable + "修改成功!");
button9_Click(sender, e);
}
}
catch (Exception ex)
{
MessageBox.Show("發生錯誤:" + ex.Message);
}
form2.oKorCancel = false;
}
else
{
}
}
private void button14_Click(object sender, EventArgs e)//打開程序
{
OpenFileDialog fileDialog = new OpenFileDialog();
fileDialog.Filter = ".mod文件(*.mod)|*.mod";
fileDialog.ValidateNames = true;
fileDialog.CheckPathExists = true;
fileDialog.CheckFileExists = true;
if (fileDialog.ShowDialog() == DialogResult.OK)
{
m_fileName = fileDialog.SafeFileName;
m_filePath = fileDialog.FileName;
m_filePath = m_filePath.Replace("\\", "//");
Console.WriteLine("name: " + m_fileName);
Console.WriteLine("path: " + m_filePath);
this.textBox9.Text = fileDialog.FileName;
FileStream fileStream = new FileStream(this.textBox9.Text, FileMode.Open, FileAccess.Read);
byte[] arraydate = new byte[(int)fileStream.Length];
int index = 0;
int code = fileStream.ReadByte();
while (code != -1)
{
arraydate[index] = Convert.ToByte(code);
code = fileStream.ReadByte();
index++;
}
this.textBox14.Text = Encoding.Default.GetString(arraydate);
fileStream.Close();
}
else
{
m_fileName = m_filePath = " ";
}
}
[Obsolete]
private void button15_Click(object sender, EventArgs e)//PP to main
{
firstButtonClick = true;
try
{
if (controller.OperatingMode == ControllerOperatingMode.Auto)
{
using (Mastership.Request(controller.Rapid))
{
controller.Rapid.Stop(StopMode.Immediate);
}
using (Mastership.Request((IMastershipResourceController)controller))
{
int taskIndex = 0; // 要操作的任務索引
ABB.Robotics.Controllers.RapidDomain.Task[] tasks = controller.Rapid.GetTasks();
if (tasks.Length > 0 && taskIndex >= 0 && taskIndex < tasks.Length)
{
tasks[taskIndex].ResetProgramPointer();
MessageBox.Show("程序指針已經復位");
}
}
}
else
{
MessageBox.Show("請切換自動模式");
}
}
catch (System.InvalidOperationException ex)
{
MessageBox.Show("權限已經占用" + ex.Message);
}
catch (Exception ex)
{
MessageBox.Show("PP to main有誤" + ex.ToString());
}
iscanchangetext = true;
}
[Obsolete]
private void button16_Click(object sender, EventArgs e)//指針移到指定程式
{
firstButtonClick = true;
try
{
if (controller.OperatingMode == ControllerOperatingMode.Auto)
{
using (Mastership.Request(controller.Rapid))
{
controller.Rapid.Stop(StopMode.Immediate);
}
tasks = controller.Rapid.GetTasks();
using (Mastership.Request((IMastershipResourceController)controller))
{
tasks = controller.Rapid.GetTasks();
tasks[0].SetProgramPointer(modulestring, routinestring);
MessageBox.Show("程序指針已經設置到了" + routinestring);
}
}
else
{
}
}
catch (Exception ex)
{
MessageBox.Show("指針移到指定程式錯誤: " + ex.Message);
}
}
private void Test_thread2()//副程式////讀取當前程式指針與手臂位置
{
if (iscanchangetext == true && tasks[taskint].ProgramPointer != null && tasks[taskint].MotionPointer != null)
{
try
{
alllines = textBox14.Text.Split('\n');
ProgramPosition programPosition = tasks[taskint].ProgramPointer;
string programstr = programPosition.Range.End.Row.ToString();
postionindex = Convert.ToInt32(programstr);
string changeprogram = postionindex.ToString() + " ->" + alllines[postionindex - 1].Trim();//指針
textBox13.Text = changeprogram;
ProgramPosition position = tasks[taskint].MotionPointer;
string motionstr = position.Range.End.Row.ToString();
motionindex = Convert.ToInt32(motionstr);
string changemotion = motionindex.ToString() + " Z*" + alllines[motionindex].Trim();//機器人
textBox12.Text = changemotion;
//有需要時再用
// string[] changePointx = alllines[postionindex - 1].Trim().Split(' ');
//changePoint = changePointx[1].Split(',');
}
catch (Exception)
{
}
}
}
[Obsolete]
private void button17_Click(object sender, EventArgs e)//程序啟動
{
// botClient.SendTextMessageAsync(
//chatId: "-1001758058968",
// text: "手臂啟動",
//disableNotification: false);
try
{
if (controller.OperatingMode == ControllerOperatingMode.Auto)
{
using (Mastership.Request(controller.Rapid))
{
StartResult s = controller.Rapid.Start();
}
}
else
{
MessageBox.Show("請切換自動模式");
}
}
catch (Exception ex)
{
MessageBox.Show("出錯了!" + ex.Message);
}
iscanchangetext = true;
}
[Obsolete]
private void button18_Click(object sender, EventArgs e)//程序停止
{
//mythread.Abort();//停止讀取執行緒
//thread.Abort();//停止讀取執行緒
// botClient.SendTextMessageAsync(
//chatId: "-1001758058968",
//text: "手臂停止",
// disableNotification: false);
try
{
using (Mastership.Request(controller.Rapid))
{
controller.Rapid.Stop(StopMode.Immediate);
}
}
catch (Exception ex)
{
MessageBox.Show("出錯了!" + ex.Message);
}
iscanchangetext = false;
}
private void button19_Click(object sender, EventArgs e)//保存程序
{
OpenFileDialog fileDialog = new OpenFileDialog();
if (fileDialog.ShowDialog() == DialogResult.OK)
{
File.WriteAllText(fileDialog.FileName, this.textBox14.Text);
MessageBox.Show("保存成功");
}
else
{
return;
}
}
class ListViewNF : System.Windows.Forms.ListView //解決ListView閃爍
{
public ListViewNF()
{
// 開啟雙緩沖
this.SetStyle(ControlStyles.OptimizedDoubleBuffer | ControlStyles.AllPaintingInWmPaint, true);
this.SetStyle(ControlStyles.EnableNotifyMessage, true);
}
}
private void button21_Click(object sender, EventArgs e)//I/O讀取
{
timer5.Enabled = true;
button22.Enabled = true;
comboBox5.Enabled = true;
}
private void timer5_Tick(object sender, EventArgs e)//掃描I/O
{
this.listView3.Items.Clear();
Thread.Sleep(100);
SignalCollection signals = controller.IOSystem.GetSignals(IOFilterTypes.Unit, "d652");
foreach (Signal signal in signals)
{
ListViewItem item = new ListViewItem(signal.Name);
item.SubItems.Add(signal.Type.ToString());
item.SubItems.Add(signal.Value.ToString());
item.SubItems.Add(signal.Unit.ToString());
item.Tag = signal;
this.listView3.Items.Add(item);
}
}
private void button22_Click(object sender, EventArgs e)//I/O寫入
{
ABBrobot.IO();
}
private void button23_Click(object sender, EventArgs e) //取得機器人資訊
{
label14.Text = controller.RobotWare.Name.ToString();
richTextBox1.Text = "";
richTextBox2.Text = "";
MechanicalUnitServiceInfo unitServiceInfo = controller.MotionSystem.ActiveMechanicalUnit.ServiceInfo;
richTextBox2.Text += "生產總時間: " + unitServiceInfo.ElapsedProductionTime.TotalHours.ToString() + "小時\r\n";
richTextBox2.Text += "自上次服務後的生產總時間: " + unitServiceInfo.ElapsedProductionTimeSinceLastService.TotalHours.ToString() + "小時\r\n";
//richTextBox2.Text += "上次開機時間: " + unitServiceInfo.LastStart.ToString() + "小時\r\n";
richTextBox2.Text += "自上次維修時間: " + unitServiceInfo.ElapsedCalenderTimeSinceLastService.TotalDays.ToString() + "天\r\n";
richTextBox1.Text += "RW版本: " + controller.RobotWare.Version.ToString() + "\r\n";
RobotWareOptionCollection options = controller.RobotWare.Options;
foreach (RobotWareOption option in options)
{
richTextBox1.Text += "option: " + option.ToString() + "\r\n";
}
}
private void button25_Click(object sender, EventArgs e)//備份
{
if (controller != null)
{
UserAuthorizationSystem uas = controller.AuthenticationSystem;
if (uas.CheckDemandGrant(Grant.BackupController))
{
string str = controller.SystemName + "_backup_" + DateTime.Now.ToString("yyyy-MM-dd");
string pathStr = controller.FileSystem.RemoteDirectory;
controller.Backup(pathStr + @"\backup\" + str);
MessageBox.Show("備份完成");
}
else
{
MessageBox.Show("沒有權限");
}
}
}
private void button26_Click(object sender, EventArgs e)//上傳
{
if (m_fileName == "" || m_fileName == "")
{
MessageBox.Show("文件為空");
return;
}
try
{
string remoteDir = controller.FileSystem.RemoteDirectory;
FileSystem file = controller.FileSystem;
//存在就替換(不加該程式,存在相同文件會回報當前操作無效)
if (controller.FileSystem.FileExists(m_fileName) == true)
{
file.PutFile(m_filePath, true);
MessageBox.Show("覆蓋成功位於HOME目錄下");
}
else
{
file.PutFile(m_filePath);
MessageBox.Show("上傳成功位於HOME目錄下");
}
}
catch (System.InvalidOperationException ex)
{
MessageBox.Show(ex.Message + ",上傳失敗");
}
catch (System.Exception ex)
{
MessageBox.Show(ex.Message + ",上傳失敗");
}
}
[Obsolete]
private void button29_Click(object sender, EventArgs e)//模擬路徑
{
#region ( Module Routine )
firstButtonClick = true;
using (Mastership.Request(controller.Rapid))
{
controller.Rapid.Stop(StopMode.Immediate);
}
using (Mastership master = Mastership.Request(controller.Rapid))
{
// 直接使用路径点数量
RapidData rd = controller.Rapid.GetRapidData(tasks[taskint].Name, "MainModule", "count");
if (rd.Value is Num)
{
Num num = (Num)rd.Value;
num.Value = aa;
rd.Value = num;
}
rd = controller.Rapid.GetRapidData(tasks[taskint].Name, "MainModule", "path");
for (int i = 0; i < aa; i++)
{
RobTarget rt = (RobTarget)rd.ReadItem(i);
rt.Trans.FillFromString2("[" + dataGridView1.Rows[i].Cells[0].Value.ToString() + ',' + dataGridView1.Rows[i].Cells[1].Value.ToString() + ',' + dataGridView1.Rows[i].Cells[2].Value.ToString() + "]");
rt.Rot.FillFromEulerAngles(Convert.ToDouble(dataGridView1.Rows[i].Cells[3].Value), Convert.ToDouble(dataGridView1.Rows[i].Cells[4].Value), Convert.ToDouble(dataGridView1.Rows[i].Cells[5].Value));
rt.Robconf.FillFromString("[0,0,0,0]");
rt.Extax.FillFromString("[9E+09,9E+09,9E+09,9E+09,9E+09,9E+09]");
rd.WriteItem(rt, i);
}
tasks[taskint].SetProgramPointer("MainModule", "WeldingPath");
controller.Rapid.Start();
}
#endregion
}
[Obsolete]
public void Home() // 手臂回原點
{
ABBrobot.Isconnectrobot();
if (controller.OperatingMode == ControllerOperatingMode.Auto && Form1.controller.State == ControllerState.MotorsOn)
{
using (Mastership.Request(controller.Rapid))
{
controller.Rapid.Stop(StopMode.Immediate);
}
int taskIndex = 0; // 獲取用戶任務
Module[] modules = controller.Rapid.GetTasks()[taskIndex].GetModules(); // 獲取任務列表
string moduleNameToFind = "MainModule"; // 指定要查找的模塊名稱
Module foundModule = modules.FirstOrDefault(module => module.Name == moduleNameToFind); // 在模塊列表中查找指定名稱的模塊
if (foundModule != null) // 如果找到了匹配的模塊
{
Routine[] routines = foundModule.GetRoutines();// 獲取程序列表,這裡使用 foundModule
string routineNameToFind = "home"; // 指定要查找的程序名稱
Routine foundRoutine = routines.FirstOrDefault(routine => routine.Name == routineNameToFind); // 在程序列表中查找指定名稱的程序
if (foundRoutine != null) // 如果找到了匹配的程序PP移至例行程序
{
using (Mastership.Request((IMastershipResourceController)controller))
{
tasks = controller.Rapid.GetTasks();
if (tasks.Length > 0 && taskIndex >= 0 && taskIndex < tasks.Length)
{
tasks[taskIndex].SetProgramPointer(moduleNameToFind, routineNameToFind);
iscanchangetext = true;
StartResult s = controller.Rapid.Start();
}
}
}
}
}
else
{
MessageBox.Show("請切換自動模式,電機是否開啟");
}
}
#endregion
#region
//--------------------------------------------- 影像部分*----------------------------------------------------------
private readonly IntelRealSense intelRealSense; // 将 IntelRealSense 实例作为类成员
//public int objectCounter = 1; // 初始化物體編號為1
public static bool firstButtonClick = true;//判別是否第一下
public bool cameraOpened = false;//相機狀態
public Image<Bgr, byte> ColorImg = null;
public Image<Rgb, byte> FilteredImg;
public VideoFrame colorFrame;
public Intel.RealSense.Frame filtered;
public IntelRealSense RealSense;
public bool cam;
public delegate void SetEnabledCallback(bool enabled);
public int aa;
private List<Point> selectedPoints = new List<Point>();
private float scaleX;
private float scaleY;
// 創建一個變數來控制執行緒是否繼續運行
public volatile bool ImageProcessing = false;
public volatile bool ImageProcessing1 = false;
public volatile bool goldsample;
// 啟動相機並使用執行緒讀取影像
private void StartCamera()
{
// 初始化相機0是默認相機
capture = new OpenCvSharp.VideoCapture(2);
if (!capture.IsOpened())
{
MessageBox.Show("無法打開相機");
return;
}
// 開始一個新執行緒來讀取影像
cameraThread = new Thread(() =>
{
while (true)
{
using (OpenCvSharp.Mat frame = new OpenCvSharp.Mat())
{
capture.Read(frame); // 讀取相機影像
if (!frame.Empty())
{
// 轉換影像格式為Bitmap
Bitmap image = BitmapConverter.ToBitmap(frame);
UpdatePictureBox(image); // 更新畫面
}
Thread.Sleep(30); // 控制影像更新速率
}
}
});
cameraThread.IsBackground = true; // 設定為背景執行緒
cameraThread.Start(); // 啟動執行緒
}
// 更新PictureBox上的影像
private void UpdatePictureBox(Bitmap image)
{
if (pictureBox1.InvokeRequired)
{
// 如果不是在UI執行緒使用Invoke來進行UI更新
pictureBox1.Invoke(new Action(() =>
{
pictureBox7.Image?.Dispose(); // 釋放之前的影像
pictureBox7.Image = image; // 顯示新影像
}));
}
else
{
pictureBox7.Image?.Dispose(); // 釋放之前的影像
pictureBox7.Image = image; // 顯示新影像
}
}
// 在視窗加載時,初始化圖片列表
private void LoadImage(int index)
{
if (index >= 0 && index < imageFiles.Length)
{
string imagePath = imageFiles[index];
var image = Image.FromFile(imagePath);
pictureBox1.Image = image;
intelRealSense.ProcessImage(image);
}
}
[Obsolete]
private void Button7_Click_1(object sender, EventArgs e)
{
ROI = false;
selectedPoints.Clear();
// 清空 PictureBox 上的標記
pictureBox2.Invalidate();
ABBrobot.Isconnectrobot();
}
public void PlanningAOI()
{
DigitalSignal digitalSignalDo3 = (DigitalSignal)controller.IOSystem.GetSignal("Do3");
while (true)
{
if (digitalSignalDo3.Value == 1)
{
// 提示使用者點選四個點
MessageBox.Show("請在彩色影像上點選ROI範圍(四個點)","提示", MessageBoxButtons.OK);
digitalSignalDo3.Value = 0;
break;
}
}
}
private void PictureBox2_MouseClick_1(object sender, MouseEventArgs e)
{
// 根据解析度和 PictureBox 的大小计算缩放比例
scaleX = (float)pictureBox2.Width / 640f;
scaleY = (float)pictureBox2.Height / 480f;
if (e.Button == MouseButtons.Left)
{
// 限制只能选取四个点
if (selectedPoints.Count < 4)
{
selectedPoints.Add(e.Location);
pictureBox2.Invalidate();
}
else
{
MessageBox.Show("以選四個點,請勿繼續點擊。", "提示", MessageBoxButtons.OK);
}
}
}
// 在需要显示点位的地方,根据校正后的 selectedPoints 列表绘制点
private void DrawPoints(PaintEventArgs e)
{
foreach (Point point in selectedPoints)
{
// 将控件坐标转换为图像坐标
int imageX = (int)(point.X / scaleX);
int imageY = (int)(point.Y / scaleY);
// 绘制点
int controlX = (int)(imageX * scaleX);
int controlY = (int)(imageY * scaleY);
e.Graphics.FillEllipse(Brushes.Red, controlX - 5, controlY - 5, 10, 10);
// 显示坐标
string coordinate = "(" + imageX.ToString() + ", " + imageY.ToString() + ")";
e.Graphics.DrawString(coordinate, this.Font, Brushes.Black, controlX + 10, controlY - 10);
}
}
private void DrawRectangle(PaintEventArgs e)
{
if (selectedPoints.Count == 4)
{
// 将图像坐标转换为控件坐标
Point[] controlPoints = selectedPoints.Select(p => new Point((int)(p.X * scaleX), (int)(p.Y * scaleY))).ToArray();
// 计算矩形的左上角和右下角坐标(图像坐标系统)
left = selectedPoints.Min(p => (int)(p.X / scaleX));
top = selectedPoints.Min(p => (int)(p.Y / scaleY));
right = selectedPoints.Max(p => (int)(p.X / scaleX));
bottom = selectedPoints.Max(p => (int)(p.Y / scaleY));
// 绘制矩形
e.Graphics.DrawRectangle(Pens.Blue, (int)(left * scaleX), (int)(top * scaleY), (int)((right - left) * scaleX), (int)((bottom - top) * scaleY));
ROI = true;
}
}
private void PictureBox2_Paint_1(object sender, PaintEventArgs e)
{
DrawPoints(e);
DrawRectangle(e);
}
private void PictureBox4_Paint(object sender, PaintEventArgs e)
{
if (!cameraOpened) // 如果相机未打开,则打开它
{
}
else
{
DrawRectangle(e);
}
}
[Obsolete]
private void Button28_Click(object sender, EventArgs e)//提取金樣本
{
intelRealSense.TakeImage = false;
ROI = false;
pictureBox1.Image = null;
pictureBox2.Image = null;
pictureBox3.Image = null;
selectedPoints.Clear();
// 清空 PictureBox 上的標記
pictureBox2.Invalidate();
ABBrobot.Isconnectrobot();
button7.Enabled = true;
if (controller.OperatingMode == ControllerOperatingMode.Auto && Form1.controller.State == ControllerState.MotorsOn && cameraOpened == true)
{
using (Mastership.Request(controller.Rapid))
{
controller.Rapid.Stop(StopMode.Immediate);
}
int taskIndex = 0; // 獲取用戶任務
Module[] modules = controller.Rapid.GetTasks()[taskIndex].GetModules(); // 獲取任務列表
string moduleNameToFind = "MainModule"; // 指定要查找的模塊名稱
Module foundModule = modules.FirstOrDefault(module => module.Name == moduleNameToFind); // 在模塊列表中查找指定名稱的模塊
if (foundModule != null) // 如果找到了匹配的模塊
{
Routine[] routines = foundModule.GetRoutines();// 獲取程序列表,這裡使用 foundModule
string routineNameToFind = "TakeImage"; // 指定要查找的程序名稱
Routine foundRoutine = routines.FirstOrDefault(routine => routine.Name == routineNameToFind); // 在程序列表中查找指定名稱的程序
if (foundRoutine != null) // 如果找到了匹配的程序PP移至例行程序
{
using (Mastership.Request((IMastershipResourceController)controller))
{
tasks = controller.Rapid.GetTasks();
if (tasks.Length > 0 && taskIndex >= 0 && taskIndex < tasks.Length)
{
tasks[taskIndex].SetProgramPointer(moduleNameToFind, routineNameToFind);
iscanchangetext = true;
groupBox2.Enabled = false;
listView4.Items.Clear();
label16.Text = null;
ImageProcessing = true;
intelRealSense.CaptureImagesAndSave();
button7.Enabled = true;
}
}
}
}
}
else
{
MessageBox.Show("請切換自動模式,電機是否開啟");
}
}
[Obsolete]
private async void Button27_Click(object sender, EventArgs e)//開關相機
{
if (!cameraOpened) // 如果相机未打开,则打开它
{
cam = true;
intelRealSense.OpenCamera(); // 打開像機
button28.Enabled = true;
cameraOpened = true;
label17.Text = "相機狀態:開";
button27.Text = "關相機";
label17.BackColor = Color.Red;
}
else // 如果相机已经打开,则关闭它
{
cam = false;
cameraOpened = false;
label17.Text = "相機狀態:關";
button27.Text = "開相機";
button7.Enabled = false;
button28.Enabled = false;
label17.BackColor = Color.Transparent;
await intelRealSense.CloseCamera(); // 關閉相機
groupBox2.Enabled = true;
this.Invoke((Action)(() =>
{
pictureBox4.Image = null;
pictureBox4.Refresh();
pictureBox5.Image = null;
pictureBox5.Refresh();
pictureBox6.Image = null;
pictureBox6.Refresh();
}));
}
}
private void Button12_Click(object sender, EventArgs e) //選擇資料夾
{
using (var folderDialog = new FolderBrowserDialog())
{
if (folderDialog.ShowDialog() == DialogResult.OK)
{
// 獲取所選文件夹中的所有.jpg.bmp文件
imageFiles = Directory.GetFiles(folderDialog.SelectedPath, "*.jpg")
.Concat(Directory.GetFiles(folderDialog.SelectedPath, "*.bmp"))
.ToArray();
if (imageFiles.Length > 0)
{
currentImageIndex = 0;
LoadImage(currentImageIndex);
}
}
}
}
private void Button13_Click(object sender, EventArgs e) // 上一張圖片按钮
{
listView4.Items.Clear();
// 上一張圖片按钮
if (imageFiles == null || imageFiles.Length == 0)
{
MessageBox.Show("請先選擇資料夾!", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
return;
}
currentImageIndex--;
if (currentImageIndex < 0)
{
currentImageIndex = 0;
}
// 重置物體編號1
intelRealSense.objectCounter = 1;
LoadImage(currentImageIndex);
}
private void Button20_Click(object sender, EventArgs e) // 下一張圖片按钮
{
listView4.Items.Clear();
if (imageFiles == null || imageFiles.Length == 0)
{
MessageBox.Show("請先選擇資料夾!", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
return;
}
currentImageIndex++;
if (currentImageIndex >= imageFiles.Length)
{
currentImageIndex = imageFiles.Length - 1;
}
// 重置物體編號1
intelRealSense.objectCounter = 1;
LoadImage(currentImageIndex);
}
private void Button13_PreviewKeyDown(object sender, PreviewKeyDownEventArgs e) //按鍵連動
{
// 使用鍵盤A键切换上一張圖片
if (e.KeyCode == Keys.A)
{
Button13_Click(sender, e);
}
// 使用键盤B键切换下一張圖片
else if (e.KeyCode == Keys.D)
{
Button20_Click(sender, e);
}
}
public void SetPictureBox4Image(Bitmap bitmap1) //pictureBox4更新
{
if (pictureBox4.InvokeRequired) // 檢查是否需要進行跨執行緒的操作
{
pictureBox4.Invoke(new Action(() => // 如果需要跨執行緒使用Invoke方法在UI執行緒上執行影像更新
{
pictureBox4.Image = bitmap1;
}));
}
else
{
pictureBox4.Image = bitmap1; // 如果不需要跨執行緒直接在當前執行緒上更新pictureBox2的影像
}
}
public void SetPictureBox5Image(Bitmap depthBitmap)//pictureBox5更新
{
if (pictureBox5.InvokeRequired)
{
pictureBox5.Invoke(new Action(() =>
{
pictureBox5.Image = depthBitmap;
}));
}
else
{
pictureBox5.Image = depthBitmap;
}
}
[Obsolete]
private void Button24_Click(object sender, EventArgs e)//路徑生成
{
Home();
// 彈出視窗詢問是否執行
DialogResult result = MessageBox.Show("是否生成路徑?", "提示", MessageBoxButtons.OKCancel); // 根據使用者的選擇執行或不執行相應的程式碼
if (result == DialogResult.OK)
{
if (ROI == true && intelRealSense.TakeImage == true)
{
try
{
camera_distance = Convert.ToDouble(textBox1.Text);
}
catch
{
textBox1.Text = "0";
camera_distance = 0;
}
aa = intelRealSense.storedCoordinates.Count;
DataTable dt = new DataTable();
// 清除 DataTable 的內容
dt.Clear();
dt.Columns.Add("X", typeof(string));
dt.Columns.Add("Y", typeof(string));
dt.Columns.Add("Z", typeof(string));
dt.Columns.Add("Rx", typeof(string));
dt.Columns.Add("Ry", typeof(string));
dt.Columns.Add("Rz", typeof(string));
foreach (Vector3 cameraPoint in intelRealSense.storedCoordinates)
{
// 顯示 coordinate 的值
Console.WriteLine($"Coordinate: X={cameraPoint.X}, Y={cameraPoint.Y}, Z={cameraPoint.Z} mm");
// 將相機座標轉換為向量
var pointVector = MathNet.Numerics.LinearAlgebra.Vector<double>.Build.DenseOfArray(new double[] { cameraPoint.X, cameraPoint.Y, cameraPoint.Z });
// 計算相對於Z軸的旋轉角度
var rotationAngles = CalculateRotationAngles(pointVector);
// 顯示旋轉信息
Console.WriteLine($"Rotation Angles:");
Console.WriteLine($" thetaX: {rotationAngles[0]} degrees");
Console.WriteLine($" thetaY: {rotationAngles[1]} degrees");
Console.WriteLine($" thetaZ: {rotationAngles[2]} degrees");
//高30寬20
//(深度相機由後往前拍,手臂法蘭面向前)
DataRow dr = dt.NewRow();
// 根據 eye-in-hand 校正計算手臂座標
Gx = ArmOrg_x + camoffset_x + (cameraPoint.Z - (camera_distance + CCDoffset_x));
Gy = ArmOrg_y + camoffset_y - cameraPoint.X - Math.Tan((rotationAngles[0]) * Math.PI / 180) * (camera_distance + CCDoffset_x);
Gz = ArmOrg_z + camoffset_z - cameraPoint.Y + CCDoffset_z;// - Math.Tan((rotationAngles[1]) * Math.PI / 180) * (camera_distance + CCDoffset_x);
GRx = 0;
GRy = 90;// - rotationAngles[1];
GRz = 3 + rotationAngles[0];
dr["X"] = Gx;
dr["Y"] = Gy;
dr["Z"] = Gz;
dr["Rx"] = GRx;
dr["Ry"] = GRy;
dr["Rz"] = GRz;
dt.Rows.Add(dr);
}
// 将 DataTable 显示在 dataGridView1 中
dataGridView1.DataSource = dt;
button29.Enabled = true;
checkBox1.Enabled = true;
checkBox2.Enabled = true;
}
else
{
MessageBox.Show("請確認是否取像與選取ROI範圍");
}
}
else
{
// 使用者按下取消,不執行任何程式碼
}
}
public double[] CalculateRotationAngles(MathNet.Numerics.LinearAlgebra.Vector<double> vector)
{
// 1. 正規化輸入向量
var normalizedVector = vector.Normalize(2);
// 2. 定義基準座標系(這裡是Z軸)
var zAxis = MathNet.Numerics.LinearAlgebra.Vector<double>.Build.Dense(new[] { 0.0, 0.0, 1.0 });
// 3. 計算旋轉矩陣
var rotationMatrix = CalculateRotationMatrix(zAxis, normalizedVector);
// 4. 從旋轉矩陣提取旋轉角度
var angles = ExtractRotationAngles(rotationMatrix);
return angles;
}
// 使用Rodrigues旋轉公式計算旋轉矩陣// 計算fromVector到toVector的旋轉矩陣
private MathNet.Numerics.LinearAlgebra.Matrix<double> CalculateRotationMatrix(MathNet.Numerics.LinearAlgebra.Vector<double> fromVector, MathNet.Numerics.LinearAlgebra.Vector<double> toVector)
{
// 建立零向量
var v = MathNet.Numerics.LinearAlgebra.Vector<double>.Build.Dense(new[] { 0.0, 0.0, 0.0 });
// 如果兩向量相同,返回單位矩陣
if (fromVector.Equals(toVector))
return MathNet.Numerics.LinearAlgebra.Matrix<double>.Build.DenseIdentity(3);
// 計算兩向量的點積
var cosTheta = fromVector.DotProduct(toVector);
// v為fromVector在toVector方向投影的垂直分量
v = fromVector - (cosTheta * toVector);
// 計算v的L2範數
var k = v.L2Norm();
// 規範化v
if (k > 1e-17)
v = (1.0 / k) * v;
// v的外積矩陣
var vvT = v.OuterProduct(v);
// v的反對稱交叉矩陣
var vSkew = SkewSymmetricCrossProductMatrix(v);
// 3階單位矩陣
var eye = MathNet.Numerics.LinearAlgebra.Matrix<double>.Build.DenseIdentity(3);
// 利用Rodrigues公式計算旋轉矩陣
var rotationMatix = eye * cosTheta +
(1 - cosTheta) * vvT +
vSkew * Math.Sin(Math.Acos(cosTheta));
return rotationMatix;
}
// Construct skew-symmetric cross product matrix// 输入一个3维向量v,构建对应的反对称交叉乘矩阵
private MathNet.Numerics.LinearAlgebra.Matrix<double> SkewSymmetricCrossProductMatrix(MathNet.Numerics.LinearAlgebra.Vector<double> v)
{
// 直接构建一个3x3矩阵
return MathNet.Numerics.LinearAlgebra.Matrix<double>.Build.DenseOfArray(new[,] {
{0, -v[2], v[1]},
{v[2], 0, -v[0]},
{-v[1], v[0], 0}
});
}
private double[] ExtractRotationAngles(MathNet.Numerics.LinearAlgebra.Matrix<double> R)
{
var thetaX = Math.Atan2(R[2, 1], R[2, 2]) * 180 / Math.PI;
var thetaY = Math.Atan2(-R[2, 0],
Math.Sqrt(R[0, 0] * R[0, 0] +
R[1, 0] * R[1, 0])) * 180 / Math.PI;
var thetaZ = Math.Atan2(R[1, 0], R[0, 0]) * 180 / Math.PI;
return new[] { thetaX, thetaY, thetaZ };
}
private CancellationTokenSource backgroundCts;
private CancellationTokenSource backgroundCts1;
[Obsolete]
private async void button30_Click(object sender, EventArgs e)
{
DigitalSignal digitalSignalDo2 = (DigitalSignal)Form1.controller.IOSystem.GetSignal("Do2");
button29.Enabled = false;
button30.Enabled = false;
digitalSignalDo2.Value = 0;
backgroundCts = new CancellationTokenSource();
// 啟動新的背景任務
_ = MonitorDigitalSignalAsync(digitalSignalDo2, backgroundCts.Token);
// 判斷哪個RadioButton被勾選
if (checkBox1.Checked)
{
//Semiautomatic();
await System.Threading.Tasks.Task.Run(() => Semiautomatic());
}
else if (checkBox2.Checked)
{
await FullyautomaticAsync();
}
//await System.Threading.Tasks.Task.Run(async () =>
//{
// while (true)
// {
// if (digitalSignalDo2.Value == 1)
// {
// // Enable the button in the UI thread
// this.Invoke(new Action(() => button30.Enabled = true));
// ok1 = true;
// hasTriggered = false;
// }
// // 每隔5秒檢查一次
// await System.Threading.Tasks.Task.Delay(1000);
// }
//});
}
private async System.Threading.Tasks.Task MonitorDigitalSignalAsync(DigitalSignal signal, CancellationToken cancellationToken)
{
while (!cancellationToken.IsCancellationRequested)
{
if (signal.Value == 1)
{
button30.Enabled = true;
ok1 = true;
hasTriggered = false;
}
await System.Threading.Tasks.Task.Delay(1000, cancellationToken);
}
}
[Obsolete]
public void Semiautomatic()//半自動化
{
TakeImage();
}
public bool ok1;
public bool hasTriggered = false;
CancellationTokenSource cts = new CancellationTokenSource();
[Obsolete]
public async System.Threading.Tasks.Task FullyautomaticAsync()//全智動化
{
using (cts = new CancellationTokenSource())
{
try
{
while (!cts.Token.IsCancellationRequested)
{
string textBoxValue = textBox2.Text;
if (string.IsNullOrEmpty(textBoxValue))
{
MessageBox.Show("請輸入等待時間");
button30.Enabled = true;
return;
}
if (!int.TryParse(textBoxValue, out int waitTime))
{
MessageBox.Show("請輸入有效的數字");
button30.Enabled = true;
return;
}
else
{
if (!hasTriggered)
{
ok1 = true;
hasTriggered = true;
}
if (ok1 == true)
{
ok1 = false;
await TakeImageAsync();
// 使用 Task.Delay 并检查取消标记
await System.Threading.Tasks.Task.Delay(40 * 1000, cts.Token);
}
// 使用 Task.Delay 并检查取消标记
await System.Threading.Tasks.Task.Delay(waitTime * 1000, cts.Token);
}
}
}
catch (OperationCanceledException)
{
// 任务被取消,可以在这里处理清理工作
Console.WriteLine("操作已被取消");
}
finally
{
// 确保在方法结束时重置状态
ok1 = false;
hasTriggered = false;
button30.Enabled = true;
}
}
}
private void button31_Click(object sender, EventArgs e) //自動模式結束
{
cts?.Cancel(); // 當按鈕被按下時,取消所有等待操作
// cts 将在 FullyautomaticAsync 方法的 using 块结束时自动释放
// 停止之前的背景任务(如果有的话)
backgroundCts?.Cancel();
backgroundCts?.Dispose();
backgroundCts = null;
}
[Obsolete]
private async System.Threading.Tasks.Task TakeImageAsync()
{
await System.Threading.Tasks.Task.Run(() => TakeImage(), cts.Token);
}
[Obsolete]
public void TakeImage()//拍取待測物
{
ABBrobot.Isconnectrobot();
if (controller.OperatingMode == ControllerOperatingMode.Auto && Form1.controller.State == ControllerState.MotorsOn && cameraOpened == true)
{
using (Mastership.Request(controller.Rapid))
{
controller.Rapid.Stop(StopMode.Immediate);
}
int taskIndex = 0; // 獲取用戶任務
Module[] modules = controller.Rapid.GetTasks()[taskIndex].GetModules(); // 獲取任務列表
string moduleNameToFind = "MainModule"; // 指定要查找的模塊名稱
Module foundModule = modules.FirstOrDefault(module => module.Name == moduleNameToFind); // 在模塊列表中查找指定名稱的模塊
if (foundModule != null) // 如果找到了匹配的模塊
{
Routine[] routines = foundModule.GetRoutines();// 獲取程序列表,這裡使用 foundModule
string routineNameToFind = "TakeImage"; // 指定要查找的程序名稱
Routine foundRoutine = routines.FirstOrDefault(routine => routine.Name == routineNameToFind); // 在程序列表中查找指定名稱的程序
if (foundRoutine != null) // 如果找到了匹配的程序PP移至例行程序
{
using (Mastership.Request((IMastershipResourceController)controller))
{
tasks = controller.Rapid.GetTasks();
if (tasks.Length > 0 && taskIndex >= 0 && taskIndex < tasks.Length)
{
tasks[taskIndex].SetProgramPointer(moduleNameToFind, routineNameToFind);
iscanchangetext = true;
ImageProcessing1 = true;
intelRealSense.CompareSamples();
}
}
}
}
}
else
{
MessageBox.Show("請切換自動模式,電機是否開啟");
}
}
private void CheckBox1_CheckedChanged(object sender, EventArgs e)
{
if (checkBox1.Checked)
{
button29.Enabled = false;
button30.Enabled = true;
checkBox2.Checked = false;
button24.Enabled = false;
textBox1.Enabled = false;
}
else if(checkBox2.Checked)
{
textBox2.Enabled = true;
button30.Enabled = true;
button24.Enabled = false;
textBox1.Enabled = false;
}
else
{
textBox2.Enabled = false;
button29.Enabled = true;
button30.Enabled = false;
button24.Enabled = true;
textBox1.Enabled = true;
}
}
private void CheckBox2_CheckedChanged(object sender, EventArgs e)
{
if (checkBox2.Checked)
{
textBox2.Enabled = true;
button29.Enabled = false;
button30.Enabled = true;
checkBox1.Checked = false;
button24.Enabled = false;
textBox1.Enabled = false;
}
else if (checkBox1.Checked)
{
textBox2.Enabled = false;
button30.Enabled = true;
button24.Enabled = false;
textBox1.Enabled = false;
}
else
{
textBox2.Enabled = false;
button29.Enabled = true;
button30.Enabled = false;
button24.Enabled = true;
textBox1.Enabled = true;
}
}
[Obsolete]
public void Pathchange() //修改路徑顯示
{
cam = true;
intelRealSense.OpenCamera(); // 打開像機
cameraOpened = true;
label17.Text = "相機狀態:開";
button27.Text = "關相機";
label17.BackColor = Color.Red;
// 将 DataGridView1 的 DataSource 转换为 DataTable
DataTable dt = dataGridView1.DataSource as DataTable;
// 创建新的 DataTable 来存储修改后的路径
DataTable dt1 = new DataTable();
dt1.Columns.Add("X", typeof(double));
dt1.Columns.Add("Y", typeof(double));
dt1.Columns.Add("Z", typeof(double));
dt1.Columns.Add("Rx", typeof(double));
dt1.Columns.Add("Ry", typeof(double));
dt1.Columns.Add("Rz", typeof(double));
// 遍历原 DataTable 的每一行并修改
foreach (DataRow dr in dt.Rows)
{
DataRow dr_new = dt1.NewRow();
newGx = Convert.ToDouble(dr["X"]) - intelRealSense.z;
newGy = Convert.ToDouble(dr["Y"]) + intelRealSense.x;
newGz = Convert.ToDouble(dr["Z"]) - intelRealSense.y;
double newGRx = Convert.ToDouble(dr["Rx"]) + intelRealSense.Rz;
double newGRy = Convert.ToDouble(dr["Ry"]) + intelRealSense.Rx;
double newGRz = Convert.ToDouble(dr["Rz"]) + intelRealSense.Ry;
// 将修改后的值添加到新的 DataRow
if (intelRealSense.z > 1 || intelRealSense.z < -1 )
{
dr_new["X"] = newGx;
gx = "X位移了"+ -intelRealSense.z;
}
else
{
dr_new["X"] = Convert.ToDouble(dr["X"]);
gx = "X不變";
}
if (intelRealSense.x > 1 || intelRealSense.x < -1)
{
dr_new["Y"] = newGy;
gy = "Y位移了" + intelRealSense.x;
}
else
{
dr_new["Y"] = Convert.ToDouble(dr["Y"]);
gy = "Y不變";
}
if (intelRealSense.y > 1 || intelRealSense.y < 1)
{
dr_new["Z"] = newGz;
gz = "Z位移了" + -intelRealSense.y;
}
else
{
dr_new["Z"] = Convert.ToDouble(dr["Z"]);
gz = "Z不變";
}
if (intelRealSense.Rz > 1 && intelRealSense.Rz < 90 || intelRealSense.Rz < -1 && intelRealSense.Rz > -90)
{
dr_new["Rx"] = newGRx;
gRx = "Rx位移了" + intelRealSense.Rz;
}
else
{
dr_new["Rx"] = Convert.ToDouble(dr["Rx"]);
gRx = "Rx不變";
}
if (intelRealSense.Rx > 1 && intelRealSense.Rx < 90 || intelRealSense.Rx < -1 && intelRealSense.Rx > -90)
{
dr_new["Ry"] = newGRy;
gRy = "Ry位移了" + intelRealSense.Rx;
}
else
{
dr_new["Ry"] = Convert.ToDouble(dr["Ry"]);
gRy = "Ry不變";
}
if (intelRealSense.Ry > 1 && intelRealSense.Ry < 90 || intelRealSense.Ry < -1 && intelRealSense.Ry > -90)
{
dr_new["Rz"] = newGRz;
gRz = "Rz位移了" + intelRealSense.Ry;
}
else
{
dr_new["Rz"] = Convert.ToDouble(dr["Rz"]);
gRz = "Rz不變";
}
dt1.Rows.Add(dr_new);
}
// 将新的 DataTable 绑定到 DataGridView2
dataGridView2.DataSource = dt1;
label23.Text = $"修改路徑:\n{gx}\n{gy}\n{gz}\n{gRx}\n{gRy}\n{gRz}\n";
Performwelding();
}
public System.Numerics.Vector2 Compute2DCoordinate(Vector3 displacementPoint)
{
// 步驟1: 將深度點從毫米轉換為米
Vector3 depthPointMeters = displacementPoint / 1000;
//// 步驟2: 應用外參,將點從深度坐標系轉換到彩色坐標系
//Vector3 colorPoint = Vector3.Transform(depthPointMeters, new Matrix4x4(
// intelRealSense.depthExtrinsics.rotation[0], intelRealSense.depthExtrinsics.rotation[1], intelRealSense.depthExtrinsics.rotation[2], 0,
// intelRealSense.depthExtrinsics.rotation[3], intelRealSense.depthExtrinsics.rotation[4], intelRealSense.depthExtrinsics.rotation[5], 0,
// intelRealSense.depthExtrinsics.rotation[6], intelRealSense.depthExtrinsics.rotation[7], intelRealSense.depthExtrinsics.rotation[8], 0,
// intelRealSense.depthExtrinsics.translation[0], intelRealSense.depthExtrinsics.translation[1], intelRealSense.depthExtrinsics.translation[2], 1
//));
// 应用投影方程
float x = (depthPointMeters.X * intelRealSense.colorIntrinsics.fx / depthPointMeters.Z) + intelRealSense.colorIntrinsics.ppx;
float y = (depthPointMeters.Y * intelRealSense.colorIntrinsics.fy / depthPointMeters.Z) + intelRealSense.colorIntrinsics.ppy;
// 步驟4: 應用畸變校正(如果需要)
if (intelRealSense.colorIntrinsics.model == Distortion.ModifiedBrownConrady)
{
float r2 = x * x + y * y;
float f = 1 + intelRealSense.colorIntrinsics.coeffs[0] * r2 + intelRealSense.colorIntrinsics.coeffs[1] * r2 * r2 + intelRealSense.colorIntrinsics.coeffs[4] * r2 * r2 * r2;
float ux = x * f + 2 * intelRealSense.colorIntrinsics.coeffs[2] * x * y + intelRealSense.colorIntrinsics.coeffs[3] * (r2 + 2 * x * x);
float uy = y * f + 2 * intelRealSense.colorIntrinsics.coeffs[3] * x * y + intelRealSense.colorIntrinsics.coeffs[2] * (r2 + 2 * y * y);
x = ux;
y = uy;
}
Console.WriteLine($"Depth to Color 2D: {x} pixels, {y} pixels");
//Console.WriteLine($"Compute2DCoordinate: {x} 像素, {y} 像素");
return new Vector2(x, y);
}
private async System.Threading.Tasks.Task CurrentlocationSignalAsync(CancellationToken cancellationToken)
{
float x, y;
DigitalSignal digitalSignalDo4 = (DigitalSignal)controller.IOSystem.GetSignal("Do4");
HashSet<System.Drawing.PointF> processedPoints = new HashSet<System.Drawing.PointF>();
if (intelRealSense.storedCoordinates.Count > 0)
{
firstCameraPoint = intelRealSense.storedCoordinates[0];
Console.WriteLine($"First Coordinate: X={firstCameraPoint.X}, Y={firstCameraPoint.Y}, Z={firstCameraPoint.Z} mm");
}
float changex, changey, changez;
changex = (float)(firstCameraPoint.X + intelRealSense.x);
changey = (float)(firstCameraPoint.Y + intelRealSense.y);
changez = (float)(firstCameraPoint.Z + intelRealSense.z);
Vector3 displacementPoint = new Vector3(changex, changey, changez);
Vector2 colorPixel = Compute2DCoordinate(displacementPoint);
if (intelRealSense.yoloFeaturePoints.Count > 0)
{
Compare_yolo = intelRealSense.yoloFeaturePoints[0];
Console.WriteLine($"First Coordinate: X={Compare_yolo.X}pixels, Y={Compare_yolo.Y}pixels");
}
while (!cancellationToken.IsCancellationRequested)
{
if (digitalSignalDo4.Value == 1) // 檢查 digitalSignalDo4.Value 是否為 1
{
foreach (System.Drawing.PointF featurePoint in intelRealSense.yoloFeaturePoints)
{
if (processedPoints.Add(featurePoint)) // 如果這個點是新的,就會被加入 HashSet
{
int Difference_x = (int)(colorPixel.X - Compare_yolo.X);
int Difference_y = (int)(colorPixel.Y - Compare_yolo.Y);
int u = (int)featurePoint.X;
int v = (int)featurePoint.Y;
Console.WriteLine($"yolo: {u} px, {v} px");
x = u - Difference_x;
y = v - Difference_y;
Console.WriteLine($"偏移: {x} px, {y} px");
DrawPointOnBitmap(x, y); // 繪製點
break; // 一旦繪製了一個點,就跳出迴圈
}
}
digitalSignalDo4.Value = 0; // 重置 digitalSignalDo4.Value
}
await System.Threading.Tasks.Task.Delay(100, cancellationToken); // 添加延遲,避免過快重複繪製
}
}
private void DrawPointOnBitmap(float x, float y, float diameter = 15f, Color? color = null)
{
using (Graphics g = Graphics.FromImage(drawingBitmap))
{
g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;
using (SolidBrush brush = new SolidBrush(color ?? Color.Red))
{
float radius = diameter / 2f;
g.FillEllipse(brush, x - radius, y - radius, diameter, diameter);
}
}
pictureBox6.Invoke((MethodInvoker)delegate
{
pictureBox6.Refresh(); // 使用 Refresh 而不是 Invalidate
});
}
private void DrawPointOnBitmap1(float x, float y, float diameter = 15f, Color? color = null)
{
using (Graphics g = Graphics.FromImage(drawingBitmap))
{
g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;
using (SolidBrush brush = new SolidBrush(color ?? Color.Blue))
{
float radius = diameter / 2f;
g.FillEllipse(brush, x - radius, y - radius, diameter, diameter);
}
}
pictureBox6.Invoke((MethodInvoker)delegate
{
pictureBox6.Refresh(); // 使用 Refresh 而不是 Invalidate
});
}
[Obsolete]
public void Performwelding() //執行焊接
{
// 假設 pictureBox6.Image 已經設置了一張圖片
if (pictureBox6.Image != null)
{
drawingBitmap = new Bitmap(pictureBox6.Image);
}
else
{
drawingBitmap = new Bitmap(pictureBox6.Width, pictureBox6.Height);
}
pictureBox6.Image = drawingBitmap;
backgroundCts1 = new CancellationTokenSource();
// 啟動新的背景任務
_ = CurrentlocationSignalAsync(backgroundCts1.Token);
#region ( Module Routine )
firstButtonClick = true;
using (Mastership.Request(controller.Rapid))
{
controller.Rapid.Stop(StopMode.Immediate);
}
using (Mastership master = Mastership.Request(controller.Rapid))
{
// 直接使用路径点数量
RapidData rd = controller.Rapid.GetRapidData(tasks[taskint].Name, "MainModule", "count");
if (rd.Value is Num)
{
Num num = (Num)rd.Value;
num.Value = aa;
rd.Value = num;
}
rd = controller.Rapid.GetRapidData(tasks[taskint].Name, "MainModule", "path");
for (int i = 0; i < aa; i++)
{
RobTarget rt = (RobTarget)rd.ReadItem(i);
rt.Trans.FillFromString2("[" + dataGridView2.Rows[i].Cells[0].Value.ToString() + ',' + dataGridView2.Rows[i].Cells[1].Value.ToString() + ',' + dataGridView2.Rows[i].Cells[2].Value.ToString() + "]");
rt.Rot.FillFromEulerAngles(Convert.ToDouble(dataGridView2.Rows[i].Cells[3].Value), Convert.ToDouble(dataGridView2.Rows[i].Cells[4].Value), Convert.ToDouble(dataGridView2.Rows[i].Cells[5].Value));
rt.Robconf.FillFromString("[0,0,0,0]");
rt.Extax.FillFromString("[9E+09,9E+09,9E+09,9E+09,9E+09,9E+09]");
rd.WriteItem(rt, i);
}
tasks[taskint].SetProgramPointer("MainModule", "WeldingPath");
controller.Rapid.Start();
}
#endregion
}
#endregion
//-------------------------------------PLC人機按鈕部分---------------------------------------
}
}