Simulink "Counter Limited" block with dynamic upper limit - simulink

The Simulink Library Block "Counter Limited" (Simulink/Sources/Counter Limited) counts up from zero to a specified upper limit. It then wraps round to zero and counts back up. This happens at a defined rate (sample time). The mask parameters are "Upper Limit" and "Sample Time".
My simulation contains a discrete-time cyclic process with a variable cycle duration, i.e. the number of samples per cycle varies (sample time is constant).
Question: Does anyone know how to make the mask parameter "Upper Limit" dynamic? I would like to pass the number of samples for the current cycle to the "Counter Limited" block at the beginning of each cycle. The current number of cycles is calculated in Simulink but I don't know how to pass it to the "Counter Limited" block correctly.
Thanks a lot for any suggestions offered!

You'll need to roll your own counter implementation. Something like the following will enable the reset value (in this case 6) to be specified as a signal rather than a parameter. Note that the Unit Delay in the feedback path is needed to prevent an algebraic loop.

Related

Change in source :Agents per arrival and Maximum number of arrival at runtime

I am modeling a manufacturing system. The case is that I would like to implement a ramp-up model so the Agents per arrival and Maximum number of arrival change at a specific time during the simulation.
I tried to implement this by using an event but then I am not able to actually change the values of the source.
Change your source arrivals to be defined by calls of inject() funtion.
Use a cyclic event with a reccurence time of 1. That will reflect your interarrival time.
Then use an if statement to control your maximum arrivals.
if (source.count() < maxArrivals) {
source.inject(agentsPerArrival);
}
Maximum number of arrivals is a static parameter, you can't change it during runtime like that. (Check out the icons in front of the edit boxes: Agents per arrival has an arrow, showing that it's dynamic and Maximum number of arivals has an equal sign)
You can call towerFactory.set_maxArrivals(145/towerRatio) in your event, but it will only take effect if the Source has not reached the previously set number of arrivals yet. If that is the case, you need to take a different approach.

How to implement Cycle counting in Modelica?

I have a battery model in Modelica. PNet is the value of power flowing through battery (PNet is positive for charging and negative for discharging). This oscillates based on a load. I want to calculate the number of cycles that the battery is put through and also the depth of discharge comin in from each of these cycles.
This is a pretty generic question so my answer will be rather generic as well. Also it is not clear to me, what you are referring to as a cycle. Wikipedia mentions deep and shallow discharge and there are some others as well.
Some general note: In Modelica the when statement is useful for counting. You can read through Section 8.3.5 of the Modelica Language Specification to get full information on this.
The below examples computes how often the variable PNet turns positive, which should respond to the number of shallow cycles above. Some description for the model:
The model noiseSource computes a random number which is then filtered by a first order (PT1) element to compute PNet. The filter should likely be skipped in the original example, it is only there to smooth the trajectory a bit.
The code in the when statement is executed once at the time when the condition turns true, which enables the counting.
The pre statement accesses the value of cycles right before the when statement got active, which enables counting how often the condition occurred.
The start=0 in cycles(start=0) sets the starting value for the variable cycles, which is necessary as you cannot use cycles = 0 as this would generate an equation for cycles, which is not what you want.
The inner model globalSeed is necessary for the noiseSource to work.
Here is the actual code:
model CycleCounter
inner Modelica.Blocks.Noise.GlobalSeed globalSeed;
Modelica.Blocks.Noise.NormalNoise noiseSource;
parameter Modelica.SIunits.Time T = 1e-3 "Time constant of PT1 element to filter random signal to compute PNet";
Integer cycles(start=0) "Counts the number of ";
Real PNet "Random value";
equation
der(PNet) = (noiseSource.y - PNet)/T;
when PNet > 0 then
cycles = pre(cycles)+1;
end when;
annotation (uses(Modelica(version="3.2.3")));
end CycleCounter;
And the result from simulating in Dymola:

Is it possible to stop a Simulink simulation when a certain condition is met?

