2015-08-08 2 views
1

Я считаю, что моя проблема как-то связана с this previous question, но я не смог исправить свою проблему своими советами.Моделирование FMM FMI, отсутствие оценки некоторых уравнений после инициализации

Вот минимальный нерабочий пример. У меня простая электрическая схема с коммутирующим переключателем в ней (разработана в openModelica). Я хочу изменить значение switch.control в зависимости от значения входного параметра. Для этого у меня есть следующий:

model MinimalNonWorkingExemple 

parameter Modelica.Blocks.Interfaces.RealInput openclose; 
Modelica.Electrical.Analog.Ideal.IdealCommutingSwitch switch; 
Modelica.Electrical.Analog.Basic.Ground G; 

equation 
connect(switch.p, G.p); 
connect(switch.n2, G.p); 
connect(switch.n1, G.p); 

switch.control = if openclose > 0.5 then true else false; 
end MinimalNonWorkingExemple; 

Примечания: Я пробовал много сочетания между параметром вводом, и т.д. ...

Я хочу сделать итеративное моделирование (например, имитировать 60 секунд системы но с 60 последовательными симуляциями 1 секунда). Это позволяет изменять входное значение (openclose) согласно другому моделированию FMU.

В результате я могу изменить значение ввода из pyFMI. (когда я его прочитал, это изменилось). Однако «новое значение» не учитывается ни в моих уравнениях.

Вот мой pyfmi сценарий:

# Import the load function (load_fmu) 
from pyfmi import load_fmu 
import numpy as np 
from pylab import * 

def simulate(model, res, startTime,finalTime, initialState): 
if res == None: 
    opts=model.simulate_options() 
    opts['initialize']=True 
else: 
    opts=model.simulate_options() 
    opts['initialize']=False 

for s in initialState: 
    model.set(s[0],s[1]) 

res = model.simulate(start_time = startTime, final_time=finalTime, options=opts) 
return res 


#main part 
model = load_fmu('MinimalNonWorkingExemple.fmu') 
switchClose = ['openclose', [0.0]] 
switchOpen = ['openclose', [1.0]] 

#Simulate an FMU 
res = simulate(model, None, 0, 50, [switchOpen]) 

v = res["openclose"] 
v2 = res["switch.control"] 

res = simulate(model, res, 50, 100, [switchClose]) 
v = np.concatenate((v,res["openclose"])) 
v2 = np.concatenate((v2,res["switch.control"])) 

res = simulate(model, res, 100, 200, [switchOpen]) 
v = np.concatenate((v,res["openclose"])) 
v2 = np.concatenate((v2,res["switch.control"])) 

print v 
print v2 

В основном я моделировать в течение 50 единиц времени, то изменить значение переменной openclose, затем имитируя снова, снова и снова переключение имитирующего. В результате я получил:

openclose:  [ 1. 1. 1. 1. 0. 0. 0. 0. 1. 1. 1. 1.] 
switch.control: [ 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1.] 

На самом деле, только набор перед первым вызовом model.simulate(...) распространяется его значение в системе.

Я попытался понять, что annotation(Evaluate = false) предложил here, но это не сработало. Я не уверен, связано ли это, потому что я действительно могу изменить свою ценность. Проблема заключается в том, что уравнения, основанные на этом параметре, кажется, оценивается только во время инициализации: -/

Любая идея/помощь была бы очень кстати ...

+0

Кажется, мы полностью удаляем уравнение if и помещаем только выбранную ветвь на основе openclose> 0.5. Однако, если вы не даете полной модели, ее сложно отладить. Вы можете попытаться переписать уравнение if в выражение if: switch.control = if openclose> 0.5, тогда true else false; –

+0

Спасибо за объяснение, я думаю, что ты прав. Изменение формы уравнения ничего не меняет: -/Я изменил свое первоначальное сообщение, чтобы предоставить минимальный нерабочий пример. Надеюсь, это поможет нам понять, как это исправить. Спасибо –

ответ

1

