Accessibility of main from agent's statechart - anylogic

May I know if main is accessible to all elements in the model?
The reason I ask is that I have created a simple M/M/n model with one resource type created through ResourcePool. The behaviour of the resource type is implemented using a statechart. I write a simple code in the action of a transition in the statechart, i.e.
if (agent_variable < main.my_parameter) { /* do something */ }
The code does not compile and give an error message "main cannot be resolved to a variable". I cannot figure out why the statechart cannot recognise main.
Thanks

Welcome to SOF, Stephan.
First, always use code-complete (Ctrl+space). You will then see what is and what is not possible to access from where you are. In your case, main would not even be an option :-)
Now, your model root (typically that is main) is always accessible via getModelRootAgent() but you will need to cast it to your Main class, i.e. ((Main)getModelRootAgent())
Otherwise, Main is accessible to all agents that are somehow embedded into Main. This is classic OOP principles. Your Resource agents are not actually an embedded population so no direct access to Main. (You can make that happen in the ResourcePool properties, though)

Related

AnyLogic: Variables from Simulation will not be displayed anymore

I have added some variables in my simulation start page. Now I want to access them from the main class. However, with ((Simulation)getExperiment()).[...] the variables are no longer displayed. When I press option+space only one of about 150 variables is displayed. This one variable is not different from the other variables in the properties.
All variables are on public and I was able to access all of them a few weeks ago. Now not anymore, although I didn't change much in the model. I have already tried restarting. Did I accidentally remove some package or something? Can someone help me here please? I have only noticed the problem now as my model has runtime errors, presumably as the now unrecognized variables are not being initiated.
Pictures:
You should not access variables from experiments on Main. If you need access, you should pass them on as parameters into Main.
If you have hundreds of variables in the experiment, turn them into fields in a single Java class. Pass 1 instance of that Java class into Main as a parameter.
This way, you always have access, it is easy to add more variables, it is easy to change them and you do not need the awkward (and bad) type-casting you currently do

Variable from simulation class is not accessible in main class

I have created many variables in my simulation class and would like to access them in my main agent in the StartUp code. First I started to create parameters in the main class like in the AnyLogic tutorial and assign the variables to the Simulation class. This works, but is very time consuming. However, in my StartUp code in the main class I can't access it directly with Simulation.example_parameter even though all variables are on public. Is this simply not possible or does anyone know where a bug might have crept in here?
If your experiment is a "Simulation" experiment, you can use ((Simulation)getExperiment()).myVariable
PS: You can also wrap all your variables into a Java class and pass that along into 1 parameter in your model, saves a ton of effort

Why World Context pin appears on function nodes called inside of Blueprint Function Library?

Lately I was creating some global functions inside of Bluprint Function Library (BPFL) and I've noticed that when I call function inside of another function that is also created in same BPFL, World Context Object Reference input pin will appear on the node. This pin doesn't need to be plugged and all the functions will compile without any errors or even warnings.
I've searched for the answear but I wasn't able to find any. I've found only UE-39873 bug ticket which exacly describes this behavior and pull request 8016 that would fix it but It has been resolved as 'Won't fix' without any reason given.
You can even quickly reproduce it by following these steps:
Create blank UE project and open Editor
Create new Blueprint Function Library
Create new function inside of Blueprint Function Library
Call the same function inside of it's own body
World Context Object Reference input pin should appear on function node
(UE5.0.3 / Epic Launcher version)
So my question is:
Why does World Context pin appear in this specific case and what is the purpose of using it?
Thanks in advance for any explanation!
This question has been answered on UnrealEngine Forum
Thats nothing you should worry about (if gives you an error just connect it with the world context variable).
But basicly, every function that comes from a function library (not from an actor), needs to have a reference in the world to be executed. That’s why it appears, when you call a function from a class that comes from the the class actor it will assume that the world context is the actor itself, that’s why it not appears in characters and actors, it still there but it just not visible.
And additionally here:
When function libraries need a reference of the world sometimes for some tasks…
for example get all actors with some tag…the function need to know the world where those actors are…or a delta time, etc.
There is a way to tell the library function to use the actor that is calling it as world context object so the world context pin does not appears in the blueprint node and is adding the meta WordlContext.

How can I use the .getServicedEntity() method on a Resource Unit without casting the agent type?

I built a custom block that, among other things, tells the resource entering portIn of the block to move to the resource's seizing unit. I use a moveTo block with the destination node as: (Node)((Cart)agent).getServicedEntity().getNetworkNode(); but I need to know the agent type and cast it into the method. I would like to make this a generic block that can be used in other models and with any Resource Unit.
I've tried using generic parameters in the custom block
then selecting the agent type:
and then trying: (Node)T.getServicedEntity().getNetworkNode(); but this results in compiling error: The method getServicedEntity() is undefined for the type T. Is there a way to do what I'm looking to do? I'm fine if the user has to select the agent type using the generic parameter pulldown, but I'd like to avoid having to change the code every time to add in all of the resource types available in the model using the instanceof command and then duplicating the code. Seems inefficient.
Well, your "T" extends Agent, and Agent does not know about getServicedEntity.
What your T extends needs to know it is a resource unit. Easiest solution I can see:
Create a parent class MyResourceUnit (but do not instantiate it)
Make sure it is "used in flowcharts as Resource Unit"
Make all agent types that should ever use your custom block to extend MyResourceUnit
Now in your custom block, you should make T extends MyResourceUnit

Windows Workflow - IfElse branch

I am trying to use Windows Workflow and have a model that looks similar to the image in the link below:
After each of the Send Activities (GetSomthing, GetSomthingElse, GetSomeMoreStuff) the same custom activity is being called (LogSomthingBadHappened).
While it might not look so bad in this picture in my real model the custom activity is a SequenceActivty, has quite a few nodes, and when its repeated 3 times starts to make the workflow look very ugly.
I would like to do something like this:
Can the IfElse branches be merged like this?
Should I be using a State Machine work flow instead (haven't figured these out yet)?
Use a FaultHandler on the workflow and throw a specific exception type that the handler will catch. Not the most graceful, but I think it should work.
In sequential workflows all steps must appear in a specific order, and the execution path is regulated exclusively by control structures (IF, WHILE).Altering the execution path in the way you describe would be like using a GOTO statement in imperative code, which we know leads to unnecessary complexity.
If the activities contained in the SequenceActivity that you need to execute at different stages of your workflow are exacty the same, you could embed them in a custom activity. This way it is easier to manage them since they are contained in a single logical unit.In imperative code, this would be like refactoring out a portion of duplicated code into a method, which is then invoked multiple places.
Another alternative that might work is to put your LogSomthingBadHappened activity into a custom workflow and include that several time. Several things to watch out for: Subworkflow are executed asynchronously, if the LogSomthingBadHappened activity needs state information from the main workflow, copying it to the sub workflow might be hard.
I have not tried this, so it might not even work.
I think the answer by gbanfill points to the right direction.
To generalize, I define the problem as:
Is there a way to define a group of activities that will be executed in several places of a workflow?
Further requirements are:
The group of activities should be defined in XAML only ie no code.
Type of input to this group will, of course, be fixed but actual values should depend on call (like calling a function).
Maybe the way to do it is define sub-workflows and build a custom activity that would instantiate the sub-workflow and wait for it to complete before continuing.
This custom activity should have at least two parameters: the sub-workflow id and input parameters.