Simulink: choosing an Arduino Digital Output based on a workspace variable - matlab

I have a Simulink model, the controller part of which I'm trying to code onto an embedded controller. Following the example here I can toggle any specific pin, but appropriately setting the Pin number parameter of the Arduino Digital Output block.
However, I would like to set this parameter to a variable name which is available in the workspace (for example myPinNumber), doing so in the example works as expected, i.e. if I set myPinNumber = 13 in the workspace, and set the Pin number parameter of the block to myPinNumber it behaves the same as if I'd directly written 13 in the block, all good.
However, it does not work when I try to set the Pin Number parameter to an element of an array. For example if I define myPinNumbers = [12 13 14], and try to set the Pin Number parameter of the Digital Output block to pinNumber(2) I get the following error:
Error in 'model_folder/model_name/Digital Output1': Initialization commands cannot be evaluated.
Caused by:
Digital Output block parameter Pin number must be an integer between 0 and 53.
Component: Simulink | Category: Block error
Most other blocks in Simulink would allow setting a parameter value to a particular element of a work-space array in this way. Does anyone know of a fix/work-around?

Related

Matlab script: Display the outputs of my Simulink model

I have the following Simulink model:
I have the following script:
Constant=43;
Constant1=43;
Constant2=43;
Constant3=43;
Constant4=43;
Constant5=43;
Constant6=43;
Constant7=43;
Constant10=43;
Constant11=43;
In1=[1,2,3];
In2=[4,5,6];
t_stop = 10;
T_s = t_stop/1000;
options = simset('solver', 'ode5', 'fixedstep', T_s);
sim('test_lau.slx',t_stop,options)
I want to display and eventually call the outputs Display, Display2 and Display3.
I tried changing the last line to:
[Display, Display2, Display3]=sim('test_lau.slx',t_stop,options)
But get the error:
Number of left-hand side arguments doesn't match block diagram. When specifying that root-level outports are to be returned individually, the number of left-hand side arguments must be 2 (for T,X) plus number of root-level outport blocks
Does anyone know how to extract those outputs from a script?
Thank you in advance for your help!
Thanks to #Ander Biguri and #Wolfie
The answer was using the block "to Worskpace" instead of the block "Display"

How to monitor error on a validation set in Chainer framework?

I am kind of new to Chainer and have written a code which trains a simple feed forward neural network. I have a validation set and a train set and want to test on the validation set on each like 500 iterations and if the results are better I want to save my network weights. Can anyone tell me how can I do that?
Here is my code:
optimizer = optimizers.Adam()
optimizer.setup(model)
updater = training.StandardUpdater(train_iter, optimizer, device=0)
trainer = training.Trainer(updater, (10000, 'epoch'), out='result')
trainer.extend(extensions.Evaluator(validation_iter, model, device=0))
trainer.extend(extensions.LogReport())
trainer.extend(extensions.PrintReport(['epoch', 'main/loss', 'validation/main/loss', 'elapsed_time']))
trainer.run()
Error on validation set
It is reported by Evaluator, and printed by PrintReport. Thus it should be shown with your code above. And to control the frequency of execution of these extentions, you can specify trigger keyword argument in trainer.extend function.
For example, below code specifies printing each 500 iteration.
trainer.extend(extensions.PrintReport(['epoch', 'main/loss', 'validation/main/loss', 'elapsed_time']), trigger=(500, 'iteration'))
You can also specify trigger to Evaluator.
Save network weights
You can use snapshot_object extension.
http://docs.chainer.org/en/stable/reference/generated/chainer.training.extensions.snapshot_object.html
It will be invoked every epoch as default.
If you want to invoke it when the loss improves, I think you can set trigger using MinValueTrigger.
http://docs.chainer.org/en/stable/reference/generated/chainer.training.triggers.MinValueTrigger.html

Retrieve a variable after simulating some data

I have a simulink model which I am running through a function , all the values to the blocks are assigned from within the function using assignin() function , now I want to retrieve the resulting data which is which is automatically saved in the workspace after simulation(I am using 'To workspace' block which stores the simulated result in a vector) , now I want to retrieve this data right after the simulation with the function. I used evalin() to retrieve the data from the workspace but it doesn't seem to work as it says the variable is undefined
I found the solution to the problem , Before I simulate the data I should enable the signal logging for the output first , then assign the simulation output to a variable as an object
FO =sim(filename,time);
after that I can retrieve the data variable to which the singal was logged from the simulation object
FT = FO.get('FT');
this works even with in a function unlike the 'To workspace' block

FMU-Export in Dymola: Is it possible to make a Modelica enumeration type variable "tunable" when exported as FMU / FMI

