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

fix hue errors in plasma_stick_rainbows #883

Merged
merged 2 commits into from
Jan 16, 2024
Merged

Conversation

raybellis
Copy link
Contributor

@raybellis raybellis commented Dec 15, 2023

In this example the use of the monotonically increasing offset variable in the hue calculations will cause the colours to stop rotating when the repeated addition of 20 / 2000 eventually becomes too small to make a difference to the accumulated value given the limited precision of a float. That is, at some point offset += float(SPEED) / 2000.0f becomes a no-op.

Granted it will take a long time - 265 days with the current code - but in a modified version of this demo I've been able to trigger issues far more rapidly.

This patch first makes sure that offset doesn't increase without bound so that it stays within the numerical precision range of a float, and secondly ensures that all hue values passed to RGBLED::set_hsv() are within the range [0..1)

The second change begs the question of whether the various FOO::set_hsv() methods in the library should perform this normalisation of the h parameter on entry to those methods. It would not only resolve some issues I've seen with negative hue values, but also avoid the need for the i % 6 in the switch since with h constrained to [0..1) i will also be similarly constrained to [0..6).

@raybellis
Copy link
Contributor Author

Correction - I forgot to account for 60 updates per second. The existing code should stop working after just 4 days and 10 hours, give or take. It takes 22918664 passes through the loop for the addition of 0.01f to stop working.

@LaaZa
Copy link

LaaZa commented Dec 18, 2023

Wouldn't it make more sense to just offset %= 1.0 and hue %= 1.0?

Comment on lines +37 to +39
if (offset > 1.0) {
offset -= 1.0;
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
if (offset > 1.0) {
offset -= 1.0;
}
offset %= 1

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Following up on https://github.com/LaaZa comment...

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this isn't legal code.

Copy link
Contributor

@bitcdr bitcdr Dec 29, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You are totally right, the code proposal would then be only for the corresponding Python code, if you won't mind fixing the issue also over there :)

See e.g. bitcdr/plasma-leds#5 for a fix.

@@ -34,10 +34,15 @@ int main() {
while(true) {

offset += float(SPEED) / 2000.0f;
if (offset > 1.0) {
offset -= 1.0;
}

for(auto i = 0u; i < NUM_LEDS; ++i) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

        for i in range(NUM_LEDS):
            hue = (offset + float(i) / NUM_LEDS) % 1
            led_strip.set_hsv(i, hue, 1.0, 1.0)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Following up on https://github.com/LaaZa comment and condensing the code a bit

@raybellis
Copy link
Contributor Author

Wouldn't it make more sense to just offset %= 1.0 and hue %= 1.0?

No, you can't use modulo on floating point numbers in C / C++

@LaaZa
Copy link

LaaZa commented Dec 28, 2023

Wouldn't it make more sense to just offset %= 1.0 and hue %= 1.0?

No, you can't use modulo on floating point numbers in C / C++

Right... another reason for why we need to move on from C as a society.

@raybellis
Copy link
Contributor Author

raybellis commented Jan 2, 2024

The proposed python fix was incomplete - it's necessary to constrain the range of the offset variable too. In fact that's the most important part of the fix.

@Gadgetoid Gadgetoid merged commit 0d3fce9 into pimoroni:main Jan 16, 2024
15 checks passed
@Gadgetoid
Copy link
Member

Thank you for the detailed explanation and fix, this looks reasonable to me!

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.

4 participants