TriggeredTrapezoid

block TriggeredTrapezoid "Triggered trapezoid generator"
    extends Modelica.Blocks.Icons.PartialBooleanBlock;

    parameter Real amplitude = 1 "Amplitude of trapezoid";
    parameter SI.Time rising(final min = 0) = 0 "Rising duration of trapezoid";
    parameter SI.Time falling(final min = 0) = rising "Falling duration of trapezoid";
    parameter Real offset = 0 "Offset of output signal";
    Blocks.Interfaces.BooleanInput u "Connector of Boolean input signal"
        annotation (Placement(transformation(extent = {
            {-140, -20}, 
            {-100, 20}})));
    Blocks.Interfaces.RealOutput y "Connector of Real output signal"
        annotation (Placement(transformation(extent = {
            {100, -10}, 
            {120, 10}})));
protected
    discrete Real endValue "Value of y at time of recent edge";
    discrete Real rate "Current rising/falling rate";
    discrete SI.Time T "Predicted time of output reaching endValue";
equation
    when {initial(), u, not u} then 
        endValue = if u then offset + amplitude else offset;
        rate = if u and 0 < rising then amplitude / rising else if not u and 0 < falling then -amplitude / falling else 0;
        T = if u and not 0 < rising or not u and not 0 < falling or not 0 < abs(amplitude) or initial() then time else time + (endValue - pre(y)) / rate;
    end when;
    y = if time < T then endValue - (T - time) * rate else endValue;

    annotation (
        Icon(
            coordinateSystem(
                preserveAspectRatio = true,
                extent = {
                    {-100, -100}, 
                    {100, 100}}),
            graphics = {
                Line(
                    points = {
                        {-60, -70}, 
                        {-60, -70}, 
                        {-30, 40}, 
                        {8, 40}, 
                        {40, -70}, 
                        {40, -70}},
                    color = {0, 0, 127}), 
                Line(
                    points = {
                        {-90, -70}, 
                        {82, -70}},
                    color = {192, 192, 192}), 
                Line(
                    points = {
                        {-80, 68}, 
                        {-80, -80}},
                    color = {192, 192, 192}), 
                Polygon(
                    lineColor = {192, 192, 192},
                    fillColor = {192, 192, 192},
                    fillPattern = FillPattern.Solid,
                    points = {
                        {90, -70}, 
                        {68, -62}, 
                        {68, -78}, 
                        {90, -70}}), 
                Polygon(
                    lineColor = {192, 192, 192},
                    fillColor = {192, 192, 192},
                    fillPattern = FillPattern.Solid,
                    points = {
                        {-80, 90}, 
                        {-88, 68}, 
                        {-72, 68}, 
                        {-80, 90}}), 
                Line(
                    points = {
                        {-80, -70}, 
                        {-60, -70}, 
                        {-60, 24}, 
                        {8, 24}, 
                        {8, -70}, 
                        {60, -70}},
                    color = {255, 0, 255})}),
        Documentation(info = "<html>\n<p>The block TriggeredTrapezoid has a Boolean input and a real\noutput signal and requires the parameters <em>amplitude</em>,\n<em>rising</em>, <em>falling</em> and <em>offset</em>. The\noutput signal <strong>y</strong> represents a trapezoidal signal dependent on the\ninput signal <strong>u</strong>.\n</p>\n\n<p>\n<img src=\"modelica://Modelica/Resources/Images/Blocks/Logical/TriggeredTrapezoid.png\"\n     alt=\"TriggeredTrapezoid.png\">\n</p>\n\n<p>The behaviour is as follows: Assume the initial input to be false. In this\ncase, the output will be <em>offset</em>. After a rising edge (i.e., the input\nchanges from false to true), the output is rising during <em>rising</em> to the\nsum of <em>offset</em> and <em>amplitude</em>. In contrast, after a falling\nedge (i.e., the input changes from true to false), the output is falling\nduring <em>falling</em> to a value of <em>offset</em>.\n</p>\n<p>Note, that the case of edges before expiration of rising or falling is\nhandled properly.</p>\n</html>"));
end TriggeredTrapezoid;