SignalK / SensESP

Universal Signal K sensor framework for the ESP32 platform
https://signalk.org/SensESP/
Apache License 2.0
145 stars 79 forks source link

Improved curve interpolator #689

Closed rszemeti closed 2 months ago

rszemeti commented 2 months ago

The curve interpolator reacted strangely to values beyond the curve limits.

Values below the lower bound were linearly interpolated between the point 0,0 and the first curve point, values above the upper bound translated to 9999.99

It seems more graceful to simply continue the curve linearly above and below the lower and upper pair of points.

If "hard limits" are desired, such as a tank cannot be less 0.0 empty or 1.0 full simply adding bounds points with the same value at the top and bottom of the list produces a flat line:

eg:

(50,0) (100,0) (1000,1) (1050,1)

Willl produce a "flat" curve lowwr than 100 and above 1000, effectively limiting the output. Without the bound points, the linear curve extends above 1000 and below 100 without unpredictable results.

mairas commented 2 months ago

Thanks. I had noticed the weird behavior you described but instead just added those guard elements you mentioned. :-)

As for the fix, though - I'm wondering would it be better to cap the output to the top value? A common use case might be to set a tank sender mapping as follows:

(0,0)
(180,1)

Here, if the measured tank sender resistance (due to either the sender itself or ADC inaccuracies - HALMET for example uses 1% resistors there) is above 180 ohms, you'll get a tank fill rate above 100%. If we didn't extrapolate but instead returned the top value, the behavior might be "less unexpected" to the user.

What do you think?

rszemeti commented 2 months ago

I think it depends on the use case ... if it was a fuel tank sender for example, limiting the values between 0 and 1 makes sense, in this case you add your "limit" values.

If it is a temperature sensor, the highest calibration point might be 500 ohms for 90 degrees, but it makes sense if it goes to 505 ohms to show a value over 90 degrees ... the calibration may not be exact, but it is better than stopping at (500,90) ... or even when it gets to 600 ohms, you want to know it is really way hot .. .

So, it is up to you, but I think this way allows the user to choose what is appropriate for the situation

On Tue, 16 Apr 2024 at 13:42, Matti Airas @.***> wrote:

Thanks. I had noticed the weird behavior you described but instead just added those guard elements you mentioned. :-)

As for the fix, though - I'm wondering would it be better to cap the output to the top value? A common use case might be to set a tank sender mapping as follows:

(0,0) (180,1)

Here, if the measured tank sender resistance (due to either the sender itself or ADC inaccuracies - HALMET for example uses 1% resistors there) is above 180 ohms, you'll get a tank fill rate above 100%. If we didn't extrapolate but instead returned the top value, the behavior might be "less unexpected" to the user.

What do you think?

— Reply to this email directly, view it on GitHub https://github.com/SignalK/SensESP/pull/689#issuecomment-2059001079, or unsubscribe https://github.com/notifications/unsubscribe-auth/ALFTBRBKCMKX5AHPWEI5CJDY5UMD5AVCNFSM6AAAAABGIFYLN6VHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDANJZGAYDCMBXHE . You are receiving this because you authored the thread.Message ID: @.***>

mairas commented 2 months ago

That's a good point (letting the user to choose). Let's go with your implementation as-is. Code looks clean.