Run move and collect functions in parallel
3 次查看(过去 30 天)
显示 更早的评论
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 个评论
回答(1 个)
Raymond Norris
2025-2-25
@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 个评论
Raymond Norris
2025-2-28
@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).
另请参阅
类别
在 Help Center 和 File Exchange 中查找有关 Parallel Computing Fundamentals 的更多信息
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!