How to publish ROS message inside a parfor loop?
2 views (last 30 days)
Show older comments
Dingqiao Zhu
on 12 Feb 2017
Commented: Flavia Causa
on 28 Mar 2018
I'm processing real-time data inside a parfor loop. I want to publish the result as soon as I get it.
segmentMsg{1} = rosmessage('std_msgs/Float64');
segmentMsg{2} = rosmessage('std_msgs/Float64');
segmentPub{1} = rospublisher('/topic_segments_1', 'std_msgs/Float64');
segmentPub{2} = rospublisher('/topic_segments_2', 'std_msgs/Float64');
parfor i=1:2
%%Processing...
% if get some result, assign it to segmentMsg, publish it immediately
send(segmentPub{i},segmentMsg{i});
end
If I use for loop instead of parfor loop, my code works well. But when I publish ROS message inside parfor loop, an error named,
Invalid or deleted object
throwed. It means that publisher is deleted. I don't know why this problem happened. Is it because when enter parfor loop certain data type will be cleared? I've checked the type of ROS publisher, it's not a handle. It may be an object.
>> class(segmentPub{1})
ans =
robotics.ros.Publisher
Then I find an article: Use Objects and Handles in parfor-Loops It says that, if you are passing objects into or out of a parfor-loop, the objects must properly facilitate being saved and loaded. For more information , see Save and Load Process for Objects And then I run the following code in command window to test if save/load can help me:
segmentMsg = rosmessage('std_msgs/Float64');
segmentPub = rospublisher('/topic_segments_1', 'std_msgs/Float64');
save('segmentPub.mat','segmentPub');
Warning: robotics.ros.Publisher object cannot be saved to a MAT-file. > In robotics.ros.internal.mixin.Unsaveable/saveobj (line 28)
clear segmentPub; % clear the variable, so that we can test if save/load work well
load('segmentPub.mat')
Warning: Loaded robotics.ros.Publisher object is invalid. > In robotics.ros.internal.mixin.Unsaveable/loadobj (line 46)
segmentMsg.Data = 111.1;
send(segmentPub,segmentMsg);
Invalid or deleted object. Error in robotics.ros.Publisher/send (line 203) if ~strcmp(sendType, obj.MessageType)
Still throwing the same problem... I double-click the variable "segmentPub", and found that it only contained its properties, the corresponding values is missed. I wonder, if there any way to publish ROS message inside a parfor loop? Thanks!!!
0 Comments
Accepted Answer
Edric Ellis
on 13 Feb 2017
I think what you need to do here is ensure you call rosmessage and rospublisher directly on the workers. One way to do that is to use a parallel.pool.Constant to store those objects. You can build the Constant using a function handle, and that way, the function gets executed on the workers. Here's what I think you need to do (I have no way to test unfortunately).
segmentMsgConstant = parallel.pool.Constant(@() rosmessage('std_msgs/Float64'));
segmentPubConstant = parallel.pool.Constant(@() rospublisher('/topic_segments_1', 'std_msgs/Float64'));
parfor i = 1:2
...
send(segmentPubConstant.Value, segmentMsgConstant.Value);
end
3 Comments
More Answers (0)
See Also
Categories
Find more on Publishers and Subscribers 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!