How to store object(like udp object) in level-2 s-function?
76 次查看(过去 30 天)
显示 更早的评论
Hello all,
I want to send control input from Matlab to FlightGear and receive aircraft data from FlightGear to Matlab with UDP communication.
So I made a code below:
function FG_Simulink(block)
% Level-2 MATLAB file S-Function for UDP communication with FlightGear
setup(block)
function setup(block)
% Register number of dialog parameters
block.NumDialogPrms = 0; % UDP send and receive ports
% Register number of input and output ports
block.NumInputPorts = 4; % aileron, elevator, rudder, throttle
block.NumOutputPorts = 11; % u, v, w, alpha, beta, p, q, r, phi, theta, psi
% Setup functional port dimensions
block.SetPreCompInpPortInfoToDynamic;
block.SetPreCompOutPortInfoToDynamic;
% Register sample times
% Specify discrete sample time with a period of 0.01 seconds and an offset of 0
block.SampleTimes = [0, 0]; % Correct format for discrete sample time
% Specify the block simStateCompliance.
block.SimStateCompliance = 'DefaultSimState';
% Register methods
block.RegBlockMethod('Start', @Start);
block.RegBlockMethod('Outputs', @Outputs);
block.RegBlockMethod('Terminate', @Terminate);
block.RegBlockMethod('SetInputPortSamplingMode', @SetInputPortSamplingMode);
block.RegBlockMethod('PostPropagationSetup', @DoPostPropSetup);
function SetInputPortSamplingMode(block, port, mode)
% Set the input port sampling mode
block.InputPort(port).SamplingMode = mode;
% Set the same sampling mode for all output ports
for i = 1:block.NumOutputPorts
block.OutputPort(i).SamplingMode = mode;
end
function DoPostPropSetup(block)
% Setup Dwork
block.NumDworks = 0;
% Setup Pwork (Pointer Work Vector) for storing UDP object
block.NumPworks = 2; % We need to store two UDP objects
function Start(block)
% Declare persistent variables to store UDP sender and receiver
persistent UdpSender UdpReceiver
% Initialize UDP sender and receiver
% Retrieve ports from dialog parameters
if isempty(UdpSender)
try
UdpSender = udpport("IPV4",'LocalPort',55001, 'Timeout', 1);
block.Pwork(1).Data = UdpSender;
catch e
error('Failed to bind sender UDP port: %s', e.message);
end
end
if isempty(UdpReceiver)
try
UdpReceiver = udpport("IPV4",'LocalPort',55002, 'Timeout', 1);
block.Pwork(2).Data = UdpReceiver;
catch e
error('Failed to bind receiver UDP port: %s', e.message);
end
end
function Outputs(block)
% Retrieve UDP objects from UserData
% Create input data vector
inputVector = zeros(1, 4);
inputVector(1) = block.InputPort(1).Data; % aileron
inputVector(2) = block.InputPort(2).Data; % elevator
inputVector(3) = block.InputPort(3).Data; % rudder
inputVector(4) = block.InputPort(4).Data; % throttle
Udpsender = block.Pwork(1).Data;
Udpreceiver = block.Pwork(2).Data;
% Send input data to FlightGear
try
write(Udpsender, inputVector, 'double', "LocalPort",55002); % Send to FlightGear receive port
catch e
warning('Failed to send data to FlightGear: %s', '%s', e.message);
end
% Receive flight data from FlightGear
try
data = read(Udpreceiver, 88, "double"); % 11 floats * 4 bytes each
if ~isempty(data)
outputVector = typecast(data, 'double');
for i = 1:block.NumOutputPorts
block.OutputPort(i).Data = outputVector(i);
end
end
catch e
% Handle timeout or any read errors
warning('Failed to receive data from FlightGear: %s', '%s', e.message);
end
function Terminate(block)
But when I launch a simulink file, the error was occured : "Cause: The property 'NumPworks' is not recognized for the class 'Simulink.MSFcnRunTimeBlock'."
I know that Dwork can not store the object type data, so if you have any idea to solve this problem, please let me know.
Thank you.
0 个评论
回答(1 个)
Divyam
2024-8-21,4:21
To store the UDP packets associated with a specific Simulink block, the "UserData" parameter of the Simulink block can be utilized to store data across callbacks. For your reference, I have made the edits to the "Start" function which incorporates the desired functionality.
function Start(block)
% Declare persistent variables to store UDP sender and receiver
persistent UdpSender UdpReceiver
%-- Get the block path --%
blockPath = gcb(block);
%-- Comment the below line if you don't wish to store the UserData persistently --%
set_param(gcb, 'UserDataPersistent', 'on');
% Initialize UDP sender and receiver
% Retrieve ports from dialog parameters
if isempty(UdpSender)
try
UdpSender = udpport("IPV4",'LocalPort',55001, 'Timeout', 1);
%-- Setting the UserData property to store UDP object --%
set_param(blockPath, 'UserData', UdpSender);
catch e
error('Failed to bind sender UDP port: %s', e.message);
end
end
if isempty(UdpReceiver)
try
UdpReceiver = udpport("IPV4",'LocalPort',55002, 'Timeout', 1);
%-- Setting the UserData property to store UDP object --%
set_param(blockPath, 'UserData', UdpReceiver);
catch e
error('Failed to bind receiver UDP port: %s', e.message);
end
end
For more information regarding the 'UserData' parameter, you can refer to this documentation: https://www.mathworks.com/help/simulink/ug/associating-user-data-with-blocks.html
0 个评论
另请参阅
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!