使用python进行模糊控制模拟仿真

输入量为e\Delta e,单输出u

构建一个模拟环境EPmodel.py,一个输入一个输出

import numpy as np
import matplotlib.pyplot as plt
import math
import random


Pa = 101

class EPmodel:
    def __init__(self):
        self.a = 973
        self.n = 0.955
        self.eta = 0.775
        self.diameter = 6.280  
        self.A = 1/4 * math.pi * self.diameter * self.diameter
        self.L = 900  
        self.Vc = self.A * self.L * 0.599
        self.As = 0.953  
        self.h = 960  

    def Pressure(self, p, v, n):
        K1 = p / Pa
        K2 = self.a * math.pow(K1, self.n) / self.Vc

        K3 = self.A * v
        K4 = (self.As * self.h * self.eta * n) / (2 * math.pi)
        K5 = K3 - K4
        deltaP = K2 * K5

        p_ = p + deltaP

        p__ = np.random.normal(loc=p_, scale=2.0, size=1)

        return p__[0]


if __name__ == '__main__':
    #测试模拟环境
    epm = EPmodel()
    p = 120
    v = 40
    n = 15
    v = v / 60
    n = n / 60

    pList = []
    for i in range(10):
        p_ = epm.Pressure(p, v, n)
        p = p_
        print(p)
        pList.append(p)

    plt.plot(pList)

    plt.show()

编写模糊控制器controller.py

import numpy as np


