control theory-优化控制算法

0.建模

控制前,需要对系统建模

我们以最简单的倒立摆为例:

a.特点+目标+原理

特点:非线性、高阶次、多变量;
目标:通过给小车底座加力 F(控制量),使小车停留在预定的位置,并使摆杆不倒下,即不超过预先定义的竖直偏离角度范围。
原理:小车位置编码器将小车的位移和速度信号反馈给运动控制卡,角度编码器将摆角的角度、角速度信号反馈给运动控制卡。计算机从运动控制卡中读取实时反馈数据,确定小车向哪个方向移动、移动速度、加速度等,产生相应的控制量 F

b.系统变量+系统受力分析

根据所取变量,一种取钝角θ为变量建立系统方程组,另一种以锐角ϕ为变量建立系统方程组

我们以锐角ϕ为变量建立系统模型,这里的ϕ为 π − θ,刚体绕定轴转动动力学方程需要规定正方向,一般取逆时针方向为正方向:

系统模型建立完毕(注意,可以选取钝角θ来建立,或者取顺时针为正方向建立)

c.动力学方程雅可比线性化

雅可比矩阵是一种线性化工具,用来近似描述非线性系统在其邻域内的行为。在机器人学和控制理论中,这种方法特别有用,它允许我们通过线性化来简化对系统的分析,如稳定性、能控性的分析

对于倒立摆:

d.传递函数&状态空间

传递函数:传递函数是经典控制理论的工具,只能用于SISO和LTI系统,它是控制系统在复数域的数学模型

状态空间:状态空间模型属于现代控制理论,对SISO和MIMO、LTI和非线性或时变系统都适用,它是描述动态系统的另一种数学模型

matlab for 状态空间方程

M = .5;
m = 0.2;
b = 0.1;
I = 0.006;
g = 9.8;
l = 0.3;

p = I*(M+m)+M*m*l^2; %denominator for the A and B matrices

A = [0      1              0           0;
     0 -(I+m*l^2)*b/p  (m^2*g*l^2)/p   0;
     0      0              0           1;
     0 -(m*l*b)/p       m*g*l*(M+m)/p  0];
B = [     0;
     (I+m*l^2)/p;
          0;
        m*l/p];
C = [1 0 0 0;
     0 0 1 0];
D = [0;
     0];

states = {'x' 'x_dot' 'phi' 'phi_dot'};
inputs = {'u'};
outputs = {'x'; 'phi'};

sys_ss = ss(A,B,C,D,'statename',states,'inputname',inputs,'outputname',outputs)

1.LQR for 倒立摆(python)

LQR:

state-x,action-u

(目标状态已知)

控制theory:R和Q矩阵分别表示在最优化的代价函数中控制输入和误差的相对权重,Q,R矩阵也是cost function的一部分;A,B,C,D矩阵(空间状态方程模型):A 是系统的状态矩阵,B 是系统的控制输入矩阵,C 是系统的输出矩阵,D 是系统的直接传递矩阵

直接目标:需要确定状态反馈矩阵(向量)K

系统变量:M=1  m=0.3(g取9.8)  L=2

def main():模拟展示倒立摆的控制和运动过程,x0 是系统初始状态的数组,包含了小车的位置(x坐标)和倒立摆的角度(theta)等等

杆的位移𝑥1 - 初始值为 0.0

杆的速度𝑥2- 初始值为 0.0

杆的角度𝑥3 - 初始值为 0.3,这意味着杆在初始时稍微偏离直立状态。

杆的角速度𝑥4 - 初始值为 0.0

time设置为0,表示模拟时间的起点。sim_time是预定的总模拟时间,delta_t 是每次模拟时间步长

