Skip to content

Add chaotic pendulum color animation mode for D4K-3ch#150

Open
GlassOnTin wants to merge 6 commits intoToyKeeper:trunkfrom
GlassOnTin:d4k-3ch-chaos-mode
Open

Add chaotic pendulum color animation mode for D4K-3ch#150
GlassOnTin wants to merge 6 commits intoToyKeeper:trunkfrom
GlassOnTin:d4k-3ch-chaos-mode

Conversation

@GlassOnTin
Copy link

@GlassOnTin GlassOnTin commented Dec 12, 2025

Summary

Adds a new channel mode (CM_CHAOS) for the Emisar D4K-3ch that creates organic, non-repeating color animations using driven coupled oscillator physics - a simplified model of a double pendulum.

Key features:

  • Chaotic dynamics that never exactly repeat
  • Spends most time at vivid, saturated colors (sqrt-like saturation mapping)
  • Smooth transitions without jarring changes
  • User-adjustable animation speed via 3H with visual brightness feedback
  • Continuous animation even when brightness is static

Files changed:

  • hw/hank/emisar-d4k-3ch/hwdef.h - Added CM_CHAOS enum and USE_CHAOS_MODE flag
  • hw/hank/emisar-d4k-3ch/hwdef.c - Chaos physics implementation, 3H handler with visual feedback
  • ui/anduril/ramp-mode.c - Hook for continuous animation in EV_tick handler
  • docs/chaotic-pendulum-science.md - Technical documentation with physics explanation
  • docs/images/chaos-*.png - 6 visualization diagrams from simulation
  • tools/chaos_simulation.py - Python simulation matching firmware exactly

User controls:

  • 3C: Cycle to chaos mode (position 8)
  • 1H: Adjust brightness (animation continues)
  • 3H: Adjust chaos energy/speed (brightness shows level, blinks on wrap)

Test plan

  • Built firmware successfully (14914 bytes, 91.0% full)
  • Flashed and tested on physical D4K-3ch hardware
  • Verified continuous animation while brightness is static
  • Verified 3H adjustment with brightness feedback and wrap-around blink
  • Verified saturation spends more time at vivid colors than white
  • Verified animation speed range is perceptually useful across full 0-255 energy range

Implements a new channel mode (CM_CHAOS) that creates organic, non-repeating
color animations using driven coupled oscillator physics.

Features:
- Driven double pendulum dynamics for sustained chaotic motion
- Hue oscillator explores full color wheel (0-255)
- Saturation oscillator keeps colors centered around white (sat 60-220)
- User-adjustable energy/speed via 3H (click-click-hold)
- Continuous animation via gradual_tick integration

Physics model:
- Two coupled oscillators with periodic driving force
- Triangle wave approximation for sine (reuses existing function)
- Very light damping (1/512) to prevent runaway
- Coupling term creates sensitive dependence on initial conditions

Documentation includes:
- Technical deep-dive (docs/chaotic-pendulum-science.md)
- Phase space diagrams showing chaotic attractor
- Color trajectory visualizations
- Time series analysis
- Energy parameter comparison
- Python simulation tool matching firmware algorithm
Repositioned Hue and Saturation output labels to avoid overlapping
with the equation box at the bottom of the diagram.
The chaos mode was only animating during brightness ramping because
gradual_tick() is only called when there's a brightness difference.

Fix by:
- Adding USE_CHAOS_MODE flag to D4K-3ch hwdef.h
- Hooking into EV_tick in ramp-mode.c to call set_level() continuously
  when in chaos mode, which advances the chaos physics each frame
- Making gradual_tick_chaos() always return false (not strictly needed
  now but keeps the function semantically correct for animation)
Energy parameter tuning:
- Scale range narrowed to 6-11 (was 4-19) to avoid too-slow boring
  oscillations and too-fast white blur
- Drive amplitude narrowed to 40-56 (was 32-63) for consistent dynamics

Saturation mapping:
- Added sqrt-like expansion to spend more time at vivid saturated
  colors and less time near white
- Range expanded to 40-240 (was 60-220)

3H adjustment visual feedback:
- Brightness now shows energy level during adjustment (dim=slow, bright=fast)
- Brief blink on wrap-around (255->0 or 0->255)
- Original brightness restored on release

Updated simulation and documentation to match firmware changes.
The default omega1=200 and omega2=150 caused the system to get trapped
in half the phase space (hue 0-128 only). Increasing to omega1=1000
and omega2=800 ensures the chaotic attractor explores the full hue
range (0-255) from startup.

Regenerated all visualization diagrams showing full color coverage.
omega1=1000 still resulted in the attractor being biased toward one
half of the hue range. omega1=1500 was found empirically to give
good coverage across all four quadrants of the color wheel.

Regenerated visualizations now show full RGB coverage in the
color trajectory polar plot.
@SammysHP
Copy link
Contributor

Sounds awesome. Can you share a video of the effect? Unfortunately I don't have a three channel light.

@GlassOnTin
Copy link
Author

Sounds awesome. Can you share a video of the effect? Unfortunately I don't have a three channel light.

Here's a minute of colour therapy, though I chose to reduce the pendulum energy (3H) after a minute.

PXL_20251212_141409159.mp4

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