一、运动控制概述

运动控制技术是自动化技术和电气拖动技术的融合,以工控机、PLC、DSP等为控制器的运动控制技术融合了微电子技术、计算机技术、检测技术、自动化技术以及伺服控制技术等学科的新成果,在工业生产中起着极为重要的作用。

早期的运动控制技术主要是伴随着数控技术、机器人技术和工厂自动化技术的发展而发展的。现已广泛应用于国民经济的各个行业,且应用形式多种多样,主要应用领域如下:

1)冶金行业:电弧炉电机控制、轧机轧辊控制、产品定尺控制等。

2)机械行业:机床定位控制、加工轨迹控制、自动化流水线及机械手的控制等。

3)信息行业:磁盘驱动器磁头的定位控制、打印机的控制等。

4)建筑行业:电梯及电梯群的控制等。

5)其他行业:立体仓库和立体车库的控制等。

二、运动控制系统的组成

  • 控制器(PLC、运动控制卡、嵌入式系统)
  • 驱动器(步进、伺服驱动器)
  • 电机(步进电机、伺服电机、直线电机)
  • 反馈装置(编码器、光栅尺)

例如:在一个简单移动平台中,有一个Y轴可以进行送料的工作。主要由正运动的控制卡、汇川的驱动器、汇川的电机构成,当然我们一般会有一个主机,通用做法是一个电脑上编写有程序来控制板卡。

        电脑上的软件下发去某个位置的指令,其中包含速度、位置等;

        由正运动的控制卡负责将指令转换成驱动器命令,下发给伺服驱动器;

        伺服驱动器再将命令转换成电机需要的电压和电流,让电机运转,电机末端一般安装有编码器,伺服驱动器会一直采集编码器的脉冲信号来修改电压和电流直到到达目标位置。

三、运动控制算法

  • PID控制原理及优化
  • 前馈控制与扰动补偿
  • 轨迹规划(S曲线、T型速度规划)
  • 多轴同步控制

PID控制(比例-积分-微分控制)​

  •  

    原理​:通过比例项(P)快速响应误差、积分项(I)消除稳态误差、微分项(D)抑制振荡,实现动态平衡。

  •  

    特点​:结构简单、调试方便、稳定性高,但对非线性系统适应性弱。

  •  

    应用​:工业电机调速、恒温控制、无人机姿态调整等线性系统

四、运动控制通信协议

  • 脉冲方向控制
  • 总线协议(EtherCAT、CANopen、Modbus)

以下是运动控制通信协议的全面解析,涵盖脉冲方向控制总线协议(EtherCAT、CANopen、Modbus)​​ 的核心原理、技术特点及应用场景:


(一)、脉冲方向控制(Pulse-Direction Control)​

脉冲方向控制是伺服/步进电机最基础的位置控制方式,通过脉冲频率控制速度、脉冲数量控制位移、方向信号电平控制转向。

  1. 技术原理
    • 脉冲信号(PULSE)​​:

      每个脉冲对应电机固定角位移(步距角)。例如1.8°步进电机需200个脉冲完成一圈旋转。

      公式​:位移量 = 脉冲数 × 步距角 / 360°

    • 方向信号(DIR)​​:

      高电平(+24V)正转,低电平(0V)反转,需在脉冲输出前设定方向。

    • 差分信号抗干扰​:

      采用 PULSE+/PULSE-DIR+/DIR-差分对,提升长距离传输稳定性。

  2. 工作模式与配置

    模式

    信号逻辑

    适用场景

    脉冲+方向

    单路脉冲 + 方向电平(正转DIR=High,反转DIR=Low)

    低成本小型设备(≤200kHz)

    CW/CCW

    双路独立脉冲(CW脉冲=正转,CCW脉冲=反转)

    高速(>200kHz)或长距离传输

    A/B正交脉冲

    两路相位差90°的脉冲(A超前B=正转,A滞后B=反转)

    高精度编码器反馈系统

    驱动器需通过参数(如 H05.15)匹配控制器输出模式,否则导致方向错误或定位偏差。

  3. 关键参数设置

    • 电子齿轮比​:

      调节输入脉冲与实际位移的比例。

      公式​:实际位移 = 输入脉冲数 ×(电子齿轮分子 / 电子齿轮分母)。

      例:设置分子/分母=4/1,则1个脉冲驱动电机转动4个步距角。

    • 方向信号延时​:

      方向信号需提前脉冲0.5μs以上,避免电机启动瞬间反向抖动。


(二)、总线协议(EtherCAT、CANopen、Modbus)​

总线协议适用于多轴协同、高实时性场景,替代传统脉冲控制,解决布线复杂和同步精度问题。

