Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improved curve interpolator #689

Merged
merged 2 commits into from
Apr 16, 2024
Merged

Improved curve interpolator #689

merged 2 commits into from
Apr 16, 2024

Conversation

rszemeti
Copy link
Contributor

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.

Prevent overun of curve producing erroneous values.

For example in a simple curve with two points (100,0) and (500,1)  representing inputs between 100 and 500  producing outputs 0 to 1 ... but any values outside the range eg 99 or 501 produce  arbitary results, for the majority of applications (eg a temperature sender or a fuel level sender) limiting the output to the min or max curve valies makes more sense.
extended curve at upper and lower bounds so values are interpolated gracefully beyond the curve limits
@mairas
Copy link
Collaborator

mairas commented Apr 16, 2024

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
Copy link
Contributor Author

rszemeti commented Apr 16, 2024 via email

@mairas
Copy link
Collaborator

mairas commented Apr 16, 2024

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

@mairas mairas merged commit d59aa7a into SignalK:main Apr 16, 2024
14 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants