MatLab: parfeval () не вызывает функцию - PullRequest
1 голос
/ 07 ноября 2019

Я пытаюсь обработать данные с UDP-сервера, близкие к реальному времени.

Для этого я написал этот код MatLab для заполнения буфера UDP-дейтаграммами и обработки данных (разделения строк и т. Д.)как только буфер из моей функции MatLab заполнится (myBuffer).

Во время обработки данных (что занимает около 0,9 с) мне нужно продолжать получать данные и сохранять их в (теперь) опустошенном буфере.

Я нашел функцию parfeval «Parallel Computing Toolbox», которая могла бы удовлетворить мои потребности, так как мне нужно, чтобы моя функция «ProcessData» работала в фоновом режиме.

Проблема, с которой я столкнулся, заключается в том, что я могузаставить его работать, так как функция parfeval не входит в мою функцию ProcessData. Я проверил это с установкой точки останова в ProcessData (), но программа никогда не останавливается. Я что-то не так сделал с параметрами функции?

Вот что говорит справка MatLab: F = parfeval (p, fcn, numout, in1, in2, ...) запрашивает асинхронное выполнение функции fcn на рабочемсодержится в параллельном пуле p, ожидая numout выходных аргументов и предоставляя в качестве входных аргументов in1, in2, ....

Надеюсь, вы, ребята, можете помочь мне с этой проблемой! Заранее спасибо.

function ReadVoltage

    %% Specify a Server (host name or IP address) with Port 8080
    u = udp('192.168.0.164', 8080);  %UDP Object Zuhause
    %u = udp('169.254.38.221', 8080);  %UDP Object Pilotfabrik    

    % Buffer in the enclosing function
    myBuffer = {};  %Initialisierung
    MAXBUFFLEN = 100; %Maximale Anzahl an Eintraegen in Buffer (1 Eintrage = 1 Datagram)

    u.InputBufferSize = 4060; 
    u.ReadAsyncMode = 'continuous';
    u.DatagramReceivedFcn = @DatagramReceivedFcn;
    u.ErrorFcn = @ErrorFcn;
    u.DatagramTerminateMode = 
    u.Terminator = '!';

    %% Initialize Parallel pool 
    pool = gcp();

    %% Oeffnen der Verbindung
    fopen(u);

     if (~strcmp(u.Status,'open'))
         NetworkError(u,'Connection failed!');
     end


    %% Start Data transmission by trigger
    fprintf(u, 'Requesting Data')

    %% Callback Funktion
    function DatagramReceivedFcn(u,~) 

        datagram = fscanf(u);
        disp('Data Received!');


        myBuffer{end+1} = datagram;         %Appends datagram to buffer


        [~, bufflen] = size(myBuffer);

        if bufflen < MAXBUFFLEN
            return;
        else
            f = parfeval(pool, @ProcessData, 1, myBuffer);
            myBuffer = {};               %empty Buffer
        end 

    end

    function ErrorFcn(u,~) 
        disp("An Error occured");
    end

end

function datagram_values = ProcessData(myBuffer)


    stringvalues = split(myBuffer, ";");        %Split Strings
    doublevalues = str2double(stringvalues)     %Convert Strings do Doubles

    dim_doublevalues = size(doublevalues);      %Dimension of Double Output Array

    i_max = dim_doublevalues(2)                 %Anzahl der Datenpakete
    j_max = (dim_doublevalues(3))-1             %Anzahl der Werte pro Datenpaket; -1 wegen leerem Wert nach ";" am Ende
    k_max = i_max*j_max                         %Gesamtanzahl der Werte in Buffer

    k=1;
    while k<=k_max
        for i = 1:i_max
            for j = 1:j_max
                    datagram_values(k,1)=doublevalues(1,i,j);
                    k=k+1;
            end
        end
    end

    disp(datagram_values);


end

1 Ответ

1 голос
/ 07 ноября 2019

К сожалению, отладчик MATLAB не может остановиться в коде, работающем на рабочих - только код, работающий на клиенте.

В этом случае вы должны попытаться посмотреть на дневниковый вывод будущего f, например:

f = parfeval(...);
wait(f); % wait for the worker to complete
disp(f.Diary); % display the output

Если вы не хотите блокировать клиента, вы можете использовать afterEach для вызова disp, например:

f = parfeval(...);
afterEach(f, @(f) disp(f.Diary), 0, 'PassFuture', true);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...