1. EtherCAT(以太网控制自动化技术)​
  • 核心机制​:

    • ​"飞读飞写"帧处理​:主站帧依次穿越各从站,每个从站实时读写数据,单帧完成多设备通信。

    • 分布式时钟​:主站同步所有从站时钟,同步误差≤±1ns,保障多轴插补精度。

  • 性能优势​:

    • 通信周期≤100μs,支持4轴同步控制(如研华控制卡)。

    • 带宽利用率>90%,远高于传统以太网。​

  • 2. CANopen(基于CAN总线的应用层协议)​
  • 核心机制​:

    • 对象字典​:标准化参数存储结构(如0x607C“目标位置”、0x6040“控制字”)。

    • NMT网络管理​:主站控制从站状态(启动/停止/复位)。

  • 性能优势​:

    • 支持1Mbps速率,最多127个节点,适合分布式控制(如10轴插片机系统)。

    • 抗干扰性强,适用于电磁环境复杂场景。

3. Modbus(主从式串行通信协议)​
  • 核心机制​:

    • 主站轮询​:主站按地址顺序查询从站数据,响应延迟随节点数增加。

    • 寄存器读写​:通过功能码(如03读保持寄存器、06写单寄存器)访问参数。

  • 性能局限​:

    • 无实时保障,通信周期≥100ms,仅适用非同步控制(如启停命令、温度读取)。

    • 仅支持简单数据类型(16位整数)。


(三)、协议选型对比

维度

脉冲方向控制

EtherCAT

CANopen

Modbus

实时性

中(依赖脉冲频率)

超高​(≤100μs)

高(1Mbps速率)

低(≥100ms)

同步精度

无多轴同步能力

±1ns

±10μs

不支持

最大轴数

≤4轴(受限于PLC脉冲口)

≥64轴

127节点

32节点(RTU模式)

布线复杂度

高(每轴需2~4芯线)

​(菊花链拓扑)

中(总线型拓扑)

中(星型/总线拓扑)

抗干扰能力

弱(需差分信号增强)

​(以太网屏蔽)

强(CAN差分信号)

弱(RS485需终端电阻)

典型成本

低(无需专用网卡)

高(需专用主站)

五、上位机控制

1、板卡连接
2、初始化参数
3、轴参数设置
4、相对移动
5、绝对移动
6、回原
7、Jog移动

