from diagrams import Diagram, Cluster
from diagrams.generic.compute import Rack
from diagrams.generic.blank import Blank
from diagrams.generic.network import Switch

# We will use Rack as generic processing block
# Blank as hidden connectors

with Diagram("Closed-loop Teleoperation Architecture",
             show=False, direction="LR",
             outformat="png"):

    # ---- Human operator ----
    human = Rack("Human\noperator")

    # ---- Master exoskeleton ----
    master = Rack("Master exoskeleton\nsensing & actuation")

    # ---- SEW retargeting ----
    sew = Rack("SEW-based posture\nretargeting (IK-free)")

    # ---- Slave controller ----
    ctrl = Rack("Slave joint\ncontroller")

    # ---- Slave arm ----
    slave = Rack("7-DoF slave arm\n+ environment")

    # ---- Bottom blocks ----
    est = Rack("Interaction\nforce estimator")
    haptic = Rack("Haptic rendering\n+ energy tank")

    # ---- Connections (Main forward loop) ----
    human >> master
    master >> sew
    sew >> ctrl
    ctrl >> slave

    # ---- Feedback loop ----
    slave >> est
    est >> haptic
    haptic >> master

    # Optional: chest-frame Jacobian dashed arrows (use Blank as endpoints)
    Jm = Blank(" ")
    Js = Blank(" ")

    master >> Jm >> haptic
    slave >> Js >> est