我是靠谱客的博主 怕孤单手套,这篇文章主要介绍Power PMAC运动控制器 —— 学习笔记1说明1. 硬件介绍2. 准备工作3. PMAC与上位机的连接4. 创建自己的伺服控制项目5. 程序下载流程6. 学习途径后记,现在分享给大家,希望可以做个参考。

Power PMAC运动控制器——学习笔记1

  • 说明
  • 1. 硬件介绍
  • 2. 准备工作
  • 3. PMAC与上位机的连接
  • 4. 创建自己的伺服控制项目
  • 5. 程序下载流程
  • 6. 学习途径
  • 后记

    有很多朋友跟博主一样,拿到PMAC控制器后一脸懵逼,技术只给了几个英文手册,便什么都不管了,咨询问题的时候敷衍了事。为了避免更多朋友像博主一样,决定跟大家分享一下Power PMAC运动控制器的使用经验。


    项目结题,分析原因,我发现我们刚拿到控制器时迷茫的原因有三:

  • 其一,没有任何经验,害怕设备损害的害怕心理;
  • 其二,没有人领进门,即使刚开始的时候技术给提供帮助,在一无所知、大脑一片空白的情况下很快就会忘记技术所给你讲过的内容;
  • 其三,手册的内容太多,且为英文,而多数人英语阅读能力有限

        但是,当你了解到整个开发过程后,再回过头来看,发现手册还是最好的老师

                                                    于2019.08.10修


为了方便大家检索,下面列出学习笔记的目录。

关于 《Power PMAC运动控制器 —— 学习笔记》 系列,目录如下:

  1. Power PMAC运动控制器——学习笔记1,主要介绍了PMAC与IDE环境的连接以及项目的创建
  2. Power PMAC运动控制器——学习笔记2,主要介绍了电机、EtherCAT网络在IDE中的配置以及基本的运动程序编写知识基础
  3. Power PMAC运动控制器——学习笔记3,主要介绍了PMAC中关于坐标系、轴和运动模式的概念,以及运动程序的编写
  4. Power PMAC运动控制器——学习笔记4,主要介绍了正逆运动学在PMAC中的实现
  5. Power PMAC运动控制器——学习笔记5,主要介绍了PLC程序和子程序的编写
  6. Power PMAC运动控制器——学习笔记6,主要介绍了Power PMAC中Modbus通信的实现以及EtherCAT网络的使能
  7. Power PMAC运动控制器——学习笔记7,主要介绍了Power PMAC配置EtherCAT下的力矩控制

说明

       博主由于项目需要开始接触PMAC系列运动控制卡 ,奈何资料太少,能找到的资料由于版本不同的原因导致无法使用,本着开源精神,以此记录整个项目过程中Power PMAC的使用,希望能同各路大神交流分享~

目标:上位机通过Modbus TCP给运动控制卡发送指令实现机械臂的同步控制

1. 硬件介绍

       PMAC全称Programmable Multi-Axis Controller(可编程多轴运动控制器 ),是美国Delta Tau Data System 公司(现已被欧姆龙收购,说到被收购我就不得不吐槽一下,自从被收购以后技术大牛都走了,遇到技术问题只能用户自己瞎摸索,欧姆龙你上点心好嘛 ???? )推出的运动控制器[^1],功能很强大,号称可实现纳米级控制,同步性不错,尤其是插补功能做的非常好,并且支持多厂商的驱动器、光栅尺等。
       本文主要介绍项目中用到的欧姆龙的CK3M型号,模块化的设计深得我心,可实现单元的扩展,而且单元之间的连接无需工具。规格参数如下图所示:


性能参数

       系统基本构成如下图所示:

       更多细节就不多介绍了,详情请参考官网。

2. 准备工作

       首先安装PowerPMAC IDE,该IDE环境是基于VS2015开发的,如果你熟悉VS工作环境,那么必然非常容易上手该IDE(如图所示)。


如果你不清楚环境的使用,可以在工具栏的帮助目录下找到PowerPMAC IDE手册,如下所示:

       在熟悉了IDE环境之后(相当于废话哈哈哈哈,直接上手即可),我们直接开干~