板卡类

 /// <summary>/// 板卡抽象基类/// </summary>public abstract class CardBase{/// <summary>/// 卡参数/// </summary>public CardParam cardParam { get; set; }public short CardNo => (short)cardParam.CardNo;/// <summary>/// 坐标系建立成功标志/// </summary>protected bool buildOK = false;/// <summary>/// 卡初始化成功标志/// </summary>private bool online;/// <summary>/// 在线状态/// </summary>public bool OnLine{get { return online; }set { online = value; }}/// <summary>/// 写错误信息方法/// </summary>public WriteInfo WriteInfo = null;/// <summary>/// 卡基类  有参构造方法/// </summary>/// <param name="cardParam">卡参数</param>public CardBase(CardParam cardParam){this.cardParam = cardParam;WriteInfo = new WriteInfo((str) =>{Console.WriteLine(str);});}/// <summary>/// 设置错误信息输出函数/// </summary>/// <param name="writeInfo">回调函数</param>public void SetWriteInfoCB(WriteInfo writeInfo){this.WriteInfo = writeInfo;for (int i = 0; i < AxisBaseList.Count; i++){AxisBaseList[i].SetWriteInfoCB(writeInfo);}}#region 板卡初始化/// <summary>///板卡初始化/// </summary>/// <returns></returns>public abstract OperationResult Init();/// <summary>///关闭板卡/// </summary>/// <returns></returns>public abstract OperationResult DeInit();/// <summary>/// 读取板卡固件版本号/// </summary>/// <returns></returns>public abstract string GetCardVersioin();#endregion 板卡初始化#region IO 操作/// <summary>/// 读取一组连续的输入/// </summary>/// <param name="startport"></param>/// <param name="endport"></param>/// <param name="data"></param>/// <returns></returns>public abstract bool ReadIoIn(int startport, int endport, ref int data);/// <summary>/// 读取一个输入点/// </summary>/// <param name="index"></param>/// <returns></returns>public abstract bool ReadIoInBit(int index);/// <summary>/// 读取一组连续的输出/// </summary>/// <param name="startport"></param>/// <param name="endport"></param>/// <param name="data"></param>/// <returns></returns>public abstract bool ReadIoOut(int startport, int endport, ref int data);/// <summary>/// 读取一个输出点/// </summary>/// <param name="index"></param>/// <returns></returns>public abstract bool ReadIoOutBit(int index);/// <summary>/// 写一个IO输出点/// </summary>/// <param name="index"></param>/// <param name="bit"></param>/// <returns></returns>public abstract bool WriteIoBit(int index, bool bit);/// <summary>/// 写一组IO输出数据/// </summary>/// <param name="data"></param>/// <returns></returns>public abstract bool WriteIo(int startport, int endport, int data);///// <summary>///// 读取数字IO输入状态///// </summary>///// <param name="type">0:正限位 | 1:负限位 | 2:驱动报警| 3:原点开关| 4:通用输入|</param>///// <returns></returns>//public abstract int GetDi(InputIOType type);///// <summary>///// 读取数字IO输入状态///// </summary>///// <param name="type">0:正限位 | 1:负限位 | 2:驱动报警| 3:原点开关| 4:通用输入|</param>///// <returns></returns>//public abstract bool[] GetInput(InputIOType type);///// <summary>///// 读取数字IO输出状态///// </summary>///// <param name="type">10:驱动器使能 | 11:报警清除 | 12:通用输出|</param>///// <returns></returns>//public abstract int GetDo(OutputIOType type);///// <summary>///// 读取输出状态 读取多位///// </summary>///// <param name="type">10:驱动器使能 | 11:报警清除 | 12:通用输出|</param>///// <returns></returns>//public abstract bool[] GetOutput(OutputIOType type);///// <summary>///// 读取输入状态 读1位///// </summary>///// <param name="index">索引1-16</param>///// <returns></returns>//public abstract bool GetInputBit(int index);///// <summary>///// 读取输出状态 读1位///// </summary>///// <param name="index">索引1-16</param>///// <returns></returns>//public abstract bool GetOutputBit(int index);///// <summary>///// 设置输出状态 写1位///// </summary>///// <param name="index">索引</param>///// <param name="state">状态</param>///// <returns></returns>//public abstract bool SetOutputBit(int index, bool state);///// <summary>///// 设置输出状态 写32位///// </summary>///// <param name="value">值</param>///// <returns></returns>//public abstract bool SetOutput(int value);#endregion IO 操作#region 插补运动/// <summary>/// 以当前位置为起始点进行多轴直线插补最多4轴/// </summary>/// <param name="axisNo">轴号数组最多4轴</param>/// <param name="pos">位置数组</param>/// <param name="vel">速度</param>/// <param name="acc">加速度</param>/// <returns>操作结果</returns>public abstract OperationResult MoveLineXYZAAbs(short[] axisNo, double[] pos, double vel, double acc = 0.2);/// <summary>/// XYC 2D 整圆插补 以起点(终点)位置和圆心位置为输入参数 画整圆/// </summary>/// <param name="axisNo">轴号数组</param>/// <param name="pos">圆弧的起点(终点)X 圆弧的圆心X </param>/// <param name="center">圆弧的起点(终点)Y 圆弧的圆心Y</param>/// <param name="vel">速度</param>/// <param name="acc">加速度</param>/// <returns>操作结果</returns>public abstract OperationResult MoveCircular(short[] axisNo, double[] pos, double[] center, double vel, double acc = 0.2);/// <summary>/// XYR 2D圆弧插补 起始点 过度点位置 终点位置为输入参数 画半圆/// </summary>/// <param name="axisNo">轴号数组</param>/// <param name="pos">起始 XY坐标</param>/// <param name="pos1">过度点 XY坐标</param>/// <param name="pos2">终点 XY坐标</param>/// <param name="vel">速度</param>/// <param name="acc">加速度</param>/// <returns>操作结果</returns>public abstract OperationResult MoveArc(short[] axisNo, double[] pos, double[] pos1, double[] pos2, double vel, double acc = 0.2);/// <summary>/// 空间圆弧插补/// </summary>/// <param name="axisNo">轴号</param>/// <param name="posX">开始位置</param>/// <param name="posY">经过位置</param>/// <param name="posZ">终点位置</param>/// <param name="vel">速度</param>/// <param name="acc">加速度</param>/// <returns></returns>public abstract OperationResult MoveArcOfSpace(short[] axisNo, double[] posStart, double[] posTransition, double[] posEnd, double vel, double acc = 0.2);/// <summary>///等待插补运动完成/// </summary>/// <returns></returns>public abstract OperationResult WaitInterpolatorXYStop();#endregion 插补运动#region 轴对象操作/// <summary>/// 轴集合/// </summary>public List<AxisBase> AxisBaseList = new List<AxisBase>();/// <summary>/// 获取板卡所有参数json(卡参数+所有轴参数)/// </summary>public abstract string GetCardAxisParamJson();/// <summary>/// 添加轴对象/// </summary>/// <param name="axisBase"></param>/// <returns></returns>public abstract bool AddAxisObj(AxisParam axisParam);/// <summary>/// 删除轴对象/// </summary>/// <param name="axisBase"></param>/// <returns></returns>public abstract bool DelAxisObj(AxisParam axisParam);/// <summary>/// 修改轴参数/// </summary>/// <param name="axisParam"></param>/// <returns></returns>public abstract bool ModifyAxisPara(AxisParam axisParam);#endregion 轴对象操作#region 2. 轴控制动作/// <summary>/// 停止板卡中全部轴/// </summary>/// <returns></returns>public abstract bool StopAllAxis();/// <summary>/// 停止轴(正常停止)/// </summary>/// <param name="nAxisNo"></param>/// <returns></returns>public virtual bool StopAxis(int nAxisNo){var v = AxisBaseList.Find(c => c.axisParam.AxisNo == nAxisNo);if (v != null){return v.StopAxis();}return false;}/// <summary>///停止轴(急停)/// </summary>/// <param name="nAxisNo"></param>/// <returns></returns>public virtual bool StopEmg(int nAxisNo){var v = AxisBaseList.Find(c => c.axisParam.AxisNo == nAxisNo);if (v != null){return v.StopEmg();}return false;}/// <summary>///绝对位置移动/// </summary>/// <param name="nAxisNo">轴号</param>/// <param name="nPos">位置</param>/// <param name="nSpeed">速度</param>/// <param name="accSpeed">加速度</param>/// <returns></returns>public virtual OperationResult AbsMove(int nAxisNo, double nPos, double nSpeed = -1, double accSpeed = -1){var v = AxisBaseList.Find(c => c.axisParam.AxisNo == nAxisNo);if (v != null){return v.AbsMove(nPos, nSpeed, accSpeed);}return new OperationResult() { IsSuccess = false, ErrorMsg = "对象为null" };}/// <summary>///相对位置移动/// </summary>/// <param name="nAxisNo"></param>/// <param name="nPos"></param>/// <param name="nSpeed"></param>/// <returns></returns>public virtual OperationResult RelativeMove(int nAxisNo, double nPos, double nSpeed = -1, double accSpeed = -1){var v = AxisBaseList.Find(c => c.axisParam.AxisNo == nAxisNo);if (v != null){return v.RelativeMove(nPos, nSpeed, accSpeed);}return new OperationResult() { IsSuccess = false, ErrorMsg = "对象为null" };}/// <summary>///jog运动/// </summary>/// <param name="nAxisNo"></param>/// <param name="bPositive"></param>/// <param name="nSpeed"></param>/// <returns></returns>public virtual OperationResult JogMove(int nAxisNo, bool bPositive, double nSpeed = -1){var v = AxisBaseList.Find(c => c.axisParam.AxisNo == nAxisNo);if (v != null){return v.JogMove(bPositive, nSpeed);}return new OperationResult() { IsSuccess = false, ErrorMsg = "对象为null" };}/// <summary>///开启使能/// </summary>/// <param name="nAxisNo"></param>/// <returns></returns>public virtual bool ServoOn(int nAxisNo){var v = AxisBaseList.Find(c => c.axisParam.AxisNo == nAxisNo);if (v != null){return v.ServoOn();}return false;}/// <summary>///断开使能/// </summary>/// <param name="nAxisNo"></param>/// <returns></returns>public virtual bool ServoOff(int nAxisNo){var v = AxisBaseList.Find(c => c.axisParam.AxisNo == nAxisNo);if (v != null){return v.ServoOff();}return false;}/// <summary>///获取轴的当前位置/// </summary>/// <param name="nAxisNo"></param>/// <returns></returns>public virtual double GetAixsPos(int nAxisNo){if (!OnLine){throw new Exception("板卡未连接!");}if (AxisBaseList.Count == 0){throw new Exception("没有可用的轴对象");}var v = AxisBaseList.Find(c => c.axisParam.AxisNo == nAxisNo);if (v != null){return v.GetAixsPos();}return -999999.4;}/// <summary>///位置清零/// </summary>/// <param name="nAxisNo"></param>/// <returns></returns>public virtual bool SetPosZero(int nAxisNo){var v = AxisBaseList.Find(c => c.axisParam.AxisNo == nAxisNo);if (v != null){return v.SetPosZero();}return false;}/// <summary>/// 读取伺服使能状态/// </summary>/// <param name="nAxisNo"></param>/// <returns></returns>public virtual bool IsServoOn(int nAxisNo){var v = AxisBaseList.Find(c => c.axisParam.AxisNo == nAxisNo);if (v != null){return v.IsServoOn();}return false;}/// <summary>///回原点/// </summary>/// <param name="nAxisNo">轴号</param>/// <param name="nParam">回原方向 1:正方向 -1:负方向</param>/// <returns></returns>public virtual OperationResult Home(int nAxisNo, int nParam){if (!OnLine){return new OperationResult() { IsSuccess = false, ErrorMsg = "设备没有连接!" };}if (AxisBaseList.Count == 0){return new OperationResult() { IsSuccess = false, ErrorMsg = "没有可用的轴对象" };}var v = AxisBaseList.Find(c => c.axisParam.AxisNo == nAxisNo);if (v != null){return v.Home(nParam);}return new OperationResult() { IsSuccess = false, ErrorMsg = $"没有找对轴号:{nAxisNo} 对应的轴对象" };}/// <summary>/// 回原点是否正常停止/// </summary>/// <param name="nAxisNo"></param>/// <returns></returns>public virtual OperationResult IsHomeNormalStop(int nAxisNo){var v = AxisBaseList.Find(c => c.axisParam.AxisNo == nAxisNo);if (v != null){return v.IsHomeNormalStop();}return new OperationResult() { IsSuccess = false, ErrorMsg = "轴对象为null" };}/// <summary>/// 停止回原动作/// </summary>/// <returns></returns>public virtual bool StopHomeAction(int nAxisNo){var v = AxisBaseList.Find(c => c.axisParam.AxisNo == nAxisNo);if (v != null){return v.StopHomeAction();}return false;}/// <summary>/// 清除轴状态/// </summary>/// <param name="nAxisNo"></param>/// <returns></returns>public virtual bool ClrSts(int nAxisNo){var v = AxisBaseList.Find(c => c.axisParam.AxisNo == nAxisNo);if (v != null){return v.ClrSts();}return false;}/// <summary>/// 清除所有轴状态/// </summary>/// <returns></returns>public abstract bool ResetAllAxisStatus();/// <summary>///获取轴卡运动状态/// </summary>/// <param name="nAxisNo"></param>/// <returns></returns>public virtual int GetMotionState(int nAxisNo){var v = AxisBaseList.Find(c => c.axisParam.AxisNo == nAxisNo);if (v != null){return v.GetMotionState();}return -1;}/// <summary>/// 检测是否有轴报警/// </summary>/// <returns></returns>public abstract bool CheckAllAxisAlarm();/// <summary>/// 读取轴报警/// </summary>/// <param name="nAxisNo"></param>/// <returns></returns>public abstract bool IsAlarmFlag(int nAxisNo);/// <summary>/// 读取轴正限位/// </summary>/// <param name="nAxisNo"></param>/// <returns></returns>public abstract bool IsPosLimitFlag(int nAxisNo);/// <summary>/// 读取轴负限位/// </summary>/// <param name="nAxisNo"></param>/// <returns></returns>hpublic abstract bool IsNegLimitFlag(int nAxisNo);/// <summary>/// 读取轴原点/// </summary>/// <param name="nAxisNo"></param>/// <returns></returns>public abstract bool IsHomeFlag(int nAxisNo);/// <summary>/// 获取回零状态/// </summary>/// <param name="nAxisNo"></param>/// <returns></returns>public abstract bool IsHomeStatus(int nAxisNo);/// <summary>/// 轴停止/// </summary>/// <param name="nAxisNo"></param>/// <returns></returns>public abstract bool IsStop(int nAxisNo);#endregion 2. 轴控制动作/// <summary>/// 设置单轴的某一运动参数/// </summary>/// <param name="nAxisNo">轴号</param>/// <param name="nParam">参数:1:加速度 2:减速度 3:起跳速度 4:结束速度(凌华卡) 5:平滑时间(固高卡S曲线) 其它:自定义扩展</param>/// <param name="nData">参数值</param>/// <returns></returns>public virtual bool SetAxisParam(int nAxisNo, AxisMotionParam nParam, int nData){var v = AxisBaseList.Find(c => c.axisParam.AxisNo == nAxisNo);if (v != null){return v.SetAxisParam(nParam, nData);}return false;}}