Насколько я могу понять, стандарт FMI говорит, что после того, как вы инициализируете модель, ваши изменения в параметрах больше не повлияют на модель. Таким образом, нужно использовать сброс и повторную инициализацию модели, чтобы изменения были снова подняты. Это, кажется, работает нормально с этим кодом:

# Import the load function (load_fmu) 
from pyfmi import load_fmu 
import numpy as np 
from pylab import * 

def simulate(model, res, startTime,finalTime, initialState): 
    if res == None: 
    opts=model.simulate_options() 
    opts['initialize']=True 
    else: 
    model.reset() 
    opts=model.simulate_options() 
    opts['initialize']=True 

    for s in initialState: 
    model.set(s[0],s[1]) 

    res = model.simulate(start_time = startTime, final_time=finalTime, options=opts) 
    return res 


#main part 
model = load_fmu('MinimalNonWorkingExemple.fmu') 
print model.get_description() 
model.set_log_level(7) 
switchClose = ['openclose', [0.0]] 
switchOpen = ['openclose', [1.0]] 

#Simulate an FMU 
res = simulate(model, None, 0, 50, [switchOpen]) 

v = res["openclose"] 
v2 = res["switch.control"] 

res = simulate(model, res, 50, 100, [switchClose]) 
v = np.concatenate((v,res["openclose"])) 
v2 = np.concatenate((v2,res["switch.control"])) 

res = simulate(model, res, 100, 200, [switchOpen]) 
v = np.concatenate((v,res["openclose"])) 
v2 = np.concatenate((v2,res["switch.control"])) 

print v 
print v2 

Результат является:

[ 1. 1. 1. 1. 0. 0. 0. 0. 1. 1. 1. 1.] 
[ 1. 1. 1. 1. 0. 0. 0. 0. 1. 1. 1. 1.] 

Вы можете увидеть также обсуждение здесь: http://ext5.modelon.ideon.se/5858

Это может также работать, если вы сделаете openclose входной сигнал (без параметра), а затем дать входной объект для моделирования (openclose, time, value), как в примере здесь: http://www.jmodelica.org/assimulo_home/pyfmi_1.0/pyfmi.examples.html#module-pyfmi.examples.fmu_with_input Ho wever, я не пробовал, чтобы он не работал.

+0

Привет, еще раз спасибо за помощь. Сброс и восстановление состояния модели было обходным путем, которое я уже экспериментировал, но в некоторых случаях это не удается. (Например, для следующей модели openmodelica: * Modelica :: Mechanics :: MultiBody :: Примеры :: Systems :: RobotR3 :: fullRobot * со следующей ошибкой: 'params [i] = model.get (i) Файл «fmi.pyx», строка 227, в файле pyfmi.fmi.ModelBase.get (src/pyfmi/fmi.c: 4099) Файл «fmi.pyx», строка 3612, в файле pyfmi.fmi.FMUModelBase2._get (src/pyfmi/fmi.c: 31666) pyfmi.fmi.FMUException: Тип не поддерживается ' , так что, хотя это было неправильное решение. –

+0

Я также попытался с решением * input object *, но результат такой же, в исходном сообщении ... Если сброс - это единственный способ, я сделаю это, но во время симуляции потребуется большое количество времени. ** Однако мне очень важно представить «volatile variable» в modelica, чтобы в полной мере использовать FMU и совместное моделирование. ** Как вы думаете? Еще раз спасибо –

+0

Редактирование: * сохранение, восстановление и восстановление * отлично работает для некоторых простых моделей. Для более сложной модели, такой как * FullRobot *, упомянутой в предыдущем комментарии, она терпит неудачу: -/ после исключения ошибки при восстановлении и сохранении (тип перечисления не может быть установлен и проблемы с ключом). Я получил два разных моделирования в зависимости от того, один вызов модели.simulate (...) или в двух последовательных вызовах ... Я думаю, что я открою еще один вопрос, но было бы здорово включить модификацию определенных переменных из FMU :) большое спасибо за вашу помощь –