Re: Lahman, how ya doing?
- From: "H. S. Lahman" <h.lahman@xxxxxxxxxxx>
- Date: Tue, 17 May 2005 19:51:48 GMT
Responding to Hansen...
The second way.
Controller -> Target -> Thermometer | | -----------<------------
Straightforward diagram right out of a control theory text (not really an OOA diagram). Normally Controller would be sent a control event, and would then get a temperature and sample time from Thermometer and calculate a control action. Instead, ControllerSubstitute would be sent a control event. Usually it would immediately send a control event to Controller. But if it had previously received a delay event, it would send a control event to Controller on the next tick. If it is sent two or
three delay events in succession (two or three identical events sent to the same object on a single tick), it can delay two or three ticks.
But ControllerSubstitute just seems like another name for Delay above. It still seems like something inserted into the feedback loop after Thermometer and before Controller.
When I saw the diagram I thought you were going to suggest that the event that triggers Controller is generated by Thermometer rather than Timer. IOW, if nothing has changed because of the delay, Controller doesn't do anything.
That's a data flow diagram like you'd get in a control theory book, not an event flow diagram. The event flows would look like
Timer --> SubstituteController -> Controller | -> Target | -> Thermometer
Controller still gets its data from Thermometer, Thermometer from Target, Target from Controller. SubstituteController doesn't get data at all, it just gets events. And it's the only object besides Timer that generates any events. It's a substitute as far as Timer sending control events is concerned, not as far as Target and Thermometer are concerned. Too many arrows for ASCII, and Greg's not really sure how to represent it with pencil and paper anyway, and perhaps his naming conventions aren't always the best.
Who's Greg? If we are doing tag teams I will have to get a partner.
I am arguing for eliminating SubstituteController because all it is really doing is delaying the Controller processing until Thermometer has the data ready. So let Thermometer announce to Controller that the data is ready directly and then let Controller do it thing with the data. Then there is no need for a delay because Thermometer issues the event when it is done -- whenever that is. [Any delay that emulates witching tick delays in the real controller is handled by using two threads whose priorities are tinkered with until the simulation provides a faithful emulation of skipped processing. However, as I discovered further below, that won't work. But as an academic exercise...]
A UML Sequence Diagram or Collaboration Diagram does a good job of representing events. Check it out in your new book. B-) What I am arguing for is essentially (assuming some content from previous missives):
Timer Thermometer Sampler Controller Target | | | | | | E1:one tick | | | | |------------->| | | | | | E2:sample | | | | |---------------->| | | | | | | | | | E6:sampled | | | | |<----------------| | | | | | | | | E3:60th tick | | | | |------------->| | | | | | E4:analyze | | | | |----------------------------->| | | | | | E5:change | | | | |------------>| | | | | | | E1:one tick | | | | |---------------------------------------------------------->| | | | | | | | | | E7:done | |<----------------------------------------------------------| | | | | |
This is the Collaboration Diagram form where the sequence is not absolute in time (e.g., there are many E1 -> E2 -> E6 sequences for each E3 -> E4 -> E5 sequence). So Thermometer could get another E1 tick before Sampler generates the E6 event. Here Thermometer and Sampler run in different threads, as I assumed previously. So on a witching tick the slower Sampler thread will result in a skipped E1 tick sample.
I am also assuming Controller is doing the heavyweight data analysis and Target just emulates the initial response to whatever Controller has defined as the new stimuli state. I also assume Target is the front end for the heat flow calculations needed to produce a temperature value on each tick in the simulation. So Target also needs to get an E1 event from Timer to trigger that computation. When that <presumably lengthy> computation is done, one is ready for another Timer tick so Target sends the E7 event (as an alternative to a self-directed event by Timer).
As I recall your original description, the feedback loop actually has a lot of processing in with filters, FFTs, etc. that chews on a large number of samples gathered over a relatively long period compared to the sampling rate. So you really have:
Controller ---> Target ---> Thermometer ^ | | | +------- Analysis <----------+
Once the Analysis is done, one knows what the Controller needs to do, so one could trigger Controller as soon as Analysis finishes. If when Analysis finishes varies for whatever reason relative to Timer's ideal schedule one could insert a delay mechanism to defer Timer's event to Controller. But wouldn't it be simpler to just let Analysis generate the event when it is done with the current pile of data?
Similarly, Analysis should be able to kick off its processing whenever there are enough data samples available from Thermometer. [An obvious exception is the 7/60 adjustment for 60 cycle noise that I assume is part of Analysis. But hopefully that can be split out as a preliminary preprocessing of the sample set and this discussion would apply to the stuff after that.] Again, any skips/delays seem upstream and Analysis could get triggered by whoever deems there are enough <preprocessed> samples rather than by Timer.
I include Analysis with Controller. Controller gets an error signal, V_temperature - V_setpoint. It's sensible, I think, to include the lock-in with Thermometer, and the output is a voltage, not a temperature. And it's a differential measurement, so the lock-in output is the error signal. So I didn't really have an Analysis block in there. I had a Delay block in the first diagram, but that's specifically a delay, it doesn't analyze anything.
I am suggesting that it might be useful to break up the processing. Controller really has two distinct responsibilities. One is to do all the feedback loop computations that are needed to determine what the stimulus should do on the next cycle. The other is to actually write to the hardware to effect that change.
The problem is that in the simulation you don't write to hardware. Instead you need to provide some data for your heat flow calculations. IOW, the second responsibility becomes unique to the simulation while the first is indistinguishable from what the real controller does. On general principles I would opt for separating those concerns simply because it allows you to isolate the simulation processing from the invariant controller processing.
The timing would then be Controller, 7/60; Target, analog; Thermometer, analog. Anything analog I assume will be at the highest time resolution the simulation offers, whatever that might be.
Good point. My bad; I should have thought of this before. I assume the heat flow calculations needed to emulate temperature readings from the analog hardware will take a whole lot more time than anything except (possibly) the feedback calculations. That presents a problem because they /must/ be completed within a tick or the temperature "read" won't be consistent. So there is no way to "slow down" the temperature sampling via thread priorities to produce skips in the simulation; the sampling logic in Thermometer/Sampler is so trivial compared to those necessary simulation calculations that it will surely get done within a tick even at the lowest priority.
IF the skip is purely because of accumulated witching tick processing AND the skip is simply missing a sample for the witching tick, then there is a fairly simple solution. When Sampler (in my version) gets E2, it first queries Timer to see how many events it is generating for the current tick, which is a reasonable thing for Timer to know given the architecture. If the count is enough to cause a skip, Sampler essentially does nothing and just returns E6:sampled (maybe with a better name now). IOW, we are back to what was essentially your original suggestion except for slightly different semantics on the condition. B-)
However, I making a lot of assumptions here about the nature of skips. Too many to throw out ideas in James Joyce mode as I type eMails. So let me kick up the level of abstraction. Basically we have a behavior that, in the simulation, needs to be ignored on some ticks. I think there are basically four design alternatives for the skip.
(1) Insert a "delay" between whoever generates the normally scheduled event and whoever responds with the processing that must be skipped for the current tick. In effect the delay is such that when the incoming event is re-dispatched it is in the next tick. (This was your first feedback loop diagram.) I think finding a reasonable mechanism for the delay would be tricky, given the disparities in processing time. It also gets a bit hoaky because the "delay" may get another tickle in the next tick and it should not double dispatch in that tick. In that situation one is essentially doing (4) below.
(2) Find a way to sequence events to take care of the problem as a faithful emulation of the real controller. For example,
Timer Target Thermometer ...
| | |
| E1:one tick | |
|------------->| |
| | |
| | E7:done |
|<-----------------------------|
| | |
| E1:one tick | |
|----------------------------->|
| | | E2:sample
| | |------------>
[Remainder same as above]In this case Timer always sends the E1 event to Target as the first thing done in a "simulation tick". Only when it gets back the E7 event does is burst out the events in eventList. Now that the simulation calculations are out of the way we can revert to the thread priority solution for the witching ticks as discussed previously. (Of course one now has to have some other means of telling Timer it is time to kick off a new simulation tick, like the self-directed event.)
(3) Have Timer determine whether an event should be sent on a given tick or deferred. We've been around on this before and I don't like it because it trashes Timer's cohesion as a provider of just the Master Schedule.
(4) Have whoever owns the processing to be skipped decide if it should be ignored. I don't have a problem with this per se, but I would be very cautious about what the decision semantics should be. That is, I wouldn't want that object to have to understand the semantics around skips (e.g., what a witching tick is). Asking Timer for an event count on the tick and then comparing that to a <parameterized> attribute to determine whether it should skip the processing is pretty abstracted (i.e., it doesn't need to know anything about why the threshold is the given value). This is full circle to essentially your original solution; just the decision semantics are somewhat different to raise my comfort level.
So the Timer would only synchronize the events that trigger gathering and preprocessing the temperature samples. Once the samples were gathered and preprocessed -- in however much time it took -- everything else in the feedback look could be daisy-chained from the owner of the samples (presumably Thermometer). If so,...
And in an explicit concession to you making more sense now, that relationship can be expressed in main() by registering events with Timer to ControllerSubstitute, but not to Controller. Controller is registered with ControllerSubstitute. And then Controller doesn't know it's not getting its events from Timer, it just knows that sometimes it gets events.
...the feedback loop events don't need to be registered because they aren't issued by Timer on a fixed schedule.
I don't know. Say Controller receives a control event every 7 ticks and the other parts receive an analog time evolution event every tick. Then something would have to count out 7 ticks before sending a control event to Controller, and that would essentially be a Timer. You could stick a second Timer in the loop that receives tick events from Thermometer and sends control events to Controller.
I am not sure why the feedback processing needs additional ticks. Once the data is ready isn't it a pretty linear computation? (I am assuming the 7/60 filtering for 60 cycle harmonics is a preprocessing operation once one has an adequate set of samples in hand.)
However, if the feedback computations need to march to a drummer, you are right that all one needs is a different instance of Timer that is initialized with a different set of events.
But I don't really think of, say, Thermometer telling Controller what to do. Thermometer just has data for Controller when Controller needs it.
What I am proposing further above is that Thermometer also has a responsibility for knowing when enough data has been accumulated (and perhaps when it has been preprocessed). It then announces that to Controller. Controller then accesses the data to do its thing.
************* 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:
- 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
- Re: Lahman, how ya doing?
- Prev by Date: Re: A Java Brainteaser - a Static Factory method Narrative
- Next by Date: Re: Lahman, how ya doing?
- Previous by thread: Re: Lahman, how ya doing?
- Next by thread: Re: Lahman, how ya doing?
- Index(es):
Relevant Pages
|