文章目录

  • 概述
  • LQR问题背景
  • LQR代价函数
  • 求解LQR方法
    • 最小二乘法
    • 动态规划法(Dynamic Programming)
      • 值函数
      • 求极值
      • 求解过程

概述

本文介绍离散时间有限范围内的LQR(Linear Quadratic Regulator)算法求解过程.

LQR问题背景

对于一个离散时间系统:
xt+1=Axt+But,x0=xinit(1)x_{t+1}=Ax_t + Bu_t,x_0=x_{init}\tag{1} xt+1​=Axt​+But​,x0​=xinit​(1)
其中,A∈Rn×nA\in R^{n\times n}A∈Rn×n,B∈Rn×mB\in R^{n\times m}B∈Rn×m

关于最优问题,就在于如何选择合适的u0,u1,...u_0,u_1,...u0​,u1​,...,使得状态量x0,x1,...x_0,x_1,...x0​,x1​,...足够小,因此得到好的调节和控制;或者使得u0,u1,...u_0,u_1,...u0​,u1​,...足够小,以使用更少的能量。这两个量通常相互制约,如果采用更大的输入uuu,就会驱使状态量xxx更快达到0。采用线性二次调节原理可以解决这个问题。

LQR代价函数

为了表示控制系统达到稳定控制所付出的代价,定义如下二次型代价函数:
J(U)=∑τ=0N−1(xτTQxτ+uτTRuτ)+xNTQfxN(2)J(U)=\sum^{N-1}_{\tau=0}(x^{T}_{\tau}Qx_{\tau} + u^{T}_{\tau}Ru_{\tau})+ x^{T}_{N}Q_{f}x_{N}\tag{2} J(U)=τ=0∑N−1​(xτT​Qxτ​+uτT​Ruτ​)+xNT​Qf​xN​(2)
其中函数参数U=(u0,u1,..,uN)U = (u_0,u_1,..,u_N)U=(u0​,u1​,..,uN​),并且矩阵Q,Qf,RQ,Q_f,RQ,Qf​,R为正定矩阵,及
Q=QT≥0,Qf=QfT≥0,R=RT>0\begin{array}{cl} Q=Q^{T}\geq0,&Q_f=Q_{f}^{T}\geq0,&R=R^{T}>0 \end{array} Q=QT≥0,​Qf​=QfT​≥0,​R=RT>0​

QQQ QfQ_fQf​ RRR
给定状态代价矩阵 最终状态代价矩阵 输入代价矩阵
  • NNN:时间范围(考虑N=∞N = \inftyN=∞)
  • xτTQxτx^{T}_{\tau} Q x_{\tau}xτT​Qxτ​:衡量状态偏差
  • uτTRuτu^{T}_{\tau} R u_{\tau}uτT​Ruτ​:衡量输入大小
  • xNTQfxNx^{T}_{N} Q_{f} x_{N}xNT​Qf​xN​:衡量最终状态偏差
  • QQQ,RRR:分别设定状态偏差和输入的相对权重
  • R>0R>0R>0:意味着任何非零输入都增加JJJ的代价

因此,关于LQR问题就是找出使得代价函数J(U)J(U)J(U)最小的一组控制输入(u0,u1,...,uN−1)lqr(u_0,u_1,...,u_{N-1})_{lqr}(u0​,u1​,...,uN−1​)lqr​。

求解LQR方法

本文主要介绍两种求解LQR的方法,分别为最小二乘法和动态规划算法。

最小二乘法

