Ejemplo n.º 1
0
def load_existing(linearized=True):
    if linearized:
        lin = '_lin'
    else:
        lin = ''
    path = os.path.dirname(os.path.abspath(__file__))
    x1, x2, x3, x4, x5, x6, u = sp.symbols("x1, x2, x3, x4, x5, x6, u")
    with open(path+'/c_files/cart_pole_double_serial' + lin + '_ode.p', 'rb') as opened_file:
        dx_t_sym = pickle.load(opened_file)
        print('Model loaded')
    with open(path+'/c_files/cart_pole_double_serial' + lin + '_A.p', 'rb') as opened_file:
        Asym = pickle.load(opened_file)
        print('A matrix loaded')
    with open(path+'/c_files/cart_pole_double_serial' + lin + '_B.p', 'rb') as opened_file:
        Bsym = pickle.load(opened_file)
        print('B matrix loaded')

    params = sp.symbols('m0, m1, m2, J1, J2, a1, a2, l1, l2, g, d0, d1, d2')  # system parameters
    m0, m1, m2, J1, J2, a1, a2, l1, l2, g, d0, d1, d2 = params
    params_values = [(m0, 3.34), (m1, 0.876), (m2, 0.938), (J1, 0.013), (J2, 0.024),
                     (a1, 0.215), (a2, 0.269), (l1, 0.323), (l2, 0.419), (g, 9.81),
                     (d0, 0.1), (d1, 0.215), (d2, 0.002)]

    dx_t_sym = dx_t_sym.subs(params_values)
    Asym = Asym.subs(params_values)
    Bsym = Bsym.subs(params_values)

    try:
        dx_c_func = sp2c.convert_to_c((x1, x2, x3, x4, x5, x6, u), dx_t_sym,
                                      cfilepath=path+'/c_files/cart_pole_double_serial' + lin + '.c',
                                      use_exisiting_so=False)
        A_c_func = sp2c.convert_to_c((x1, x2, x3, x4, x5, x6, u), Asym,
                                     cfilepath=path+'/c_files/cart_pole_double_serial' + lin + '_A.c',
                                     use_exisiting_so=False)
        B_c_func = sp2c.convert_to_c((x1, x2, x3, x4, x5, x6, u), Bsym,
                                     cfilepath=path+'/c_files/cart_pole_double_serial' + lin + '_B.c',
                                     use_exisiting_so=False)
        A = lambda x, u: A_c_func(*x, *u)
        B = lambda x, u: B_c_func(*x, *u)
        dxdt = lambda t, x, u: dx_c_func(*x, *u).T[0]
        assert(any(dxdt(0, [0, 0, 0, 1., 1., 1.], [0]) != [0., 0., 0., 0., 0., 0.]))
        print('Using C-function')
    except:
        A_func = sp.lambdify((x1, x2, x3, x4, x5, x6, u), Asym, modules="numpy")
        B_func = sp.lambdify((x1, x2, x3, x4, x5, x6, u), Bsym, modules="numpy")
        A = lambda x, u: A_func(*x, *u)
        B = lambda x, u: B_func(*x, *u)

        dx_func = sp.lambdify((x1, x2, x3, x4, x5, x6, u), dx_t_sym[:], modules="numpy")  # creating a callable python function
        dxdt = lambda t, x, u: np.array(dx_func(*x, *u))
        assert(any(dxdt(0, [0, 0, 0, 1., 1., 1.], [0]) != [0., 0., 0., 0., 0., 0.]))
        print('Using lambdify')
    return dxdt, A, B
