How to publish ROS message inside a parfor loop?

2 Ansichten (letzte 30 Tage)
Dingqiao Zhu
Dingqiao Zhu am 12 Feb. 2017
Kommentiert: Flavia Causa am 28 Mär. 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!!!

Akzeptierte Antwort

Edric Ellis
Edric Ellis am 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 Kommentare
Dingqiao Zhu
Dingqiao Zhu am 14 Mär. 2017
I finally find that if I want to publish ROS message in workers, I have to run rosinit in every worker so that they can connect to the ROS network. By this way, workers can publish ROS message to the ROS network.
Flavia Causa
Flavia Causa am 28 Mär. 2018
How did you manage to run rosinit for every worker?

Melden Sie sich an, um zu kommentieren.

Weitere Antworten (0)

Kategorien

Mehr zu Publishers and Subscribers finden Sie in Help Center und File Exchange

Community Treasure Hunt

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

Start Hunting!

Translated by