jjzjj

基于反步法backstepping的自适应控制简介

高能阿博特 2023-05-18 原文

基于反步法backstepping的自适应控制简介

反步法基础

反步法(Backstepping)是一种基于李雅普诺夫稳定性理论的现代控制方法,通过对控制量的数学处理达到稳定性控制的效果,其数学处理过程十分巧妙。
更加详细的反步法基础可以阅读笔者的Backstepping反步法控制四旋翼无人机(2)文章进行了解,本文在这里简单引入反步法的一些基本思想,为基于Backstepping的自适应控制打下基础。

系统描述

一般地,任意系统,不论是线性的还是非线性的,都可以写为以下形式:
x ˙ = f ( x , t ) + g ( t ) u \dot x = f(x, t) + g(t)u x˙=f(x,t)+g(t)u即系统的状态变量 x x x的导数(变化速率)可以用 x , t , u x,t,u x,t,u的函数来描述。
比如,对于最简单的匀加速直线运动系统,设状态变量为位移 x = x 1 x=x_1 x=x1,速度 v = x 2 v=x_2 v=x2,则根据 F = m a F = ma F=ma
x ˙ 1 = x 2 x ˙ 2 = F m \begin{aligned} \dot x_1 = x_2 \\ \dot x_2 = \frac{F}{m} \end{aligned} x˙1=x2x˙2=mF若把力 F F F设为控制量 u u u,那么可以将上式写成矩阵形式
[ x ˙ 1 x ˙ 2 ] = [ 0 1 0 0 ] [ x 1 x 2 ] + [ 0 1 m ] F \left[ \begin{matrix} \dot x_1 \\ \dot x_2 \end{matrix} \right] = \left[ \begin{matrix} 0&1 \\ 0&0 \end{matrix} \right] \left[ \begin{matrix} x_1 \\ x_2 \end{matrix} \right] + \left[ \begin{matrix} 0 \\ \frac{1}{m} \end{matrix} \right] F [x˙1x˙2]=[0010][x1x2]+[0m1]F
该例子为线性的例子,但非线性例子同样可以写为 x ˙ = f ( x , t , u ) \dot x = f(x, t, u) x˙=f(x,t,u)的形式。

反步法运算

要使用反步法有一个小小的限制:最好将变量“分组”设为状态变量,如 x 2 = x ˙ 1 x_2=\dot x_1 x2=x˙1。以下举例进行说明反步法的简单运算,以二阶系统为例。

设有二阶系统
x ˙ 1 = x 2 x ˙ 2 = f ( x , t , u ) \begin{aligned} \dot x_1 &= x_2 \\ \dot x_2 &= f(x,t,u) \end{aligned} x˙1x˙2=x2=f(x,t,u)其中函数 f f f不显含 x ˙ 1 , x ˙ 2 \dot x_1, \dot x_2 x˙1,x˙2的函数。

