Dynamically adjusting arrival rate in source - anylogic

the basic idea behind the modeling issue is a breakdown of a production machine.
I would like to model this by setting the arrival rate (simply arrivals per second) to zero (Source.rate = 0). After the machine is repaired, the arrival rate is set to its actual value again (e.g., Source.rate = 5). While the first command does the job, the second does not seem to have any effect, i.e. new agents are not created.
The segment of the model is rather simple: Source --> Select Output (decision about breakdown) --> true: go on in production; false: delay (repair machine) --> go on in production.
Source.rate = 0 is called at the out port (false) of "breakdown" and Source.rate = 5 at the out port of "repair".
https://i.stack.imgur.com/hqGoI.png
Of cause, this issue might be modeled differently (e.g., using hold with disabled "forced pushing"), however, it is not clear for me why my approach does not work.
Thanks in advance!

Instead of using source.rate=5; use source.set_rate(5);

To expand on Felipe's answer with an explanation:
Instead of using source.rate=5; use source.set_rate(5);
rate is effectively a Parameter (in the AnyLogic sense) of the Source block. (All AnyLogic's Process Modeling blocks are actually themselves Agents developed by AnyLogic, and thus with Parameters, Variables, etc.)
You can set an AnyLogic Parameter directly (via just assigning a value as you did), but they also all have a set_<parameter name> method (function) which should really always be used instead because this triggers any internal on-change logic for this Parameter. It is only this triggered logic (internal to the Source block) which causes the Source to 're-evaluate' the rate properly.
(You can use on-change logic for Parameters in your own models, and need to do so when altering a parameter requires some 'adjustments' to the rest of the model; i.e., in situations where the change doesn't 'just work' due to other bits of the model reading the new value after the change point.)

I don't know why your model doesn't work (maybe more details of your model is needed), but a simple solution which I tested and worked, is as below:
You can set the source's "Type of arrival" to "calls of inject() function", add an event to your model and set its "Trigger type" to "Rate" and set its rate value to 5. Then in action code of the event use below code:
if(yourCondition)
{
source.inject(1);
}
I hope it helps you.

Related

Set transporter speed based on parameter of transported product?

In my model I am transporting (path guided) several types of products (motors) by an agv trough a manufacturing line with 27 cycles. It´s a flowing manufacturing line. That means the product gets manufactured while the agv is constantly running.
To model that I created an agent population called "motors" with parameter "axelType" (string) which is loaded from column "axel_type" in database "manufacturing_sequence" (local excelsheet) and is placed on Main.
Each motor is placed on an transporter "agvAssembly" (in Flowchart as: Transporter) and runs from node "locationCycle1" all the way to "locationCycle27".
Now I want to change the transporters speed at each of the 27 cycle nodes dependent on the currently loaded motor. To do that I got another database called "speeds_axel" which includes all the needed speeds for the cycles and respective parameter name for axelType (column axel_type).
So now, when the transporter enters a node I have to check first the nodes name. Than I want to read out the parameter "axelType" of the currently in that node entered agent "Motor" and search in the database for the respective speed.
In the block "transporter Fleet" - "On enter node:" I wrote as an example for cycle 1 the following:
if (node == locationCycle1) {
unit.setMaximumSpeed(
selectFrom(speeds_axel)
.where(speeds_axel.axel_type.eq(motor.axelType))
.firstResult(false, speeds_axel.cycle1)/60.0,MPS);
}
When running the model I get the following error:
"motor cannot be resolved to a variable"
(location: TransporterFleet)
I think that error accures because my approach doesn't specify which motor I mean. How can I clarify to AnyLogic that I always mean the current motor which enters the node?
I need something like this:
if (node == locationCycle1) {
unit.setMaximumSpeed(
selectFrom(speeds_axel)
.where(speeds_axel.axel_type.eq("get motor which is currently in locationCycle1".axelType))
.firstResult(false, speeds_axel.cycle1)/60.0,MPS);
}
the biggest problem in your model is that you don't follow conventions. An agent type should be named with an uppercase first letter
Why is this important? Because you want to make the difference between Motor, motor, and motors
Motor is the class (or Agent Type)
motor is an instance of that class (or agent type)
motors is a population.
Since you don't follow this convention, you make mistakes of this kind since motor is a class
in your case when you do motor.cycle1
if you followed the conventions, you would be doing
Motor.cycle1 (which is obvioulsy wrong)
Note that Motor is the Agent Type name, and what you really want is to know for a particular motor what the value of cycle1 is
The first thing you need to do with this model, is get back to using the conventions, and this will probably solve this problem and many problems in the future.
Just because you have a population called motors (which the agents within your flow 'come from' --- though it looks like they don't actually; see later), this does not mean that you can 'magically' refer to the current agent via the singular form motor at any point in the code. (And, similarly, your agent type being Motor does not mean you can use the lower-case form to refer to 'the current one'.)
In Transporter Fleet block "On enter node" actions, you refer to the current transporter via the unit keyword; see the help page. The motor is not the transporter; it's the thing being transported.
So, just use the "On exit" (or, better, "On at exit") actions of your MoveByTransporter blocks (which trigger on arrival at the destination node), where you can refer to the current motor (the agent in the flow) via the agent keyword; again, see the block help.
But, from a quick glance, there appear to be a few important changes/simplifications you should also make (though hard to definitively tell without details of all your code):
You are using a Source block to add agents (motors) to the flow when you have already created the motors in your population. You should be using an Enter block instead to add the (already-existing) Motor agents to the flow at the appropriate time (triggered by code: I imagine you want one to start at model start time, requiring code in Main's "On startup" action, and then others added either at certain simulation times or when earlier motors reach a certain stage in the process...). If your population was actually just for 'templates' of data for each motor axle type (and you would then potentially create multiple instances of motors for a given axle type) then your current logic might make sense, but your screenshot of your manufacturing_sequence table makes clear that isn't the case. (If you did go that route, you would want to rename your population so that its purpose was clear.)
It looks like you have a 'looping' process (with the same process behaviour for all your in-sequence nodes), so you should look to make your process generic with an explicit loop (so you don't have near-copies of blocks for every node in your sequence). There is a fair amount of detail in terms of how you do this but roughly:
Track the node the motor is currently in (or its sequence number) via a variable in the Motor agent.
Use a collection (List) which contains the nodes-in-order to determine where it has to go to next.
Your process would have a MoveByTransporter --> Delay --> SelectOutput sequence (plus TimeMeasureStart/End if you're using them), where SelectOutput loops back to the MoveByTransporter if the motor is not yet at the last node.

Anylogic how create new agent and assign properties?

Anylogic: This should be simple but I just cannot find it in the help files..
On creating a new agent instance, we know there are four parameters and what they are, but not in what order they were defined. Lets say parameters are "type_of_car" (String), "number_of_pax" (Integer), "automatic" (boolean), "fuel_capacity" (double). Now when calling: new myagenttype("ford", 5, false, 55) the agent gets created as a ford with 55 pax, manual and 5 liter fuel capacity - which is all wrong. (it seems the definition order of the parameters in the agent definition are in a different order)
How do we include the parameter name (or definition) when we call new agenttype() to avoid this problem, ensuring the right value gets assigned to the right parameter?
The problem originates because of a bug in Anylogic's logic in triggering functions. We have a Split which creates a new agent and assigns the agent properties on the "On exit copy" - event, however what Anylogic does is it creates the agent, forward it to the next logical block (a decision node), then execute the code of the decision - all wrong now for the agent's properties are undefined - and only then executes the "On exit copy" event which assigns the agent's properties. Very frustrating.
This is actually not a bug, this is defined in the simulation experiment properties, in the randomness section, with the "selection mode for simultaneous events" property. The default is LIFO, but if you want the opposite behavior in your case you should use FIFO... I always use LIFO too, and in these cases, sometimes I might use a 1milisecond auxiliary delay between the split and the next block in order to control the order manually... if you do that, you will solver your problem in fact... just use a 0.001 miliseconds delay after your split
Now from your Agent Type problem, the arguments for your class constructor should be written in order, and the only way to know the correct order is by using the autocomplete feature when you write new agenttype()... the autocomplete will tell you the order in which you should write your constructor arguments.

Managing multiple anylogic simulations within an experiment

We are developing an ABM under AnyLogic 7 and are at the point where we want to make multiple simulations from a single experiment. Different parameters are to be set for each simulation run so as to generate results for a small suite of standard scenarios.
We have an experiment that auto-starts without the need to press the "Run". Subsequent pressing of the Run does increment the experiment counter and reruns the model.
What we'd like is a way to have the auto-run, or single press of Run, launch a loop of simulations. Within that loop would be the programmatic adjustment of the variables linked to passed parameters.
EDIT- One wrinkle is that some parameters are strings. The Optimization or Parameter Variation experiments don't lend themselves to enumerating a set of strings to be be used across a set of simulation runs. You can set a string per parameter for all the simulation runs within one experiment.
We've used the help sample for "Running a Model from Outside Without Presentation Window", to add the auto-run capability to the initial experiment setup block of code. A method to wait for Run 0 to complete, then dispatch Run 1, 2, etc, is needed.
Pointers to tutorial models with such features, or to a snip of code for the experiment's java blocks are much appreciated.
maybe I don't understand your need but this certainly sounds like you'd want to use a "Parameter Variation" experiment. You can specify which parameters should be varied in which steps and running the experiment automatically starts as many simulation runs as needed, all without animation.
hope that helps
As you, I was confronted to this problem. My aim was to use parameter variation with a model and variation were on non numeric data, and I knew the number of runs to start.
Then i succeed in this task with the help of Custom Variation.
Firstly I build an experiment typed as 'multiple run', create my GUI (user was able to select the string values used in each run.
Then, I create a new java class which inherit from the previous 'multiple run' experiment,
In this class (called MyMultipleRunClass) was present:
- overload of the getMaximumIterations method from default experiment to provide to default anylogic callback the correct number of iteration, and idnex was also used to retrieve my parameter value from array,
- implementation of the static method start,
public static void start() {
prepareBeforeExperimentStart_xjal( MyMultipleRunClass.class);
MyMultipleRunClass ex = new MyMultipleRunClass();
ex.setCommandLuneArguments_xjal(null);
ex.setup(null);
}
Then the experiment to run is the 'empty' customExperiment, which automatically start the other Multiple run experiment thru the presented subclass.
Maybe it exists shortest path, but from my point of view anylogic is correctly used (no trick with non exposed interface) and it works as expected.

Is is possible to programmatically play a Simulink model and measure its states?

I am looking to set up a test set for an existing Simulink model. Ideally I could take full control of the model, explicitly stepping it and measuring the state of any signal on any bus in the model.
As might have been gleaned, this is the precursor of a unit testing system for the model. Being so, I can't really justify changing the model to suit the test, the test must accommodate the model as-is.
The furthest I've got so far is using load_model() to return a handle to the model. From there there seems to be a quite obscure set of functions for accessing the model. I can't see any that relate to accessing states and can't see any further commands that relate to accessing a loaded model.
The easiest way is to use the Data Import/Export function within the Simulink Preferences.
Set the checkbox States and it will store every state of your system for every time step in your workspace, also when you pause the simulation or execute it step by step.
Be aware not to set Save simulation output as single object, in this case the access would be more complicated and you need to follow the instructions here.
To add to the other answer, you probably want to check this page in the documentation: Control Simulation Using the set_param Command. Of interest are the following commands:
set_param(<model_name>, 'SimulationCommand', 'start')
set_param(<model_name>, 'SimulationCommand', 'pause')
set_param(<model_name>, 'SimulationCommand', 'WriteDataLogs')
set_param(<model_name>, 'SimulationCommand', 'continue')
Replace <model_name> by the path to your model file.

How can I use 5x5filter (Xilinx block), it keeps telling me there is an error in the counter?

I'm trying to apply edge filter to an image using Xilinx blocks,
I used 5x5 buffer then I connected the 5x5filter to it.
But it keeps telling me:
Illegal Period, This blocks attempts to set period that is a non-integer multiple of the system rate
Error occurred during "Block Configuration".'
which I did not understand.
Similar such problem(with solution) is posted in Xilinx Forum. Go through the link given below:
http://forums.xilinx.com/t5/DSP-Tools/Can-any-1-help-me-regarding-FIR-implementation-in-system/m-p/33650#M1463
It means that the sample time of one of the block isn't an integer multiple of the model's minor timestep. Check the configuration parameters for the model and the parameters of your new blocks.
I don't think this has anything to do with the Xilinx blocks specifically.