MATLAB中如何计算传感器读数超出阈值的总持续时长?
问题描述
我正在使用MATLAB开发代码,需统计传感器读数超出阈值(5)时的总持续时长。现有代码可检测传感器丢失/恢复状态并记录对应仿真时间戳,但无法正确计算每次丢失的时长。
现有代码
if SensorReadingsFunction(nTracks) > 5 % Fusion lost, log the time stamp if isempty(lostLog) || lostLog(end) ~= nTracks lostLog = [lostLog, nTracks]; lostTimestamp = scene.SimulationTime; fuseLostTimestamp = [fuseLostTimestamp; lostTimestamp]; % fusedRegainedTimestamp= []; end status = 'Sensor Lost'; else % Fusion regained, log the time stamp if ~isempty(lostLog) && lostLog(end) ~= nTracks-1 regainedLog = [regainedLog, nTracks-1]; regainedTimestamp = scene.SimulationTime; fusedRegainedTimestamp = [fusedRegainedTimestamp; regainedTimestamp]; % Calculate the duration of lost fusion if fusion was regained if ~isempty(fuseLostTimestamp) && ~isempty(fusedRegainedTimestamp) lostDuration = fusedRegainedTimestamp(1) - fuseLostTimestamp(1); end lostDurationRecord = [lostDurationRecord; lostDuration]; % Reset lost timestamp when fusion is regained for the first time %fuseLostTimestamp = []; end status = 'Sensor Gained'; end
示例时间戳数据
fuseLostTimestamp(传感器丢失时间)
0 69 70 71 72 90 93 96 97 98
fusedRegainedTimestamp(传感器恢复时间)
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 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 92 95 100
解决方案
一、计算每次传感器丢失的持续时长
现有时间戳存在重复记录问题(连续丢失/恢复时多次记录),需先清洗数据,将丢失与恢复事件一一配对后再计算时长:
步骤1:清洗时间戳
仅保留状态切换的关键时刻(正常→丢失的起始时间、丢失→正常的结束时间):
% 清洗丢失时间戳:去除连续重复的丢失记录,仅保留每次丢失的起始时刻 cleanLost = fuseLostTimestamp([true; diff(fuseLostTimestamp) > 1]); % 清洗恢复时间戳:去除连续重复的恢复记录,仅保留每次恢复的结束时刻 cleanRegained = fusedRegainedTimestamp([true; diff(fusedRegainedTimestamp) > 1]);
步骤2:补全未配对的时间戳(可选)
若仿真结束时传感器仍处于丢失状态,用当前仿真时间补全恢复时间:
if length(cleanLost) > length(cleanRegained) cleanRegained = [cleanRegained; scene.SimulationTime]; end
步骤3:计算时长
% 计算每次丢失的持续时长 eachLostDuration = cleanRegained - cleanLost; % 计算总丢失时长 totalLostDuration = sum(eachLostDuration);
二、更优的实现方式
现有代码逻辑混乱、重复记录时间戳且效率低,建议采用状态机思路,仅在状态切换时记录时间戳,实时计算丢失时长:
% 初始化状态变量(放在仿真循环外部) isSensorLost = false; fuseLostTimestamp = []; fusedRegainedTimestamp = []; lostDurationRecord = []; % 仿真循环内的核心代码 currentReading = SensorReadingsFunction(nTracks); currentTime = scene.SimulationTime; if currentReading > 5 if ~isSensorLost % 状态从正常转为丢失,记录丢失起始时间 fuseLostTimestamp = [fuseLostTimestamp; currentTime]; isSensorLost = true; end status = 'Sensor Lost'; else if isSensorLost % 状态从丢失转为正常,记录恢复时间并计算本次丢失时长 fusedRegainedTimestamp = [fusedRegainedTimestamp; currentTime]; lostDuration = currentTime - fuseLostTimestamp(end); lostDurationRecord = [lostDurationRecord; lostDuration]; isSensorLost = false; end status = 'Sensor Gained'; end % 仿真结束时,若传感器仍处于丢失状态,补全最后一次丢失的时长(可选) if isSensorLost finalDuration = scene.SimulationTime - fuseLostTimestamp(end); lostDurationRecord = [lostDurationRecord; finalDuration]; fusedRegainedTimestamp = [fusedRegainedTimestamp; scene.SimulationTime]; end % 总丢失时长 totalLostDuration = sum(lostDurationRecord);
优势
- 逻辑清晰:用
isSensorLost跟踪当前状态,仅在状态切换时操作,避免重复记录 - 实时计算:每次恢复时直接计算本次丢失时长,无需后续清洗数据
- 效率更高:大幅减少数组拼接次数,提升代码运行效率
内容的提问来源于stack exchange,提问作者Harsh R
相关产品推荐
相关产品推荐

