sobota, 30 czerwca 2012

[Matlab / Simulink] Przekazywanie danych z Simulinka do workspace podczas symulacji


W większości przypadków, dane z symulacji wystarczy przekazywać do workspace bloczkiem ToWorkspace, lub przez funkcję [x.y.t] = sim(...).



Podejście to ma jedną poważną wadę : cały wektor sygnału aktualizuje się dopiero po zakończeniu symulacji. Czasami zachodzi jednak potrzeba, by przesyłać dane na bieżąco, na przykład dla symulacji z czasem końcowym nieskończoność, gdzie użytkownik zmienia sygnały z GUI.

Aby na bieżąco aktualizować w workspace pewien sygnał, można wykorzystać bloczek Embedded Matlab Function





Wewnątrz wykorzystana zostanie funkcja assignin:


function y = fcn(u)
eml.extrinsic('assignin');
assignin('base','volume_work',u);
y = 1;  


 Instrukcja eml.extrinsic importuje funkcję do Embedded Matlab. Assignin przypisuje wejście bloczka (u) do zmiennej 'volume_work' z workspace o nazwie 'base' . Jest to nazwa domyślnego workspace w Matlabie.

Do komunikacji w drugą stronę można wykorzystać funkcję evalin.

Linki:
1. Mathworks - assignin
2. Mathworks - evalin

5 komentarzy:

  1. Super! Tzn bardzo mi to pomoże :) Mam jeszcze problem z tym jak wywołać w simulinku zewnętrzny m-plik. Może napiszesz coś na ten temat? Albo chociaż pomożesz w komentażu?

    Pozdrawiam, Paweł

    OdpowiedzUsuń
  2. Witam, w tym samym bloczku Embedded MATLAB Function i także przez eml.extrinsic, np.
    eml.extrinsic('mytest');
    mytest

    Pozdrowienia

    OdpowiedzUsuń
  3. Gra! :) tylko jest jeden problem. Wyniki działania funkcji nie mogę dać na wyjście bloczku Embedded MATLAB Function

    Robie tak:
    function y = fcn(u)

    fluid='r507a';
    temp=277;
    p=u*100; % input pressure unit is [kPa]

    eml.extrinsic('refpropm');
    gestosc=refpropm('D','T',temp,'P',p,fluid); % fluid property calculation


    eml.extrinsic('assignin');
    assignin('base','rho',gestosc);

    y = rho;

    No i na y nie ma nic :) Jest błąd:Function output 'y' cannot be of MATLAB type.
    Czy tutaj muszę wykorzystać jakoś wspomniany w Twoim poście evalin? W jaki sposób? Czy linijka assign('base','rho',gestosc) jest w ogóle potrzebna?


    Dziękuję za pomoc i pozdrawiam, Paweł

    OdpowiedzUsuń
  4. Nie wiem jakiego typu aplikację piszesz. Tego posta o evalin i assignim pisałem po stworzeniu dużego projektu w Simulinku (i Stateflow), który w GUI Matlabowym wyświetlał pewne wyniki. Dlatego potrzebne mi było przekazywanie danych między Matlabem (i jego workspace), a danymi w Simulinku.

    Jeżeli chcesz tylko wykonać pewne obliczenia, które masz w funkcji refpropm, to może bardziej się opłaca przenieść ten kod do Embedded MATLAB Function. Pamiętaj, że instrukcja assignin na bieżąco aktualizuje Ci workspace w Matlabie. Pytanie czy tego potrzebujesz ? Jeżeli chcesz lub musisz mimo wszystko wołać funkcję z M-Pliku przez eml.extrinsic('refpropm') i nie potrzebujesz tego rho w workspace to usuń oczywiście assignin.

    A problem, który dostajesz polega na tym, że funkcja Matlaba zwraca inny typ niż typy w Simulinku. Zakładam, że rho to liczba. Możesz to obejść w taki sposób:

    function y = fcn(u)

    fluid='r507a';
    temp=277;
    p=u*100; % input pressure unit is [kPa]

    eml.extrinsic('refpropm');
    y = 0;
    y =refpropm('D','T',temp,'P',p,fluid); % fluid property calculation

    Dzięki przypisaniu y = 0 Simulink będzie wiedział, że wszystko co dalej przypiszesz do y ma być typu skalarnego.

    Pozdrawiam

    OdpowiedzUsuń
  5. Wszystko działa. Zwykłe zainicjowanie zerem pomaga (nie mogę uwierzyć)... Dzięki jeszcze raz!

    OdpowiedzUsuń