TriggeredTrapezoid

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

    parameter Real amplitude = 1 "Amplitude of trapezoid";
    parameter Modelica.SIunits.Time rising(final min = 0) = 0 "Rising duration of trapezoid";
    parameter Modelica.SIunits.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 Modelica.SIunits.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})}),
        Diagram(
            coordinateSystem(
                preserveAspectRatio = true,
                extent = {
                    {-100, -100}, 
                    {100, 100}}),
            graphics = {
                Line(
                    points = {
                        {-80, -20}, 
                        {-60, -20}, 
                        {-30, 40}, 
                        {8, 40}, 
                        {40, -20}, 
                        {60, -20}},
                    color = {0, 0, 255}), 
                Line(points = {
                    {-90, -70}, 
                    {82, -70}}), 
                Line(points = {
                    {-80, 68}, 
                    {-80, -80}}), 
                Polygon(
                    points = {
                        {90, -70}, 
                        {68, -62}, 
                        {68, -78}, 
                        {90, -70}},
                    fillColor = {255, 255, 255},
                    fillPattern = FillPattern.Solid), 
                Polygon(
                    points = {
                        {-80, 90}, 
                        {-88, 68}, 
                        {-72, 68}, 
                        {-80, 90}},
                    fillColor = {255, 255, 255},
                    fillPattern = FillPattern.Solid), 
                Line(
                    points = {
                        {-80, -68}, 
                        {-60, -68}, 
                        {-60, -42}, 
                        {8, -42}, 
                        {8, -68}, 
                        {60, -68}},
                    color = {255, 0, 255}), 
                Line(
                    points = {
                        {-60, 40}, 
                        {-60, -42}},
                    pattern = LinePattern.Dot), 
                Line(
                    points = {
                        {8, -42}, 
                        {8, 40}},
                    pattern = LinePattern.Dot), 
                Line(
                    points = {
                        {-60, 40}, 
                        {-30, 40}},
                    color = {0, 0, 0}), 
                Line(points = {
                    {8, -20}, 
                    {40, -20}}), 
                Line(points = {
                    {-20, 40}, 
                    {-20, -20}}), 
                Line(points = {
                    {-20, -20}, 
                    {-20, -70}}), 
                Text(
                    extent = {
                        {-44, 50}, 
                        {-44, 40}},
                    textString = "rising"), 
                Text(
                    extent = {
                        {24, -10}, 
                        {24, -20}},
                    textString = "falling"), 
                Polygon(
                    points = {
                        {-60, 40}, 
                        {-56, 42}, 
                        {-56, 38}, 
                        {-60, 40}},
                    fillColor = {255, 255, 255},
                    fillPattern = FillPattern.Solid), 
                Polygon(
                    points = {
                        {-30, 40}, 
                        {-34, 42}, 
                        {-34, 38}, 
                        {-30, 40}},
                    fillColor = {255, 255, 255},
                    fillPattern = FillPattern.Solid), 
                Polygon(
                    points = {
                        {8, -20}, 
                        {12, -18}, 
                        {12, -22}, 
                        {8, -20}},
                    fillColor = {255, 255, 255},
                    fillPattern = FillPattern.Solid), 
                Polygon(
                    points = {
                        {40, -20}, 
                        {36, -18}, 
                        {36, -22}, 
                        {40, -20}},
                    fillColor = {255, 255, 255},
                    fillPattern = FillPattern.Solid), 
                Polygon(
                    points = {
                        {-22, -24}, 
                        {-20, -20}, 
                        {-18, -24}, 
                        {-22, -24}},
                    fillColor = {255, 255, 255},
                    fillPattern = FillPattern.Solid), 
                Polygon(
                    points = {
                        {-18, -66}, 
                        {-22, -66}, 
                        {-20, -70}, 
                        {-18, -66}},
                    fillColor = {255, 255, 255},
                    fillPattern = FillPattern.Solid), 
                Polygon(
                    points = {
                        {-22, 36}, 
                        {-20, 40}, 
                        {-18, 36}, 
                        {-22, 36}},
                    fillColor = {255, 255, 255},
                    fillPattern = FillPattern.Solid), 
                Polygon(
                    points = {
                        {-18, -16}, 
                        {-22, -16}, 
                        {-20, -20}, 
                        {-18, -16}},
                    fillColor = {255, 255, 255},
                    fillPattern = FillPattern.Solid), 
                Rectangle(
                    extent = {
                        {-40, 6}, 
                        {0, -4}},
                    lineColor = {255, 255, 255},
                    fillColor = {255, 255, 255},
                    fillPattern = FillPattern.Solid), 
                Text(
                    extent = {
                        {-20, 6}, 
                        {-20, -4}},
                    textString = "amplitude"), 
                Rectangle(
                    extent = {
                        {-40, -48}, 
                        {0, -58}},
                    lineColor = {255, 255, 255},
                    fillColor = {255, 255, 255},
                    fillPattern = FillPattern.Solid), 
                Text(
                    extent = {
                        {-20, -48}, 
                        {-20, -58}},
                    textString = "offset"), 
                Text(
                    extent = {
                        {60, -82}, 
                        {94, -92}},
                    textString = "time"), 
                Text(
                    extent = {
                        {-88, -4}, 
                        {-54, -14}},
                    textString = "y"), 
                Text(
                    extent = {
                        {-88, -46}, 
                        {-54, -56}},
                    textString = "u")}),
        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<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;