Target Language Compiler    

Derivatives Function

The Outputs and InitializeConditions functions in this TLC file roughly parallel the corresponding functions in the sisosf.c program and thus will not be elaborated on. The heart of the program is again the Derivatives function, where the derivatives of the states (assigned to the dx vector) will be computed. Since the expression for the derivatives for all but the last state is similar, it is put in a loop. However, the discrepancy in the indices of dx and x must be treated with care.

The main section of the Derivatives function appears inside the %roll...%endroll construct. The utility of this method as opposed to, say, foreach, is that if there are only a few states (less than RollThreshold, which is set to 5 by default), the expressions are explicitly written out, since using a for loop would cause unnecessary overhead. However, when there are more states (especially when there are very many), the code is put in a for loop. The %roll command is explained in the Compiler Directives section of this document. However, this section points out some features as well.

The states run from 0 to (ncStates -1), and therefore, so do the derivatives. However, when the dx vector is returned by the call to the ssGetdX macro, the pointer for the entire set of derivatives is returned, not just the ones corresponding to this block. In fact, this model has been designed so that the derivatives from the dx block appear before those from the SiSoSF block in the generated code. Therefore, dx corresponding to x0 is actually dx[8] in this example. For this purpose, we use the statement

in the beginning of the function. Alternatively, dx could have been declared as

and then the offset term could have been dropped, since dx[0] would correspond to x0.

Next, since dx[ncStates - 1] needs special treatment, the looping is done over the range [0 : ncStates - 2]. This appears in the %roll statement, reproduced here for convenience

Parameters

The parameters are as follows: xIdx plays a dual role. If the loop does roll, i.e., a for loop is generated, then xIdx is set to the first value of the RollRegion (in this case 0). The for loop always starts from zero and goes up to one less than the width of the RollRegion. The RollRegion, which usually (but not in this case) is set to the eponymous identifier from the model.rtw file, contains the vector(s) upon which the TLC compiler bases its decision whether or not to roll.

In this case, we have a customized vector, i.e., [0:%<ncStates-2>] as our RollRegion, and the xlcv variable is set to the (string) value of the loop index. The parameter rollVars specifies the variables over which the rolling takes place. If rolling does occur, a vector that starts from the appropriate place in (say) the state vector will be declared; similarly for the parameter vector. The "appropriate place" will be given by the value of xIdx.

If the loop does not roll, xIdx goes from 0 to one less than the width of the RollRegion, irrespective of the actual start and end points of the vector. In this mode, the %roll command behaves identically to the %foreach command. However, the RollVars are appropriately offset so that the correct elements of the state and parameter vectors (in this case) are used. This is given by the first element of the RollRegion.

As an exercise, generate the code using the Build command in the Simulation Parameters dialog box. Check that the Loop rolling threshold option is set to 5 (less than the width of the RollRegion) in the Options section of the dialog box.

Study the following lines of code from the Derivatives function of the sisosf.tlc file to see how they change. This gives important insights into the functionality of %roll.

Now, set the Loop rolling threshold to 10 so that the code does not roll. Study the code again, and see how the various parameters have changed.

Additional Exercise

  1. Copy gain.tlc from matlabroot/rtw/c/tlc to your working directory.
  2. Change RollRegions in the lines below to arbitrary vectors, e.g., [0:10,11,12,13:19].
  3. Now use the simple_mimo2.mdl model from an earlier assignment, only changing the inputs to [1:20] (to match our RollRegion), and the gain to [20:-1:1] to match the inputs.
  4. Set the Loop rolling threshold to 12 (no roll), 8 (second region rolls, first does not) and 5 (neither region rolls). The relevant section of gain.tlc is given below.
  5. Add comment lines as above to see what the values of sigIdx, lcv, etc. become.
  6. Change RollRegions below to [0:10,11,12,13:19]

This is not, of course, a recommended practice for writing TLC files (i.e., hard coding roll regions), but is merely an exercise to see how %roll works. You may also try changing the RollRegion to [3:10,. . .] etc., and sigIdx to sigIdx-1 in the %assign u line.

When you are done, do not forget to change the name of gain.tlc to gain_old.tlc so that future code generation endeavors involving the Gain block are not hampered.


 Generating Code for Models with States Simulink External Mode and GRT