x 1 x_1 x1的期望值为 x d 1 x_{d1} xd1,则可以得到期望值与实际值的差,即误差
e 1 = x d 1 − x 1 (1) e_1 = x_{d1} - x_1 \tag{1} e1=xd1x1(1)李雅普诺夫函数
V 1 ( e 1 ) = 1 2 e 1 2 V_1 (e_1) = \frac{1}{2} e_1^2 V1(e1)=21e12对其求导有
V ˙ 1 = e 1 e ˙ 1 = e 1 ( x ˙ d 1 − x ˙ 1 ) = e 1 ( x ˙ d 1 − x 2 ) \begin{aligned} \dot V_1 &= e_1 \dot e_1 \\ &= e_1 \left( \dot x_{d1} - \dot x_1 \right) \\ &= e_1 \left( \dot x_{d1} - x_2 \right) \end{aligned} V˙1=e1e˙1=e1(x˙d1x˙1)=e1(x˙d1x2)为了满足李雅普诺夫稳定性理论,最好有 V ˙ 1 = − α 1 e 1 2 ≤ 0 ( α 1 > 0 ) \dot V_1 = - \alpha_1 e_1^2 \leq 0 \quad (\alpha_1 >0) V˙1=α1e120(α1>0),也就是 x ˙ d 1 − x 2 = − α 1 e 1 \dot x_{d1} - x_2 = - \alpha_1 e_1 x˙d1x2=α1e1。在这个基础上可以得到 x 2 = x ˙ d 1 + α 1 e 1 x_2 = \dot x_{d1} + \alpha_1 e_1 x2=x˙d1+α1e1。但是,实际的 x 2 x_2 x2不可能等于这个值,因此这个 x 2 x_2 x2我们称之为“虚拟控制量”,用 x 2 v x_2^v x2v表示:
x 2 v = x ˙ d 1 + α 1 e 1 x_2^v = \dot x_{d1} + \alpha_1 e_1 x2v=x˙d1+α1e1那么,该虚拟控制量和实际 x 2 x_2 x2之间又会存在一个误差:
e 2 = x 2 − x 2 v = x 2 − x ˙ d 1 − α 1 e 1 \begin{aligned} e_2 &= x_2 - x_2^v \\ &= x_2 - \dot x_{d1} - \alpha_1 e_1 \end{aligned} e2=x2x2v=x2x˙d1α1e1亦即
x 2 − x ˙ d 1 = e 2 + α 1 e 1 (2) x_2 - \dot x_{d1} = e_2 + \alpha_1 e_1 \tag{2} x2x˙d1=e2+α1e1(2)同时还能得到
e ˙ 2 = x ˙ 2 − x ¨ d 1 − α 1 e ˙ 1 (3) \dot e_2 = \dot x_2 - \ddot x_{d1} - \alpha_1 \dot e_1 \tag{3} e˙2=x˙2x¨d1α1e˙1(3)
现在,设新的李雅普诺夫函数
V 2 ( e 1 , e 2 ) = 1 2 e 1 2 + 1 2 e 2 2 V_2 (e_1, e_2) = \frac{1}{2} e_1^2 + \frac{1}{2} e_2^2 V2(e1,e2)=21e12+21e22并对其求导(其中考虑到(2)(3)式)
V ˙ 2 = e 1 e ˙ 1 + e 2 e ˙ 2 = e 1 ( x ˙ d 1 − x 2 ) + e 2 ( x ˙ 2 − x ¨ d 1 − α 1 e ˙ 1 ) = e 1 ( − e 2 − α 1 e 1 ) + e 2 [ x ˙ 2 − x ¨ d 1 − α 1 ( − e 2 − α 1 e 1 ) ] = − e 1 e 2 − α 1 e 1 2 + e 2 [ f ( x , t ) + g ( t ) u − x ¨ d 1 + α 1 ( e 2 + α 1 e 1 ) ] (4) \begin{aligned} \dot V_2 &= e_1 \dot e_1 + e_2 \dot e_2 \\ &= e_1 \left( \dot x_{d1} - x_2 \right) + e_2 \left( \dot x_2 - \ddot x_{d1} - \alpha_1 \dot e_1 \right) \\ &= e_1 \left( -e_2 - \alpha_1 e_1 \right) + e_2 \left[ \dot x_2 - \ddot x_{d1} - \alpha_1 \left( -e_2 - \alpha_1 e_1 \right) \right] \\ &= -e_1 e_2 - \alpha_1 e_1^2 + e_2 \left[ f(x,t) +g(t) u - \ddot x_{d1} + \alpha_1 \left( e_2 + \alpha_1 e_1 \right) \right] \tag{4} \end{aligned} V˙2=e1e˙1+e2e˙2=e1(x˙d1x2)+e2(x˙2x¨d1α1e˙1)=e1(e2α1e1)+e2[x˙2x¨d1α1(e2α1e1)]=e1e2α1e12+e2[f(x,t)+g(t)ux¨d1+α1(e2+α1e1)](4)稍加考虑即可发现,若令
u = 1 g ( t ) [ x ¨ d 1 − f ( x , t ) − α 1 ( e 2 + α 1 e 1 ) + e 1 − α 2 e 2 ] (5) u = \frac{1}{g(t)} \left[ \ddot x_{d1} -f(x,t) - \alpha_1 \left( e_2 + \alpha_1 e_1 \right) + e_1 - \alpha_2 e_2 \right] \tag{5} u=g(t)1[x¨d1f(x,t)α1(e2+α1e1)+e1α2e2](5)那么将(5)代入(4)即有
V ˙ 2 = − α 1 e 1 2 − α 2 e 2 2 ≤ 0 \dot V_2 = -\alpha_1 e_1^2 - \alpha_2 e_2^2 \leq 0 V˙2=α1e12α2e220即满足李雅普诺夫稳定性,系统稳定。