轴控制类

 /// <summary>/// 轴抽象基类/// </summary>public abstract class AxisBase{/// <summary>/// 轴无效值/// </summary>public const double AxisInvalidPos = -999999.4;/// <summary>/// 轴参数/// </summary>public AxisParam axisParam { get; set; }/// <summary>/// 轴号/// </summary>public short AxisNo => (short)axisParam.AxisNo;/// <summary>/// 卡号/// </summary>public short CardNo => (short)axisParam.CardNo;/// <summary>/// 脉冲当量/// </summary>public float Units => (float)(axisParam.Subdivide * 1.0 / axisParam.HelicalPitch);///// <summary>///// 停止回原动作(标志)///// 判断此标志true 停止进行中的回原动作///// </summary>//protected bool stopHome;/// <summary>/// 构造方法/// </summary>/// <param name="axisParam">轴参数</param>public AxisBase(AxisParam axisParam){this.axisParam = axisParam;WriteInfo = new WriteInfo((str) =>{Console.WriteLine(str);});}/// <summary>/// 写错误信息方法/// </summary>public WriteInfo WriteInfo = null;/// <summary>/// 设置错误信息输出函数/// </summary>/// <param name="writeInfo">回调函数</param>public void SetWriteInfoCB(WriteInfo writeInfo){this.WriteInfo = writeInfo;}// 轴的操作方法   jog  move abs  使能#region 2. 轴控制动作/// <summary>/// 停止回原动作/// </summary>/// <returns></returns>public abstract bool StopHomeAction();/// <summary>///轴位置清零/// </summary>/// <returns></returns>public abstract bool SetPosZero();/// <summary>/// 报警清除/// </summary>/// <returns>结果</returns>public abstract bool ClrSts();/// <summary>///开启使能/// </summary>/// <returns></returns>public abstract bool ServoOn();/// <summary>///断开使能/// </summary>/// <returns></returns>public abstract bool ServoOff();/// <summary>/// 伺服使能状态/// </summary>/// <returns> </returns>public abstract bool IsServoOn();/// <summary>/// 绝对位置移动/// </summary>/// <param name="nPos">位置</param>/// <param name="nSpeed">速度 默认为:-1 表示使用轴参数的速度</param>/// <param name="accSpeed">加速度 默认为:-1 表示使用轴参数的加速度</param>/// <returns></returns>public abstract OperationResult AbsMove(double nPos, double nSpeed = -1,double accSpeed=-1);/// <summary>///相对位置移动/// </summary>/// <param name="nPos"></param>/// <param name="nSpeed">速度 默认为:-1 表示使用轴参数的速度</param>/// <returns></returns>public abstract OperationResult RelativeMove(double nPos, double nSpeed = -1,double accSpeed=-1);/// <summary>///jog运动/// </summary>/// <param name="bPositive">方向</param>/// <param name="nSpeed">速度 默认为:-1 表示使用轴参数的速度</param>/// <returns></returns>public abstract OperationResult JogMove(bool bPositive, double nSpeed = -1);/// <summary>///轴正常停止/// </summary>/// <param name="nAxisNo"></param>/// <returns></returns>public abstract bool StopAxis();/// <summary>/// 单轴急停/// </summary>/// <returns></returns>public abstract bool StopEmg();/// <summary>///获取轴的当前位置/// </summary>/// <returns></returns>public abstract double GetAixsPos();/// <summary>/// 回原/// </summary>/// <param name="nParam">回原方向 1:正方向 -1:负方向</param>/// <param name="timeout">超时时间(-1表示 不启用超时时间)</param>/// <returns></returns>public abstract OperationResult Home(int nParam);/// <summary>/// 回原点是否正常停止/// </summary>/// <returns></returns>public abstract OperationResult IsHomeNormalStop();#endregion 2. 轴控制动作#region 3. 轴状态/// <summary>///获取轴运动状态/// </summary>/// <returns></returns>public abstract int GetMotionState();///// <summary>/////获取轴卡运动IO信号///// </summary>///// <returns></returns>//public abstract int GetMotionIoState();///// <summary>///// 轴是否正常停止///// </summary>///// <returns> -2:指令返回错误 -1:运动中 1:驱动器报警 4:正限位 5:负限位 3:未使能</returns>//public abstract int IsAxisNormalStop();/// <summary>/// 轴是否报警/// </summary>/// <returns>返回 true 报警  false 没有报警</returns>public abstract bool IsAlarmFlag();/// <summary>/// 轴是否处于正限位/// </summary>/// <returns></returns>public abstract bool IsPosLimitFlag();/// <summary>/// 轴是否处于负限位/// </summary>/// <returns></returns>public abstract bool IsNegLimitFlag();public abstract bool IsHomeFlag();///// <summary>///// 等待轴正常停止///// </summary>///// <returns>操作结果</returns>//public abstract OperationResult WaitStop();#endregion 3. 轴状态/// <summary>/// 设置轴的 单一控制参数/// </summary>/// <param name="nParam">参数类型:1:加速度 2:减速度 3:起跳速度 4:结束速度 5:平滑时间 其它:自定义扩展</param>/// <param name="nData">参数值</param>/// <returns></returns>public abstract bool SetAxisParam(AxisMotionParam nParam, int nData);/// <summary>/// 设置轴软极限/// </summary>/// <returns></returns>public abstract bool SetSoftLimit();/// <summary>/// 轴状态检测/// </summary>/// <returns>检测结果 OperationResult</returns>public abstract OperationResult CommonMotionValidate();/// <summary>/// 更新轴信息/// </summary>public void UpdataState(){axisParam.NegativeSignalState = IsNegLimitFlag();axisParam.PositiveSignalState = IsPosLimitFlag();axisParam.HomeSignalState = IsHomeFlag();axisParam.AxisPos = GetAixsPos();axisParam.IsErrState = IsAlarmFlag();}}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/web/95206.shtml
