ROS2 Subscriber Callback Function Arguments for Code Generation
8 ビュー (過去 30 日間)
古いコメントを表示
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
0 件のコメント
採用された回答
Josh Chen
2022 年 11 月 15 日
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
3 件のコメント
Josh Chen
2022 年 11 月 16 日
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
Josh Chen
2024 年 6 月 30 日
Quick update on the expected behavior since R2022b update:
If you have just one custom data in subscriber callback, you may pass it as either cell array, or function handle. For example:
mySub2 = ros2subscriber(node,"/myTopic","builtin_interfaces/Time",{@myCBFun2,pub2});
If have more than one custom data, pass it as function handle. For example:
mySub = ros2subscriber(node,"/myTopic","builtin_interfaces/Time",@(msg)myCBFun(msg, pub, varB));
Here is a dummy example:
function test_fun
node = ros2node("myNode");
pub = ros2publisher(node,"my_cb_pub","std_msgs/Bool");
pub2 = ros2publisher(node,"my_cb_pub2","std_msgs/Bool");
varB = int32(3);
mySub = ros2subscriber(node,"/myTopic","builtin_interfaces/Time",@(msg)myCBFun(msg, pub, varB));
mySub2 = ros2subscriber(node,"/myTopic","builtin_interfaces/Time",{@myCBFun2,pub2});
while true
fprintf('Waiting for messages to arrive ... \n');
pause(5);
end
function myCBFun(msg, myPub, var2)
fprintf('MESSAGE RECEIVED!, msg.sec is %d\n', msg.sec);
cb_msg = ros2message(myPub);
send(myPub, cb_msg);
fprintf('Var2 is: %d\n', var2);
end
function myCBFun2(msg, myPub)
fprintf('MESSAGE RECEIVED!, msg.sec is %d\n', msg.sec);
cb_msg = ros2message(myPub);
cb_msg.data = true;
send(myPub, cb_msg);
end
end
Hope that helps,
Thanks,
Josh
その他の回答 (0 件)
参考
カテゴリ
Help Center および File Exchange で Specialized Messages についてさらに検索
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!