需要的手册主要有:软件参考手册、用户使用手册,所有文件已在百度云盘共享(失效请留言)。

3. PMAC与上位机的连接

  • step1 用双绞线电缆建立CK3M与电脑主机的连接,然后给CK3M上电(注意:千万千万千万别接反了,不然稍不留神上万元就没了 ???? )。
  • step2 PMAC默认IP为192.168.0.200,握手成功后我们打开IDE环境,点击:通讯设置->应用,注意要选择设备的IP地址。

    在这里插入图片描述

①连接成功后,IDE的标题栏会显示PMAC的版本信息,且由灰色变为绿色。

在这里插入图片描述

②如果连接失败或者连接没反应,我们可以通过<运行>功能ping一下PMAC,查看是否已经握手成功,如果已经握手成功(如下图所示),上位机会收到CK3M的反馈。
运行:window + R


在这里插入图片描述

那么问题可能出在上位机的IP设置上,找到网络适配器设置,选择与PMAC连接的接口,按下图设置,最后单击确定。(注意:更改适配器的设置可能会导致下次网线连接此口时无法进行网络访问,那时需要恢复设置为【自动获得IP地址】),修改完毕后重复step2。如果仍然连接失败,断开网络再试试。 ????

在这里插入图片描述

4. 创建自己的伺服控制项目

        创建项目的过程跟VS中project的创建几乎无差,在此不再赘述,参见Power PMAC IDE手册P139。项目目录结构如下:


