How to publish ROS message inside a parfor loop?
3 次查看(过去 30 天)
显示 更早的评论
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 个评论
采纳的回答
Edric Ellis
2017-2-13
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 个评论
更多回答(0 个)
另请参阅
类别
在 Help Center 和 File Exchange 中查找有关 Publishers and Subscribers 的更多信息
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!