I have implemented three similar publications in one Modelica model, using an enumeration type variable to select the publication. The goal is to switch between calculation methods (i.e. between publications) by changing the value of the enumeration type variable online.
The calculation consists of three steps, each of which has its own enumeration variable. This allows for mixed calculation methods, e.g. by setting step 1 to calculate according to publication 1 and steps 2 and 3 according to publication 2.
Each step reads something like this
model Calculation_step
type pubSelect = enumeration(
Publication_1,
Publication_2,
Publication_3);
// ####### Publication Selection #######
parameter pubSelect selection = pubSelect.Publication_2;
// ##### End Publication Selection #####
Modelica.Blocks.Interfaces.RealInput incoming;
Modelica.Blocks.Interfaces.RealOutput outgoing;
parameter Real factor = 5;
equation
if selection == pubSelect.Publication_1 then
outgoing = factor * sin(incoming);
elseif selection == pubSelect.Publication_2 then
outgoing = factor * sin(incoming)^2;
elseif selection == pubSelect.Publication_3 then
outgoing = factor * sin(incoming)^3;
else
outgoing = 99999;
end if;
annotation (uses(Publicationica(version="3.2.1"), Modelica(version="3.2.1")));
end Calculation_step;
The model will not be calculated in Dymola. Instead, a functional mock-up unit (FMU) is created using Dymola. This creates an XML file describing the model. In order to enable online changes, a variable has to have the attribute variability="tunable" set in this XML.
However, the variable selection is not tunable, as shown in the following excerpt of the XML:
-<ModelVariables>
<!-- Index for next variable = 1 -->
-<ScalarVariable name="selection" variability="constant" valueReference="100663296">
<Enumeration start="2" declaredType="Calculation_step"/>
</ScalarVariable>
Using the same code for the declaration of the variable factor yields a tunable FMU variable:
<!-- Index for next variable = 4 -->
-<ScalarVariable name="factor" variability="tunable" valueReference="16777216" causality="parameter">
<Real start="5"/>
</ScalarVariable>
tl;dr:
Is it possible to make a Modelica enumeration type variable "tunable" when exported as FMU / FMI?
Dymola Version 2015 FD01 (32-bit), 2014-11-04
I tried to add a start value to the selection parameter, and with annotation (Evaluate=false) it became tunable.
parameter pubSelect selection(start=pubSelect.Publication_2) annotation (Evaluate=false);
It will give you a warning about an unassigned parameter tho, I have not really tried if it really works(change the value at events/communication points), please let me know the result if you have a chance to give it a try. Thanks~

set threshold as a function of autoThreshold

I have written a macro for ImageJ/FIJI to deconvolve my confocal microscopy images and run the "3D Object Counter" plugin. The macro successfully runs all required commands and saves all required data in the specified places.
However, I have found that the 3D-OC autothreshold (as shown in the plugin dialog box) is to stringent resulting in objects being lost or divided.
To remedy this I would like to reduce the autothreshold by a predetermined function something similar to what was done here (from:How to get threshold value used by auto threshold Plugin) which resulted in this code:
setAutoThreshold();
getThreshold(lower,upper);
v=setThreshold(lower,upper*0.5);
run("3D Objects Counter", "threshold="v" slice=10 min.=400 max.=20971520 objects statistics summary");
The idea was to call the AutoThreshold values, modify them and set them to a variable. However when these lines are run the following error is returned:
Number or numeric function expected in line 3.
v=<setThreshold>(lower,upper*0.5);
And if the variable is inserted directly into the threshold key for run(3D-OC) the following msg is encountered:
Numeric value expected in run() function
Key:"threshold"
Value or variable name:"setThreshold(lower,upper*0.5"
Any suggestions or help on how to designate the 3D-OC threshold value as a variable as described would be greatly appreciated (as would any work arounds of course :) ).
Cheers
Edit: After testing Jan's response below (which works perfectly), it appears I need to call the threshold set by the 3D-OC plugin. Anyone know how to do this?
The getThreshold(lower, upper) function returns the lower and upper threshold levels in the provided variables. There is no need to assign any value to a new variable, and as you observed, setThreshold does not have any return value.
Instead, you can use the value(s) returned from getThreshold and use them as parameters in the run method (in the correct way, by string concatenation, see here):
setAutoThreshold();
getThreshold(lower, v);
run("3D Objects Counter", "threshold=" + v + " slice=10 min.=400 max.=20971520 objects statistics summary");
Alternatively, you can use &v in the second parameter to avoid string concatenation in the last line (see the documentation for the run() macro function):
run("3D Objects Counter", "threshold=&v slice=10 min.=400 max.=20971520 objects statistics summary");
You might have to use the lower instead of the upper threshold value, depending on whether you count bright or dark objects.