.. include:: defs.hrst

Ramp
====

A source unit that generates a smooth transition between two values. The unit can be
triggered to start transitioning to a target value for a certain duration.

Parameters
----------

.. list-table::
   :header-rows: 1
   :widths: 12 33 9 16 15 15

   * - Name
     - Description
     - Range
     - Setter
     - Getter
     - Flow
   * - duration
     - Duration of the ramp transition (in seconds).
     - > 0
     - ``duration(v)``
     - ``duration()``
     - ``Duration()``
   * - speed
     - Rate of change (change-per-second).
     - > 0
     - ``speed(v)``
     - ``speed()``
     - ``Speed()``

Events
------

.. list-table::
   :header-rows: 1
   :widths: 50 25 25

   * - When
     - Trigger
     - Callback
   * - Timed process completes
     - ``finished()``
     - ``onFinish(c)``

Usage
-----

There are two ways to start the ramp:

 * ``go(from, to, duration)``: ramp will transition from value ``from`` to value ``to`` in ``duration`` seconds.
 * ``go(to, duration)``: starts a transition from the ramp's current value to ``to`` in ``duration`` seconds.

The following diagram shows what happens to the ramp signal if ``go(5.0, 1.0, 2.0)`` is
called, followed later by ``go(3.0, 1.0)``:

.. image:: images/Plaquette-Ramp.png

.. important::
  Ramps also support the use of `easing functions <http://easings.net>`_ in order to
  create different kinds of expressive effects with signals. An easing function can
  optionally be specified at the end of a ``go()`` command or by calling the
  ``easing()`` function.

  Please refer to :doc:`this page <easings>` for a full list of available easing functions.

|Example|
---------

Sequentially ramps through different values.

.. code-block:: c++

   #include <Plaquette.h>

   Ramp myRamp(3.0); // initial duration: 3 seconds

   Plotter serialOut(115200);

   void begin() {
     // Apply an easing function (optional).
     myRamp.easing(easeOutSine);
     // Launch ramp: ramp from -10 to 10.
     myRamp.go(-10, 10);
   }

   void step() {
     if (myRamp.isFinished())
     {
       // Launch ramp from current value to half, increasing duration by one second.
       myRamp.go(myRamp / 2, myRamp.duration() + 1);
     }

     myRamp >> serialOut;
   }


|Reference|
-----------

.. doxygenclass:: Ramp
   :project: Plaquette
   :members:

|SeeAlso|
---------
- :doc:`Alarm`
- :doc:`Chronometer`
- :doc:`easings`
- :doc:`Metronome`
- :doc:`Wave`
