How to develop a FIFO Circular Buffer for analyzing real-time data?

60 次查看(过去 30 天)
I'm working on a project using the Polhemus Liberty system for real-time motion tracking. Recently, I have developed a GUI in Matlab's GUIDE to acquire the position and orientation of the attached sensors at a 240Hz sampling frequency. Also, I added an artificial neural network (ANN) to do some predictions on the kinematic parameters in real-time. However, after having the ANN's predictions I should do some data analysis on multiple dimension arrays. Without having the real-time criteria this particular data analysis could only be done by adding multiple nested loops because of the high dimensionality. The issue is that if I add FOR loops to the method then the real-time (or close to real-time) criteria will definitely be harmed. In order to avoid the addition of the nested FOR loops I thought I could create a buffer (FIFO circular buffer) to temporarily store the predicted data and have the data analyzed. I have found a smart solution under the following link:
In my understanding, the above solution works as a '1 frame/sec' method. So after capturing an image and defining its 'centroid data' only one column will be either removed or expanded in the buffer mechanism. This works quite well in that particular case. What would happen if the sampling rate is not 1 sample/sec but 240Hz. Given an infinite while loop the data loss will be increased without changing the parameters of the buffer.
Does somebody have an idea how to either modify the linked solution or to create a completely new one? In the buffer I should have 100 samples to analyze.
Let's have some brainstorming on it! I'm opened to have some smart ideas. Thanks in advance, Rob

采纳的回答

Anver Hisham
Anver Hisham 2016-9-13
编辑:Walter Roberson 2016-9-13
In case you are looking for a circular buffer implementation, here is the one I'm using, https://www.mathworks.com/matlabcentral/fileexchange/52411-circularbuffer/content/circularBuffer.m
This is an extension of double class, so you can input it to any function accepting vectors/matrices.

更多回答(1 个)

Gavin
Gavin 2024-9-23,17:48
For a simpler case of needing a circular buffer to process USB or other irregularly timed input, try this:
Initialize the buffer, in my case there are 2 data components to each interrupt and I get about 10 inputs that can come in quickly.
Buffer, pointers and flag need to be globals
app.InBuffer = zeros(20, 2); % Array init for buffer
app.InPtr = 1; % Where to write
app.OutPtr = 1; % Where to read
app.BFEmpty = true; % No data yet
The USB input triggers a callback putting data into the buffer:
% Callback for whenever a "terminator" is received
function PicoInput(app,src,~)
% Inside the callback function, don't do much else
% (error checking allowed) that you don't have to do ASAP
raw = readline(src);
ch = char(raw); % readline gives a string, make it chars for easier parsing?
% Make the data into numbers so array can be used
PicoType = unicode2native(ch(1:1),'US-ASCII'); % first char always "type" - Convert to uint8?
PicoData = str2double(ch(2:end)); % numeric data starts at second char
PicoData = uint32(PicoData); % save as integer
% Put them into the buffer
app.InBuffer(app.InPtr,1) = app.PicoType;
app.InBuffer(app.InPtr,2) = app.PicoData;
% Go to the next position looping as necessary
if app.InPtr<size(app.InBuffer,1)
app.InPtr = app.InPtr + 1;
else
app.InPtr = 1;
end
app.BFEmpty = false; % Let reader know that there is data available
end
And in the "main" code retrieve the data as needed (make sure your buffer is big enough if this is slow)
% Read from the circular buffer of the input from Pico
function [Typ, Dat] = ReadInBuf(app)
if app.BFEmpty % already nothing to read, don't bother
Typ = 0;
Dat = 0;
return;
else
Typ = char(app.InBuffer(app.OutPtr,1)); % number in the array, char to use it
Dat = app.InBuffer(app.OutPtr,2); %
app.OutPtr = app.OutPtr + 1;
% A pain of MATLAB: uses 1 based instead of 0 based indexing so modulo can't be used
if app.OutPtr > size(app.InBuffer,1)
app.OutPtr = 1;
end
if app.OutPtr == app.InPtr % All caught up
app.BFEmpty = true;
end
end
end
This avoids the recopying the data every time an item is put in or taken out (buffer doesn't move). By making the buffer an array rather than a table (where possible) it's simple and fast. Note I use the ascii value of my input which is nastier that is should be in MATLAB.
Comments from experts welcome but don't get too nitpicky. ;-)
a side rant
Where are simple char2ascii() and ascii2char() ? And don't tell me about ascii2str and str2ascii, those are too messy and need extra work for string to char
rant off

类别

Help CenterFile Exchange 中查找有关 Graphics Performance 的更多信息

产品

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by