Re: Lahman, how ya doing?



In article <42700764.80205@xxxxxxxxxx>, cstb <jas@xxxxxxxxxx> wrote:
>
>
>Gregory L. Hansen wrote:
>...snip...
>> including a
>> chart recorder that saves as a data point an average and standard
>> deviation over a given time. That's what DoubleTimer is for, because
>> there will be a sampling time and an averaging time, similarly to the
>> apparatus. But it reflects what I want "real" to be. There'll be
>> separate timers for the analog peices, the digital controllers, the chart
>> recorders, and the switch that turns the beam on and off-- four total,
>> each with one or more tasks, or control blocks, to manage. All on one
>> clock.
>
>
>As another approach, you might have the tasks schedule themselves,
>rather than deal with a master-scheduler, queues, events, and timers.
>To schedule itself, a task just needs to delay its own execution until
>its schedulingInterval has elapsed, then doTheRightThing, and loop.

I think that's sort of what I do. I think I wasn't clear, but when
timer.add_task(&c1,5) is called, internally it creates a task object,
which the user will never see, with a wait_time of 5 seconds, and
initializes some other variables to track the timing, and attaches the
control block pointer &c1 and puts it in the queue. At each tick, each
task is given the current time. Each task figures out whether to trigger
its control block, and when it does so passes the elapsed time
dt=current_time-last_action and schedules the time of the next trigger.

The control blocks can be connected to each other and pass information
between each other, but the only information they get from the timer is
the elapsed time since their last trigger. They don't even know the
current time, unless they've been summing the intervals.

I have a master clock ticking each task because something has to control
the process. I'm running in simulated time, not real time, so the system
clock is basically meaningless. But the timer just goes through the queue
and reports the current (simulated) time, each Task in the queue decides
what to do about it.

>
>
>For example, the following depicts a generic "chart recorder"...

Hmm... I'm a C++ guy. I'll have to do a little guessing at the code
below.

>
>-----
>
>ChartRecorder>>
> iVars := samples samplingProcess AveragingProcess
>
>
>ChartRecorder>>sample: sBlock every: sTime avg: avgBlock every: avgTime
>
> | samplingDelay averagingDelay |
> self stopRecording.
> samplingInterval := Delay for: sTime.
> averagingInterval := Delay for: avgTime.
> samplingProcess :=
> [ | singleton |
> samplingInterval wait.
> self samples add: #skip -> #pre.
> singleton := self samples.
> singleton add: #valid -> sBlock value.
> singleton add: #skip -> #post
> ] fork.
> averagingProcess :=
> [ | capturedSamples |
> averagingInterval wait.
> capturedSamples := self captureSamples.
> avgBlock value: capturedSamples
> ] fork.
>
>
>ChartRecorder>>samples
> ^samples
>
>
>ChartRecorder>>captureSamples
> | snagged noLongerBeingAddedInto theValidPairs justTheSamples |
> snagged := self samples.
> samples := OrderedCollection new.
> [ snagged isEmpty
> or: [snagged last value == #post]
> ] whileFalse: [Process yield].
> noLongerBeingAddedInto := snagged.
> theValidPairs :=
> noLongerBeingAddedInto select: [:each| each key == #valid].
> justTheSamples := theValidPairs collect: [:each| each value].
> ^justTheSamples
>
>
>ChartRecorder>>stopRecording
> averagingProcess terminate.
> samplingProcess terminate.
> samples := nil
>
>-----
>
>
>The other tasks appear similar this one.
>Each of them either "knows" its own scheduling interval(s),
>or can be told the interval(s) whenever it is being started.
>
>Assuming your OS provides some kind of multitasking,
>it should already do what you want done - and if so,
>you can just use that. If not, you might still want
>to consider building a "Delay" unit, rather than a "Timer".
>
>There doesn't appear to be any value-add (in your context)
>to building a custom master/queue/event handling dispatcher.

I'm having a little trouble following you, but to be clear, this is a
simulation. It's not a device controller, it doesn't run in real-time.
ControlBlocks include things like thermal blocks whose temperature change
in response to heat inputs and outputs must be calculated, and the
temperature change at 10 seconds must be in response to heat inputs at 10
seconds, and not at 8 seconds or 12 seconds. So the major reason to
collect the tasks in a queue instead of forking off a bunch of independent
processes (besides having an old OS that doesn't easily support that) is
to ensure that every block stays synchronized in (simulated) time.
Advance time by one tick, update every block, advance time by another
tick, update every block, etc.
--
"Very well, he replied, I allow you cow's dung in place of human
excrement; bake your bread on that." -- Ezekiel 4:15
.