Run move and collect functions in parallel
5 views (last 30 days)
Show older comments
I have a translation stage that I want to move over a set of positions. While the stage is moving I want to record data collected from an oscilliscope. The data is collected in a function using a while loop that periodically queries the buffer of the oscilliscope. The timing of the data read and stage movement are NOT synced. So I would like to continously collect data while the stage is moving and then stop once the stage finishes its motion. How can I do this using parpool and parfeval.
Conceptual code follows
parpool('Processes',1)
points = linspace(1,10,100); %positions to move translation stage
movePos(points) %move the stage to each point
parfeval(@getData,0,D) %read data from the oscilliscope while stage is moving
function data = getData(opts) %get data from the oscilliscope
data = [];
while isStageMoving %collect data while the stage is moving
datatemp = readOscope; %read segment of data
data = [data datatemp]; %concatonate data as it is collected
end
end
function movePos(points) %move the translation stage
isStageMoving = 1;
send(D,isStageMoving) %send to getData function to start data collection
nPoints = length(points) %loop over the positions that I want to move stage
for iPoints = 1:nPoints
movestage(points(iPoints))
end
isStageMoving = 0;
send(D,isStageMoving) %send to getData function to stop data collection
end
0 Comments
Answers (1)
Raymond Norris
on 25 Feb 2025
@Christopher Saltonstall here's an approach using spmd with two workers.
% function saltonstall
% 1. How is "D/opts" assigned and used?
% 2. What are we doing with "data" in getData()?
% 3. Does movePos need to return anything or does movestage do everything?
% 4. Can we block MATLAB while this spmd block is running or should it be
% non-blocking (this could be done)?
parpool("Threads",2);
spmd
if spmdIndex==1
% Move the translation stage
% Kick start reading Oscope on worker 2
spmdSend("start",2)
points = linspace(1,10,100);
nPoints = length(points);
for iPoints = 1:nPoints
movestage(points(iPoints))
end
% Signal worker 2 to stop reading Oscope
spmdSend("stop",2)
elseif spmdIndex==2
% Get data from the oscilliscope
% Get the signal from worker 1 to start
spmdReceive(1);
data = [];
while true
% Get data from the oscilliscope
datatemp = readOscope();
data = [data datatemp]; %#ok<AGROW>
if spmdProbe
% Got a signal, should we stop?
cmd = spmdReceive(1);
if strcmp(cmd,"stop")
break
end
end
end
end
end
% Pull the data from worker 2 and plot it
ldata = data{2};
plot(ldata)
2 Comments
Christopher Saltonstall
on 28 Feb 2025
Edited: Christopher Saltonstall
on 28 Feb 2025
Raymond Norris
on 28 Feb 2025
@Christopher Saltonstall if the workers need to send data back to the MATLAB client to update a UI in "real time", I would suggest you look at Receive Communication on Workers -- it's a good working example of what you probably want. A couple of comments:
- The example is running the same function on each worker. Instead of running a for-loop to spawn the same future on each worker, call parfeval twice, each with a different function to run on the worker (i.e., translation and oscope).
- The client is responsible for kicking things off and stopping. Worker 1 is not instructing Worker 2 to do something (if that's what you want). If you have the R2025a prerelease, you can read about pollable dataqueues between workers (where Worker 1 could instruct Worker 2 to do something).
See Also
Categories
Find more on Parallel Computing Fundamentals in Help Center and File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!