当模拟时间time小于sim_time时,持续执行循环,time += delta_t;每次迭代,时间time增加一个delta_t,u = lqr_control(x)计算控制输入u,通常使用线性二次调节(LQR)控制算法,根据当前系统状态x来确定。x = simulation(x, u):根据当前状态x和控制输入u,执行一次模拟步骤,更新系统状态x

                    
def get_model_matrix():计算出A,B矩阵,为倒立摆系统提供一个状态空间模型,状态矩阵A 定义了系统状态随时间的变化。对于一个简单的倒立摆,控制输入矩阵 B 定义了控制输入 u(在这个例子中是控制力矩)如何影响系统的状态(无C,D,在这个例子中,我们不关注输出

def simulation(x, u):计算下一个状态x

def solve_DARE(A, B, Q, R, maxiter=150, eps=0.01):迭代法计算Pn直到收敛,解出P

def dlqr(A, B, Q, R):解出P和增益矩阵K以及特征值

def lqr_control(x):计算LQR控制器的控制输入 u (u=−K⋅x),用于倒立摆系统(dlqr函数,准确地说是solve_DARE函数首先求解出离散时间代数Riccati方程以获取状态反馈增益矩阵 K)

import math
import time

import matplotlib.pyplot as plt
import numpy as np
from numpy.linalg import inv, eig

# Model parameters

l_bar = 2.0  # length of bar
M = 1.0  # [kg]
m = 0.3  # [kg]
g = 9.8  # [m/s^2]

nx = 4  # number of state
nu = 1  # number of input
Q = np.diag([0.0, 1.0, 1.0, 0.0])  # state cost matrix
R = np.diag([0.01])  # input cost matrix

delta_t = 0.1  # time tick [s]
sim_time = 5.0  # simulation time [s]

show_animation = True


def main():
    x0 = np.array([
        [0.0],
        [0.0],
        [0.3],
        [0.0]
    ])

    x = np.copy(x0)
    time = 0.0

    while sim_time > time:
        time += delta_t

        # calc control input
        u = lqr_control(x)

        # simulate inverted pendulum cart
        x = simulation(x, u)

        if show_animation:
            plt.clf()
            px = float(x[0, 0])
            theta = float(x[2, 0])
            plot_cart(px, theta)
            plt.xlim([-5.0, 2.0])
            plt.pause(0.001)

    print("Finish")
    print(f"x={float(x[0, 0]):.2f} [m] , theta={math.degrees(x[2, 0]):.2f} [deg]")
    if show_animation:
        plt.show()


def simulation(x, u):
    A, B = get_model_matrix()
    x = A @ x + B @ u

    return x


def solve_DARE(A, B, Q, R, maxiter=150, eps=0.01):
    """
    Solve a discrete time_Algebraic Riccati equation (DARE)
    """
    P = Q

    for i in range(maxiter):
        Pn = A.T @ P @ A - A.T @ P @ B @ \
            inv(R + B.T @ P @ B) @ B.T @ P @ A + Q
        if (abs(Pn - P)).max() < eps:
            break
        P = Pn

    return Pn


def dlqr(A, B, Q, R):
    """
    Solve the discrete time lqr controller.
    x[k+1] = A x[k] + B u[k]
    cost = sum x[k].T*Q*x[k] + u[k].T*R*u[k]
    # ref Bertsekas, p.151
    """

    # first, try to solve the ricatti equation
    P = solve_DARE(A, B, Q, R)

    # compute the LQR gain
    K = inv(B.T @ P @ B + R) @ (B.T @ P @ A)

    eigVals, eigVecs = eig(A - B @ K)
    return K, P, eigVals


def lqr_control(x):
    A, B = get_model_matrix()
    start = time.time()
    K, _, _ = dlqr(A, B, Q, R)
    u = -K @ x
    elapsed_time = time.time() - start
    print(f"calc time:{elapsed_time:.6f} [sec]")
    return u


def get_numpy_array_from_matrix(x):
    """
    get build-in list from matrix
    """
    return np.array(x).flatten()


def get_model_matrix():
    A = np.array([
        [0.0, 1.0, 0.0, 0.0],
        [0.0, 0.0, m * g / M, 0.0],
        [0.0, 0.0, 0.0, 1.0],
        [0.0, 0.0, g * (M + m) / (l_bar * M), 0.0]
    ])
    A = np.eye(nx) + delta_t * A

    B = np.array([
        [0.0],
        [1.0 / M],
        [0.0],
        [1.0 / (l_bar * M)]
    ])
    B = delta_t * B

    return A, B


def flatten(a):
    return np.array(a).flatten()


def plot_cart(xt, theta):
    cart_w = 1.0
    cart_h = 0.5
    radius = 0.1

    cx = np.array([-cart_w / 2.0, cart_w / 2.0, cart_w /
                   2.0, -cart_w / 2.0, -cart_w / 2.0])
    cy = np.array([0.0, 0.0, cart_h, cart_h, 0.0])
    cy += radius * 2.0

    cx = cx + xt

    bx = np.array([0.0, l_bar * math.sin(-theta)])
    bx += xt
    by = np.array([cart_h, l_bar * math.cos(-theta) + cart_h])
    by += radius * 2.0

    angles = np.arange(0.0, math.pi * 2.0, math.radians(3.0))
    ox = np.array([radius * math.cos(a) for a in angles])
    oy = np.array([radius * math.sin(a) for a in angles])

    rwx = np.copy(ox) + cart_w / 4.0 + xt
    rwy = np.copy(oy) + radius
    lwx = np.copy(ox) - cart_w / 4.0 + xt
    lwy = np.copy(oy) + radius

    wx = np.copy(ox) + bx[-1]
    wy = np.copy(oy) + by[-1]

    plt.plot(flatten(cx), flatten(cy), "-b")
    plt.plot(flatten(bx), flatten(by), "-k")
    plt.plot(flatten(rwx), flatten(rwy), "-k")
    plt.plot(flatten(lwx), flatten(lwy), "-k")
    plt.plot(flatten(wx), flatten(wy), "-k")
    plt.title(f"x: {xt:.2f} , theta: {math.degrees(theta):.2f}")

    # for stopping simulation with the esc key.
    plt.gcf().canvas.mpl_connect(
        'key_release_event',
        lambda event: [exit(0) if event.key == 'escape' else None])

    plt.axis("equal")


if __name__ == '__main__':
    main()

注:此例未设置目标状态,但在使得cost function最小的过程中,为使状态最小,最终是杆直立状态。x-状态(的)成本,u-输入(的)成本

result(最终系统稳定即达到了杆直立,杆的角度接近或等于 0°):

2.ILQR for 倒立摆(python)

3.MPC for 四旋翼无人机(python)

4.ILQR for panda robot arm(python+pybullet+pinocchio)

5.c++从零实现mpc

  • 49
    点赞
  • 39
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 模型预测控制(Model Predictive Control,MPC)理论、计算和设计是控制工程领域的重要研究方向。MPC是一种先进的控制方法,其基本思想是根据系统的动力学模型,在每次控制周期中通过对未来一段时间的状态和输入进行优化,从而实现对系统的控制。 模型预测控制理论研究了MPC方法的基本原理和数学基础。该理论主要涉及多个方面,包括系统建模、模型预测、优化理论等。通过建立系统的数学模型,可以将系统的动力学特性转化为数学方程,从而提供模型预测控制中所需的状态和输入信息。模型预测控制通过预测状态和输入的未来发展,以及对控制目标的优化,可以实现对系统的精确控制。 模型预测控制计算指的是基于模型预测控制理论进行系统计算的方法。这涉及到数值计算、优化算法和计算机仿真等技术。模型预测控制计算需要对系统的模型进行数值求解,通过建立状态估计和控制输入优化模型,从而实现对控制策略的计算和调整。 模型预测控制的设计是将模型预测控制方法应用于实际系统的过程。设计的目标是通过选择合适的系统模型和控制算法,实现系统的稳定性和性能要求。在设计过程中,需要选择适当的系统模型和参数,确定控制优化目标和约束条件,并选择合适的优化算法进行控制策略的计算。 总而言之,模型预测控制理论、计算和设计是控制工程领域中研究和应用广泛的控制方法。通过研究MPC的基本原理、进行计算和设计,可以实现对复杂系统的精确控制优化。 ### 回答2: 模型预测控制(Model Predictive Control,MPC)理论是一种在控制系统中应用的高级控制方法。它基于数学模型对系统的未来行为进行预测,并根据所得的预测结果进行控制决策。MPC可以应用于各种不确定的、非线性的和多变量的系统。 在MPC中,计算是一个关键的环节。MPC需要通过求解一个最优化问题来确定最佳的控制决策。这个最优化问题通常是一个非线性、有约束的优化问题,需要使用高效的计算方法进行求解。由于求解这个问题的复杂性,MPC方法在以前很难实现实时控制。然而,随着计算机计算能力的增强,以及优化算法的改进,MPC已经成为了一个广泛应用的控制方法。 在设计MPC控制器时,需要选择合适的模型、性能指标和约束条件。模型可以是线性的或非线性的,可以是定常的或动态的。性能指标用于度量控制系统的性能,通常包括稳定性、响应速度和鲁棒性等方面。约束条件用于限制系统的行为,例如,约束控制系统的输出或操作变量在一定范围内。 MPC方法的设计过程包括模型识别、性能指标选择、约束条件定义和优化问题的求解。通过对实际系统进行实验或建模,可以得到系统的数学模型。根据系统的特点和需求,选择合适的性能指标和约束条件。然后,使用优化算法求解最优化问题,确定最佳的控制决策。最后,将这些控制决策转化为实际的控制信号,实现对系统的控制。 总之,模型预测控制理论包括了计算和设计两个主要方面。计算方面主要涉及优化算法和复杂计算问题的求解,而设计方面需要选择合适的模型、性能指标和约束条件。通过合理的计算和设计,MPC可以实现对复杂系统的高效控制
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值