繁体地址,请注明出处:http://hk.pswp.cn/web/95206.shtml
英文地址,请注明出处:http://en.pswp.cn/web/95206.shtml

如若内容造成侵权/违法违规/事实不符,请联系英文站点网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

链表实战指南:手动实现单链表与双链表的接口及OJ挑战(含完整源码)

文章目录一、链表的概念二、链表的分类三、手动实现单链表1.链表的初始化2.链表的打印3.申请新的节点大小空间4.链表的尾插5.链表的头插6.链表的尾删7.链表的头删8.链表的查找9.在指定位置之前插入数据10.在指定位置之后插入数据11.删除指定节点12.删除指定节点之后的数据13.销…

Spring 事件驱动编程初探:用 @EventListener 轻松处理业务通知

一、核心概念与模型Spring 的事件机制是观察者模式&#xff08;也叫发布-订阅模型&#xff09;的一种典型实现。它主要由三个核心部分组成&#xff1a;事件 (Event)&#xff1a; 承载信息的对象&#xff0c;通常是某种状态变化的通知。可以是继承 ApplicationEvent 的类&#x…

无人机也能称重?电力巡检称重传感器安装与使用指南

在无人机电力巡检中&#xff0c;工程师们常常面临一个棘手难题&#xff1a;如何精确知道新架设或老旧缆线的实际负重&#xff1f; 传统依靠老师傅“肉眼估算”的方法不仅风险极高&#xff0c;而且数据极不准确&#xff0c;给电网安全埋下巨大隐患。难道没有更科学的方法吗&…

