Package: mindstone
MindstoneThe mindstone package offers an easy to use framework for creating control systems.
This package houses a collection of tools that make it possible
for a remote processing source to control a local actor.The package defines two entities. The first being whats known as a driver. This entity
interfaces directly with a given platform, such as a Raspberry Pi micro-controller,
and acts as a bridge between said platform and a higher functioning controller.
The other entity is the controller. The controller handles most of the processing and
defines the behaviours and protocols by which a driver operates. The controller does
this by processing objects called gates. These gates are connected to each other to form a network.
Gates represent simple processes that can be ordered and arranged in
different ways to produce different behaviours. Gates also allow users to extend the
functions of a control system by allowing users to embed their own custom-made functions
and operations into the network.InstallingInstall and update usingpippip install mindstoneClone from Githubgit clone https://github.com/joshuasello/mindstone.gitBasic UsageCreating a driverOn the driver's platform, the mindstone package can be
create a new driver in the following way:frommindstone.embeddedimportstart_driverif__name__=='__main__':start_driver("raspberry",hostname="10.0.0.1",port=50000)This will start the connection on the driver's side, allowing
for a new controller to connect to it. In this case, the platform
used by the driver is the Raspberry Pi platform.Creating a Controllerfrommindstone.controlimport*defchange_servo_angle(**kwargs):return{"test_component_1":{"angle":90,"is_active":True}}gates=[RootGate("host_1",{"my_component":("servo",{"model":"SG90","trigger":8})}),FunctionGate(change_servo_angle),ConfigGate("host_1")]connections=[(0,1),(1,2)]hosts={"host_1":("10.0.0.1",50000)}my_controller=Controller(gates,connections,hosts)final_received_data=my_controller.run()Importing the controller toolsBefore we can start creating our controller we need to import all the
necessary tools:frommindstone.controlimport*Setting up the gates and gate connectionsgates=[RootGate("host_1",{"my_component":("servo",{"model":"SG90","trigger":8})}),FunctionGate(change_servo_angle),ConfigGate("host_1")]connections=[(0,1),(1,2)]hosts={"host_1":(get_hostname(),50000)}Each gate performs a specific task when activated.
The root gateRootGate()is where it all begins. When activated, it initializes the
connection with the driver. During this connection, it tells the driver what components
the driver should register with the platform it is on, and receives information about
the connected driver that can be used by the rest of the gates in the network.The function gateFunctionGate()executes a callable when triggered. This callable
takes in the data received from the previous gate and outputs new
data in the form of a python dictionary.Lastly, the configuration gateConfigGate()is used to communicate new configurations for
components that are in use by the driver. This will send the data from the previous gate as a
new configuration to the connected driver. Essentially, if you are only connecting to one host,
during the runtime of your network, only one configuration gate is needed.To connect the gates to each other to form the network, the indices of the the gates in the
list that holds them are used to identify each gate. Alternatively, a dictionary could also
be used where keywords are instead used to identify gates.For gates that need to communicate with the driver (like the root gate and the configuration gate), a
host needs to be attached so that the gate knows where it should connect to. these hosts are defined
using a dictionary object, such as the one used in the above example. It is then passed into the controller,
along with the gates and connection, when the controller is being initialized.
It is important to make sure that any host a gate uses in the network is listed in this dictionary.Initializing the controllermy_controller=Controller(gates,connections,hosts)final_received_data=my_controller.run()Now that everything has been set up, we can finally initialize the controller object.
once initialized, the controller can be activated using therun()method.ContributersJoshua Sello