using MMCE_Test;
using System;
namespace SHARP_CLAS_UI
{
public class Axis : Slave
{
#region Enum
#endregion
#region Property
///
/// Axis Status 값
///
public uint AxisStatus;
///
/// Axis State 중 하나로 축의 Error상태로 모션 동작이 불가능한 상태
///
public bool ErrorStop { get { return ((AxisStatus & (uint)NMCSDKLib.MC_AXISSTATUS.mcErrorStop) > 0); } }
///
/// Axis State 중 하나로 축의 Amp Off 상태로 모션 동작이 불가능한 상태
///
public bool Disabled { get {return ((AxisStatus & (uint)NMCSDKLib.MC_AXISSTATUS.mcDisabled) > 0); } }
///
/// Axis State 중 하나로 MC_Stop에 의해 감속정지 중 또는 감속정지는 완료 되었지만 MC_Stop의 Execute가 유지되어 있는 상태로 모션 동작이 불가능한 상태
///
public bool Stopping { get { return ((AxisStatus & (uint)NMCSDKLib.MC_AXISSTATUS.mcStopping) > 0); } }
///
/// Axis State 중 하나로 축의 Amp On 상태로 모션 동작이 가능한 준비 상태
///
public bool StandStill { get { return ((AxisStatus & (uint)NMCSDKLib.MC_AXISSTATUS.mcStandStill) > 0); } }
///
/// Axis State 중 하나로 MC_MoveAbsoulte, MC_MoveRelative, MC_Halt 등에 의해 단축 모션 중인 상태
///
public bool DiscreteMotion { get { return ((AxisStatus & (uint)NMCSDKLib.MC_AXISSTATUS.mcDiscreteMotion) > 0); } }
///
/// Axis State 중 하나로 MC_MoveVelocity에 의해 지속적인 모션 중인 상태
///
public bool ContinuousMotion { get { return ((AxisStatus & (uint)NMCSDKLib.MC_AXISSTATUS.mcContinuousMotion) > 0); } }
///
/// Axis State 중 하나로 MC_GearIn 또는 GroupMotion에 의한 모션 상태
///
public bool SynchroMotion { get { return ((AxisStatus & (uint)NMCSDKLib.MC_AXISSTATUS.mcSynchroMotion) > 0); } }
///
/// Axis State 중 하나로 축이 MC_Home에 의해 원점복귀 중인 상태
///
public bool Homing { get { return ((AxisStatus & (uint)NMCSDKLib.MC_AXISSTATUS.mcHoming) > 0); } }
///
/// Software Position Positive Limit Value를 벗어나면 On으로 변경
///
public bool Reserved_as_8 { get { return ((AxisStatus & (uint)NMCSDKLib.MC_AXISSTATUS.mcReserved_as_8) > 0); } }
///
/// Software Position Negative Limit Value를 벗어나면 On으로 변경
///
public bool Reserved_as_9 { get { return ((AxisStatus & (uint)NMCSDKLib.MC_AXISSTATUS.mcReserved_as_9) > 0); } }
///
/// 모션이 등속동작 중인 상태
///
public bool ConstantVelocity { get { return ((AxisStatus & (uint)NMCSDKLib.MC_AXISSTATUS.mcConstantVelocity) > 0); } }
///
/// 모션이 가속동작 중인 상태
///
public bool Accelerating { get { return ((AxisStatus & (uint)NMCSDKLib.MC_AXISSTATUS.mcAccelerating) > 0); } }
///
/// 모션이 감속동작 중인 상태
///
public bool Decelerating { get { return ((AxisStatus & (uint)NMCSDKLib.MC_AXISSTATUS.mcDecelerating) > 0); } }
///
/// 모션이 정방향으로 동작 중인 상태(모션이 정지 중일 때 Default로 동작)
///
public bool DirectionPositive { get { return ((AxisStatus & (uint)NMCSDKLib.MC_AXISSTATUS.mcDirectionPositive) > 0); } }
///
/// 모션이 역방향으로 동작 중인 상태
///
public bool DirectionNegative { get { return ((AxisStatus & (uint)NMCSDKLib.MC_AXISSTATUS.mcDirectionNegative) > 0); } }
///
/// Negative Hardware Limit Switch의 상태 0: OFF, 1: ON
///
public bool LimitSwitchNeg { get { return ((AxisStatus & (uint)NMCSDKLib.MC_AXISSTATUS.mcLimitSwitchNeg) > 0); } }
///
/// Positive Hardware Limit Switch의 상태0: OFF, 1: ON
///
public bool LimitSwitchPos { get { return ((AxisStatus & (uint)NMCSDKLib.MC_AXISSTATUS.mcLimitSwitchPos) > 0); } }
///
/// Home Switch의 상태 0: OFF, 1: ON
///
public bool HomeAbsSwitch { get { return ((AxisStatus & (uint)NMCSDKLib.MC_AXISSTATUS.mcHomeAbsSwitch) > 0); } }
///
/// Positive Hardware Limit Switch가Active 되었을 때 On으로 변경(해당 Switch가 Off되었다고 해서 Off가 해제 되는 것은 아님)
///
public bool LimitSwitchPosEvent { get { return ((AxisStatus & (uint)NMCSDKLib.MC_AXISSTATUS.mcLimitSwitchPosEvent) > 0); } }
///
/// Negative Hardware Limit Switch가Active 되었을 때 On으로 변경(해당 Switch가 Off되었다고 해서 Off가 되는 것은 아님)
///
public bool LimitSwitchNegEvent { get { return ((AxisStatus & (uint)NMCSDKLib.MC_AXISSTATUS.mcLimitSwitchNegEvent) > 0); } }
///
/// 해당 축에 링크된 Slave Drive가 Fault상태(Slave Statusword bit 3)
///
public bool DriveFault { get { return ((AxisStatus & (uint)NMCSDKLib.MC_AXISSTATUS.mcDriveFault) > 0); } }
///
/// 해당 축에 설정된 SensorStop에 의해 모션이 정지된 상태
///
public bool SensorStop { get { return ((AxisStatus & (uint)NMCSDKLib.MC_AXISSTATUS.mcSensorStop) > 0); } }
///
/// AmpOn이 가능한 상태
///
public bool ReadyForPowerOn { get { return ((AxisStatus & (uint)NMCSDKLib.MC_AXISSTATUS.mcReadyForPowerOn) > 0); } }
///
/// AmpOn이 정상적으로 완료된 상태
///
public bool PowerOn { get { return ((AxisStatus & (uint)NMCSDKLib.MC_AXISSTATUS.mcPowerOn) > 0); } }
///
/// MC_Home에 의해 원점복귀가 완료된 상태
///
public bool IsHomed { get { return ((AxisStatus & (uint)NMCSDKLib.MC_AXISSTATUS.mcIsHomed) > 0); } }
///
/// 모션 동작에는 문제가 없지만 축의 Warning상태
///
public bool AxisWarning { get { return ((AxisStatus & (uint)NMCSDKLib.MC_AXISSTATUS.mcAxisWarning) > 0); } }
///
/// 모션 동작이 완료된 Inposition 상태
///
public bool MotionComplete { get { return ((AxisStatus & (uint)NMCSDKLib.MC_AXISSTATUS.mcMotionComplete) > 0); } }
///
/// MC_GearIn에 의해 Gearing 동작 중인 상태
///
public bool Gearing { get { return ((AxisStatus & (uint)NMCSDKLib.MC_AXISSTATUS.mcGearing) > 0); } }
///
/// 해당 축이 그룹에 속한 상태이며 해당 그룹이 Enable인 상태
///
public bool GroupMotion { get { return ((AxisStatus & (uint)NMCSDKLib.MC_AXISSTATUS.mcGroupMotion) > 0); } }
///
/// 해당 축의 Buffer 1000개가 모두 사용된 상태
///
public bool BufferFull { get { return ((AxisStatus & (uint)NMCSDKLib.MC_AXISSTATUS.mcBufferFull) > 0); } }
///
/// Reserved for Future Use
///
public bool Reserved_as_30 { get { return ((AxisStatus & (uint)NMCSDKLib.MC_AXISSTATUS.mcReserved_as_30) > 0); } }
///
/// 해당 축에 링크된 Slave Drive의 Sensor data의 버그상태
///
public bool Reserved_as_31 { get { return ((AxisStatus & (uint)NMCSDKLib.MC_AXISSTATUS.mcReserved_as_31) > 0); } }
public ushort ErrorID { get; private set; }
public ushort ErrorInfo0 { get; private set; }
public ushort ErrorInfo1 { get; private set; }
///
/// Current Position
///
public double Position { get; private set; }
///
/// Current Velocity
///
public double Velocity { get; private set; }
private bool Auto_Mode
{
get
{
return Board_Control.IO_manager.Get_Input(InputData.Safety_Mode_SW_Auto);
}
}
#endregion
#region Field
private Sharp_Board_Control Board_Control;
public Func Check_Jog_Interlock;
public Func Check_Move_Interlock;
public Func Check_Home_Interlock;
private double teach_velocity = 30;
#endregion
#region Construct
public Axis(Sharp_Board_Control Board_Control, ushort Board_Id, ushort Device_Id)
: base(Board_Id, Device_Id)
{
this.Board_Control = Board_Control;
}
#endregion
#region Function
///
/// Get Axis Status
///
///
public bool Get_Axis_Status()
{
try
{
uint uData = 0;
NMCSDKLib.MC_STATUS mc;
mc = NMCSDKLib.MC_ReadAxisStatus(Board_Id, Device_Id, ref uData);
if (mc == NMCSDKLib.MC_STATUS.MC_OK)
{
AxisStatus = uData;
return true;
}
else
{
AxisStatus = 0;
throw new Exception($"Board_Id : {Board_Id}, Device_Id : {Device_Id}, " + mc.ToString());
}
}
catch (Exception ex)
{
//WriteExceptionLog(MethodBase.GetCurrentMethod().Name, ex);
return false;
}
}
///
/// Axis Amp On
///
///
public bool Amp_On()
{
try
{
NMCSDKLib.MC_STATUS mc;
mc = NMCSDKLib.MC_Power(Board_Id, Device_Id, true);
if (mc == NMCSDKLib.MC_STATUS.MC_OK)
{
return true;
}
else
{
throw new Exception($"Board_Id : {Board_Id}, Device_Id : {Device_Id}, " + mc.ToString());
}
}
catch (Exception ex)
{
//WriteExceptionLog(MethodBase.GetCurrentMethod().Name, ex);
return false;
}
}
///
/// Axis Amp Off
///
///
public bool Amp_Off()
{
try
{
NMCSDKLib.MC_STATUS mc;
mc = NMCSDKLib.MC_Power(Board_Id, Device_Id, false);
if (mc == NMCSDKLib.MC_STATUS.MC_OK)
{
return true;
}
else
{
throw new Exception($"Board_Id : {Board_Id}, Device_Id : {Device_Id}, " + mc.ToString());
}
}
catch (Exception ex)
{
//WriteExceptionLog(MethodBase.GetCurrentMethod().Name, ex);
return false;
}
}
///
/// Axis MC Error Reset
///
///
public bool MC_Error_Reset()
{
try
{
NMCSDKLib.MC_STATUS mc;
mc = NMCSDKLib.MC_Reset(Board_Id, Device_Id);
if (mc == NMCSDKLib.MC_STATUS.MC_OK)
{
return true;
}
else
{
throw new Exception($"Board_Id : {Board_Id}, Device_Id : {Device_Id}, " + mc.ToString());
}
}
catch (Exception ex)
{
//WriteExceptionLog(MethodBase.GetCurrentMethod().Name, ex);
return false;
}
}
///
/// Zog Move Negative
///
/// velocity
/// accelator
/// deccelator
/// jerk
///
public bool Negative_Zog(double Velocity)
{
try
{
if (Check_Jog_Interlock != null && Check_Jog_Interlock(false))
{
return false;
}
if (Velocity <= 0)
{
Interlock_Manager.Add_Interlock_Msg($"{((MotorAxis)Device_Id).ToString()} can't minus jog", $"{((MotorAxis)Device_Id).ToString()}'s velocity is under 0");
return false;
}
if(!Auto_Mode)
{
if(Velocity > teach_velocity)
{
Velocity = teach_velocity;
}
}
NMCSDKLib.MC_STATUS mc;
double Accel = Velocity * 10;
double Decel = Velocity * 10;
double Jerk = Velocity * 100;
mc = NMCSDKLib.MC_MoveVelocity(Board_Id, Device_Id, Velocity, Accel, Decel, Jerk, NMCSDKLib.MC_DIRECTION.mcNegativeDirection, NMCSDKLib.MC_BUFFER_MODE.mcAborting);
if (mc == NMCSDKLib.MC_STATUS.MC_OK)
{
return true;
}
else
{
throw new Exception($"Board_Id : {Board_Id}, Device_Id : {Device_Id}, " + mc.ToString());
}
}
catch (Exception ex)
{
//WriteExceptionLog(MethodBase.GetCurrentMethod().Name, ex);
return false;
}
}
///
/// Zog Move Positive
///
/// velocity
/// accelator
/// deccelator
/// jerk
///
public bool Positive_Zog(double Velocity)
{
try
{
if(Check_Jog_Interlock != null && Check_Jog_Interlock(true))
{
return false;
}
if(Velocity <= 0)
{
Interlock_Manager.Add_Interlock_Msg($"{((MotorAxis)Device_Id).ToString()} can't plus jog", $"{((MotorAxis)Device_Id).ToString()}'s velocity is under 0");
return false;
}
if (!Auto_Mode)
{
if (Velocity > teach_velocity)
{
Velocity = teach_velocity;
}
}
NMCSDKLib.MC_STATUS mc;
double Accel = Velocity * 10;
double Decel = Velocity * 10;
double Jerk = Velocity * 100;
mc = NMCSDKLib.MC_MoveVelocity(Board_Id, Device_Id, Velocity, Accel, Decel, Jerk, NMCSDKLib.MC_DIRECTION.mcPositiveDirection, NMCSDKLib.MC_BUFFER_MODE.mcAborting);
if (mc == NMCSDKLib.MC_STATUS.MC_OK)
{
return true;
}
else
{
throw new Exception($"Board_Id : {Board_Id}, Device_Id : {Device_Id}, " + mc.ToString());
}
}
catch (Exception ex)
{
//WriteExceptionLog(MethodBase.GetCurrentMethod().Name, ex);
return false;
}
}
///
/// Home
///
///
public bool Home()
{
try
{
if(Check_Home_Interlock !=null && Check_Home_Interlock())
{
return false;
}
NMCSDKLib.MC_STATUS mc;
mc = NMCSDKLib.MC_Home(Board_Id, Device_Id, 0, NMCSDKLib.MC_BUFFER_MODE.mcAborting);
if (mc == NMCSDKLib.MC_STATUS.MC_OK)
{
return true;
}
else
{
throw new Exception($"Board_Id : {Board_Id}, Device_Id : {Device_Id}, " + mc.ToString());
}
}
catch (Exception ex)
{
//WriteExceptionLog(MethodBase.GetCurrentMethod().Name, ex);
return false;
}
}
///
/// Axis Move Stop
///
/// deccelator
/// jerk
///
public bool Move_Stop(double Velocity = 300)
{
try
{
if (Velocity <= 0)
{
Velocity = 300;
}
NMCSDKLib.MC_STATUS mc;
double Decel = Velocity * 10;
double Jerk = Velocity * 100;
mc = NMCSDKLib.MC_Halt(Board_Id, Device_Id, Decel, Jerk, NMCSDKLib.MC_BUFFER_MODE.mcAborting);
if (mc == NMCSDKLib.MC_STATUS.MC_OK)
{
return true;
}
else
{
return false;
//throw new Exception($"Board_Id : {Board_Id}, Device_Id : {Device_Id}, " + mc.ToString());
}
}
catch (Exception ex)
{
//WriteExceptionLog(MethodBase.GetCurrentMethod().Name, ex);
return false;
}
}
///
/// Move absololute
///
/// positiion
/// velocity
/// accelator
/// deccelator
/// jerk
///
public bool Move_Absolute_Pos(double Position, double Velocity)
{
try
{
if (Check_Move_Interlock != null && Check_Move_Interlock())
{
return false;
}
if (Velocity <= 0)
{
Interlock_Manager.Add_Interlock_Msg($"{((MotorAxis)Device_Id).ToString()} can't absolute move", $"{((MotorAxis)Device_Id).ToString()}'s velocity is under 0");
return false;
}
if (!Auto_Mode)
{
if (Velocity > teach_velocity)
{
Velocity = teach_velocity;
}
}
NMCSDKLib.MC_STATUS mc;
double Accel = Velocity * 10;
double Decel = Velocity * 10;
double Jerk = Velocity * 100;
mc = NMCSDKLib.MC_MoveAbsolute(Board_Id, Device_Id, Position, Velocity, Accel, Decel, Jerk, NMCSDKLib.MC_DIRECTION.mcPositiveDirection, NMCSDKLib.MC_BUFFER_MODE.mcAborting);
if (mc == NMCSDKLib.MC_STATUS.MC_OK)
{
return true;
}
else
{
throw new Exception($"Board_Id : {Board_Id}, Device_Id : {Device_Id}, " + mc.ToString());
}
}
catch (Exception ex)
{
//WriteExceptionLog(MethodBase.GetCurrentMethod().Name, ex);
return false;
}
}
///
/// Move Relative
///
/// distance
/// velocity
/// accelator
/// deccelator
/// jerk
///
public bool Move_Relative_Pos(double Distance, double Velocity)
{
try
{
if (Check_Move_Interlock != null && Check_Move_Interlock())
{
return false;
}
if (Velocity <= 0)
{
Interlock_Manager.Add_Interlock_Msg($"{((MotorAxis)Device_Id).ToString()} can't relative move", $"{((MotorAxis)Device_Id).ToString()}'s velocity is under 0");
return false;
}
if (!Auto_Mode)
{
if (Velocity > teach_velocity)
{
Velocity = teach_velocity;
}
}
double Accel = Velocity * 10;
double Decel = Velocity * 10;
double Jerk = Velocity * 100;
NMCSDKLib.MC_STATUS mc;
mc = NMCSDKLib.MC_MoveRelative(Board_Id, Device_Id, Distance, Velocity, Accel, Decel, Jerk, NMCSDKLib.MC_BUFFER_MODE.mcAborting);
if (mc == NMCSDKLib.MC_STATUS.MC_OK)
{
return true;
}
else
{
throw new Exception($"Board_Id : {Board_Id}, Device_Id : {Device_Id}, " + mc.ToString());
}
}
catch (Exception ex)
{
//WriteExceptionLog(MethodBase.GetCurrentMethod().Name, ex);
return false;
}
}
///
/// Get actual position
///
/// position
///
public bool Get_Actual_Position()
{
try
{
double dData = 0;
NMCSDKLib.MC_STATUS mc;
mc = NMCSDKLib.MC_ReadCommandedPosition(Board_Id, Device_Id, ref dData);
if (mc == NMCSDKLib.MC_STATUS.MC_OK)
{
Position = double.Parse(dData.ToString("F3"));
return true;
}
else
{
Position = 0;
throw new Exception($"Board_Id : {Board_Id}, Device_Id : {Device_Id}, " + mc.ToString());
}
}
catch (Exception ex)
{
//WriteExceptionLog(MethodBase.GetCurrentMethod().Name, ex);
return false;
}
}
///
/// Get actual velocity
///
/// velocity
///
public bool Get_Actual_Velocity()
{
try
{
double dData = 0;
NMCSDKLib.MC_STATUS mc;
mc = NMCSDKLib.MC_ReadCommandedVelocity(Board_Id, Device_Id, ref dData);
if (mc == NMCSDKLib.MC_STATUS.MC_OK)
{
Velocity = double.Parse(dData.ToString("F3"));
return true;
}
else
{
Velocity = 0;
throw new Exception($"Board_Id : {Board_Id}, Device_Id : {Device_Id}, " + mc.ToString());
}
}
catch (Exception ex)
{
//WriteExceptionLog(MethodBase.GetCurrentMethod().Name, ex);
return false;
}
}
public bool Position_Clear()
{
try
{
NMCSDKLib.MC_STATUS mc;
mc = NMCSDKLib.MC_SetPosition(Board_Id, Device_Id, 0, false, NMCSDKLib.MC_EXECUTION_MODE.mcImmediately);
if (mc == NMCSDKLib.MC_STATUS.MC_OK)
{
return true;
}
else
{
throw new Exception($"Board_Id : {Board_Id}, Device_Id : {Device_Id}, " + mc.ToString());
}
}
catch (Exception ex)
{
//WriteExceptionLog(MethodBase.GetCurrentMethod().Name, ex);
return false;
}
}
///
/// Get Error Info
///
///
public bool ErrorInfo()
{
try
{
NMCSDKLib.MC_STATUS mc;
ushort usErrorId = 0;
ushort usErrorInfo0 = 0;
ushort usErrorInfo1 = 0;
mc = NMCSDKLib.MC_ReadAxisError(Board_Id, Device_Id, ref usErrorId, ref usErrorInfo0, ref usErrorInfo1);
if (mc == NMCSDKLib.MC_STATUS.MC_OK)
{
ErrorID = usErrorId;
ErrorInfo0 = usErrorInfo0;
ErrorInfo1 = usErrorInfo1;
return true;
}
else
{
ErrorID = 0;
ErrorInfo0 = 0;
ErrorInfo1 = 0;
throw new Exception($"Board_Id : {Board_Id}, Device_Id : {Device_Id}, " + mc.ToString());
}
}
catch (Exception ex)
{
//WriteExceptionLog(MethodBase.GetCurrentMethod().Name, ex);
return false;
}
}
public bool Is_Inposition(double position, double offset)
{
if (position - offset <= this.Position && this.Position <= position + offset)
{
return true;
}
else
{
return false;
}
}
#endregion
}
}