可以看出,在整个过程中,通过在 u u u表达式中增减相应的项,可以达到消除 V ˙ 2 \dot V_2 V˙2中某些项的目的,从而使得 V ˙ 2 \dot V_2 V˙2负定或半负定。这个过程完全通过数学运算来规避掉不确定因素,强行使得李雅普诺夫函数负定或半负定,而整个过程中需要确定的参量仅仅是 α 1 , α 2 \alpha_1, \alpha_2 α1,α2两个而已;而控制量 u u u的运算也可以通过(5)式得到。

基于反步法的自适应

反步法是如此的优美,它仅仅通过数学运算,就规定了控制量 u u u的取值方法,实际调参中仅调节 α 1 , α 2 \alpha_1, \alpha_2 α1,α2两个参数,就能达到不错的效果。很容易能想到,当系统中出现了无法预测、无法测量的扰动时,依然可以用相似的思想,用数学方法进行运算规避掉。下面进行简单介绍。

依然是该系统,但存在难以测量的扰动 T T T
x ˙ = f ( x , t ) + g ( t ) u + T \dot x = f(x, t) + g(t)u + T x˙=f(x,t)+g(t)u+T相应地应当有
V ˙ 2 = e 1 e ˙ 1 + e 2 e ˙ 2 = e 1 ( x ˙ d 1 − x 2 ) + e 2 ( x ˙ 2 − x ¨ d 1 − α 1 e ˙ 1 ) = e 1 ( − e 2 − α 1 e 1 ) + e 2 [ x ˙ 2 − x ¨ d 1 − α 1 ( − e 2 − α 1 e 1 ) ] = − e 1 e 2 − α 1 e 1 2 + e 2 [ f ( x , t ) + g ( t ) u + T − x ¨ d 1 + α 1 ( e 2 + α 1 e 1 ) ] (6) \begin{aligned} \dot V_2 &= e_1 \dot e_1 + e_2 \dot e_2 \\ &= e_1 \left( \dot x_{d1} - x_2 \right) + e_2 \left( \dot x_2 - \ddot x_{d1} - \alpha_1 \dot e_1 \right) \\ &= e_1 \left( -e_2 - \alpha_1 e_1 \right) + e_2 \left[ \dot x_2 - \ddot x_{d1} - \alpha_1 \left( -e_2 - \alpha_1 e_1 \right) \right] \\ &= -e_1 e_2 - \alpha_1 e_1^2 + e_2 \left[ f(x,t) +g(t) u + T - \ddot x_{d1} + \alpha_1 \left( e_2 + \alpha_1 e_1 \right) \right] \tag{6} \end{aligned} V˙2=e1e˙1+e2e˙2=e1(x˙d1x2)+e2(x˙2x¨d1α1e˙1)=e1(e2α1e1)+e2[x˙2x¨d1α1(e2α1e1)]=e1e2α1e12+e2[f(x,t)+g(t)u+Tx¨d1+α1(e2+α1e1)](6)应当注意,在(6)式中将 x ˙ 2 \dot x_2 x˙2表达式代入时,出现了 T T T
根据之前所述, T T T无法测量,因此无法得知其真实值。那么如果再按照(5)的方法设计 u u u,那么 u u u中势必会显含 T T T
u = 1 g ( t ) [ x ¨ d 1 − f ( x , t ) − α 1 ( e 2 + α 1 e 1 ) + e 1 − α 2 e 2 − T ] (7) u = \frac{1}{g(t)} \left[ \ddot x_{d1} -f(x,t) - \alpha_1 \left( e_2 + \alpha_1 e_1 \right) + e_1 - \alpha_2 e_2 - T\right] \tag{7} u=g(t)1[x¨d1f(x,t)α1(e2+α1e1)+e1α2e2T](7) T T T未知,从而 u u u也无法计算。
那么,该如何把这个不可测量的 T T T规避掉呢?