根据公式(1)可知,x0x_0x0​是X=(x0,...,xN)X = (x_0,...,x_N)X=(x0​,...,xN​)的线性函数,并且U=(u0,...,uN−1)U = (u_0,...,u_{N-1})U=(u0​,...,uN−1​),可以得出如下关系:
x1=Ax0+Bu0x2=Ax1+Bu1⋮xn=AxN−1+BuN−1(3)\begin{array}{cl} x_1 &= Ax_0 + Bu_0\\ x_2 &= Ax_1 + Bu_1\\ \vdots\\ x_n &= Ax_{N-1} + Bu_{N-1} \end{array}\tag{3} x1​x2​⋮xn​​=Ax0​+Bu0​=Ax1​+Bu1​=AxN−1​+BuN−1​​(3)
将上述公式(3)逐个带入得
x1=Ax0+Bu0x2=A2x0+ABu0+Bu1⋮xn=ANx0+AN−1Bu0+AN−2Bu1+⋯+BuN−1(4)\begin{array}{cl} x_1 &= Ax_0 + Bu_0\\ x_2 &= A^{2}x_0 + ABu_0 + Bu_1\\ \vdots\\ x_n &= A^{N}x_0 + A^{N-1}Bu_0 + A^{N-2}Bu_1 + \dots+ Bu_{N-1} \end{array} \tag{4} x1​x2​⋮xn​​=Ax0​+Bu0​=A2x0​+ABu0​+Bu1​=ANx0​+AN−1Bu0​+AN−2Bu1​+⋯+BuN−1​​(4)
整理得
[x0x1⋮xN]=[0…B0…ABB0…⋮⋮AN−1BAN−2B…B][u0u1⋮uN−1]+[IA⋮AN]x0(5)\left[\begin{array}{cl} x_0\\ x_1\\ \vdots\\ x_N \end{array}\right]= \left[ \begin{array}{cl} 0 & \dots \\ B & 0 & \dots \\ AB & B & 0 & \dots \\ \vdots & \vdots \\ A^{N-1}B & A^{N-2}B & \dots & B \end{array}\right] \left[ \begin{array}{cl} u_0\\ u_1\\ \vdots\\ u_{N-1} \end{array} \right]+ \left[ \begin{array}{cl} I\\ A\\ \vdots\\ A^{N} \end{array} \right]x_0 \tag{5} ⎣⎢⎢⎢⎡​x0​x1​⋮xN​​⎦⎥⎥⎥⎤​=⎣⎢⎢⎢⎢⎢⎡​0BAB⋮AN−1B​…0B⋮AN−2B​…0…​…B​⎦⎥⎥⎥⎥⎥⎤​⎣⎢⎢⎢⎡​u0​u1​⋮uN−1​​⎦⎥⎥⎥⎤​+⎣⎢⎢⎢⎡​IA⋮AN​⎦⎥⎥⎥⎤​x0​(5)
其中
G=[0…B0…ABB0…⋮⋮AN−1BAN−2B…B],H=[IA⋮AN]G=\left[ \begin{array}{cl} 0 & \dots \\ B & 0 & \dots \\ AB & B & 0 & \dots \\ \vdots & \vdots \\ A^{N-1}B & A^{N-2}B & \dots & B \end{array}\right],H=\left[ \begin{array}{cl} I\\ A\\ \vdots\\ A^{N} \end{array} \right] G=⎣⎢⎢⎢⎢⎢⎡​0BAB⋮AN−1B​…0B⋮AN−2B​…0…​…B​⎦⎥⎥⎥⎥⎥⎤​,H=⎣⎢⎢⎢⎡​IA⋮AN​⎦⎥⎥⎥⎤​

等式(5)可以进一步表示为
X=GU+Hx0(6)X= GU + Hx_0 \tag{6} X=GU+Hx0​(6)
其中,G∈RNn×NmG\in R^{Nn\times Nm}G∈RNn×Nm,H∈RNn×nH\in R^{Nn\times n}H∈RNn×n。

从而等式(2)所表示得代价函数可以表示为
J(U)=∥diag(Q1/2,…,Q1/2,Qf1/2)(GU+Hx0)∥2+∥diag(R1/2,…,R1/2)U∥2(7)J(U)=\parallel diag(Q^{1/2},\dots,Q^{1/2},Q^{1/2}_{f})(GU+Hx_0)\parallel^2+ \parallel diag(R^{1/2},\dots,R^{1/2})U\parallel^2 \tag{7} J(U)=∥diag(Q1/2,…,Q1/2,Qf1/2​)(GU+Hx0​)∥2+∥diag(R1/2,…,R1/2)U∥2(7)
这就转化成一个求解最小二乘法的问题,其问题大小为N(n+m)×NmN(n + m)\times NmN(n+m)×Nm。

动态规划法(Dynamic Programming)

动态规划算法是解决多阶段决策过程最优化的一种有效的数学方法。

值函数