第二阶段WinForm-8:特性和反射,加密和解密,单例模式

1_预处理指令 &#xff08;1&#xff09;源代码指定了程序的定义&#xff0c;预处理指令&#xff08;preprocessor directive&#xff09;指示编译器如何处理源代码。例如&#xff0c;在某些情况下&#xff0c;我们希望编译器能够忽略一部分代码&#xff0c;而在其他情况下&am…

基于mac的智能语音处理与应用开发-环境部署

上一次写文章还是上一次&#xff0c;时隔一年再次开启学习之路。新机mac没有开发环境&#xff0c;在gpt老师的指导下开始学习之路。 mac开发环境的部署参考了b站程序员云谦和Clover-You的视频教程&#xff0c;然后结合自身及gpt老师的帮助现在开始部署。 g老师的&#x1f34e…

Java中使用正则表达式的正确打开方式

正则表达式基础语法Java正则表达式基于java.util.regex包&#xff0c;核心类是Pattern和Matcher。基本语法遵循标准正则规范&#xff1a;. 匹配任意单个字符&#xff08;除换行符&#xff09;\d 匹配数字&#xff0c;等价于 [0-9]\w 匹配单词字符&#xff0c;等价于 [a-zA-Z0-9…

Docker中Mysql容器忽略大小写

