Plotting in a parallel while reading serial

Hi there,
I have the following code (which I have simplified a bit to post).
It captures the position and force from a test rig, which I am printing out over serial as fast as possible and reading into matlab.
It grabs the most recent reading from each serial device and stores it along with the current time (using tic toc).
I then plot this data on a graph.
My problem is that while matlab is executing the plot I miss some new incoming serial data and build up a back log.
I have improved the situation by only plotting every 50 times i collect data, but this still allows a buildup to occur during plotting. Can i carry out the plot in a parallel thread to avoid affecting the serial reads? How would i structure this?
Thanks!
positioncounter=0;
forcecounter=0;
tic
while running==1
if rig.bytesavailable>0 %grab rig position and time
positioncounter=positioncounter+1;
position = fscanf(rig);
ResultsPosition(positioncounter,1)= toc;
ResultsPosition(positioncounter,2)=str2double(position(1:end-2));
end
if s.bytesavailable>0 %grab force and time
forcecounter=forcecounter+1;
force = fscanf(s);
ResultsForce(forcecounter,2)=9.81*str2double(force(1:end-2));
ResultsForce(forcecounter,1)= toc;
end
try
yyaxis left
plot(ResultsForce(:,1),ResultsForce(:,2));
yyaxis right
plot(ResultsPosition(:,1),ResultsPosition(:,2));
end
running =get(handles.BTN_CAPTURE,'Value'); %is button still toggled on
drawnow();
end

8 comentarios

Walter Roberson
Walter Roberson el 7 de Jun. de 2019
No. The graphic display cannot be affected by any parallel thread.
You would have to do the plotting in the client, but you could potentially do the data collection in a parallel thread. However, there will be overhead in making the data available between processes, and so there is risk of similar build-up.
You shoud look in the File Exchange for "shared array": it can be used to share data between processes.
Adam
Adam el 7 de Jun. de 2019
Editada: Adam el 7 de Jun. de 2019
If you have the Parallel Computing Toolbox then
doc batch
may help, though it is one of those things I have often wanted to look into to see where it could be useful but have never had the time. Theoretically it lets you run a Matlab script or function on a worker, but plotting is not generally possible in parallel. I'm not sure if it would work in this case or not though or what the syntax would be. Maybe you can run the code that collects the data in this way and keep the plotting in the main thread, but I don't know.
Walter Roberson
Walter Roberson el 7 de Jun. de 2019
Communication back to the thread doing the plotting becomes an issue at high speed.
The problem can be reduced by using a BytesAvailableFcn callback to read available data instead of doing polling, and possibly adjusting the buffer size.
Steven Brace
Steven Brace el 7 de Jun. de 2019
It's important that I know reasonably accurately when the message was received, that's why I don't store it in a buffer.
I am basically receiving position and force data and plotting them against time. And then interpolating the data to plot force against position.
I could just throw away all of the serial messages that arrived during the plotting and have a small gap in my data, think that might be easiest way forward.
Walter Roberson
Walter Roberson el 7 de Jun. de 2019
You need to be able to plot with accurate timestamps, but you do not need to compute with them in real-time.
This suggests that you should consider doing data collection with an NI chassis that will timestamp samples for you, or else that you should consider doing data collection with an Arduino or Raspberry Pi and have those add timestamps before sending the data on to MATLAB.
Steven Brace
Steven Brace el 8 de Jun. de 2019
I am actually recording and sending the data with two adruinos, one for force one for position. I had opted to time stamp the in matlab to increase the sample frequency possible as this is limited by the speed of the serial port. Also as I am using one of the arduinos to do motion control the blocking during the serial write causes issues with shuddering, so I am trying to keep the amount of writing to a minimum on that one. So potentially I need a third arduino!
Walter Roberson
Walter Roberson el 8 de Jun. de 2019
Are you using true serial, or are you using serial over USB ?
There is an arduino-like device that sends data direct to USB instead of buffering it, and so can achieve higher data rates. Unfortunately I keep losing track of which device it is.
Do you need or want every point to be its own plot, as is in your code included in the question? This is, in general, an expensive way to plot data. Much more efficient is to create one plot and then edit its XData and YData properties to add your new data.
e.g.
yyaxis left
hPlotForce = plot(ResultsForce(:,1),ResultsForce(:,2));
yyaxis right
hPlotPosition = plot(ResultsPosition(:,1),ResultsPosition(:,2));
for the first point, then
set( hPlotForce, 'XData', [ hPlotForce.XData, ResultsForce(:,1) ], 'YData', [ hPlotForce.YData, ResultsForce(:,2) ] );
set( hPlotPosition, 'XData', [ hPlotPosition.XData, ResultsPosition(:,1) ], 'YData', [ hPlotPosition.YData, ResultsPosition(:,2) ] );
on each subsequent pass.
Normally I do this by storing a handle to the initially empty plot e.g.
hPlotForce = [];
then in my code I have an if else
if isempty( hPlotForce )
...
else
...
end
where the first code above goes in the if and the second block of code in the else - i.e. if the plot hasn't been created yet then call plot, if it has then edit the existing plot.
Sometimes simply speeding up the way you plot solves the problems itself without you needing to come up with complex parallelisation. It may not in this case, I don't know, but calls to plot are expensive and create a new graphics object every time and the more individual graphics objects you have the slower your code is generally.

Iniciar sesión para comentar.

Respuestas (0)

Categorías

Más información sobre Graphics Performance en Centro de ayuda y File Exchange.

Productos

Versión

R2018b

Preguntada:

el 7 de Jun. de 2019

Comentada:

el 10 de Jun. de 2019

Community Treasure Hunt

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

Start Hunting!

Translated by