一、前言
当我们在电脑上输入一个目标速度,例如让电机以 100 rpm 的速度旋转时,电机是如何理解这个数字,并最终产生运动的?
计算机发送的是数字,电机执行的却是物理运动。两者之间,需要经历通信协议、驱动器控制程序、功率电路以及传感器反馈等多个环节。
以常见的伺服电机和 CANopen 通信协议为例,我们可以把整个过程理解为:
正在绘制图表…
这条链路包含三个不同的层次:
| 层次 | 核心问题 | 关键技术 |
|---|---|---|
| 通信层 | 数据怎么传到电机? | CAN、CANopen、SDO、PDO |
| 控制层 | 数字指令如何变成目标速度和转矩? | 对象字典、单位换算、CiA 402、PID、FOC |
| 物理层 | 电机为什么真的会转? | PWM、功率开关、绕组电流、电磁转矩 |
理解时不要把这三个层次混在一起。CANopen 负责传输和定义参数,电机控制算法负责决定如何驱动,功率电路才负责向电机提供实际能量。
下面从实际指令出发,逐步理解这个过程。
第一步:上位机如何告诉电机该做什么?
在机器人系统中,上位机可以是电脑、控制板或机器人主控制器。它负责向电机驱动器发送控制指令。
例如,我们希望电机以指定速度运行,就需要告诉驱动器:
- 当前应该处于什么控制状态?
- 使用什么控制模式?
- 目标速度是多少?
CANopen 是一种建立在 CAN 总线之上的高层通信协议。它不仅规定了数据如何传输,还定义了一套常见的参数组织方式,称为对象字典(Object Dictionary)。
对象字典可以理解为驱动器内部的一张参数表。不同的索引对应不同的控制参数或状态信息。
以常见的 CiA 402 驱动器配置为例:
| 索引 | 名称 | 作用 |
|---|---|---|
0x6040 | Controlword | 控制驱动器状态,例如使能 |
0x6041 | Statusword | 读取驱动器当前状态 |
0x6060 | Modes of operation | 设置控制模式 |
0x6061 | Modes of operation display | 读取当前生效的控制模式 |
0x60FF | Target velocity | 设置目标速度 |
0x606C | Velocity actual value | 读取实际速度 |
这些索引属于常见的 CiA 402 对象定义,但驱动器是否支持它们,以及参数的单位、缩放方式,都需要以具体设备手册为准。
第二步:理解几个关键控制指令
1. 0x6040:控制字
控制字用于控制驱动器状态,例如请求驱动器使能。
常见的 CiA 402 控制状态转换操作包括:
0x0006:Shutdown,请求进入准备使能状态。0x0007:Switch on,请求进入已接通状态。0x000F:Enable operation,请求使能运行。0x0080:Fault reset,故障复位请求,具体行为取决于设备状态和驱动器实现。
这些值是不可以随意排列的启动口令。驱动器有自己的状态机,通常需要按照规定的状态转换顺序操作,并确认状态字中的反馈。
例如,即使发送了 0x000F,如果驱动器仍处于故障状态、电源未就绪或存在安全互锁,电机也不一定能够运行。
2. 0x6060:工作模式
电机驱动器可以工作在不同模式下,例如位置控制、速度控制和转矩控制。
常见的 CiA 402 模式值包括:
| 模式值 | 模式 | 含义 |
|---|---|---|
1 | Profile Position | 按目标位置运动 |
3 | Profile Velocity | 按目标速度运动 |
6 | Homing | 执行回零操作 |
8 | CSP | 周期同步位置模式 |
9 | CSV | 周期同步速度模式 |
10 | CST | 周期同步转矩模式 |
- 并不是所有驱动器都支持全部模式
如果想让电机以指定速度运行,就需要选择驱动器支持的速度控制模式,并确认该模式对应的目标参数和控制流程。
3. 0x60FF:目标速度
假设我们希望电机达到目标速度,就可以使用 0x60FF 这个常见的目标速度对象。
需要注意:写入的数值不一定直接等于 rpm。
例如,写入数字 1000,它究竟代表 1000 rpm、100 rpm,还是经过特定比例缩放的内部数值,取决于驱动器的单位定义、电子齿轮比和参数配置。
因此,实际使用时必须先查阅驱动器手册,确认数据类型和缩放比例。
第三步:数字指令如何通过 CAN 总线传输?
CAN 总线传输的不是文字,而是由标识符和数据字节组成的报文。
在 CANopen 中,SDO(服务数据对象)常用于读写对象字典参数。
例如,假设:
- 驱动器节点 ID 为
1; - 使用标准 CANopen SDO;
- 要向
0x60FF:00写入一个 32 位整数; - 写入的原始数值为
1000。
对应的经典 CANopen SDO 下载请求可以表示为:
| 字段 | 数值 | 含义 |
|---|---|---|
| CAN ID | 0x601 | 节点 1 的 SDO 请求 |
| Byte 0 | 0x23 | 发起 4 字节数据写入 |
| Byte 1 | 0xFF | 索引低字节 |
| Byte 2 | 0x60 | 索引高字节 |
| Byte 3 | 0x00 | 子索引 |
| Byte 4 | 0xE8 | 数值 1000 的低字节 |
| Byte 5 | 0x03 | 数值 1000 的次低字节 |
| Byte 6 | 0x00 | 数值的次高字节 |
| Byte 7 | 0x00 | 数值的高字节 |
CANopen SDO 数据部分:小端,低字节先发
- 第 1 字节 (最低):0xE8
- 第 2 字节:0x03
- 第 3 字节:0x00
- 第 4 字节 (最高):0x00
整帧数据为:
CAN ID: 0x601
Data: 23 FF 60 00 E8 03 00 00
这里的 1000 按照小端序编码为 E8 03 00 00。
如果写入成功,驱动器通常会返回 SDO 响应:
CAN ID: 0x581
Data: 60 FF 60 00 00 00 00 00
其中 0x581 是节点 1 的常见 SDO 响应标识符,0x60 表示写入成功的确认响应。
但要特别注意:这条报文只是一个参数写入示例,不代表发送后电机就一定会转动。 实际控制还需要正确的工作模式、驱动器状态、参数单位和设备配置。
第四步:驱动器收到指令后做了什么?
CAN 总线只是负责传输数据。真正决定电机如何运动的是驱动器内部的控制程序。
当驱动器收到一条指令后,通常需要完成以下工作:
- 接收并校验 CAN 报文。
- 根据 CANopen 协议解析请求。
- 定位对象字典中的目标参数。
- 检查数据类型、参数范围和当前驱动器状态。
- 将目标值交给相应的控制算法。
例如,当目标速度被写入后,驱动器会将其作为控制目标。
如果工作在速度控制模式,控制程序就需要比较目标速度和当前实际速度,并根据两者之间的误差计算控制输出。
这一过程可以简化为:
目标速度
↓
与实际速度比较
↓
计算速度误差
↓
速度控制器(例如 PI)
↓
生成转矩或电流指令
↓
电流控制器
↓
控制功率器件
具体控制结构因电机类型和驱动器设计而异,但速度环、电流环是许多伺服系统中常见的控制结构。
第五步:电信号如何让电机真正转动?
驱动器最终需要控制电机绕组中的电流,才能产生电磁转矩。
以常见的永磁同步电机为例,电机内部主要包含定子和转子:
- 定子:具有绕组,通入受控电流后产生磁场。
- 转子:具有永磁体或其他磁场结构。
- 功率驱动电路:通过控制功率器件的开关,将直流电源转换成电机所需的多相电压和电流。
在常见的伺服驱动器中,控制器会使用 PWM 等方式控制功率器件;对于采用磁场定向控制(FOC)的永磁同步电机,还会对电流进行坐标变换和调节,以控制转矩与磁场分量。
当绕组电流受到控制后,定子磁场与转子磁场之间产生电磁作用,电机就会输出转矩。
只要转矩足以克服摩擦、负载和其他阻力,转子便开始转动。
因此,从数字指令到机械运动,中间并不是简单的“数字直接变成转速”,而是经过了控制算法、电流调节和电磁能量转换。
第六步:编码器如何知道电机转了多少?
如果只给电机供电,它可能会旋转,但控制器未必知道它实际转了多少、速度是多少。
为了实现精准控制,伺服电机通常会配备编码器等传感器。
编码器可以提供转子位置或增量计数信息。驱动器根据一段时间内的位置变化,估算实际转速。
例如,假设:
- 在
0.1秒内,编码器计数增加了1000; - 经过设备定义的解码方式换算后,每转对应
4000个计数; - 暂时忽略滤波、量化和测量误差。
则转速估算为:
其中:
- :这段时间内的计数变化;
- :每转对应的有效计数;
- :测量时间,单位为秒;
- :转速,单位为 rpm。
代入示例:
这说明电机在该测量区间内的平均转速约为 150 rpm。
实际计算时,必须确认编码器计数定义、减速器传动比以及驱动器是否已经完成单位换算。
第七步:闭环控制如何让电机稳定运行?
假设目标速度为 100 rpm,而编码器测得的实际速度只有 80 rpm。
控制器就会计算速度误差:
速度控制器根据误差和内部参数,调整转矩或电流指令,让电机输出更合适的转矩。
随后,驱动器再次读取实际速度,重新计算误差并调整输出。
这一过程会不断重复:
目标速度:100 rpm
↓
比较目标与实际速度
↓
实际速度:80 rpm
↓
计算误差:20 rpm
↓
调整电流 / 转矩指令
↓
电机速度发生变化
↓
编码器再次反馈实际速度
└───────循环
这就是闭环控制的基本思想:不是发出一次指令就不再管它,而是持续测量实际结果,并根据误差修正控制输出。
当负载突然增大时,电机转速可能下降。闭环控制可以检测这种变化,并尝试通过调整输出转矩维持目标速度,但它能否维持速度,仍取决于电机功率、驱动器能力和负载大小。
思考
学习电机控制时,很容易把注意力集中在通信指令上,例如 0x6040、0x6060 和 0x60FF。但这些指令只是整个系统中的一部分。
0x6040 负责请求驱动器改变状态,0x6060 用于选择控制模式,0x60FF 可以设置目标速度。它们本身不会直接产生电磁转矩。真正让电机运动的,是驱动器把数字目标转换成控制量,再通过功率电路控制绕组电流;而编码器反馈与闭环算法,让电机能够根据实际运动状态持续调整输出。
理解这一点之后,机器人控制就不再只是发送几个十六进制数字,而是一个连接了通信协议、嵌入式软件、控制理论、电力电子和机械运动的完整系统。
这也是我认为学习机器人硬件最重要的一点:不要只记住某条指令的含义,更要弄清楚这条指令进入系统之后,究竟改变了什么,以及它最终如何影响真实世界。