场景说明 在数据迁移场景中&#xff0c;从一个数据库中将数据迁移到另一个数据&#xff0c;经常会遇到&#xff0c;两个不同数据库之间&#xff0c;一个默认忽略大小写&#xff0c;一个默认不忽略大小写&#xff0c;导致实际业务层服务进行数据库访问时&#xff0c;切换数据库之…

神经网络激活函数:从ReLU到前沿SwiGLU

摘要 本文全面介绍了神经网络中常用的激活函数,包括Sigmoid、Tanh、ReLU等传统函数,以及2017年后出现的Swish、Mish、SwiGLU等新兴函数。每个函数均提供数学定义、优缺点分析、Python实现代码和可视化图像,并附有实际应用建议和性能对比数据,帮助读者根据具体任务选择合适…

线程池常见面试问答

好嘞 &#x1f44d;&#xff0c;我帮你把这些 线程池 并发编程八股文 整理成 问答对照表&#xff08;Q & A&#xff09;&#xff0c;你面试时可以直接用。&#x1f9fe; 线程池常见面试问答一、基础语法 & STLQ1&#xff1a;std::function<void()> 和函数指针的…

Flutter 开发技巧 AI 快速构建 json_annotation model 的提示词

将下面这段复制到AI GPT、DeepSeek 、文心快码 试过效果都可以&#xff0c;不用做任何更改。将 json 数据丢给 AI 就行了 我会提供一段 JSON 数据&#xff0c;请帮我生成 Dart 模型&#xff0c;要求严格如下&#xff1a;1. 使用 json_annotation 包&#xff0c;包含&#xff1a…

