Xmod Co-simulation [upd] May 2026
def get_state(self): return {"x": self.x, "v": self.v}
def __init__(self, name: str, Kp: float, x_ref: float = 0.0): super().__init__(name) self.Kp = Kp self.x_ref = x_ref self.input_ports = [XModPort("x_measured")] self.output_ports = [XModPort("F_cmd")] xmod co-simulation
def step(self, t: float, dt: float, inputs: Dict[str, np.ndarray]) -> XModStep: F_ext = inputs.get("F_ext", np.array([0.0]))[0] # Simple semi-implicit Euler a = (F_ext - self.k * self.x - self.c * self.v) / self.m self.v += a * dt self.x += self.v * dt return XModStep( outputs={"x": np.array([self.x]), "v": np.array([self.v])}, new_time=t + dt ) def get_state(self): return {"x": self
sim = XModCoSimulation(dt=0.01) sim.add_model(plant) sim.add_model(ctrl) sim.connect("controller", "F_cmd", "mass_spring", "F_ext") sim.connect("mass_spring", "x", "controller", "x_measured") def get_state(self): return {"x": self.x
def step(self, t: float, dt: float, inputs: Dict[str, np.ndarray]) -> XModStep: x_meas = inputs.get("x_measured", np.array([0.0]))[0] F_cmd = self.Kp * (self.x_ref - x_meas) return XModStep( outputs={"F_cmd": np.array([F_cmd])}, new_time=t + dt )