Programmatically create ROS message in Matlab Function block (Simulink)

2 views (last 30 days)
Hi!
I am using the Robotics System Toolbox in Simulink to make a publisher. As the messages I want to publish contain arrays I am using a Matlab Function Block to fill out all the fields. To obtain an empty message object of the correct type in the Matlab Function Block I use an input port that gets the message from a Blank Message- Block. However I also want to create messages in subfunctions called by the Matlab Function Block that do not have such an input port themselves.
Now my question is: How can I create a ROS message object (Bus signal) of the proper type programatically in a Matlab Function Block? I cannot use the rosmessage command from Matlab as it is not supported by Code Generation.

Answers (1)

Swarooph
Swarooph on 27 Jul 2016
Hello,
Since rosmessage is not supported for code generation, you may have to use the Simulink infrastructure to make your life easy. Long story short: Pass a second blank message also as an input to your main MATLAB function. Then pass this dummy message as an input to your sub function. Sub functions don't require mention of ROS message/any data type. They will take in whatever you pass them. So here is an example.
Suppose you have 2 messages.
  1. A GeoPoint message
  2. A WayPoint message that is constructed from the above GeoPoint message in a sub function
First let's use 2 blank message blocks. 1 for each of the above message. In a real application, the GeoPoint message could come from a Subscriber.
Inside the MATLAB function block you could do the following:
function y = fcn(inputMsg,toConstructMsg)
%#codegen
%inputMsg is a GeoPoint message
%toConstructMsg is a WayPoint message
%Example tries to set toConstruct to twice the input GeoPoint
%Pass blank message to be constructed inside subfunction 'twoTimes'
y = twoTimes(inputMsg,toConstructMsg);
end
function y1 = twoTimes(u1,u2)
%Create a blank message copy to set the output
y1 = u2;
%Set appropriate values for fields
y1.Position.Latitude = 2*(u1.Latitude);
y1.Position.Longitude = 2*(u1.Longitude);
y1.Position.Altitude = 2*(u1.Altitude);
end
Attached is the example. Runs in MATLAB R2016a.
  2 Comments
offroad
offroad on 28 Jul 2016
Thank you for the thorough answer. Your way would enable a subblock to fill in a message object. However with many message objects it might get messy to pass around the Blank Message objects. So I conclude that there would be no programmatic way?
Swarooph
Swarooph on 28 Jul 2016
If you don't care about code generation, you could declare the rosmessage function with the coder.extrinsic keyword and see if that works. Note that, during simulation, the code generation software generates code for the call to an extrinsic function, but does not generate the function's internal code. Therefore, simulation can run only on platforms where MATLAB software is installed.

Sign in to comment.

Categories

Find more on Publishers and Subscribers in Help Center and File Exchange

Community Treasure Hunt

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

Start Hunting!