Ejemplo n.º 2
0
def load_existing(linearized=True):
    if linearized:
        lin = '_lin'
    else:
        lin = ''
    path = os.path.dirname(os.path.abspath(__file__))
    x1, x2, x3, x4, u = sp.symbols("x1, x2, x3, x4, u")
    with open(path + '/c_files/cart_pole' + lin + '_ode.p',
              'rb') as opened_file:
        dx_t_sym = pickle.load(opened_file)
        print('Model loaded')
    with open(path + '/c_files/cart_pole' + lin + '_A.p', 'rb') as opened_file:
        Asym = pickle.load(opened_file)
        print('A matrix loaded')
    with open(path + '/c_files/cart_pole' + lin + '_B.p', 'rb') as opened_file:
        Bsym = pickle.load(opened_file)
        print('B matrix loaded')
    try:
        A_c_func = sp2c.convert_to_c(
            (x1, x2, x3, x4, u),
            Asym,
            cfilepath=path + '/c_files/cart_pole' + lin + '_A.c',
            use_exisiting_so=False)
        B_c_func = sp2c.convert_to_c(
            (x1, x2, x3, x4, u),
            Bsym,
            cfilepath=path + '/c_files/cart_pole' + lin + '_B.c',
            use_exisiting_so=False)
        A = lambda x, u: A_c_func(*x, *u)
        B = lambda x, u: B_c_func(*x, *u)
        dx_c_func = sp2c.convert_to_c(
            (x1, x2, x3, x4, u),
            dx_t_sym,
            cfilepath=path + '/c_files/cart_pole' + lin + '_ode.c',
            use_exisiting_so=False)
        dxdt = lambda t, x, u: dx_c_func(*x, *u).T[0]
        assert (any(dxdt(0, [0, 0, 1., 1.], [0]) != [0., 0., 0., 0.]))
        print('Using C-function')
    except:
        A_func = sp.lambdify((x1, x2, x3, x4, u), Asym, modules="numpy")
        B_func = sp.lambdify((x1, x2, x3, x4, u), Bsym, modules="numpy")
        A = lambda x, u: A_func(*x, *u)
        B = lambda x, u: B_func(*x, *u)
        dx_func = sp.lambdify(
            (x1, x2, x3, x4, u), dx_t_sym[:],
            modules="numpy")  # creating a callable python function
        dxdt = lambda t, x, u: np.array(dx_func(*x, *u))
        assert (any(dxdt(0, [0, 0, 1., 1.], [0]) != [0., 0., 0., 0.]))
        print('Using lambdify')
    return dxdt, A, B
Ejemplo n.º 3
0
def feedback_factory(vf_f, vf_g, xx, clcp_coeffs):

    n = len(xx)
    assert len(clcp_coeffs) == n + 1
    assert len(vf_f) == n
    assert len(vf_g) == n
    assert clcp_coeffs[-1] == 1

    # prevent datatype problems:
    clcp_coeffs = st.to_np(clcp_coeffs)

    # calculate the relevant covector_fields

    # 1. extended nonlinear controllability matrix
    Qext = st.nl_cont_matrix(vf_f, vf_g, xx, n_extra_cols=0)

    QQinv = Qext.inverse_ADJ()

    w_i = QQinv[-1, :]
    omega_symb_list = [w_i]

    t0 = time.time()

    for i in range(1, n + 1):
        w_i = st.lie_deriv_covf(w_i, vf_f, xx)
        omega_symb_list.append(w_i)
        print(i, t0 - time.time())

    # dieser schritt dauert ca. 1 min
    # ggf. sinnvoll: Konvertierung in c-code

    # stack all 1-forms together
    omega_matrix = sp.Matrix(omega_symb_list)
    IPS()

    omega_matrix_func = sp2c.convert_to_c(xx,
                                          omega_matrix,
                                          cfilepath="omega.c")

    # noinspection PyPep8Naming
    def feedback(xx_ref):

        omega_matrix = omega_matrix_func(*xx_ref)

        # iterate row-wise over the matrix
        feedback_gain = st.to_np(
            sum([rho_i * w for (rho_i, w) in zip(clcp_coeffs, omega_matrix)]))

        return feedback_gain

    # now return that fabricated function
    return feedback
