1242 lines
31 KiB
C#
1242 lines
31 KiB
C#
using ACS.SPiiPlusNET;
|
|
using HexcalMC.Base;
|
|
using HexcalMC.Properties;
|
|
using System;
|
|
using System.Diagnostics;
|
|
using System.Runtime.InteropServices;
|
|
using System.Windows.Forms;
|
|
using Telerik.WinControls.UI;
|
|
|
|
// ACS .NET Library
|
|
|
|
namespace HexcalMC
|
|
{
|
|
public partial class Motion : System.Windows.Forms.Form
|
|
{
|
|
private const int MaxAxisCount = 32;
|
|
private const int MaxBufferCnt = 64;
|
|
|
|
private const int MaxUiLimitCnt = 8;
|
|
private const int MaxUiIoCnt = 8;
|
|
private readonly Api _acs;
|
|
private readonly int _motionTimeout = 50000; //延时时间
|
|
|
|
private readonly MainForm mainFrom;
|
|
|
|
private readonly Axis[] UseAxis = MainForm.UseAxis; //获取激活的轴
|
|
private MotionStates _currentMotionState = MotionStates.None; //运动状态
|
|
private Axis[] _mArrAxisList;
|
|
private Array _mArrReadVector;
|
|
|
|
private bool _mBConnected;
|
|
private Button[] _mBtnOutput;
|
|
|
|
//定义Jog运动 速度
|
|
private double _mJogVel = 10.0f;
|
|
|
|
private Label[] _mLblInput;
|
|
|
|
private Label[] _mLblLeftLimit; //左限位
|
|
private Label[] _mLblOutput;
|
|
private Label[] _mLblRightLimit; //右限位
|
|
private double _mLfRPos, _mLfFPos, _mLfPe, _mLfFvel; //参考位置,反馈位置 位置误差 反馈速度 double类型
|
|
|
|
// For update values
|
|
private MotorStates _mNMotorState; //运动状态
|
|
|
|
private ProgramStates _mNProgramState; //程序状态
|
|
|
|
private int _mNTotalAxis;
|
|
private int _mNTotalBuffer;
|
|
private int _mNValues, _mNOutputState;
|
|
private object _mObjReadVar;
|
|
|
|
public Motion(MainForm mainFrom)
|
|
{
|
|
InitializeComponent();
|
|
|
|
this.mainFrom = mainFrom; // 存储传递的主窗体对象
|
|
_acs = this.mainFrom._acs; //初始化 ACS运动控制类
|
|
|
|
_acs.PHYSICALMOTIONEND += ACS_PHYSICALMOTIONEND; // Register Event 注册时间
|
|
_acs.PROGRAMEND += ACS_PROGRAMEND;
|
|
}
|
|
|
|
private void BtnSetZero_Click(object sender, EventArgs e)
|
|
{
|
|
// Change current poisition as you want SetFPosition(Axis number, new position)
|
|
_acs.SetFPosition((Axis)cboAxisNo.SelectedIndex, 0);
|
|
}
|
|
|
|
#region 绝对运动
|
|
|
|
private void BtnPTP_Click(object sender, EventArgs e)
|
|
{
|
|
double lfTargetPos = 0.0f;
|
|
try
|
|
{
|
|
if (txtPTP_Pos.Text.Length > 0)
|
|
{
|
|
lfTargetPos = Convert.ToDouble(txtPTP_Pos.Text);
|
|
_acs.ToPoint(
|
|
0, // '0' - Absolute position
|
|
(Axis)cboAxisNo.SelectedIndex, // Axis number
|
|
lfTargetPos // Target position
|
|
);
|
|
}
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
MessageBox.Show(ex.Message, "ERROR", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
|
Debug.WriteLine(ex.Message);
|
|
}
|
|
}
|
|
|
|
#endregion 绝对运动
|
|
|
|
#region 通用IO
|
|
|
|
private void BtnSW_Click(object sender, EventArgs e)
|
|
{
|
|
int nBitNo = 0x01;
|
|
|
|
try
|
|
{
|
|
Button btn = sender as Button;
|
|
if (btn == null) return;
|
|
|
|
nBitNo = btn.TabIndex;
|
|
nBitNo = 0x01 << nBitNo; //左移几位
|
|
|
|
if ((_mNOutputState & nBitNo) != 0)
|
|
{
|
|
// Set only 1 bit
|
|
_acs.SetOutput(
|
|
0, // Port number
|
|
btn.TabIndex, // Bit number
|
|
0 // 0 = OFF, 1 = ON
|
|
);
|
|
|
|
// If your I/O device is EtherCAT type, you cannot use this function You can use
|
|
// WriteVariable function and Command function
|
|
//
|
|
// Ex) If EtherCAT mapped variable is 'EC_DOUT' Want to ON bit '3' _ACS.Command("EC_DOUT.3=1");
|
|
}
|
|
else
|
|
{
|
|
_acs.SetOutput(0, btn.TabIndex, 1);
|
|
}
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
Debug.WriteLine("btnSW_Click() Error\n" + ex);
|
|
}
|
|
}
|
|
|
|
#endregion 通用IO
|
|
|
|
#region 初始化
|
|
|
|
private void Form1_Load(object sender, EventArgs e)
|
|
{
|
|
//禁止通讯按钮
|
|
btnOpen.Enabled = false;
|
|
btnClose.Enabled = false;
|
|
|
|
_mLblLeftLimit = new Label[MaxUiLimitCnt]; //左限位
|
|
_mLblLeftLimit[0] = lblLL0;
|
|
_mLblLeftLimit[1] = lblLL1;
|
|
_mLblLeftLimit[2] = lblLL2;
|
|
_mLblLeftLimit[3] = lblLL3;
|
|
_mLblLeftLimit[4] = lblLL4;
|
|
_mLblLeftLimit[5] = lblLL5;
|
|
_mLblLeftLimit[6] = lblLL6;
|
|
_mLblLeftLimit[7] = lblLL7;
|
|
|
|
_mLblRightLimit = new Label[MaxUiLimitCnt]; //有限位
|
|
_mLblRightLimit[0] = lblRL0;
|
|
_mLblRightLimit[1] = lblRL1;
|
|
_mLblRightLimit[2] = lblRL2;
|
|
_mLblRightLimit[3] = lblRL3;
|
|
_mLblRightLimit[4] = lblRL4;
|
|
_mLblRightLimit[5] = lblRL5;
|
|
_mLblRightLimit[6] = lblRL6;
|
|
_mLblRightLimit[7] = lblRL7;
|
|
|
|
_mLblInput = new Label[MaxUiIoCnt];
|
|
_mLblInput[0] = lblIN0;
|
|
_mLblInput[1] = lblIN1;
|
|
_mLblInput[2] = lblIN2;
|
|
_mLblInput[3] = lblIN3;
|
|
_mLblInput[4] = lblIN4;
|
|
_mLblInput[5] = lblIN5;
|
|
_mLblInput[6] = lblIN6;
|
|
_mLblInput[7] = lblIN7;
|
|
|
|
_mLblOutput = new Label[MaxUiIoCnt];
|
|
_mLblOutput[0] = lblOUT0;
|
|
_mLblOutput[1] = lblOUT1;
|
|
_mLblOutput[2] = lblOUT2;
|
|
_mLblOutput[3] = lblOUT3;
|
|
_mLblOutput[4] = lblOUT4;
|
|
_mLblOutput[5] = lblOUT5;
|
|
_mLblOutput[6] = lblOUT6;
|
|
_mLblOutput[7] = lblOUT7;
|
|
|
|
_mBtnOutput = new Button[MaxUiIoCnt];
|
|
_mBtnOutput[0] = btnSW0;
|
|
_mBtnOutput[1] = btnSW1;
|
|
_mBtnOutput[2] = btnSW2;
|
|
_mBtnOutput[3] = btnSW3;
|
|
_mBtnOutput[4] = btnSW4;
|
|
_mBtnOutput[5] = btnSW5;
|
|
_mBtnOutput[6] = btnSW6;
|
|
_mBtnOutput[7] = btnSW7;
|
|
|
|
//m_nFault = new int[MAX_AXIS_COUNT];
|
|
//Array.Clear(m_nFault, 0, MAX_AXIS_COUNT);
|
|
_mNOutputState = 0;
|
|
|
|
// Clear connection list from SPiiPlus UserMode-Driver (UMD)
|
|
//TernminateUMD_Connection();
|
|
|
|
#region 副屏显示功能
|
|
|
|
// Screen[] screens = Screen.AllScreens; Screen secondaryScreen = screens.Length > 1 ?
|
|
// screens[1] : screens[0]; // 如果有多个屏幕,选择第二个屏幕作为副屏幕
|
|
//
|
|
// // 创建一个新的窗体实例 Form secondaryForm = new Form();
|
|
//
|
|
// // 设置窗体的位置和大小以适应副屏幕 secondaryForm.StartPosition = FormStartPosition.Manual;
|
|
// secondaryForm.Location = secondaryScreen.Bounds.Location; secondaryForm.Size = secondaryScreen.Bounds.Size;
|
|
//
|
|
// // 可选:设置副屏窗体的标题、样式等其他属性 secondaryForm.Text = "副屏窗体"; // ... 其他属性设置
|
|
//
|
|
// // 显示副屏窗体 secondaryForm.Show();
|
|
|
|
#endregion 副屏显示功能
|
|
|
|
#region 初始化
|
|
|
|
InitMotion();
|
|
|
|
#endregion 初始化
|
|
}
|
|
|
|
private void Motion_FormClosed(object sender, FormClosedEventArgs e)
|
|
{
|
|
tmrMonitor.Stop();
|
|
}
|
|
|
|
#endregion 初始化
|
|
|
|
#region 通讯建立
|
|
|
|
private void InitMotion()
|
|
{
|
|
string strTemp;
|
|
int i;
|
|
|
|
_mBConnected = _acs.IsConnected;
|
|
// Get Total number of axes
|
|
strTemp = _acs.Transaction("?SYSINFO(13)");
|
|
_mNTotalAxis = Convert.ToInt32(strTemp.Trim());
|
|
|
|
_mArrAxisList = new Axis[_mNTotalAxis + 1];
|
|
for (i = 0; i < _mNTotalAxis; i++)
|
|
{
|
|
cboAxisNo.Items.Add(i.ToString());
|
|
_mArrAxisList[i] = (Axis)i;
|
|
}
|
|
|
|
// Insert '-1' at the last
|
|
_mArrAxisList[_mNTotalAxis] = Axis.ACSC_NONE;
|
|
cboAxisNo.SelectedIndex = 0;
|
|
|
|
// Update current motion paramter to UI.
|
|
UpdateProfile();
|
|
|
|
strTemp = _acs.Transaction("?SYSINFO(10)");
|
|
_mNTotalBuffer = Convert.ToInt32(strTemp.Trim());
|
|
for (i = 0; i < _mNTotalBuffer; i++)
|
|
{
|
|
cboBufferNo.Items.Add(i.ToString());
|
|
}
|
|
|
|
cboBufferNo.SelectedIndex = 0;
|
|
|
|
// Set updating timer
|
|
tmrMonitor.Interval = 50;
|
|
tmrMonitor.Start();
|
|
}
|
|
|
|
private void BtnOpen_Click(object sender, EventArgs e)
|
|
{
|
|
//double lfTemp = 0.0f;
|
|
|
|
try
|
|
{
|
|
if (_acs.IsConnected)
|
|
{
|
|
DebugDfn.AddLogText("运动平台已连接");
|
|
}
|
|
|
|
InitMotion();
|
|
_mBConnected = true;
|
|
}
|
|
catch (COMException comex)
|
|
{
|
|
MessageBox.Show("Connection fail", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
|
Debug.WriteLine("Connection fail" + comex.Message);
|
|
|
|
_mBConnected = false;
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
MessageBox.Show(ex.Message, "ERROR", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
|
Debug.WriteLine(ex.Message);
|
|
}
|
|
}
|
|
|
|
private void BtnClose_Click(object sender, EventArgs e)
|
|
{
|
|
if (_mBConnected) _acs.CloseComm();
|
|
|
|
tmrMonitor.Stop();
|
|
|
|
btnOpen.Enabled = true;
|
|
btnClose.Enabled = false;
|
|
}
|
|
|
|
private void TernminateUMD_Connection()
|
|
{
|
|
try
|
|
{
|
|
string terminateExceptionConnName = "ACS.Framework.exe";
|
|
|
|
ACSC_CONNECTION_DESC[] connectionList = _acs.GetConnectionsList();
|
|
for (int index = 0; index < connectionList.Length; index++)
|
|
{
|
|
if (terminateExceptionConnName.CompareTo(connectionList[index].Application) != 0)
|
|
_acs.TerminateConnection(connectionList[index]);
|
|
}
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
Debug.WriteLine(ex.ToString());
|
|
}
|
|
}
|
|
|
|
#endregion 通讯建立
|
|
|
|
#region UI 刷新
|
|
|
|
/// <summary>
|
|
/// Update Motion Profile from Controller
|
|
/// </summary>
|
|
private void UpdateProfile()
|
|
{
|
|
if (_mBConnected)
|
|
{
|
|
txtVel.Text = _acs.GetVelocity((Axis)cboAxisNo.SelectedIndex).ToString();
|
|
txtAcc.Text = _acs.GetAcceleration((Axis)cboAxisNo.SelectedIndex).ToString();
|
|
txtDec.Text = _acs.GetDeceleration((Axis)cboAxisNo.SelectedIndex).ToString();
|
|
txtKdec.Text = _acs.GetKillDeceleration((Axis)cboAxisNo.SelectedIndex).ToString();
|
|
txtJerk.Text = _acs.GetJerk((Axis)cboAxisNo.SelectedIndex).ToString();
|
|
}
|
|
}
|
|
|
|
private void CboAxisNo_SelectedIndexChanged(object sender, EventArgs e)
|
|
{
|
|
UpdateProfile();
|
|
}
|
|
|
|
private void TmrMonitor_Tick(object sender, EventArgs e)
|
|
{
|
|
// Get selected axis number
|
|
int iAxisNo = cboAxisNo.SelectedIndex;
|
|
// Get selected buffer number
|
|
int iBufferNo = cboBufferNo.SelectedIndex;
|
|
|
|
if (_mBConnected)
|
|
{
|
|
try
|
|
{
|
|
_mNMotorState = _acs.GetMotorState((Axis)iAxisNo);
|
|
|
|
// Returned value is integer, you need to use bitmaks
|
|
if ((_mNMotorState & MotorStates.ACSC_MST_MOVE) != 0) lblMoving.Image = Resources.On;
|
|
else lblMoving.Image = Resources.Off; // 运动中
|
|
if ((_mNMotorState & MotorStates.ACSC_MST_INPOS) != 0) lblInPos.Image = Resources.On;
|
|
else lblInPos.Image = Resources.Off; // 就位
|
|
if ((_mNMotorState & MotorStates.ACSC_MST_ACC) != 0) lblAcc.Image = Resources.On;
|
|
else lblAcc.Image = Resources.Off; // 加速
|
|
if ((_mNMotorState & MotorStates.ACSC_MST_ENABLE) != 0) lblEnable.Image = Resources.On;
|
|
else lblEnable.Image = Resources.Off; // 使能
|
|
|
|
// Reference position ACSPL+ Variable : RPOS (real)
|
|
_mLfRPos = _acs.GetRPosition((Axis)iAxisNo); // 参考位置
|
|
|
|
// Feedback position (Encoder value) ACSPL+ Variable : FPO (real)
|
|
_mLfFPos = _acs.GetFPosition((Axis)iAxisNo); //反馈位置
|
|
|
|
// PE (Position Error) There is no function in library. We need to use
|
|
// ReadVariable function
|
|
_mLfPe = (double)_acs.ReadVariable("PE", ProgramBuffer.ACSC_NONE, iAxisNo, iAxisNo); //位置误差
|
|
|
|
// Feedback Velocity
|
|
_mLfFvel = (double)_acs.ReadVariable("FVEL", ProgramBuffer.ACSC_NONE, iAxisNo, iAxisNo); //实际速度
|
|
|
|
txtRPOS.Text = string.Format("{0:0.0000}", _mLfRPos);
|
|
txtFPOS.Text = string.Format("{0:0.0000}", _mLfFPos);
|
|
txtPE.Text = string.Format("{0:0.0000}", _mLfPe);
|
|
txtFVEL.Text = string.Format("{0:0.0000}", _mLfFvel);
|
|
|
|
// Program State 运动状态 State : Compiled, Running, Suspended, Autoroutine is
|
|
// running (ON syntax)
|
|
//
|
|
// ACSPL+ Variable : PST (integer)
|
|
_mNProgramState = _acs.GetProgramState((ProgramBuffer)iBufferNo);
|
|
if ((_mNProgramState & ProgramStates.ACSC_PST_RUN) != 0)
|
|
{
|
|
lblPRG_Status_LED.Image = Resources.On;
|
|
lblPRG_Status.Text = "Running";
|
|
}
|
|
else
|
|
{
|
|
lblPRG_Status_LED.Image = Resources.Off;
|
|
lblPRG_Status.Text = "Stop";
|
|
}
|
|
|
|
// Read left/right hardware limits state ACSPL+ Variable : FAULT (integer)
|
|
_mObjReadVar =
|
|
_acs.ReadVariableAsVector("FAULT", ProgramBuffer.ACSC_NONE, 0, _mNTotalAxis - 1);
|
|
if (_mObjReadVar != null)
|
|
{
|
|
_mArrReadVector = _mObjReadVar as Array;
|
|
if (_mArrReadVector != null)
|
|
{
|
|
for (int i = 0; i < _mNTotalAxis; i++)
|
|
{
|
|
UpdateLimitState(i, (int)_mArrReadVector.GetValue(i));
|
|
}
|
|
}
|
|
}
|
|
|
|
// Read digital input/output (Port means all of bits) If you want to read only 1
|
|
// bit (not an integer), use "GetInput" function
|
|
_mNValues = _acs.GetInputPort(0); // _ACS.ReadVariableAsVector("IN", -1, 0, 0, -1, -1);
|
|
UpdateIoState(_mNValues, true);
|
|
|
|
_mNOutputState = _acs.GetOutputPort(0); // _ACS.ReadVariableAsVector("OUT", -1, 0, 0, -1, -1);
|
|
UpdateIoState(_mNOutputState, false);
|
|
|
|
//刷新平台位置
|
|
UpdatePostion();
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
MessageBox.Show(ex.Message, "ERROR", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
|
Debug.WriteLine(ex.Message);
|
|
}
|
|
}
|
|
}
|
|
|
|
private void UpdateLimitState(int axisNo, int fault) //刷新限位状态
|
|
{
|
|
if (axisNo < MaxUiLimitCnt)
|
|
{
|
|
if ((fault & (int)SafetyControlMasks.ACSC_SAFETY_LL) != 0)
|
|
_mLblLeftLimit[axisNo].Image = Resources.Error;
|
|
else _mLblLeftLimit[axisNo].Image = Resources.Off;
|
|
if ((fault & (int)SafetyControlMasks.ACSC_SAFETY_RL) != 0)
|
|
_mLblRightLimit[axisNo].Image = Resources.Error;
|
|
else _mLblRightLimit[axisNo].Image = Resources.Off;
|
|
}
|
|
}
|
|
|
|
private void UpdateIoState(int value, bool isInput) //刷新IO状态
|
|
{
|
|
int bitUpCnt = 0x01;
|
|
|
|
for (int i = 0; i < MaxUiIoCnt; i++)
|
|
{
|
|
if (isInput)
|
|
{
|
|
// Input state
|
|
if ((value & bitUpCnt) != 0) _mLblInput[i].Image = Resources.On;
|
|
else _mLblInput[i].Image = Resources.Off;
|
|
}
|
|
else
|
|
{
|
|
// Output state
|
|
if ((value & bitUpCnt) != 0)
|
|
{
|
|
_mBtnOutput[i].Text = "OFF";
|
|
_mLblOutput[i].Image = Resources.On;
|
|
}
|
|
else
|
|
{
|
|
_mBtnOutput[i].Text = "ON";
|
|
_mLblOutput[i].Image = Resources.Off;
|
|
}
|
|
}
|
|
|
|
// 0x01 => 0x02 => 0x04 => 0x08 ... increase bit number
|
|
bitUpCnt = 0x01 << (i + 1);
|
|
}
|
|
}
|
|
|
|
private void UpdatePostion()
|
|
{
|
|
Point3D _mPoint3D = mainFrom._mPoint3D;
|
|
|
|
//更新实时位置
|
|
if (_mPoint3D != null)
|
|
{
|
|
lbl_X_current.Text = _mPoint3D.X.ToString("F3");
|
|
lbl_Y_current.Text = _mPoint3D.Y.ToString("F3");
|
|
lbl_z_current.Text = _mPoint3D.Z.ToString("F3");
|
|
}
|
|
|
|
//设置目标位置
|
|
lbl_X_target.Text = textBox_x.Text;
|
|
lbl_Y_target.Text = textBox_y.Text;
|
|
lbl_Z_target.Text = textBox_z.Text;
|
|
}
|
|
|
|
#endregion UI 刷新
|
|
|
|
#region 电机使能
|
|
|
|
private void BtnEnable_Click(object sender, EventArgs e)
|
|
{
|
|
// Enable selected axis
|
|
_acs.Enable((Axis)cboAxisNo.SelectedIndex);
|
|
|
|
// If you want to enable several axes,
|
|
//
|
|
// Ex) Eanble three axes (0, 1, 6)
|
|
//
|
|
// int[] AxisList = new int[] { 0, 1, 6, -1 }; !!!! Important !! Must insert '-1' at the
|
|
// last _ACS.EnableM(AxisList);
|
|
}
|
|
|
|
private void BtnDisable_Click(object sender, EventArgs e)
|
|
{
|
|
// Disable selected axis
|
|
_acs.Disable((Axis)cboAxisNo.SelectedIndex);
|
|
// Disable multi axes : DisableM(int[] axisList)
|
|
}
|
|
|
|
private void BtnDisableAll_Click(object sender, EventArgs e)
|
|
{
|
|
// Disable all of axes
|
|
_acs.DisableAll();
|
|
}
|
|
|
|
#endregion 电机使能
|
|
|
|
#region 相对移动
|
|
|
|
private void BtnPTP_R_Neg_Click(object sender, EventArgs e)
|
|
{
|
|
double lfTargetPos = 0.0f;
|
|
try
|
|
{
|
|
if (txtPTP_Pos.Text.Length > 0)
|
|
{
|
|
lfTargetPos = Convert.ToDouble(txtPTP_Pos.Text);
|
|
if (lfTargetPos > 0)
|
|
lfTargetPos = lfTargetPos * -1; // Target position (from current position, step move)
|
|
|
|
_acs.ToPoint(
|
|
MotionFlags.ACSC_AMF_RELATIVE, // Flat
|
|
(Axis)cboAxisNo.SelectedIndex, // Axis number
|
|
lfTargetPos // Move distance
|
|
);
|
|
}
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
MessageBox.Show(ex.Message, "ERROR", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
|
Debug.WriteLine(ex.Message);
|
|
}
|
|
}
|
|
|
|
private void BtnPTP_R_Pos_Click(object sender, EventArgs e)
|
|
{
|
|
double lfTargetPos = 0.0f;
|
|
try
|
|
{
|
|
if (txtPTP_Pos.Text.Length > 0)
|
|
{
|
|
lfTargetPos = Convert.ToDouble(txtPTP_Pos.Text);
|
|
if (lfTargetPos < 0) lfTargetPos = lfTargetPos * -1;
|
|
|
|
_acs.ToPoint(MotionFlags.ACSC_AMF_RELATIVE, (Axis)cboAxisNo.SelectedIndex, lfTargetPos);
|
|
}
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
MessageBox.Show(ex.Message, "ERROR", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
|
Debug.WriteLine(ex.Message);
|
|
}
|
|
}
|
|
|
|
#endregion 相对移动
|
|
|
|
#region 停止运动
|
|
|
|
private void BtnHalt_Click(object sender, EventArgs e)
|
|
{
|
|
try
|
|
{
|
|
_acs.Halt((Axis)cboAxisNo.SelectedIndex); //使用 halt 命令减速
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
MessageBox.Show(ex.Message, "ERROR", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
|
Debug.WriteLine(ex.Message);
|
|
}
|
|
}
|
|
|
|
private void BtnHallAll_Click(object sender, EventArgs e)
|
|
{
|
|
try
|
|
{
|
|
Axis[] m_arrAxisList = { Axis.ACSC_AXIS_0, Axis.ACSC_AXIS_1, Axis.ACSC_AXIS_8, Axis.ACSC_NONE };
|
|
|
|
if (_mArrAxisList != null) _acs.HaltM(m_arrAxisList);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
MessageBox.Show(ex.Message, "ERROR", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
|
Debug.WriteLine(ex.Message);
|
|
}
|
|
}
|
|
|
|
#endregion 停止运动
|
|
|
|
#region JOG 功能
|
|
|
|
// Move negative direction
|
|
private void BtnJogNeg_MouseDown(object sender, MouseEventArgs e)
|
|
{
|
|
double lfVelocity = 0.0f;
|
|
|
|
try
|
|
{
|
|
if (chkUseVel.Checked)
|
|
{
|
|
lfVelocity = Convert.ToDouble(txtJogVel.Text.Trim());
|
|
if (lfVelocity > 0) lfVelocity = lfVelocity * -1; // Negative direction : Using - (minus) velocity
|
|
|
|
_acs.Jog(
|
|
MotionFlags.ACSC_AMF_VELOCITY, // Velocity flag 速度标志
|
|
(Axis)cboAxisNo.SelectedIndex, // Axis number
|
|
lfVelocity // Velocity
|
|
);
|
|
}
|
|
else
|
|
{
|
|
_acs.Jog(0, (Axis)cboAxisNo.SelectedIndex, (double)GlobalDirection.ACSC_NEGATIVE_DIRECTION);
|
|
}
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
MessageBox.Show(ex.Message, "ERROR", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
|
Debug.WriteLine(ex.Message);
|
|
}
|
|
}
|
|
|
|
private void BtnJogPos_MouseDown(object sender, MouseEventArgs e)
|
|
{
|
|
double lfVelocity = 0.0f;
|
|
|
|
try
|
|
{
|
|
if (chkUseVel.Checked)
|
|
{
|
|
lfVelocity = Convert.ToDouble(txtJogVel.Text.Trim());
|
|
if (lfVelocity < 0) lfVelocity = lfVelocity * -1;
|
|
|
|
_acs.Jog(MotionFlags.ACSC_AMF_VELOCITY, (Axis)cboAxisNo.SelectedIndex, lfVelocity);
|
|
}
|
|
else
|
|
{
|
|
_acs.Jog(0, (Axis)cboAxisNo.SelectedIndex, (double)GlobalDirection.ACSC_POSITIVE_DIRECTION);
|
|
}
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
MessageBox.Show(ex.Message, "ERROR", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
|
Debug.WriteLine(ex.Message);
|
|
}
|
|
}
|
|
|
|
// Stop JOG motion
|
|
private void BtnJog_MouseUp(object sender, MouseEventArgs e)
|
|
{
|
|
_acs.Halt((Axis)cboAxisNo.SelectedIndex);
|
|
|
|
//自定义Jog
|
|
if (sender is Button button)
|
|
{
|
|
string btn_name = button.Name;
|
|
switch (btn_name)
|
|
{
|
|
case "btn_X_left":
|
|
_acs.Halt(Axis.ACSC_AXIS_1);
|
|
break;
|
|
|
|
case "btn_X_right":
|
|
_acs.Halt(Axis.ACSC_AXIS_1);
|
|
break;
|
|
|
|
case "btn_Y_Forward":
|
|
_acs.Halt(Axis.ACSC_AXIS_0);
|
|
break;
|
|
|
|
case "btn_Y_Back":
|
|
_acs.Halt(Axis.ACSC_AXIS_0);
|
|
break;
|
|
|
|
case "btn_Z_Up":
|
|
_acs.Halt(Axis.ACSC_AXIS_8);
|
|
break;
|
|
|
|
case "btn_Z_Down":
|
|
_acs.Halt(Axis.ACSC_AXIS_8);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
#endregion JOG 功能
|
|
|
|
#region 运行 Buffer Program
|
|
|
|
private void BtnRunBuffer_Click(object sender, EventArgs e)
|
|
{
|
|
string temp;
|
|
|
|
try
|
|
{
|
|
if (txtLabelName.Text.Length > 0)
|
|
{
|
|
temp = txtLabelName.Text.ToUpper();
|
|
// Allow _ (Under bar) or A ~ Z characters
|
|
if (temp[0] != 0x5F && (temp[0] < 0x41 || temp[0] > 0x5A))
|
|
{
|
|
MessageBox.Show("Wrong 'Label' name inputed.", "ERROR", MessageBoxButtons.OK,
|
|
MessageBoxIcon.Information);
|
|
return;
|
|
}
|
|
|
|
// Run buffer program from label position
|
|
_acs.RunBuffer((ProgramBuffer)cboBufferNo.SelectedIndex, txtLabelName.Text.Trim());
|
|
}
|
|
else
|
|
{
|
|
// Run buffer program from first line
|
|
_acs.RunBuffer((ProgramBuffer)cboBufferNo.SelectedIndex, null);
|
|
}
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
MessageBox.Show(ex.Message, "ERROR", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
|
Debug.WriteLine(ex.Message);
|
|
}
|
|
}
|
|
|
|
private void BtnStopBuffer_Click(object sender, EventArgs e)
|
|
{
|
|
// Stop program
|
|
_acs.StopBuffer((ProgramBuffer)cboBufferNo.SelectedIndex);
|
|
}
|
|
|
|
#endregion 运行 Buffer Program
|
|
|
|
#region 修改运动参数
|
|
|
|
private void TextBoxes_KeyPress(object sender, KeyPressEventArgs e)
|
|
{
|
|
try
|
|
{
|
|
double lfTemp = 0.0f;
|
|
TextBox textBox = sender as TextBox;
|
|
if (textBox != null)
|
|
{
|
|
// Allow numbers (0 ~ 9), . (DOT), Backspace
|
|
if ((e.KeyChar >= 0x30 && e.KeyChar <= 0x39) || e.KeyChar == 0x2E || e.KeyChar == 0x08 ||
|
|
e.KeyChar == (char)Keys.Return || e.KeyChar == (char)Keys.Enter)
|
|
{
|
|
if (e.KeyChar == 0x2E && textBox.Text.Contains(Convert.ToString(0x2E)))
|
|
e.KeyChar = (char)0x00;
|
|
if (e.KeyChar == (char)Keys.Return || e.KeyChar == (char)Keys.Enter)
|
|
{
|
|
e.Handled = true;
|
|
|
|
lfTemp = Convert.ToDouble(textBox.Text.Trim());
|
|
switch (textBox.TabIndex)
|
|
{
|
|
// Immediately change value (On the fly) : SetVelocityImm() Affect
|
|
// next motion : SetVelocity()
|
|
|
|
case 0:
|
|
_acs.SetVelocityImm((Axis)cboAxisNo.SelectedIndex, lfTemp);
|
|
break;
|
|
|
|
case 1:
|
|
_acs.SetAccelerationImm((Axis)cboAxisNo.SelectedIndex, lfTemp);
|
|
break;
|
|
|
|
case 2:
|
|
_acs.SetDecelerationImm((Axis)cboAxisNo.SelectedIndex, lfTemp);
|
|
break;
|
|
|
|
case 3:
|
|
_acs.SetKillDecelerationImm((Axis)cboAxisNo.SelectedIndex, lfTemp);
|
|
break;
|
|
|
|
case 4:
|
|
_acs.SetJerkImm((Axis)cboAxisNo.SelectedIndex, lfTemp);
|
|
break;
|
|
}
|
|
|
|
textBox.SelectAll();
|
|
}
|
|
}
|
|
else e.KeyChar = (char)0x00;
|
|
}
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
Debug.WriteLine("TextBoxes_KeyPress() Error\n" + ex);
|
|
}
|
|
}
|
|
|
|
private void TextBoxes_Enter(object sender, EventArgs e)
|
|
{
|
|
try
|
|
{
|
|
TextBox textBox = sender as TextBox;
|
|
if (textBox != null) textBox.SelectAll();
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
Debug.WriteLine("TextBoxes_Enter() Error\n" + ex);
|
|
}
|
|
}
|
|
|
|
private void TextBoxes_Leave(object sender, EventArgs e)
|
|
{
|
|
try
|
|
{
|
|
double lfTemp = 0.0f;
|
|
|
|
TextBox textBox = sender as TextBox;
|
|
if (textBox == null) return;
|
|
|
|
lfTemp = Convert.ToDouble(textBox.Text.Trim());
|
|
switch (textBox.TabIndex)
|
|
{
|
|
case 0:
|
|
_acs.SetVelocityImm((Axis)cboAxisNo.SelectedIndex, lfTemp);
|
|
break;
|
|
|
|
case 1:
|
|
_acs.SetAccelerationImm((Axis)cboAxisNo.SelectedIndex, lfTemp);
|
|
break;
|
|
|
|
case 2:
|
|
_acs.SetDecelerationImm((Axis)cboAxisNo.SelectedIndex, lfTemp);
|
|
break;
|
|
|
|
case 3:
|
|
_acs.SetKillDecelerationImm((Axis)cboAxisNo.SelectedIndex, lfTemp);
|
|
break;
|
|
|
|
case 4:
|
|
_acs.SetJerkImm((Axis)cboAxisNo.SelectedIndex, lfTemp);
|
|
break;
|
|
}
|
|
|
|
textBox.SelectAll();
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
Debug.WriteLine("TextBoxes_Leave() Error\n" + ex);
|
|
}
|
|
}
|
|
|
|
#endregion 修改运动参数
|
|
|
|
#region 事件回调
|
|
|
|
private void BtnEventMotionEnd_Click(object sender, EventArgs e)
|
|
{
|
|
_acs.PHYSICALMOTIONEND += ACS_PHYSICALMOTIONEND;
|
|
_acs.EnableEvent(Interrupts.ACSC_INTR_PHYSICAL_MOTION_END);
|
|
lstLog.Items.Add("PHYSICAL_MOTION_END event enabled");
|
|
}
|
|
|
|
private void ACS_PHYSICALMOTIONEND(AxisMasks axis)
|
|
{
|
|
int bit = 0x01;
|
|
int axisNo = 0;
|
|
// Param value is bit number Bit Number = Axis Number
|
|
for (int i = 0; i < 64; i++)
|
|
{
|
|
if ((int)axis == bit)
|
|
{
|
|
axisNo = i;
|
|
break;
|
|
}
|
|
|
|
bit = bit << 1;
|
|
}
|
|
|
|
// Add log to ListBox
|
|
if (lstLog.IsHandleCreated)
|
|
{
|
|
Invoke((MethodInvoker)delegate
|
|
{
|
|
lstLog.Items.Add(string.Format(" - Axis {0}, Stoppped", axisNo));
|
|
lstLog.SelectedIndex = lstLog.Items.Count - 1;
|
|
});
|
|
}
|
|
}
|
|
|
|
private void BtnEventProgramEnd_Click(object sender, EventArgs e)
|
|
{
|
|
//_ACS.PROGRAMEND += _ACS_PROGRAMEND;
|
|
_acs.EnableEvent(Interrupts.ACSC_INTR_PROGRAM_END);
|
|
lstLog.Items.Add("PROGRAM_END event enabled");
|
|
}
|
|
|
|
private void ACS_PROGRAMEND(BufferMasks buffer)
|
|
{
|
|
int bit = 0x01;
|
|
int bufferNo = 0;
|
|
// Param value is bit number Bit Number = Axis Number
|
|
for (int i = 0; i < 32; i++)
|
|
{
|
|
if ((int)buffer == bit)
|
|
{
|
|
bufferNo = i;
|
|
break;
|
|
}
|
|
|
|
bit = bit << 1;
|
|
}
|
|
|
|
// Add log to ListBox
|
|
Invoke((MethodInvoker)delegate
|
|
{
|
|
lstLog.Items.Add(string.Format(" - Buffer {0}, Stoppped", bufferNo));
|
|
lstLog.SelectedIndex = lstLog.Items.Count - 1;
|
|
});
|
|
}
|
|
|
|
#endregion 事件回调
|
|
|
|
#region 命令行响应
|
|
|
|
private void TxtCommand_KeyPress(object sender, KeyPressEventArgs e)
|
|
{
|
|
if (e.KeyChar == (char)Keys.Enter)
|
|
btnSend.PerformClick();
|
|
}
|
|
|
|
private void BtnSend_Click(object sender, EventArgs e)
|
|
{
|
|
string temp = string.Empty;
|
|
if (_mBConnected)
|
|
{
|
|
try
|
|
{
|
|
AppendTextToTextBox("> " + txtCommand.Text.Trim());
|
|
temp = _acs.Transaction(txtCommand.Text.Trim());
|
|
}
|
|
catch (ACSException ex)
|
|
{
|
|
temp = string.Format("?{0}", ex.ErrorCode);
|
|
}
|
|
finally
|
|
{
|
|
if (temp.Length > 0)
|
|
{
|
|
AppendTextToTextBox(temp);
|
|
AppendTextToTextBox(":");
|
|
}
|
|
}
|
|
|
|
txtCommand.Focus();
|
|
txtCommand.SelectAll();
|
|
}
|
|
}
|
|
|
|
private void AppendTextToTextBox(string text)
|
|
{
|
|
rtxtTerminal.AppendText(text);
|
|
rtxtTerminal.AppendText(Environment.NewLine);
|
|
rtxtTerminal.ScrollToCaret();
|
|
}
|
|
|
|
#endregion 命令行响应
|
|
|
|
#region 按钮
|
|
|
|
private void Btn_MovePose_Click(object sender, EventArgs e)
|
|
{
|
|
//判断是否为textBox_x空
|
|
if (string.IsNullOrWhiteSpace(textBox_x.Text) || string.IsNullOrEmpty(textBox_y.Text) ||
|
|
string.IsNullOrEmpty(textBox_z.Text))
|
|
{
|
|
MessageBox.Show("输入文本框为空,请修改", "警告");
|
|
return;
|
|
}
|
|
|
|
//获取 textBox_x 的值
|
|
double x = double.Parse(textBox_x.Text);
|
|
double y = double.Parse(textBox_y.Text);
|
|
double z = double.Parse(textBox_z.Text);
|
|
Point3D _point3D = new Point3D(x, y, z);
|
|
|
|
if (MainForm.IsWithinLimit(_point3D)) //判断点是否在行程范围内
|
|
{
|
|
double[] pointsArray =
|
|
{
|
|
_point3D.X,
|
|
_point3D.Y,
|
|
_point3D.Z
|
|
};
|
|
|
|
//判断电机状态
|
|
if (!mainFrom.totalAxisEnabled)
|
|
{
|
|
DebugDfn.AddLogText("存在电机未使能");
|
|
|
|
_acs.EnableM(UseAxis);
|
|
for (int i = 0; i < UseAxis.Length; i++)
|
|
{
|
|
_acs.WaitMotorEnabled(UseAxis[i], 1, _motionTimeout); //等待电机使能
|
|
}
|
|
|
|
DebugDfn.AddLogText("电机已启用");
|
|
}
|
|
|
|
//执行运动指令
|
|
_acs.ToPointM(MotionFlags.ACSC_NONE, UseAxis, pointsArray); //多轴运动到指定位置
|
|
}
|
|
else
|
|
{
|
|
DebugDfn.AddLogText("目标位置超出行程范围,请重新设置");
|
|
MessageBox.Show("目标位置超出行程范围,请重新设置", "异常", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
|
}
|
|
}
|
|
|
|
private void btn_home_Click(object sender, EventArgs e) //回零
|
|
{
|
|
double[] pointsArray =
|
|
{
|
|
0,
|
|
0,
|
|
0
|
|
};
|
|
|
|
//判断电机状态
|
|
if (!mainFrom.totalAxisEnabled)
|
|
{
|
|
DebugDfn.AddLogText("存在电机未使能");
|
|
|
|
_acs.EnableM(UseAxis);
|
|
for (int i = 0; i < UseAxis.Length; i++)
|
|
{
|
|
_acs.WaitMotorEnabled(UseAxis[i], 1, _motionTimeout); //等待电机使能
|
|
}
|
|
|
|
DebugDfn.AddLogText("电机已启用");
|
|
}
|
|
|
|
//执行运动指令
|
|
_acs.ToPointM(MotionFlags.ACSC_NONE, UseAxis, pointsArray); //多轴运动到指定位置
|
|
|
|
//等待运动完成
|
|
for (int i = 0; i < UseAxis.Length - 1; i++)
|
|
{
|
|
_acs.WaitMotionEnd(UseAxis[i], _motionTimeout); //等待回家完成
|
|
}
|
|
|
|
_currentMotionState = MotionStates.InPos;
|
|
DebugDfn.AddLogText("运动到位");
|
|
}
|
|
|
|
private void btn_X_left_MouseDown(object sender, MouseEventArgs e)
|
|
{
|
|
try
|
|
{
|
|
if (chkUseVel.Checked)
|
|
{
|
|
_mJogVel = Convert.ToDouble(txtJogVel.Text.Trim());
|
|
if (_mJogVel > 0) _mJogVel = _mJogVel * -1; // Negative direction : Using - (minus) velocity
|
|
DebugDfn.AddLogText("X左移速度: " + _mJogVel);
|
|
|
|
_acs.Jog(
|
|
MotionFlags.ACSC_AMF_VELOCITY, // Velocity flag 速度标志
|
|
Axis.ACSC_AXIS_1, // Axis number
|
|
_mJogVel // Velocity
|
|
);
|
|
}
|
|
else
|
|
{
|
|
_acs.Jog(0, Axis.ACSC_AXIS_1, (double)GlobalDirection.ACSC_NEGATIVE_DIRECTION);
|
|
}
|
|
}
|
|
catch (Exception exception)
|
|
{
|
|
DebugDfn.AddLogText("X左移异常" + exception);
|
|
}
|
|
}
|
|
|
|
private void btn_X_right_MouseDown(object sender, MouseEventArgs e)
|
|
{
|
|
try
|
|
{
|
|
if (chkUseVel.Checked)
|
|
{
|
|
_mJogVel = Convert.ToDouble(txtJogVel.Text.Trim());
|
|
|
|
_acs.Jog(
|
|
MotionFlags.ACSC_AMF_VELOCITY, // Velocity flag 速度标志
|
|
Axis.ACSC_AXIS_1, // Axis number
|
|
_mJogVel // Velocity
|
|
);
|
|
|
|
DebugDfn.AddLogText("X右移速度: " + _mJogVel);
|
|
}
|
|
else
|
|
{
|
|
_acs.Jog(0, Axis.ACSC_AXIS_1, (double)GlobalDirection.ACSC_POSITIVE_DIRECTION);
|
|
}
|
|
}
|
|
catch (Exception exception)
|
|
{
|
|
DebugDfn.AddLogText("X左移异常" + exception);
|
|
}
|
|
}
|
|
|
|
private void btn_Y_Forward_MouseDown(object sender, MouseEventArgs e)
|
|
{
|
|
try
|
|
{
|
|
if (chkUseVel.Checked)
|
|
{
|
|
_mJogVel = Convert.ToDouble(txtJogVel.Text.Trim());
|
|
if (_mJogVel > 0) _mJogVel = _mJogVel * -1; // Negative direction : Using - (minus) velocity
|
|
|
|
_acs.Jog(
|
|
MotionFlags.ACSC_AMF_VELOCITY, // Velocity flag 速度标志
|
|
Axis.ACSC_AXIS_0, // Axis number
|
|
_mJogVel // Velocity
|
|
);
|
|
DebugDfn.AddLogText("Y前移速度: " + _mJogVel);
|
|
}
|
|
else
|
|
{
|
|
_acs.Jog(0, Axis.ACSC_AXIS_0, (double)GlobalDirection.ACSC_NEGATIVE_DIRECTION);
|
|
}
|
|
}
|
|
catch (Exception exception)
|
|
{
|
|
DebugDfn.AddLogText("Y前移异常" + exception);
|
|
}
|
|
}
|
|
|
|
private void btn_Y_Back_MouseDown(object sender, MouseEventArgs e)
|
|
{
|
|
try
|
|
{
|
|
if (chkUseVel.Checked)
|
|
{
|
|
_mJogVel = Convert.ToDouble(txtJogVel.Text.Trim());
|
|
|
|
_acs.Jog(
|
|
MotionFlags.ACSC_AMF_VELOCITY, // Velocity flag 速度标志
|
|
Axis.ACSC_AXIS_0, // Axis number
|
|
_mJogVel // Velocity
|
|
);
|
|
|
|
DebugDfn.AddLogText("Y后移速度: " + _mJogVel);
|
|
}
|
|
else
|
|
{
|
|
_acs.Jog(0, Axis.ACSC_AXIS_0, (double)GlobalDirection.ACSC_POSITIVE_DIRECTION);
|
|
}
|
|
}
|
|
catch (Exception exception)
|
|
{
|
|
DebugDfn.AddLogText("Y后移异常" + exception);
|
|
}
|
|
}
|
|
|
|
private void btn_Z_Down_MouseDown(object sender, MouseEventArgs e)
|
|
{
|
|
try
|
|
{
|
|
if (chkUseVel.Checked)
|
|
{
|
|
_mJogVel = Convert.ToDouble(txtJogVel.Text.Trim());
|
|
if (_mJogVel > 0) _mJogVel = _mJogVel * -1; // Negative direction : Using - (minus) velocity
|
|
|
|
_acs.Jog(
|
|
MotionFlags.ACSC_AMF_VELOCITY, // Velocity flag 速度标志
|
|
Axis.ACSC_AXIS_8, // Axis number
|
|
_mJogVel // Velocity
|
|
);
|
|
|
|
DebugDfn.AddLogText("Z向下速度: " + _mJogVel);
|
|
}
|
|
else
|
|
{
|
|
_acs.Jog(0, Axis.ACSC_AXIS_8, (double)GlobalDirection.ACSC_NEGATIVE_DIRECTION);
|
|
}
|
|
}
|
|
catch (Exception exception)
|
|
{
|
|
DebugDfn.AddLogText("Z向下异常" + exception);
|
|
}
|
|
}
|
|
|
|
private void btn_Z_Up_MouseDown(object sender, MouseEventArgs e)
|
|
{
|
|
try
|
|
{
|
|
if (chkUseVel.Checked)
|
|
{
|
|
_mJogVel = Convert.ToDouble(txtJogVel.Text.Trim());
|
|
|
|
_acs.Jog(
|
|
MotionFlags.ACSC_AMF_VELOCITY, // Velocity flag 速度标志
|
|
Axis.ACSC_AXIS_8, // Axis number
|
|
_mJogVel // Velocity
|
|
);
|
|
|
|
DebugDfn.AddLogText("Z向上速度: " + _mJogVel);
|
|
}
|
|
else
|
|
{
|
|
_acs.Jog(0, Axis.ACSC_AXIS_8, (double)GlobalDirection.ACSC_POSITIVE_DIRECTION);
|
|
}
|
|
}
|
|
catch (Exception exception)
|
|
{
|
|
DebugDfn.AddLogText("Z向上异常" + exception);
|
|
}
|
|
}
|
|
|
|
#endregion 按钮
|
|
}
|
|
} |