Assume that you have a Simulink simulation where a certain signal is first positive and after some time t in a given interval, it becomes negative. Your goal is to find the zero-crossing.
A first approach would be to plot the signal over the given interval, save it and calculate the zero-crossing.
When repeating this simulation numerous times for varying parameters, it would be beneficial to be able to stop the simulation after the signal has become negative. Then there is already enough information for the calculation of the zero-crossing in Matlab. How could you do that?
Yes, use the Stop Simulation block with the appropriate logical input to the block:
You can use an if / else block to control the flow in the Simulink model. In the if / else block, you can choose the condition if u > 0, continue as normal if it's true, and use the else-option to bypass the rest of the flow you would otherwise run. For instance jump directly to the scope.
Another ways:
You can use Hit Crossing Block in Simulink to find time at the moment of hitting zero.
Another way - use any Trigger or Resettable system. It detects the zero crossing too. For example: this question at SO.
Of course you can also use User Defined function to detect zero crossing by your hand and do whatever you want with the signal at the same time.
About making a lot of simulations and then stops:
you can use Check Upper Static Bound for automatically stops simulation at the moment when zero will be crossed in nth time. For example:
I set upper bound = 10 for this block and this stops at 10th crossing.
There are a lot of ways to save function values in this points or just array of times but this is an another question :)

Matlab Simulink Square Wave

I am new to Simulink and I am trying to model an oscillator to control an automation controller.
The question is:
I created a pulse generator that results in a square wave. To design the oscilator I need that 2 others chanels (one is the same signal, while other is the reverse) remain in zero when the input (the square wave) is oscillating. The problem is that I can't make the other 2 signals remain in zero. I tried using the blocks for discrete elements in the library, such as: "Delay", "Unit Delay", and even "Zero Order Hold". Every block just shifted the entire curve, while what I need is to delay the signal when it assumes the "1" value.
Follows some prints:
I have no reputation for all the images so: the subsystem consists of 3 pulse generators, and theres a scope linked to the subsystem
Please Help!!!!
It sounds like you're asking for a signal that rises at some pre-specified delay after the pulse generator rises, but falls at the same time as the pulse. This is shown in the picture below,
If that's correct, then it can be created using an enabled subsystem, where the subsystem contains only a unit delay, as shown in this picture,
Within the subsystem you must also
Set the Enable block to reset its states.
Set the Outport block to reset its value when disabled AND set an initial value of 0.
Specify an appropriate sample rate in the Unit Delay block (this acts as the amount by which the rising signal is delayed)

How to use the value of the variable in the previous interval as an input to the equation....?

Is it possible to use the previous value of the time varying variable
for eg:
Suppose I have pipe whose inlet temperature is 298K with a specified uniform mass flow(m_flow), now suppose i am heating the pipe using a heater of 100 watts.
The outlet temperature will be attain a higher temperature of suppose 302K, now if i have to use this outlet temperature as my inlet temperature (in the sense i am recircuilating the water), how would i be doing it?
is it possible to update the value of the inlet temperature based on the outlet temperature at the previous timestep? so that for the next iteration the inlet temperature will be the same as the oulet temperature in the previous iteration (in other words the fluid would be recirculating).
Thanks
You cannot access the value in the previous time step. The closest you can get in Modelica is using delay(exp,T) to get the value T units of time ago.
The timestep does not enter into it at all. A model that uses information about timestep is just wrong. Nature doesn't know or care about integration time steps, the model should reflect that.
It seems to me what you want to capture is transport delay. Transport delay is the delay introduced by the time it takes for molecules, electrons, etc. through the system. So presumably what you wish to model is the time it takes the inlet fluid to reach the exit. Again, this has nothing to do with the integration timestep but rather the velocity of the fluid and the distance it must travel. Once you know how long that takes (by either a priori knowledge of the system of by looking at the simulation results themselves), you can follow Marco's suggestion of using the delay operator.
In order to setup a proper model for the system you described I suggest you to look at the example :
Modelica.Thermal.FluidHeatFlow.Examples.IndirectCooling
of the modelica standard library ver. 3.2. Instead of one pipe you can put an ambient or control volume component to better suit you needs. Moreover using continous and differentiable equations (the delay function is not) you will benefit from some of the advantages of the Modelica code, e.g. you will be able to reuse your models in a much wider range of cases, solve inverse problems, solve initial value problems, ...
I hope this helps,
Marco