Issues with using codegen on handle objects with complex methods
5 次查看(过去 30 天)
显示 更早的评论
I'm running into a fundamental issue with using codegen in my project, and it is unclear if there is a reasonable workaround. I am using several custom handle objects within a ros2 node that are used as inputs to subscription callback functions. In order to have codegen convert all of the internal functions (ie, to fully excercise it), I need to send that node a rather long and complex series of ros2 messages that trigger these various callbacks. In order to generate these messages within the node function itself, I would have to bring in the entire large test script and go through codegen for the whole thing, even though it is irrelevant to the function of the node itself. I addition to this, many of the functions I would need to be able to do so are not supported by codegen, so I would need to rework that entire script to account for that.
What I have tried so far as a workaround is the following:
- Place the node generation function within the test script, and output the node and subscriber handles back into the script. This works as intended within normal matlab, but is not supported within codegen since it does not support handle outputs.
- If I do not output the node and subscription handle, they are deleted when the function completes. In this case the script runs but none of the callbacks I want to trigger ever get run with the data they need to be thoroughly exercised, since they are triggered by the test script but the handles to which they are associated have been deleted. I can run codegen on this version, but it ultimately runs into the following error after all other errors have been resolved: 'The library 'ROS 2 Node' is not supported by the current target, language or compiler.'
- If I add a loop within the function to stop it from completing, it blocks further evaluation of the test script, so the messages never get sent and the callbacks never trigger. I have not tried running codegen on this variation.
At a high level, the test script and node that works look like the following:
%%% Test Script that works but fails codegen %%%
% Set up test node
% Call the node that I am trying to run codegen on
[objectfindernode, objectfindersub]=objectFinderNode()
% Import test data
% Convert test data into msg1 format
% Send msg1 via test node publisher
% Check msg2 via test node subscriber callback
%%% End of test script %%%
%%% Node that works but fails codegen %%%
function [objectfindernode, objectfindersub]=objectFinderNode()
% Initialize handle objects ob1-obn and run needed methods
% build ros2 node 'objectfindernode'
% Add publisher 'pub' that publishes response 'msg2'
% Add subscriber 'objectfindersub' that subcribes to 'msg1' with callback
% callback1(ob1,...,obn,pub)
end
function callback1(msg,ob1,..,obn,pub)
% Do handle objects ob1-obn methods
% Populate and send msg2 via pub
end
%%% End of node that works but fails codegen %%%
If I change it to the following, the msg2 check never occurs, indicating that callback 1 never happened. Codegen runs on this version, but I still run into the error: 'The library 'ROS 2 Node' is not supported by the current target, language or compiler.' I also do not know which parts of the code are actually getting called.
%%% Test Script that does not work correctly and fails codegen differently %%%
% Set up test node
% Call the node that I am trying to run codegen on
[objectfindernode, objectfindersub]=objectFinderNode()
% Import test data
% Convert test data into msg1 format
% Send msg1 via test node publisher
% Check msg2 via test node subscriber callback
%%% End of test script %%%
%%% Node that can run in codegen until the listed error %%%
function objectFinderNode()
% Initialize handle objects ob1-obn and run needed methods
% build ros2 node 'objectfindernode'
% Add publisher 'pub' that publishes response 'msg2'
% Add subscriber 'objectfindersub' that subcribes to 'msg1' with callback
% callback1(ob1,...,obn,pub)
end
function callback1(msg,ob1,..,obn,pub)
% Do handle objects ob1-obn methods
% Populate and send msg2 via pub
end
%%% End of node %%%
At this point I am stuck. Unless there are more workarounds that I am not aware of this is questionably feasible project, due to the difficulty involved in generating test data for the node with only the codegen-viable set of functions. Also, I have already applied the workaround shown here for how to fix the ros2subscription callback issues within codegen: https://www.mathworks.com/matlabcentral/answers/1851568-ros2-subscriber-callback-function-arguments-for-code-generation
Separately, are there plans to support handle object generation within loops in the future within codegen? I use cell arrays of handle objects throughout my project, so having to initialize each one individually is very tedious and verbose if it is a large array.
5 个评论
Josh Chen
2024-1-11
编辑:Josh Chen
2024-1-11
Hi James,
Sorry about my late response, not sure why there is no notification forwarded to my email.
Yes, when you mentioned the system has multiple nodes (n=1:N), and they should be able to interact with each other, first time came into my mind is you can use script-based codegen and just run the codegen commmand multiple times to build and run multiple nodes.
I might not fully understand the execution structures you want to check and convert, but it sounds like each node and callback has their own specific parameter/variable, and you want to test all of those combinations.
If we create one function for each node, then it allows you to:
- Include infinite loop to keep node alive until you manually kill the node
- Use meaningful name to distinguish between different nodes (e.g. first function is the first node, so inside first function, use ros2node('node_1');, in second function, use ros2node('node_2');, etc
- Each node run independently and are always visible to other nodes as long as they are in the same domain id.
Hope that helps.
Thanks,
Josh
回答(0 个)
另请参阅
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!