Управление сценарием Matlab (Пауза, Сброс) - PullRequest
8 голосов
/ 24 февраля 2011

Я пытаюсь создать сценарий matlab (m-файл), который должен управляться внешним сценарием VBA.

Сценарий matlab должен выполнять одну и ту же операцию каждый раз (даже изменение параметров, но этоне в этом дело) для определенного числа циклов.Если я вижу это правильно, я могу использовать функции Matlab в VBA следующим образом: http://www.mathworks.de/help/techdoc/matlab_external/f135590.html#f133975

Моя главная проблема заключается в том, как реализовать часть Matlab этой проблемы ... в настоящее время моя часть управления выглядит следующим образом:

start.m:

run = 1;
reset = 0;
while run ~= 0     % Loop until external reset of 'run' to '0'
    if reset ~= 0
        doReset();   % Reset the parameters for the processing
        reset = 0;
        disp('I did a reset');
    end

    disp('I am processing');
    doProcess();
    pause(1)
end
disp('I am done');

Компонент сброса работает очень хорошо при изменении значения скриптом, но когда я пытаюсь вручную изменить значение'выполнить' или 'сбросить' до любого другого значения в моей рабочей области, ничего не происходит ... мой сценарий не прерывается, а также не выполняется сброс, если он работает ... мне кажется, что сценарий не распознаетлюбые изменения в рабочей области?!

позже переменные 'run' и 'reset' должны быть установлены или сброшены сценарием VBA.Есть ли какая-либо правдоподобная причина, по которой я не могу прервать цикл вручную?

Спасибо за любой совет!

привет, поэшлорн

Редактировать:

Кажется, что скрипт загружает переменные один раз перед запуском и никогда больше во время выполнения ... есть ли возможность иметь явный доступ к переменной рабочей области?

Редактировать 2:

В настоящее время я использую Matlab 2010b без дополнительных наборов инструментов

Редактировать 3:

Я обнаружил, что есть несколько 'рабочие пространства или ОЗУ в Matlab.Если моя функция запущена, переменные хранятся в «базовом» (?) Рабочем пространстве, которое не является рабочим пространством matlab, в котором вы можете щелкнуть и изменить каждое значение.Поэтому я должен получить доступ к этому зловещему «базовому» пространству и изменить флаг «run» на ноль.

Ответы [ 3 ]

4 голосов
/ 01 марта 2011

Полагаю, ваша проблема в том, что ваш цикл блокирует выполнение внешнего интерфейса.Во время выполнения цикла вы не можете получить доступ к другим интерфейсам.

Я хотел сделать аналогичную вещь - разрешить управление циклом Matlab внешней программой (либо Ruby, либо другим экземпляром Matlab).Наиболее гибким решением на сегодняшний день было использование UDP.Существует отличный набор инструментов под названием PNET для matlab, и я предполагаю, что VB также должен иметь библиотеку сокетов.Я просто открываю UDP-порт с обеих сторон и использую простые текстовые команды для управления и обратной связи.

obj.conn = pnet('udpsocket', 9999);
command = '';
while run ~= 0
    nBytes = pnet(obj.conn, 'readpacket');
    if nBytes > 0
        command = pnet(obj.conn, 'read', nBytes, 'string');
    end
    switch command
        case '--reset--'
            doReset();   % Reset the parameters for the processing
            reset = 0;
            disp('I did a reset');
        case '--abort--'
            run = 0;
            disp('Going to abort');
        case '--echo--'
            pnet(obj.conn, 'write', '--echo--');
            pnet(obj.conn, 'writepacket', remoteAddress, remotePort);
    end
    doProcess();
end

Таким образом, я могу создать свой собственный расширяемый интерфейс управления, не беспокоясь о блокировке из цикла, он можетработать кроссплатформенный и кросс-языковой, может работать в машине или по сети.

ОБНОВЛЕНИЕ: Чтобы общаться между двумя клиентами UDP, вам нужно настроить два дополнительных порта UDP, оба являются клиентами (в этом примере все в Matlab, представьте, что obj здесь - это структура, в моем случае это класся оборачиваюсь вокруг функциональности pnet):

obj = struct();
obj.success = 0;
obj.client1Port = 9999;
obj.client2Port = 9998;
obj.client1Address = '127.0.0.1';
obj.client2Address = '127.0.0.1';
obj.conn1 = pnet('udpsocket', obj.client1Port);
obj.conn2 = pnet('udpsocket', obj.client2Port);

pnet(obj.conn1, 'write', '--echo--')
pnet(obj.conn1, 'writepacket', obj.client2Address, obj.client2Port);

nBytes = pnet(obj.conn2, 'readpacket');
if nBytes > 0
    command = pnet(obj.conn2, 'read', nBytes, 'string');
    if regexpi(command,'--echo--')
        obj.success = obj.success+1;
        fprintf('Client 2 recieved this message: %s\n',command);
        pnet(obj.conn2, 'write', '--echo--')
        pnet(obj.conn2, 'writepacket', obj.client1Address, obj.client1Port);
    end
end

nBytes = pnet(obj.conn1, 'readpacket');
if nBytes > 0
    command = pnet(obj.conn1, 'read', nBytes, 'string');
    if regexpi(command,'--echo--')
        obj.success = obj.success+1;
        fprintf('Client 1 got this back: %s\n',command);
    end
end

if obj.success == 2
    fprintf('\nWe both sent and received messages!\n');
end
1 голос
/ 04 марта 2011

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

@ Адам Ледбеттер: Спасибо, это имеет смысл.Единственная проблема, с которой я сталкиваюсь - это приостановить (после этого сброса и затем возобновить) сценарий, когда он был запущен командой run = 1 в качестве параметра ... - poeschlorn 25 февраля в 7:17

Если вы хотите выйти из цикла, как только сброс был установлен на единицу, а затем подождать, пока цикл не продолжится снова после run = 1, это почти то же самое, что просто начать заново?

function processRun()
run = 1;
while run ~= 1
   run = doProcess();
end

если doProcess() возвращает 0, тогда функция processRun() завершится (как и поведение, которое вы хотите иметь при сбросе), при следующем вызове processRun она начинается снова со значениями "сброс" / значения по умолчанию,

Или я что-то упустил?

1 голос
/ 24 февраля 2011

Является ли ваш сценарий m-файлом сценария или функцией?

Если это функция, вы потеряете область действия переменных рабочей области, поэтому она не работает.Я бы превратил ваш код в функцию, подобную этой:

  function processRun(run,reset)
    while run ~= 0     % Loop until external reset of 'run' to '0'
      if reset ~= 0
        doReset;   % Reset the parameters for the processing
        reset = 0;
        disp('I did a reset');
      end

      disp('I am processing');
      [run,reset]  =  doProcess;
      pause(1)
    end

Затем вы можете устанавливать значения запуска и сброса каждый раз, когда вызываете функцию из VBA.

Если у вас есть скриптпопробуйте удалить строки запуска и сброса сверху и установить их значения в рабочей области перед запуском сценария.Я думаю, что вы перезаписываете свои значения рабочей области, запуская файл сценария.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...