Class: Legion::Extensions::Agentic::Homeostasis::Tide::Helpers::Oscillator

Inherits:
Object
  • Object
show all
Defined in:
lib/legion/extensions/agentic/homeostasis/tide/helpers/oscillator.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(oscillator_type:, period:, amplitude: 1.0, phase_offset: 0.0) ⇒ Oscillator

Returns a new instance of Oscillator.

Raises:

  • (ArgumentError)


12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
# File 'lib/legion/extensions/agentic/homeostasis/tide/helpers/oscillator.rb', line 12

def initialize(oscillator_type:, period:, amplitude: 1.0, phase_offset: 0.0)
  unless Constants::OSCILLATOR_TYPES.include?(oscillator_type)
    raise ArgumentError, "unknown oscillator_type: #{oscillator_type.inspect}; " \
                         "must be one of #{Constants::OSCILLATOR_TYPES.inspect}"
  end

  raise ArgumentError, 'period must be positive' unless period.positive?

  @id = SecureRandom.uuid
  @oscillator_type = oscillator_type
  @period         = period.to_f
  @amplitude      = amplitude.clamp(0.0, 1.0)
  @phase_offset   = phase_offset.to_f
  @last_ticked_at = nil
end

Instance Attribute Details

#amplitudeObject (readonly)

Returns the value of attribute amplitude.



10
11
12
# File 'lib/legion/extensions/agentic/homeostasis/tide/helpers/oscillator.rb', line 10

def amplitude
  @amplitude
end

#idObject (readonly)

Returns the value of attribute id.



10
11
12
# File 'lib/legion/extensions/agentic/homeostasis/tide/helpers/oscillator.rb', line 10

def id
  @id
end

#oscillator_typeObject (readonly)

Returns the value of attribute oscillator_type.



10
11
12
# File 'lib/legion/extensions/agentic/homeostasis/tide/helpers/oscillator.rb', line 10

def oscillator_type
  @oscillator_type
end

#periodObject (readonly)

Returns the value of attribute period.



10
11
12
# File 'lib/legion/extensions/agentic/homeostasis/tide/helpers/oscillator.rb', line 10

def period
  @period
end

#phase_offsetObject (readonly)

Returns the value of attribute phase_offset.



10
11
12
# File 'lib/legion/extensions/agentic/homeostasis/tide/helpers/oscillator.rb', line 10

def phase_offset
  @phase_offset
end

Instance Method Details

#current_valueObject

Current value based on Time.now



43
44
45
# File 'lib/legion/extensions/agentic/homeostasis/tide/helpers/oscillator.rb', line 43

def current_value
  value_at(Time.now.utc)
end

#in_phase_with?(other) ⇒ Boolean

Two oscillators are in phase when their normalized values are within tolerance

Returns:

  • (Boolean)


48
49
50
51
52
53
54
# File 'lib/legion/extensions/agentic/homeostasis/tide/helpers/oscillator.rb', line 48

def in_phase_with?(other)
  combined_amplitude = [@amplitude, other.amplitude].sum
  return false if combined_amplitude.zero?

  tolerance = Constants::SPRING_TIDE_PHASE_TOLERANCE * combined_amplitude
  (current_value - other.current_value).abs <= tolerance
end

#tick!Object

Advance the oscillator by computing its current sinusoidal value



29
30
31
32
# File 'lib/legion/extensions/agentic/homeostasis/tide/helpers/oscillator.rb', line 29

def tick!
  @last_ticked_at = Time.now.utc
  current_value
end

#to_hObject



56
57
58
59
60
61
62
63
64
65
66
# File 'lib/legion/extensions/agentic/homeostasis/tide/helpers/oscillator.rb', line 56

def to_h
  {
    id:              @id,
    oscillator_type: @oscillator_type,
    period:          @period,
    amplitude:       @amplitude,
    phase_offset:    @phase_offset,
    current_value:   current_value,
    last_ticked_at:  @last_ticked_at
  }
end

#value_at(time) ⇒ Object

Sinusoidal value at a given time, normalized to [0, 1]



35
36
37
38
39
40
# File 'lib/legion/extensions/agentic/homeostasis/tide/helpers/oscillator.rb', line 35

def value_at(time)
  t = time.to_f
  radians = ((2.0 * Math::PI * t) / @period) + @phase_offset
  # sin ranges [-1, 1] — shift to [0, 1]
  ((Math.sin(radians) + 1.0) / 2.0 * @amplitude).round(10)
end