首先定义一个值函数Vt:Rn→RV_t:R^n \to RVt​:Rn→R,其中t=(0,…,N)t=(0,\dots,N)t=(0,…,N):
Vt(z)=min⁡ut,…,uN−1(∑τ=tN−1(xτTQxτ+uτtRuτ)+xNTQfxN)(8)V_t(z)=\min_{u_t,\dots,u_{N-1}}\Bigl(\sum_{\tau=t}^{N-1}(x^T_\tau Qx_\tau + u^t_\tau Ru_\tau) + x_N^TQ_fx_N\Bigr) \tag{8} Vt​(z)=ut​,…,uN−1​min​(τ=t∑N−1​(xτT​Qxτ​+uτt​Ruτ​)+xNT​Qf​xN​)(8)
如果设置xt=zx_t = zxt​=z,根据公式(1)的关系,xτ+1=Axτ+Buτx_{\tau+1} = Ax_{\tau} + Bu_{\tau}xτ+1​=Axτ​+Buτ​,并且τ=t,…,N\tau=t,\dots,Nτ=t,…,N。

  • Vt(z)V_t(z)Vt​(z)可以表示在ttt时刻,从状态zzz开始的LQR最小代价值
  • V0(x0)V_0(x_0)V0​(x0​)表示在0时刻,从状态x0x_0x0​开始的LQR最小代价值

VtV_tVt​可以表示为二次型的形式,即VT(z)=zTPtz,其中Pt=PtT≥0V_T(z)=z^TP_tz,其中P_t=P_t^T \geq 0VT​(z)=zTPt​z,其中Pt​=PtT​≥0。当t=Nt=Nt=N时,代价值函数为:
VN(z)=zTQfz(9)V_N(z) = z^TQ_f z \tag{9} VN​(z)=zTQf​z(9)
因此PN=QfP_N = Q_fPN​=Qf​。

根据动态规划原理,等式(8)可以写成如下递归关系式:
Vt(z)=min⁡w(zTQz+wTRw+Vt+1(Az+Bw))(10)V_t(z)=\min_w\bigl(z^TQz + w^TRw + V_{t+1}(Az+Bw)\bigr)\tag{10} Vt​(z)=wmin​(zTQz+wTRw+Vt+1​(Az+Bw))(10)
其中,

  • zTQz+wTRwz^TQz + w^TRwzTQz+wTRw:如果ut=wu_t = wut​=w,则代表ttt时刻产生的代价值;
  • Vt+1(Az+Bw)V_{t+1}(Az+Bw)Vt+1​(Az+Bw):代表从t+1t+1t+1时刻开始,引起的最小代价值;

提取等式(10)中与www无关的选项得
Vt(z)=zTQz+min⁡w(wTRw+Vt+1(Az+Bw))(11)V_t(z)=z^TQz + \min_w\bigl(w^TRw + V_{t+1}(Az+Bw)\bigr)\tag{11} Vt​(z)=zTQz+wmin​(wTRw+Vt+1​(Az+Bw))(11)
等式(11)描述了Vt(z)V_t(z)Vt​(z)与Vt+1(z)V_{t+1}(z)Vt+1​(z)之间的递归关系。

求极值

