Why I'm obtaining NaN in the output of a simple FMU exported from Simulink and tested in Python 3? - simulink

I'm new to the FMI standard and FMUs. I'm trying to export a FMU of a simple Simulink model, the Ohm's law in my case, to test the funcionality of the FMI standard in Python. I'm obtaining NaN in the output of this simple FMU exported from Simulink and tested in Python 3.
In the next model I'm defining 2 inputs (Voltage and Resistance), a division and 1 output (Current). Then, I export the FMU by clicking on Save As > Export Model To > Standalone FMU. Note I'm configuring fixed-step size in the model settings. I've also tested exporting the FMU from the Command Window with the following line:
exportToFMU2CS('OhmLaw')
The FMU is exported correctly, but when I go to test it in Python 3 with a Jupyter notebook, I'm not obtaining the expected output. As shown below, for the input values V=10 and R=2, the simulation returns I=NaN. I'm also pasting the minimal code:
from pyfmi import load_fmu
model = load_fmu('OhmLaw.fmu')
model.set('Voltage', 10)
model.set('Resistance', 2)
res = model.simulate(final_time=1, input=(), options={'ncp': 1})
model.get('Current')
I've tested with different data types in all blocks (auto, int32 and double), but I'm still not able to achieve the correct result.
Does anyone know what's happening here? I'm using MATLAB R2022a in Windows 10.
UPDATE. Finally, I've been able to simulate the FMU with the FMPy library in Python. Note that "pip install fmpy" is giving problems, so I've installed it with "conda install -c conda-forge fmpy" and used a Jupyter Notebook.

I assume that the model get's evaluated in initialization mode before the inputs are set. Does the Simulink FMU export allow for setting start values for the inputs? Then set them to a nonzero value.

You just need to set start values before dividing by 0 happens. It can be done in fmpy (do not confuse with pyfmi) in the following way:
import fmpy
fmu_filename = 'Ohm.fmu'
def simulate_with_start_values():
# calculate the parameters for this run
start_values = {'Voltage': 10.0, 'Resistance': 2.0, }
# simulate the FMU
result = fmpy.simulate_fmu(fmu_filename,
start_values=start_values,
start_time=0.0,
stop_time=1.0)
# plot Current output
fmpy.util.plot_result(result)
if __name__ == "__main__":
simulate_with_start_values()
Then you get your Current output right:
results_chart

Related

Simulink Design Verifier: Input argument #1 is an invalid cvdata object

I am trying to run a few tests on a very simple Simulink model on Matlab 2020a.
I have obtained test results by using the Test Manager app, which allows me to set up a test case.
The function I created is very simple, it just checks two boolean values and returns another boolean value in accordance to their own value, so I have not reported it here.
My procedure is as follows:
From Simulink Test Manager -> New Test File -> Test For Model Component -> Importing both Top Model and Component to create a Harness -> Using Design Verifier options (with the only changes from the default values being (1) Test Generation -> Model Coverage Objectives : MCDC ; and (2) Report -> Generate report of results) and IMPORTING Test harness inputs as a source -> Use component under test output as baseline -> saving data as an Excel sheet.
Tests are then generated and everything is working fine.
I then use a small python script to edit the Excel file, generating an Oracle with a structure like this:
time Var_A Var_B time Out1:1
AbsTol:0
type:boolean type:boolean Type:int8
Interp:zoh Interp:zoh Interp:zoh
0 0 1 0 0
0.4 1 1 0.4 1
0.8 0 0 0.8 TRUE
After this, I have to let Simulink write a PDF report of the project. To do so, I set up the following options:
From the test harness:
Inputs -> Include input data in test result; Stop simulation at last time point;
Baseline Criteria -> Include baseline data in test result;
Coverage Settings -> Record coverage for system under test; Record coverage for referenced models;
From the top level test folder:
Coverage Settings -> Record coverage for system under test; Record coverage for referenced models;
Coverage Metrics: Decision; Condition; MCDC;
Test File Options-> Close all open figures at the end of execution; Generate report after execution (with author and file path); Include Matlab version; Results for: All tests; Test Requirements; Plots of criteria and assessments; Simulation metadata; Error log and messages; Coverage results; File format PDF.
Then I let it run. The test manager tells me everything went fine, but for some reason, whenever it has to create a report, it throws me an error:
X_component_test: Input argument #1 is an invalid cvdata object. CVDATA objects become invalid when their associated models are closed or modified
Now, I am sure this worked fine before with much more complex components, but I have no idea what am I doing wrong here. Anyone got a clue?
In the end, the solution was much more simple than I thought. Just delete all .cv files and clean up your project's folder of all test files or unnecessary files. Matlab seems to have issues when there's way too many present.
Also the script had to be modified to remove that TRUE value and replace it with a 1.

Import Beckhoff twinCAT scope view csv format into Matlab

