| 1 | package Tables "One and two-dimensional interpolation in tables" |
|---|
| 2 | extends Icons.Library; |
|---|
| 3 | model CombiTable1D |
|---|
| 4 | "Table look-up in one dimension (matrix/file) with n inputs and n outputs " |
|---|
| 5 | import Modelica.Blocks.Types; |
|---|
| 6 | parameter Boolean tableOnFile=false |
|---|
| 7 | "true, if table is defined on file or in function usertab" |
|---|
| 8 | annotation(Dialog(group="table data definition")); |
|---|
| 9 | parameter Real table[:, :]=fill(0.0,0,2) |
|---|
| 10 | "table matrix (grid = first column)" |
|---|
| 11 | annotation(Dialog(group="table data definition", enable = not tableOnFile)); |
|---|
| 12 | parameter String tableName="NoName" |
|---|
| 13 | "table name on file or in function usertab (see docu)" |
|---|
| 14 | annotation(Dialog(group="table data definition", enable = tableOnFile)); |
|---|
| 15 | parameter String fileName="NoName" "file where matrix is stored" |
|---|
| 16 | annotation(Dialog(group="table data definition", enable = tableOnFile)); |
|---|
| 17 | parameter Integer columns[:]=2:size(table, 2) |
|---|
| 18 | "columns of table to be interpolated" |
|---|
| 19 | annotation(Dialog(group="table data interpretation")); |
|---|
| 20 | parameter Blocks.Types.Smoothness.Temp smoothness=Types.Smoothness.LinearSegments |
|---|
| 21 | "smoothness of table interpolation" |
|---|
| 22 | annotation(Dialog(group="table data interpretation")); |
|---|
| 23 | extends Modelica.Blocks.Interfaces.MIMOs(final n=size(columns, 1)); |
|---|
| 24 | protected |
|---|
| 25 | Real tableID; |
|---|
| 26 | annotation ( |
|---|
| 27 | Documentation(info="<html> |
|---|
| 28 | <p> |
|---|
| 29 | <b>Linear interpolation</b> in <b>one</b> dimension of a <b>table</b>. |
|---|
| 30 | Via parameter <b>columns</b> it can be defined how many columns of the |
|---|
| 31 | table are interpolated. If, e.g., columns={2,4}, it is assumed that 2 input |
|---|
| 32 | and 2 output signals are present and that the first output interpolates |
|---|
| 33 | the first input via column 2 and the second output interpolates the |
|---|
| 34 | second input via column 4 of the table matrix. |
|---|
| 35 | </p> |
|---|
| 36 | <p> |
|---|
| 37 | The grid points and function values are stored in a matrix \"table[i,j]\", |
|---|
| 38 | where the first column \"table[:,1]\" contains the grid points and the |
|---|
| 39 | other columns contain the data to be interpolated. Example: |
|---|
| 40 | </p> |
|---|
| 41 | <pre> |
|---|
| 42 | table = [0, 0; |
|---|
| 43 | 1, 1; |
|---|
| 44 | 2, 4; |
|---|
| 45 | 4, 16] |
|---|
| 46 | If, e.g., the input u = 1.0, the output y = 1.0, |
|---|
| 47 | e.g., the input u = 1.5, the output y = 2.5, |
|---|
| 48 | e.g., the input u = 2.0, the output y = 4.0, |
|---|
| 49 | e.g., the input u =-1.0, the output y = -1.0 (i.e. extrapolation). |
|---|
| 50 | </pre> |
|---|
| 51 | <ul> |
|---|
| 52 | <li> The interpolation is <b>efficient</b>, because a search for a new interpolation |
|---|
| 53 | starts at the interval used in the last call.</li> |
|---|
| 54 | <li> If the table has only <b>one row</b>, the table value is returned, |
|---|
| 55 | independent of the value of the input signal.</li> |
|---|
| 56 | <li> If the input signal <b>u[i]</b> is <b>outside</b> of the defined <b>interval</b>, i.e., |
|---|
| 57 | u[i] > table[size(table,1),i+1] or u[i] < table[1,1], the corresponding |
|---|
| 58 | value is also determined by linear |
|---|
| 59 | interpolation through the last or first two points of the table.</li> |
|---|
| 60 | <li> The grid values (first column) have to be <b>strict</b> |
|---|
| 61 | monotonically increasing.</li> |
|---|
| 62 | </ul> |
|---|
| 63 | <p> |
|---|
| 64 | The table matrix can be defined in the following ways: |
|---|
| 65 | </p> |
|---|
| 66 | <ol> |
|---|
| 67 | <li> Explicitly supplied as <b>parameter matrix</b> \"table\", |
|---|
| 68 | and the other parameters have the following values: |
|---|
| 69 | <pre> |
|---|
| 70 | tableName is \"NoName\" or has only blanks, |
|---|
| 71 | fileName is \"NoName\" or has only blanks. |
|---|
| 72 | </pre></li> |
|---|
| 73 | <li> <b>Read</b> from a <b>file</b> \"fileName\" where the matrix is stored as |
|---|
| 74 | \"tableName\". Both ASCII and binary file format is possible. |
|---|
| 75 | (the ASCII format is described below). |
|---|
| 76 | It is most convenient to generate the binary file from Matlab |
|---|
| 77 | (Matlab 4 storage format), e.g., by command |
|---|
| 78 | <pre> |
|---|
| 79 | save tables.mat tab1 tab2 tab3 -V4 |
|---|
| 80 | </pre> |
|---|
| 81 | when the three tables tab1, tab2, tab3 should be |
|---|
| 82 | used from the model.</li> |
|---|
| 83 | <li> Statically stored in function \"usertab\" in file \"usertab.c\". |
|---|
| 84 | The matrix is identified by \"tableName\". Parameter |
|---|
| 85 | fileName = \"NoName\" or has only blanks.</li> |
|---|
| 86 | </ol> |
|---|
| 87 | <p> |
|---|
| 88 | Table definition methods (1) and (3) do <b>not</b> allocate dynamic memory, |
|---|
| 89 | and do not access files, whereas method (2) does. Therefore (1) and (3) |
|---|
| 90 | are suited for hardware-in-the-loop simulation (e.g. with dSpace hardware). |
|---|
| 91 | When the constant \"NO_FILE\" is defined in \"usertab.c\", all parts of the |
|---|
| 92 | source code of method (2) are removed by the C-preprocessor, such that |
|---|
| 93 | no dynamic memory allocation and no access to files takes place. |
|---|
| 94 | </p> |
|---|
| 95 | <p> |
|---|
| 96 | If tables are read from an ASCII-file, the file need to have the |
|---|
| 97 | following structure (\"-----\" is not part of the file content): |
|---|
| 98 | </p> |
|---|
| 99 | <pre> |
|---|
| 100 | ----------------------------------------------------- |
|---|
| 101 | #1 |
|---|
| 102 | double tab1(5,2) # comment line |
|---|
| 103 | 0 0 |
|---|
| 104 | 1 1 |
|---|
| 105 | 2 4 |
|---|
| 106 | 3 9 |
|---|
| 107 | 4 16 |
|---|
| 108 | double tab2(5,2) # another comment line |
|---|
| 109 | 0 0 |
|---|
| 110 | 2 2 |
|---|
| 111 | 4 8 |
|---|
| 112 | 6 18 |
|---|
| 113 | 8 32 |
|---|
| 114 | ----------------------------------------------------- |
|---|
| 115 | </pre> |
|---|
| 116 | <p> |
|---|
| 117 | Note, that the first two characters in the file need to be |
|---|
| 118 | \"#1\". Afterwards, the corresponding matrix has to be declared |
|---|
| 119 | with type, name and actual dimensions. Finally, in successive |
|---|
| 120 | rows of the file, the elements of the matrix have to be given. |
|---|
| 121 | Several matrices may be defined one after another. |
|---|
| 122 | </p> |
|---|
| 123 | </HTML> |
|---|
| 124 | "), Icon( |
|---|
| 125 | Line(points=[-60, 40; -60, -40; 60, -40; 60, 40; 30, 40; 30, -40; -30, |
|---|
| 126 | -40; -30, 40; -60, 40; -60, 20; 60, 20; 60, 0; -60, 0; -60, -20; |
|---|
| 127 | 60, -20; 60, -40; -60, -40; -60, 40; 60, 40; 60, -40], style( |
|---|
| 128 | color=0)), |
|---|
| 129 | Line(points=[0, 40; 0, -40], style(color=0)), |
|---|
| 130 | Rectangle(extent=[-60, 40; -30, 20], style( |
|---|
| 131 | color=0, |
|---|
| 132 | fillColor=6, |
|---|
| 133 | fillPattern=1)), |
|---|
| 134 | Rectangle(extent=[-60, 20; -30, 0], style( |
|---|
| 135 | color=0, |
|---|
| 136 | fillColor=6, |
|---|
| 137 | fillPattern=1)), |
|---|
| 138 | Rectangle(extent=[-60, 0; -30, -20], style( |
|---|
| 139 | color=0, |
|---|
| 140 | fillColor=6, |
|---|
| 141 | fillPattern=1)), |
|---|
| 142 | Rectangle(extent=[-60, -20; -30, -40], style( |
|---|
| 143 | color=0, |
|---|
| 144 | fillColor=6, |
|---|
| 145 | fillPattern=1))), |
|---|
| 146 | Diagram( |
|---|
| 147 | Rectangle(extent=[-60, 60; 60, -60], style(fillColor=30, |
|---|
| 148 | fillPattern = 1)), |
|---|
| 149 | Line(points=[-100, 0; -58, 0]), |
|---|
| 150 | Line(points=[60, 0; 100, 0]), |
|---|
| 151 | Text(extent=[-100, 100; 100, 64], string= |
|---|
| 152 | "1 dimensional linear table interpolation"), |
|---|
| 153 | Line(points=[-54, 40; -54, -40; 54, -40; 54, 40; 28, 40; 28, -40; -28, |
|---|
| 154 | -40; -28, 40; -54, 40; -54, 20; 54, 20; 54, 0; -54, 0; -54, -20; |
|---|
| 155 | 54, -20; 54, -40; -54, -40; -54, 40; 54, 40; 54, -40], style( |
|---|
| 156 | color=0)), |
|---|
| 157 | Line(points=[0, 40; 0, -40], style(color=0)), |
|---|
| 158 | Rectangle(extent=[-54, 40; -28, 20], style( |
|---|
| 159 | color=0, |
|---|
| 160 | fillColor=6, |
|---|
| 161 | fillPattern=1)), |
|---|
| 162 | Rectangle(extent=[-54, 20; -28, 0], style( |
|---|
| 163 | color=0, |
|---|
| 164 | fillColor=6, |
|---|
| 165 | fillPattern=1)), |
|---|
| 166 | Rectangle(extent=[-54, 0; -28, -20], style( |
|---|
| 167 | color=0, |
|---|
| 168 | fillColor=6, |
|---|
| 169 | fillPattern=1)), |
|---|
| 170 | Rectangle(extent=[-54, -20; -28, -40], style( |
|---|
| 171 | color=0, |
|---|
| 172 | fillColor=6, |
|---|
| 173 | fillPattern=1)), |
|---|
| 174 | Text(extent=[-50,54; -32,42], string="u[1]/[2]"), |
|---|
| 175 | Text(extent=[-24,54; 0,42], string="y[1]"), |
|---|
| 176 | Text(extent=[-2, -40; 30, -54], string="columns"), |
|---|
| 177 | Text(extent=[2,54; 26,42], string="y[2]"))); |
|---|
| 178 | equation |
|---|
| 179 | if tableOnFile then |
|---|
| 180 | assert(tableName<>"NoName", "tableOnFile = true and no table name given"); |
|---|
| 181 | end if; |
|---|
| 182 | if not tableOnFile then |
|---|
| 183 | assert(size(table,1) > 0 and size(table,2) > 0, "tableOnFile = false and parameter table is an empty matrix"); |
|---|
| 184 | end if; |
|---|
| 185 | |
|---|
| 186 | for i in 1:n loop |
|---|
| 187 | y[i] = if not tableOnFile and size(table,1)==1 then |
|---|
| 188 | table[1, columns[i]] else dymTableIpo1(tableID, columns[i], u[i]); |
|---|
| 189 | end for; |
|---|
| 190 | when initial() then |
|---|
| 191 | tableID=dymTableInit(1.0, smoothness, if tableOnFile then tableName else "NoName", if tableOnFile then fileName else "NoName", table, 0.0); |
|---|
| 192 | end when; |
|---|
| 193 | end CombiTable1D; |
|---|
| 194 | |
|---|
| 195 | model CombiTable1Ds |
|---|
| 196 | "Table look-up in one dimension (matrix/file) with one input and n outputs" |
|---|
| 197 | |
|---|
| 198 | import Modelica.Blocks.Types; |
|---|
| 199 | parameter Boolean tableOnFile=false |
|---|
| 200 | "true, if table is defined on file or in function usertab" |
|---|
| 201 | annotation(Dialog(group="table data definition")); |
|---|
| 202 | parameter Real table[:, :]=fill(0.0,0,2) |
|---|
| 203 | "table matrix (grid = first column)" |
|---|
| 204 | annotation(Dialog(group="table data definition", enable = not tableOnFile)); |
|---|
| 205 | parameter String tableName="NoName" |
|---|
| 206 | "table name on file or in function usertab (see docu)" |
|---|
| 207 | annotation(Dialog(group="table data definition", enable = tableOnFile)); |
|---|
| 208 | parameter String fileName="NoName" "file where matrix is stored" |
|---|
| 209 | annotation(Dialog(group="table data definition", enable = tableOnFile)); |
|---|
| 210 | parameter Integer columns[:]=2:size(table, 2) |
|---|
| 211 | "columns of table to be interpolated" |
|---|
| 212 | annotation(Dialog(group="table data interpretation")); |
|---|
| 213 | parameter Blocks.Types.Smoothness.Temp smoothness=Types.Smoothness.LinearSegments |
|---|
| 214 | "smoothness of table interpolation" |
|---|
| 215 | annotation(Dialog(group="table data interpretation")); |
|---|
| 216 | extends Modelica.Blocks.Interfaces.SIMO(final nout=size(columns, 1)); |
|---|
| 217 | protected |
|---|
| 218 | Real tableID; |
|---|
| 219 | annotation ( |
|---|
| 220 | Documentation(info="<html> |
|---|
| 221 | <p> |
|---|
| 222 | <b>Linear interpolation</b> in <b>one</b> dimension of a <b>table</b>. |
|---|
| 223 | Via parameter <b>columns</b> it can be defined how many columns of the |
|---|
| 224 | table are interpolated. If, e.g., icol={2,4}, it is assumed that one input |
|---|
| 225 | and 2 output signals are present and that the first output interpolates |
|---|
| 226 | via column 2 and the second output interpolates via column 4 of the |
|---|
| 227 | table matrix. |
|---|
| 228 | </p> |
|---|
| 229 | <p> |
|---|
| 230 | The grid points and function values are stored in a matrix \"table[i,j]\", |
|---|
| 231 | where the first column \"table[:,1]\" contains the grid points and the |
|---|
| 232 | other columns contain the data to be interpolated. Example: |
|---|
| 233 | </p> |
|---|
| 234 | <pre> |
|---|
| 235 | table = [0, 0; |
|---|
| 236 | 1, 1; |
|---|
| 237 | 2, 4; |
|---|
| 238 | 4, 16] |
|---|
| 239 | If, e.g., the input u = 1.0, the output y = 1.0, |
|---|
| 240 | e.g., the input u = 1.5, the output y = 2.5, |
|---|
| 241 | e.g., the input u = 2.0, the output y = 4.0, |
|---|
| 242 | e.g., the input u =-1.0, the output y = -1.0 (i.e. extrapolation). |
|---|
| 243 | </pre> |
|---|
| 244 | <ul> |
|---|
| 245 | <li> The interpolation is <b>efficient</b>, because a search for a new interpolation |
|---|
| 246 | starts at the interval used in the last call.</li> |
|---|
| 247 | <li> If the table has only <b>one row</b>, the table value is returned, |
|---|
| 248 | independent of the value of the input signal.</li> |
|---|
| 249 | <li> If the input signal <b>u</b> is <b>outside</b> of the defined <b>interval</b>, i.e., |
|---|
| 250 | u > table[size(table,1),1] or u < table[1,1], the corresponding |
|---|
| 251 | value is also determined by linear |
|---|
| 252 | interpolation through the last or first two points of the table.</li> |
|---|
| 253 | <li> The grid values (first column) have to be <b>strict</b> |
|---|
| 254 | monotonically increasing.</li> |
|---|
| 255 | </ul> |
|---|
| 256 | <p> |
|---|
| 257 | The table matrix can be defined in the following ways: |
|---|
| 258 | </p> |
|---|
| 259 | <ol> |
|---|
| 260 | <li> Explicitly supplied as <b>parameter matrix</b> \"table\", |
|---|
| 261 | and the other parameters have the following values: |
|---|
| 262 | <pre> |
|---|
| 263 | tableName is \"NoName\" or has only blanks, |
|---|
| 264 | fileName is \"NoName\" or has only blanks. |
|---|
| 265 | </pre></li> |
|---|
| 266 | <li> <b>Read</b> from a <b>file</b> \"fileName\" where the matrix is stored as |
|---|
| 267 | \"tableName\". Both ASCII and binary file format is possible. |
|---|
| 268 | (the ASCII format is described below). |
|---|
| 269 | It is most convenient to generate the binary file from Matlab |
|---|
| 270 | (Matlab 4 storage format), e.g., by command |
|---|
| 271 | <pre> |
|---|
| 272 | save tables.mat tab1 tab2 tab3 -V4 |
|---|
| 273 | </pre> |
|---|
| 274 | when the three tables tab1, tab2, tab3 should be |
|---|
| 275 | used from the model.</li> |
|---|
| 276 | <li> Statically stored in function \"usertab\" in file \"usertab.c\". |
|---|
| 277 | The matrix is identified by \"tableName\". Parameter |
|---|
| 278 | fileName = \"NoName\" or has only blanks.</li> |
|---|
| 279 | </ol> |
|---|
| 280 | <p> |
|---|
| 281 | Table definition methods (1) and (3) do <b>not</b> allocate dynamic memory, |
|---|
| 282 | and do not access files, whereas method (2) does. Therefore (1) and (3) |
|---|
| 283 | are suited for hardware-in-the-loop simulation (e.g. with dSpace hardware). |
|---|
| 284 | When the constant \"NO_FILE\" is defined, all parts of the |
|---|
| 285 | source code of method (2) are removed by the C-preprocessor, such that |
|---|
| 286 | no dynamic memory allocation and no access to files takes place. |
|---|
| 287 | </p> |
|---|
| 288 | <p> |
|---|
| 289 | If tables are read from an ASCII-file, the file need to have the |
|---|
| 290 | following structure (\"-----\" is not part of the file content): |
|---|
| 291 | </p> |
|---|
| 292 | <pre> |
|---|
| 293 | ----------------------------------------------------- |
|---|
| 294 | #1 |
|---|
| 295 | double tab1(5,2) # comment line |
|---|
| 296 | 0 0 |
|---|
| 297 | 1 1 |
|---|
| 298 | 2 4 |
|---|
| 299 | 3 9 |
|---|
| 300 | 4 16 |
|---|
| 301 | double tab2(5,2) # another comment line |
|---|
| 302 | 0 0 |
|---|
| 303 | 2 2 |
|---|
| 304 | 4 8 |
|---|
| 305 | 6 18 |
|---|
| 306 | 8 32 |
|---|
| 307 | ----------------------------------------------------- |
|---|
| 308 | </pre> |
|---|
| 309 | <p> |
|---|
| 310 | Note, that the first two characters in the file need to be |
|---|
| 311 | \"#1\". Afterwards, the corresponding matrix has to be declared |
|---|
| 312 | with type, name and actual dimensions. Finally, in successive |
|---|
| 313 | rows of the file, the elements of the matrix have to be given. |
|---|
| 314 | Several matrices may be defined one after another. |
|---|
| 315 | </p> |
|---|
| 316 | </HTML> |
|---|
| 317 | "), Icon( |
|---|
| 318 | Line(points=[-60, 40; -60, -40; 60, -40; 60, 40; 30, 40; 30, -40; -30, |
|---|
| 319 | -40; -30, 40; -60, 40; -60, 20; 60, 20; 60, 0; -60, 0; -60, -20; |
|---|
| 320 | 60, -20; 60, -40; -60, -40; -60, 40; 60, 40; 60, -40], style( |
|---|
| 321 | color=0)), |
|---|
| 322 | Line(points=[0, 40; 0, -40], style(color=0)), |
|---|
| 323 | Rectangle(extent=[-60, 40; -30, 20], style( |
|---|
| 324 | color=0, |
|---|
| 325 | fillColor=6, |
|---|
| 326 | fillPattern=1)), |
|---|
| 327 | Rectangle(extent=[-60, 20; -30, 0], style( |
|---|
| 328 | color=0, |
|---|
| 329 | fillColor=6, |
|---|
| 330 | fillPattern=1)), |
|---|
| 331 | Rectangle(extent=[-60, 0; -30, -20], style( |
|---|
| 332 | color=0, |
|---|
| 333 | fillColor=6, |
|---|
| 334 | fillPattern=1)), |
|---|
| 335 | Rectangle(extent=[-60, -20; -30, -40], style( |
|---|
| 336 | color=0, |
|---|
| 337 | fillColor=6, |
|---|
| 338 | fillPattern=1))), |
|---|
| 339 | Diagram( |
|---|
| 340 | Rectangle(extent=[-60, 60; 60, -60], style(fillColor=30, |
|---|
| 341 | fillPattern = 1)), |
|---|
| 342 | Line(points=[-100, 0; -58, 0]), |
|---|
| 343 | Line(points=[60, 0; 100, 0]), |
|---|
| 344 | Text(extent=[-100, 100; 100, 64], string= |
|---|
| 345 | "1 dimensional linear table interpolation"), |
|---|
| 346 | Line(points=[-54, 40; -54, -40; 54, -40; 54, 40; 28, 40; 28, -40; -28, |
|---|
| 347 | -40; -28, 40; -54, 40; -54, 20; 54, 20; 54, 0; -54, 0; -54, -20; |
|---|
| 348 | 54, -20; 54, -40; -54, -40; -54, 40; 54, 40; 54, -40], style( |
|---|
| 349 | color=0)), |
|---|
| 350 | Line(points=[0, 40; 0, -40], style(color=0)), |
|---|
| 351 | Rectangle(extent=[-54, 40; -28, 20], style( |
|---|
| 352 | color=0, |
|---|
| 353 | fillColor=6, |
|---|
| 354 | fillPattern=1)), |
|---|
| 355 | Rectangle(extent=[-54, 20; -28, 0], style( |
|---|
| 356 | color=0, |
|---|
| 357 | fillColor=6, |
|---|
| 358 | fillPattern=1)), |
|---|
| 359 | Rectangle(extent=[-54, 0; -28, -20], style( |
|---|
| 360 | color=0, |
|---|
| 361 | fillColor=6, |
|---|
| 362 | fillPattern=1)), |
|---|
| 363 | Rectangle(extent=[-54, -20; -28, -40], style( |
|---|
| 364 | color=0, |
|---|
| 365 | fillColor=6, |
|---|
| 366 | fillPattern=1)), |
|---|
| 367 | Text(extent=[-52, 56; -34, 44], string="u"), |
|---|
| 368 | Text(extent=[-22,54; 2,42], string="y[1]"), |
|---|
| 369 | Text(extent=[4,54; 28,42], string="y[2]"), |
|---|
| 370 | Text(extent=[0,-40; 32,-54], string="columns"))); |
|---|
| 371 | equation |
|---|
| 372 | if tableOnFile then |
|---|
| 373 | assert(tableName<>"NoName", "tableOnFile = true and no table name given"); |
|---|
| 374 | end if; |
|---|
| 375 | if not tableOnFile then |
|---|
| 376 | assert(size(table,1) > 0 and size(table,2) > 0, "tableOnFile = false and parameter table is an empty matrix"); |
|---|
| 377 | end if; |
|---|
| 378 | |
|---|
| 379 | for i in 1:nout loop |
|---|
| 380 | y[i] = if not tableOnFile and size(table,1)==1 then |
|---|
| 381 | table[1, columns[i]] else dymTableIpo1(tableID, columns[i], u); |
|---|
| 382 | end for; |
|---|
| 383 | when initial() then |
|---|
| 384 | tableID=dymTableInit(1.0, smoothness, if tableOnFile then tableName else "NoName", if tableOnFile then fileName else "NoName", table, 0.0); |
|---|
| 385 | end when; |
|---|
| 386 | end CombiTable1Ds; |
|---|
| 387 | |
|---|
| 388 | model CombiTable2D "Table look-up in two dimensions (matrix/file) " |
|---|
| 389 | |
|---|
| 390 | import Modelica.Blocks.Types; |
|---|
| 391 | extends Modelica.Blocks.Interfaces.SI2SO; |
|---|
| 392 | |
|---|
| 393 | parameter Boolean tableOnFile=false |
|---|
| 394 | "true, if table is defined on file or in function usertab" |
|---|
| 395 | annotation(Dialog(group="table data definition")); |
|---|
| 396 | parameter Real table[:, :]=fill(0.0,0,2) |
|---|
| 397 | "table matrix (grid u1 = first column, grid u2 = first row)" |
|---|
| 398 | annotation(Dialog(group="table data definition", enable = not tableOnFile)); |
|---|
| 399 | parameter String tableName="NoName" |
|---|
| 400 | "table name on file or in function usertab (see docu)" |
|---|
| 401 | annotation(Dialog(group="table data definition", enable = tableOnFile)); |
|---|
| 402 | parameter String fileName="NoName" "file where matrix is stored" |
|---|
| 403 | annotation(Dialog(group="table data definition", enable = tableOnFile)); |
|---|
| 404 | parameter Blocks.Types.Smoothness.Temp smoothness=Types.Smoothness.LinearSegments |
|---|
| 405 | "smoothness of table interpolation" |
|---|
| 406 | annotation(Dialog(group="table data interpretation")); |
|---|
| 407 | annotation ( |
|---|
| 408 | Documentation(info="<html> |
|---|
| 409 | <p> |
|---|
| 410 | <b>Linear interpolation</b> in <b>two</b> dimensions of a <b>table</b>. |
|---|
| 411 | The grid points and function values are stored in a matrix \"table[i,j]\", |
|---|
| 412 | where: |
|---|
| 413 | </p> |
|---|
| 414 | <ul> |
|---|
| 415 | <li> the first column \"table[2:,1]\" contains the u[1] grid points,</li> |
|---|
| 416 | <li> the first row \"table[1,2:]\" contains the u[2] grid points,</li> |
|---|
| 417 | <li> the other rows and columns contain the data to be interpolated.</li> |
|---|
| 418 | </ul> |
|---|
| 419 | <p> |
|---|
| 420 | Example: |
|---|
| 421 | </p> |
|---|
| 422 | <pre> |
|---|
| 423 | | | | | |
|---|
| 424 | | 1.0 | 2.0 | 3.0 | // u2 |
|---|
| 425 | ----*-------*-------*-------* |
|---|
| 426 | 1.0 | 1.0 | 3.0 | 5.0 | |
|---|
| 427 | ----*-------*-------*-------* |
|---|
| 428 | 2.0 | 2.0 | 4.0 | 6.0 | |
|---|
| 429 | ----*-------*-------*-------* |
|---|
| 430 | // u1 |
|---|
| 431 | is defined as |
|---|
| 432 | table = [0.0, 1.0, 2.0, 3.0; |
|---|
| 433 | 1.0, 1.0, 3.0, 5.0; |
|---|
| 434 | 2.0, 2.0, 4.0, 6.0] |
|---|
| 435 | If, e.g. the input u is [1.0;1.0], the output y is 1.0, |
|---|
| 436 | e.g. the input u is [2.0;1.5], the output y is 3.0. |
|---|
| 437 | </pre> |
|---|
| 438 | <ul> |
|---|
| 439 | <li> The interpolation is <b>efficient</b>, because a search for a new interpolation |
|---|
| 440 | starts at the interval used in the last call.</li> |
|---|
| 441 | <li> If the table has only <b>one element</b>, the table value is returned, |
|---|
| 442 | independent of the value of the input signal.</li> |
|---|
| 443 | <li> If the input signal <b>u1</b> or <b>u2</b> is <b>outside</b> of the defined <b>interval</b>, |
|---|
| 444 | the corresponding value is also determined by linear |
|---|
| 445 | interpolation through the last or first two points of the table.</li> |
|---|
| 446 | <li> The grid values (first column and first row) have to be <b>strict</b> |
|---|
| 447 | monotonically increasing.</li> |
|---|
| 448 | </ul> |
|---|
| 449 | <p> |
|---|
| 450 | The table matrix can be defined in the following ways: |
|---|
| 451 | </p> |
|---|
| 452 | <ol> |
|---|
| 453 | <li> Explicitly supplied as <b>parameter matrix</b> \"table\", |
|---|
| 454 | and the other parameters have the following values: |
|---|
| 455 | <pre> |
|---|
| 456 | tableName is \"NoName\" or has only blanks, |
|---|
| 457 | fileName is \"NoName\" or has only blanks. |
|---|
| 458 | </pre></li> |
|---|
| 459 | <li> <b>Read</b> from a <b>file</b> \"fileName\" where the matrix is stored as |
|---|
| 460 | \"tableName\". Both ASCII and binary file format is possible. |
|---|
| 461 | (the ASCII format is described below). |
|---|
| 462 | It is most convenient to generate the binary file from Matlab |
|---|
| 463 | (Matlab 4 storage format), e.g., by command |
|---|
| 464 | <pre> |
|---|
| 465 | save tables.mat tab1 tab2 tab3 -V4 |
|---|
| 466 | </pre> |
|---|
| 467 | when the three tables tab1, tab2, tab3 should be |
|---|
| 468 | used from the model.</li> |
|---|
| 469 | <li> Statically stored in function \"usertab\" in file \"usertab.c\". |
|---|
| 470 | The matrix is identified by \"tableName\". Parameter |
|---|
| 471 | fileName = \"NoName\" or has only blanks.</li> |
|---|
| 472 | </ol> |
|---|
| 473 | <p> |
|---|
| 474 | Table definition methods (1) and (3) do <b>not</b> allocate dynamic memory, |
|---|
| 475 | and do not access files, whereas method (2) does. Therefore (1) and (3) |
|---|
| 476 | are suited for hardware-in-the-loop simulation (e.g. with dSpace hardware). |
|---|
| 477 | When the constant \"NO_FILE\" is defined, all parts of the |
|---|
| 478 | source code of method (2) are removed by the C-preprocessor, such that |
|---|
| 479 | no dynamic memory allocation and no access to files takes place. |
|---|
| 480 | </p> |
|---|
| 481 | <p> |
|---|
| 482 | If tables are read from an ASCII-file, the file need to have the |
|---|
| 483 | following structure (\"-----\" is not part of the file content): |
|---|
| 484 | </p> |
|---|
| 485 | <pre> |
|---|
| 486 | ----------------------------------------------------- |
|---|
| 487 | #1 |
|---|
| 488 | double tab1(5,2) # comment line |
|---|
| 489 | 0 0 |
|---|
| 490 | 1 1 |
|---|
| 491 | 2 4 |
|---|
| 492 | 3 9 |
|---|
| 493 | 4 16 |
|---|
| 494 | double tab2(5,2) # another comment line |
|---|
| 495 | 0 0 |
|---|
| 496 | 2 2 |
|---|
| 497 | 4 8 |
|---|
| 498 | 6 18 |
|---|
| 499 | 8 32 |
|---|
| 500 | ----------------------------------------------------- |
|---|
| 501 | </pre> |
|---|
| 502 | <p> |
|---|
| 503 | Note, that the first two characters in the file need to be |
|---|
| 504 | \"#1\". Afterwards, the corresponding matrix has to be declared |
|---|
| 505 | with type, name and actual dimensions. Finally, in successive |
|---|
| 506 | rows of the file, the elements of the matrix have to be given. |
|---|
| 507 | Several matrices may be defined one after another. |
|---|
| 508 | </p> |
|---|
| 509 | </HTML> |
|---|
| 510 | "), Icon( |
|---|
| 511 | Line(points=[-60, 40; -60, -40; 60, -40; 60, 40; 30, 40; 30, -40; -30, |
|---|
| 512 | -40; -30, 40; -60, 40; -60, 20; 60, 20; 60, 0; -60, 0; -60, -20; |
|---|
| 513 | 60, -20; 60, -40; -60, -40; -60, 40; 60, 40; 60, -40], style( |
|---|
| 514 | color=0)), |
|---|
| 515 | Line(points=[0, 40; 0, -40], style(color=0)), |
|---|
| 516 | Rectangle(extent=[-60, 20; -30, 0], style( |
|---|
| 517 | color=0, |
|---|
| 518 | fillColor=6, |
|---|
| 519 | fillPattern=1)), |
|---|
| 520 | Rectangle(extent=[-60, 0; -30, -20], style( |
|---|
| 521 | color=0, |
|---|
| 522 | fillColor=6, |
|---|
| 523 | fillPattern=1)), |
|---|
| 524 | Rectangle(extent=[-60, -20; -30, -40], style( |
|---|
| 525 | color=0, |
|---|
| 526 | fillColor=6, |
|---|
| 527 | fillPattern=1)), |
|---|
| 528 | Rectangle(extent=[-30, 40; 0, 20], style( |
|---|
| 529 | color=0, |
|---|
| 530 | fillColor=6, |
|---|
| 531 | fillPattern=1)), |
|---|
| 532 | Rectangle(extent=[0, 40; 30, 20], style( |
|---|
| 533 | color=0, |
|---|
| 534 | fillColor=6, |
|---|
| 535 | fillPattern=1)), |
|---|
| 536 | Rectangle(extent=[30, 40; 60, 20], style( |
|---|
| 537 | color=0, |
|---|
| 538 | fillColor=6, |
|---|
| 539 | fillPattern=1)), |
|---|
| 540 | Line(points=[-60, 40; -30, 20], style(color=0)), |
|---|
| 541 | Line(points=[-30, 40; -60, 20], style(color=0))), |
|---|
| 542 | Diagram( |
|---|
| 543 | Rectangle(extent=[-60, 60; 60, -60], style(fillColor=30, |
|---|
| 544 | fillPattern = 1)), |
|---|
| 545 | Line(points=[60, 0; 100, 0]), |
|---|
| 546 | Text(extent=[-100, 100; 100, 64], string= |
|---|
| 547 | "2 dimensional linear table interpolation"), |
|---|
| 548 | Line(points=[-54, 40; -54, -40; 54, -40; 54, 40; 28, 40; 28, -40; -28, |
|---|
| 549 | -40; -28, 40; -54, 40; -54, 20; 54, 20; 54, 0; -54, 0; -54, -20; |
|---|
| 550 | 54, -20; 54, -40; -54, -40; -54, 40; 54, 40; 54, -40], style( |
|---|
| 551 | color=0)), |
|---|
| 552 | Line(points=[0, 40; 0, -40], style(color=0)), |
|---|
| 553 | Rectangle(extent=[-54, 20; -28, 0], style( |
|---|
| 554 | color=0, |
|---|
| 555 | fillColor=6, |
|---|
| 556 | fillPattern=1)), |
|---|
| 557 | Rectangle(extent=[-54, 0; -28, -20], style( |
|---|
| 558 | color=0, |
|---|
| 559 | fillColor=6, |
|---|
| 560 | fillPattern=1)), |
|---|
| 561 | Rectangle(extent=[-54, -20; -28, -40], style( |
|---|
| 562 | color=0, |
|---|
| 563 | fillColor=6, |
|---|
| 564 | fillPattern=1)), |
|---|
| 565 | Rectangle(extent=[-28, 40; 0, 20], style( |
|---|
| 566 | color=0, |
|---|
| 567 | fillColor=6, |
|---|
| 568 | fillPattern=1)), |
|---|
| 569 | Rectangle(extent=[0, 40; 28, 20], style( |
|---|
| 570 | color=0, |
|---|
| 571 | fillColor=6, |
|---|
| 572 | fillPattern=1)), |
|---|
| 573 | Rectangle(extent=[28, 40; 54, 20], style( |
|---|
| 574 | color=0, |
|---|
| 575 | fillColor=6, |
|---|
| 576 | fillPattern=1)), |
|---|
| 577 | Line(points=[-54, 40; -28, 20], style(color=0)), |
|---|
| 578 | Line(points=[-28, 40; -54, 20], style(color=0)), |
|---|
| 579 | Text(extent=[-54, -40; -30, -56], string="u1"), |
|---|
| 580 | Text(extent=[28, 58; 52, 44], string="u2"), |
|---|
| 581 | Text(extent=[-2,12; 32,-22], string="y"))); |
|---|
| 582 | protected |
|---|
| 583 | Real tableID; |
|---|
| 584 | equation |
|---|
| 585 | if tableOnFile then |
|---|
| 586 | assert(tableName<>"NoName", "tableOnFile = true and no table name given"); |
|---|
| 587 | end if; |
|---|
| 588 | if not tableOnFile then |
|---|
| 589 | assert(size(table,1) > 0 and size(table,2) > 0, "tableOnFile = false and parameter table is an empty matrix"); |
|---|
| 590 | end if; |
|---|
| 591 | |
|---|
| 592 | y = dymTableIpo2(tableID, u1, u2); |
|---|
| 593 | when initial() then |
|---|
| 594 | tableID=dymTableInit(2.0, smoothness, if tableOnFile then tableName else "NoName", if tableOnFile |
|---|