synnax icon indicating copy to clipboard operation
synnax copied to clipboard

Python Client - Sensor Simulation

Open emilbon99 opened this issue 10 months ago • 2 comments

Background

As with writing good software, implementing solid hardware control sequences involves extensively testing them in a variety of scenarios, including edge cases.

Testing software that interacts with hardware is uniquely challenging. Software systems can typically be tested extensively in isolation, where the behavior of small modules can be separated and asserted on independently. Hardware control sequences depend on physical phenomena from sensor readings or actuator changes. If you don't have the physical system assembled, it very difficult to meaningfully test.

Assembling a complex hardware system after every software change is time consuming, resource intensive, and, in many cases, poses significant safety risks.

The solution is to simulate physical behavior using software. Accurately modeling physical responses based on device actuations is difficult, and, generally speaking, the complexity of doing so scales exponentially with the size of the assembly being simulated. There's a reason why software like simulink has taken millions of dollars, dozens of employees, and many years to build.

Implementation Thoughts

The approach here should not be to model the physics with perfect accuracy, but to determine an appropriate degree of precision in which the assertions we make on the behavior of a particular control sequence are meaningful.

As an example, imaging we're writing a simple sequence for cryogenic tank pressure maintenance:

import synnax as sy

client = sy.Synnax()

LOWER_BOUND, UPPER_BOUND = 90, 100 #psi

with client.control("TPC") as auto:
    while True:
         auto.wait_until(lambda auto: auto.tank_pt > 100)
         auto.vent.open()
         auto.wait_until(lambda auto: auto.tank_pt < 90)
         auto.vent.close()

In this case, modeling the perfect parabolic curve of the tank pressure drop when we open the vent clearly isn't necessary to assert that we close the valve at 90 PSI. A simple linear drop would do just fine:

# Imaging we're running at 20Hz, and every 50 ms the `on_change` function is called 
# by some controlling class.
class TankSimulation:
    # How quickly the tank changes pressure under these conditions. 
    slope: number

    def __init__(slope: number):
      self.slope = slope
       
    def on_change(state: SystemState):
        # If vent is open, drop the tank pressure by the step
        if state.vlv1.is_open():
            return state.tank_pt - self.step
        # if its closed, increase the tank pressure by the step
        return state.tank_pt + self.step

This implementation is very crude, and definitely needs fleshing out, but it gives a gist of what we're trying to accomplish: whats the simplest meaningful simulation for testing our control sequence?.

Another option might be to not implement sensor simulation ourselves, and instead see if we can link in to some other software to do it for us e.g. simulink. Research is necessary in this area.

Success Criteria

The difficulty with establishing success criteria for this issue is that we're in the middle of implementing the auto sequence engine itself, so there's really no concrete set of interfaces to build against. That being said, what I'm thinking is the following:

  1. What does the architecture look like for a simulation engine, that, given the current state of the system, can produce the next state? Ideally this system is highly configurable meaning you can swap in and out physical phenomena to test under different scenarios.
  2. What are the base set of behaviors we need to be able to simulate? Tanks, thermocouples, structural loads?
  3. Implement this system for the above scenario of tank pressure maintenance.

This is ticket is pretty broad and challenging, and will require a fair amount of critical thinking and research to accomplish successfully. My hope is that as we lay down the foundations of the auto sequence engine, building a concrete implementation here will be less challenging. For now, focus on developing an understanding of the problem, and building out a high level architecture/strategy.

Stuff that is Good to Know

Learning and reading about the following topics is the best place to get started.

Python, Python, Python. Make sure you're brushed up on all the python basics (variables, functions, lists, dicts, sets, classes, maps, lambda expressions, ternary expressions, list comprehensions, iterators). Here are the intermediate to advanced topics that I think are also really important:

  1. Type Hinting/Static Typing. All of the Synnax code base is statically typed.
  2. Interfaces, and, in pythons specifically, Protocol classes.
  3. Composition as a Design Pattern -> This one is really important. In college CS classes you're typically taught about inheritance; composition is now generally thought of as a more powerful and more sustainable pattern.
  4. Design patterns in general -> This is a book I frequently reference and think should do you well. You can probably find it for free through the library.
  5. Python testing using Pytest.
  6. Private and public properties.
  7. Decorators
  8. Property setters and getters

Synnax Background:

  1. The completed sections in the Synnax docs
  2. The Synnax RFCs.
  3. The dev environment doc, specifically the "Python" section.

From SyncLinear.com | SY-25

emilbon99 avatar Aug 27 '23 14:08 emilbon99