Open EvanKirshenbaum opened 5 months ago
This issue was referenced by the following commits before migration:
DML now has a CLOCK type, which is a BINARY_COMPONENT, so you can say
the clock : on;
if the clock is on { ... }
s = the clock's current state;
You can also specifically say
the board's clock;
the clock is running; // and paused
pause the clock; // and resume, start, restart
the clock's update interval = 100ms;
the clock's update rate = 20 Hz;
the clock's update rate = 5/second;
I spent a little bit of time trying to figure out how to say
the clock's update interval = 20 ms/tick;
the clock's rate = 5 ticks/second;
but it turned out to be surprisingly tricky, so I'm going to postpone that for later (assuming later comes).
Just to get it down, what I was trying was to get rid of the unit_recip_expr
rule and generalize dim_unit
to possibly take divisions:
dim_unit returns[tuple[Optional[PhysUnit], Optional[Unit]] units]
: ('per' | DIV) denom=simple_dim_unit {$ctx.unit=(None, $denom.unit)}
| non_recip_unit {$ctx.units=$non_recip_unit.units}
;
non_recip_unit returns[tuple[PhysUnit, Optional[Unit]] units]
: num=maybe_env_unit ('per' | DIV) denom=simple_dim_unit {$ctx.unit=($num.unit, $denom.unit)}
| num=maybe_env_unit {$ctx.unit=($num.unit, None)}
;
maybe_env_unit returns[PhysUnit unit]
: ('drop' | 'drops') {$ctx.unit=EnvRelativeUnit.DROP}
| simple_dim_unit{$ctx.unit=$simple_dim_unit.unit}
;
simple_dim_unit returns[Unit unit]
: ('s' | 'sec' | 'secs' | 'second' | 'seconds') {$ctx.unit=SI.sec}
| ('ms' | 'millisecond' | 'milliseconds') {$ctx.unit=SI.ms}
| ('minute' | 'minutes' | 'min' | 'mins') {$ctx.unit=SI.minutes}
| ('hour' | 'hours' | 'hr' | 'hrs') {$ctx.unit=SI.hours}
| ('uL' | 'ul' | 'microliter' | 'microlitre' | 'microliters' | 'microlitres') {$ctx.unit=SI.uL}
| ('mL' | 'ml' | 'milliliter' | 'millilitre' | 'milliliters' | 'millilitres') {$ctx.unit=SI.mL}
| ('tick' | 'ticks') {$ctx.unit=ticks}
| ('V' | 'volt' | 'volts') {$ctx.unit=SI.volts}
| ('mV' | 'millivolt' | 'millivolts') {$ctx.unit=SI.millivolts}
| ('Hz' | 'hz') {$ctx.unit=SI.hertz}
;
But getting that to work not only for 5/second
and 5 ticks per second
, but also 5 drops per second
(since drops
needs to come from the environment) and the clock's update interval in ms/tick
and the clock's update rate's magnitude in ticks/second
quickly got hairy. Not to mention that allowing this makes it seem like you should be able to say things like 5 ticks every 3 seconds
.
Okay, it turns out that making Clock
a BinaryComponent
breaks the hybrid Bilby/Yaminon model. I've reorganized things a bit,
Config.owns_externals
that the model can set to False
when building its internal Yaminon board.This seems to work, but unfortunately, the resulting board is just a Wombat board, not a Yaminon board. Looking into it, it appears that
with (wombat.Config.is_yaminon >> True
and device.Config.owns_externals >> False
):
self._yaminon = wombat.Board()
is somehow making Config.is_yaminon
read as False
. I'll look into what's happening with conjoined overrides to see whether (and why) it's taking the second override instead of the first.
Mike pointed out that it would be useful to be able to control the clock from the macro language. (He suggested it in the context of implementing pausing for user input #219, but it's a good idea in general.)
The easiest way is probably to add a
clock
type (Type.CLOCK
) as aType.BINARY_COMPONENT
. I'm not sure why the internalClock
class isn't aBinaryComponent
. I guess it may be thatBinaryComponent
is specifically aBoardComponent
(I forget why, theboard
attribute doesn't appear to be used) andClock
isn't. But I could probably split outBinaryBoardComponent
or just make the currentBinaryComponent
s inherit from both.In any case, doing this and giving myself a
**CLOCK**
special variable would allow the user to talk aboutclock
orthe clock
.Making it a binary component would allow the user to say
We could also give the clock attributes such as
[update] interval
,[update] rate
(orspeed
),next tick
, andcurrent tick
. Also properties such aspaused
andrunning
It would probably be worthwhile to add a
pause [the] clock
expression, which would be equivalent to turning the clock off and resuming once it was turned on (either by other code running in parallel or by the user hitting theRUN
button). This could be done by turning it off and then delaying the future post to after the next tick.To handle the
update rate
properly, I'll want to add afrequency
type andHz
/hertz
units, with the ability to divide numbers by time and frequency to interchange. To be able to handle forms like5/sec
, I'll want to put an optional (but checkable)DIV
in theunit_expr
rule:On the other hand, if I want to be able to support things like
2 ticks/second
, I may want to simply have a second division operator that takes a unit as its rhs.For completeness, I also jotted down on my board
but those are probably not that important. Simple division should be sufficient.
Migrated from internal repository. Originally created by @EvanKirshenbaum on Jan 20, 2023 at 2:36 PM PST.