How to publish ROS message inside a parfor loop?

2 visualizzazioni (ultimi 30 giorni)
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!!!

Risposta accettata

Edric Ellis
Edric Ellis il 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 Commenti
Dingqiao Zhu
Dingqiao Zhu il 14 Mar 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 il 28 Mar 2018
How did you manage to run rosinit for every worker?

Accedi per commentare.

Più risposte (0)

Categorie

Scopri di più su Publishers and Subscribers in Help Center e File Exchange

Community Treasure Hunt

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

Start Hunting!

Translated by