分析电机编码器的A相和Z相波形

numpy_motor_az.py

本习题的程序文件

用旋转编码器可以获得电机的旋转角度,旋转编码器输出A相和Z相波形。电机每旋转一圈Z相会产生一个脉冲信号,而电机每旋转一个小角度都会在A相产生一个脉冲信号。

numpy_motor_az.csv

使用数据采集卡采集的A相和Z相的信号

文件“numpy_motor_az.csv”是使用数据采集卡采集的A相和Z相的信号,我们希望通过此数据计算电机每旋转一圈会产生多少个A相的脉冲信号,即计算两个Z相脉冲之间的A相脉冲的个数。

读入CSV数据

“numpy_motor_az_az.csv”是以逗号隔开的CSV格式的文本数据,可以使用NumPy的loadtxt()读入。请编写读入数据的程序,数据的第0列用变量a保存,而第1列用变量z保存。

import numpy as np
DataFileName = "ex004_az.csv"

【你的程序】从DataFileName文件读入两列数据到数组a和z中

import pylab as pl
pl.subplot(221)
pl.plot(a)
pl.ylabel(u"A")
pl.subplot(223)
pl.plot(z)
pl.ylabel(u"Z")
pl.subplot(222)
pl.plot(a)
pl.xlim(166000, 167000)
pl.subplot(224)
pl.plot(z)
pl.xlim(166000, 167000)
“numpy_motor_az_az.csv”的第一行是数据名,读入数据时须注意跳过此行。

读入的数据如【图:电机编码器的A相和Z相波形】所示,左侧两个图显示波形的整体情况。由图可以数据中的Z相信号共有5个脉冲,而由于A相的脉冲太多,只有放大X轴(时间轴)才能观察到右侧显示的脉冲波形。

/tech/static/books/scipyex/_images//numpy_motor_az_01.png

电机编码器的A相和Z相波形

去噪声

【图:电机编码器的A相和Z相波形】可以看出A相和Z相波形中存在噪声,因此需要在将波形转换为脉冲波形之前对器进行低通滤波处理。请编写程序设计一个低通滤波器,得到去除噪声之后的信号fa和fz:

import scipy.signal as signal

【你的程序】设计一个滤波器,并用它对a和z滤波得到滤波之后的fa和fz

pl.figure()
pl.subplot(211)
pl.plot(a)
pl.plot(fa, "r", lw=2)
pl.xlim(166000, 167000)
pl.subplot(212)
pl.plot(z)
pl.plot(fz, "r", lw=2)
pl.xlim(166000, 167000)

程序的输出应和【图:用低通滤波器对A相和Z相信号滤波】相似。

/tech/static/books/scipyex/_images//numpy_motor_az_02.png

用低通滤波器对A相和Z相信号滤波

用lfilter()对信号滤波会产生延时,为了和原始信号进行比较,推荐使用无延时的滤波函数filtfilt()。

二值化

为了方便后续的数据处理,我们可以将滤波之后的波形数据转换为布尔数组。由【图:用低通滤波器对A相和Z相信号滤波】可知,使用15作为阈值对数据进行二值化是一个不错的选择。请编写二值化的程序计算两个布尔数组ba和bz,其结果如【图:二值化之后的A相和Z相波形】所示。

【你的程序】将数组fa和fz二值化成数组ba和bz

pl.figure()
pl.subplot(211)
pl.plot(ba, lw=2)
pl.xlim(166000, 167000)
pl.subplot(212)
pl.plot(bz, lw=2)
pl.xlim(166000, 167000)
/tech/static/books/scipyex/_images//numpy_motor_az_03.png

二值化之后的A相和Z相波形

如何用程序自动从数据中找到二值化的最佳阈值?

计算波形的个数

为了计算两个Z相脉冲之间的A相脉冲的个数,首先需要计算脉冲发生的时刻。我们可以把脉冲发生的时刻定义为数据由0变为1时的下标,请编写程序找到A相和Z相脉冲发生时的下标a_pos和z_pos:

【你的程序】计算ba和bz中数据由0变为1的下标
print "a_pos:", a_pos
print "z_pos:", z_pos

程序的输出应该为:

a_pos: [    92    258    406 ..., 999608 999795 999970]
z_pos: [166294 333181 499987 666786 833670]

最后只需要找到a_pos中值在z_pos的连续两个数值之间的元素个数既可。由于a_pos是一个递增的数组,因此我们可以用NumPy的searchsorted()快速计算z_pos中每个元素在a_pos中的位置。

searchsorted(a, v)在递增数组a中找到数值v的插入位置idx,使得将v插入到a中的位置idx之前时,能保持a仍然是递增数组,例如:

>>> np.searchsorted([1,3,5,7,9],4)
2

请编写程序使用searchsorted()计算两个Z相脉冲之间的A相脉冲的个数a_count:

【你的程序】计算z_pos中每个值在a_pos中的位置的差值

print "counts:", a_count

程序的输出应该为:

counts: [1024 1024 1024 1024]

由结果可知,电机每旋转一圈将产生1024个A相脉冲,因此每两个A相脉冲之间相差0.36度。

我们知道两个A相脉冲之间相差0.36度,而a_pos数组中保存的是A相脉冲发生的时刻,你能请通过a_pos绘制出电机的旋转角度和时间之间关系图吗?

內容目录

上一个主题

对多个数组做矩阵乘法运算

下一个主题

数值微分的精度

本页

loading...