class FuzzyController:
    def __init__(self, n0):
        self.outputLast = n0
        self.outputMin = 0
        self.outputMax = 16

    def TensorProduct(self, a, b):
        ## a是列向量(表示有多少行) b是行向量(表示有多少列)
        rows = len(a)
        cols = len(b)
        c = np.ones((rows, cols))
        ChooseSmall = lambda x, y: y if x > y else x
        for i in range(rows):
            for j in range(cols):
                c[i, j] = ChooseSmall(a[i], b[j])

        return c

    def ReshapeToCol(self, a):
        rows = a.shape[0]
        cols = a.shape[1]
        length = rows * cols
        b = np.ones(length)
        for i in range(rows):
            r = i*rows
            c = i*rows+cols
            b[r:c] = a[i, :]

        return b[..., np.newaxis]

    def ReshapeToRow(self, a):
        rows = a.shape[0]
        cols = a.shape[1]
        length = rows * cols
        b = np.ones(length)
        for i in range(rows):
            r = i * rows
            c = i * rows + cols
            b[r:c] = a[i, :]

        return b[np.newaxis, ...]

    def MatricUnion(self, a, b):
        ## 矩阵 a b 取并集
        c = np.ones((a.shape[0], a.shape[1]))
        for i in range(a.shape[0]):
            for j in range(a.shape[1]):
                if a[i, j] > b[i, j]:
                    c[i, j] = a[i, j]
                else:
                    c[i, j] = b[i, j]

        return c

    def VectorIntersection(self, a, b):
        ##两个向量取交集(取小数)
        ChooseSmall = lambda x, y: y if x > y else x
        c = np.ones(a.shape[0])
        for i in range(c.shape[0]):
            c[i]= ChooseSmall(a[i], b[i])

        return c

    def Compose(self, a, b):
        ##矩阵合成运算
        i = a.shape[0]
        j = b.shape[1]
        c = np.ones((i, j))
        for ii in range(i):
            for jj in range(j):
                c[ii, jj] = self.VectorIntersection(a[ii, :], b[:, jj]).max()

        return c

    def Output(self, Err, ErrK):
        ## Err是当前值-目标值 x - xd
        # -40, -20, 0, 20, 40
        eTable = [[1, 0, 0, 0, 0],
                  [0, 1, 0, 0, 0],
                  [0, 0, 1, 0, 0],
                  [0, 0, 0, 1, 0],
                  [0, 0, 0, 0, 1]]
        eTable = np.array(eTable)
        # -40, -20, 0, 20, 40
        ecTable = [[1, 0, 0, 0, 0],
                   [0, 1, 0, 0, 0],
                   [0, 0, 1, 0, 0],
                   [0, 0, 0, 1, 0],
                   [0, 0, 0, 0, 1]]
        ecTable = np.array(ecTable)
        # -4, -2, 0, 2, 4
        uTable = [[1, 0, 0, 0, 0],
                  [0, 1, 0, 0, 0],
                  [0, 0, 1, 0, 0],
                  [0, 0, 0, 1, 0],
                  [0, 0, 0, 0, 1]]
        uTable = np.array(uTable)
        R = np.zeros((25, 5))

        ## 控制规则
        a1 = eTable[0, :]
        a2 = eTable[1, :]
        a3 = eTable[2, :]
        a4 = eTable[3, :]
        a5 = eTable[4, :]

        b1 = ecTable[0, :]
        b2 = ecTable[1, :]
        b3 = ecTable[2, :]
        b4 = ecTable[3, :]
        b5 = ecTable[4, :]

        ab11 = self.ReshapeToCol(self.TensorProduct(a1, b1))
        ab12 = self.ReshapeToCol(self.TensorProduct(a1, b2))
        ab13 = self.ReshapeToCol(self.TensorProduct(a1, b3))
        ab14 = self.ReshapeToCol(self.TensorProduct(a1, b4))
        ab15 = self.ReshapeToCol(self.TensorProduct(a1, b5))
        ab21 = self.ReshapeToCol(self.TensorProduct(a2, b1))
        ab22 = self.ReshapeToCol(self.TensorProduct(a2, b2))
        ab23 = self.ReshapeToCol(self.TensorProduct(a2, b3))
        ab24 = self.ReshapeToCol(self.TensorProduct(a2, b4))
        ab25 = self.ReshapeToCol(self.TensorProduct(a2, b5))
        ab31 = self.ReshapeToCol(self.TensorProduct(a3, b1))
        ab32 = self.ReshapeToCol(self.TensorProduct(a3, b2))
        ab33 = self.ReshapeToCol(self.TensorProduct(a3, b3))
        ab34 = self.ReshapeToCol(self.TensorProduct(a3, b4))
        ab35 = self.ReshapeToCol(self.TensorProduct(a3, b5))
        ab41 = self.ReshapeToCol(self.TensorProduct(a4, b1))
        ab42 = self.ReshapeToCol(self.TensorProduct(a4, b2))
        ab43 = self.ReshapeToCol(self.TensorProduct(a4, b3))
        ab44 = self.ReshapeToCol(self.TensorProduct(a4, b4))
        ab45 = self.ReshapeToCol(self.TensorProduct(a4, b5))
        ab51 = self.ReshapeToCol(self.TensorProduct(a5, b1))
        ab52 = self.ReshapeToCol(self.TensorProduct(a5, b2))
        ab53 = self.ReshapeToCol(self.TensorProduct(a5, b3))
        ab54 = self.ReshapeToCol(self.TensorProduct(a5, b4))
        ab55 = self.ReshapeToCol(self.TensorProduct(a5, b5))

        r11 = self.TensorProduct(ab11, uTable[0, :])
        r12 = self.TensorProduct(ab12, uTable[0, :])
        r13 = self.TensorProduct(ab13, uTable[0, :])
        r14 = self.TensorProduct(ab14, uTable[1, :])
        r15 = self.TensorProduct(ab15, uTable[3, :])
        r21 = self.TensorProduct(ab21, uTable[0, :])
        r22 = self.TensorProduct(ab22, uTable[0, :])
        r23 = self.TensorProduct(ab23, uTable[1, :])
        r24 = self.TensorProduct(ab24, uTable[2, :])
        r25 = self.TensorProduct(ab25, uTable[3, :])
        r31 = self.TensorProduct(ab31, uTable[0, :])
        r32 = self.TensorProduct(ab32, uTable[1, :])
        r33 = self.TensorProduct(ab33, uTable[2, :])
        r34 = self.TensorProduct(ab34, uTable[3, :])
        r35 = self.TensorProduct(ab35, uTable[4, :])
        r41 = self.TensorProduct(ab41, uTable[1, :])
        r42 = self.TensorProduct(ab42, uTable[2, :])
        r43 = self.TensorProduct(ab43, uTable[3, :])
        r44 = self.TensorProduct(ab44, uTable[4, :])
        r45 = self.TensorProduct(ab45, uTable[4, :])
        r51 = self.TensorProduct(ab51, uTable[2, :])
        r52 = self.TensorProduct(ab52, uTable[3, :])
        r53 = self.TensorProduct(ab53, uTable[4, :])
        r54 = self.TensorProduct(ab54, uTable[4, :])
        r55 = self.TensorProduct(ab55, uTable[4, :])

        rList = [r11, r12, r13, r14, r15,
                 r21, r22, r23, r24, r25,
                 r31, r32, r33, r34, r35,
                 r41, r42, r43, r44, r45,
                 r51, r52, r53, r54, r55]
        for rr in rList:
            R = self.MatricUnion(R, rr)

        if Err <= -40:
            e = np.array([1, 0, 0, 0, 0])
        if Err > -40 and Err <= -20:
            e = np.array([-1 / 20 * Err - 1, 1 / 20 * Err + 2, 0, 0, 0])
        if Err > -20 and Err <= 0:
            e = np.array([0, -1 / 20 * Err, 1 / 20 * Err + 1, 0, 0])
        if Err > 0 and Err <= 20:
            e = np.array([0, 0, -1 / 20 * Err + 1, 1 / 20 * Err, 0])
        if Err > 20 and Err <= 40:
            e = np.array([0, 0, 0, -1 / 20 * Err + 2, 1 / 20 * Err - 1])
        if Err > 40:
            e = np.array([0, 0, 0, 0, 1])

        if ErrK <= -40:
            ec = np.array([1, 0, 0, 0, 0])
        if ErrK > -40 and ErrK <= -20:
            ec = np.array([-1 / 20 * ErrK - 1, 1 / 20 * ErrK + 2, 0, 0, 0])
        if ErrK > -20 and ErrK <= 0:
            ec = np.array([0, -1 / 20 * ErrK, 1 / 20 * ErrK + 1, 0, 0])
        if ErrK > 0 and ErrK <= 20:
            ec = np.array([0, 0, -1 / 20 * ErrK + 1, 1 / 20 * ErrK, 0])
        if ErrK > 20 and ErrK <= 40:
            ec = np.array([0, 0, 0, -1 / 20 * ErrK + 2, 1 / 20 * ErrK - 1])
        if Err > 40:
            ec = np.array([0, 0, 0, 0, 1])

        u = self.Compose(self.ReshapeToRow(self.TensorProduct(e, ec)), R)
        u = u.squeeze()

        output = (0 * u[0] + 4 * u[1] + 8 * u[2] + 12 * u[3] + 16 * u[4]) / u.sum()
        output = np.clip(output, self.outputLast - 4, self.outputLast + 4)
        output = np.clip(output, self.outputMin, self.outputMax)
        self.outputLast = output

        return output

    def CalDeltaErr(self, y):
        x = np.linspace(0, 9, num=10)
        n = x.shape[0]
        sum_xy = 0
        sum_x = 0
        sum_y = 0
        sum_xx = 0
        for i in range(n):
            sum_xy += x[i] * y[i]
            sum_x += x[i]
            sum_y += y[i]
            sum_xx += x[i] ** 2

        print(sum_xy, sum_x, sum_y, sum_xx)
        k = (n * sum_xy - sum_x * sum_y) / (n * sum_xx - sum_x ** 2)
        b = sum_y / n - k * sum_x / n

        return k