在这里插入图片描述

        为防止在调试过程中由于参数设置不当导致伺服电机或驱动器的损坏,我们可以通过设置虚轴的方式进行模拟调试。
        虚轴设置如下:

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
//来自官方论坛某大神 // Activate servo algorithms for motors Motor[1].ServoCtrl=1 Motor[2].ServoCtrl=1 Motor[3].ServoCtrl=1 Motor[4].ServoCtrl=1 Motor[5].ServoCtrl=1 Motor[6].ServoCtrl=1 Motor[7].ServoCtrl=1 Motor[8].ServoCtrl=1 // Write servo output to user shared memory registers Motor[1].pDac=Sys.Idata[1].a // Same as EncTable[1].pEnc Motor[2].pDac=Sys.Idata[2].a // Same as EncTable[2].pEnc Motor[3].pDac=Sys.Idata[3].a // Same as EncTable[3].pEnc Motor[4].pDac=Sys.Idata[4].a // Same as EncTable[4].pEnc Motor[5].pDac=Sys.Idata[5].a // Same as EncTable[5].pEnc Motor[6].pDac=Sys.Idata[6].a // Same as EncTable[6].pEnc Motor[7].pDac=Sys.Idata[7].a // Same as EncTable[7].pEnc Motor[8].pDac=Sys.Idata[8].a // Same as EncTable[8].pEnc // Encoder conversion table entry to read and integrate this EncTable[1].type=1 // 32-bit register read EncTable[1].pEnc=Sys.idata[1].a // Same as Motor[1].pDac EncTable[1].pEnc1=Sys.pushm // Dummy read (not used) EncTable[1].index1=0 // No shift right of source data EncTable[1].index2=0 // No shift left of source data EncTable[1].index3=0 // No accel limiting EncTable[1].index4=1 // Single integration EncTable[1].PrevDelta=0 // No bias before integration EncTable[1].MaxDelta=0 // No velocity limit EncTable[1].ScaleFactor=1/65536 // 32 bits -> 16 bits EncTable[2].type=1 // 32-bit register read EncTable[2].pEnc=Sys.idata[2].a // Same as Motor[2].pDac EncTable[2].pEnc1=Sys.pushm // Dummy read (not used) EncTable[2].index1=0 // No shift right of source data EncTable[2].index2=0 // No shift left of source data EncTable[2].index3=0 // No accel limiting EncTable[2].index4=1 // Single integration EncTable[2].PrevDelta=0 // No bias before integration EncTable[2].MaxDelta=0 // No velocity limit EncTable[2].ScaleFactor=1/65536 // 32 bits -> 16 bits EncTable[3].type=1 // 32-bit register read EncTable[3].pEnc=Sys.idata[3].a // Same as Motor[3].pDac EncTable[3].pEnc1=Sys.pushm // Dummy read (not used) EncTable[3].index1=0 // No shift right of source data EncTable[3].index2=0 // No shift left of source data EncTable[3].index3=0 // No accel limiting EncTable[3].index4=1 // Single integration EncTable[3].PrevDelta=0 // No bias before integration EncTable[3].MaxDelta=0 // No velocity limit EncTable[3].ScaleFactor=1/65536 // 32 bits -> 16 bits EncTable[4].type=1 // 32-bit register read EncTable[4].pEnc=Sys.idata[4].a // Same as Motor[4].pDac EncTable[4].pEnc1=Sys.pushm // Dummy read (not used) EncTable[4].index1=0 // No shift right of source data EncTable[4].index2=0 // No shift left of source data EncTable[4].index3=0 // No accel limiting EncTable[4].index4=1 // Single integration EncTable[4].PrevDelta=0 // No bias before integration EncTable[4].MaxDelta=0 // No velocity limit EncTable[4].ScaleFactor=1/65536 // 32 bits -> 16 bits EncTable[5].type=1 // 32-bit register read EncTable[5].pEnc=Sys.idata[5].a // Same as Motor[5].pDac EncTable[5].pEnc1=Sys.pushm // Dummy read (not used) EncTable[5].index1=0 // No shift right of source data EncTable[5].index2=0 // No shift left of source data EncTable[5].index3=0 // No accel limiting EncTable[5].index4=1 // Single integration EncTable[5].PrevDelta=0 // No bias before integration EncTable[5].MaxDelta=0 // No velocity limit EncTable[5].ScaleFactor=1/65536 // 32 bits -> 16 bits EncTable[6].type=1 // 32-bit register read EncTable[6].pEnc=Sys.idata[6].a // Same as Motor[6].pDac EncTable[6].pEnc1=Sys.pushm // Dummy read (not used) EncTable[6].index1=0 // No shift right of source data EncTable[6].index2=0 // No shift left of source data EncTable[6].index3=0 // No accel limiting EncTable[6].index4=1 // Single integration EncTable[6].PrevDelta=0 // No bias before integration EncTable[6].MaxDelta=0 // No velocity limit EncTable[6].ScaleFactor=1/65536 // 32 bits -> 16 bits EncTable[7].type=1 // 32-bit register read EncTable[7].pEnc=Sys.idata[7].a // Same as Motor[7].pDac EncTable[7].pEnc1=Sys.pushm // Dummy read (not used) EncTable[7].index1=0 // No shift right of source data EncTable[7].index2=0 // No shift left of source data EncTable[7].index3=0 // No accel limiting EncTable[7].index4=1 // Single integration EncTable[7].PrevDelta=0 // No bias before integration EncTable[7].MaxDelta=0 // No velocity limit EncTable[7].ScaleFactor=1/65536 // 32 bits -> 16 bits EncTable[8].type=1 // 32-bit register read EncTable[8].pEnc=Sys.idata[8].a // Same as Motor[8].pDac EncTable[8].pEnc1=Sys.pushm // Dummy read (not used) EncTable[8].index1=0 // No shift right of source data EncTable[8].index2=0 // No shift left of source data EncTable[8].index3=0 // No accel limiting EncTable[8].index4=1 // Single integration EncTable[8].PrevDelta=0 // No bias before integration EncTable[8].MaxDelta=0 // No velocity limit EncTable[8].ScaleFactor=1/65536 // 32 bits -> 16 bits // Read the encoder conversion table result as feedback Motor[1].pEnc=EncTable[1].a // Position loop feedback source Motor[1].pEnc2=EncTable[1].a // Velocity loop feedback source Motor[2].pEnc=EncTable[2].a // Position loop feedback source Motor[2].pEnc2=EncTable[2].a // Velocity loop feedback source Motor[3].pEnc=EncTable[3].a // Position loop feedback source Motor[3].pEnc2=EncTable[3].a // Velocity loop feedback source Motor[4].pEnc=EncTable[4].a // Position loop feedback source Motor[4].pEnc2=EncTable[4].a // Velocity loop feedback source Motor[5].pEnc=EncTable[5].a // Position loop feedback source Motor[5].pEnc2=EncTable[5].a // Velocity loop feedback source Motor[6].pEnc=EncTable[6].a // Position loop feedback source Motor[6].pEnc2=EncTable[6].a // Velocity loop feedback source Motor[7].pEnc=EncTable[7].a // Position loop feedback source Motor[7].pEnc2=EncTable[7].a // Velocity loop feedback source Motor[8].pEnc=EncTable[8].a // Position loop feedback source Motor[8].pEnc2=EncTable[8].a // Velocity loop feedback source // Disable overtravel limit inputs // May be needed if there are no physical switches present Motor[1].pLimits=0 Motor[2].pLimits=0 Motor[3].pLimits=0 Motor[4].pLimits=0 Motor[5].pLimits=0 Motor[6].pLimits=0 Motor[7].pLimits=0 Motor[8].pLimits=0 // Disable amplifier enable output // May be needed if channel is also connected to real amplifier Motor[1].pAmpEnable=0 Motor[2].pAmpEnable=0 Motor[3].pAmpEnable=0 Motor[4].pAmpEnable=0 Motor[5].pAmpEnable=0 Motor[6].pAmpEnable=0 Motor[7].pAmpEnable=0 Motor[8].pAmpEnable=0 // Disable amplifier fault input // May be needed if channel is also connected to real amplifier Motor[1].pAmpFault=0 Motor[2].pAmpFault=0 Motor[3].pAmpFault=0 Motor[4].pAmpFault=0 Motor[5].pAmpFault=0 Motor[6].pAmpFault=0 Motor[7].pAmpFault=0 Motor[8].pAmpFault=0 // Set derivative gain term in servo loop to zero // This is a Type 1 servo (single integration); does not need Kd Motor[1].Servo.Kvfb=0 Motor[2].Servo.Kvfb=0 Motor[3].Servo.Kvfb=0 Motor[4].Servo.Kvfb=0 Motor[5].Servo.Kvfb=0 Motor[6].Servo.Kvfb=0 Motor[7].Servo.Kvfb=0 Motor[8].Servo.Kvfb=0 // Lower proportional gain term from default Motor[1].Servo.Kp=1 Motor[2].Servo.Kp=1 Motor[3].Servo.Kp=1 Motor[4].Servo.Kp=1 Motor[5].Servo.Kp=1 Motor[6].Servo.Kp=1 Motor[7].Servo.Kp=1 Motor[8].Servo.Kp=1 // Add integral gain to force to zero error Motor[1].Servo.Ki=0.01 Motor[2].Servo.Ki=0.01 Motor[3].Servo.Ki=0.01 Motor[4].Servo.Ki=0.01 Motor[5].Servo.Ki=0.01 Motor[6].Servo.Ki=0.01 Motor[7].Servo.Ki=0.01 Motor[8].Servo.Ki=0.01 // Set deadband zone to zero Motor[1].Servo.BreakPosErr=0 Motor[2].Servo.BreakPosErr=0 Motor[3].Servo.BreakPosErr=0 Motor[4].Servo.BreakPosErr=0 Motor[5].Servo.BreakPosErr=0 Motor[6].Servo.BreakPosErr=0 Motor[7].Servo.BreakPosErr=0 Motor[8].Servo.BreakPosErr=0 // Add feedforward to minimize tracking error Motor[1].Servo.Kvff=1 Motor[1].Servo.Kaff=1 Motor[2].Servo.Kvff=1 Motor[2].Servo.Kaff=1 Motor[3].Servo.Kvff=1 Motor[3].Servo.Kaff=1 Motor[4].Servo.Kvff=1 Motor[4].Servo.Kaff=1 Motor[5].Servo.Kvff=1 Motor[5].Servo.Kaff=1 Motor[6].Servo.Kvff=1 Motor[6].Servo.Kaff=1 Motor[7].Servo.Kvff=1 Motor[7].Servo.Kaff=1 Motor[8].Servo.Kvff=1 Motor[8].Servo.Kaff=1

        我们把上述代码拷贝到PMAC脚本语言目录下的全局变量定义中,如下图所示:


在这里插入图片描述

        然后开始写入运动程序,在Motion Programs目录下的prog1.pmc文件中写入运动程序代码,此例中我们以两轴电机绘制矩形为例,把代码写进文件并保存。

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
/****************************************/ //By Jack Soong //Time:2019.1.21 &1 //定义坐标系1 #1->X; //将电机指定给x,y轴 #2->Y; open prog 1 // --------------------User Code Goes Here------------------------ linear //直线mode abs //绝对值编程 tm 500 //插补加速参数设置 ta 100 ts 200 dwell 0 Gather.Enable = 2;dwell 0//将数据收集到先前plot设置元素的缓冲区 X0 Y0; X0 Y100; X100 Y100; X100 Y0; X0 Y0; dwell 100; //延时 Gather.Enable = 0;dwell 0 //关闭收集 close /****************************************/

        完成上述步骤后,在解决方案名称上右击选择构建并下载所有程序,将程序下载到CK3M中,注意:如果连接实际硬件,需要在配置完电机后先选择映射PowerPMAC变量。


        OK!接下来我们就要让它动起来了,首先打开数据收集功能,在代码中我们已经开启了数据收集并保存到缓存中,这是我们需要在程序真正运行之前打开数据收集界面(位于菜单栏中,即绘图功能),如下图所示。



        在终端中输入"#1…2j/“命令先使能电机,然后用命令”&1 b1 r"运行我们的运动程序,在程序运行过程中,绘图界面上传数据按钮下方的进度条会随着程序的执行过程而有所变化,待进度条满后点击上传数据,并把要绘制的值添加到坐标轴(选中要添加的值,然后点击>>按钮将其添加到绘制栏,如果需要删除,则在绘制栏中选中该选项点击<<即可删除),此处我们以Motion[1].Cmd Position(即电机1的命令位置,换句话说就是理想输出位置)为横坐标,以Motion[2].Cmd Position为纵坐标绘制图形,得到的绘制图形如下,我们可以看到绘制的矩形似乎不太听话 ???? ???? ????,淡定点老铁,所画图形并非方方正正的矩形的原因在于:Power PMAC中有一个状态位(Coord[x].NoBlend)是用来控制各运动点之间是否进行插补的,Coord[x].NoBlend默认为0,即使能Move Blending,因此走出来的矩形并非理想形状,如果设置Coord[x].NoBlend=1那么这个矩形就比较听话啦!


