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 } }