if __name__ == '__main__':
    # 测试
    fc = FuzzyController(0)
    u = fc.Output(0, 0)
    print(u)

    print('done')

e的控制域为、模糊集和隶属度函数按下图所示

\Delta e的控制域、模糊集和隶属度函数与e相同。因此,e和\Delta e的模糊矩阵为

eTable = [[1, 0, 0, 0, 0],
          [0, 1, 0, 0, 0],
          [0, 0, 1, 0, 0],
          [0, 0, 0, 1, 0],
          [0, 0, 0, 0, 1]]
eTable = np.array(eTable)
ecTable = [[1, 0, 0, 0, 0],
           [0, 1, 0, 0, 0],
           [0, 0, 1, 0, 0],
           [0, 0, 0, 1, 0],
           [0, 0, 0, 0, 1]]
ecTable = np.array(ecTable)

u的控制域、模糊集和隶属度函数如下图所示

u的模糊矩阵如下图所示

uTable = [[1, 0, 0, 0, 0],
           [0, 1, 0, 0, 0],
           [0, 0, 1, 0, 0],
           [0, 0, 0, 1, 0],
           [0, 0, 0, 0, 1]]
uTable = np.array(uTable)

定义控制规则矩阵

代码实现如下

## 控制规则
a1 = eTable[0, :]
a2 = eTable[1, :]
a3 = eTable[2, :]
a4 = eTable[3, :]
a5 = eTable[4, :]