假设Vt+1=zTPt+1zV_{t+1}= z^TP_{t+1}zVt+1​=zTPt+1​z,并且Pt+1=Pt+1T≥0P_{t+1}=P^{T}_{t+1} \geq0Pt+1​=Pt+1T​≥0,等式(11)可以进一步转化为Pt+1P_{t+1}Pt+1​的形式:
Vt(z)=zTQz+min⁡w(wTRw+(Az+Bw)TPt+1(Az+Bw))(12)V_t(z)=z^TQz + \min_w\bigl(w^TRw + (Az+Bw)^TP_{t+1}(Az+Bw)\bigr)\tag{12} Vt​(z)=zTQz+wmin​(wTRw+(Az+Bw)TPt+1​(Az+Bw))(12)
为了求最小值,对www求导,导数为零的点即为最值点。
2wTR+2(Az+Bw)TPt+1B=0(13)2w^TR + 2(Az+Bw)^TP_{t+1}B = 0 \tag{13} 2wTR+2(Az+Bw)TPt+1​B=0(13)
推导等式(13),求取www:
wTR+zTATPt+1B+wTBTPt+1B=0wT(R+BTPt+1B)=−zTATPt+1B(合并同类项并移项)(R+BTPt+1B)Tw=−BTPt+1TAz(转置)(R+BTPt+1B)w=−BTPt+1Az(Pt+1=Pt+1T,R=RT)w=−(R+BTPt+1B)−1BTPt+1Az(矩阵求逆)(14)\begin{array}{cl} w^TR + z^{T}A^{T}P_{t+1}B+w^{T}B^{T}P_{t+1}B &= 0\\ w^T(R + B^TP_{t+1}B) &= - z^{T}A^{T}P_{t+1}B &\text{(合并同类项并移项)}\\ (R + B^TP_{t+1}B)^Tw &= -B^TP_{t+1}^{T}Az & \text{(转置)}\\ (R + B^TP_{t+1}B)w &= -B^TP_{t+1}Az &(P_{t+1}=P^{T}_{t+1},R=R^T)\\ w &=-(R + B^TP_{t+1}B)^{-1}B^TP_{t+1}Az &\text{(矩阵求逆)} \end{array}\tag{14} wTR+zTATPt+1​B+wTBTPt+1​BwT(R+BTPt+1​B)(R+BTPt+1​B)Tw(R+BTPt+1​B)ww​=0=−zTATPt+1​B=−BTPt+1T​Az=−BTPt+1​Az=−(R+BTPt+1​B)−1BTPt+1​Az​(合并同类项并移项)(转置)(Pt+1​=Pt+1T​,R=RT)(矩阵求逆)​(14)
由等式(14)可知,最优输入为
w∗=−(R+BTPt+1B)−1BTPt+1Az(15)w^* =-(R + B^TP_{t+1}B)^{-1}B^TP_{t+1}Az \tag{15} w∗=−(R+BTPt+1​B)−1BTPt+1​Az(15)
将等式(15)带入等式(12)得
Vt(z)=zTQz+w∗TRw∗+(Az+Bw∗)TPt+1(Az+Bw∗)(16)V_t(z)=z^TQz + w^{*T}Rw^* + (Az+Bw^*)^TP_{t+1}(Az+Bw^*)\tag{16} Vt​(z)=zTQz+w∗TRw∗+(Az+Bw∗)TPt+1​(Az+Bw∗)(16)
对等式(16)化简得
Vt(z)=zTQz+w∗TRw∗+(Az+Bw∗)TPt+1(Az+Bw∗)=zTQz+w∗TRw∗+zTATPt+1Az+2zTATPt+1Bw∗+w∗TBTPt+1Bw∗=zTQz+zTATPt+1Az+w∗T(R+BTPt+1B)w∗+2zTATPt+1Bw∗=zTQz+zTATPt+1Az+zTATPt+1B(R+BTPt+1B)−1(R+BTPt+1B)(R+BTPt+1B)−1BTPt+1Az−2zTATPt+1B(R+BTPt+1B)−1BTPt+1Az=zTQz+zTATPt+1Az+zTATPt+1B(R+BTPt+1B)−1BTPt+1Az−2zTATPt+1B(R+BTPt+1B)−1BTPt+1Az=zTQz+zTATPt+1Az−zTATPt+1B(R+BTPt+1B)−1BTPt+1Az=zT(Q+ATPt+1A−ATPt+1B(R+BTPt+1B)−1BTPt+1A)z=zTPtz(17)\begin{array}{cl} V_t(z) &= z^TQz + w^{*T}Rw^* + (Az+Bw^*)^TP_{t+1}(Az+Bw^*)\\ &= z^TQz + w^{*T}Rw^* + z^TA^TP_{t+1}Az + 2z^TA^TP_{t+1}Bw^* + w^{*T}B^TP_{t+1}Bw^*\\ & = z^TQz + z^TA^TP_{t+1}Az + w^{*T}(R+B^TP_{t+1}B)w^* + 2z^TA^TP_{t+1}Bw^*\\ & = z^TQz + z^TA^TP_{t+1}Az\\ &+z^TA^TP_{t+1}B(R + B^TP_{t+1}B)^{-1}(R+B^TP_{t+1}B)(R + B^TP_{t+1}B)^{-1}B^TP_{t+1}Az\\ &-2z^TA^TP_{t+1}B(R + B^TP_{t+1}B)^{-1}B^TP_{t+1}Az\\ &=z^TQz + z^TA^TP_{t+1}Az\\ &+z^TA^TP_{t+1}B(R + B^TP_{t+1}B)^{-1}B^TP_{t+1}Az\\ &-2z^TA^TP_{t+1}B(R + B^TP_{t+1}B)^{-1}B^TP_{t+1}Az\\ &= z^TQz + z^TA^TP_{t+1}Az - z^TA^TP_{t+1}B(R + B^TP_{t+1}B)^{-1}B^TP_{t+1}Az\\ &= z^T(Q + A^TP_{t+1}A - A^TP_{t+1}B(R + B^TP_{t+1}B)^{-1}B^TP_{t+1}A)z\\ &= z^TP_tz \end{array}\tag{17} Vt​(z)​=zTQz+w∗TRw∗+(Az+Bw∗)TPt+1​(Az+Bw∗)=zTQz+w∗TRw∗+zTATPt+1​Az+2zTATPt+1​Bw∗+w∗TBTPt+1​Bw∗=zTQz+zTATPt+1​Az+w∗T(R+BTPt+1​B)w∗+2zTATPt+1​Bw∗=zTQz+zTATPt+1​Az+zTATPt+1​B(R+BTPt+1​B)−1(R+BTPt+1​B)(R+BTPt+1​B)−1BTPt+1​Az−2zTATPt+1​B(R+BTPt+1​B)−1BTPt+1​Az=zTQz+zTATPt+1​Az+zTATPt+1​B(R+BTPt+1​B)−1BTPt+1​Az−2zTATPt+1​B(R+BTPt+1​B)−1BTPt+1​Az=zTQz+zTATPt+1​Az−zTATPt+1​B(R+BTPt+1​B)−1BTPt+1​Az=zT(Q+ATPt+1​A−ATPt+1​B(R+BTPt+1​B)−1BTPt+1​A)z=zTPt​z​(17)
上述公式化简过程中,由于Pt+1=Pt+1T,R=RTP_{t+1}=P^{T}_{t+1},R=R^TPt+1​=Pt+1T​,R=RT,所以((R+BTPt+1B)−1)T=(R+BTPt+1B)−1\bigl((R + B^TP_{t+1}B)^{-1}\bigr)^T = (R + B^TP_{t+1}B)^{-1}((R+BTPt+1​B)−1)T=(R+BTPt+1​B)−1。

