Initial node implementation (#4)

Reviewed-on: #4
Co-authored-by: Zack <zack@bfpower.io>
Co-committed-by: Zack <zack@bfpower.io>
This commit is contained in:
2023-07-19 18:09:13 +00:00
committed by Zachary Sunforge
parent 886fbf0020
commit 6fc828e864
40 changed files with 2079 additions and 44 deletions

View File

@ -1,52 +1,25 @@
# Physical
# Conceptual Design
Physical is a library for interacting with the physical world from a computer. This can broadly be broken down into two categories:
Physical is a library for interacting with the physical world from a computer. This can broadly be broken down into two
categories:
* Collecting and digitizing data from the physical world.
* Controlling devices that take physical action.
As this is a broad purpose physical is intended to run on or interact with a wide range of computer hardware. This broad range of hardware can be categorized into two distinct "layers".
## Concepts
## Computer Hardware Layers
The main concepts of Physical are:
* Peripherals - A peripheral is a minimal set of hardware and firmware that directly interfaces with sensors or controllers (in fact it may be a single hardwired sensor or controller).
* Peripherals are always where analog to digital conversion takes place in the case of inputs and digital to analog conversion takes place in the case of outputs.
* Peripherals are things that run extremely minimal software, either with no dedicated operating system at all or a minimal RTOS such as [Embassy](https://embassy.dev/).
* Peripherals should do very little data processing, usually directly sending collected data to the host in the case of inputs or adjusting electronics components in response to output settings. Potentially a peripheral could have some very simple logic built in for things that need extremely fast response times such as closing a gate between two evacuated solar collectors when one loses vacuum.
* Physical is designed to work with peripherals running arbitrary firmware, i.e. peripherals do not need to be running any components from physical. However, it will eventually be possible for to make firmware for peripherals using firmware.
* Hosts - A host is the computer peripherals are connected to. A host may be a fairly low power single board computer like a raspberry pi 0, all the way up to a 128 core supercomputer.
* Hosts are intended to run full fledged multi-process operating systems such as GNU/Linux.
* Hosts are intended to do the heavy lifting of data processing and decision making for the system being controlled.
## Software Abstractions
* Input - Individual unit for data collection (e.g. an analog input reads a voltage).
* Output - Individual unit for device control.
* Transformation - Some way of transforming data coming from inputs and going to outputs. E.g. transforming an analog input to a type K thermocouple. Transformations are for I/O where many different physical sensors or devices could be plugged into an input or output and need some algorithm applied to the direct data for it to be useful. E.g. analog input reads voltage whether a thermocouple or pressure sensor is connected to it. Transformation will transform the voltage to temperature or pressure.
* Peripheral - Software representation of what's described in "Computer Hardware Layers".
* Peripherals host inputs and outputs.
* Connection - Peripherals could be connected to the host in various ways (SPI, I²C, USB, etc.) different connection methods must be supported in physical.
## Device Builder
* In physical, all configuration must be done ahead of time. That is once the device build phase of the program is complete, there cannot be any change to the configuration.
* Peripherals cannot be added or removed.
* I/O settings cannot be changed.
* The only allowed "change" is to change the value of an output (like setting a digital output to high instead of low).
## Roadmap
- [ ] Minimal implementation of physical for hosts. Think about what components can be separated out and reused for peripherals.
- [ ] Add support for more peripherals (basically aiming to add support for what's needed for early BFPOWER systems).
- [ ] Common abstractions for system control (recording, PID control, etc.)
- [ ] Implementation of physical running directly on peripherals.
- [ ] Kotlin embedded DSL and general API to make simple programs to be run on a physical host (optional).
- [ ] GUI to be run on a physical host to do simple data collection, control, and analysis.
## Questions
* Nested hosts - Should there be abstractions built in to physical for setting one host to be the master of another.
* Leaning towards not having this. Would be better to have slightly more sophisticated peripherals running a RTOS then to have the added complexity of nested hosts.
* Peripheral: A peripheral is a board that hosts physical I/O and usually does analog to digital conversion or
digital to analog conversion. A peripheral cannot function on its own, it must be connected to a node. This is more
narrow than the definition of a peripheral in embedded systems generally. Peripheral support is done on the basis
of complete boards, not individual components like an ADC. Abstractions for individual components should be made
separately, such as in BFPOWER drivers.
* Node: A node hosts peripherals. A node can have a commander but does not need one. A node can ignore or even override
commands from the commander. In a complex system, nodes are intended to be kept simple, less likely to
encounter an error than the commander, and in some cases should check for obvious problems in commands from the
commander.
* Commander: A commander hosts nodes. It is possible for a device to be both a node and a commander at the same time,
although it may not be the best idea to make such a setup. There is no concept of nesting commanders built into
Physical. If some kind of abstraction for a computer that commands multiple commanders, which command nodes, is
necessary, it should be made for that specific application.