I try to import data from twinCAT into matlab for analyzing.
I have tried it with the code:
Tb = readtable('LogTestScopeView1.csv');
But that didn't work. I guess the header of a twinCAT csv-file is a bit more complicated.
Have someone experience with this?
Already many thanks.
This might depend on the header configuration you choose in the TwinCAT Scope Export Wizard. E.g. when choosing "Name only header" the readtable() command worked fine for me. Also, I selected "Comma" as CSV-Separator and "Point" as Decimal mark (see this
Measurement Export Wizard screenshot)
If you just need to quickly analyze the data and don't need code to automate this process, you can also use Matlab's import tool (Home -> Import Data), where you can interactively select the data to import.

Referencing External Files in JModelica

I have a Modelica file that references c code during simulation through an external library *.a file.
For example:
model CallAdd
input Real FirstInput(start=0);
input Real SecondInput(start=0);
output Real FMUOutput(start=0);
function CAdd
input Real x(start=0);
input Real y(start=0);
output Real z(start=0);
external "C" annotation(Library = "CAdd", LibraryDirectory = "modelica://CallAdd");
end CAdd;
equation
FMUOutput = CAdd(FirstInput,SecondInput);
annotation(uses(Modelica(version = "3.2.1")));
end CallAdd;
When opening the Modelica model in OpenModelica the required files appear to be automatically loaded because it simulates and gives appropriate results.
However, when I try to compile the Modelica file with JModelica-SDK-1.12 I receive an error that the library *.a file could not be found.
So my question is: What is the proper way to reference additional files when using compile_fmu in JModelica?
With no success, I've tried:
# Import the compiler function
from pymodelica import compile_fmu
model_name = "CallAdd"
mo_file = "CallAdd.mo"
# Compile the model and save the return argument, for use later if wanted
my_fmu = compile_fmu(model_name, mo_file, target="cs",compiler_options = {'extra_lib_dirs':'C:/ToFolderContainingLib/'})
The strange thing is that when I was using JModelica-1.17 (non-SDK) the file compiled fine but the results didn't make sense. I was recommended to try the SDK version to see if it fixed my errors in my previous post here.
Try positioning the external library in sub-folder named as the platform your currently on. So in your example, I'd position the library (libCAdd.a) in sub-folder named linux64, as I'm on a 64bit Linux machine and then run the code.
If is a small piece of C code, as a last alternative you could try to include the C file directly in the Modelica code:
external "C" annotation(Include="
// the entire C code here
");
Hopefully the JModelica people will give you a better answer soon.
You could try to ask this on their website also:
http://www.jmodelica.org/forum

Caffe web demo error when running a model trained on Digits

I trained a neural network model on Digits and it seemed to run fine there.
Then i exported the trained model files and copied them into a different system running the standard caffe web demo.
I hoped to just be able to plug those files in and have them run in Caffe but i am getting an error.
Specifically I copied my model into bvlc_reference_caffenet.caffemodel, the deploy.prototxt into deploy.prototxt, and the mean.binaryproto into the ilsvrc_2012_mean.npy file.
However when I try to run it , it appears to not like the format of the mean.binaryproto file as indicated by the error message:
IOError: Failed to interpret file '/home/vagrant/caffe/python/caffe/imagenet/ilsvrc_2012_mean.npy' as a pickle
what am I doing wrong here? Do I need to process the mean.binaryproto file from Digits somehow before I use it with caffe?
You need to convert the .binaryproto file to a numpy file.
There is a nice example here using caffe.io and caffe.proto.

programmatically add cells to an ipython notebook for report generation

I have seen a few of the talks by iPython developers about how to convert an ipython notebook to a blog post, a pdf, or even to an entire book(~min 43). The PDF-to-X converter interprets the iPython cells which are written in markdown or code and spits out a newly formatted document in one step.
My problem is that I would like to generate a large document where many of the figures and sections are programmatically generated - something like this. For this to work in iPython using the methods above, I would need to be able to write a function that would write other iPython-Code-Blocks. Does this capability exist?
#some pseudocode to give an idea
for variable in list:
image = make_image(variable)
write_iPython_Markdown_Cell(variable)
write_iPython_Image_cell(image)
I think this might be useful so I am wondering if:
generating iPython Cells through iPython is possible
if there is a reason that this is a bad idea and I should stick to a 'classic' solution like a templating library (Jinja).
thanks,
zach cp
EDIT:
As per Thomas' suggestion I posted on the ipython mailing list and got some feedback on the feasibility of this idea. In short - there are some technical difficulties that make this idea less than ideal for the original idea. For a repetitive report where you would like to generate markdown -cells and corresponding images/tables it is ore complicated to work through the ipython kernel/browser than to generate a report directly with a templating system like Jinja.
There's a Notebook gist by Fernando Perez here that demonstrates how to programmatically create new cells. Note that you can also pass metadata in, so if you're generating a report and want to turn the notebook into a slideshow, you can easily indicate whether the cell should be a slide, sub-slide, fragment, etc.
You can add any kind of cell, so what you want is straightforward now (though it probably wasn't when the question was asked!). E.g., something like this (untested code) should work:
from IPython.nbformat import current as nbf
nb = nbf.new_notebook()
cells = []
for var in my_list:
# Assume make_image() saves an image to file and returns the filename
image_file = make_image(var)
text = "Variable: %s\n![image](%s)" % (var, image_file)
cell = nbf.new_text_cell('markdown', text)
cells.append(cell)
nb['worksheets'].append(nbf.new_worksheet(cells=cells))
with open('my_notebook.ipynb', 'w') as f:
nbf.write(nb, f, 'ipynb')
I won't judge whether it's a good idea, but if you call get_ipython().set_next_input(s) in the notebook, it will create a new cell with the string s. This is what IPython uses internally for its %load and %recall commands.
Note that the accepted answer by Tal is a little deprecated and getting more deprecated: in ipython v3 you can (/should) import nbformat directly, and after that you need to specify which version of notebook you want to create.
So,
from IPython.nbformat import current as nbf
becomes
from nbformat import current as nbf
becomes
from nbformat import v4 as nbf
However, in this final version, the compatibility breaks because the write method is in the parent module nbformat, where all of the other methods used by Fernando Perez are in the v4 module, although some of them are under different names (e.g. new_text_cell('markdown', source) becomes new_markdown_cell(source)).
Here is an example of the v3 way of doing things: see generate_examples.py for the code and plotstyles.ipynb for the output. IPython 4 is, at time of writing, so new that using the web interface and clicking 'new notebook' still produces a v3 notebook.
Below is the code of the function which will load contents of a file and insert it into the next cell of the notebook:
from IPython.display import display_javascript
def make_cell(s):
text = s.replace('\n','\\n').replace("\"", "\\\"").replace("'", "\\'")
text2 = """var t_cell = IPython.notebook.get_selected_cell()
t_cell.set_text('{}');
var t_index = IPython.notebook.get_cells().indexOf(t_cell);
IPython.notebook.to_code(t_index);
IPython.notebook.get_cell(t_index).render();""".format(text)
display_javascript(text2, raw=True)
def insert_file(filename):
with open(filename, 'r') as content_file:
content = content_file.read()
make_cell(content)
See details in my blog.
Using the magics can be another solution. e.g.
get_ipython().run_cell_magic(u'HTML', u'', u'<font color=red>heffffo</font>')
Now that you can programatically generate HTML in a cell, you can format in any ways as you wish. Images are of course supported. If you want to repetitively generate output to multiple cells, just do multiple of the above with the string to be a placeholder.
p.s. I once had this need and reached this thread. I wanted to render a table (not the ascii output of lists and tuples) at that time. Later I found pandas.DataFrame is amazingly suited for my job. It generate HTML formatted tables automatically.
from IPython.display import display, Javascript
def add_cell(text, type='code', direct='above'):
text = text.replace('\n','\\n').replace("\"", "\\\"").replace("'", "\\'")
display(Javascript('''
var cell = IPython.notebook.insert_cell_{}("{}")
cell.set_text("{}")
'''.format(direct, type, text)));
for i in range(3):
add_cell(f'# heading{i}', 'markdown')
add_cell(f'code {i}')
codes above will add cells as follows:
#xingpei Pang solution is perfect, especially if you want to create customized code for each dataset having several groups for instance. However, the main issue with the javascript code is that if you run this code in a trusted notebook, it runs every time the notebook is loaded.
The solution I came up with is to clear the cell output after execution. The javascript code is stored in the output cell, so by clearing the output the code is gone and nothing is left to be executed in the trusted mode again. By using the code from here, the solution is the code below.
from IPython.display import display, Javascript, clear_output
def add_cell(text, type='code', direct='above'):
text = text.replace('\n','\\n').replace("\"", "\\\"").replace("'", "\\'")
display(Javascript('''
var cell = IPython.notebook.insert_cell_{}("{}")
cell.set_text("{}")
'''.format(direct, type, text)));
# create cells
for i in range(3):
add_cell(f'# heading{i}', 'markdown')
add_cell(f'code {i}')
# clean the javascript code from the current cell output
for i in range(10):
clear_output(wait=True)
Note that the clear_output() needs the be run several times to make sure the output is cleared.
As a slight update incorporating Tal's answer above, updates from Chris Barnes and a little digging in the nbformat docs, the following worked for me:
import nbformat
from nbformat import v4 as nbf
nb = nbf.new_notebook()
cells = [
nbf.new_code_cell(f"""print("Doing the thing: {i}")""")
for i in range(10)
]
nb.cells.extend(cells)
with open('generated_notebook.ipynb', 'w') as f:
nbformat.write(nb, f)
You can then start up the new artificial notebook and cut-n-paste cells where ever you need them.
This is unlikely to be the best way to do anything, but it's useful as a dirty hack. 🐱‍💻
This worked with the following versions:
Package Version
-------------------- ----------
ipykernel 5.3.0
ipython 7.15.0
jupyter 1.0.0
jupyter-client 6.1.3
jupyter-console 6.1.0
jupyter-core 4.6.3
nbconvert 5.6.1
nbformat 5.0.7
notebook 6.0.3
...
Using the command line goto the directory where the myfile.py file is located
and execute (Example):
C:\MyDir\pip install p2j
Then execute:
C:\MyDir\p2j myfile.py -t myfile.ipynb
Run in the Jupyter notebook:
!pip install p2j
Then, using the command line, go the corresponding directory where the file is located and execute:
python p2j <myfile.py> -t <myfile.ipynb>