【秋招笔试】2025.08.30科大讯飞秋招笔试题

📌 点击直达笔试专栏 👉《大厂笔试突围》 💻 春秋招笔试突围在线OJ 👉 笔试突围在线刷题 bishipass.com 科大讯飞 题目一:物品种类统计 1️⃣:使用集合或哈希表统计不同物品编号的数量 2️⃣:利用数学公式 n - 不同种类数 计算最终答案 难度:简单 这道题目的关…

AI 智能体汇总,自动执行任务的“真 Agent”

AI Agent 正在掀起一场静默的效率革命&#xff1a;当 AI 遇上 RPA&#xff0c;真正的“数字员工”时代已经到来最近一段时间&#xff0c;我密集关注了多场 AI Agent&#xff08;智能体&#xff09;的发布会&#xff0c;覆盖了从消费级到企业级的各类产品。一个越来越清晰的趋势…

vue布局

给于2个div块状元素的布局方案1&#xff1a;横向并排&#xff08;Flex Row&#xff09;<template><div class"container"><div class"background">背景</div><div class"panel">内容</div></div> <…

Hysplit大气传输和污染扩散-轨迹聚合标准20%30%用途

1、HYSPLIT轨迹聚合中的百分比标准在HYSPLIT模型中&#xff0c;轨迹聚合&#xff08;Trajectory Clustering&#xff09;用于将大量轨迹按相似性分组&#xff0c;20%和30%是常见的聚合阈值标准&#xff0c;反映轨迹间的空间相似度要求。2、20%和30%的具体含义这两个百分比代表轨…

Linux shell 脚本基础 003

目录 Linux shell 脚本语句 1. for 循环流程控制 1.1 基本语法格式 1.2 常见用法示例 1.3生产案例示例 2. while 循环 2.1 基本语法格式 2.2 常见用法示例 3. case 语句 3.1 基本语法格式 3.2 常见用法示例 3.3生产案例示例 4. shell 函数 4.1 函数的定义 4.2 函…

7.1elementplus的表单

Element Plus 表单由以下几个关键部分构成&#xff1a;<el-form>: 表单容器。它是整个表单的根组件&#xff0c;负责管理表单数据、校验规则、布局方式等。<el-form-item>: 表单项容器。用于包裹一个具体的表单控件&#xff08;如输入框、选择器等&#xff09;及其…

TF-IDF:文本分析的“火眼金睛”

TF-IDF&#xff1a;文本分析的“火眼金睛” 在信息爆炸的时代&#xff0c;我们每天都会接触到海量的文本数据。如何从这些数据中快速找出最重要的信息&#xff1f;TF-IDF&#xff08;Term Frequency-Inverse Document Frequency&#xff09;算法就是一种非常实用的工具&#xf…

传统星型拓扑结构的5G,WiFi无线通信网络与替代拓扑结构自组网

一、个人理解 区别自组网&#xff0c;5G和WiFi三者要抓住两个关键点&#xff1a;移动、组网。 5G通信是移动通信的最新一代&#xff1b;1940年代美军的手持对讲机虽然可以移动&#xff0c;但是算不上网络&#xff0c;后面的第一代移动通信蜂窝网络才能算上网络。 WiFi通信虽…

REST API 是无状态的吗,如何保障 API 的安全调用?

当然&#xff0c;这是一个非常核心的API设计和安全领域的问题。我们来详细拆解一下。1. REST API 是无状态的吗&#xff1f;​是的&#xff0c;REST API 的核心原则之一就是“无状态”&#xff08;Statelessness&#xff09;。​​这意味着&#xff1a;​服务器不保存客户端的会…

Machine Learning HW3 report:图像分类(Hongyi Lee)

任务&#xff1a;使用CNN把食物图片分为11类&#xff08;不能使用预训练的模型&#xff09;。此任务很耗时&#xff0c;一次训练至少1h&#xff0c;所以要利用好Kaggle notebook中Save Version功能&#xff0c;并行训练节省时间。 基准 Simple : 0.50099Medium : 0.73207 Train…