Effacer les filtres
Effacer les filtres

How to store object(like udp object) in level-2 s-function?

76 vues (au cours des 30 derniers jours)
준호
준호 le 6 Août 2024 à 5:00
Réponse apportée : Divyam le 21 Août 2024 à 4:21
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.

Réponses (1)

Divyam
Divyam le 21 Août 2024 à 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

Community Treasure Hunt

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

Start Hunting!

Translated by