Re: Lahman, how ya doing?
- From: "H. S. Lahman" <h.lahman@xxxxxxxxxxx>
- Date: Thu, 28 Apr 2005 17:09:42 GMT
Responding to Hansen...
First, I think there may be a disconnect here over real-time vs. simulation time. A time tick in the simulation can occur at arbitrary intervals in real time to accommodate software processing. However, the rules and policies for what /must/ happen and the order in which it must happen on a given tick are exactly the same for a simulation tick as for a real-time tick. In fact, a necessary condition of a simulation is that it correctly emulates the real-time constraints for what happens on each tick.
Your simulation has to correctly emulate sample processing every 1, 60, and 7/60 ticks in real time. The relative processing between the 1 and 60 ticks and between the 1 and 7/60 ticks AND the state of the simulation must be exactly the same as in a real-time system when those ticks are processed. The simplest way to ensure that in a practical simulation where software processing takes finite time is to tie everything to the 1 tick but let it be triggered only when the software is ready (i.e., everything else is tied to a count of the 1 tick events).
Thus all the software processing responds to 1 tick events exactly like the real-time system on each tick. We use Timer objects for that in practice because the responding software is decoupled from the source of the 1 tick events. IOW, it doesn't matter whether the 1 tick comes from the system clock or is triggered by some other mechanism after an arbitrary real-time delay.
In your <simulation> case the Timer is going to generate a 1 tick event when it is told that all the processing for the last 1 tick is done. But that is completely transparent to the software solution. As far as it is concerned those ticks are off the system clock in real time.
But to make that work properly if there are delays, multiple frequencies, etc., the simulation software is going to have to address exactly the same real-time issues somehow. That may be trivial to do, such as using an event queue manager to serialize things, but the developer must somehow address all of the same real-time problems.
Bottom line: one has to think about the simulation as-if it were real-time when dealing with synchronization, delays, etc. The closer the simulation structure reflects the real-time structure, the easier that will be. For example, the real-time system is proactively triggered by timer events. So don't have the tasks poll a timer and then make a decision about what to do. Construct the software so it reacts explicitly and unequivocally to the events that the timer generates just like the real system. Then you isolate the problem of generating the "real-time" events as a simulation implementation problem for the Timer object rather than as part of emulation abstractions.
I also need jobs that do task 1 at time interval 1, and task 2 at time interval 2. But it won't be hard to add a
time.add_task(&c3, 5, 20);
At the risk of being picky, doesn't this do the /same/ task twice?
No. In the system I want to simulate, there's a sampling time of, say, one second, and an averaging time of, say, 60 seconds. Once per second it takes a data point and calculates a running total and total^2, and once per 60 seconds it calculates and reports an average and standard deviation, and zeroes the totals.
OK, I thought the tasks would be in different objects. So the c3 object has a state machine like(?):
E2:sixty ticks +--------> [Sampled] --------------> [Statistics Computed] | | ^ | | | | | +------------+ +--------------------------+ E1:one tick E1:one tick
and all you are doing is registering it to receive both the E1 and E2 events from the Time object. If so, then it might be simpler to just register via
time.add_task(&c3, 1); time.add_task(&c3, 60);
since the Time object shouldn't care about duplicate handles; it just needs to know where to send the indicated event. Then you don't a special implementation in Time for this case.
I am a little nervous about the notion of 'interval'. That sounds like a hard real-time constraint. I assume this is a delay for settling times or something. But first let me digress to look at the vanilla precedence view where all one needs to do is ensure some task completes before another starts.
Data samples are taken every second and averaged every 60, the control system samples and adjusts every 7/60 second (incommensurate with 60 Hz line noise), the state of the beam changes every half hour, and the analog peices are analog and don't really have an iteration time but should at least be faster than the control system. Those are the intervals.
It's a simulation, so simulated time will be frozen until all tasks complete, in the sense of e.g. getting an input voltage and calculating the output of a simulated gain and filter.
So every 420 seconds when the 1 second, 60 second, and 7/60 second tasks are on the same tick (i.e. Time has put all three events on the queue at the same time), you just let the event queue manager serialize it. That's one of the nice things about event-based simulation. B-)
OTOH, if accuracy requires that when they fall on the same <simulation> tick some precedence rule needs to be applied one might need to include a priority in the event data and let the event queue manager to do the prioritization. (Probably overkill here.)
Which brings up another member function I've added, timer.update_tasks(). I don't want, say, a thermal block at t=10s to be getting a heat input from another block at t=10.1s. So the new state in each block will be saved until they've all been processed, and then transferred to the current state.
I suspect this is really an issue for the heat flow computation needed in the simulation to determine the temperature the Thermometer "reads". (More below.)
You kind of get that for free if you use a single event queue and popping an event doesn't return in the event queue manager until the task is completed. If, though, the timer event is only one of several events that may be issued to complete tasks, one needs a different mechanism.
What I've done so far, I don't think you could really call an event queue. Each task keeps a wait_time and a next_event, and executes and updates when polled with a time >= next_event. Since it's a simulation, I don't think it's really sensible to have an event queue. It's not going to be waiting for a user to decide to click the mouse or anything, except externally to the simulation.
If you have a timer at all it is easier to make it event-based. Then you don't have to write any conditional code or have history attributes. The serialization is essentially free, as in the 1, 60, and 7/60 event case above. At most you may have to have a prioritization scheme. The Timer will be a simpler and more generic as well. And the event queue manager will be entirely reusable (the target &cN is passed in the event).
Note that one can even change the role of the Timer from doling out events based on clock ticks to a arbitrator. Suppose you have an Activity Diagram with multiple dependencies among tasks like
Task1 task2 task3 | | | +----+ +----+ | | | | ===== | | | task4 | | | +-------+ +------+ | | ===== | task5
Now the Timer can manage a suite of semaphores for the tasks. It starts off with one task, say task2 and sends it a trigger event. When task2 completes, it sends back an I'm done event to Timer. Timer then sets the task2 semaphore and and checks its rules (each task has a bitmap of semaphores that must be set for it to execute). It selects some task whose prerequisites are done, say task3. And so on... When all the semaphores are set, Timer clears them and starts over.]
Not that I don't appreciate the insight; I'm reading it and thinking of things to do with it. But I'm looking at a system more like
beam | heater --- thermal block 1 --- heat link --- thermal block 2 --- He bath | thermometer
There isn't a time sequence of events, every part of the system evolves simultaneously. Heat goes from the heater to thermal block 1, heat goes from thermal block 1 to the heat link and to block 2, the temperature and resistance of the thermometer change as the heat load changes, all at the same time. So at a given instant of simulation time I just freeze the state and determine how much heat goes into and out of block 1, how much heat goes into and out of block 2, how much does the temperature of the thermometer change, etc.
That's fine, but I don't think it is relevant to the sampling timer issues. B-) As I understand it you are computing what those actual transfers to the He bath would be in order to simulate what the thermometer would actually see (i.e., the simulated temperature will be the from the net residual heat in thermal block 1 after the heat flow is computed). IOW, you don't care about the propagation delays on the right because all you want is the heat out of the 1st thermal block.
The simple way to march those calculations is to just daisy-chain them. In fact, from an OOA/D viewpoint the calculation of the residual heat the thermometer is sampling would probably be best done in a single realized method. The algorithms are rigidly defined mathematically so they aren't part of the OO problem solution flow of control, which is managing samples in the simulation. That is, the decisions made in the actual heat flow algorithm are orthogonal to the simulation problem, which is about managing when that calculation gets triggered relative to the thermometer sampling and statistics.
That is, on the 1 second <simulation> tick, you calculate: (a) the heat in from the heater, then (b) the residual heat out of the 1st thermal block using the current state of the gizmos on the right, and finally (c) the temperature the thermometer would see on that tick sample after the net heat flow from (b). The 60 second and 7/60 second tick activities are all relative to the thermometer samples collected on the 1 tick events so they are completely independent of the heat flow calculations.
There are some things (in the real system) like moving the shutter to turn the beam on or off, but then block 1 just takes what it gets, it can't wait for it.
That just parameterizes the (a) and (b) calculations above.
What you've described seems more applicable to process control. Like open valve A until so much water flows into a tank, open valve B until so much syrup flows into it, operate the solids feeder until so many solids flow in, blend until so many minutes after all materials have been added and after the contents have reached a desired temperature, etc.
What I am talking about is the sample management for the 1, 60, and 7/60 processing and subsequent feedback simulation of the heater control. None of the stuff on the right of your diagram is relevant to that.
OTOH, suppose you decide that the computation of (b) above is complicated enough by shutters, beam, etc. that you want a more explicit OO solution to manage that sort of dynamics. In that case I would recommend putting that computation in its own subsystem and solving it as a unique problem with abstractions for Beam, Shutter, and the rest of the stuff on the right.
That solution would still be accessed by a single method in the higher level control solution and it would synchronously return the temperature of the 1st thermal block.
But all the directly controllable things that I'm doing, like changing the beam or recording data, have fixed times, or else it's something like analog heat flow that evolves continuously.
The only event that the real apparatus actually watches for is a mouse click, to stop. Nothing else is event driven, it just goes through a loop, checking TickCount() again and again to see if it's the scheduled time to sample a voltage or move the shutter or something. You could write out a schedule of events for every change of state of the system in advance.
I am suggesting that the sample management is event-based for <at least> three different frequencies. It may be simulation time rather than real-time and you can use the the event queue to conveniently serialize the processing, but it will still be the most natural way to solve that part of the problem.
************* There is nothing wrong with me that could not be cured by a capful of Drano.
H. S. Lahman hsl@xxxxxxxxxxxxxxxxx Pathfinder Solutions -- Put MDA to Work http://www.pathfindermda.com blog: http://pathfinderpeople.blogs.com/hslahman (888)OOA-PATH
.
- Follow-Ups:
- Re: Lahman, how ya doing?
- From: Gregory L. Hansen
- Re: Lahman, how ya doing?
- References:
- Lahman, how ya doing?
- From: Gregory L. Hansen
- Re: Lahman, how ya doing?
- From: H. S. Lahman
- Re: Lahman, how ya doing?
- From: Gregory L. Hansen
- Re: Lahman, how ya doing?
- From: H. S. Lahman
- Re: Lahman, how ya doing?
- From: Gregory L. Hansen
- Lahman, how ya doing?
- Prev by Date: Re: When and where to use Visitor Pattern?
- Next by Date: Re: UML metamodel
- Previous by thread: Re: Lahman, how ya doing?
- Next by thread: Re: Lahman, how ya doing?
- Index(es):
Relevant Pages
|