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


    // Только при предварительной симуляции заполняем личные планы из глобальных
    IF NOT commit THEN
        FOR i := 1 TO 17 DO
            podveska.simFreeTime[i] := GVL.planVatFreeTime[i];
            podveska.simBusyUntil[i] := GVL.planVatBusyUntil[i];
            podveska.simStartTime[i] := DT#1970-01-01-00:00:00;   // сброс для будущего заполнения
        END_FOR;
    END_IF;

    // Начальный момент времени (как и раньше)
    IF (podveska.currentStep >= 0) AND (podveska.currentPos >= 1) AND (podveska.currentPos <= 17) THEN
        arrivalTime := MAX(GVL.sysTime, GVL.vanEndTime[podveska.currentPos]);
    ELSE
        arrivalTime := GVL.sysTime;
    END_IF;

    prevVat := podveska.currentPos;
    step := podveska.currentStep + 1;

    WHILE step <= 14 DO
        vat := GetVatFromRecipe(podveska.processType, step);
        IF vat = 0 THEN EXIT; END_IF;

        // Транспорт к ванне
        srcIdx := MapToTransitIndex(prevVat);
        transitTime := REAL_TO_TIME(PV.transitTimed[srcIdx, vat] * 1000.0);
        arrivalTime := arrivalTime + transitTime;

        // Технологическое время
        IF podveska.processType = E_RouteType.eTin THEN
            techTime := TargetVars.recipeTin[step].duration;
        ELSE
            techTime := TargetVars.recipeSilver[step].duration;
        END_IF;

        // Вычисляем время выезда
        IF step < 14 THEN
            nextVat := GetVatFromRecipe(podveska.processType, step + 1);
            IF nextVat <> 0 THEN
                transitOut := REAL_TO_TIME(PV.transitTimed[vat, nextVat] * 1000.0);
            ELSE
                transitOut := T#0s;
            END_IF;
        ELSE
            transitOut := T#0s;
        END_IF;

        // Время старта
        IF commit THEN
            // При фиксации плана используем уже рассчитанные личные планы
            startTime := podveska.simStartTime[vat];
            IF startTime = DT#1970-01-01-00:00:00 THEN
                // Если не заполнено – аварийный случай, считаем по стандартной логике
                startTime := MAX(arrivalTime, podveska.simFreeTime[vat]);
            END_IF;
        ELSE
            // При симуляции рассчитываем startTime как обычно
            startTime := MAX(arrivalTime, podveska.simFreeTime[vat]);
            // Проверка на пересечение окон
            IF (podveska.simBusyUntil[vat] > DT#1970-01-01-00:00:00) THEN
                IF (startTime < podveska.simBusyUntil[vat]) AND 
                   ((startTime + techTime + transitOut) > podveska.simBusyUntil[vat]) THEN
                    EvaluatePodveska := FALSE;
                    RETURN;
                END_IF;
            END_IF;
        END_IF;

        waitTime := startTime - arrivalTime;

        // Проверка лимита ожидания (только при симуляции)
        IF (NOT commit) AND (waitTime > maxWait) THEN
            EvaluatePodveska := FALSE;
            RETURN;
        END_IF;

        endTime := startTime + techTime;

        // Сохраняем в структуру подвески
        podveska.simStartTime[vat] := startTime;
        podveska.simFreeTime[vat] := endTime + transitOut;
        podveska.simBusyUntil[vat] := endTime + transitOut;

        // При commit := TRUE обновляем глобальные планы точечно
        IF commit THEN
            GVL.planVatFreeTime[vat] := MAX(GVL.planVatFreeTime[vat], endTime + transitOut);
            GVL.planVatBusyUntil[vat] := MAX(GVL.planVatBusyUntil[vat], endTime + transitOut);
        END_IF;

        arrivalTime := endTime;
        prevVat := vat;
        step := step + 1;
    END_WHILE;

    EvaluatePodveska := TRUE;