|
| 1 | +function SatelliteAttitudeControl_sFunction(block) |
| 2 | +%MSFUNTMPL_BASIC A Template for a Level-2 MATLAB S-Function |
| 3 | +% The MATLAB S-function is written as a MATLAB function with the |
| 4 | +% same name as the S-function. Replace 'msfuntmpl_basic' with the |
| 5 | +% name of your S-function. |
| 6 | +% |
| 7 | +% It should be noted that the MATLAB S-function is very similar |
| 8 | +% to Level-2 C-Mex S-functions. You should be able to get more |
| 9 | +% information for each of the block methods by referring to the |
| 10 | +% documentation for C-Mex S-functions. |
| 11 | +% |
| 12 | +% Copyright 2003-2010 The MathWorks, Inc. |
| 13 | + |
| 14 | +%% |
| 15 | +%% The setup method is used to set up the basic attributes of the |
| 16 | +%% S-function such as ports, parameters, etc. Do not add any other |
| 17 | +%% calls to the main body of the function. |
| 18 | +%% |
| 19 | +setup(block); |
| 20 | + |
| 21 | +%endfunction |
| 22 | + |
| 23 | +%% Function: setup =================================================== |
| 24 | +%% Abstract: |
| 25 | +%% Set up the basic characteristics of the S-function block such as: |
| 26 | +%% - Input ports |
| 27 | +%% - Output ports |
| 28 | +%% - Dialog parameters |
| 29 | +%% - Options |
| 30 | +%% |
| 31 | +%% Required : Yes |
| 32 | +%% C-Mex counterpart: mdlInitializeSizes |
| 33 | +%% |
| 34 | +function setup(block) |
| 35 | + |
| 36 | +% Register number of ports |
| 37 | +block.NumInputPorts = 3; |
| 38 | +block.NumOutputPorts = 3; |
| 39 | + |
| 40 | +% Setup port properties to be inherited or dynamic |
| 41 | +block.SetPreCompInpPortInfoToDynamic; |
| 42 | +block.SetPreCompOutPortInfoToDynamic; |
| 43 | + |
| 44 | +% Override input port properties |
| 45 | +block.InputPort(1).Dimensions = 1; |
| 46 | +block.InputPort(1).DatatypeID = 0; % double |
| 47 | +block.InputPort(1).Complexity = 'Real'; |
| 48 | +block.InputPort(1).DirectFeedthrough = false; |
| 49 | + |
| 50 | +block.InputPort(2).Dimensions = 1; |
| 51 | +block.InputPort(2).DatatypeID = 0; % double |
| 52 | +block.InputPort(2).Complexity = 'Real'; |
| 53 | +block.InputPort(2).DirectFeedthrough = false; |
| 54 | + |
| 55 | +block.InputPort(3).Dimensions = 1; |
| 56 | +block.InputPort(3).DatatypeID = 0; % double |
| 57 | +block.InputPort(3).Complexity = 'Real'; |
| 58 | +block.InputPort(3).DirectFeedthrough = false; |
| 59 | + |
| 60 | +% Override output port properties |
| 61 | +block.OutputPort(1).Dimensions = 1; |
| 62 | +block.OutputPort(1).DatatypeID = 0; % double |
| 63 | +block.OutputPort(1).Complexity = 'Real'; |
| 64 | + |
| 65 | +block.OutputPort(2).Dimensions = 1; |
| 66 | +block.OutputPort(2).DatatypeID = 0; % double |
| 67 | +block.OutputPort(2).Complexity = 'Real'; |
| 68 | + |
| 69 | +block.OutputPort(3).Dimensions = 1; |
| 70 | +block.OutputPort(3).DatatypeID = 0; % double |
| 71 | +block.OutputPort(3).Complexity = 'Real'; |
| 72 | + |
| 73 | +% Register parameters |
| 74 | +block.NumDialogPrms = 0; |
| 75 | + |
| 76 | +% Register sample times |
| 77 | +% [0 offset] : Continuous sample time |
| 78 | +% [positive_num offset] : Discrete sample time |
| 79 | +% |
| 80 | +% [-1, 0] : Inherited sample time |
| 81 | +% [-2, 0] : Variable sample time |
| 82 | +block.SampleTimes = [0.5 0]; |
| 83 | + |
| 84 | +% Specify the block simStateCompliance. The allowed values are: |
| 85 | +% 'UnknownSimState', < The default setting; warn and assume DefaultSimState |
| 86 | +% 'DefaultSimState', < Same sim state as a built-in block |
| 87 | +% 'HasNoSimState', < No sim state |
| 88 | +% 'CustomSimState', < Has GetSimState and SetSimState methods |
| 89 | +% 'DisallowSimState' < Error out when saving or restoring the model sim state |
| 90 | +block.SimStateCompliance = 'DefaultSimState'; |
| 91 | + |
| 92 | +%% ----------------------------------------------------------------- |
| 93 | +%% The MATLAB S-function uses an internal registry for all |
| 94 | +%% block methods. You should register all relevant methods |
| 95 | +%% (optional and required) as illustrated below. You may choose |
| 96 | +%% any suitable name for the methods and implement these methods |
| 97 | +%% as local functions within the same file. See comments |
| 98 | +%% provided for each function for more information. |
| 99 | +%% ----------------------------------------------------------------- |
| 100 | + |
| 101 | + % SetInputPortSamplingMode: |
| 102 | + % Functionality : Check and set input and output port |
| 103 | + % attributes specifying if port is operating |
| 104 | + % in sample-based or frame-based mode |
| 105 | + % C-Mex counterpart: mdlSetInputPortFrameData |
| 106 | + % (Signal Processing Blockset is required in order to set a port |
| 107 | + % to be frame-based) |
| 108 | + % |
| 109 | +block.RegBlockMethod('SetInputPortSamplingMode', @SetInpPortFrameData); |
| 110 | +block.RegBlockMethod('PostPropagationSetup', @DoPostPropSetup); |
| 111 | +block.RegBlockMethod('Start', @Start); |
| 112 | +block.RegBlockMethod('Outputs', @Outputs); % Required |
| 113 | +block.RegBlockMethod('Update', @Update); |
| 114 | +block.RegBlockMethod('Terminate', @Terminate); % Required |
| 115 | + |
| 116 | +%end setup |
| 117 | + |
| 118 | +%% |
| 119 | +%% PostPropagationSetup: |
| 120 | +%% Functionality : Setup work areas and state variables. Can |
| 121 | +%% also register run-time methods here |
| 122 | +%% Required : No |
| 123 | +%% C-Mex counterpart: mdlSetWorkWidths |
| 124 | +%% |
| 125 | +function DoPostPropSetup(block) |
| 126 | + |
| 127 | +block.NumDworks = 5; |
| 128 | + |
| 129 | +block.Dwork(1).Name = 'time'; |
| 130 | +block.Dwork(1).Dimensions = 1; |
| 131 | +block.Dwork(1).DatatypeID = 0; % double |
| 132 | +block.Dwork(1).Complexity = 'Real'; % real |
| 133 | +block.Dwork(1).UsedAsDiscState = true; |
| 134 | + |
| 135 | +block.Dwork(2).Name = 'A'; |
| 136 | +block.Dwork(2).Dimensions = 1; |
| 137 | +block.Dwork(2).DatatypeID = 0; % double |
| 138 | +block.Dwork(2).Complexity = 'Real'; % real |
| 139 | +block.Dwork(2).UsedAsDiscState = true; |
| 140 | + |
| 141 | +block.Dwork(3).Name = 'B'; |
| 142 | +block.Dwork(3).Dimensions = 1; |
| 143 | +block.Dwork(3).DatatypeID = 0; % double |
| 144 | +block.Dwork(3).Complexity = 'Real'; % real |
| 145 | +block.Dwork(3).UsedAsDiscState = true; |
| 146 | + |
| 147 | +block.Dwork(4).Name = 'C'; |
| 148 | +block.Dwork(4).Dimensions = 1; |
| 149 | +block.Dwork(4).DatatypeID = 0; % double |
| 150 | +block.Dwork(4).Complexity = 'Real'; % real |
| 151 | +block.Dwork(4).UsedAsDiscState = true; |
| 152 | + |
| 153 | +block.Dwork(5).Name = 'lastTime'; |
| 154 | +block.Dwork(5).Dimensions = 1; |
| 155 | +block.Dwork(5).DatatypeID = 0; % double |
| 156 | +block.Dwork(5).Complexity = 'Real'; % real |
| 157 | +block.Dwork(5).UsedAsDiscState = true; |
| 158 | + |
| 159 | +function SetInpPortFrameData(block, idx, fd) |
| 160 | + |
| 161 | + block.InputPort(idx).SamplingMode = fd; |
| 162 | + block.OutputPort(1).SamplingMode = fd; |
| 163 | + block.OutputPort(2).SamplingMode = fd; |
| 164 | + block.OutputPort(3).SamplingMode = fd; |
| 165 | + |
| 166 | +%endfunction |
| 167 | + |
| 168 | +%% |
| 169 | +%% Start: |
| 170 | +%% Functionality : Called once at start of model execution. If you |
| 171 | +%% have states that should be initialized once, this |
| 172 | +%% is the place to do it. |
| 173 | +%% Required : No |
| 174 | +%% C-MEX counterpart: mdlStart |
| 175 | +%% |
| 176 | +function Start(block) |
| 177 | + |
| 178 | +block.Dwork(1).Data = 0; |
| 179 | +block.Dwork(2).Data = 0; |
| 180 | +block.Dwork(3).Data = 0; |
| 181 | +block.Dwork(4).Data = 0; |
| 182 | +block.Dwork(5).Data = 0; |
| 183 | + |
| 184 | +%endfunction |
| 185 | + |
| 186 | +%% |
| 187 | +%% Outputs: |
| 188 | +%% Functionality : Called to generate block outputs in |
| 189 | +%% simulation step |
| 190 | +%% Required : Yes |
| 191 | +%% C-MEX counterpart: mdlOutputs |
| 192 | +%% |
| 193 | +function Outputs(block) |
| 194 | + |
| 195 | +%retreive the stkParameters array from the UserData |
| 196 | +stkParameters = get_param(block.BlockHandle, 'UserData'); |
| 197 | + |
| 198 | +%get the root and the access objects from the array |
| 199 | +root = stkParameters{2}; |
| 200 | +realSat = stkParameters{3}; |
| 201 | +perfectPointingSat = stkParameters{4}; |
| 202 | +perfectBodyAxes = stkParameters{5}; |
| 203 | + |
| 204 | +%update the current time in STK |
| 205 | +%root.CurrentTime = block.Dwork(1).Data; |
| 206 | +root.CurrentTime = block.CurrentTime; |
| 207 | + |
| 208 | +%find the new desired attitude |
| 209 | +perfectAttitude = perfectBodyAxes.FindInAxes(root.CurrentTime + 2, perfectPointingSat.Vgt.Axes.Item('ICRF')).Orientation.QueryEulerAnglesArray('e321'); |
| 210 | + |
| 211 | +block.OutputPort(1).Data = perfectAttitude{1}; |
| 212 | +block.OutputPort(2).Data = perfectAttitude{2}; |
| 213 | +block.OutputPort(3).Data = perfectAttitude{3}; |
| 214 | + |
| 215 | +block.InputPort(1).Data; |
| 216 | +block.InputPort(2).Data; |
| 217 | +block.InputPort(3).Data; |
| 218 | + |
| 219 | +%end Outputs |
| 220 | + |
| 221 | +%% |
| 222 | +%% Update: |
| 223 | +%% Functionality : Called to update discrete states |
| 224 | +%% during simulation step |
| 225 | +%% Required : No |
| 226 | +%% C-MEX counterpart: mdlUpdate |
| 227 | +%% |
| 228 | +function Update(block) |
| 229 | + |
| 230 | +%update the time and feedback C |
| 231 | +block.Dwork(5).Data = block.Dwork(1).Data; %Set lastTime before updating time |
| 232 | +block.Dwork(1).Data = block.CurrentTime; |
| 233 | +block.Dwork(2).Data = block.InputPort(1).Data; |
| 234 | +block.Dwork(3).Data = block.InputPort(2).Data; |
| 235 | +block.Dwork(4).Data = block.InputPort(3).Data; |
| 236 | + |
| 237 | +%update STK so that the satellite's attitude is using the output from the |
| 238 | +%feedback loop |
| 239 | +%retreive the stkParameters array from the UserData |
| 240 | +stkParameters = get_param(block.BlockHandle, 'UserData'); |
| 241 | + |
| 242 | +%get the root and satellite object |
| 243 | +root = stkParameters{2}; |
| 244 | +realSat = stkParameters{3}; |
| 245 | + |
| 246 | +A = block.Dwork(2).Data; |
| 247 | +B = block.Dwork(3).Data; |
| 248 | +C = block.Dwork(4).Data; |
| 249 | +realSat.Attitude.AddEuler(block.Dwork(5).Data, '321', A, B, C); |
| 250 | + |
| 251 | +%end Update |
| 252 | + |
| 253 | +%% |
| 254 | +%% Terminate: |
| 255 | +%% Functionality : Called at the end of simulation for cleanup |
| 256 | +%% Required : Yes |
| 257 | +%% C-MEX counterpart: mdlTerminate |
| 258 | +%% |
| 259 | +function Terminate(block) |
| 260 | + |
| 261 | +stkParameters = get_param(block.BlockHandle, 'UserData'); |
| 262 | + |
| 263 | +%get the root |
| 264 | +root = stkParameters{2}; |
| 265 | +uiapp = stkParameters{1}; |
| 266 | + |
| 267 | +%end Terminate |
| 268 | + |
0 commit comments