b1 = ecTable[0, :]
b2 = ecTable[1, :]
b3 = ecTable[2, :]
b4 = ecTable[3, :]
b5 = ecTable[4, :]

ab11 = self.ReshapeToCol(self.TensorProduct(a1, b1))
ab12 = self.ReshapeToCol(self.TensorProduct(a1, b2))
ab13 = self.ReshapeToCol(self.TensorProduct(a1, b3))
ab14 = self.ReshapeToCol(self.TensorProduct(a1, b4))
ab15 = self.ReshapeToCol(self.TensorProduct(a1, b5))
ab21 = self.ReshapeToCol(self.TensorProduct(a2, b1))
ab22 = self.ReshapeToCol(self.TensorProduct(a2, b2))
ab23 = self.ReshapeToCol(self.TensorProduct(a2, b3))
ab24 = self.ReshapeToCol(self.TensorProduct(a2, b4))
ab25 = self.ReshapeToCol(self.TensorProduct(a2, b5))
ab31 = self.ReshapeToCol(self.TensorProduct(a3, b1))
ab32 = self.ReshapeToCol(self.TensorProduct(a3, b2))
ab33 = self.ReshapeToCol(self.TensorProduct(a3, b3))
ab34 = self.ReshapeToCol(self.TensorProduct(a3, b4))
ab35 = self.ReshapeToCol(self.TensorProduct(a3, b5))
ab41 = self.ReshapeToCol(self.TensorProduct(a4, b1))
ab42 = self.ReshapeToCol(self.TensorProduct(a4, b2))
ab43 = self.ReshapeToCol(self.TensorProduct(a4, b3))
ab44 = self.ReshapeToCol(self.TensorProduct(a4, b4))
ab45 = self.ReshapeToCol(self.TensorProduct(a4, b5))
ab51 = self.ReshapeToCol(self.TensorProduct(a5, b1))
ab52 = self.ReshapeToCol(self.TensorProduct(a5, b2))
ab53 = self.ReshapeToCol(self.TensorProduct(a5, b3))
ab54 = self.ReshapeToCol(self.TensorProduct(a5, b4))
ab55 = self.ReshapeToCol(self.TensorProduct(a5, b5))

r11 = self.TensorProduct(ab11, uTable[0, :])
r12 = self.TensorProduct(ab12, uTable[0, :])
r13 = self.TensorProduct(ab13, uTable[0, :])
r14 = self.TensorProduct(ab14, uTable[1, :])
r15 = self.TensorProduct(ab15, uTable[3, :])
r21 = self.TensorProduct(ab21, uTable[0, :])
r22 = self.TensorProduct(ab22, uTable[0, :])
r23 = self.TensorProduct(ab23, uTable[1, :])
r24 = self.TensorProduct(ab24, uTable[2, :])
r25 = self.TensorProduct(ab25, uTable[3, :])
r31 = self.TensorProduct(ab31, uTable[0, :])
r32 = self.TensorProduct(ab32, uTable[1, :])
r33 = self.TensorProduct(ab33, uTable[2, :])
r34 = self.TensorProduct(ab34, uTable[3, :])
r35 = self.TensorProduct(ab35, uTable[4, :])
r41 = self.TensorProduct(ab41, uTable[1, :])
r42 = self.TensorProduct(ab42, uTable[2, :])
r43 = self.TensorProduct(ab43, uTable[3, :])
r44 = self.TensorProduct(ab44, uTable[4, :])
r45 = self.TensorProduct(ab45, uTable[4, :])
r51 = self.TensorProduct(ab51, uTable[2, :])
r52 = self.TensorProduct(ab52, uTable[3, :])
r53 = self.TensorProduct(ab53, uTable[4, :])
r54 = self.TensorProduct(ab54, uTable[4, :])
r55 = self.TensorProduct(ab55, uTable[4, :])

