Использование java BufferedRead в Matlab с подключением TCP / IP Ethernet - доступ к самым последним данным - PullRequest
1 голос
/ 06 марта 2012

В настоящее время я пишу код MATLAB для управления инструментами, установленными на конце манипулятора.Я получаю доступ к позиционным данным робота через соединение TCP / IP Ethernet.Ком работают.Данные передаются в пакетах файлов XML.Я написал скрипт синтаксического анализа для извлечения правильных данных из потока.

Однако, когда я пытаюсь добавить больше команд (например, для управления инструментами), мой код работает неправильно.Проблема в том, что буфер заполняется определенным (большим) объемом данных от робота, и когда я вызываю команду in.readLine, он читает следующую строку буфера, а не самую последнюю строку, полученную по соединению.Если программа была занята другими делами (смоделированными с помощью команды pause(0.01), то отображаемые позиционные данные могут сильно отставать от того, где на самом деле находится робот. Если робот остается неподвижным, данные в конечном итоге, однако, догоняют. Команды нетсбросить BufferedReader, и я не могу найти способ использовать команды сброса и пометки для работы, поскольку это, кажется, сбрасывает в более раннюю строку данных в буфере. Есть ли способ доступасамые последние данные в буфере, который постоянно обновляется из коммуникаций Ethernet?

Я не могу удалить буфер и создать новый, так как это разрывает соединение с роботом и вызывает сбой его программы.

Извините за приведенный ниже код, он находится в стадии разработки, поэтому извините за грубость и готовность. Код, закомментированный с помощью команд mark и reset, является лишь одной попыткой их использования, которую я пробовал. Iтакже пытался поиграть с размером буфера, чтобы он постоянно переполняли сам "сбросить", но даже с размером буфера, установленным на его наименьшее из 1, проблема все еще сохраняется.

clear all; close all; clc;
import java.net.*;
import java.io.*;
import java.lang.System;

PORT = 6008;

try
    server_socket = ServerSocket(PORT);
    disp('Server started, awaiting connections...')

    client_socket = server_socket.accept;
    in = BufferedReader(InputStreamReader(client_socket.getInputStream));

%    m = in.markSupported;
%     if(m == 1)
%         disp('Mark supported');
%     end
%    in.mark(8192);

    while 1
        XMLdata = in.readLine;                    %Reads the next line in the buffer
        [test, bin]=strtok(char(XMLdata));        %
         if strcmp(test, '<RIst') == 1            %Tests to see if it is a line with positional data
             rsi_parse                            %If so, parses the data into an array
%             in.reset;
%             in.mark(8192);
         end
         pause(0.01)                             %Pause to simulate other commands which cause the buffer to fill up
    end

catch
    disp('Error. Closing connection.')
    closeConnections(server_socket, client_socket, in);
end

Ответы [ 2 ]

0 голосов
/ 06 марта 2012

Звучит так: «Как я могу гарантировать, что я читаю самые последние данные из моего входного потока, отбрасывая данные при необходимости».

Если это так, то вы захотите расширить свою часть кода для приема данных с помощью внутреннего цикла while:

    while 1
        %
        %  Read until we find the end of the buffer
        %
        XMLdata = in.readLine;  %Reset current line
        foundData = nan;        %Reset value found
        while ~isempty(XMLdata)                 %Loop to the end of the buffer
            [test, bin]=strtok(char(XMLdata));  %Line testing, as before
            if strcmp(test, '<RIst') == 1       
                foundData = rsi_parse           %Store the found data, we may get a more recent version
            end
            XMLdata = in.readLine;              %Try and read another line
        end
        %Do something with foundData

        %
        %Go and perform other work
        %
        pause(0.01)                             %Go and do something else
    end

В связи с вашим комментарием, что вы не можете "очистить" BufferedReader, я думаю, что вы можете, как это:

charactersSkipped = in.skip(1000000000);

(Если вы писали непосредственно на Java, вы должны использовать in.skip(java.lang.Long.MAX_VALUE);, но это нарушает интерфейс Matlab / Java и отправляется на Java в виде отрицательного числа, поэтому вам просто нужно выбрать наибольшее число, которое вам удобно набирать .)

Но после того, как вы его очистили, нет четкого способа выполнить резервное копирование, пока не найдете искомый образец персонажа.

0 голосов
/ 06 марта 2012

В настоящее время вы используете MATLAB для запуска Java в качестве языка сценариев, что является отличной возможностью.При этом вы наследуете «единственное» главное ограничение MATLAB, оно однопоточное.Есть обходные пути, такие как таймеры, но в его основе только один поток.

Чтобы получать самые последние данные от вашего робота, вам, кажется, приходится непрерывно читать данные из потока данных.Этого можно достичь, создав чистый класс Java, охватывающий поток, который непрерывно считывает данные из вашего сокета и обновляет свойство класса самыми последними данными.Класс Java должен быть скомпилирован с использованием javac, чтобы создать файл класса, который может быть создан как объект в MATLAB.Помимо метода start и stop он должен предоставлять метод getLatestDate (), который вызывается из сценария MATLAB для получения последних данных.

...