Ejemplo n.º 4
0
    def cost_init(self):
        """ Computes second order expansion of the """
        # 2nd order taylor expansion of the cost function along a trajectory

        xx = sp.symbols('x1:' + str(self.xDim + 1))
        uu = sp.symbols('u1:' + str(self.uDim + 1))
        t = sp.Symbol('t')

        c = self.cost_fnc(xx, uu, t, sp)
        cc = sp.Matrix([[c]])
        cx = cc.jacobian(xx)
        cu = cc.jacobian(uu)
        Cxx = cx.jacobian(xx)
        Cuu = cu.jacobian(uu)
        Cxu = cx.jacobian(uu)

        # final cost
        cf = self.fcost_fnc(xx, sp)
        ccf = sp.Matrix([[cf]])
        cfx = ccf.jacobian(xx)
        Cfxx = cfx.jacobian(xx)

        try:
            cx_func = sp2c.convert_to_c((*xx, *uu, t), cx.T, cfilepath=self.path + 'c_files/cx.c', use_exisiting_so=False)
            self.cx = lambda x, u, t: cx_func(*x, *u, t)
            cu_func = sp2c.convert_to_c((*xx, *uu, t), cu.T, cfilepath=self.path + 'c_files/cu.c', use_exisiting_so=False)
            self.cu = lambda x, u, t: cu_func(*x, *u, t)
            Cxx_func = sp2c.convert_to_c((*xx, *uu, t), Cxx, cfilepath=self.path + 'c_files/Cxx.c', use_exisiting_so=False)
            self.Cxx = lambda x, u, t: Cxx_func(*x, *u, t)
            Cuu_func = sp2c.convert_to_c((*xx, *uu, t), Cuu, cfilepath=self.path + 'c_files/Cuu.c', use_exisiting_so=False)
            self.Cuu = lambda x, u, t: Cuu_func(*x, *u, t)
            Cxu_func = sp2c.convert_to_c((*xx, *uu, t), Cxu, cfilepath=self.path + 'c_files/Cxu.c', use_exisiting_so=False)
            self.Cxu = lambda x, u, t: Cxu_func(*x, *u, t)
            cfx_func = sp2c.convert_to_c((*xx,), cfx.T, cfilepath=self.path + 'c_files/cfx.c', use_exisiting_so=False)
            self.cfx = lambda x: cfx_func(*x,)
            Cfxx_func = sp2c.convert_to_c((*xx,), Cfxx, cfilepath=self.path + 'c_files/Cfxx.c', use_exisiting_so=False)
            self.Cfxx = lambda x: Cfxx_func(*x,)
            print('Using C functions for taylor expansion of the cost function!')
        except:
            print('Could not use C functions for taylor expansion of the cost function!')
            self.cx = sp.lambdify((xx, uu, t), cx.T)
            self.cu = sp.lambdify((xx, uu, t), cu.T)
            self.Cxx = sp.lambdify((xx, uu, t), Cxx)
            self.Cuu = sp.lambdify((xx, uu, t), Cuu)
            self.Cxu = sp.lambdify((xx, uu, t), Cxu)
            self.cfx = sp.lambdify((xx,), cfx.T)
            self.Cfxx = sp.lambdify((xx,), Cfxx)

        pass
