Нужно реализовать в программе ПИД- регулятор, который будет удерживать угол заданный маятнику

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">

<style>
    body
     {
        text-align: center;
        max-width: 50em;
        margin: 0 auto;
        padding: 8px;
    }
    h2
    {
        text-align: center;
    }
    #canvas
    {
        display: block;
        margin: 0 auto;
        padding: 0;
        background: #f1f5f5;
        pointer-events: none;
    }
    .quantity-block
    {
        display: grid;
        grid-template-columns: 100px 250px;
        justify-content: center;
        align-items: flex-start;
        gap: 1em;
        padding: 10px ;
    }
    .quantity-block label
    {
        text-align:start;
    }
    .button
    {
        background-color: white;
        color: black;
        border: 2px solid #555555;
        padding: 15px 20px;
        text-align: center;
        cursor: pointer;
        border-radius: 8px;
    }
    input, select, button
    {
        font: inherit;
    }
</style>
    </head>
    <body>

<canvas id="canvas" width="350" height="350"></canvas>

    <div class="quantity-block">

    <label>Начальный угол маятника</label>
    <input name="α" type="range" value="0" min="-1.57" max="1.57" step="any">

    <label> Масса шарика</label>
    <input name="m" type="number" value="1" step="any">

    <label>Длина маятника</label>
    <input name="l" type="number" value="5" step="any">

    <label>Коэффициент сопротивления окружающей среды</label>
    <input name="kf" type="number" value="0.01" step="any">

</div>

<button class="button" onclick="toggleSimulation();">Моделировать</button>

<script>
    var canvas = $("#canvas");
    var context = canvas.getContext("2d");
    context.lineWidth = 3;

    var WIDTH = canvas.width;
    var HEIGHT = canvas.height;

    var α = 0;
    var ω = 0;
    var m = 0.1;
    var g = 9.8;
    var l = 0.5;
    var kf = 1;
    var M = 0;

    var isSimulationOn = false;
    var lastT = performance.now();

    function $(selector, context)
    {
        return (context || document).querySelector(selector);
    }

    function $$(selector, context)
    {
        return Array.from((context || document).querySelectorAll(selector));
    }

    function draw(t)
    {
    requestAnimationFrame(draw);
    var dt = Math.min(1 / 24, (t - lastT) / 1000);
    lastT = t;

    if(isSimulationOn)
    {
    α += dt * ω;
    ω += dt * (- g / l * Math.sin(α) - kf * l / m * ω * ω * Math.sign(ω) + M / m / l / l);
    }

    var angle = α + Math.PI / 2;
    var size = Math.min(WIDTH, HEIGHT);
    var ox = WIDTH / 2;
    var rPend = size * 0.45 * Math.tanh(0.5 * l);
    var rBall = size * 0.05 * Math.tanh(0.5 * m);
    var x = ox - rPend * Math.cos(angle);
    var y = rPend * Math.sin(angle) + 2;

    context.clearRect(0, 0, WIDTH, HEIGHT);
    context.beginPath();
    context.arc(x, y, rBall, 0, Math.PI * 2);
    context.fill();

    context.moveTo(0, 2);
    context.lineTo(WIDTH, 2);
    context.moveTo(ox, 0);
    context.lineTo(x, y);
    context.stroke();
    }

    function updateVariables()
    {
    $$(".quantity-block input[name]").forEach(function (input)
        {
            assignVariable(input.name, input.value);
        });
    }

    function assignVariable(name, value)
    {
        if (name in window)
        {
            window[name] = Number(value);
            if (name === "α") ω = 0;
            if (name === "l" || name === "m") window[name] = Math.max(0.01, window[name]);
        }
    }

    function toggleSimulation()
    {
        isSimulationOn = !isSimulationOn;
        $(".button").textContent = isSimulationOn ? "Остановить" : "Моделировать"
        updateVariables();
    }

    $(".quantity-block").addEventListener("input", function (event)
    {
        var input = event.target;
        if (input.matches("input[name]"))
        {
            assignVariable(input.name, input.value);
        }
    });
    requestAnimationFrame(draw);
    toggleSimulation();

</script>
      </body>
     </html>

Ответы (0 шт):