def test_events(): # use bouncing ball to test events work # simulate in block diagram int_opts = block_diagram.DEFAULT_INTEGRATOR_OPTIONS.copy() int_opts['rtol'] = 1E-12 int_opts['atol'] = 1E-15 int_opts['nsteps'] = 1000 int_opts['max_step'] = 2**-3 x = x1, x2 = Array(dynamicsymbols('x_1:3')) mu, g = sp.symbols('mu g') constants = {mu: 0.8, g: 9.81} ic = np.r_[10, 15] sys = SwitchedSystem( x1, Array([0]), state_equations=r_[x2, -g], state_update_equation=r_[sp.Abs(x1), -mu*x2], state=x, constants_values=constants, initial_condition=ic ) bd = BlockDiagram(sys) res = bd.simulate(5, integrator_options=int_opts) # compute actual impact time tvar = dynamicsymbols._t impact_eq = (x2*tvar - g*tvar**2/2 + x1).subs( {x1: ic[0], x2: ic[1], g: 9.81} ) t_impact = sp.solve(impact_eq, tvar)[-1] # make sure simulation actually changes velocity sign around impact abs_diff_impact = np.abs(res.t - t_impact) impact_idx = np.where(abs_diff_impact == np.min(abs_diff_impact))[0] assert np.sign(res.x[impact_idx-1, 1]) != np.sign(res.x[impact_idx+1, 1])
BlockDiagram = block_diagram.BlockDiagram int_opts = block_diagram.DEFAULT_INTEGRATOR_OPTIONS.copy() find_opts = block_diagram.DEFAULT_EVENT_FIND_OPTIONS.copy() int_opts['rtol'] = 1E-12 int_opts['atol'] = 1E-15 int_opts['nsteps'] = 1000 find_opts['xtol'] = 1E-12 find_opts['maxiter'] = int(1E3) # This example shows how to implement a simple saturation block # create an oscillator to generate the sinusoid x = Array([dynamicsymbols('x')]) # placeholder output symbol tvar = dynamicsymbols._t # use this symbol for time sin = DynamicalSystem(Array([sp.cos(tvar)]), x) # define the oscillator, llim = -0.75 ulim = 0.75 saturation_limit = r_[llim, ulim] saturation_output = r_['0,2', llim, x[0], ulim] sat = SwitchedOutput(x[0], saturation_limit, output_equations=saturation_output, input_=x) sat_bd = BlockDiagram(sin, sat) sat_bd.connect(sin, sat)
fig.set_size_inches(10, 10, forward=True) leg_artist = plt.legend(loc='lower right', bbox_to_anchor=(1.1, 1.0)) mplpub.horizontal_center(fig) mplpub.vertical_aspect(fig, mplpub.golden_ratio, overlapping_extra_artists=[leg_artist]) def plot_x(result, label=''): plt.plot(result.t, result.y[:, 0] * 180 / np.pi, label=label) plt.xlabel('time, s') plt.ylabel('position, degrees') ## define systems x, v, u = dynamicsymbols('x v u') l, m = sp.symbols('l m') parameters = {l: 1, m: 1} inertia = DynamicalSystem(state_equation=r_[v, u / (m * l**2)], state=r_[x, v], input_=u, constants_values=parameters) g = sp.symbols('g') parameters[g] = 9.8 gravity = DynamicalSystem(output_equation=-g * m * l * sp.sin(x), input_=x, constants_values=parameters)
def shape_figure(): fig=plt.gcf() fig.set_size_inches(10,10,forwaord=True) Ieg_arist=plt.legend(loc='upper right', bbox_to_anchor=(1.1, 1.0)) mplpub.horizontal_center(fig) mplpub.vertical_aspect(fig, mplpub.golden_ratio, overlapping_extra_artista=[leg_artist]) def plot_x(result, lable=''): plt.plot(result.t, result.y[:0]*180/np.pi, label=label) plt.xlabel ('time, s') plt.ylabel('position, degress') #define system x,y,u=dynamicsymbols('x,y,u') l,m=sp.symbols('l,m') parameters={l:1, m:1} inertia=DynamicalSystem( state_equation=r_[v,u/(m*l**2)], state=r_[x,v] input_u, constants_values=parameters ) g=sp.symbols('g') parameters[g]=9.8 gravity=DynamicalSystem( output_equation=-g*m*l*sp.sin(x),
from simupy.systems.symbolic import DynamicalSystem, dynamicsymbols from simupy.block_diagram import BlockDiagram from sympy.tensor.array import Array from numpy import matlib legends = [r'$x_1(t)$', r'$x_2(t)$', r'$x_3(t)$', r'$u(t)$'] tF = 6 """ This example shows the design of a linear quadratic regulator for a nonlinear system linearized about the origin. It is stable for some initial conditions, but not all initial conditions. The region of stability is not dependent only on the distance from the origin. """ # construct system x = Array(dynamicsymbols('x1:4')) u = dynamicsymbols('u') x1, x2, x3 = x sys = DynamicalSystem(Array([-x1 + x2 - x3, -x1 * x2 - x2 + u, -x1 + u]), x, Array([u])) # linearization to design LQR t0 = 0 x0 = np.zeros((3, 1)) u0 = 0 A = sys.state_jacobian_equation_function(t0, x0, u0) B = sys.input_jacobian_equation_function(t0, x0, u0) # LQR gain Q = np.matlib.eye(3) R = np.matrix([1])
import numpy as np import sympy as sp import matplotlib.pyplot as plt from simupy.systems.symbolic import DynamicalSystem, dynamicsymbols from simupy.block_diagram import BlockDiagram from simupy.array import Array, r_ plt.ion() # This example simulates the Van der Pol oscillator. x = x1, x2 = Array(dynamicsymbols('x1:3')) mu = sp.symbols('mu') state_equation = r_[x2, -x1 + mu * (1 - x1**2) * x2] output_equation = r_[x1**2 + x2**2, sp.atan2(x2, x1)] sys = DynamicalSystem(state_equation, x, output_equation=output_equation, constants_values={mu: 5}) sys.initial_condition = np.array([1, 1]).T BD = BlockDiagram(sys) res = BD.simulate(30) plt.figure() plt.plot(res.t, res.x) plt.legend([sp.latex(s, mode='inline') for s in sys.state])
import numpy as np import sympy as sp import matplotlib.pyplot as plt from simupy.systems.symbolic import DynamicalSystem, dynamicsymbols from simupy.block_diagram import BlockDiagram from simupy.array import Array, r_ from simupy.discontinuities import SwitchedOutput plt.ion() # This example shows how to implement a simple saturation block llim = -0.75 ulim = 0.75 x = Array([dynamicsymbols('x')]) tvar = dynamicsymbols._t sin = DynamicalSystem(Array([sp.cos(tvar)]), x) sin_bd = BlockDiagram(sin) sin_res = sin_bd.simulate(2 * np.pi) plt.figure() plt.plot(sin_res.t, sin_res.x) limit = r_[llim, ulim] saturation_output = r_['0,2', llim, x[0], ulim] sat = SwitchedOutput(x[0], limit, output_equations=saturation_output, input_=x) sat_bd = BlockDiagram(sin, sat) sat_bd.connect(sin, sat)