Ejemplo n.º 5
0
def tv_feedback_factory(ff, gg, xx, uu, clcp_coeffs, use_exisiting_so="smart"):
    """

    :param ff:
    :param gg:
    :param xx:
    :param uu:
    :param clcp_coeffs:
    :param use_exisiting_so:
    :return:
    """

    n = len(ff)
    assert len(xx) == n

    clcp_coeffs = st.to_np(clcp_coeffs)
    assert len(clcp_coeffs) == n + 1

    cfilepath = "k_timev.c"

    # if we reuse the compiled code for the controller,
    # we can skip the complete caluclation

    input_data_hash = sp2c.reproducible_fast_hash([ff, gg, xx, uu])
    print(input_data_hash)

    if use_exisiting_so == "smart":
        try:
            lib_meta_data = sp2c.get_meta_data(cfilepath, reload_lib=True)
        except FileNotFoundError as ferr:
            use_exisiting_so = False
        else:

            if lib_meta_data.get("input_data_hash") == input_data_hash:
                pass
                use_exisiting_so = True
            else:
                use_exisiting_so = False

    assert use_exisiting_so in (True, False)

    if use_exisiting_so is True:

        try:
            nargs = sp2c.get_meta_data(cfilepath, reload_lib=True)["nargs"]
        except FileNotFoundError as ferr:
            print("File not found. Unable to use exisiting shared libray.")
            # noinspection PyTypeChecker
            return tv_feedback_factory(ff,
                                       gg,
                                       xx,
                                       uu,
                                       clcp_coeffs,
                                       use_exisiting_so=False)

        # now load the existing function
        sopath = sp2c._get_so_path(cfilepath)
        L_matrix_func = sp2c.load_func(sopath)

        nu = nargs - n

    else:
        K1 = time_variant_controllability_matrix(ff, gg, xx, uu)
        kappa = K1.det()

        # K1_inv = K1.inverse_ADJ()
        K1_adj = K1.adjugate()

        lmd = K1_adj[-1, :]

        diffop = DiffOpTimeVarSys(ff, gg, xx, uu)

        ll = [
            diffop.MA_vect(lmd, order=i, subs_xref=False) for i in range(n + 1)
        ]
        # append a vector which contains kappa as first entries and 0s elsewhere
        kappa_vector = sp.Matrix([kappa] + [0] * (n - 1)).T
        ll.append(kappa_vector)

        L_matrix = st.row_stack(*ll)

        maxorder = max([0] + [symb.difforder for symb in L_matrix.s])
        rplm = diffop.get_orig_ref_replm(maxorder)

        L_matrix_r = L_matrix.subs(rplm)
        xxuu = list(zip(*rplm))[1]
        nu = len(xxuu) - len(xx)

        # additional metadata
        amd = dict(input_data_hash=input_data_hash, variables=xxuu)

        L_matrix_func = sp2c.convert_to_c(xxuu,
                                          L_matrix_r,
                                          cfilepath=cfilepath,
                                          use_exisiting_so=False,
                                          additional_metadata=amd)

    # noinspection PyShadowingNames
    def tv_feedback_gain(xref, uuref=None):

        if uuref is None:
            args = list(xref) + [0] * nu
        else:
            args = list(xref) + list(uuref)

        ll_num_ext = L_matrix_func(*args)
        ll_num = ll_num_ext[:n + 1, :]

        # extract kappa which we inserted into the L_matrix for convenience
        kappa = ll_num_ext[n + 1, 0]

        k = np.dot(clcp_coeffs, ll_num) / kappa

        return k

    # ship the information and internal functions to the outside
    tv_feedback_gain.nu = nu
    tv_feedback_gain.n = n
    tv_feedback_gain.L_matrix_func = L_matrix_func
    # return the fucntion
    return tv_feedback_gain