不可测量参数的规避

既然 T T T的真实值无法测量,不如引入一个估计值 T ^ \hat T T^。很明显,该估计值是怎么“估计”得到的依然是个亟待解决的问题,但这不影响我们后续的推导,且在我们后续的推导中可以看出,该估计值的具体估计表达式实际上和 T T T的真实值并无关系

设对于扰动 T T T,其实际值与估计值之间的误差为
ε = T − T ^ (8) \varepsilon = T - \hat T \tag{8} ε=TT^(8)且有
ε ˙ = T ˙ − T ^ ˙ \dot \varepsilon = \dot T - \dot {\hat T} ε˙=T˙T^˙一般地,若将扰动视为瞬时的、脉冲性的,则在极短时间 Δ t \Delta t Δt可以有 T ˙ ≈ 0 \dot T \approx 0 T˙0,因而
ε ˙ = − T ^ ˙ (9) \dot \varepsilon = - \dot {\hat T} \tag{9} ε˙=T^˙(9)现在暂且把 ε \varepsilon ε放在一边,回来考虑控制量 u u u的设计。既然在(7)中含有实际值 T T T,无法计算 u u u的准确值,那不如把(7)中的 T T T替换成 T ^ \hat T T^,这样一来,用估计值代入 u u u表达式来计算 u u u
u = 1 g ( t ) [ x ¨ d 1 − f ( x , t ) − α 1 ( e 2 + α 1 e 1 ) + e 1 − α 2 e 2 − T ^ ] (10) u = \frac{1}{g(t)} \left[ \ddot x_{d1} -f(x,t) - \alpha_1 \left( e_2 + \alpha_1 e_1 \right) + e_1 - \alpha_2 e_2 - \hat T\right] \tag{10} u=g(t)1[x¨d1f(x,t)α1(e2+α1e1)+e1α2e2T^](10)换句话说就是,(7)中只有 T T T这一项无法得知,那不如换成其估计值(因为估计值是一个已知的值),这样 u u u就可以计算了。

现在看来, u u u可以利用 T ^ \hat T T^计算了,满足(10)的 u u u就可以使 V 2 V_2 V2满足李雅普诺夫稳定性。可是,真正实施起来就会如此顺利吗?

不可测量参数的估计值的计算方法

细心的读者可能发现了,我们用 T ^ \hat T T^替换掉 T T T的大前提是,我们假设 T ^ \hat T T^是已知量,是能算出来的。可是, T T T作为一个瞬发性扰动,无法预测、无法测量、极难建模,那又该用什么样的数学公式、什么样的方法去估计 T T T得到 T ^ \hat T T^呢?连 T T T的数学模型都不知道,该如何估计它?

