HPInc / HP-Digital-Microfluidics

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

Add suport for Glider/HAL sensors (and other Glider changes) #264

Open EvanKirshenbaum opened 5 months ago

EvanKirshenbaum commented 5 months ago

Aaron Bowdle and I are working, in the DynamicHAL (Glider) repository on implementing a general sensor framework that can be used by Bilby (DMFSoftware/DynamicHAL#5, DMFSoftware/DynamicHAL#7) in furtherance of Thylacine being able to support the ESELog sensor, which is needed ASAP.

Being able to communicate with Bilby over the API we're developing there falls somewhere between #206, which is aimed specifically at supporting ESELog and #208, which aims to provide a general notion of being able to support SystemComponents that move, a class that was thought to include ESELog.

This issue aims narrowly at being able to use whatever we come up with on the Glider end of things, but that will include Glider's generalized sensor API.

In addition, as we're working on the sensor API there, I'm changing the way that other things are implemented, and those changes will be reflected in this issue. Most notably, where many of the methods in the C++ code there were of the form

        class IGGliderHAL {
        ...
        virtual ErrorCode EnableHighVoltage() = 0;
                virtual ErrorCode DisableHighVoltage() = 0;
        virtual ErrorCode GetHighVoltage(float &voltage) = 0;
        ...
        };

where the methods always returned an ErrorCode and the caller had to check to see whether it matched ErrorCode::ErrorSuccess and if there was any actual expected return value, it had to be passed back using reference parameters, the new code makes use of the C++23 std::expected<V,E> class, which returns either the (possibly void) expected result or an ErrorCode:

    template <typename T> using ErrorOr = std::expected<T, ErrorCode>;
    using MaybeError = ErrorOr<void>;

        class IGGliderHAL {
        ...
        virtual MaybeError EnableHighVoltage() = 0;
                virtual MaybeError DisableHighVoltage() = 0;
        virtual ErrorOr<float> GetHighVoltage() = 0;
        ...
        };

This is much cleaner on the C++ end, and it means that the corresponding Python class can be annotated as

class Board():
    ...
    def EnableHighVoltage(self) -> Optional[ErrorCode]: ...
    def DisableHighVoltage(self) -> Optional[ErrorCode]: ...
    def GetHighVoltage(self) -> Union[float,ErrorCode]: ...
    ...

which will be more intuitive for Python programmers

Migrated from internal repository. Originally created by @EvanKirshenbaum on Apr 14, 2023 at 4:10 PM PDT.
EvanKirshenbaum commented 5 months ago

This issue was referenced by the following commits before migration:

EvanKirshenbaum commented 5 months ago

See https://github.com/HPInc/HP-Digital-Microfluidics/issues/265 [comment by @EvanKirshenbaum on Apr 17, 2023 at 2:49 PM PDT] for an explanation of the long string of commits.

Migrated from internal repository. Originally created by @EvanKirshenbaum on Apr 17, 2023 at 2:50 PM PDT.
EvanKirshenbaum commented 5 months ago

As part of the rework on the C++ end, methods that used to return ErrorCode now either return Optional[ErrorCode] or Union[ErrorCode,T]. These correspond to the new use of std::expected and represent expected<void, ErrorCode> and expected<T, ErrorCode>, respectively. Doing it this way means that you don't have to continually use comparisons against ErrorCode.ErrorSuccess and you can get normal return values directly.

Migrated from internal repository. Originally created by @EvanKirshenbaum on Apr 17, 2023 at 3:21 PM PDT.