1. 转速自定义计算
matlab 的tachorpm函数解析
function [rpm, t] = tachorpmauto(signal, fs, ppr, varargin)
% MY_TACHORPM 自定义实现的转速计算函数
% 输入参数:
% signal : 转速计脉冲信号(一维数组)
% fs : 采样率 (Hz)
% ppr : 每转脉冲数 (Pulses Per Revolution)
% 可选参数:
% 'EdgeType' : 边沿类型 ('rising'(默认)/'falling'/'both')
% 'MinPeakHeight' : 最小峰值高度阈值(默认:信号最大值的50%)
% 'MinPeakDist' : 最小脉冲间隔(默认自动计算)
% 输出参数:
% rpm : 转速序列 (RPM)
% t : 时间序列 (秒)
% 参数解析
p = inputParser;
addRequired(p, 'signal', @isvector);
addRequired(p, 'fs', @isscalar);
addRequired(p, 'ppr', @isscalar);
addParameter(p, 'EdgeType', 'rising', @(x) any(validatestring(x, {'rising','falling','both'})));
addParameter(p, 'MinPeakHeight', [], @isscalar);
addParameter(p, 'MinPeakDist', [], @isscalar);
parse(p, signal, fs, ppr, varargin{:});
% 转换为行向量
signal = signal(:)';
edgeType = lower(p.Results.EdgeType);
minPeakHeight = p.Results.MinPeakHeight;
minPeakDist = p.Results.MinPeakDist;
%% 1. 信号预处理:移动平均滤波
windowSize = 5;
filtered = movmean(signal, windowSize);
%% 2. 自动计算阈值
if isempty(minPeakHeight)
maxVal = max(filtered);
minPeakHeight = 0.5 * maxVal;
end
%% 3. 计算最小脉冲间隔(基于最大预期RPM)
if isempty(minPeakDist)
maxRpm = 6000; % 预期最大转速
minInterval = 60/(maxRpm * ppr); % 最短时间间隔(s)
minPeakDist = floor(minInterval * fs); % 转换为采样点数
end
%% 4. 脉冲检测
[locs_rise, locs_fall] = deal([]);
% 检测上升沿
if contains(edgeType, {'rising','both'})
[~, locs_rise] = findpeaks(filtered, 'MinPeakHeight',minPeakHeight,...
'MinPeakDistance',minPeakDist);
end
% 检测下降沿
if contains(edgeType, {'falling','both'})
[~, locs_fall] = findpeaks(-filtered, 'MinPeakHeight',-minPeakHeight,...
'MinPeakDistance',minPeakDist);
end
% 合并并排序脉冲位置
locs = sort([locs_rise, locs_fall]);
% 检查有效脉冲数
if numel(locs) < 2
error('检测到不足2个脉冲,无法计算转速!');
end
%% 5. 计算RPM
intervals = diff(locs)/fs; % 脉冲间隔(秒)
rpm_pulses = 60./(intervals * ppr); % 脉冲间RPM
% 脉冲时间点(取后一个脉冲时刻)
t_pulses = locs(2:end)/fs;
%% 6. 插值到原始时间轴
t = (0:length(signal)-1)/fs; % 完整时间序列
rpm = interp1(t_pulses, rpm_pulses, t, 'nearest', 'extrap'); % nearest linaer spline
end
使用方法测试
%% ------渥太华数据 ------
load I-C-2.mat;
fs= 200000;
x = Channel_1(1:fs*10);
x = x;
speed = Channel_2(1:fs*10);
t = (0:length(x)-1) / fs ;
%% 计算转速
rpm= tachorpm(speed, fs ,'FitPoints', 50, 'PulsesPerRev', 1024) ;
% 自定义函数
ppr = 1024 ; %% 每转 2 个脉冲
rpm1 = tachorpmauto(speed,fs, ppr,'EdgeType', "rising")'; % , "rising"
% rpm1 = tachorpm_auto(speed,fs, ppr,'MinPeakHeight')'
%% ------tachorpm 测试------
levels = statelevels(speed);
figure()
subplot(2,1,1)
plot(rpm1) ;
title('tachorpm-auto')
window_length = 51; % 根据数据调整
poly_order = 3;
%% rpm_smoothed = sgolayfilt(rpm1, poly_order, window_length);
% rpm_smoothed1 = sgolayfilt(rpm1, poly_order, window_length);
% 数据处理
rpm_smoothed = rpm1;
rpmtemp1 = zeros(length(rpm_smoothed),1);
N11 = length(rpm_smoothed);
for i = 1: length(rpm_smoothed)
if(i<(N11 -1024))
rpmtemp1(i) = mean(rpm_smoothed(i:i+1024));
else
rpmtemp1(i) = mean(rpm_smoothed(i:end));
end
end
rpm_smoothed= rpmtemp1;
N11 = length(rpm_smoothed);
for i = 1: length(rpm_smoothed)
if(i<(N11 -1024))
rpmtemp1(i) = mean(rpm_smoothed(i:i+1024));
else
rpmtemp1(i) = mean(rpm_smoothed(i:end));
end
end
figure()
plot(rpm)
hold on;
plot(rpmtemp1)
legend('tachorpm', 'tachorpm-auto')
title('对比')
使用方式:
function [rpm, t] = tachorpmauto(signal, fs, ppr, varargin)
% MY_TACHORPM 自定义实现的转速计算函数
% 输入参数:
% signal : 转速计脉冲信号(一维数组)
% fs : 采样率 (Hz)
% ppr : 每转脉冲数 (Pulses Per Revolution)
% 可选参数:
% 'EdgeType' : 边沿类型 ('rising'(默认)/'falling'/'both')
% 'MinPeakHeight' : 最小峰值高度阈值(默认:信号最大值的50%)
% 'MinPeakDist' : 最小脉冲间隔(默认自动计算)
% 输出参数:
% rpm : 转速序列 (RPM) % t : 时间序列 (秒)
% 参数解析
p = inputParser;
addRequired(p, 'signal', @isvector);
addRequired(p, 'fs', @isscalar);
addRequired(p, 'ppr', @isscalar);
addParameter(p, 'EdgeType', 'rising', @(x) any(validatestring(x, {'rising','falling','both'})));
addParameter(p, 'MinPeakHeight', [], @isscalar);
addParameter(p, 'MinPeakDist', [], @isscalar);
parse(p, signal, fs, ppr, varargin{:});
% 转换为行向量
signal = signal(:)';
edgeType = lower(p.Results.EdgeType);
minPeakHeight = p.Results.MinPeakHeight;
minPeakDist = p.Results.MinPeakDist;
%% 1. 信号预处理:移动平均滤波
windowSize = 5;
filtered = movmean(signal, windowSize);
%% 2. 自动计算阈值
if isempty(minPeakHeight)
maxVal = max(filtered);
minPeakHeight = 0.5 * maxVal;
end
%% 3. 计算最小脉冲间隔(基于最大预期RPM)
if isempty(minPeakDist)
maxRpm = 6000; % 预期最大转速
minInterval = 60/(maxRpm * ppr); % 最短时间间隔(s)
minPeakDist = floor(minInterval * fs); % 转换为采样点数
end
%% 4. 脉冲检测
[locs_rise, locs_fall] = deal([]);
% 检测上升沿
if contains(edgeType, {'rising','both'})
[~, locs_rise] = findpeaks(filtered, 'MinPeakHeight',minPeakHeight,...
'MinPeakDistance',minPeakDist);
end
%% -----自定义实现 4.0 脉冲检测 - 上------
tempx = zeros(1,100);
Li=1;
for i =2:(length(filtered)-1)
temp11 = filtered(i) - filtered(i-1);
temp12= filtered(i+1) - filtered(i);
if(temp11 >= 0 && temp12< 0 &&filtered(i)>0.8)
if(Li>1)
if((i-tempx(Li-1))<5)
tempx(Li-1) = i; % 去除邻近值
else
tempx(Li) = i;
Li = Li+ 1;
end
else
tempx(Li) = i;
Li = Li+ 1;
end
end
end
%% 去除邻近值
% for j = 2:(length(tempx)-1)
% tempx1 = tempx(j) - tempx(j-1);
% if(tempx1<5)
% tempx(j-1) =0;
% end
%
% end
tempxx =sort(tempx);
recordnoequal = zeros(1,500);
N3= 1;
N1=1;
N2 = 1;
for j= 1:length(locs_rise)
boolx11 = ismember(locs_rise(j), tempx);
if(~boolx11)
recordnoequal(N3) =locs_rise(j);
N3 = N3 + 1 ;
end
end
asdfg= 1;
%% -----自定义实现4.0 脉冲检测 -下------
% 检测下降沿
if contains(edgeType, {'falling','both'})
[~, locs_fall] = findpeaks(-filtered, 'MinPeakHeight',-minPeakHeight,...
'MinPeakDistance',minPeakDist);
end
% 合并并排序脉冲位置
locs = sort([locs_rise, locs_fall]);
% 检查有效脉冲数
if numel(locs) < 2
error('检测到不足2个脉冲,无法计算转速!');
end
%% ---- 测试---
locs = tempxx;
%% 5. 计算RPM
intervals = diff(locs)/fs; % 脉冲间隔(秒)
rpm_pulses = 60./(intervals * ppr); % 脉冲间RPM
% 脉冲时间点(取后一个脉冲时刻)
t_pulses = locs(2:end)/fs;
%% 6. 插值到原始时间轴
t = (0:length(signal)-1)/fs; % 完整时间序列
rpm = interp1(t_pulses, rpm_pulses, t, 'nearest', 'extrap'); % nearest linaer spline
end
测试计算