这里,我们回头检视我们的整个运算过程,会发现中间除了 e 1 , e 2 e_1, e_2 e1,e2,还出现了第三个误差量 ε \varepsilon ε。因此,不妨再次设计新的李雅普诺夫函数,把所有误差量都考虑进去:
V 3 ( e 1 , e 2 , ε ) = 1 2 e 1 2 + 1 2 e 2 2 + 1 2 λ ε 2 (11) V_3(e_1, e_2, \varepsilon) = \frac{1}{2} e_1^2 + \frac{1}{2} e_2^2 + \frac{1}{2 \lambda} \varepsilon^2 \tag{11} V3(e1,e2,ε)=21e12+21e22+2λ1ε2(11)对其求导(代入(9))
V ˙ 3 = e 1 e ˙ 1 + e 2 e ˙ 2 + ε ε ˙ = e 1 ( x ˙ d 1 − x 2 ) + e 2 ( x ˙ 2 − x ¨ d 1 − α 1 e ˙ 1 ) + 1 λ ε ( − T ^ ˙ ) = e 1 ( − e 2 − α 1 e 1 ) + e 2 [ x ˙ 2 − x ¨ d 1 − α 1 ( − e 2 − α 1 e 1 ) ] − 1 λ ε T ^ ˙ = − e 1 e 2 − α 1 e 1 2 + e 2 [ f ( x , t ) + g ( t ) u + T − x ¨ d 1 + α 1 ( e 2 + α 1 e 1 ) ] − 1 λ ε T ^ ˙ (12) \begin{aligned} \dot V_3 &= e_1 \dot e_1 + e_2 \dot e_2 + \varepsilon \dot \varepsilon \\ &= e_1 \left( \dot x_{d1} - x_2 \right) + e_2 \left( \dot x_2 - \ddot x_{d1} - \alpha_1 \dot e_1 \right) + \frac{1}{\lambda} \varepsilon \left( - \dot {\hat T} \right) \\ &= e_1 \left( -e_2 - \alpha_1 e_1 \right) + e_2 \left[ \dot x_2 - \ddot x_{d1} - \alpha_1 \left( -e_2 - \alpha_1 e_1 \right) \right] - \frac{1}{\lambda} \varepsilon \dot {\hat T} \\ &= -e_1 e_2 - \alpha_1 e_1^2 + e_2 \left[ f(x,t) +g(t) u + T - \ddot x_{d1} + \alpha_1 \left( e_2 + \alpha_1 e_1 \right) \right] - \frac{1}{\lambda} \varepsilon \dot {\hat T} \tag{12} \end{aligned} V˙3=e1e˙1+e2e˙2+εε˙=e1(x˙d1x2)+e2(x˙2x¨d1α1e˙1)+λ1ε(T^˙)=e1(e2α1e1)+e2[x˙2x¨d1α1(e2α1e1)]λ1εT^˙=e1e2α1e12+e2[f(x,t)+g(t)u+Tx¨d1+α1(e2+α1e1)]λ1εT^˙(12)把显含 T ^ \hat T T^ u u u的表达式(10)代入(12)有
V ˙ 3 = − α 1 e 1 2 − α 2 e 2 2 + e 2 ( T − T ^ ) − 1 λ ε T ^ ˙ = − α 1 e 1 2 − α 2 e 2 2 + e 2 ε − 1 λ ε T ^ ˙ (13) \begin{aligned} \dot V_3 &= - \alpha_1 e_1^2 - \alpha_2 e_2^2 + e_2 \left( T - \hat T \right) - \frac{1}{\lambda} \varepsilon \dot {\hat T} \\ &= - \alpha_1 e_1^2 - \alpha_2 e_2^2 + e_2 \varepsilon - \frac{1}{\lambda} \varepsilon \dot {\hat T} \tag{13} \end{aligned} V˙3=α1e12α2e22+e2(TT^)λ1εT^˙=α1e12α2e22+e2ελ1εT^˙(13)显然,为了使 V ˙ 3 ≤ 0 \dot V_3 \leq 0 V˙30,最好有
e 2 ε − 1 λ ε T ^ ˙ = 0 (14) e_2 \varepsilon - \frac{1}{\lambda} \varepsilon \dot {\hat T} = 0 \tag{14} e2ελ1εT^˙=0(14)
T ^ ˙ = λ e 2 (15) \dot {\hat T} = \lambda e_2 \tag{15} T^˙=λe2(15)换句话说,只要估计值 T ^ \hat T T^满足了式(15),那么所得到的李雅普诺夫函数就是负定或者半负定的,系统就是稳定的
而可喜的是,即使我们并不知道 T T T的实际数学模型,我们也不知道根据式(15)得到的“估计值”是否接近真实值,但是该估计值确实有效,它确实可以使系统稳定。只需要改变 α 1 , α 2 , λ \alpha_1, \alpha_2, \lambda α1,α2,λ三个参数,就可以使系统稳定。

更加值得注意的是,每次迭代运算中, e 2 = x 2 − x 2 v e_2 = x_2 - x_2^v e2=x2x2v的值都是改变的,因此 T ^ ˙ \dot {\hat T} T^˙的值也是改变的,即每次迭代时 T ^ ˙ \dot {\hat T} T^˙都可以“自适应”地去改变自身参数,以达到整体系统的稳定。我们不知道每次迭代时估计值 T ^ \hat T T^有多接近真实值 T T T,但是利用式(15)的确可以达到稳定。

