ROS2 Subscriber Callback Function Arguments for Code Generation

21 vues (au cours des 30 derniers jours)
Michael
Michael le 15 Nov 2022
Commenté : Josh Chen le 16 Nov 2022
I need to pass additional variables to my ROS2 subscriber callback function. I am trying to follow the help file explicity, which states:
"callback can be a single function handle or a cell array. The first element of the cell array needs to be a function handle or a string containing the name of a function. The remaining elements of the cell array can be arbitrary user data that will be passed to the callback function."
Based on this I built the following function to run my ROS2 subscriber node:
function [] = multirate_tag_sorter_test_simple()
node = ros2node("myNode",0);
myMsg = ros2message("builtin_interfaces/Time");
tableA = struct2table(myMsg, 'AsArray', true);
%% THE CREATING PROBLEMS ---V
mySub = ros2subscriber(node,"/myTopic","builtin_interfaces/Time",{@receivedMessageCallback,tableA});
%
while true
fprintf('Waiting for messages to arrive...\n')
pause(5);
end
function receivedMessageCallback(src,msg,inputTable)
fprintf('MESSAGE RECEIVED!');
end
end
but this generates error for code generation (see end of this question). The callback works fine if I don't try to pass additional arguments (i.e. mySub = ros2subscriber(node,"/myTopic","builtin_interfaces/Time",@receivedMessageCallback). The issue I am having is that when I try to specify the callback as {@receivedMessageCallback,tableA}, I get the error message shown at the bottom of this message.
The error message states that it expects a parameter name. It seems that Coder doesn't know that {@func,var1} is a callback function declaration. Unfortunately, callback functions are not listed in the nave-value pair list in the help file for ros2subscriber. I even tried setting the property manually after the subscriber intialization,
mySub = ros2subscriber(node,"/myTopic","builtin_interfaces/Time")
mySub.NewMessageFnc = {@receivedMessageCallback,tableA};
but got an error stating that NewMessageFnc is immutable, so it must be specified in the ros2subscriber call. Is this a bug with code generation for these callbacks, or am I doing something wrong? If it is a bug, is there a work around? Thanks.
The code generation script
cfg = coder.config('exe');
cfg.Hardware = coder.hardware('Robot Operating System 2 (ROS 2)');
cfg.Hardware.BuildAction = 'Build and load';
cfg.Hardware.RemoteDeviceAddress = 'XXX.XXX.XXX.XXX';
cfg.Hardware.RemoteDeviceUsername = 'XXXX';
cfg.Hardware.RemoteDevicePassword = 'XXXXX';
cfg.Hardware.DeployTo = 'Remote Device';
cfg.Hardware.ROS2Folder = '/opt/ros/galactic';
cfg.Hardware.ROS2Workspace = '~/uavrt_ws';
cfg.HardwareImplementation.ProdHWDeviceType = 'Intel->x86-64 (Linux 64)';
cfg.RuntimeChecks = true;%Disable for final deployments.
codegen multirate_tag_sorter_test_simple -args {} -config cfg
The error message
>> multirate_tag_sorter_test_codegen_script
??? Expected a parameter name.
Error in ==> multirate_tag_sorter_test_simple Line: 7 Column: 9
Code generation failed: View Error Report
Error using codegen
Error in multirate_tag_sorter_test_codegen_script (line 22)
codegen multirate_tag_sorter_test_simple -args {} -config cfg

Réponse acceptée

Josh Chen
Josh Chen le 15 Nov 2022
Hello Michael,
This is a known issue in code generation with ros2subscriber callback. Sorry about the inconvenience caused by this.
We are actively addressing this issue and will include the fix in a future update. May I know which version of MATLAB are you currently using?
Before this update get delivered, please use the modified code below as a workaround:
function [] = multirate_tag_sorter_test_simple()
node = ros2node("myNode",0);
myMsg = ros2message("builtin_interfaces/Time");
tableA = struct2table(myMsg, 'AsArray', true);
%% THE CREATING PROBLEMS ---V
mySub = ros2subscriber(node,"/myTopic","builtin_interfaces/Time",@(src,msg) receivedMessageCallback(src,msg,tableA));
%
while true
fprintf('Waiting for messages to arrive...\n')
pause(5);
end
function receivedMessageCallback(src,msg,inputTable)
fprintf('MESSAGE RECEIVED!');
end
end
i.e. still keep the callback function as a function handle and pass additional arguments as shown above.
I am using MATLAB R2022bd, which generates code and run as expected (See attached screenshot). Feel free to let me know if anything else I can help.
Thanks,
Josh
  2 commentaires
Michael
Michael le 16 Nov 2022
Josh,
Thanks for looking into this. I am running R2022b. This solution works for me. Glad to know it will be fixed in the next release. Will it be released in one of the R2022b updates or in R2023a? If you don't know, that's fine. I just want to know when I'll need to update my function. When it is fixed, I'll also want to come back into this post and make a comment about the fix for posterity's sake. I stay current on Matlab releases, but don't typically updated during between major releases. Will this work around continue to work when the update comes out, or will the update break this line of code? Thanks again.
Michael
Josh Chen
Josh Chen le 16 Nov 2022
Hello Michael,
Thanks for the feedback!
Given the severity and impact of this issue, it will be fixed in both R2022b updates and R2023a. We've created a bug report. Once it's published, you should be able to find it through this link.
The update would not affect how we process this workaround. You can continue using this workaround without any issue.
Best,
Josh

Connectez-vous pour commenter.

Plus de réponses (0)

Catégories

En savoir plus sur Publishers and Subscribers dans Help Center et File Exchange

Produits


Version

R2022b

Community Treasure Hunt

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

Start Hunting!

Translated by