由等式(17)可知
Pt=Q+ATPt+1A−ATPt+1B(R+BTPt+1B)−1BTPt+1A(18)P_t = Q + A^TP_{t+1}A - A^TP_{t+1}B(R + B^TP_{t+1}B)^{-1}B^TP_{t+1}A \tag{18} Pt​=Q+ATPt+1​A−ATPt+1​B(R+BTPt+1​B)−1BTPt+1​A(18)

求解过程

关于LQR的求解过程,可以采用动态规划算法,依据上述公式(20)的递归关系,反向递推,求出满足一定条件的最小代价值。

  1. 确定迭代范围NNN
  2. 设置迭代初始值PN=QfP_N=Q_fPN​=Qf​
  3. 循环迭代,t=N,…,1t = N,\dots,1t=N,…,1

Pt−1=Q+ATPt+1A−ATPt+1B(R+BTPt+1B)−1BTPt+1AP_{t-1} = Q + A^TP_{t+1}A - A^TP_{t+1}B(R + B^TP_{t+1}B)^{-1}B^TP_{t+1}A Pt−1​=Q+ATPt+1​A−ATPt+1​B(R+BTPt+1​B)−1BTPt+1​A

  1. 则反馈系数Kt=−(R+BTPt+1B)−1BTPt+1AK_t = -(R + B^TP_{t+1}B)^{-1}B^TP_{t+1}AKt​=−(R+BTPt+1​B)−1BTPt+1​A,对于时间t=0,…,N−1t=0,\dots,N-1t=0,…,N−1
  2. 优化的控制量utlqr=Ktxtu_t^{lqr}=K_tx_tutlqr​=Kt​xt​