因此,可以做出以下结论:

  1. 本质上,基于backstepping的自适应控制算法依然是利用数学技巧去进行某些项的消去操作强行使得最后的李雅普诺夫函数负定或者半负定;
  2. 与backstepping不同的是,控制量 u u u的表达式中需要多出一项估计值 T ^ \hat T T^
  3. 该估计值是否能够准确估计 T T T不得而知,估计规律 T ^ ˙ = λ e 2 \dot {\hat T} = \lambda e_2 T^˙=λe2是否正确也不得而知,但是该估计规律却可以帮助我们消项,并进一步达到李雅普诺夫函数的负定或半负定;
  4. 可以通过调节 λ \lambda λ参数来改变 T ^ \hat T T^ T T T的“接近程度”,进而达到系统稳定。
  5. 笔者认为,该控制算法“自适应”之处在于,即使对扰动 T T T无法建模,依然可以通过一些规律 T ^ ˙ = λ e 2 \dot {\hat T} = \lambda e_2 T^˙=λe2来维持系统稳定,而式(15)的有效性恰恰证明了该估计规律对 T T T的实际值“适应”得很好。

在后续的笔记中,我会在基于反步法的四旋翼控制基础上,引入扰动项,并利用本文所讲述的自适应方法进行控制。请拭目以待!

