I'm trying to model a conveyor line that should work over time, by the signal of sensors.
The model have a lot of these conveyors in sequence, and I'm modeling the Conveyors behavior with it's most important characteristics, in order to have an accurate result on the Sim.
So far, I've managed to do the following, on an inherited class i created (by duplicating the default Line object):
- Every of these conveyors have a Sensor near it's end (around 0.2 or 0.3m from it's end);
- The Conveyor, when the Successor conveyor is blocked/stopped/notworking/etc, will stop (change its speed to 0) when a MU reach its sensor (not at the end of the line);
- The Conveyor default state is stopped, with 0 speed. When it's own sensor is triggered, or when it's Predecessor Conveyor's sensor is triggered, it changes it's speed to a nominal speed definied in an attribute. This way, it simulates the accel and decel accordingly, and when there's a peak on the demand the MUs correctly stops at the sensors - not exactly at the sensors, a bit ahead because of the decel time (this is intended);
- When a Conveyor receives a "signal" to start (change it's speed from 0 to nominal), it waits a short predefined time to start;
- When a MU enters a Conveyor, it checks if the current speed of the Conveyor is >= a certain ratio (defined as an attribute), and print an alert that I let an MU enter while the Conveyor was still accelerating up (on real world, some specific MUs can fall from the conveyor if this happens). This will mean that i will have to wait more time to let the Successor ramp up, and waiting more time will impact on the product flow and will cascade these consequences upstream the model, etc.
Those characteristics are working fine. But there is one problem that I'm facing: to make these Conveyors start/stop with a timed demand. Right now, I added an Observer to "NumMU", and made the Conveyor stop when there's no MUs on it; but this is not the right behavior (actually, this is a worst case scenario, where everytime the Conveyor gets empty, its Sucessor will need to ramp up and I will need to wait a short time; I need to define a smal "run after" time but, as i said above, this time should be dynamically resetable/changeable).
What I need something like this:
- Every Conveyor would have an "DemandSetPoint" time value, that is the minimum time it is expected to run. So everytime it receives an event ordering it to start/run, it will run until "root.EventController.SimTime + self.DemandSetPoint".
- But everytime a new MU arrives at its own or its predecessor sensor, it should re-set this time, for example:
A) The DemandSetPoint is 5, and the Conveyor started at SimTime=2. So it should stay running until SimTime=7;
B) In the event of another MU arrives at SimTime=5, the same Conveyor should not stop at SimTime=7 anymore, but only at SimTime=10, and keep rescheduling if more events happen when it's still running.
So, I tried the following approaches, without success:
- Setting a "DemandUntil" attribute at the Conveyors. Every time a new event reaches, I set DemandUntil to "root.EventController.SimTime + self.DemandSetPoint"... But how do I observe this? I tried writing an observe method for "SimTime" on the EventController to check on all Conveyors if "DemandUntil >= SimTime", so I order the Conveyor to stop.... but this seems to make the Simulation so much slow!
- Using methCall. I tried to set a method to run "DemandSetPoint" time units in the future. Seems ok for the A) case above, but for B), it won't work because it doesn't seem to be a way to reschedule or cancel and already made methCall (or is it?!). I tried to reschedule the methCall by forcing to overwrite the value at "EventList" on EvenController... but it seems to be read only.
- I also considered to model a Trigger object for each Conveyor... but this i did not tried. I would actually prefer a solution that doesn't involve adding a Trigger object to each Conveyor, and I'm not sure if it would fit my needs.
Uhmn, do you have any better idea on how to model this "time demand" logic for the Lines?
Solved! Go to Solution.
You can cancel/disable a scheduled method
by checking at the beginning of the method whether it should be continued /processed or not and
if not cancelling the methodcode with a "return"
Before the "return" you can add a new methcall for rescheduling the method.
freelance simulation specialist
Thanks, stephen and simulator!
I didn't figure out that i can schedule various methcalls and have like a flag to return if a methcall scheduled in the past turned out to don't be relevant anymore when it's time to execute has come.
I was trying to find a way to reschedule to avoid a lot of methcalls, and wondering if writing too many "custom code" for an object would impact performance, as one of the solutions i was trying seemed to do. But just having a flag and a return, like simulator pointed out, or comparing and letting that method do nothing if a newer method got scheduled ,like stephen's answer, do what I need.