In AnyLogic Simulation software, I have an agent that has some parameters. I just want that whenever this agent passes from a specific process, say delay, its parameter value to be changed to another value. Moreover, if I have 100 individuals (all same type of agents) passing from this process, I will change the first 40 of these individuals' parameter values to 1, and the last 60's values to 2. Is this possible? Do I need to write codes to these boxes:
Yes, you have to write some code on one of these boxes.
Create an integer variable named v_countand set the initial value to 0. If you want agent's parameters to be changed as soon as they enter the block write this code "On enter" box, else if you want them to be changed when they leave the block write it "On at exit":
if(v_count < 40)
agent.parameter = value1;
else
agent.parameter = value2;
v_count++;
//reset the count to 0 when 100 agents have passed through this block
if(v_count == 100)
v_count = 0;
Related
I want to find the index my agent has in its population (named dullieses), which lives in my Main-agent.
I want to find one of my dullieses-agent via one of its variables (DullyID) which, in this example, shall be equal to my counter variable. Both are of type int.
I have tried the following to no avail:
int i = 0;
for ( i = 0; i < dullieses.size(); i++){
if (Main.dullieses(i).DullyID == counter){
traceln("I found myself! I have the index " + i);
break;
}
}
Error code: Cannot make a static reference to the non-static method dullies(int) from type Main.
How can I find my agent in my population and find its index?
I think you're probably already in main and don't need to add Main..
Anyway, I would recommend using:
Dully d = findFirst( dullieses, d -> d.ID == counter );
d.variable = 10;
I used variable and 10 as random examples, but this should give you the idea. Also replace Dully with whatever your agent type name is.
You don't need to use a custom ID parameter in your agents (at least not for what you're doing here).
All agents in a population have the getIndex function which returns their index in the population. Just be wary that, if you remove agents from a population, their indices will change (so you can't, for example, use their index as a unique ID for them in that case).
I am using a Queue and hold block together, where the hold remains blocked until all the agents arrive at the Queue block.
How to change it and want to allow only a fixed number of agents (say 5 agents) at fixed intervals of time(say every 3 minutes)? Current properties of my Queue and hold block:
queue_block_properties
hold_block_properties
Create a cyclic event with recurrence time 3 minutes.
Also create a variable which you can name count of type int.
In the event action field write:
count = 0;
hold.unblock();
Then, in the On enter field of the hold block write the following:
count++;
if( count == 5 ) {
self.block();
}
The only question that I have is whether you want every 3 minutes to have exactly 5 agents leave or whether it's okay if they arrive a bit later. In other words if after 3 minutes, there are only 3 agents in the queue, do they leave and the hold remains unblocked in case another 2 arrive before the next cycle? Or does the hold block blocks again immediately?
In the solution I provided, if there are less than 5 at the cycle time occurrence, and then new agents arrive before the next cycle, they can pass.
Otherwise, create a new variable called target for example and write the following in the event action:
count= 0;
if( queue.size() >= 5 ) {
target = 5;
hold.unblock();
}
else if ( queue.size() > 0 ) {
target = queue.size();
hold.unblock();
}
And in the on enter of the hold, write:
count++;
if( count == target ) {
self.block();
target = 0;
}
I would advise to not use a hold block for such delicate control of releasing agents. Instead, I would propose a simpler solution.
Simply let the agents build up in the queue and then you remove them using an event. The only action for this event is to remove the minimum between your set number of agents and the queue size, from the queue and send them to an enter block. The enter block is where your process flow then continues. See the screenshot below.
Code in the event is
for (int i = 0; i < min(5, queue.size()); i ++){
enter.take(queue.remove(0));
}
On that note, you can also use the Wait block (Which is hidden in the Auxillary section in the PML library
Then you can ditch the enter block and simply call the following code
for (int i = 0; i < min(5, wait.size()); i ++){
wait.free(wait.get(0));
}
New to reactive programming and pretty lost.
I have a number (which can be positive or negative) coming into a script from a patch in SparkAR and I'd like to add the number to itself once every frame.
ie if the incoming number is 1 and it comes in 9 times the variable would be 9.
let intoScript = Patches.getScalarValue('intoScript').pinLastValue;
let myValue = Reactive.add(myValue, intoScript);
The above doesnt work.
One way-
Increment counter in Patch editor and send variable value to SparkAR.
(https://sparkar.facebook.com/ar-studio/learn/documentation/docs/visual-programming/javascript-to-patch-bridging/)
let originalValue = Reactive.val(0)
function increment(newValue){
Diagnostics.watch('originalValue', originalValue)
originalValue = newValue.add(originalValue)
}
Don't forget to import Reactive module. more info about logical operations here
How would I correctly make a recursive call within every if-statement to get the change of money? Im specifically focusing on the "change" variable.Thanks
TEST CASE 1-------------------------------------------------------------------------------
<>> [change,flag] = makeChangeRecursive(2,100)
change =
50
20
20
5
2
1
flag =
1
My code is the following
function [change,flag] = makeChangeRecursive(cost,paid)
if extra > 0
flag = true;
elseif extra == 0
change = 0;
flag = true;
return
elseif cost > paid;
flag = false;
change = [];
warning('That''s not enough to buy that item.');
return
end
if extra >= 100
change = [change; makeChangeRecursive(cost,paid - change )];
paid =paid-100;
elseif extra >= 50
change = [change; 50];
paid =paid-50;
elseif
This continues for all dollar values.
Let's take a look at your first case:
if extra >= 100
change = [change; makeChangeRecursive(cost,paid - change )];
paid =paid-100;
elseif ...
The first time we call your function, the variable change doesn't have anything in it. In fact, it will never have anything in it at the beginning of the function call because you don't pass it in as a parameter or give it a value prior to this line. So putting change on the right-hand side of the assignment will give you an error.
But that's okay, because that's not what you want to do anyway. You want to build change up from the beginning.
In addition, change is a list of values. We want to pass the recursive calls a single value, paid after updating its value.
Let's build this up step by step:
if extra >= 100
If this is true, we want subtract 100 from the amount paid (what we pass in to the recursive call) and add 100 to our list of change. Let's do the first part:
paid = paid - 100;
As I said, we want to update paid first because we're going to use this value in the recursive call, which happens next, along with adding our new change value to the list:
change = [100; makeChangeRecursive(cost, paid)];
elseif ...
And so on for the remainder of the change values. I'm sure you can take care of the rest of them now by yourself.
I also noticed that you didn't assign a value to extra. This might have been just a cut-and-paste error, but you need to make sure that you have that at the beginning of your function.
In ral file, I have something like:
class ral_reg_AAA_0 extends uvm_reg;
rand uvm_reg_field R2Y;
constraint R2Y_default {
}
function new(string name = "AAA_0");
super.new(name, 32,build_coverage(UVM_NO_COVERAGE));
endfunction: new
virtual function void build();
this.R2Y = uvm_reg_field::type_id::create("R2Y",,get_full_name());
this.R2Y.configure(this, 12, 4, "RW", 0, 12'h0, 0, 1, 1);
endfunction: build
`uvm_object_utils(ral_reg_AAA_0)
endclass : ral_reg_AAA_0
You can find R2Y is set to has_reset = 0, in real RTL, it's 'X' value by default
but if I use set/update mechanism to write this reg, if write data is 0, which is equal to reset value in R2Y (even has_reset = 0), seems like RAL will treat m_mirror == m_desired so there won't be a bus transaction for this reg access.
like
env.regmodel.AAA_0.R2Y.set(0);
env.regmodel.AAA_0.update(status,UVM_FRONTDOOR);
Does that make sense? I thought no matter which value I set to these kind of regs, there should be always bus transaction happening.
PS: mirrored and desired values are 2-state vectors, and even reg fields are set as 'no reset' value, m_mirrored initial value for a reg field is still 0. if RTL reset value is "x", for instance, there are 10 regs in design, I want to randomly pick up any number of them to write them with random value (of course, 0 is also a legal value), seems I will miss those '0' value register setting in this case.
I am using a workaround for now, flush all regs to be 0 value with a 'write' ral method, it can meet my expectation with some extra overhead on bus
The internal representations of the mirrored and desired values are 2-state vectors and are stored on a per field basis. This means that when created, your R2Y field's mirrored value is 0. By setting the desired value to 0, the values are still the same, which is why no bus transaction is started. If you want to force a bus transaction, just use the write(...) method:
env.regmodel.AAA_0.write(status, 0); // this will write the value '0' to the register
If you still want to use set(...) to play with the register fields, then you could try something like:
env.regmodel.AAA_0.R2Y.set(0);
env.regmodel.AAA_0.write(status, env.regmodel.AAA_0.get());