mph- / lcapy

Lcapy is a Python package for symbolic linear circuit analysis and signal processing. It uses SymPy for symbolic mathematics.
GNU Lesser General Public License v2.1
244 stars 46 forks source link

Generalized circuit drawing without needing direction hints or extra wire components #79

Open dyc3 opened 2 years ago

dyc3 commented 2 years ago

It's very frustrating to work with a circuit that you can't visualize to make sure you did it right. Unfortunately, for lcapy circuits, not all circuits that are drawable are solvable, and vice versa.

These functions generate circuits that are either drawable or solvable.

def __generate_RC_filter(high_pass: bool, order: int=1, drawable: bool=False) -> Circuit:
    """Generate an RC filter circuit of the given order.

    If drawable is True, the circuit will be drawable when you call draw(). Otherwise, it may not. Drawable circuits may not be solvable circuits."""
    assert order > 0
    netlist = ""
    if drawable:
        netlist += f"""
        Vin 1 "0_0"; down, v=V_{{in}}
        """
    for i in range(order):
        if high_pass:
            netlist += f"""
            C{i} {i+1} {i+2}; right
            R{i} {i+2} {f"0_{(i+1)}" if drawable else 0}; down
            """
        else:
            netlist += f"""
            R{i} {i+1} {i+2}; right
            C{i} {i+2} {f"0_{(i+1)}" if drawable else 0}; down
            """

        if drawable:
            netlist += f"""
            W 0_{i} 0_{i+1}; right, ground
            """
    # if drawable:
    #   netlist += f"""
    #   Pout {order + 2} 0_0; down, v=V_{{out}}
    #   """
    netlist += f"""
    ;draw_nodes=connections, cpt_size=1
    """
    cct = Circuit(netlist)
    return cct

def low_pass_RC_filter(order: int = 1, drawable=False) -> Circuit:
    """Generate a low pass filter circuit of the given order."""
    assert order > 0
    return __generate_RC_filter(False, order, drawable)

def high_pass_RC_filter(order: int = 1, drawable=False) -> Circuit:
    """Generate a high pass filter circuit of the given order."""
    assert order > 0
    return __generate_RC_filter(True, order, drawable)

I think it could be possible to use something like the networkx library to compute layouts for circuits automatically.

mph- commented 2 years ago

This is on my list of todos. However, it is a tricky problem. Moreover, the drawing hints are not sufficient and other heuristics are required such as symmetry.

The current algorithm solves the horizontal placement and vertical placement graphs independently but I think this more sophisticated approach will require both graphs to be solved concurrently. There is another algorithm I have tried (see schemlineqplacer.py) that could be applied but again this needs some heuristics to get a tidy solution.

I welcome any suggestions of algorithms that could be used.