2026-01-26 18:56:53 +09:00

622 lines
23 KiB
C#

using Aurora.Api;
using Aurora.Api.Manager;
using AuroraIO;
using Hermes;
using System;
using System.Windows;
using static AuroraIO.Vendor.PAIX.PAIXIO;
namespace AuroraMotionBoard.Ajin
{
public class AJINDevice : Device
{
private readonly Logger Log = new Logger("AjinMotion");
public AJINDeviceConfig _config;
private IODevice _IO;
private int _MotorCount;
private bool _XPosInterlockType;
//var systemParameterILSOS = AuroraEnv.SettingEntry[SettingIds.SystemParameter] as SystemParameter;
//systemParameterILSOS.MachineType == eMachineType.PRIBAT_L1
//public AJINDevice(bool XPosInterlock, string deviceId, bool isSimul = false)
public AJINDevice(bool XPosInterlockType, IDeviceManager deviceManager, string deviceId)
{
//_devManager = deviceManager;
_XPosInterlockType = XPosInterlockType;
_IO = deviceManager["IO_Board"] as IODevice;
}
protected override int DoActivate(IDeviceConfig config)
{
_config = config as AJINDeviceConfig;
if (IsSimul) {
return E1.OK;
}
_MotorCount = _config.TotalMotorCount;
if (!Init())
return E1.NETWORK;
return E1.OK;
}
protected override int DoDeactivate()
{
if (!IsSimul) {
if (!Close())
return E1.NETWORK;
}
return E1.OK;
}
public bool Init()
{
try {
uint res = 0;
int count = 0;
// 객체 초기화
if (CAXL.AxlIsOpened() == (int)AXT_BOOLEAN.FALSE) {
res = CAXL.AxlOpen(0);
if (res != (uint)AXT_FUNC_RESULT.AXT_RT_SUCCESS) {
Log.E($"AXM AxlOpen Error : {Enum.GetName(typeof(AXT_FUNC_RESULT), res)}");
return false;
}
}
// Board Count 추가
res = CAXL.AxlGetBoardCount(ref count);
if (count < 1 || (res != (uint)AXT_FUNC_RESULT.AXT_RT_SUCCESS)) {
Log.E($"AXM AxlGetBoardCount Error : {Enum.GetName(typeof(AXT_FUNC_RESULT), res)}");
return false;
}
// Motion Param Setting File Load
if (!string.IsNullOrEmpty(_config.MotionSettingsPath)) {
res = CAXM.AxmMotLoadParaAll(_config.MotionSettingsPath);
if (res != (uint)AXT_FUNC_RESULT.AXT_RT_SUCCESS) {
Log.E($"AXM AxmMotLoadParaAll Error : {Enum.GetName(typeof(AXT_FUNC_RESULT), res)}");
return false;
}
}
} catch (Exception e) {
Log.FuncE(e.Message);
return false;
}
return true;
}
public bool Close()
{
try {
int res = 0;
// 객체 초기화
res = CAXL.AxlClose();
if (res != (int)AXT_FUNC_RESULT.AXT_RT_SUCCESS) {
Log.E($"AXM AxlClose Error : {Enum.GetName(typeof(AXT_FUNC_RESULT), res)}");
return false;
}
} catch (Exception ex) {
Log.FuncE(ex.Message);
return false;
}
return true;
}
public bool AmpDisable(int Axis)
{
try {
uint res = 0;
double Decel = 0.0;
res = CAXM.AxmMoveStop(Axis, Decel);
if (res != (uint)AXT_FUNC_RESULT.AXT_RT_SUCCESS) {
Log.E($"AXM AxmMoveStop Error : {Enum.GetName(typeof(AXT_FUNC_RESULT), res)}");
return false;
}
if (ServoOnOff(Axis, (uint)AXT_MOTION_SIGNAL_LEVEL.INACTIVE))
return false;
if (AlarmReset(Axis))
return false;
} catch (Exception ex) {
Log.FuncE(ex.Message);
return false;
}
return true;
}
#region Home Func
public int SetHomeVelocity(int AxisNo, double VelFirst, double VelSecond, double VelThird, double velLast, double AccFirst, double AccSecond)
{
try {
uint res = 0;
res = CAXM.AxmHomeSetVel(AxisNo, VelFirst, VelSecond, VelThird, velLast, AccFirst, AccSecond);
if (res != (uint)AXT_FUNC_RESULT.AXT_RT_SUCCESS) {
Log.E($"AXM SetHomeVelocity Error : {Enum.GetName(typeof(AXT_FUNC_RESULT), res)}");
return E2.ABORTED;
}
} catch (Exception ex) {
Log.FuncE(ex.Message);
return E2.ABORTED;
}
return E1.OK;
}
public int SetHomeMethod(int AxisNo, int HmDir, uint HomeSignal, uint Zphas, double HomeClrTime, double HomeOffset)
{
try {
uint res = 0;
res = CAXM.AxmHomeSetMethod(AxisNo, HmDir, HomeSignal, Zphas, HomeClrTime, HomeOffset);
if (res != (uint)AXT_FUNC_RESULT.AXT_RT_SUCCESS) {
Log.E($"AXM AxmHomeSetMethod Error : {Enum.GetName(typeof(AXT_FUNC_RESULT), res)}");
return E2.ABORTED;
}
} catch (Exception ex) {
Log.FuncE(ex.Message);
return E2.ABORTED;
}
return E1.OK;
}
public int StartHome(int Axis)
{
try {
if (GetAlarmStatus(Axis) || !IsServoOn(Axis)) return E2.ABORTED;
if (CheckXPosInterlock(_XPosInterlockType, Axis) == false)
return E2.ABORTED;
else {
uint res = 0;
res = CAXM.AxmHomeSetStart(Axis);
if (res != (uint)AXT_FUNC_RESULT.AXT_RT_SUCCESS) {
Log.E($"AXM Home Error : {Enum.GetName(typeof(AXT_FUNC_RESULT), res)}");
return E2.ABORTED;
}
}
} catch (Exception ex) {
Log.FuncE(ex.Message);
return E2.ABORTED;
}
return E1.OK;
}
public uint GetHomeResult(int Axis)
{
uint status = 0;
try {
uint res = 0;
res = CAXM.AxmHomeGetResult(Axis, ref status);
if (res != (uint)AXT_FUNC_RESULT.AXT_RT_SUCCESS) {
Log.E($"AXM AxmHomeGetResult Error : {Enum.GetName(typeof(AXT_FUNC_RESULT), res)}");
return status;
}
} catch (Exception ex) {
Log.FuncE(ex.Message);
return E1.OK;
}
return status;
}
#endregion
#region Move Func
public int MoveABS(int Axis, double Pos, double Vel, double Accel, double Decel)
{
try {
if ((uint)AXT_MOTION_HOME_RESULT.HOME_SUCCESS != GetHomeResult(Axis) || GetAlarmStatus(Axis) || !IsServoOn(Axis)) return E2.ABORTED;
if (CheckXPosInterlock(_XPosInterlockType, Axis) == false)
return E2.ABORTED;
else {
double curr = GetCurrentPosition(Axis);
if (double.IsNaN(curr))
return E2.ABORTED;
if (Math.Abs(curr - Pos) < 0.001)
return E1.OK;
uint res = CAXM.AxmMotSetAbsRelMode(Axis, (uint)AXT_MOTION_ABSREL.POS_ABS_MODE);
if (res != (uint)AXT_FUNC_RESULT.AXT_RT_SUCCESS) {
Log.E($"AXM AxmMotSetAbsRelMode Error : {Enum.GetName(typeof(AXT_FUNC_RESULT), res)}");
return E2.ABORTED;
}
if (Move(Axis, Pos, Vel, Accel, Decel) < 0)
return E2.ABORTED;
}
} catch (Exception ex) {
Log.FuncE(ex.Message);
return E1.ARGUMENT;
}
return E1.OK;
}
public int MoveREL(int Axis, double Pos, double Vel, double Accel, double Decel)
{
try {
if ((uint)AXT_MOTION_HOME_RESULT.HOME_SUCCESS != GetHomeResult(Axis) || GetAlarmStatus(Axis) || !IsServoOn(Axis)) return E2.ABORTED;
if (CheckXPosInterlock(_XPosInterlockType, Axis) == false)
return E2.ABORTED;
else {
double curr = GetCurrentPosition(Axis);
if (double.IsNaN(curr))
return E2.ABORTED;
if (Math.Abs(curr + Pos) < 0.001)
return E1.OK;
uint res = CAXM.AxmMotSetAbsRelMode(Axis, (uint)AXT_MOTION_ABSREL.POS_REL_MODE);
if (res != (uint)AXT_FUNC_RESULT.AXT_RT_SUCCESS) {
Log.E($"AXM AxmMotSetAbsRelMode Error : {Enum.GetName(typeof(AXT_FUNC_RESULT), res)}");
return E2.ABORTED;
}
if (Move(Axis, Pos, Vel, Accel, Decel) < 0)
return E2.ABORTED;
}
} catch (Exception ex) {
Log.FuncE(ex.Message);
return E1.ARGUMENT;
}
return E1.OK;
}
internal int Move(int Axis, double Pos, double Vel, double Accel, double Decel)
{
try {
if ((uint)AXT_MOTION_HOME_RESULT.HOME_SUCCESS != GetHomeResult(Axis) || GetAlarmStatus(Axis) || !IsServoOn(Axis)) return E2.ABORTED;
if (CheckXPosInterlock(_XPosInterlockType, Axis) == false)
return E2.ABORTED;
uint res = 0;
res = CAXM.AxmMoveStartPos(Axis, Pos, Vel, Accel, Decel);
if (res != (uint)AXT_FUNC_RESULT.AXT_RT_SUCCESS) {
Log.E($"AXM Stop Error : {Enum.GetName(typeof(AXT_FUNC_RESULT), res)}");
return E2.ABORTED;
}
} catch (Exception ex) {
Log.FuncE(ex.Message);
return E2.ABORTED;
}
return E1.OK;
}
public int MoveJog(int Axis, int direction, double velocity, double Accel, double Decel)
{
try {
if ((uint)AXT_MOTION_HOME_RESULT.HOME_SUCCESS != GetHomeResult(Axis) || GetAlarmStatus(Axis) || !IsServoOn(Axis)) return E2.ABORTED;
if (CheckXPosInterlock(_XPosInterlockType, Axis) == false)
return E2.ABORTED;
uint res = 0;
res = CAXM.AxmMoveVel(Axis, direction * velocity, Accel, Decel);
if (res != (uint)AXT_FUNC_RESULT.AXT_RT_SUCCESS) {
Log.E($"AXM Jog Error : {Enum.GetName(typeof(AXT_FUNC_RESULT), res)}");
return E2.ABORTED;
}
} catch (Exception ex) {
Log.FuncE(ex.Message);
return E2.ABORTED;
}
return E1.OK;
}
public int Stop(int Axis)
{
try {
uint res = 0;
res = CAXM.AxmMoveSStop(Axis);
if (res != (uint)AXT_FUNC_RESULT.AXT_RT_SUCCESS) {
Log.E($"AXM Stop Error : {Enum.GetName(typeof(AXT_FUNC_RESULT), res)}");
return E2.ABORTED;
}
} catch (Exception ex) {
Log.FuncE(ex.Message);
return E2.ABORTED;
}
return E1.OK;
}
#endregion
#region Getter Func
public (int boardNo, int modulePos, int ModuleId) ReadAxisInfo(int Axis)
{
int BoardNo = 0, ModulePos = 0;
uint ModuleID = 0;
try {
uint res = 0;
res = CAXM.AxmInfoGetAxis(Axis, ref BoardNo, ref ModulePos, ref ModuleID);
if (res != (uint)AXT_FUNC_RESULT.AXT_RT_SUCCESS) {
Log.E($"AXM AxmInfoGetAxis Error : {Enum.GetName(typeof(AXT_FUNC_RESULT), res)}");
return (BoardNo, ModulePos, (int)ModuleID);
}
} catch (Exception ex) {
Log.FuncE(ex.Message);
return (BoardNo, ModulePos, (int)ModuleID);
}
return (BoardNo, ModulePos, (int)ModuleID);
}
public double GetTargetPosition(int Axis)
{
double pos = 0.0;
try {
uint res = 0;
res = CAXM.AxmStatusGetCmdPos(Axis, ref pos);
if (res != (uint)AXT_FUNC_RESULT.AXT_RT_SUCCESS) {
Log.E($"AXM GetTargetPosition Error : {Enum.GetName(typeof(AXT_FUNC_RESULT), res)}");
return double.NaN;
}
} catch (Exception ex) {
Log.FuncE(ex.Message);
return double.NaN;
}
return pos;
}
public double GetCurrentPosition(int Axis)
{
double pos = 0.0;
try {
uint res = 0;
res = CAXM.AxmStatusGetActPos(Axis, ref pos);
if (res != (uint)AXT_FUNC_RESULT.AXT_RT_SUCCESS) {
Log.E($"AXM GetCurrentPosition Error : {Enum.GetName(typeof(AXT_FUNC_RESULT), res)}");
return double.NaN;
}
} catch (Exception ex) {
Log.FuncE(ex.Message);
return double.NaN;
}
return pos;
}
public bool CheckInside(double Target, double cur)
{
if (Target - 0.1 < cur && cur < Target + 0.1)
return true;
return false;
}
public bool ReadInPosition(int Axis)
{
uint status = 0;
try {
uint res = 0;
res = CAXM.AxmSignalReadInpos(Axis, ref status);
if (res != (uint)AXT_FUNC_RESULT.AXT_RT_SUCCESS) {
Log.E($"AXM ReadInposition Error : {Enum.GetName(typeof(AXT_FUNC_RESULT), res)}");
return false;
}
} catch (Exception ex) {
Log.FuncE(ex.Message);
return false;
}
return status == (uint)AXT_MOTION_SIGNAL_LEVEL.ACTIVE ? true : false;
}
public bool ReadInMotion(int Axis)
{
if (IsSimul)
return true;
uint status = 0;
try {
uint res = 0;
res = CAXM.AxmStatusReadInMotion(Axis, ref status);
if (res != (uint)AXT_FUNC_RESULT.AXT_RT_SUCCESS) {
Log.E($"AXM ReadInMotion Error : {Enum.GetName(typeof(AXT_FUNC_RESULT), res)}");
return false;
}
} catch (Exception ex) {
Log.FuncE(ex.Message);
return false;
}
return status == (uint)AXT_MOTION_SIGNAL_LEVEL.ACTIVE ? true : false;
}
public double ReadServoLoadRatio(int Axis)
{
double status = 0;
try {
uint res = 0;
res = CAXM.AxmStatusReadServoLoadRatio(Axis, ref status);
if (res != (uint)AXT_FUNC_RESULT.AXT_RT_SUCCESS) {
Log.E($"AXM AxmStatusReadServoLoadRatio Error : {Enum.GetName(typeof(AXT_FUNC_RESULT), res)}");
return double.NaN;
}
} catch (Exception ex) {
Log.FuncE(ex.Message);
return double.NaN;
}
return double.NaN;
}
public (bool HwPos, bool HwNeg) ReadLimit(int Axis)
{
uint posStatus = 0, negStatus = 0;
try {
uint res = 0;
res = CAXM.AxmSignalReadLimit(Axis, ref posStatus, ref negStatus);
if (res != (uint)AXT_FUNC_RESULT.AXT_RT_SUCCESS) {
Log.E($"AXM ReadLimit Error : {Enum.GetName(typeof(AXT_FUNC_RESULT), res)}");
return (true, true);
}
} catch (Exception ex) {
Log.FuncE(ex.Message);
return (true, true);
}
return (posStatus == (uint)AXT_MOTION_SIGNAL_LEVEL.ACTIVE ? true : false,
negStatus == (uint)AXT_MOTION_SIGNAL_LEVEL.ACTIVE ? true : false);
}
#endregion
public bool ServoOnOff(int Axis, uint onoff)
{
if (IsSimul)
return true;
try {
uint res = 0;
res = CAXM.AxmSignalServoOn(Axis, onoff);
if (res != (uint)AXT_FUNC_RESULT.AXT_RT_SUCCESS) {
Log.E($"AXM ServoOnOff Error : {Enum.GetName(typeof(AXT_FUNC_RESULT), res)}");
return false;
}
} catch (Exception ex) {
Log.FuncE(ex.Message);
return false;
}
return true;
}
public bool IsServoOn(int Axis)
{
if (IsSimul)
return true;
uint status = 0;
try {
uint res = 0;
res = CAXM.AxmSignalIsServoOn(Axis, ref status);
if (res != (uint)AXT_FUNC_RESULT.AXT_RT_SUCCESS) {
Log.E($"AXM ReadInMotion Error : {Enum.GetName(typeof(AXT_FUNC_RESULT), res)}");
return false;
}
} catch (Exception ex) {
Log.FuncE(ex.Message);
return false;
}
return status == (uint)AXT_MOTION_SIGNAL_LEVEL.ACTIVE ? true : false;
}
public bool AlarmReset(int Axis)
{
if (IsSimul)
return true;
try {
uint res = 0;
res = CAXM.AxmSignalServoAlarmReset(Axis, (uint)AXT_USE.ENABLE);
if (res != (uint)AXT_FUNC_RESULT.AXT_RT_SUCCESS) {
Log.E($"AXM AxmSignalServoAlarmReset Error : {Enum.GetName(typeof(AXT_FUNC_RESULT), res)}");
return false;
}
} catch (Exception ex) {
Log.FuncE(ex.Message);
return false;
}
return true;
}
public double ReadCurrentVelocity(int Axis)
{
double status = 0;
try {
uint res = 0;
res = CAXM.AxmStatusReadVel(Axis, ref status);
if (res != (uint)AXT_FUNC_RESULT.AXT_RT_SUCCESS) {
Log.E($"AXM AxmStatusReadServoLoadRatio Error : {Enum.GetName(typeof(AXT_FUNC_RESULT), res)}");
return double.NaN;
}
} catch (Exception ex) {
Log.FuncE(ex.Message);
return double.NaN;
}
return status;
}
public bool GetAlarmStatus(int Axis)
{
if (IsSimul)
return false;
try {
//res는 함수의 실행 결과 여부고 alarmCode에 따라서 알람 유무를 확인해야 함
//Return True : Alarm 상태
uint res = 0;
uint alarmCode = 0;
res = CAXM.AxmStatusReadServoAlarm(Axis, 0, ref alarmCode);
if (res != (uint)AXT_FUNC_RESULT.AXT_RT_SUCCESS) {
Log.E($"AXM AxmStatusRequestServoAlarm Func Error : {Enum.GetName(typeof(AXT_FUNC_RESULT), res)}");
return true;
} else {
if (alarmCode != 0) {
Log.E($"AXM AxmStatusRequestServoAlarm Error : {Enum.GetName(typeof(AXT_FUNC_RESULT), alarmCode)}");
return true;
} else
return false;
}
} catch (Exception ex) {
Log.FuncE(ex.Message);
return false;
}
}
public const uint DPRAM_COMMON_CMD_SIIIH_SCAN = 0x74;
public bool CheckXPosInterlock(bool XPosInterlockType, int Axis)
{
if (XPosInterlockType) {
if (Axis == 1) {
bool bSuctionUp = false;
bool bSuctionDown = false;
// TODO: 향후, 공용으로 처리 할 수 있는 방법 확인 필요함, 장비 안에서 Interlock 을 처리 한다든지..
// 장비별로 존재하는 Interlock 이므로, 필요하다면 해당 장비군의 Git 에서 별도 처리
//bSuctionUp = _IO._iOUnit.ReadDiBit((Convert.ToInt32(ePTDIAddress.SUCTION_UP_CY)));
//bSuctionDown = _IO._iOUnit.ReadDiBit((Convert.ToInt32(ePTDIAddress.SUCTION_DOWN_CY)));
if (bSuctionUp == true && bSuctionDown == false) {
return true;
} else
return false;
} else
return true;
} else
return true;
}
public uint SSCNET_DeviceRescan(int Axis)
{
int nBoardCnt = 0;
double dCmdPos = 0;
int nOldTick = 0, nNewTick = 0, nTickTime = 0;
uint[] uSendData = new uint[22];
uint uReturn;
CAXL.AxlOpenNoReset(7);
CAXL.AxlGetBoardCount(ref nBoardCnt);
if (nBoardCnt < 1)
return (uint)AXT_FUNC_RESULT.AXT_RT_OPEN_ERROR;
System.Array.Clear(uSendData, 0, 22);
//'AxlSetSendBoardCommand' 함수의 첫 번째 인자는 보드 넘버입니다.
//PC에 장착한 순서에 따라 보드 넘버는 변경됩니다.
//EzConfig UC을 통해 보드 넘버를 알 수 있습니다.
uReturn = CAXDev.AxlSetSendBoardCommand(0, DPRAM_COMMON_CMD_SIIIH_SCAN, ref uSendData[21], 0);
nOldTick = Environment.TickCount;
while (true) {
//TimeOut Check
nNewTick = Environment.TickCount;
nTickTime = nNewTick - nOldTick;
if (nTickTime > 20000) {
MessageBox.Show("Scan Error");
return (uint)AXT_FUNC_RESULT.AXT_RT_OPEN_ERROR;
}
//Network Connect Check
uReturn = CAXM.AxmStatusGetCmdPos(Axis, ref dCmdPos);
if (uReturn == 0) {
break;
}
}
CAXM.AxmMotLoadParaAll(_config.MotionSettingsPath);
CAXL.AxlClose();
CAXL.AxlOpenNoReset(7);
return (uint)AXT_FUNC_RESULT.AXT_RT_SUCCESS;
}
}
}