rList = [r11, r12, r13, r14, r15,
         r21, r22, r23, r24, r25,
         r31, r32, r33, r34, r35,
         r41, r42, r43, r44, r45,
         r51, r52, r53, r54, r55]
for rr in rList:
    R = self.MatricUnion(R, rr)

拿出e为NB时e控制矩阵的对应行a1和\Delta e为NB时\Delta e控制矩阵b1,进行张量乘法(注意顺序),对应函数为

def TensorProduct(self, a, b):

将张量乘法的结果转为列向量(25*1)

def ReshapeToCol(self, a):

e为NB\Delta e为NB时,u为NB,因此,将上述所得列向量与u控制矩阵的NB对应行做张量乘法得到25行5列的矩阵r11,将规则矩阵的25个元素对应的r11到r55求出,25个矩阵取并集

def MatricUnion(self, a, b):

得到规则矩阵R(25*5)

假设当e为-10,\Delta e为20时,计算各自的隶属度矩阵(两个1*5的列向量),将e、\Delta e隶属度矩阵做张量乘法(注意顺序与上面对应),再转为行向量(1*25),与R矩阵(25*5)做矩阵合成运算

def Compose(self, a, b):

得到u的隶属度矩阵(1*5),进行反模糊化,得到输出量

编写主程序main.py 运行仿真,查看控制器效果

from EPmodel import EPmodel
from fuzzy_control import FuzzyController
import numpy as np
import matplotlib.pyplot as plt
import pickle
import time


epm = EPmodel()
pd = 200
v = 30
n = 0
p = 300
fc = FuzzyController(n)
pCache = np.ones(10) * p
pIndex = 0
balanced = 0
nList = []
vList = []
pList = []
for i in range(1000):
    # fuzzy control
    ErrK = fc.CalDeltaErr(pCache)
    Err = p - pd
    n = fc.Output(Err=Err, ErrK=ErrK)

    p_ = epm.Pressure(p, v/60, n/60)
    pCache[pIndex] = p_
    pIndex += 1
    pIndex = pIndex % len(pCache)
    p = pCache.mean()
    print(v, p)
    pList.append(p_)
    nList.append(n)


plt.figure('1')
plt.plot(pList)
plt.figure('2')
plt.plot(nList)

plt.show()

 

倒立摆,也叫倒陆摆,是一种经典的力学系统,可以用来研究控制理论和机器人运动控制算法。在计算机仿真中,我们可以使用Python编程语言来实现倒立摆的仿真。 倒立摆系统由一个可以在水平面上自由旋转的杆和一个悬挂在杆末端的质点组成。在没有外力的情况下,杆会受到重力的作用而垂直下垂。我们的目标是设计一个控制算法,使得杆能够在垂直位置附近保持平衡,即倒立。 首先,我们需要使用Python编写一个数学模型来描述倒立摆系统的动力学。这个模型可以使用牛顿力学原理和刚体动力学理论来建立。通过这个模型,我们可以计算出杆的角度、角速度以及质点的位置和速度等物理量。 然后,我们可以使用Python的数值计算库,如NumPy和SciPy,来求解倒立摆的动力学方程。我们可以使用数值积分方法,如欧拉法或龙格-库塔法,来模拟系统的时间演化过程。 接下来,我们可以设计一个控制算法来实现杆的倒立。常用的控制方法有PID控制器、模糊控制和模型预测控制等。我们可以根据倒立摆系统的特点和控制目标选择适合的控制算法,并使用Python编程语言来实现。 最后,我们可以进行倒立摆的仿真实验,通过给定杆的初始条件和控制输入,观察杆的运动轨迹和平衡性能。可以通过绘制图表和动画来可视化仿真结果,以便更好地理解系统的行为和控制效果。 总之,利用Python编程语言进行倒立摆的仿真可以帮助我们研究和理解控制理论和机器人运动控制算法,并可用于设计和评估不同的控制策略。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值