Ejemplo n.º 6
0
def load_existing(linearized=True):
    if linearized:
        lin = '_lin'
    else:
        lin = ''
    path = os.path.dirname(os.path.abspath(__file__))
    x1, x2, x3, x4, x5, x6, x7, x8, u = sp.symbols(
        "x1, x2, x3, x4, x5, x6, x7, x8, u")
    with open(path + '/c_files/cart_pole_triple' + lin + '_ode.p',
              'rb') as opened_file:
        dx_t_sym = pickle.load(opened_file)
        print('Model loaded')
    with open(path + '/c_files/cart_pole_triple' + lin + '_A.p',
              'rb') as opened_file:
        Asym = pickle.load(opened_file)
        print('A matrix loaded')
    with open(path + '/c_files/cart_pole_triple' + lin + '_B.p',
              'rb') as opened_file:
        Bsym = pickle.load(opened_file)
        print('B matrix loaded')

    params = sp.symbols(
        'm0, m1, m2, m3, J1, J2, J3, a1, a2, a3, l1, l2, l3, g, d0, d1, d2, d3'
    )  # system parameters
    m0, m1, m2, m3, J1, J2, J3, a1, a2, a3, l1, l2, l3, g, d0, d1, d2, d3 = params
    params_values = [(m0, 3.34), (m1, 0.876), (m2, 0.938), (m3, 0.553),
                     (J1, 0.013), (J2, 0.024), (J3, 0.018), (a1, 0.215),
                     (a2, 0.269), (a3, 0.226), (l1, 0.323), (l2, 0.419),
                     (l3, 0.484), (g, 9.81), (d0, 0.1), (d1, 0.215),
                     (d2, 0.002), (d3, 0.002)]

    # parameters of the test bench at the Institute of Control Theory, TU Dresden
    params_values = [(m0, 3.34), (m1, 0.8512), (m2, 0.8973), (m3, 0.5519),
                     (J1, 0.01980194), (J2, 0.02105375), (J3, 0.01818537),
                     (a1, 0.20001517), (a2, 0.26890449), (a3, 0.21666087),
                     (l1, 0.32), (l2, 0.419), (l3, 0.485), (g, 9.81),
                     (d0, 0.1), (d1, 0.00715294), (d2, 1.9497e-06),
                     (d3, 0.00164642)]

    dx_t_sym = dx_t_sym.subs(params_values)
    Asym = Asym.subs(params_values)
    Bsym = Bsym.subs(params_values)

    try:
        A_c_func = sp2c.convert_to_c(
            (x1, x2, x3, x4, x5, x6, x7, x8, u),
            Asym,
            cfilepath=path + '/c_files/cart_pole_triple' + lin + '_A.c',
            use_exisiting_so=False)
        B_c_func = sp2c.convert_to_c(
            (x1, x2, x3, x4, x5, x6, x7, x8, u),
            Bsym,
            cfilepath=path + '/c_files/cart_pole_triple' + lin + '_B.c',
            use_exisiting_so=False)
        A = lambda x, u: A_c_func(*x, *u)
        B = lambda x, u: B_c_func(*x, *u)
        dx_c_func = sp2c.convert_to_c(
            (x1, x2, x3, x4, x5, x6, x7, x8, u),
            dx_t_sym,
            cfilepath=path + '/c_files/cart_pole_triple' + lin + '_ode.c',
            use_exisiting_so=False)
        dxdt = lambda t, x, u: dx_c_func(*x, *u).T[0]
        assert (any(
            dxdt(0, [0, 0, 0, 0, 1., 1., 1., 1.], [0]) !=
            [0., 0., 0., 0., 0., 0., 0., 0.]))
        print('Using C-function')
    except:
        A_func = sp.lambdify((x1, x2, x3, x4, x5, x6, x7, x8, u),
                             Asym,
                             modules="numpy")
        B_func = sp.lambdify((x1, x2, x3, x4, x5, x6, x7, x8, u),
                             Bsym,
                             modules="numpy")
        A = lambda x, u: A_func(*x, *u)
        B = lambda x, u: B_func(*x, *u)
        dx_func = sp.lambdify(
            (x1, x2, x3, x4, x5, x6, x7, x8, u), dx_t_sym[:],
            modules="numpy")  # creating a callable python function
        dxdt = lambda t, x, u: np.array(dx_func(*x, *u))
        assert (any(
            dxdt(0, [0, 0, 0, 0, 1., 1., 1., 1.], [0]) !=
            [0., 0., 0., 0., 0., 0., 0., 0.]))
        print('Using lambdify')
    return dxdt, A, B