Files
LM-Middleware/HexcalMC/MainFrom.cs
T
2024-03-04 17:00:32 +08:00

1011 lines
27 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
using System;
using System.Collections.Generic;
using System.IO;
using System.Windows.Forms;
using ACS.SPiiPlusNET;
using HexcalMC.Base;
using HexcalMC.Form;
using HexcalMC.Hexcal;
using HexcalMC.Properties;
using SharpGL;
using Telerik.WinControls.UI;
namespace HexcalMC
{
//定一个 回家状态枚举,包括 从未回家,正在回家,已经回家
public enum HomeStates
{
None, //默认状态
NotHome,
Homing,
Homed
}
//定义 运动状态枚举,包括 正在运动,运动到位,Jog运动
public enum MotionStates
{
None, //默认状态
Moving,
InPos,
Jogging
}
public partial class MainFrom : RadRibbonForm
{
private readonly List<Point3D> _pointCloud = new List<Point3D>(); //运动中点集合
public MainFrom()
{
InitializeComponent();
#region 3D
//var sharpGlViewportControl = new SharpGLViewportControl
//{
// Dock = DockStyle.Fill
//};
//var tabPage = new TabPage("3D 窗口");
//tabPage.Controls.Add(sharpGlViewportControl);
//tabControl1.TabPages.Add(tabPage);
//// 设置容器控件的 DoubleBuffered 属性为 true
//DoubleBuffered = true;
//// 创建一个包含点云数据的列表
//var points = new List<Point3D>
//{
// new Point3D(0, 0, 0),
// new Point3D(1, 1, 1),
// new Point3D(-1, -1, -1)
// // 可以添加更多的点云数据
//};
//// 将点云数据传递给 SharpGLViewportControl
//sharpGlViewportControl.SetPointCloud(points);
tabControl1.TabPages.RemoveAt(1);
#endregion
}
private void MainFrom_Load(object sender, EventArgs e)
{
FormBorderStyle = FormBorderStyle.FixedSingle; // 设置窗体边框样式为固定大小
MaximizeBox = false; // 禁用窗体的最大化按钮
DebugDfn.textBox_Msg = TextBoxMsg;
//加载配置文件
LoadConfig();
_acs = new Api(); //初始化 ACS运动控制类
//启动界面刷新
timer_RefreshUI.Start();
this.TopMost = true;
}
private void MainFrom_Shown(object sender, EventArgs e) //窗体显示准备好接受用户输入时发生
{
//启动服务端,用于接收hexcal传来的指令
StartServer();
Btn_ACSStart_Click(null, null);
//Plot3D();
}
private void MainFrom_FormClosed(object sender, FormClosedEventArgs e)
{
MyBase.TraceWriteLine("关闭程序");
DebugDfn._strEndTime = DateTime.Now.ToString("yyyy.MM.dd HH-mm-ss");
timer_RefreshUI.Stop();
string copyFileName = DebugDfn.StrDebugSavePath + "\\Debug(" + DebugDfn._strStartTime + " To " +
DebugDfn._strEndTime + ")" + ".txt";
if (!File.Exists(DebugDfn.StrDebugSavePath))
{
//创建文件夹 DebugDfn.StrDebugSavePath
Directory.CreateDirectory(DebugDfn.StrDebugSavePath);
}
File.Copy(DebugDfn.StrDebugFile, copyFileName);
if (Errors.ErrorWrite != null)
Errors.ErrorWrite.Close();
if (Errors.OtherWrite != null)
Errors.OtherWrite.Close();
if (Errors.StatusWrite != null)
Errors.StatusWrite.Close();
}
private void LoadConfig() //加载配置文件
{
//判断配置文件是否存在
if (!File.Exists(StrConfigFile))
{
MessageBox.Show("配置文件不存在,请检查配置文件", "异常", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
MOTION_SPEED = FileIni.ReadDouble(StrConfigFile, "MOTOR", "MOTION_SPEED"); //运动定位速度
//正限位
X_MAXSTROKESW = FileIni.ReadDouble(StrConfigFile, "MOTOR", "X_MAXSTROKESW");
Y_MAXSTROKESW = FileIni.ReadDouble(StrConfigFile, "MOTOR", "Y_MAXSTROKESW");
Z_MAXSTROKESW = FileIni.ReadDouble(StrConfigFile, "MOTOR", "Z_MAXSTROKESW");
//负限位
X_MINSTROKESW = FileIni.ReadDouble(StrConfigFile, "MOTOR", "X_MINSTROKESW");
Y_MINSTROKESW = FileIni.ReadDouble(StrConfigFile, "MOTOR", "Y_MINSTROKESW");
Z_MINSTROKESW = FileIni.ReadDouble(StrConfigFile, "MOTOR", "Z_MINSTROKESW");
}
private void Plot2D(List<Point3D> pointCloud)
{
// 清空画布
formsPlot1.Plot.Clear();
//pointCloud 是否为空
if (pointCloud.Count <= 0)
{
return;
}
List<double> dataX = new List<double>();
List<double> dataY = new List<double>();
foreach (Point3D point3D in pointCloud)
{
dataX.Add(point3D.X);
dataY.Add(point3D.Y);
}
formsPlot1.Plot.AddScatter(dataX.ToArray(), dataY.ToArray());
formsPlot1.Refresh();
}
private void Plot3D() //绘制3D图
{
List<Point3D> points = new List<Point3D>();
// 假设已经有了一些点的数据,将其添加到 List<Point3D> 对象中
points.Add(new Point3D(1, 2, 3));
points.Add(new Point3D(4, 5, 6));
LoadPoints(points);
}
#region
private Api _acs;
private const int MaxUiLimitCnt = 8;
private const int MaxUiIoCnt = 8;
private readonly int _mNTotalAxis = 0;
private int _mNTotalBuffer = 0;
private Axis[] _mArrAxisList = null;
private bool _mAcsConnected; //ACS通讯状态
// For update values
private MotorStates _mNMotorState; //运动状态
private ProgramStates _mNProgramState; //程序状态
private object _mObjReadVar;
private Array _mArrReadVector;
private double _mLfRPos, _mLfFPos, _mLfPe, _mLfFvel; //参考位置,反馈位置 位置误差 反馈速度 double类型
private int _mNValues, _mNOutputState;
private Label[] _mLblLeftLimit; //左限位
private Label[] _mLblRightLimit; //右限位
private HomeStates _homeStates; //回家状态
private MotionStates _currentMotionState; //当前运动状态
private readonly int _motionTimeout = 50000; //定义运动超时时间
public static Axis[] USE_AXIS =
{ Axis.ACSC_AXIS_1, Axis.ACSC_AXIS_0, Axis.ACSC_AXIS_8, Axis.ACSC_NONE }; //定义启用的轴,后面运动时会使用
//定义 XYZ三个轴的左右行程范围
public string StrConfigFile = Application.StartupPath + "\\File\\config.ini";
public static double MOTION_SPEED = 60;
public static double X_MAXSTROKESW = 730; //正限位
public static double Y_MAXSTROKESW = 1000;
public static double Z_MAXSTROKESW = 5;
public static double X_MINSTROKESW = -30; //负限位
public static double Y_MINSTROKESW = -10;
public static double Z_MINSTROKESW = -280;
#endregion
#region hexcal变量区
private TcpIpServer _mTcpIpServer; //创建tcpserver,用于接收hexcal传来的指令,并解析传递平台
private bool _mBHexcalConnected;
#endregion
#region hexcal软件交互
private void StartServer()
{
// 对_mTcpIpServer增加判断是否已经启动且存在设备连接
if (_mTcpIpServer != null)
{
//弹窗提醒已经启动
MessageBox.Show("TCP服务端已经启动,请勿重复启动", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
return;
}
//启动服务器,并获取数据,解析
_mTcpIpServer = new TcpIpServer("100.0.0.1", Convert.ToString(1234));
_mTcpIpServer.UseMode = 1; //设置通讯返回数据流格式
try
{
//启动监听
if (_mTcpIpServer.StartListen())
{
//绑定两个事件 OnRaisedStatus 和OnRaisedMessage
_mTcpIpServer.OnRaisedMessage += ReceiveMessage; //接收消息回调
_mTcpIpServer.OnRaisedStatus += ReceiveStatus; //连接状态
_mTcpIpServer.DataReceived += ReceiveByte;
DebugDfn.AddLogText("TCP服务端启动成功 ");
}
else
{
MessageBox.Show("TCP服务端启动失败,请检查网络连接,重新打开软件", "异常", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
catch (Exception ex)
{
DebugDfn.AddLogText("启动TCP服务端异常" + ex);
}
}
private void ReceiveByte(object sender, byte[] e)
{
DebugDfn.AddLogText("接收到" + BitConverter.ToString(e));
}
private void ReceiveMessage(string clientIp, string msg) //接收的内容
{
//打印ClientIP 和 Msg
DebugDfn.AddLogText("接收到" + clientIp + ": " + msg);
//根据源地址的不同,执行不同处理
string sourceIp = clientIp.Split(':')[0];
switch (sourceIp)
{
case "100.0.0.1": //L2系统
//解析处理数据
ParseHexcalMsg(msg);
break;
default:
DebugDfn.AddLogText("未知来源,没有应答");
break;
}
}
public static string ConstructString(string variableName, double[] values)
{
string result = variableName + " ";
for (int i = 0; i < values.Length; i++)
{
result += values[i].ToString("F6");
if (i < values.Length - 1)
{
result += ", ";
}
}
return result;
}
public static string ConstructPosString(Point3D point)
{
double[] values = { point.X, point.Y, point.Z, 0.0, 0.0, 0.0, 0.0 };
return ConstructString("POS", values);
}
public static Point3D ParsePoint3DFromCommand(string input)
{
string[] parts = input.Split(' ')[1].Split(',');
if (parts.Length >= 3)
{
double x = double.Parse(parts[0]);
double y = double.Parse(parts[1]);
double z = double.Parse(parts[2]);
return new Point3D(x, y, z);
}
throw new ArgumentException("输入字符串格式不正确。");
}
private void CheckPlatformStatus()
{
if (_currentMotionState == MotionStates.None || _currentMotionState == MotionStates.InPos) //默认或到位
{
SendMsgToHexcal("READY");
}
else
{
SendMsgToHexcal("BUSY");
}
}
private void ParseHexcalMsg(string msg) //编写一个Hexcal协议解析函数
{
DebugDfn.AddLogText("正在解析 " + msg);
//去除Msg中\r\n
msg = msg.Replace("\r\n", "");
//判断是否含有故障ERROR字样
if (msg.Contains("ERROR")) return;
if (msg.Contains("\x02") || msg.Contains("\u0002"))
{
CheckPlatformStatus();
}
else if (msg.Contains("\x03") || msg.Contains("\u0003"))
{
CheckPlatformStatus();
}
else if (msg.Contains("^B")) //查询状态, READY或BUSY
{
CheckPlatformStatus();
}
else if (msg.Contains("CMMTYP")) //测量机类型
{
SendMsgToHexcal("CMMTYP MA 19617, FDC V15.00, 6 6 2 , 0");
}
else if (msg.Contains("VERSION")) //版本号
{
SendMsgToHexcal("00-000-000-00000 FDC V51.04.0000 DATE: 12/21/22 TIME: 12:50:55");
}
else if (msg.Contains("SHOW MAXSTROKESW")) //最大行程,根据实际情况填写
{
//SendMsgToHexcal("MAXSTROKESW 233.200000,346.500000,15.100000,0.000000,0.000000,0.000000,0.000000");
double[] values = { X_MAXSTROKESW, Y_MAXSTROKESW, Z_MAXSTROKESW, 0.0, 0.0, 0.0, 0.0 };
string resultString = ConstructString("MAXSTROKESW", values);
SendMsgToHexcal(resultString);
}
else if (msg.Contains("SHOW MINSTROKESW")) //最小行程,根据实际情况填写
{
//SendMsgToHexcal("MINSTROKESW -68.800000,-55.500000,-286.900000,0.000000,0.000000,0.000000,0.000000");
double[] values = { X_MINSTROKESW, Y_MINSTROKESW, Z_MINSTROKESW, 0.0, 0.0, 0.0, 0.0 };
string resultString = ConstructString("MINSTROKESW", values);
SendMsgToHexcal(resultString);
}
else if (msg.Contains("SHOW MAXVEL")) //最大速度
{
SendMsgToHexcal("MAXVEL 300.000000,300.000000,300.000000,0.000000,0.000000,0.000000,0.000000,0.000000");
}
else if (msg.Contains("SHOW MAXACC")) //最大加速度
{
SendMsgToHexcal(
"MAXACC 300.000000,300.000000,300.000000,0.000000,0.000000,0.000000,0.000000,0.000000");
}
else if (msg.Contains("SHOW SENSWKP"))
{
SendMsgToHexcal("X_ SENSWKP 4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0");
}
else if (msg.Contains("SHOW X_SENSAXIS"))
{
SendMsgToHexcal("X_SENSAXIS 6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0");
}
else if (msg.Contains("SHOW Y_SENSAXIS")) //查询Y轴
{
SendMsgToHexcal("Y_SENSAXIS 2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0");
}
else if (msg.Contains("SHOW Z_SENSAXIS")) //查询Z轴
{
SendMsgToHexcal("Z_SENSAXIS 7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0");
}
else if (msg.Contains("SHOW TEMPCOMPTYPE")) //温度补偿,温度补偿 >1 表示支持温度补偿
{
SendMsgToHexcal("TEMPCOMPTYPE 1");
}
else if (msg.Contains("READTP"))
{
SendMsgToHexcal("READTP 0.000000");
}
else if (msg.Contains("SHOW ESTOP")) //查询急停状态,根据真是情况调整
{
SendMsgToHexcal("ESTOP FALSE");
}
else if (msg.Contains("CMHWST"))
{
SendMsgToHexcal("CMHWST 8257,0,1792,0");
}
else if (msg.Contains("SHOW MOVPAR")) //查询速度
{
SendMsgToHexcal(
"MOVPAR 300.000000,300.000000,300.000000,0.000000,0.000000,0.000000,0.000000,0.000000,0.000000,0.00000 0,0.000000");
}
else if (msg.Contains("SHOW MAXVEL")) //查询最大速度
{
SendMsgToHexcal("MAXVEL 300.000000,300.000000,300.000000,0.000000,0.000000,0.000000,0.000000,0.000000");
}
else if (msg.Contains("SHOW ACCEL")) //查询加速度
{
SendMsgToHexcal(
"ACCEL 1000.000000,1000.000000,1000.000000,0.000000,0.000000,0.000000,0.000000,0.000000");
}
else if (msg.Contains("MOVPAR")) //设置速度 xyz 轴的速度
{
SendMsgToHexcal("%");
}
else if (msg.Contains("ACCEL")) //设置加速度
{
SendMsgToHexcal("%");
}
else if (msg.Contains("PRBPIN")) //设置侧头偏置
{
SendMsgToHexcal("%");
}
else if (msg.Contains("ENABLE TEMP")) //设置温度补偿
{
SendMsgToHexcal("%");
}
else if (msg.Contains("WKPPAR"))
{
SendMsgToHexcal("%");
}
else if (msg.Contains("SCLTMP"))
{
SendMsgToHexcal("%");
}
else if (msg.Contains("AUTZER")) //回家指令
{
SendMsgToHexcal("%"); //收到并执行,同时状态改为忙碌
//执行回家
Ishome();
}
else if (msg.Contains("MOVABS")) //移动指令,解析移动位置
{
//收到指令 ,形如 MOVABS 0.015000,127.172997,-114.897003,0.000000\r\n
SendMsgToHexcal("%");
Point3D point = ParsePoint3DFromCommand(msg);
SetPositionXyz(point); //开始移动
_pointCloud.Add(point); //添加到点集合
}
else if (msg.Contains("GETPOS")) //获取位置
{
//SendMsgToHexcal("POS 167.553898,-55.400421,-208.548678,0.000000,0.000000,0.000000,0.000000");
Point3D point3D = GetPositionXyz(); //获取当前位置
string resultString = ConstructPosString(point3D);
SendMsgToHexcal(resultString);
}
else
{
DebugDfn.AddLogText("未知命令,没有应答");
}
}
private void ReceiveStatus(TcpIpServer.EnumTcpIpServer iType, string msg)
{
//记录到日志
DebugDfn.AddLogText(iType + " : " + msg);
//根据连接状态,更新界面
switch (iType)
{
case TcpIpServer.EnumTcpIpServer.ClientConnect:
_mBHexcalConnected = true;
break;
default:
_mBHexcalConnected = false;
break;
}
}
private void SendMsgToHexcal(string msg)
{
//发送数据
DebugDfn.AddLogText("回复 " + msg);
_mTcpIpServer.SendMessageToAllClients(msg += "\r\n"); //回复内容末尾加上\r\n,协议要求
}
private void Btn_StartServer_Click(object sender, EventArgs e)
{
StartServer();
}
private void Btn_StopServer_Click(object sender, EventArgs e)
{
//关闭服务端
if (_mTcpIpServer != null)
{
_mTcpIpServer.StopListen();
}
}
#endregion
#region ACS平台相关
private void BtnEnable_Click(object sender, EventArgs e) //使能所有轴
{
if (_mAcsConnected)
{
//!!!! Important !! Must insert '-1' at the last
_acs.EnableM(USE_AXIS);
}
else
{
//弹窗提醒尚未连接
MessageBox.Show("未连接到运动平台,请先点击连接");
}
}
private void BtnDisable_Click(object sender, EventArgs e) //轴取消
{
// Disable all of axes
_acs.DisableAll();
}
private void TmrMonitor_Tick(object sender, EventArgs e) //用于刷新状态
{
int iAxisNo = cboAxisNo.SelectedIndex;
if (_mAcsConnected)
{
try
{
// Get Motor State ACSPL+ Variable : MST (integer)
_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;
_currentMotionState = MotionStates.Moving;
}
else
{
lblMoving.Image = Resources.Off;
}
// 就位
if ((_mNMotorState & MotorStates.ACSC_MST_INPOS) != 0)
{
lblInPos.Image = Resources.On;
_currentMotionState = MotionStates.InPos;
}
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;
}
}
catch (Exception ex)
{
DebugDfn.AddLogText("ACS平台刷新异常" + ex);
MessageBox.Show(ex.Message, "ERROR", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
}
private void Btn_ACSStart_Click(object sender, EventArgs e) //连接
{
btn_ACSStart.Enabled = false;
btn_ACSStop.Enabled = true;
try
{
_acs.OpenCommEthernetTCP(
txtIP.Text, // IP Address (Default : 10.0.0.100)
Convert.ToInt32(txtPort.Text.Trim())); // TCP/IP Port nubmer (default : 701)
_mAcsConnected = true;
}
catch (Exception ex)
{
DebugDfn.AddLogText("ACS平台连接异常" + ex);
MessageBox.Show(ex.Message, "ERROR", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
// 启动定时器
tmrMonitor.Interval = 50;
tmrMonitor.Start();
//运动相关初始化操作
InitMotion();
}
private void Btn_ACSStop_Click(object sender, EventArgs e) //断开连接
{
if (_mAcsConnected) _acs.CloseComm();
tmrMonitor.Stop();
btn_ACSStart.Enabled = true;
btn_ACSStop.Enabled = false;
}
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 Ishome() //读取回家状态,当未回家时执行回家指令
{
// 1、连接状态检查,如果未连接,提示
if (!_mAcsConnected)
{
DebugDfn.AddLogText("[Ishome] ACS平台未连接,请先点击连接");
MessageBox.Show("ACS平台未连接,请先点击连接", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
return;
}
// 2、回家状态检查是否已经回家
if (_mAcsConnected && _homeStates == HomeStates.Homed)
{
//弹窗提示
MessageBox.Show("轴已经回家", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
return;
}
// 3、读取回家状态
if (_acs != null && _mAcsConnected)
{
var yawHome = _acs.ReadVariable("YAW_HOME_DONE");
if (Convert.ToBoolean(yawHome))
{
//弹窗提示
MessageBox.Show("轴已经回家", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
_homeStates = HomeStates.Homed;
return;
}
// 4、执行回家指令,弹窗等待用户确认
DialogResult result = MessageBox.Show("轴未回家,即将执行回家指令", "提示", MessageBoxButtons.OK,
MessageBoxIcon.Information);
if (result == DialogResult.OK)
{
// 在这里执行接下来的操作,例如回家指令
_acs.RunBuffer(ProgramBuffer.ACSC_BUFFER_6, null); //执行回家指令,这里的buffer6是回家指令的buffer
_homeStates = HomeStates.Homing;
_currentMotionState = MotionStates.Moving;
DebugDfn.AddLogText("回家运动中");
//等待回家完成
for (int i = 0; i < USE_AXIS.Length; i++)
{
_acs.WaitMotionEnd(USE_AXIS[i], _motionTimeout); //等待回家完成
}
_homeStates = HomeStates.Homed;
_currentMotionState = MotionStates.InPos;
DebugDfn.AddLogText("回家完成");
}
else
{
//弹窗提醒
MessageBox.Show("点击了取消,未进行任何动作", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
}
}
private void InitMotion() //定义 运动状态初始化函数,包括内部变量,轴启用,回家判断等
{
//运动相关变量初始化
_homeStates = HomeStates.None;
_currentMotionState = MotionStates.None;
_currentMotionState = MotionStates.None;
if (!_mAcsConnected)
{
MessageBox.Show("未连接运动平台,请先连接运动平台");
return;
}
if (_acs == null)
{
DebugDfn.AddLogText("运动控制对象不存在");
return;
}
//轴启用,加电
_acs.EnableM(USE_AXIS);
for (int i = 0; i < USE_AXIS.Length; i++)
{
_acs.WaitMotorEnabled(USE_AXIS[i], 1, _motionTimeout); //等待电机使能
}
DebugDfn.AddLogText("电机已启用");
//回家
Ishome();
SetSpeedXyz();
//注册到位事件
_acs.PHYSICALMOTIONEND += ACS_PHYSICALMOTIONEND;
_acs.EnableEvent(Interrupts.ACSC_INTR_PHYSICAL_MOTION_END);
}
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
Invoke((MethodInvoker)delegate
{
DebugDfn.AddLogText("运动到位");
_currentMotionState = MotionStates.InPos;
DebugDfn.AddLogText("运动到位");
});
}
private bool IsWithinStrokes(Point3D point) //判断点是否在行程范围内
{
if (point.X >= X_MINSTROKESW && point.X <= X_MAXSTROKESW &&
point.Y >= Y_MINSTROKESW && point.Y <= Y_MAXSTROKESW &&
point.Z >= Z_MINSTROKESW && point.Z <= Z_MAXSTROKESW)
{
return true;
}
return false;
}
private void SetPositionXyz(Point3D point3D) //运动到指定位置
{
if (!_mAcsConnected)
{
DebugDfn.AddLogText("ACS平台未连接,请先点击连接");
MessageBox.Show("ACS平台未连接,请先点击连接", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
return;
}
if (_currentMotionState != MotionStates.Moving)
{
_currentMotionState = MotionStates.Moving; //设置当前运动状态
//判断 point3D是否合法
if (point3D != null)
{
if (IsWithinStrokes(point3D)) //判断点是否在行程范围内
{
double[] pointsArray =
{
point3D.X,
point3D.Y,
point3D.Z
};
//执行运动指令
_acs.ToPointM(MotionFlags.ACSC_NONE, USE_AXIS, pointsArray); //多轴运动到指定位置
////等待运动完成
//for (int i = 0; i < USE_AXIS.Length; i++)
//{
// _acs.WaitMotionEnd(USE_AXIS[i], _motionTimeout); //等待回家完成
//}
//_currentMotionState = MotionStates.InPos;
//DebugDfn.AddLogText("运动到位");
}
else
{
DebugDfn.AddLogText("目标位置超出行程范围,请重新设置");
MessageBox.Show("目标位置超出行程范围,请重新设置", "异常", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
else
{
DebugDfn.AddLogText("目标位置为空,请重新设置");
MessageBox.Show("目标位置为空,请重新设置", "异常", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
}
private Point3D GetPositionXyz(int positionMode = 1) //获取当前位置
{
double xPosition = 0, yPosition = 0, zPosition = 0;
Point3D point3D = new Point3D(xPosition, yPosition, zPosition);
if (!_mAcsConnected)
{
DebugDfn.AddLogText("ACS平台未连接,请先点击连接");
MessageBox.Show("ACS平台未连接,请先点击连接", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
return point3D;
}
//获取当前位置, 两种 GetRPositionGetFPosition
if (positionMode == 1)
{
//获取反馈位置 Feedback position (Encoder value) ACSPL+ Variable : FPO (real)
xPosition = _acs.GetFPosition(USE_AXIS[0]);
yPosition = _acs.GetFPosition(USE_AXIS[1]);
zPosition = _acs.GetFPosition(USE_AXIS[2]);
DebugDfn.AddLogText("反馈位置: " + xPosition + " " + yPosition + " " + zPosition);
}
else
{
//获取参考位置 ACSPL+ Variable : RPOS (real)
xPosition = _acs.GetRPosition(USE_AXIS[0]);
yPosition = _acs.GetRPosition(USE_AXIS[1]);
zPosition = _acs.GetRPosition(USE_AXIS[2]);
DebugDfn.AddLogText("参考位置: " + xPosition + " " + yPosition + " " + zPosition);
}
//构造point3D格式
point3D = new Point3D(xPosition, yPosition, zPosition);
return point3D;
}
private void SetSpeedXyz() //获取运动参数
{
//获取实际速度
double feedbackVelocity = (double)_acs.ReadVariable("FVEL", ProgramBuffer.ACSC_NONE, 0, 0);
DebugDfn.AddLogText("实际速度: " + feedbackVelocity);
//设置Y轴 速度参数
_acs.SetVelocity(Axis.ACSC_AXIS_0, MOTION_SPEED);
_acs.SetAcceleration(Axis.ACSC_AXIS_0,MOTION_SPEED*10);
_acs.SetDeceleration(Axis.ACSC_AXIS_0,MOTION_SPEED*10);
//设置X轴速度参数
_acs.SetVelocity(Axis.ACSC_AXIS_1, MOTION_SPEED);
_acs.SetAcceleration(Axis.ACSC_AXIS_1, MOTION_SPEED * 10);
_acs.SetDeceleration(Axis.ACSC_AXIS_1, MOTION_SPEED * 10);
//设置Z轴速度参数
_acs.SetVelocity(Axis.ACSC_AXIS_8, MOTION_SPEED);
_acs.SetAcceleration(Axis.ACSC_AXIS_8, MOTION_SPEED * 10);
_acs.SetDeceleration(Axis.ACSC_AXIS_8, MOTION_SPEED * 10);
}
private void openGLControl1_OpenGLDraw(object sender, RenderEventArgs args)
{
OpenGL gl = openGLControl1.OpenGL;
gl.ClearColor(0, 0, 0, 0);
gl.Clear(OpenGL.GL_COLOR_BUFFER_BIT | OpenGL.GL_DEPTH_BUFFER_BIT);
gl.LoadIdentity();
//gl.Translate(0.0f, 0.0f, -5.0f); // 平移场景
}
private void LoadPoints(List<Point3D> points)
{
OpenGL gl = openGLControl1.OpenGL;
gl.ClearColor(0, 0, 0, 0);
gl.Clear(OpenGL.GL_COLOR_BUFFER_BIT | OpenGL.GL_DEPTH_BUFFER_BIT);
gl.LoadIdentity();
//gl.Translate(0.0f, 0.0f, -5.0f); // 平移场景
gl.Begin(OpenGL.GL_POINTS);
foreach (Point3D point in points)
{
// 设置点的颜色
gl.Color(1.0f, 0.0f, 0.0f); // 红色
// 设置点的大小
gl.PointSize(5.0f); // 大小为5个单位
gl.Vertex(point.X, point.Y, point.Z);
}
gl.End();
gl.Flush();
}
private void openGLControl1_OpenGLInitialized(object sender, EventArgs e)
{
}
private void openGLControl1_Resized(object sender, EventArgs e)
{
}
private void openGLControl1_GDIDraw(object sender, RenderEventArgs args)
{
}
#endregion ACS平台相关
#region
private void Rtb_motion_Click(object sender, EventArgs e) //ACS调试页面
{
Motion motion = new Motion();
motion.Show();
}
private void Rtb_about_Click(object sender, EventArgs e) //关于界面
{
AboutBox mAboutBox = new AboutBox();
mAboutBox.StartPosition = FormStartPosition.CenterScreen;
mAboutBox.Show();
}
private void Timer_RefreshUI_Tick(object sender, EventArgs e) //UI刷新
{
//状态灯刷新
lamp_acs.State = _mAcsConnected ? LampColor.Green : LampColor.Silver;
lamp_hexcal.State = _mBHexcalConnected ? LampColor.Green : LampColor.Silver;
//时间栏
//获取当前时间,构造形如 精确到秒,例如 2023-10-08 16:01:23
rle_timer.Text = "当前时间: " + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
Plot2D(_pointCloud); //绘图
}
#endregion
}
}