Загрузка данных


Мы нашли причину: SimulateAllActive прерывал всю симуляцию, если хотя бы одна подвеска не могла быть рассчитана. Это блокировало запуск остальных, даже если они были готовы.

Теперь SimulateAllActive не возвращает FALSE и не прерывается при ошибке одной подвески. Для активных подвесок (в линии) мы всё равно обязаны симулировать их, но если симуляция не удалась, мы просто не добавляем их планы в глобальный массив. Для новых подвесок (на позиции 0) симуляция будет вызвана позже в SelectAndMove, и если она не пройдёт, подвеска просто не станет кандидатом.

Вот исправленный метод SimulateAllActive:

pascal
METHOD SimulateAllActive : BOOL
VAR
    a : INT;
    i : INT;
BEGIN
    // ----------------------------------------------------------------------------
    // БЛОК 1: СИНХРОНИЗАЦИЯ ПЛАНОВ С ФИЗИЧЕСКИМ СОСТОЯНИЕМ ЛИНИИ (АЛГОРИТМ Б)
    // ----------------------------------------------------------------------------
    FOR i := 1 TO 17 DO 
        IF GVL.vanBusy[i] THEN 
            GVL.planVatBusyUntil[i] := MAX(GVL.vanEndTime[i], GVL.sysTime); 
        ELSE 
            GVL.planVatBusyUntil[i] := GVL.sysTime; 
        END_IF;
    END_FOR;

    // ----------------------------------------------------------------------------
    // БЛОК 2: КАСКАДНОЕ НАКОПЛЕНИЕ ПЛАНОВ АКТИВНЫХ ПОДВЕСОК
    // ----------------------------------------------------------------------------
    FOR a := 1 TO 4 DO
        IF (GVL.podveskas[a].currentStep >= 0) AND (GVL.podveskas[a].currentPos <> 0) THEN
            // Симулируем, но если не получилось – просто пропускаем,
            // не прерывая весь цикл и не блокируя остальные подвески
            IF EvaluatePodveska(podveska := GVL.podveskas[a]) THEN
                FOR i := 1 TO 17 DO
                    GVL.planVatBusyUntil[i] := MAX(GVL.planVatBusyUntil[i], GVL.podveskas[a].simBusyUntil[i]);
                    GVL.planVatStartTime[i] := MAX(GVL.planVatStartTime[i], GVL.podveskas[a].simStartTime[i]);
                END_FOR;
            END_IF;
        END_IF;
    END_FOR;

    // Симуляция всегда завершается успешно, даже если отдельные подвески не прошли проверку.
    // Решение о допуске к движению принимает SelectAndMove.
    SimulateAllActive := TRUE;
END_METHOD
Что изменилось: убрано IF NOT EvaluatePodveska(...) THEN SimulateAllActive := FALSE; RETURN;. Теперь ошибка симуляции одной подвески не парализует всю линию.

Метод SelectAndMove (и новый CyclicCall) остаются без изменений, так как они уже корректно обрабатывают случай, когда EvaluatePodveska возвращает FALSE для конкретной подвески, и просто не делают её кандидатом.

После этого исправления третья подвеска не будет «зависать», а линия продолжит обрабатывать остальных.