最优算法-LQR-离散时间有限边界相关推荐

  1. 【C/C++】阿克曼函数以及其数学的有限边界思维

    ## 在递归函数论和涉及集合的并的某些算法的复杂性研究中,有一个起重要作用的递归函数--阿克曼(Ackermann)函数,该函数是由希尔伯特的学生,德国著名数学家威尔海姆·阿克曼于1928年发现的.这 ...

  2. 线程池:治理线程的法宝

    点击上方"方志朋",选择"设为星标" 回复"666"获取新整理的面试资料 作者:Oo鲁毅oO juejin.im/post/5e1b1fcc ...

  3. ThreadPoolExecutor使用介绍

    private static ExecutorService exec = new ThreadPoolExecutor(8, 8, 0L, TimeUnit.MILLISECONDS, new Li ...

  4. ThreadPool原理介绍

    public class ThreadPoolExecutorextends AbstractExecutorService 一个 ExecutorService,它使用可能的几个池线程之一执行每个提 ...

  5. 大数据框架对比:Hadoop、Storm、Samza、Spark和Flink——flink支持SQL,待看

    简介 大数据是收集.整理.处理大容量数据集,并从中获得见解所需的非传统战略和技术的总称.虽然处理数据所需的计算能力或存储容量早已超过一台计算机的上限,但这种计算类型的普遍性.规模,以及价值在最近几年才 ...

  6. Java线程池--ThreadPoolExecutor

    一.线程池的处理流程 向线程池提交一个任务后,它的主要处理流程如下图所示: 一个线程从被提交(submit)到执行共经历以下流程: 线程池判断核心线程池里的线程是否都在执行任务,如果不是,则创建一个新 ...

  7. 双11还是那个双11,双12却早已不是那个双12

    (图片来源于网络) 文 | 易不二 来源 | 螳螂财经(ID:TanglangFin) 1936年12月12日,张学良和杨虎城在西安发动的兵谏,致使蒋介石停止内战,一致抗日,从而,为抗日战争胜利.新中 ...

  8. Java线程池--拒绝策略RejectedExecutionHandler

    当线程池的任务缓存队列已满并且线程池中的线程数目达到maximumPoolSize,如果还有任务到来就会采取任务拒绝策略,通常有以下四种策略: 当线程池的任务缓存队列已满并且线程池中的线程数目达到ma ...

  9. java后台异步任务执行器TaskManager

    java后台异步任务执行器TaskManager 此方式基于MVC方式: 一,使用任务: 1 @Resource 2 private TaskManager taskManager; 3 4 publ ...

  10. 【局部敏感度的问题代码实现】差分隐私代码实现系列(八)

    差分隐私代码实现系列(八) 写在前面的话 回顾 局部敏感度(Local Sensitivity) 均值的局部灵敏度(Local Sensitivity of the Mean) 通过局部灵敏度实现差分 ...

最新文章

  1. mysql创建非聚集索引_一文看懂聚集索引和非聚集索引的区别
  2. Linux网络编程之select
  3. VS2013+qt-vs-addin-1.2.4安装配置
  4. apache+php32位平台安装
  5. 微软企业库mysql分页存储_使用微软企业库,非分页sql语句得到分页数据方法
  6. PowerDesigner生成数据库设计文档
  7. Linux常用命令--iconv
  8. Windows下Python3.6安装PIL
  9. CSS属性小结之--半透明处理
  10. html手机弧线div,纯css实现让div的四个角成弧形
  11. centos各文件夹作用
  12. 路过秋天版博客 V2.0 正式版发布 增加后台管理系统[支持多语言、多用户、多数据库、目录级URL]
  13. 《剑指offter》
  14. 知道创宇爬虫题--代码持续更新中
  15. 基于知识图谱的知识泛化让AI学会“举一反三”
  16. Oracle的常见错误及解决办法
  17. gstreamer element创建
  18. 全球区块链第9周看点 | 以太坊君士坦丁堡/圣彼得堡硬分叉正式完成;纳斯达克正式上线BTC和ETH指数...
  19. 移动电影院创造中国电影市场的新增量
  20. 学习笔记-如何设计离线跑批系统

热门文章

  1. php mysql上机题_基于PHP+MySQL的题库管理系统
  2. 网络工程师成长日记389-防火墙
  3. js小游戏之锅打灰太狼
  4. 阿里云“芝麻信用互查”产品接入使用过程中遇到的那些坑以及解决方案
  5. 计算机并口被禁用,电脑并口被禁用怎么办
  6. 开放式虚拟仿真实验服务器,润尼尔开放式虚拟仿真实验教学及资源共享平台
  7. 桌面版微信打开链接,H5页面一片空白
  8. cc2530 按键唤醒功耗模式PM3例程
  9. android点九切图,点九图切图规范
  10. Labview 气体/温度检测系统