using CSZTM; using GTN; using gts; using Rs.Framework; using Rs.Motion.Base; using Rs.Motion.Base.Config; using System; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Text; using System.Threading; using System.Threading.Tasks; namespace Rs.Motion.GugaoPulse { public class GugaoPulseAxis:IAxis { public GugaoPulseAxis(AxisConfig config) { Config = config; } private GugaoPulseCardManager cardManager = GugaoPulseCardManager.Instance; private short apiResult = 0; private double m_dfCommandPosition = 0.0; private object m_objLocker = new object(); /// /// 轴初始化,设置轴参数 /// /// public override ErrorCode Init() { mc_pulse_cfg.TAxisConfig axisConfig; apiResult = mc_pulse_cfg.GT_GetAxisConfig((short)Config.CardId,(short)Config.AxisId,out axisConfig); mc_pulse_cfg.TDiConfig diConfig; if (!cardManager.IsInitialized) { return ErrorCode.CardNotInit; } HomeStatus = EHomeStatus.NotStart; if (Config.EnableAlarm == 0) { mc_pulse.GT_AlarmOff((short)Config.CardId, (short)Config.AxisId); } else if (Config.EnableAlarm == 1) { axisConfig.alarmIndex = (short)Config.AxisId; apiResult = mc_pulse_cfg.GT_GetDiConfig((short)Config.CardId, mc_pulse.MC_ALARM, (short)Config.AxisId, out diConfig); diConfig.active = 1; diConfig.reverse = (short)Config.AlarmLogic; diConfig.filterTime = 3; apiResult = mc_pulse_cfg.GT_SetDiConfig((short)Config.CardId, mc_pulse.MC_ALARM, (short)Config.AxisId, ref diConfig); } mc_pulse_cfg.GT_GetDoConfig((short)Config.CardId, mc_pulse.MC_GPO, 11, out mc_pulse_cfg.TDoConfig oConfig); oConfig.reverse = 0; mc_pulse_cfg.GT_SetDoConfig((short)Config.CardId, mc_pulse.MC_GPO, 11, ref oConfig); mc_pulse_cfg.GT_GetDoConfig((short)Config.CardId, mc_pulse.MC_GPO, 12, out oConfig); oConfig.reverse = 1; mc_pulse_cfg.GT_SetDoConfig((short)Config.CardId, mc_pulse.MC_GPO, 12, ref oConfig); mc_pulse_cfg.GT_GetDoConfig((short)Config.CardId, mc_pulse.MC_GPO, 13, out oConfig); oConfig.reverse = 1; mc_pulse_cfg.GT_SetDoConfig((short)Config.CardId, mc_pulse.MC_GPO, 13, ref oConfig); //先判断正限位 if ((Config.EnableEL & 0x01) == 0)//禁用正限位 { mc_pulse.GT_LmtsOff((short)Config.CardId, (short)Config.AxisId, mc_pulse.MC_LIMIT_POSITIVE); } else { axisConfig.limitPositiveIndex = (short)Config.AxisId; //axisConfig.alarmIndex = (short)Config.AxisId; apiResult = mc_pulse_cfg.GT_GetDiConfig((short)Config.CardId, mc_pulse.MC_LIMIT_POSITIVE, (short)Config.AxisId, out diConfig); diConfig.active = 1; diConfig.reverse = (short)Config.ElLogic; diConfig.filterTime = 3; apiResult = mc_pulse_cfg.GT_SetDiConfig((short)Config.CardId, mc_pulse.MC_LIMIT_POSITIVE, (short)Config.AxisId, ref diConfig); } //先判断负限位 if (((Config.EnableEL >> 1) & 0x01) == 0) { mc_pulse.GT_LmtsOff((short)Config.CardId, (short)Config.AxisId, mc_pulse.MC_LIMIT_NEGATIVE); } else { axisConfig.limitNegativeIndex = (short)Config.AxisId; apiResult = mc_pulse_cfg.GT_GetDiConfig((short)Config.CardId, mc_pulse.MC_LIMIT_NEGATIVE, (short)Config.AxisId, out diConfig); diConfig.active = 1; diConfig.reverse = (short)Config.ElLogic; diConfig.filterTime = 3; apiResult = mc_pulse_cfg.GT_SetDiConfig((short)Config.CardId, mc_pulse.MC_LIMIT_NEGATIVE, (short)Config.AxisId, ref diConfig); } apiResult = mc_pulse_cfg.GT_GetDiConfig((short)Config.CardId, mc_pulse.MC_HOME, (short)Config.AxisId, out diConfig); diConfig.active = 1; diConfig.reverse = (short)Config.HomeOrgLogic; diConfig.filterTime = 3; apiResult = mc_pulse_cfg.GT_SetDiConfig((short)Config.CardId, mc_pulse.MC_HOME, (short)Config.AxisId, ref diConfig); apiResult = mc_pulse_cfg.GT_SetAxisConfig((short)Config.CardId, (short)Config.AxisId, ref axisConfig); // mc_cfg.GT_SetDiConfig(short diType, short diIndex, ref TDiConfig pDi); //mc_pulse.GT_EncSns((short)Config.CardId, 0); mc_pulse.GT_ClrSts((short)Config.CardId, (short)Config.AxisId, 1); IsInitialized = true; return ErrorCode.Ok; } /// /// 反初始化轴,停止轴 /// /// public override ErrorCode Deinit() { IsInitialized = false; if (!cardManager.IsInitialized) { return ErrorCode.CardNotInit; } else { Stop(); Disable(); return ErrorCode.Ok; } } /// /// 毫米转脉冲 /// 总长度/电机转一圈走的长度*电机转一圈的脉冲数 /// /// /// /// public override ErrorCode MmToPulse(double mm, out double pulse) { pulse = 0; if (Config.DistOneRound == 0.0) { return ErrorCode.UndefineDistanceOneRound; } else { pulse = mm / Config.DistOneRound * (double)Config.PulseOneRound; return ErrorCode.Ok; } } /// /// 脉冲转毫米 /// 总脉冲数/电机转一圈的脉冲数*电机转一圈走的长度 /// /// /// /// public override ErrorCode PulseToMm(double pulse, out double mm) { mm = 0; if (Config.PulseOneRound == 0) { return ErrorCode.UndefinePulseOneRound; } else { mm = pulse / (double)Config.PulseOneRound * Config.DistOneRound; return ErrorCode.Ok; } } /// /// 使能电机 /// /// public override ErrorCode Enable() { if (!cardManager.IsInitialized) { return ErrorCode.CardNotInit; } else { apiResult = mc_pulse.GT_ClrSts((short)Config.CardId, (short)Config.AxisId, 1); if (apiResult != 0) return ErrorCode.Fail; apiResult = mc_pulse.GT_AxisOn((short)Config.CardId, (short)Config.AxisId); if (apiResult != 0) return ErrorCode.Fail; else return ErrorCode.Ok; } } /// /// 去使能 /// /// public override ErrorCode Disable() { if (!cardManager.IsInitialized) { return ErrorCode.CardNotInit; } apiResult = mc_pulse.GT_AxisOff((short)Config.CardId, (short)Config.AxisId); if (apiResult != 0) { return ErrorCode.Fail; } return ErrorCode.Ok; } /// /// 停止运动 /// /// public override ErrorCode Stop() { if (!cardManager.IsInitialized) { return ErrorCode.CardNotInit; } //int axes = 1 << m_axis_config.AxisId; //int option = 1 << m_axis_config.AxisId; apiResult = mc_pulse.GT_Stop((short)Config.CardId, 1 << Config.AxisId - 1, 1 << Config.AxisId - 1);//option 对应位1表示紧急停止 0 为平滑停止 if (apiResult != 0) return ErrorCode.Fail; else return ErrorCode.Ok; } /// /// 运动控制卡回零 /// /// public override ErrorCode Default_Home_Move() { //if (!m_motion_card.IsInitialized) //{ // return ErrorCode.CARD_NOT_INIT; //} //if (!m_bIsInitialized) //{ // return ErrorCode.AXIS_NOT_INIT; //} //ErrorCode err = MmToPulse(m_axis_config.HomeOffset, out double dfHome_offset); //if (err > ErrorCode.OK) //{ // return err; //} //err = MmToPulse(1.0, out double dfPulseRaio); //m_LastErrorCode = ZTM.ZT_SetHomePol(m_axis_config.CardMc, (short)m_axis_config.AxisId, (short)m_axis_config.HomeOrgLogic); //if (m_LastErrorCode != 0) //{ // return ErrorCode.FAIL; //} //MmToPulse(m_axis_config.HomeSpeed, out double homeSpeedPulse); ////acc vel/s mm/s pulse/s pulse/ms mm //MmToPulse(m_axis_config.MaxSpeed, out double maxSpeedPulse); //m_LastErrorCode = ZTM.ZT_SetHomeParam(m_axis_config.CardMc, // (short)m_axis_config.AxisId, // (short)m_axis_config.HomeDir, // (short)m_axis_config.HomeMode, // (float)((double)(homeSpeedPulse / 4) / 1000.0), // (float)((double)homeSpeedPulse / 1000.0), // (float)((maxSpeedPulse / 1000.0) / (m_axis_config.AccTime * 1000.0)), // (int)dfHome_offset, 0); //if (m_LastErrorCode != 0) //{ // return ErrorCode.FAIL; //} ////int axes = SetBit(0, (int)m_axis_config.AxisId, 1); ////m_LastErrorCode = ZTM.ZT_Home(m_axis_config.CardMc, (uint)axes); //if (m_LastErrorCode != 0) //{ // return ErrorCode.MOVE_FAIL; //} //else //{ // return ErrorCode.OK; //} return ErrorCode.Ok; } /// /// 绝对位置运动 /// /// /// /// /// public override ErrorCode MovePos(double dfPosVal, int nSpeedPercent = 4) { if (!cardManager.IsInitialized) return ErrorCode.CardNotInit; if (!IsInitialized) return ErrorCode.AxisNotInit; if (!SafeCheck()) return ErrorCode.Unsafe; //运动之前先清一下状态 ClearAlarm(); nSpeedPercent = nSpeedPercent <= 0 ? 10 : nSpeedPercent; nSpeedPercent = nSpeedPercent > 100 ? 100 : nSpeedPercent; if (HomeStatus != EHomeStatus.Finished) return ErrorCode.AxisNotHome; if (Config.EnableSoftwareEL == 1 && (dfPosVal > Config.PelSoftwarePosition || dfPosVal < Config.NelSoftwarePosition))//启用软限位 { return ErrorCode.OutOfLimit; } ErrorCode err = GetEmgStatus(out bool bEmg); if (err > ErrorCode.Ok) return err; if (bEmg) return ErrorCode.Emergency; err = GetAlarmStatus(out bool bAlarm); if (err > ErrorCode.Ok) return err; if (bAlarm) return ErrorCode.Alarm; err = IsEnable(out bool bEnable); if (err > ErrorCode.Ok) return err; if (!bEnable) return ErrorCode.ServoOff; err = IsStop(out bool bStop); if (err > ErrorCode.Ok) return err; if (!bStop) return ErrorCode.Moving; err = MmToPulse(dfPosVal, out double dfPos); if (err > ErrorCode.Ok) return err; double dfPercent = (double)nSpeedPercent / 100.0; MmToPulse(Config.MaxSpeed, out double maxSpeedPulse); MmToPulse(Config.MinSpeed, out double minSpeedPulse); MmToPulse(Config.StopSpeed, out double stopSpeedPulse); float fMaxVel = (float)(maxSpeedPulse * dfPercent / 1000.0);//pulse/ms //float fAcc = (float)(maxSpeedPulse / (accTime == 0 ? Config.AccTime : accTime) / 1000000.0); //float fDec = (float)(maxSpeedPulse / (decTime == 0 ? Config.DecTime : decTime) / 1000000.0); float fAcc = (float)(maxSpeedPulse / Config.AccTime / 1000000.0); float fDec = (float)(maxSpeedPulse / Config.DecTime / 1000000.0); float fStart = (float)(minSpeedPulse / 1000.0); float fStop = (float)(stopSpeedPulse / 1000.0); apiResult = mc_pulse.GT_PrfTrap((short)Config.CardId, (short)Config.AxisId);//设置运动模式为点位运动 if (apiResult != 0) { return ErrorCode.Fail; } apiResult = mc_pulse.GT_GetTrapPrm((short)Config.CardId, (short)Config.AxisId, out mc_pulse.TTrapPrm trapPrm);//获取点位运动参数 if (apiResult != 0) { return ErrorCode.Fail; } trapPrm.acc = fAcc; trapPrm.dec = fDec; trapPrm.velStart = fStart; apiResult = mc_pulse.GT_SetTrapPrm((short)Config.CardId, (short)Config.AxisId, ref trapPrm);//设置点位运动参数 if (apiResult != 0) { return ErrorCode.Fail; } apiResult = mc_pulse.GT_SetPos((short)Config.CardId, (short)Config.AxisId, (int)dfPos);//设置目标位置 if (apiResult != 0) { return ErrorCode.Fail; } apiResult = mc_pulse.GT_SetVel((short)Config.CardId, (short)Config.AxisId, fMaxVel);//设置目标速度 if (apiResult != 0) { return ErrorCode.Fail; } apiResult = mc_pulse.GT_Update((short)Config.CardId, (1 << Config.AxisId - 1)); if (apiResult != 0) { return ErrorCode.Fail; } else { m_dfCommandPosition = dfPosVal; LogHelper.MoveLog($"acc={trapPrm.acc},dec={trapPrm.dec},targetpos={m_dfCommandPosition},maxvel={fMaxVel}"); return ErrorCode.Ok; } } /// /// 相对当前位置运动 /// /// /// /// /// public override ErrorCode MoveOffset(double dfDistVal, int nSpeedPercent = 100) { if (!cardManager.IsInitialized) { return ErrorCode.CardNotInit; } if (!IsInitialized) { return ErrorCode.AxisNotInit; } if (!SafeCheck()) return ErrorCode.Unsafe; nSpeedPercent = nSpeedPercent <= 0 ? 10 : nSpeedPercent; nSpeedPercent = nSpeedPercent > 100 ? 100 : nSpeedPercent; double curPos = 0.0; ErrorCode err; if (Config.EnableEncoder == 1) { err = GetEncoderPosition(out curPos); if (err > ErrorCode.Ok) { return err; } } else { err = GetPrfPosition(out curPos); if (err > ErrorCode.Ok) { return err; } } double dstPos = curPos + dfDistVal; return MovePos(dstPos, nSpeedPercent); //bool isNotSafe = !bypassEL && (dstPos > Config.PelSoftwarePosition || dstPos < Config.NelSoftwarePosition) // && Config.PelSoftwarePosition != Config.NelSoftwarePosition; //if (isNotSafe) //{ // return ErrorCode.POSITION_OUT_OF_RANGE; //} err = GetEmgStatus(out bool bEmg); if (err > ErrorCode.Ok) { return err; } if (bEmg) { return ErrorCode.Emergency; } err = GetAlarmStatus(out bool bAlarm); if (err > ErrorCode.Ok) { return err; } if (bAlarm) { return ErrorCode.Alarm; } err = IsEnable(out bool bEnable); if (err > ErrorCode.Ok) { return err; } if (!bEnable) { return ErrorCode.ServoOff; } err = IsStop(out bool bStop); if (err > ErrorCode.Ok) { return err; } if (!bStop) { return ErrorCode.Moving; } //return MovePos(dstPos, nSpeedPercent, bypassEL); err = MmToPulse(dstPos, out double dfPos); if (err > ErrorCode.Ok) { return err; } double dfPercent = (double)nSpeedPercent / 100.0; MmToPulse(Config.MaxSpeed, out double maxSpeedPulse); MmToPulse(Config.MinSpeed, out double minSpeedPulse); MmToPulse(Config.StopSpeed, out double stopSpeedPulse); float fMaxVel = (float)(maxSpeedPulse * dfPercent / 1000.0);//pulse/ms float fAcc = (float)(maxSpeedPulse / Config.AccTime / 1000000.0);//pulse/ms2 float fDec = (float)(maxSpeedPulse / Config.DecTime / 1000000.0);//pulse/ms2 float fStart = (float)(minSpeedPulse / 1000.0);//pulse/ms float fStop = (float)(stopSpeedPulse / 1000.0);//pulse/ms apiResult = mc_pulse.GT_PrfTrap((short)Config.CardId, (short)Config.AxisId);//设置运动模式为点位运动 if (apiResult != 0) { return ErrorCode.Fail; } apiResult = mc_pulse.GT_GetTrapPrm((short)Config.CardId, (short)Config.AxisId, out mc_pulse.TTrapPrm trapPrm);//获取点位运动参数 if (apiResult != 0) { return ErrorCode.Fail; } trapPrm.acc = fAcc; trapPrm.dec = fDec; trapPrm.velStart = fStart; apiResult = mc_pulse.GT_SetTrapPrm((short)Config.CardId, (short)Config.AxisId, ref trapPrm);//设置点位运动参数 if (apiResult != 0) { return ErrorCode.Fail; } apiResult = mc_pulse.GT_SetPos((short)Config.CardId, (short)Config.AxisId, (int)dfPos);//设置目标位置 if (apiResult != 0) { return ErrorCode.Fail; } apiResult = mc_pulse.GT_SetVel((short)Config.CardId, (short)Config.AxisId, fMaxVel);//设置目标速度 if (apiResult != 0) { return ErrorCode.Fail; } apiResult = mc_pulse.GT_Update((short)Config.CardId, (1 << Config.AxisId - 1)); if (apiResult != 0) { return ErrorCode.Fail; } else { m_dfCommandPosition = dstPos; return ErrorCode.Ok; } } public override ErrorCode MoveJog(short dir, int nSpeedPercent = 10) { if (!cardManager.IsInitialized) { return ErrorCode.CardNotInit; } if (!IsInitialized) { return ErrorCode.AxisNotInit; } if (!SafeCheck()) return ErrorCode.Unsafe; nSpeedPercent = nSpeedPercent <= 0 ? 10 : nSpeedPercent; nSpeedPercent = nSpeedPercent > 100 ? 100 : nSpeedPercent; ErrorCode err = IsEnable(out bool bEnable); if (err > ErrorCode.Ok) { return err; } if (!bEnable) { return ErrorCode.ServoOff; } err = IsStop(out bool bStop); if (err > ErrorCode.Ok) { return err; } if (!bStop) { return ErrorCode.Moving; } err = GetEmgStatus(out bool bEmg); if (err > ErrorCode.Ok) { return err; } if (bEmg) { return ErrorCode.Emergency; } err = GetAlarmStatus(out bool bAlarm); if (err > ErrorCode.Ok) { return err; } if (bAlarm) { return ErrorCode.Alarm; } else { double dfPercent = (double)nSpeedPercent / 100.0; MmToPulse(Config.MaxSpeed, out double maxSpeedPulse); MmToPulse(Config.MinSpeed, out double minSpeedPulse); MmToPulse(Config.StopSpeed, out double stopSpeedPulse); float fMaxVel = (float)(maxSpeedPulse * dfPercent / 1000.0);//pulse/ms float fAcc = (float)(maxSpeedPulse / Config.AccTime / 1000000.0); float fDec = (float)(maxSpeedPulse / Config.DecTime / 1000000.0); float fStart = (float)(minSpeedPulse / 1000.0); float fStop = (float)(stopSpeedPulse / 1000.0); apiResult = mc_pulse.GT_PrfJog((short)Config.CardId, (short)Config.AxisId);//设置运动模式为JOG运动模式 if (apiResult != 0) { return ErrorCode.Fail; } apiResult = mc_pulse.GT_GetJogPrm((short)Config.CardId, (short)Config.AxisId, out mc_pulse.TJogPrm jogPrm); if (apiResult != 0) { return ErrorCode.Fail; } jogPrm.acc = fAcc; jogPrm.dec = fDec; apiResult = mc_pulse.GT_SetJogPrm((short)Config.CardId, (short)Config.AxisId, ref jogPrm); if (apiResult != 0) { return ErrorCode.Fail; } if (dir == 0) { fMaxVel = -1 * fMaxVel; } apiResult = mc_pulse.GT_SetVel((short)Config.CardId, (short)Config.AxisId, fMaxVel); if (apiResult != 0) { return ErrorCode.Fail; } apiResult = mc_pulse.GT_Update((short)Config.CardId, 1< m_axis_config.PelSoftwarePosition || dfNewPosVal < m_axis_config.NelSoftwarePosition) // && m_axis_config.PelSoftwarePosition != m_axis_config.NelSoftwarePosition; //if (isNotSafe) //{ // return ErrorCode.POSITION_OUT_OF_RANGE; //} //ErrorCode err = GetEmgStatus(out bool bEmg); //if (err > ErrorCode.OK) //{ // return err; //} //if (bEmg) //{ // return ErrorCode.EMERGENCY; //} //err = GetAlarmStatus(out bool bAlarm); //if (err > ErrorCode.OK) //{ // return err; //} //if (bAlarm) //{ // return ErrorCode.ALARM; //} //err = IsEnable(out bool bEnable); //if (err > ErrorCode.OK) //{ // return err; //} //if (bEnable) //{ // return ErrorCode.SERVO_OFF; //} //err = MmToPulse(dfNewPosVal, out double dfPos); //if (err > ErrorCode.OK) //{ // return err; //} //else //{ // m_dfCommandPosition = dfNewPosVal; // bool flag19 = m_LastErrorCode != 0; // if (flag19) // { // return ErrorCode.FAIL; // } // else // { // return ErrorCode.OK; // } //} return ErrorCode.Ok; } // Token: 0x06000256 RID: 598 RVA: 0x0000373C File Offset: 0x0000193C public override ErrorCode ChangeSpeed(double dfNewSpeed) { //if (!m_motion_card.IsInitialized) //{ // return ErrorCode.CARD_NOT_INIT; //} //if (!m_bIsInitialized) //{ // return ErrorCode.AXIS_NOT_INIT; //} //if (dfNewSpeed <= m_axis_config.MinSpeed) //{ // dfNewSpeed = m_axis_config.MinSpeed; //} //if (dfNewSpeed >= m_axis_config.MaxSpeed) //{ // dfNewSpeed = m_axis_config.MaxSpeed; //} return ErrorCode.Ok; } /// /// 判断轴是否使能 /// /// /// public override ErrorCode IsEnable(out bool bIsEable) { bIsEable = false; if (!cardManager.IsInitialized) { return ErrorCode.CardNotInit; } apiResult = mc_pulse.GT_GetSts((short)Config.CardId, (short)Config.AxisId, out int pSts, 1, out uint pClock); if (apiResult != 0) { return ErrorCode.Fail; } else { bIsEable = ((pSts >> 9) & 0x01) == 1; return ErrorCode.Ok; } } /// /// 运动控制卡回零 /// /// public void DefaultHome(object obj) { if (!SafeCheck()) { MessageQueue.Instance.Insert($"{Config.AxisName} go home unsafe"); return; } MessageQueue.Instance.Insert($"{Config.AxisName} go home"); //判断是否在原点 GetOrgStatus(out bool bOrg); if(bOrg) { //如果在原点,向回原方向的反方向运动直到离开原点 if(Config.HomeDir==1) { MoveJog(0, 2); } else { MoveJog(1, 2); } while (true && bOrg) { GetOrgStatus(out bOrg); } Stop(); Thread.Sleep(100); } mc_pulse.GT_ZeroPos((short)Config.CardId,(short)Config.AxisId, 1); HomeStatus = EHomeStatus.Start; MmToPulse(Config.HomeOffset, out double dfHome_offset); MmToPulse(Config.HomeSpeed, out double homeSpeedPulse); mc_pulse.THomePrm homePrm; apiResult = mc_pulse.GT_GetHomePrm((short)Config.CardId, (short)Config.AxisId, out homePrm); homePrm.mode = (short)Config.HomeMode; homePrm.moveDir = (short)Config.HomeDir; homePrm.indexDir = (short)(Config.HomeDir * -1); homePrm.velHigh = ((double)homeSpeedPulse / 1000.0); homePrm.velLow = (float)((double)(homeSpeedPulse / 10) / 1000.0); homePrm.acc = ((homeSpeedPulse / 1000.0) / (Config.AccTime * 1000.0)); homePrm.dec = ((homeSpeedPulse / 1000.0) / (Config.AccTime * 1000.0)); //homePrm.pad1_1 = 0; homePrm.homeOffset = (int)dfHome_offset; homePrm.searchHomeDistance = 0; homePrm.searchIndexDistance = 0; homePrm.edge = (short)(Config.HomeOrgLogic == 0 ? 1 : 0); apiResult = mc_pulse.GT_GoHome((short)Config.CardId, (short)Config.AxisId, ref homePrm); // LogHelper.Debug($"axis {Config.AxisName} start home ,homedir={Config.HomeDir},homemode={Config.HomeMode}"); if (apiResult != 0) { MessageQueue.Instance.Insert($"{Config.AxisName} go home fail ret:{apiResult}"); HomeStatus = EHomeStatus.Fail; } Stopwatch timer = new Stopwatch(); timer.Restart(); while (HomeStatus != EHomeStatus.Finished && HomeStatus != EHomeStatus.Abort && timer.ElapsedMilliseconds < 2 * 60 * 1000) { mc_pulse.GT_GetHomeStatus((short)Config.CardId, (short)Config.AxisId, out mc_pulse.THomeStatus pHomeStatus); //MessageQueue.Instance.Insert($"run={pHomeStatus.run},stage={pHomeStatus.stage},err={pHomeStatus.error}"); //MessageQueue.Instance.Insert($"run={pHomeStatus.run},stage={pHomeStatus.stage},err={pHomeStatus.error}"); Thread.Sleep(10); if(pHomeStatus.run==0 && pHomeStatus.stage==100 && pHomeStatus.error==0) { Thread.Sleep(500); mc_pulse.GT_ZeroPos((short)Config.CardId, (short)Config.AxisId, 1); mc_pulse.GT_ClrSts((short)Config.CardId, (short)Config.AxisId, 1); HomeStatus = EHomeStatus.Finished; break; } } } /// /// 判断轴是否回零 /// /// /// public override ErrorCode IsHomed(out bool bIsHomed) { bIsHomed = false; if (!cardManager.IsInitialized) { return ErrorCode.CardNotInit; } if (HomeStatus == EHomeStatus.Finished) { bIsHomed = true; } return ErrorCode.Ok; } /// /// 判断轴是否已停止 /// /// /// public override ErrorCode IsStop(out bool bIsStop) { bIsStop = false; if (!cardManager.IsInitialized) { return ErrorCode.CardNotInit; } apiResult = mc_pulse.GT_GetSts((short)Config.CardId, (short)Config.AxisId, out int pSts, 1, out uint pClock); if (apiResult != 0) { return ErrorCode.Fail; } bool warning= ((pSts >> 1) & 0x01) == 1; if (warning) { return ErrorCode.Alarm; } else { bIsStop = ((pSts >> 10) & 0x01) == 0; } return ErrorCode.Ok; } public override ErrorCode IsArrived(out bool bIsArrived) { bIsArrived = false; if (!cardManager.IsInitialized) { return ErrorCode.CardNotInit; } bool bIsStop = false; ErrorCode err = IsStop(out bIsStop); if (err > ErrorCode.Ok) { return err; } if (!bIsStop) { return ErrorCode.Ok; } double currentPos = 0.0; if(Config.EnableEncoder==1) { GetEncoderPosition(out currentPos); } else { GetPrfPosition(out currentPos); } bIsArrived = Math.Abs((currentPos - m_dfCommandPosition)) < 0.05; return ErrorCode.Ok; } /// /// 判断运动是否到位 /// /// /// public override ErrorCode IsInPosition(out bool bIsInPosition) { bIsInPosition = false; if (!cardManager.IsInitialized) { return ErrorCode.CardNotInit; } if (0 == Config.EnableEncoder)//步进 { return IsStop(out bIsInPosition); } bool bIsStop = false; ErrorCode err = IsStop(out bIsStop); if (err > ErrorCode.Ok) { return err; } if (!bIsStop) { return ErrorCode.Ok; } bool bINP = false; err = GetInpStatus(out bINP); if (err > ErrorCode.Ok) { return err; } if (!bINP) { return ErrorCode.Ok; } double dfCurrentTorlance = 0.0; double dfTorlance = Math.Abs(Config.Tolerance); err = GetTolerance(out dfCurrentTorlance); if (Math.Abs(dfCurrentTorlance) <= dfTorlance) { bIsInPosition = true; } return err; } /// /// 获取规划位置 /// /// /// public override ErrorCode GetPrfPosition(out double dfCmdPos) { dfCmdPos = 0.0; ErrorCode err = ErrorCode.Fail; if (!cardManager.IsInitialized) { return ErrorCode.CardNotInit; } try { lock (m_objLocker) { apiResult = mc_pulse.GT_GetPrfPos((short)Config.CardId, (short)Config.AxisId, out double pValue, 1, out uint pClock); //apiResult = mc_ecat.GTN_ReadAuEncPos(core, (short)Config.AxisId, out double pValue, 1); if (apiResult != 0) { return ErrorCode.Fail; } err = PulseToMm(pValue, out dfCmdPos); } } catch { } return err; } /// /// 获取编码器位置 /// /// /// public override ErrorCode GetEncoderPosition(out double dfEncPos) { dfEncPos = 0.0; ErrorCode err = ErrorCode.Fail; if (!cardManager.IsInitialized) { return ErrorCode.CardNotInit; } if (0 == Config.EnableEncoder) { return GetPrfPosition(out dfEncPos); } try { lock (m_objLocker) { apiResult = mc_pulse.GT_GetEncPos((short)Config.CardId, (short)Config.AxisId, out double pValue, 1, out uint pClock); if (apiResult != 0) { return ErrorCode.Fail; } err = PulseToMm(pValue, out dfEncPos); } } catch { } return err; } public override ErrorCode GetAuEncoderPosition(out double dfCmdPos) { dfCmdPos = 0.0; ErrorCode err = ErrorCode.Fail; //if (!cardManager.IsInitialized) //{ // return ErrorCode.CardNotInit; //} //try //{ // lock (m_objLocker) // { // apiResult = mc_ecat.GTN_ReadAuEncPos(core, (short)Config.AxisId, out double pValue, 1); // if (apiResult != 0) // { // return ErrorCode.Fail; // } // err = PulseToMm(pValue, out dfCmdPos); // } //} //catch //{ //} return err; } /// /// 获取编码器位置 /// /// /// public override ErrorCode GetDriverPosition(out double dfDriverPos) { dfDriverPos = 0.0; ErrorCode err = ErrorCode.Fail; //if (!cardManager.IsInitialized) //{ // return ErrorCode.CardNotInit; //} //try //{ // lock (m_objLocker) // { // apiResult = mc_ecat.GTN_GetEcatEncPos(core, (short)Config.AxisId, out int pValue);// ZTM.ZT_GetPosEncoder(m_axis_config.CardMc, (short)m_axis_config.AxisId, ref iPos); // if (apiResult != 0) // { // return ErrorCode.Fail; // } // err = PulseToMm(pValue, out dfDriverPos); // } //} //catch //{ //} return err; } /// /// 获取轴允许的公差值 /// /// /// public override ErrorCode GetTolerance(out double dfTolerance) { dfTolerance = 0.0; ErrorCode err; if (0 == Config.EnableEncoder) { return ErrorCode.Ok; } if (!cardManager.IsInitialized) { return ErrorCode.CardNotInit; } err = GetPrfPosition(out double dfTargetPos); if (err > ErrorCode.Ok) { return err; } err = GetEncoderPosition(out double dfCurrentPos); if (err > ErrorCode.Ok) { return err; } dfTolerance = dfCurrentPos - dfTargetPos; double dfTolerance2 = dfCurrentPos - m_dfCommandPosition; if (Math.Abs(dfTolerance) < Math.Abs(dfTolerance2)) { dfTolerance = dfTolerance2; } return ErrorCode.Ok; } /// /// 获取正限位状态 /// /// /// public override ErrorCode GetPelStatus(out bool bIsOn) { apiResult = mc_pulse.GT_GetDi((short)Config.CardId, mc_pulse.MC_LIMIT_POSITIVE, out int pValue); bIsOn = (pValue >> (Config.AxisId - 1) & 0x01) == 1; // bIsOn = false; // //apiResult = mc_pulse.GT_GetDi((short)Config.CardId, mc_ecat.MC_LIMIT_POSITIVE, out int pValue); //apiResult = mc_pulse.GT_GetSts((short)Config.CardId, (short)Config.AxisId, out int pSts, 1, out uint pClock); // if (apiResult != 0) // { // return ErrorCode.Fail; // } // bIsOn = (pSts >> 5 & 0x01) == 1; return ErrorCode.Ok; } /// /// 获取负限位状态 /// /// /// public override ErrorCode GetNelStatus(out bool bIsOn) { apiResult = mc_pulse.GT_GetDi((short)Config.CardId, mc_pulse.MC_LIMIT_NEGATIVE, out int pValue); bIsOn = (pValue >> (Config.AxisId - 1) & 0x01) == 1; //bIsOn = false; //apiResult = mc_pulse.GT_GetSts((short)Config.CardId, (short)Config.AxisId, out int pSts, 1, out uint pClock); //if (apiResult != 0) //{ // return ErrorCode.Fail; //} //bIsOn = (pSts >> 6 & 0x01) == 1; return ErrorCode.Ok; } /// /// 获取原点的状态 /// /// /// public override ErrorCode GetOrgStatus(out bool bIsOn) { bIsOn = false; apiResult = mc_pulse.GT_GetDi((short)Config.CardId, mc_ecat.MC_HOME, out int pValue); if (apiResult != 0) { return ErrorCode.Fail; } bIsOn = (pValue >> (Config.AxisId-1) & 0x01) == 1; return ErrorCode.Ok; } /// /// 获取报警状态 /// /// /// public override ErrorCode GetAlarmStatus(out bool bIsOn) { bIsOn = false; apiResult = mc_pulse.GT_GetDi((short)Config.CardId, mc_ecat.MC_ALARM, out int pValue); if (apiResult != 0) { return ErrorCode.Fail; } bIsOn = ((pValue >> Config.AxisId - 1) & 0x01) == 1; if (bIsOn) { HomeStatus = EHomeStatus.NotStart; } return ErrorCode.Ok; } /// /// 获取EMG状态 /// /// /// public override ErrorCode GetEmgStatus(out bool bIsOn) { bIsOn = false; apiResult = mc_pulse.GT_GetSts((short)Config.CardId, (short)Config.AxisId, out int pSts, 1, out uint pClock); if (apiResult != 0) { return ErrorCode.Fail; } bIsOn = ((pSts >> 8) & 0x01) == 1; return ErrorCode.Ok; } /// /// 获取到位信号 /// /// /// public override ErrorCode GetInpStatus(out bool bIsOn) { bIsOn = false; if (!cardManager.IsInitialized) { return ErrorCode.CardNotInit; } apiResult = mc_pulse.GT_GetSts((short)Config.CardId, (short)Config.AxisId, out int pSts, 1, out uint pClock); if (apiResult != 0) { return ErrorCode.Fail; } bIsOn = ((pSts >> 11) & 0x01) == 1; return ErrorCode.Ok; } /// /// 获取EZ状态 /// /// /// public override ErrorCode GetEzStatus(out bool bIsOn) { bIsOn = false; return ErrorCode.Ok; } /// /// 轴回原 /// /// /// public override ErrorCode Home() { if (HomeStatus == EHomeStatus.Homing || HomeStatus == EHomeStatus.Start) { return ErrorCode.Ok; } if (!cardManager.IsInitialized) { return ErrorCode.CardNotInit; } ErrorCode err = GetAlarmStatus(out bool bAlarm); if (err > ErrorCode.Ok) { return err; } if (bAlarm) { return ErrorCode.Alarm; } err = IsEnable(out bool bEnable); if (err > ErrorCode.Ok) { return err; } if (!bEnable) { return ErrorCode.ServoOff; } err = IsStop(out bool bStop); if (err > ErrorCode.Ok) { return err; } if (!bStop) { return ErrorCode.Moving; } Thread t = t = new Thread(new ParameterizedThreadStart(DefaultHome)); HomeStatus = EHomeStatus.Start; t.Name = Config.AxisName + " homing thread"; t.Start(this); return ErrorCode.Ok; } /// /// /// //protected void AutoHomeMode(object obj) //{ // bool bIsStop = false; // int searchDistance = 1000;//回原搜索距离 // double searchPulse = 0; // double curPos = 0.0; // //固高板块的回原点,可以用捕获回原,如果是步进电机采用直接回原的方式 // int pValue = 0; // if (Config.HomeDir == 0) // { // searchDistance *= -1; // } // MmToPulse(searchDistance, out searchPulse); // MmToPulse(Config.HomeSpeed, out double homeSpeedPulse); // MmToPulse(Config.MinSpeed, out double minSpeedPulse); // MmToPulse(Config.StopSpeed, out double stopSpeedPulse); // float fMaxVel = (float)(homeSpeedPulse / 1000.0);//pulse/ms // float fAcc = (float)(homeSpeedPulse / Config.AccTime / 1000000.0);//pulse/ms2 // float fDec = (float)(homeSpeedPulse / Config.DecTime / 1000000.0);//pulse/ms2 // float fStart = (float)(minSpeedPulse / 1000.0);//pulse/ms // float fStop = (float)(stopSpeedPulse / 1000.0);//pulse/ms // mc_pulse.GT_HomeInit((short)Config.CardId); // mc_pulse.GT_Home(apiResult, (short)Config.AxisId, (int)searchPulse, fMaxVel, fAcc, 0); // while(true) // { // mc_pulse.GT_HomeSts((short)Config.CardId,(short)Config.AxisId, out ushort pStatus); // if(pStatus==1) // { // ClearAlarm(); // HomeStatus = EHomeStatus.Finished; // break; // } // } //} /// /// /// /// protected void CaptureHome(object obj) { if(HomeJudge()) { bool bIsStop = false; int searchDistance = 1000;//回原搜索距离 double searchPulse = 0; double curPos = 0.0; //固高板块的回原点,可以用捕获回原,如果是步进电机采用直接回原的方式 short pStatus = 0; int pValue = 0; if (Config.HomeDir == 0) { searchDistance *= -1; } MmToPulse(searchDistance, out searchPulse); mc_pulse.GT_SetCaptureSense((short)Config.CardId, (short)Config.AxisId, mc_pulse.CAPTURE_HOME, (short)Config.HomeOrgLogic); //启动捕获回原 mc_pulse.GT_SetEncPos(0, 1, 0); mc_pulse.GT_SetPrfPos(0, 1, 0); if (Config.EnableEncoder == 1) { mc_pulse.GT_GetEncPos(0, 1, out curPos, 1, out uint pClock); } else { mc_pulse.GT_GetPrfPos(0, 1, out curPos, 1, out uint pClock); } apiResult = mc_pulse.GT_SetCaptureMode((short)Config.CardId, (short)Config.AxisId, mc_pulse.CAPTURE_HOME); if (apiResult != 0) { return; } double targetPos = curPos + searchPulse; MmToPulse(Config.HomeSpeed, out double homeSpeedPulse); MmToPulse(Config.MinSpeed, out double minSpeedPulse); MmToPulse(Config.StopSpeed, out double stopSpeedPulse); float fMaxVel = (float)(homeSpeedPulse / 1000.0);//pulse/ms float fAcc = (float)(homeSpeedPulse / Config.AccTime / 1000000.0);//pulse/ms2 float fDec = (float)(homeSpeedPulse / Config.DecTime / 1000000.0);//pulse/ms2 float fStart = (float)(minSpeedPulse / 1000.0);//pulse/ms float fStop = (float)(stopSpeedPulse / 1000.0);//pulse/ms apiResult = mc_pulse.GT_PrfTrap((short)Config.CardId, (short)Config.AxisId);//设置运动模式为点位运动 if (apiResult != 0) { return;// ErrorCode.Fail; } apiResult = mc_pulse.GT_GetTrapPrm((short)Config.CardId, (short)Config.AxisId, out mc_pulse.TTrapPrm trapPrm);//获取点位运动参数 if (apiResult != 0) { return;// ErrorCode.Fail; } trapPrm.acc = fAcc; trapPrm.dec = fDec; trapPrm.velStart = fStart; apiResult = mc_pulse.GT_SetTrapPrm((short)Config.CardId, (short)Config.AxisId, ref trapPrm);//设置点位运动参数 if (apiResult != 0) { return;// ErrorCode.Fail; } apiResult = mc_pulse.GT_SetPos((short)Config.CardId, (short)Config.AxisId, (int)targetPos);//设置目标位置 if (apiResult != 0) { return;// ErrorCode.Fail; } apiResult = mc_pulse.GT_SetVel((short)Config.CardId, (short)Config.AxisId, fMaxVel);//设置目标速度 if (apiResult != 0) { return;// ErrorCode.Fail; } apiResult = mc_pulse.GT_Update((short)Config.CardId, (1 << Config.AxisId - 1)); if (apiResult != 0) { return;// ErrorCode.Fail; } do { //获取捕获状态 apiResult = mc_pulse.GT_GetCaptureStatus((short)Config.CardId, (short)Config.AxisId, out pStatus, out pValue, 1, out uint pClock); IsStop(out bIsStop); if (bIsStop) { HomeStatus = EHomeStatus.Fail; return; } } while (pStatus == 0); MmToPulse(Config.HomeOffset, out double offsetPulse); targetPos = pValue + (int)offsetPulse; apiResult = mc_pulse.GT_SetPos((short)Config.CardId, (short)Config.AxisId, (int)targetPos);//设置目标位置 apiResult = mc_pulse.GT_Update((short)Config.CardId, (1 << Config.AxisId - 1)); do { IsStop(out bIsStop); } while (!bIsStop && HomeStatus != EHomeStatus.Abort); Thread.Sleep(500); Zero(0); HomeStatus = EHomeStatus.Finished; } } protected bool HomeJudge() { int persent = (int)((Config.HomeSpeed / Config.MaxSpeed) * 100); if (persent <= 0) persent = 2; bool bIsOrg = false; bool bIsPel = false; bool bIsNel = false; int homeStep = 0; while(homeStep>=0 && HomeStatus!= EHomeStatus.Abort) { switch (homeStep) { case 0://判断是否在原点,在原点,就先离开原点 GetOrgStatus(out bIsOrg); if(bIsOrg) { //离开原点 if(Config.HomeDir==0) { MoveJog(1, persent); } else { MoveJog(0, persent); } do { GetOrgStatus(out bIsOrg); } while (bIsOrg && HomeStatus!= EHomeStatus.Abort); Stop(); Thread.Sleep(500); homeStep = -1; } else homeStep = 1; break; case 1://判断是否在正限位 GetPelStatus(out bIsPel); if( bIsPel) { //先去找原点 MoveJog(0, persent); do { GetOrgStatus(out bIsOrg); } while (!bIsOrg && HomeStatus != EHomeStatus.Abort); Stop(); ClearAlarm(); Thread.Sleep(100); homeStep = 0; } else homeStep = 2; break; case 2://判断是否在负限位 GetNelStatus(out bIsNel); if( bIsNel ) { MoveJog(1, persent); do { GetOrgStatus(out bIsOrg); } while (!bIsOrg && HomeStatus != EHomeStatus.Abort); Stop(); ClearAlarm(); Thread.Sleep(100); homeStep = 0; } homeStep = 3; break; case 3://不在原点,也不在限位上,先朝回原方向搜索 if(Config.HomeDir==0) { MoveJog(0, persent); } else { MoveJog(1, persent); } //搜索的过程中,可能碰到原点,也可能碰到限位,碰到任何一个就停下来 do { GetOrgStatus(out bIsOrg); if (bIsOrg) { homeStep = 0; } GetPelStatus(out bIsPel); if (bIsPel) { homeStep = 1; } GetNelStatus(out bIsNel); if (bIsNel) { homeStep = 2; } } while (!bIsOrg && !bIsPel && !bIsNel && HomeStatus != EHomeStatus.Abort); Stop(); Thread.Sleep(100); break; default: break; } } if(HomeStatus!= EHomeStatus.Abort) { return true; } return false; } /// /// 回原完成 /// /// /// public override ErrorCode Zero(int iOrig) { if (!cardManager.IsInitialized) { return ErrorCode.CardNotInit; } if(!IsInitialized) { return ErrorCode.AxisNotInit; } apiResult = mc_pulse.GT_SetPrfPos((short)Config.CardId, (short)Config.AxisId, 0); if(apiResult!=0) { return ErrorCode.Fail; } if(Config.EnableEncoder==1) { apiResult = mc_pulse.GT_SetEncPos((short)Config.CardId, (short)Config.AxisId, 0); if (apiResult != 0) { return ErrorCode.Fail; } } return ErrorCode.Ok; } public void SetHomeFinished() { Zero(0); //base.Set_Home_Finished(); } /// /// 获取运动的目标位置 /// /// /// public override ErrorCode Get_Target_Position(out double dfTargetPos) { dfTargetPos = m_dfCommandPosition; return ErrorCode.Ok; } public override ErrorCode SetPosCompare(ushort channel, double[] postions) { int[] compareDatas = new int[postions.Length]; int[] companreData2s = new int[3]; for (int i=0;i