5. 程序下载流程

  • step1:使用在线指令$$$***save$$$三个指令清零PMAC
  • step2:检查Motor的硬件接口(PS:老是自己变,咱也不知道为啥~)
  • step3:右击项目树主题,选择映射PowerPMAC变量
    在这里插入图片描述
  • step4:选择构建并下载程序
  • step5:记得要保存项目到PMAC,在线指令save

6. 学习途径

[1]前文提到的手册:软件参考手册、用户使用手册
[2]官方视频教程(发布在Youtube,需要怎么访问你懂的,前文提到的5天培训PPT便是该教程配套的)
[3]泰道官方论坛
[4]工控论坛PMAC专区
[5]文大侠博客
[6]Jackie的储物袋的博客

后记

        这几周可谓是历经千辛万险,终于有所入门,可离结题还是遥遥无期,虽然困难重重,但是问题的解决总会伴随着慢慢的成就感,越挫越勇才能成就更好的自己~
        第一次写博文,干货不多,只提供给大家一个初步入门的路子,顺便也当做学习笔记了。在此要感谢北京机科国创的李工、欧姆龙技术支持周工以及我的林副总师兄提供的帮助。

        下期预告:Power PMAC中运动程序的编写

复制代码
1
2
3
4
5
6
7
[1]: https://baike.baidu.com/item/PMAC/1955812?fr=aladdin 链接:https://pan.baidu.com/s/1bckz0_5ZJCDa17wzFxY-ug 提取码:6oo6

最后

以上就是怕孤单手套最近收集整理的关于Power PMAC运动控制器 —— 学习笔记1说明1. 硬件介绍2. 准备工作3. PMAC与上位机的连接4. 创建自己的伺服控制项目5. 程序下载流程6. 学习途径后记的全部内容,更多相关Power内容请搜索靠谱客的其他文章。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(60)

评论列表共有 0 条评论

立即
投稿
返回
顶部