HPInc / HP-Digital-Microfluidics

HP Digital Microfluidics Software Platform and Libraries
MIT License
2 stars 0 forks source link

Add Generic Boards and Board Description Language (BDL) #263

Open EvanKirshenbaum opened 5 months ago

EvanKirshenbaum commented 5 months ago

Currently, aside from a simple OpenDrop board, the only board layout is joey.Board. This is described in joey.py as a purely-simulated Board implementation, with subclasses wombat.Board and bilby.Board, which define ways of actually communicating with the board and changes to its characteristics. In the case of bilby, information on the position of the heaters and magnets is obtained from the device itself, while with wombat (which uses an opendrop controller), only some of the rows are live, and not all of the pads in some of the live rows are, in fact, live. (This is due to the controller having a very limited number of electrodes that can be controlled.)

As people have used wombat, changes have been made. The live pads and extraction point locations changed, which led to the addition of a WombatLayout enum to allow the user to specify which type of board they had. Some boards (called yaminon) replicate the signals to a different area of the board, leading to the ability to specify an is_yaminon parameter to get that behavior. Plastic and glass lids on V2 layouts have different heights, yielding to different dispensed volumes, so a LidType enum was introduced. All of these changes required changes to the Python code, which needed to be pushed out to users (many of which don't have GitHub access), and all required adding command-line parameters to allow the user to specify the particulars of the board they were using.

It appears likely that in the near future, the crew will be experimenting with TFT-based boards that are much larger and may not actually have wells at all. These boards will talk to the controller in a completely different way (passing some sort of bitmap).

In #122, I proposed making the Joey layout dynamically configurable by specifying on the command line where things like magnets and extraction points and heaters were. Later in that thread (https://github.com/HPInc/HP-Digital-Microfluidics/issues/122) [comment by @EvanKirshenbaum on Feb 02, 2023 at 2:54 PM PST], I realized that what I really want is a specification language:

I think that what makes the most sense now is too write a little ANTLR grammar for board specifications that will allow you to say something like

board Joey {
   pads from (a,b) to (c,d);  // lower left to upper right
   dead zone from (a,b) to (c,d);
   heating zone from ...
   magnet at ...
   extraction point at ...
   drop size = ...
   min clock speed = ...
   max clock speed = ...
   sensor target = ...
   well exiting west at ...
   wells have n internal pads
   well transitions from READY to DISPENSED by ...
}

board Joey v2 = Joey except {
   override magnets;
   add magnet at ...;
}

and then allow selection by command-line argument.

It might be nice to be able to talk about components with multiple instances by name in DMF language and have them named here.

As of my new work plan, I'm calling this language, the Board Description Language (BDL), and I think that it's the way to go.

Migrated from internal repository. Originally created by @EvanKirshenbaum on Mar 29, 2023 at 11:47 AM PDT.
EvanKirshenbaum commented 5 months ago

My current plan is to create a BDL grammar and compiler, which takes a BDL specification and creates a BoardDescription object. I will also design an abstract BoardProxy class that encapsulates actual communication with the board in three ways:

  1. To instruct the board to change state.
  2. To query the board for its current state.
  3. To query the board for its layout.

The proxy may not support one or both of the querying functions (and may not fully support the ones it supports). There will be a built in BoardSimulator proxy that doesn't attempt any actual communication and possibly a ComposedProxy that allows you to specify a list of proxies and uses the first one that supports a function. To that, we would need to add OpenDropProxy, GliderProxy, and TFTProxy.

With this, we can write a GenericBoard that takes a BoardDescription and an optional BoardProxy (defaulting to BoardSimulator).

If this is done right, almost all changes can probably be left to the user to specify in a .bdl file (possibly including others if we have a search path (#230)) specified on the command line. It will only be when a new type of controller is used that anybody will have to write Python code, and then only to create a BoardProxy subclass.

Migrated from internal repository. Originally created by @EvanKirshenbaum on Mar 29, 2023 at 12:00 PM PDT.
EvanKirshenbaum commented 5 months ago

One thing that will need to be able to be specified somehow is that we sometimes want to specify things like magnet locations in BDL and sometimes (e.g., with a GliderProxy) want to get them from the hardware itself. That can be done in BDL (e.g., from hardware) or the proxy can know to trust the hardware and perhaps warn if it conflicts with what is specified in the description.

Migrated from internal repository. Originally created by @EvanKirshenbaum on Mar 29, 2023 at 12:02 PM PDT.