1+ function autodrive_hunter(block )
2+ % AutoDRIVE Hunter SE Simulink API
3+ % This is a Level-2 MATLAB S-Function wrapper for AutoDRIVE Hunter SE API
4+
5+ % Copyright 2024 AutoDRIVE Ecosystem
6+
7+ %% The setup method is used to set up the basic attributes of the
8+ %% S-function such as ports, parameters, etc. Do not add any other
9+ %% calls to the main body of the function.
10+
11+ setup(block );
12+
13+ % endfunction
14+
15+ %% Function: setup
16+ %% Abstract:
17+ %% Set up the basic characteristics of the S-function block such as:
18+ %% - Input ports
19+ %% - Output ports
20+ %% - Dialog parameters
21+ %% - Options
22+ %%
23+ %% Required: Yes
24+ %% C MEX counterpart: mdlInitializeSizes
25+
26+ function setup(block )
27+
28+ % Allow more than 2D signals
29+ block.AllowSignalsWithMoreThan2D = 1 ;
30+
31+ % Register number of ports
32+ block.NumInputPorts = 10 ;
33+ block.NumOutputPorts = 13 ;
34+
35+ % Setup port properties to be inherited or dynamic
36+ block .SetPreCompInpPortInfoToDynamic ;
37+ block .SetPreCompOutPortInfoToDynamic ;
38+
39+ % Override input port properties
40+ % Co-Simulation Mode
41+ block .InputPort(1 ).Dimensions = 1 ;
42+ block .InputPort(1 ).DatatypeID = 3 ; % uint8
43+ block .InputPort(1 ).Complexity = ' Real' ;
44+ block .InputPort(1 ).DirectFeedthrough = true ;
45+ % Position X Component
46+ block .InputPort(2 ).Dimensions = 1 ;
47+ block .InputPort(2 ).DatatypeID = 0 ; % double
48+ block .InputPort(2 ).Complexity = ' Real' ;
49+ block .InputPort(2 ).DirectFeedthrough = true ;
50+ % Position Y Component
51+ block .InputPort(3 ).Dimensions = 1 ;
52+ block .InputPort(3 ).DatatypeID = 0 ; % double
53+ block .InputPort(3 ).Complexity = ' Real' ;
54+ block .InputPort(3 ).DirectFeedthrough = true ;
55+ % Position Z Component
56+ block .InputPort(4 ).Dimensions = 1 ;
57+ block .InputPort(4 ).DatatypeID = 0 ; % double
58+ block .InputPort(4 ).Complexity = ' Real' ;
59+ block .InputPort(4 ).DirectFeedthrough = true ;
60+ % Orientation Quaternion X Component
61+ block .InputPort(5 ).Dimensions = 1 ;
62+ block .InputPort(5 ).DatatypeID = 0 ; % double
63+ block .InputPort(5 ).Complexity = ' Real' ;
64+ block .InputPort(5 ).DirectFeedthrough = true ;
65+ % Orientation Quaternion Y Component
66+ block .InputPort(6 ).Dimensions = 1 ;
67+ block .InputPort(6 ).DatatypeID = 0 ; % double
68+ block .InputPort(6 ).Complexity = ' Real' ;
69+ block .InputPort(6 ).DirectFeedthrough = true ;
70+ % Orientation Quaternion Z Component
71+ block .InputPort(7 ).Dimensions = 1 ;
72+ block .InputPort(7 ).DatatypeID = 0 ; % double
73+ block .InputPort(7 ).Complexity = ' Real' ;
74+ block .InputPort(7 ).DirectFeedthrough = true ;
75+ % Orientation Quaternion W Component
76+ block .InputPort(8 ).Dimensions = 1 ;
77+ block .InputPort(8 ).DatatypeID = 0 ; % double
78+ block .InputPort(8 ).Complexity = ' Real' ;
79+ block .InputPort(8 ).DirectFeedthrough = true ;
80+ % Throttle Command
81+ block .InputPort(9 ).Dimensions = 1 ;
82+ block .InputPort(9 ).DatatypeID = 0 ; % double
83+ block .InputPort(9 ).Complexity = ' Real' ;
84+ block .InputPort(9 ).DirectFeedthrough = true ;
85+ % Steering Command
86+ block .InputPort(10 ).Dimensions = 1 ;
87+ block .InputPort(10 ).DatatypeID = 0 ; % double
88+ block .InputPort(10 ).Complexity = ' Real' ;
89+ block .InputPort(10 ).DirectFeedthrough = true ;
90+
91+ % Override output port properties
92+ % Vehicle ID
93+ block .OutputPort(1 ).Dimensions = 1 ;
94+ block .OutputPort(1 ).DatatypeID = 5 ; % uint16
95+ block .OutputPort(1 ).Complexity = ' Real' ;
96+ % Throttle Feedback
97+ block .OutputPort(2 ).Dimensions = 1 ;
98+ block .OutputPort(2 ).DatatypeID = 0 ; % double
99+ block .OutputPort(2 ).Complexity = ' Real' ;
100+ % Steering Feedback
101+ block .OutputPort(3 ).Dimensions = 1 ;
102+ block .OutputPort(3 ).DatatypeID = 0 ; % double
103+ block .OutputPort(3 ).Complexity = ' Real' ;
104+ % Encoder Ticks
105+ block .OutputPort(4 ).Dimensions = [2 1 ];
106+ block .OutputPort(4 ).DatatypeID = 6 ; % int32
107+ block .OutputPort(4 ).Complexity = ' Real' ;
108+ % Encoder Angles
109+ block .OutputPort(5 ).Dimensions = [2 1 ];
110+ block .OutputPort(5 ).DatatypeID = 0 ; % double
111+ block .OutputPort(5 ).Complexity = ' Real' ;
112+ % Position
113+ block .OutputPort(6 ).Dimensions = [3 1 ];
114+ block .OutputPort(6 ).DatatypeID = 0 ; % double
115+ block .OutputPort(6 ).Complexity = ' Real' ;
116+ % Orientation (Quaternion)
117+ block .OutputPort(7 ).Dimensions = [4 1 ];
118+ block .OutputPort(7 ).DatatypeID = 0 ; % double
119+ block .OutputPort(7 ).Complexity = ' Real' ;
120+ % Orientation (Euler Angles)
121+ block .OutputPort(8 ).Dimensions = [3 1 ];
122+ block .OutputPort(8 ).DatatypeID = 0 ; % double
123+ block .OutputPort(8 ).Complexity = ' Real' ;
124+ % Angular Velocity
125+ block .OutputPort(9 ).Dimensions = [3 1 ];
126+ block .OutputPort(9 ).DatatypeID = 0 ; % double
127+ block .OutputPort(9 ).Complexity = ' Real' ;
128+ % Linear Acceleration
129+ block .OutputPort(10 ).Dimensions = [3 1 ];
130+ block .OutputPort(10 ).DatatypeID = 0 ; % double
131+ block .OutputPort(10 ).Complexity = ' Real' ;
132+ % LIDAR Pointcloud
133+ block .OutputPort(11 ).DimensionsMode = ' Variable' ;
134+ block .OutputPort(11 ).Dimensions = [57600 ,3 ]; % max. size
135+ block .OutputPort(11 ).DatatypeID = 1 ; % single
136+ block .OutputPort(11 ).Complexity = ' Real' ;
137+ % Camera 01
138+ block .OutputPort(12 ).Dimensions = [720 ,1280 ,3 ];
139+ block .OutputPort(12 ).DatatypeID = 3 ; % uint8
140+ block .OutputPort(12 ).Complexity = ' Real' ;
141+ % Camera 02
142+ block .OutputPort(13 ).Dimensions = [720 ,1280 ,3 ];
143+ block .OutputPort(13 ).DatatypeID = 3 ; % uint8
144+ block .OutputPort(13 ).Complexity = ' Real' ;
145+
146+ % Register parameters
147+ block.NumDialogPrms = 1 ;
148+
149+ % Register sample times
150+ % [0 offset] : Continuous sample time
151+ % [positive_num offset] : Discrete sample time
152+ % [-1, 0] : Inherited sample time
153+ % [-2, 0] : Variable sample time
154+ block.SampleTimes = [1 0 ];
155+
156+ % Specify the block simStateCompliance. The allowed values are:
157+ % 'UnknownSimState', < The default setting; warn and assume DefaultSimState
158+ % 'DefaultSimState', < Same sim state as a built-in block
159+ % 'HasNoSimState', < No sim state
160+ % 'CustomSimState', < Has GetSimState and SetSimState methods
161+ % 'DisallowSimState' < Error out when saving or restoring the model sim state
162+ block.SimStateCompliance = ' DefaultSimState' ;
163+
164+ %% The MATLAB S-function uses an internal registry for all
165+ %% block methods. You should register all relevant methods
166+ %% (optional and required) as illustrated below. You may choose
167+ %% any suitable name for the methods and implement these methods
168+ %% as local functions within the same file. See comments
169+ %% provided for each function for more information.
170+
171+ % block.RegBlockMethod('PostPropagationSetup', @DoPostPropSetup);
172+ block .RegBlockMethod(' InitializeConditions' , @InitializeConditions );
173+ % block.RegBlockMethod('Start', @Start);
174+ block .RegBlockMethod(' Outputs' , @Outputs ); % Required
175+ % block.RegBlockMethod('Update', @Update);
176+ % block.RegBlockMethod('Derivatives', @Derivatives);
177+ block .RegBlockMethod(' Terminate' , @Terminate ); % Required
178+
179+ % end setup
180+
181+ %% PostPropagationSetup:
182+ %% Functionality: Setup work areas and state variables. Can
183+ %% also register run-time methods here
184+ %% Required: No
185+ %% C MEX counterpart: mdlSetWorkWidths
186+
187+ % function DoPostPropSetup(block)
188+
189+ % end DoPostPropSetup(block)
190+
191+ %% InitializeConditions:
192+ %% Functionality: Called at the start of simulation and if it is
193+ %% present in an enabled subsystem configured to reset
194+ %% states, it will be called when the enabled subsystem
195+ %% restarts execution to reset the states.
196+ %% Required: No
197+ %% C MEX counterpart: mdlInitializeConditions
198+
199+ function InitializeConditions(block )
200+ global autodrive
201+ autodrive = server_hunter(block .DialogPrm(1 ).Data);
202+
203+ % end InitializeConditions
204+
205+ %% Start:
206+ %% Functionality: Called once at start of model execution. If you
207+ %% have states that should be initialized once, this
208+ %% is the place to do it.
209+ %% Required: No
210+ %% C MEX counterpart: mdlStart
211+
212+ % function Start(block)
213+
214+ % end Start
215+
216+ %% Outputs:
217+ %% Functionality: Called to generate block outputs in
218+ %% simulation step
219+ %% Required: Yes
220+ %% C MEX counterpart: mdlOutputs
221+
222+ function Outputs(block )
223+ global autodrive
224+ % Parse inputs
225+ autodrive.hunter_1.cosim_mode = block .InputPort(1 ).Data;
226+ autodrive.hunter_1.posX_command = block .InputPort(2 ).Data;
227+ autodrive.hunter_1.posY_command = block .InputPort(3 ).Data;
228+ autodrive.hunter_1.posZ_command = block .InputPort(4 ).Data;
229+ autodrive.hunter_1.rotX_command = block .InputPort(5 ).Data;
230+ autodrive.hunter_1.rotY_command = block .InputPort(6 ).Data;
231+ autodrive.hunter_1.rotZ_command = block .InputPort(7 ).Data;
232+ autodrive.hunter_1.rotW_command = block .InputPort(8 ).Data;
233+ autodrive.hunter_1.throttle_command = block .InputPort(9 ).Data;
234+ autodrive.hunter_1.steering_command = block .InputPort(10 ).Data;
235+ % Configure outputs
236+ block .OutputPort(1 ).Data = autodrive .hunter_1 .id ;
237+ block .OutputPort(2 ).Data = autodrive .hunter_1 .throttle ;
238+ block .OutputPort(3 ).Data = autodrive .hunter_1 .steering ;
239+ block .OutputPort(4 ).Data = autodrive .hunter_1 .encoder_ticks ;
240+ block .OutputPort(5 ).Data = autodrive .hunter_1 .encoder_angles ;
241+ block .OutputPort(6 ).Data = autodrive .hunter_1 .position ;
242+ block .OutputPort(7 ).Data = autodrive .hunter_1 .orientation_quaternion ;
243+ block .OutputPort(8 ).Data = autodrive .hunter_1 .orientation_euler_angles ;
244+ block .OutputPort(9 ).Data = autodrive .hunter_1 .angular_velocity ;
245+ block .OutputPort(10 ).Data = autodrive .hunter_1 .linear_acceleration ;
246+ block .OutputPort(11 ).CurrentDimensions = [size(autodrive .hunter_1 .lidar_pointcloud ,1 ),3 ];
247+ block .OutputPort(11 ).Data = autodrive .hunter_1 .lidar_pointcloud ;
248+ block .OutputPort(12 ).Data = autodrive .hunter_1 .front_camera_image ;
249+ block .OutputPort(13 ).Data = autodrive .hunter_1 .rear_camera_image ;
250+
251+ % end Outputs
252+
253+ %% Update:
254+ %% Functionality: Called to update discrete states
255+ %% during simulation step
256+ %% Required: No
257+ %% C MEX counterpart: mdlUpdate
258+
259+ % function Update(block)
260+
261+ % end Update
262+
263+ %% Derivatives:
264+ %% Functionality: Called to update derivatives of
265+ %% continuous states during simulation step
266+ %% Required: No
267+ %% C MEX counterpart: mdlDerivatives
268+
269+ % function Derivatives(block)
270+
271+ % end Derivatives
272+
273+ %% Terminate:
274+ %% Functionality: Called at the end of simulation for cleanup
275+ %% Required: Yes
276+ %% C MEX counterpart: mdlTerminate
277+
278+ function Terminate(block )
279+ global autodrive
280+ autodrive .stop ;
281+ autodrive .delete ;
282+
283+ % end Terminate
0 commit comments