JSBSim-Team / jsbsim

An open source flight dynamics & control software library
GNU Lesser General Public License v2.1
1.36k stars 454 forks source link

Improvements to <table> #185

Closed ghost closed 1 year ago

ghost commented 5 years ago

I am currently making a FDM out of limited set of data, with dimension per AoA and nose cone deflection being available only up to some Mach number, and have run into 2 frustrating behaviours of <table> which are turning this into a chore.

  1. When a tree-dimensional <table> is given a single column or a single number under one of the <tableData>, JSBSim refuses to work. But I would expect it to interpret <tableData> like this:
shape 1x1
0
ignore row and column

shape Nx2
0 4
1 5
2 6
3 7
ignore column

shape 2xN
0 1 2 3
4 5 6 7
ignore row

shape(N+1)x(N+1) with empty corner
   0  1  2  3
0  4  5  6  7
1  8  9 10 11
2 12 13 14 15
3 16 17 18 19
interpolate both row and column as usual

thus the only only invalid inputs would be array shapes of 2x1 and 1x2 or a NxN with non-empty corner.

  1. Even if I don't specify column coordinate at all, <table> does not want to use combination of row and table coordinates without column -- which means some tables I would have to reshuffle instead of just pasting them under different <tableData>. This actually may be a consequence of "1."

But I'm not sure whether I'm asking for makes sense -- maybe there are other tools than <table> anyone would suggest for this job?

Zaretto commented 5 years ago

have a look at <interpolate1d> ; AlanT uses these a lot in his model to achieve the same as a 3d table.

e.g.

      <interpolate1d>
        <property>atmosphere/density-altitude</property>
        <value>9400</value>
        <table name =  "aero/table/alt9400">
          <independentVar lookup = "row">fcs/elevator-pos-deg </independentVar>
          <independentVar lookup = "column"> aero/alpha-deg </independentVar>
          <tableData>
            ...
          </tableData>
        </table>
        <value>16000.0</value>
        <table name =  "aero/table/alt16000">
          <independentVar lookup = "row">fcs/elevator-pos-deg </independentVar>
          <independentVar lookup = "column"> aero/alpha-deg </independentVar>
          <tableData>
            ...
          </tableData>
        </table>
      </interpolate1d>
ghost commented 5 years ago

Thanks for the example, I've been wondering how to use that func for a while!

bcoconni commented 5 years ago

@mike402 So should we consider this issue closed ? Or do you need any further help ?

ghost commented 5 years ago

It depends. Ultimately I had to write a complex sed/awk script to update tables faster anyway, so transposing tables was not that bad, so my particular issue was resolved. On the other hand this could be reclassified as "feature request" because it would help with other use cases.

bcoconni commented 5 years ago

I am not sure I am understanding correctly your request.

Do you mean that if some rows/columns are missing in a <table> then JSBSim should fill the gaps by interpolating the values it has been provided with ?

ghost commented 5 years ago

No, I mean ideally it should: 1) treat vertical and horizontal single-dimensional tables equally (right now it only takes the vertical one) 2) allow to use the <tableData breakPoint=""> for any shape (far as I remember, right now it already allows that for different sizes of table, but it won't work if the tables are single-dimensional)

It would not break any compatibility.

bcoconni commented 5 years ago

Right I have renamed the issue so that it fits better for a feature request.

legoboyvdlp commented 4 years ago

It appears that having zero difference in values in a table is invalid, as is having "non-monotonic increases". I wonder if the table operation could be updated to interpolate regardless of values?

Is there some limitation that inhibits this?

Also, would it be possible to simply not interpolate if there is zero difference between consecutive elements rather than returning an error?

For example,

<tableData breakpoint="15000">
        0    1 
92    0    0 
95   16.7  0
100  58.7  50.7
</tableData>
<tableData breakpoint="20000">
        0    1 
92    0    0 
95    6.7  0
100  48.7  40.7
</tableData>

I would have expected this to work correctly, but it gave an error. Notice, this was in a 3D table, rather than a 2D. The mo

ghost commented 4 years ago

Zero difference between output values is completely valid (unlike input). I think this one causes an error because of breakpoint instead of breakPoint :P

On Tue, May 05, 2020 at 04:56:33PM -0700, Jonathan Redpath wrote:

It appears that having zero difference in values in a table is invalid, as is having "non-monotonic increases". I wonder if the table operation could be updated to interpolate regardless of values?

Is there some limitation that inhibits this?

Also, would it be possible to simply not interpolate if there is zero difference between consecutive elements rather than returning an error?

For example,

<tableData breakpoint="15000">
                                            0    1 
                                      92    0    0 
                                      95   16.7  0
                                      100  58.7  50.7
                                  </tableData>
                                  <tableData breakpoint="20000">
                                            0    1 
                                      92    0    0 
                                      95    6.7  0
                                      100  48.7  40.7
                                  </tableData>

I would have expected this to work correctly, but it gave an error. Notice, this was in a 3D table, rather than a 2D. The mo

legoboyvdlp commented 4 years ago

I just typed that in here, copied + pasted from the interpolate1D method. I really cannot remember if I had it set correctly or not in the original 3D table, but regardless I would have thought it would at least give an error, rather than crash silently :)