有关基于反步法backstepping的自适应控制简介的更多相关文章

  1. Ruby Readline 在向上箭头上使控制台崩溃 - 2

    当我在Rails控制台中按向上或向左箭头时,出现此错误:irb(main):001:0>/Users/me/.rvm/gems/ruby-2.0.0-p247/gems/rb-readline-0.4.2/lib/rbreadline.rb:4269:in`blockin_rl_dispatch_subseq':invalidbytesequenceinUTF-8(ArgumentError)我使用rvm来管理我的ruby​​安装。我正在使用=>ruby-2.0.0-p247[x86_64]我使用bundle来管理我的gem,并且我有rb-readline(0.4.2)(人们推荐的最少

  2. ruby-on-rails - 带 Spring 锁的 Rails 4 控制台 - 2

    我正在使用Ruby2.1.1和Rails4.1.0.rc1。当执行railsc时,它被锁定了。使用Ctrl-C停止,我得到以下错误日志:~/.rvm/gems/ruby-2.1.1/gems/spring-1.1.2/lib/spring/client/run.rb:47:in`gets':Interruptfrom~/.rvm/gems/ruby-2.1.1/gems/spring-1.1.2/lib/spring/client/run.rb:47:in`verify_server_version'from~/.rvm/gems/ruby-2.1.1/gems/spring-1.1.

  3. ruby-on-rails - openshift 上的 rails 控制台 - 2

    我将我的Rails应用程序部署到OpenShift,它运行良好,但我无法在生产服务器上运行“Rails控制台”。它给了我这个错误。我该如何解决这个问题?我尝试更新ruby​​gems,但它也给出了权限被拒绝的错误,我也无法做到。railsc错误:Warning:You'reusingRubygems1.8.24withSpring.UpgradetoatleastRubygems2.1.0andrun`gempristine--all`forbetterstartupperformance./opt/rh/ruby193/root/usr/share/rubygems/rubygems

  4. 叮咚买菜基于 Apache Doris 统一 OLAP 引擎的应用实践 - 2

    导读:随着叮咚买菜业务的发展,不同的业务场景对数据分析提出了不同的需求,他们希望引入一款实时OLAP数据库,构建一个灵活的多维实时查询和分析的平台,统一数据的接入和查询方案,解决各业务线对数据高效实时查询和精细化运营的需求。经过调研选型,最终引入ApacheDoris作为最终的OLAP分析引擎,Doris作为核心的OLAP引擎支持复杂地分析操作、提供多维的数据视图,在叮咚买菜数十个业务场景中广泛应用。作者|叮咚买菜资深数据工程师韩青叮咚买菜创立于2017年5月,是一家专注美好食物的创业公司。叮咚买菜专注吃的事业,为满足更多人“想吃什么”而努力,通过美好食材的供应、美好滋味的开发以及美食品牌的孵

  5. 基于C#实现简易绘图工具【100010177】 - 2

    C#实现简易绘图工具一.引言实验目的:通过制作窗体应用程序(C#画图软件),熟悉基本的窗体设计过程以及控件设计,事件处理等,熟悉使用C#的winform窗体进行绘图的基本步骤,对于面向对象编程有更加深刻的体会.Tutorial任务设计一个具有基本功能的画图软件**·包括简单的新建文件,保存,重新绘图等功能**·实现一些基本图形的绘制,包括铅笔和基本形状等,学习橡皮工具的创建**·设计一个合理舒适的UI界面**注明:你可能需要先了解一些关于winform窗体应用程序绘图的基本知识,以及关于GDI+类和结构的知识二.实验环境Windows系统下的visualstudio2017C#窗体应用程序三.

  6. C51单片机——实现用独立按键控制LED亮灭(调用函数篇) - 2

    说在前面这部分我本来是合为一篇来写的,因为目的是一样的,都是通过独立按键来控制LED闪灭本质上是起到开关的作用,即调用函数和中断函数。但是写一篇太累了,我还是决定分为两篇写,这篇是调用函数篇。在本篇中你主要看到这些东西!!!1.调用函数的方法(主要讲语法和格式)2.独立按键如何控制LED亮灭3.程序中的一些细节(软件消抖等)1.调用函数的方法思路还是比较清晰地,就是通过按下按键来控制LED闪灭,即每按下一次,LED取反一次。重要的是,把按键与LED联系在一起。我打算用K1来作为开关,看了一下开发板原理图,K1连接的是单片机的P31口,当按下K1时,P31是与GND相连的,也就是说,当我按下去时

  7. kvm虚拟机安装centos7基于ubuntu20.04系统 - 2

    需求:要创建虚拟机,就需要给他提供一个虚拟的磁盘,我们就在/opt目录下创建一个10G大小的raw格式的虚拟磁盘CentOS-7-x86_64.raw命令格式:qemu-imgcreate-f磁盘格式磁盘名称磁盘大小qemu-imgcreate-f磁盘格式-o?1.创建磁盘qemu-imgcreate-fraw/opt/CentOS-7-x86_64.raw10G执行效果#ls/opt/CentOS-7-x86_64.raw2.安装虚拟机使用virt-install命令,基于我们提供的系统镜像和虚拟磁盘来创建一个虚拟机,另外在创建虚拟机之前,提前打开vnc客户端,在创建虚拟机的时候,通过vnc

  8. HBase Region 简介和建议数量&大小 - 2

    Region是HBase数据管理的基本单位,region有一点像关系型数据的分区。region中存储这用户的真实数据,而为了管理这些数据,HBase使用了RegionSever来管理region。Region的结构hbaseregion的大小设置默认情况下,每个Table起初只有一个Region,随着数据的不断写入,Region会自动进行拆分。刚拆分时,两个子Region都位于当前的RegionServer,但处于负载均衡的考虑,HMaster有可能会将某个Region转移给其他的RegionServer。RegionSplit时机:当1个region中的某个Store下所有StoreFile

  9. ruby-on-rails - 在 Rails 控制台中使用 asset_path - 2

    在我的Character模型中,我添加了:字符.rbbefore_savedoself.profile_picture_url=asset_path('icon.png')end但是,对于数据库中已存在的所有角色,它们的profile_picture_url为nil。因此,我想进入控制台并遍历所有这些并进行设置。在我试过的控制台中:Character.find_eachdo|c|c.profile_picture_url=asset_path('icon.png')end但这给出了错误:NoMethodError:undefinedmethod`asset_path'formain:O

  10. ruby-on-rails - 带有 Pry 的 Rails 控制台 - 2

    当我进入Rails控制台时,我已将pry设置为加载代替irb。我找不到该页面或不记得如何将其恢复为默认行为,因为它似乎干扰了我的Rubymine调试器。有什么建议吗? 最佳答案 我刚发现问题,pry-railsgem。忘记了它的目的是让“railsconsole”打开pry。 关于ruby-on-rails-带有Pry的Rails控制台,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/question

随机推荐