Looping through agents in a queue - anylogic

I'm new to Anylogic and Java, so I apologize in advance if this is a beginner question. I have one agent type that enters a queue (for example, called queue_X). I would like to loop through all the agents in the queue and perform some check on a parameter (that governs the removal of the agent from the queue). There may not be any agents in the queue in some instances.
This loop is set up inside an event that executes every X minutes.
What is the syntax for looping through the agents?
Thanks in advance for any help you can provide.
Cheers

Simplest way:
for (int i=0; i< myQueue.size(); i++) {
MyAgentType currentAgent = ((MyAgentType)myQueue.get(i));
}
This assumes there are only agents of type MyAgentType in your queue

Related

StopDelay for cars based on variable value (AnyLogic)

I am trying to stopDelay at delayNucSafe1 (See Screenshot) when the car exits at carMovetoScale1 They way I am currently doing it is at the "On Exit" block of carMovetoScale1 typing: delayNucSafe1 .stopDelay() but I am getting an error that says:
Description: The method stopDelay(Agent) in the type Delay is not applicable for the arguments (). Location: Scale House/Main/carMoveToScale1 - CarMoveTo
Logic Flowchar
where I am asking to stopDelay
Can someone help with this?
The stopDelay(Agent) method is for use when there are multiple agents waiting within the delay and you need to stop the delay for ONE specific agent. If this is the case for you, you would need to know which agent you want to stop the delay for.
For instance, you would call: delayNucSafe1.stopDelay(delayNucSafe1.get(0)) to stop the delay for the agent at index 0 in delayNucSafe1. (This code would also work if there is only 1 agent in the delay).
On the other hand, if you know for sure that there will only ever be 1 agent in the delay (or if you'd like to stop the delay for every agent simultaneously), you would use the method: stopDelayForAll(). This method has the benefit that it doesn't need an argument, but it will obviously cause problems if there are multiple agents waiting in the delay, each of which need to be released independently.
So in summary:
delayNucSafe1.stopDelay(delayNucSafe1.get(agentIndex))
will stop the delay for the agent at index agentIndex within delayNucSafe1. And:
delayNucSafe1.stopDelayForAll()
requires no arguments, and will stop the delay for all agents within delayNucSafe1

UVM End of test Objection Mechanism and Phase Ready to End Implementation

I am exploring different ways to end a UVM test. One method that has come often from studying different blogs from Verification Academy and other sites is to use the Phase Ready to End. I have some questions regarding the implementation of this method.
I am using this method in scoreboard class, where my understanding is after my usual run phase is finished, it will call the phase ready to end method and implement it. The reason I am using it my scoreboard's run_phase finishes early, and there are some data into queues that need to be processed. So I am trying to prolong this scoreboard run_phase using this method. Here are is some pseudo-code that I have used.
function void phase_ready_to_end(uvm_phase phase);
if (phase.get_name() != "run") return;
if (queue.size() != 0) begin
phase.raise_objection(.obj(this));
fork
begin
delay_phase(phase);
end
join_none
end
endfunction
task delay_phase(uvm_phase phase);
wait(queue.size() == 0);
phase.drop_objection(.obj(this));
endtask
I have taken inspiration for this implementation from this link UVM-End of Test Mechanism for your reference. Here are some of the ungated thoughts in my mind on which I need guidance and help.
to the best of my understanding the phase_ready_to_end is called at the end of run_phase and when it runs it raises the objection for that scoreboard run_phase and runs delay_phase task.
That Delay Phase task is just waiting for the queue to end, but I am not seeing any method or task which will pop the items from the queue. Does I have to call some method to pop from the queue or as according to the 1st point above the raised objection will start the run phase so there is no need for that and we have to wait for a considerable amount of time?
Let me give you some pre-context to this question. I have a scoreboard where there are two queues whose write methods are implemented and they are being fed correctly by their source.
task run_phase (uvm_phase phase);
forever begin
compare_queues(); // this method takes data from two queues and compares them, both queues implementation are fine and they take data from their respective sources. Let me give you a scenario, let's suppose there are a total of 10 transactions being generated but the scoreboard was able to process only 6 of them and there are 4 transactions left when all objections are dropped. So to tackle that I implement this phase_to_ready_end method in my scoreboard.
end
endtask
The problem with this method that I am having is that, when I raise the objection in this phase_ready_to_end and call delay_phase method, nothing happens. And I am curious is there more to this implementation or not?
Sorry for the delay. I have shared more context to the existing question. Please see to that, let me know if it is confusing.
We have a pair of monitors that calls write method implemented inside the scoreboard. The monitors typically capture the transaction from BUS and call these WR methods to push the transactions. Thus two source and destination monitors WR into two - source and destination - queues as and when they find the transactions.
We have a checker task with RD-n-check running in forever loop in the run-phase of scoreboard. It's in a while loop and watches if the destination queue has non-zero entry. Once it finds so, it pops the head entry from destination queue and then pops the head entry from source queue as well and compares the two entries to declare if the check was a PASS or FAIL.
There are more than 2 queues and more than a pair of source/destination of course, but broadly this is the architecture around here.
Now in the current scenario, it seems that the checker tasks stop prints after certain point of time in some of the test cases. Upon adding debug prints thoroughly, it seems that checker tasks that does the job #2/#3 above and gets called inside the forever loop of the run-phase, exits gracefully one last time. However they are entered again - which is to say that the forever loop that should be calling them didn't call. As if the forever loop of run-phase stopped completely.
We also added another forever loop in run-phase that observes whether the queues are empty. From prints inside that parallel loop and from the monitor prints, we know that the queues aren't empty and monitors did push WRs into the queues for a long time.
It seems that the forever loop stopped working suddenly ( going by prints spewed out) all of a sudden but another set of threads that we added in runphase in another forever loop just to monitor those queues - keep printing that the queues have contents. So run-phase shouldn't be over but the checker tasks running in forever has stopped.
We are using Vivado 2020.2 for the simulation. This is a baffling/weird problem for us and we did go through prints multiple times to make sure nothing has been missed out. It seems we are missing very very basic or has hit a bug/broken some basics of UVM coding to land into here.
If you have any help, thoughts here, will appreciate that greatly.
The function phase_ready_to_end() gets called at the end of every task-based phase when all objections have been dropped (or never raised at all).
Typically a scoreboard has a queue or some kind of array of transactions waiting to be checked sent from a monitor via an analysis_port write() method. If your scoreboard is an in-order comparison checker, the queue size is zero when there are no more transactions waiting to be received.
If you look at the code in the link you shared, there is the following in the write_south method doing exactly that:
if (!item.compare(item_stream.pop_front()))

(OMNeT++) Why PacketQueue is always 0?

I'm trying to code in OMNeT++ an app that gets the queue length from the node where it is invoked and sends it to another node.
The plan is to modify the UdpBasicApp.cc file invoked in a router and make it get the length of the queue of the DropTailQueue module.
Searching online I found that this is the right method...
cModule *mod = getModuleByPath("router3.eth[*].mac.queue");
queueing::PacketQueue *queue = check_and_cast<queueing::PacketQueue*>(mod);
int c = queue->getNumPackets();
EV << c;
...since the DropTailQueue extends the PacketQueue module.
I put a print at the end to see if there was something wrong.
When I run the simulation, using the modified UdpBasicApp module, c is always 0.
I hardly doubt that the queue is always 0, but I don't know how to verify this doubt.
If it's an error, why is it always 0?
My guess is, that you are querying a different queue than you assume. You should not use patterns (i.e. *) in your model path, because that may match on multiple eth modules, and it's unspecified, which one will be returned.

How I can match bags an passenger in the reclaim area?

I'm simulating a security control process, and i can't do that each passenger pickup their baggage. I have tried with Match, Combine, Pickup, but I still can't execute the commands correctly.
I've created the follow flowchart, and the problem is in the wReclaimPax, pickup and wReclaimBags blocks (you can see them in the picture).
https://ibb.co/v3V57Tm
I saw this link Anylogic - Combined multiple items back to original owner to understand something, but I still need help.
I've created 3 functions:
isMatch:
if(equipaje.pasajeroLink.equals(pasajero.equipajeLink)){
return true;
}
return false;
paxBags:
for(int i=0;i<wait.size();i++){
Pasajero p=(Pasajero)wait.get(i);
if(isMatch(p,bag))
return p;
}
return null;
bagsPax:
for(int i=0;i<wait.size();i++){
Equipaje e=(Equipaje)wait.get(i);
if(isMatch(pasajero,e))
return e;
}
return null;
Assumed context
You haven't really explained how your code is related to your process but I'm assuming the following:
Because this is luggage-retrieval, you want to ensure that a passenger
agent (Pasajero) only enters the Pickup block (representing taking bag from
carousel) when his bag (Equipaje agent by the look of it) has
arrived into the wReclaimBag Wait, and been released from it to
queue4 Queue.
For this you need triggers (to remove agents from Wait blocks) when
either a passenger (Pasajero) arrives in wReclaimPax Wait, or a bag (Equipaje) arrives
in the wReclaimBag Wait (because you don't know whether the passenger or their bag will get to their respective Wait blocks first).
So your paxBags function is called in on-entry action of the wReclaimBag Wait, and your bagsPax function in the on-entry action of the wReclaimPax Wait.
Possible problems with current approach
Without knowing more of your model it's hard to say but problems I can think of based on what you've supplied are:
Your functions return the Pasajero or Equipaje if there is one that matches. Your match check relies seemingly on bidirectional connections (links) between Pasajero and Equipaje. Obviously if they're not setup properly the model won't work and, if you're using bidirectional connections you shouldn't need to check both ends.
Your functions need calling so that, if they return non null, they then free the matching agent from the other Wait block, and free themselves. Are you doing that? Without checking, there may be issues with calling free for yourself as you enter a Wait block (since this kind of depends on AnyLogic internals as to whether you count as being 'in' the block at this stage and can be freed). If this seems to be the problem you could create a timeout 0 dynamic event instance to do the free so that you're not doing it within the scope of the on-enter action.
Your pickup block (since it's been setup so that the entering agent will always want to pickup the first agent (Equipaje) in queue4) just needs to be set as waiting for quantity 1 (though see below).
If you've done all this the most likely problem is that the underlying events ordering of AnyLogic is affecting things. When you free agents I'm fairly sure the freeing actually happens in a timeout 0 event scheduled under-the-covers. So it may be that the passenger arrives at the Pickup before their Equipment arrives in queue4 though, if you set the Pickup to be "Exact quantity (wait for)", with quantity of 1, it should handle that.
The animation of the process (numbers in/out/within each block and details when clicking on blocks) should also help you debug what is going wrong; e.g., are bags being left in the Wait when they should have been released, etc.
P.S. With this kind of thing you should always create a minimal example model to make testing the issue/solution easier (and for sharing in help forums such as this where the rest of the complexity of your model is irrelevant). Often you find the problem 'naturally' in the process of trying to construct such a model that reproduces your problem in a minimal way.

Can Semaphores use number operations?

By that I mean, is it acceptable to add to or subtract from semaphores? The example I have is the following:
semaphore secureTarget = 7;
semaphore allClearAlert = 0;
semaphore bellAlert = 0;
Archer:
start();
wait(secureTarget);
wait(allClearAlert);
fireAtTarget();
signal(secureTarget);
wait(secureTarget - 7);
signal(bellAlert);
end();
Boy:
start();
signal(allClearAlert);
wait(bellAlert);
end();
Does that seem acceptable? If it helps, the initial question I'm trying to answer is:
An archery club has seven targets. Archers in the club must compete
to secure a target. Once an archer secures her target she must wait
until the all-clear has been sounded before she can fire. Once an
archer finishes firing she leaves her target. The last archer to finish
sounds the bell that signifies that all have finished firing. Only then
is it safe for the small boy who collects the arrows to venture forth.
When all the arrows have been collected the boy gets out of the firing
lines and sounds the all-clear to the archers.
Semaphores can only be incremented using the signal() and wait() methods, you can't explictly change the variable as you describe. I can't give the solution explictly - looking at your history I think I'm doing the same coursework for the same module and I don't want to be done for plagiarism, but you may find the Little Book of Semaphores useful.
EDIT: you don't have to just use semaphores. You can use other types of shared data, as long as you use a mutex semaphore to control concurrent access to those variables.