bcoconni commented 4 years ago

@legoboyvdlp Has your problem been fixed once you fixed the typo ?

regardless I would have thought it would at least give an error, rather than crash silently :)

Well, such a process is called XML validation and our on going effort is discussed in the issue #155 (unfortunately it is stalled at the moment). Any help would be appreciated :wink:

legoboyvdlp commented 4 years ago

Well, I'm using Interpolated1D now, but yes, I believe it would have been.

bcoconni commented 2 years ago

@mike402, I pushed some commits (de6c69804d4e06a4cf4d077401e7bc3ee816763e and f133d7b59411d31b0c836359297838b01b5a6c0c) that extends the allowed matrix shapes in the definition of a <table> element.

Shape 1x1 (constant 1D matrix)

This one can be specified with the following syntax:

<table name=\"test\">
  <independentVar>x</independentVar>
  <tableData>
    0.0 1.0
  </tableData>
</table>

This is a 1D table that will always return 1.0 whatever the value of the property x. Note that, in this context, the row value 0.0 is irrelevant and it can be replaced by any real value to the same effect.

As JSBSim interprets this table as a 1D table, this syntax cannot be used in the context of a 3D table.

Shape 1x1 (constant 2D matrix)

This one can be specified with the following syntax:

<table name=\"test\">
  <independentVar lookup="row">x</independentVar>
  <independentVar lookup="column">y</independentVar>
  <tableData>
        2.0
    0.0 1.0
  </tableData>
</table>

This 2D matrix will always return 1.0 whatever are the values of the properties x and y. Note that, in this context, the row value 0.0 and the column value 2.0 are irrelevant and can be replaced by any other real values to the same effect.

As this table is interpreted as a 2D table by JSBSim, this syntax can be used in the context of a 3D table.

Shape 1xN (2D matrix)

This one can be specified with the following syntax:

<table name=\"test\">
  <independentVar lookup="row">x</independentVar>
  <independentVar lookup="column">y</independentVar>
  <tableData>
        1.0 2.0 3.0
    0.0 4.0 5.0 6.0
  </tableData>
</table>

This 2D table will interpolate the output values 4.0 5.0 6.0 based on the value of the property y ("column" lookup variable). The result will be independent of the property x so the row value 0.0 in the table definition is irrelevant.

Shape Nx1 (2D matrix)

This one can be specified with the following syntax:

<table name=\"test\">
  <independentVar lookup="row">x</independentVar>
  <independentVar lookup="column">y</independentVar>
  <tableData>
        0.0
    1.0 2.0
    3.0 4.0
    5.0 6.0
  </tableData>
</table>

This 2D table will interpolate the output values 2.0 4.0 6.0 based on the value of the property x ("row" lookup variable). The result will be independent of the property y so the value 0.0in the table definition is irrelevant.

JSBSim makes the distinction between a 2D table with a Nx1 shape and a 1D matrix with N rows because the header line has only one value (0.0) while the header line would have 2 values for a 1D table. Hence the requirement to provide the dummy value 0.0 for a 2D table.

I took the opportunity to improve the detection of malformed <table> definitions so you might find that JSBSim is pickier in that regard than it used to be. The goal being of course to help the user detecting errors earlier rather than silently ignoring errors.

Could you please test this feature and let us know if this works as expected ?

bcoconni commented 1 year ago

Closing the issue as no further comments have been made since the comment I have posted one year ago.