AoboSir 博客

与15年前的我比,我现在是大人;与15年后的我比,我现在还是个婴儿

Python3 大型网络爬虫实战 001 --- 搭建开发环境


我使用的电脑: Windows 10 64位

前言

开发Python爬虫有很多种方式,从程序的复杂程度的角度来说,可以分为:爬虫项目和爬虫文件。 相信有些朋友玩过Python的urllib模块,一般我们可以用该模块写一些爬虫文件,实现起来非常方便,但做大型项目的时候,会发现效率不是太好、并且程序的稳定性也不是太好。 Scrapy是一个Python的爬虫框架,使用Scrapy可以提高开发效率,并且非常适合做一些中大型爬虫项目。 简单来说,urllib库更适合写爬虫文件,scrapy更适合做爬虫项目。

本套专栏,就来讲解如何做爬虫项目。本篇博客是第一篇博客:搭建开发环境。

1 . 安装Python3

到官网下载就可以了,下载一个Python3.5版本就可以,傻瓜式安装。

Python 3 被默认安装在:C:\Users\[Username]\AppData\Local\Programs\Python\Python35 这个路径里面。

2 . 安装Python程序开发集成开发环境 — PyCharm IDE 2016.1.4

软件下载:https://www.jetbrains.com/pycharm/download/#section=windows

注意:

Professional是完整版的,但是需要注册码

注册方法:http://blog.csdn.net/tianzhaixing2013/article/details/44997881

我这次安装的是PyCharm 2016。

Community是免费版的,但是软件里面的Terminal是不能使用的。

3 . 安装 Visual Studio 2015 软件

要知道:为什么需要 Visual Studio 软件了。(参考这个网站

如果不安装,当中你执行pip install third-package-name时,有时会出现下面这个错误: error: Unable to find vcvarsall.bat

Alt text

安装Visual Studio 2015 软件是为了安装里面的Python Tools 2.2.5 for Visual Studio 2015软件。

下载和安装 Visual Studio 2015 软件 的方法在这里

4 . 升级 pip 工具

在DOS窗口中执行下面的命令来升级pip工具。

1
python -m pip install --upgrade pip

5 . 安装一些第三方库

lxml、Twisted、pywin32、scrapy

lxml是一种可以迅速、灵活地处理 XML。 Twisted是用Python实现的基于事件驱动的网络引擎框架。 pywin32提供win32api。 Scrapy是一个为了爬取网站数据,提取结构性数据而编写的应用框架。


我们安装的是python3.5,并且我的电脑是64位的,所以:下载:

lxml‑3.6.4‑cp35‑cp35m‑win_amd64.whl

Twisted‑16.5.0‑cp35‑cp35m‑win_amd64.whl

pywin32‑220.1‑cp35‑cp35m‑win_amd64.whl

scrapy(直接使用命令:pip.exe install scrapy 来安装。)


Python安装第三方库的方法:http://blog.csdn.net/github_35160620/article/details/52203682

注意:如果你的电脑之前安装了Python2,那么Python2 有自己的pip工具,Python3 也是有自己的pip工具,所以,如果你在DOS命令行上执行pip install some-package-name命令的时候,系统会使用哪个pip工具呢?是python2的pip,还是python3的pip?

这个问题,你可以在这篇博客里得到解决答案:http://www.aobosir.com/blog/2016/11/23/pip-install-python2-python3/


下载后,在我的电脑上是这样安装:

安装 lxml:

1
2
3
4
5
C:\Users\AOBO>cd C:\Users\AOBO\AppData\Local\Programs\Python\Python35\Scripts
C:\Users\AOBO\AppData\Local\Programs\Python\Python35\Scripts>pip.exe install D:\software_install_package_win\python\some-Python-third-packages\lxml-3.6.4-cp35-cp35m-win_amd64.whl
Processing d:\software_install_package_win\python\some-python-third-packages\lxml-3.6.4-cp35-cp35m-win_amd64.whl
Installing collected packages: lxml
Successfully installed lxml-3.6.4

安装 Twisted :(执行到Collecting constantly>=15.1 (from Twisted==16.5.0)这句时,卡住了,我按了 Ctrl+C 才继续执行下去。自动下载了下面的:constantly、incremental、zope.interface 这三个依赖库)

1
2
3
4
5
6
7
8
9
10
11
12
13
C:\Users\AOBO\AppData\Local\Programs\Python\Python35\Scripts>pip.exe install D:\software_install_package_win\python\some-Python-third-packages\Twisted-16.5.0-cp35-cp35m-win_amd64.whl
Processing d:\software_install_package_win\python\some-python-third-packages\twisted-16.5.0-cp35-cp35m-win_amd64.whl
Collecting constantly>=15.1 (from Twisted==16.5.0)
#(执行到这卡住了,我按了 Ctrl+C 才继续执行下去。自动下载了下面的:constantly、incremental、zope.interface 这三个依赖库)
  Downloading constantly-15.1.0-py2.py3-none-any.whl
Collecting incremental>=16.10.1 (from Twisted==16.5.0)
  Downloading incremental-16.10.1-py2.py3-none-any.whl
Collecting zope.interface>=4.0.2 (from Twisted==16.5.0)
  Downloading zope.interface-4.3.2-cp35-cp35m-win_amd64.whl (136kB)
    100% |████████████████████████████████| 143kB 7.1kB/s
Requirement already satisfied: setuptools in c:\users\aobo\appdata\local\programs\python\python35\lib\site-packages (from zope.interface>=4.0.2->Twisted==16.5.0)
Installing collected packages: constantly, incremental, zope.interface, Twisted
Successfully installed Twisted-16.5.0 constantly-15.1.0 incremental-16.10.1 zope.interface-4.3.2

安装pywin32:

1
2
3
4
C:\Users\AOBO\AppData\Local\Programs\Python\Python35\Scripts>pip.exe install D:\software_install_package_win\python\some-Python-third-packages\pywin32-220.1-cp35-cp35m-win_amd64.whl
Processing d:\software_install_package_win\python\some-python-third-packages\pywin32-220.1-cp35-cp35m-win_amd64.whl
Installing collected packages: pywin32
Successfully installed pywin32-220.1

安装scropy:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
C:\Users\AOBO\AppData\Local\Programs\Python\Python35\Scripts>pip.exe install scrapy
Collecting scrapy
  Downloading Scrapy-1.2.1-py2.py3-none-any.whl (294kB)
    100% |████████████████████████████████| 296kB 338kB/s
Collecting service-identity (from scrapy)
  Downloading service_identity-16.0.0-py2.py3-none-any.whl
Collecting six>=1.5.2 (from scrapy)
  Downloading six-1.10.0-py2.py3-none-any.whl
Collecting w3lib>=1.15.0 (from scrapy)
  Downloading w3lib-1.16.0-py2.py3-none-any.whl
Collecting PyDispatcher>=2.0.5 (from scrapy)
  Downloading PyDispatcher-2.0.5.tar.gz
Requirement already satisfied: Twisted>=10.0.0 in c:\users\aobo\appdata\local\programs\python\python35\lib\site-packages (from scrapy)
Requirement already satisfied: lxml in c:\users\aobo\appdata\local\programs\python\python35\lib\site-packages (from scrapy)
Collecting cssselect>=0.9 (from scrapy)
  Downloading cssselect-1.0.0-py2.py3-none-any.whl
Collecting parsel>=0.9.3 (from scrapy)
  Downloading parsel-1.1.0-py2.py3-none-any.whl
Collecting queuelib (from scrapy)
  Downloading queuelib-1.4.2-py2.py3-none-any.whl
Collecting pyOpenSSL (from scrapy)
  Downloading pyOpenSSL-16.2.0-py2.py3-none-any.whl (43kB)
    100% |████████████████████████████████| 51kB 4.7MB/s
Collecting pyasn1 (from service-identity->scrapy)
  Downloading pyasn1-0.1.9-py2.py3-none-any.whl
Collecting pyasn1-modules (from service-identity->scrapy)
  Downloading pyasn1_modules-0.0.8-py2.py3-none-any.whl
Collecting attrs (from service-identity->scrapy)
  Downloading attrs-16.2.0-py2.py3-none-any.whl
Requirement already satisfied: constantly>=15.1 in c:\users\aobo\appdata\local\programs\python\python35\lib\site-packages (from Twisted>=10.0.0->scrapy)
Requirement already satisfied: zope.interface>=4.0.2 in c:\users\aobo\appdata\local\programs\python\python35\lib\site-packages (from Twisted>=10.0.0->scrapy)
Requirement already satisfied: incremental>=16.10.1 in c:\users\aobo\appdata\local\programs\python\python35\lib\site-packages (from Twisted>=10.0.0->scrapy)
Collecting cryptography>=1.3.4 (from pyOpenSSL->scrapy)
  Downloading cryptography-1.6-cp35-cp35m-win_amd64.whl (1.3MB)
    100% |████████████████████████████████| 1.3MB 257kB/s
Requirement already satisfied: setuptools in c:\users\aobo\appdata\local\programs\python\python35\lib\site-packages (from zope.interface>=4.0.2->Twisted>=10.0.0->scrapy)
Collecting cffi>=1.4.1 (from cryptography>=1.3.4->pyOpenSSL->scrapy)
  Downloading cffi-1.9.1-cp35-cp35m-win_amd64.whl (158kB)
    100% |████████████████████████████████| 163kB 322kB/s
Collecting idna>=2.0 (from cryptography>=1.3.4->pyOpenSSL->scrapy)
  Downloading idna-2.1-py2.py3-none-any.whl (54kB)
    100% |████████████████████████████████| 61kB 4.4MB/s
Collecting pycparser (from cffi>=1.4.1->cryptography>=1.3.4->pyOpenSSL->scrapy)
  Downloading pycparser-2.17.tar.gz (231kB)
    100% |████████████████████████████████| 235kB 311kB/s
Installing collected packages: six, pycparser, cffi, pyasn1, idna, cryptography, pyOpenSSL, pyasn1-modules, attrs, service-identity, w3lib, PyDispatcher, cssselect, parsel, queuelib, scrapy
  Running setup.py install for pycparser ... done
  Running setup.py install for PyDispatcher ... done
Successfully installed PyDispatcher-2.0.5 attrs-16.2.0 cffi-1.9.1 cryptography-1.6 cssselect-1.0.0 idna-2.1 parsel-1.1.0 pyOpenSSL-16.2.0 pyasn1-0.1.9 pyasn1-modules-0.0.8 pycparser-2.17 queuelib-1.4.2 scrapy-1.2.1 service-identity-16.0.0 six-1.10.0 w3lib-1.16.0

查看 scrapy 是否安装成功:(执行scrapy -h 命令,如果能输出信息,说明安装成功)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
C:\Users\AOBO>scrapy -h
Scrapy 1.2.1 - no active project

Usage:
  scrapy <command> [options] [args]

Available commands:
  bench         Run quick benchmark test
  commands
  fetch         Fetch a URL using the Scrapy downloader
  genspider     Generate new spider using pre-defined templates
  runspider     Run a self-contained spider (without creating a project)
  settings      Get settings values
  shell         Interactive scraping console
  startproject  Create new project
  version       Print Scrapy version
  view          Open URL in browser, as seen by Scrapy

  [ more ]      More commands available when run from project directory

Use "scrapy <command> -h" to see more info about a command

C:\Users\AOBO>

检查所有刚刚安装的库是否安装成功:

启动PyCharm 软件,新建一个工程:

Alt text

Alt text

刚刚安装的库在这里可以看到:

Alt text

安装成功。


6 . 一个超好的命令行串口软件 — PowerCmd

PowerCmd 是一款Windows CMD 的增强工具。

下载安装地址:http://www.aobosir.com/blog/2016/11/23/powercmd-install/

这个软件真的很喽,像我执行scrapy -h 这样的命令,都打印不出信息,在DOS窗口里面是有信息打印出来的。



测试环境

1 . 执行 scrapy -h,如果有打印出来信息,说明Scrapy 安装成功。

2 . 执行 scrapy bench ,如果遇到问题,说明pywin32库还有需要完成的步骤。(解决问题: import win32api ImportError: DLL load failed,到这里查看解决办法。)


接下来,我们学习 Scrapy 的命令。了解了Scrapy 命令后,我学习:scrapy 爬虫项目的创建及爬虫的创建 — 实例:爬取百度标题和CSDN博客


Python3 Pip 解决问题: Error: Unable to Find vcvarsall.bat


当我给 python3.5 安装 第三方库 charset 时:pip install charset,出现了错误:

Alt text

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
D:\WorkSpace\python_ws\python-large-web-crawler\firstdemo>pip install charset
Collecting charset
  Downloading charset-1.0.1.tar.gz (189kB)
    100% |████████████████████████████████| 194kB 3.9kB/s
Collecting chardet (from charset)
  Using cached chardet-2.3.0.tar.gz
Installing collected packages: chardet, charset
  Running setup.py install for chardet ... done
  Running setup.py install for charset ... error
    Complete output from command c:\users\aobo\appdata\local\programs\python\python35\python.exe -u -c "import setuptools, tokenize;__file__='C:\\Users\\AOBO\\AppData\\Local\\Temp\\pip-build-ydv8oep3\\charset\\setup.py';f=getattr(tokenize, 'open', open)(__file__);code=f.read().replace('\r\n', '\n');f.close();exec(compile(code, __file__, 'exec'))" install --record C:\Users\AOBO\AppData\Local\Temp\pip-hlxpja30-record\install-record.txt --single-version-externally-managed --compile:
    running install
    running build
    running build_py
    creating build
    creating build\lib.win-amd64-3.5
    creating build\lib.win-amd64-3.5\charset
    copying charset\cmd.py -> build\lib.win-amd64-3.5\charset
    copying charset\__init__.py -> build\lib.win-amd64-3.5\charset
    running egg_info
    writing charset.egg-info\PKG-INFO
    writing top-level names to charset.egg-info\top_level.txt
    writing dependency_links to charset.egg-info\dependency_links.txt
    writing requirements to charset.egg-info\requires.txt
    writing entry points to charset.egg-info\entry_points.txt
    warning: manifest_maker: standard file '-c' not found

    reading manifest file 'charset.egg-info\SOURCES.txt'
    reading manifest template 'MANIFEST.in'
    warning: no files found matching '*.txt' under directory 'docs'
    warning: no files found matching '*.txt' under directory 'languagedet\data'
    warning: no files found matching '*.pickle' under directory 'languagedet\data'
    warning: no files found matching '*.conf' under directory 'languagedet\data'
    writing manifest file 'charset.egg-info\SOURCES.txt'
    running build_ext
    building 'charset.detector' extension
    error: Unable to find vcvarsall.bat

    ----------------------------------------
Command "c:\users\aobo\appdata\local\programs\python\python35\python.exe -u -c "import setuptools, tokenize;__file__='C:\\Users\\AOBO\\AppData\\Local\\Temp\\pip-build-ydv8oep3\\charset\\setup.py';f=getattr(tokenize, 'open', open)(__file__);code=f.read().replace('\r\n', '\n');f.close();exec(compile(code, __file__, 'exec'))" install --record C:\Users\AOBO\AppData\Local\Temp\pip-hlxpja30-record\install-record.txt --single-version-externally-managed --compile" failed with error code 1 in C:\Users\AOBO\AppData\Local\Temp\pip-build-ydv8oep3\charset\

为什么出现这个问题?

在命令行中执行:python,看看当前使用的python的版本,和它所需要的Vs软件的编译器的版本:

Alt text

当前python版本是:python3.5.0;当前需要的Vs编译器的版本是:MSC v. 1900

查看下面的表格,对于版本的Visual C ++使用的编译器版本如下:(表的参考网站

Visual C ++版本 编译器版本
Visual C++ 4.x MSC_VER=1000
Visual C++ 5 MSC_VER=1100
Visual C++ 6 MSC_VER=1200
Visual C++ .NET MSC_VER=1300
Visual C++ .NET 2003 MSC_VER=1310
Visual C++ 2005 (8.0) MSC_VER=1400
Visual C++ 2008 (9.0) MSC_VER=1500
Visual C++ 2010 (10.0) MSC_VER=1600
Visual C++ 2012 (11.0) MSC_VER=1700
Visual C++ 2013 (12.0) MSC_VER=1800
Visual C++ 2015 (14.0) MSC_VER=1900

所以解决这个 error: Unable to find vcvarsall.bat 问题的方法就是:下载并安装 Visual Studio 2015 软件,问题即可解决。

解决办法 — 安装:Python Tools 2.2.5 for Visual Studio 2015

Step 1 . 下载 Visual Studio 2015 软件。

下载和安装 Visual Studio 2015 软件 的详细步骤请到这个博客查看:下载和安装 Visual Studio 2015 软件 的详细步骤图文教程。(我们按照这个网站的方法安装VS2015,但不按照这个博客里面说的安装。

如果安装上面的网站的方法安装VS2015软件,那么问题还是不能解决。(error: Unable to find vcvarsall.bat

Step 2 . 安装 Visual Studio 2015 软件

这个VS2015,安装时需要选择:自定义安装。(参考网站

参考网站:

Alt text

Alt text

我们的目的就是安装这个软件:Python Tools 2.2.5 for Visual Studio 2015 。现在,这个软件已经安装完了。

Alt text

注意:

如果一直停留在:“正在配置您的系统,这可能需要一些时间”

Alt text

解决:关掉VS的所有进程。

搞定,问题解决


现在再执行:pip install charset。问题解决。

Alt text


下载和安装 Visual Studio 2015 软件 的详细步骤图文教程


我的电脑系统:Windows 10 64位

下载:

下载网站:https://www.visualstudio.com/zh-hans/downloads/

选择 ISO(离线安装包),选择 简体中文,点击下载。

Alt text

下载一个7.1G的安装包,请耐心等待。(用迅雷下载,速度很快)

Alt text

安装

双击 vs2015.3.com_chs.iso ,进行安装

全程傻瓜式安装。

Alt text

Alt text

Alt text

Alt text

如果遇到问题: 下载Microsoft.net framework 4.6.2 https://www.microsoft.com/zh-CN/download/details.aspx?id=53344

Alt text

搞定

手动重新启动电脑后,打开Visual Microsoft 2015 软件:(需要几分钟)

Alt text

Alt text

Learning Python 014 使用 Pip 工具的注意事项 --- 混淆的python2 和 Python3


Q : 如果你的电脑之前安装了Python2,那么Python2 有自己的pip工具,Python3 也是有自己的pip工具,所以,如果你在DOS命令行上执行pip install some-package-name命令的时候,系统会使用哪个pip工具呢?是python2的pip,还是python3的pip?

A : 如果你先安装的是python2,后安装的python3,那么系统默认使用python2的pip;反之,如果你先安装的是python3,后安装的python2,那么系统默认安装的是python3的pip。

解决方法 : 为了避开这个问题,我们在使用 pip 工具时,使用绝对路径:

使用 python2 的 pip

1
2
cd C:\Python27\Scripts
pip.exe install some-package-name

使用 python3 的 pip

1
2
cd C:\Users\AOBO\AppData\Local\Programs\Python\Python35\Scripts
pip.exe install some-package-name

Learning Python 013 按行读取文件(逐行读取) --- 按行写入文件(逐行写入) --- 实战:从字幕文件中提取字幕内容


使用的开发集成环境:PyCharm 2016.1.4 使用的Python的版本:python 2.7.10


知识点:Python 按行读取文件

读取整个文件的内容

1
2
3
4
5
f = open('filename.txt', 'r')
text = f.read()
f.close()

print text

读取一行的内容(按行读文件的内容)

参考网站:

Python逐行读取文件内容 http://www.cnblogs.com/sysuoyj/archive/2012/03/14/2395789.html

1
2
3
4
5
6
7
8
9
10
f = open('filename.txt', 'r')

while 1:
  line = f.readline()
  if not line:
      break
  print text
  pass

f.close()

缺点:它依赖于前后文的关系,所以不能获取指定行的内容。

读取一行的内容 和 行号

参考网站:

python读取文件同时输出行号和内容 http://outofmemory.cn/code-snippet/3222/python-duqu-file-tongshi-output-xinghao-content

1
2
3
4
f = open('filename.txt', 'r')
for (num,value) in enumerate(f):
  print "line number", num, "is:", value
f.close()

缺点:虽然这段代码可以获取到指定行的内容,但是,使用enumerate()函数获取指定行内容的代价是:需要对所有依次进行编号,可想运算量之大。

读取指定行的内容

参考网站:

Python 从指定行读取数据 http://blog.163.com/xiaowei_090513/blog/static/11771835920140251257802

1
2
3
4
import linecache

num = 20
linecache.getline('filename.txt', num)

优点:读取的是缓存内的数据,速度快,并且代码简单。


知识点:Python 按行写入文件

参考网站:

Python文件读写 http://cxymrzero.github.io/blog/2015/03/19/python-file/ Python读写文件 http://blog.csdn.net/adupt/article/details/4435615

写一行(新建文件、替换现有文件)

1
2
3
4
5
6
7
8
9
10
f = open('namefile.txt', 'w')
f.write('the first line: hello world in the new file.\n')
f.write('the sencond line: ')
f.write('this is also the second line.\n')
f.close()

f = open('namefile.txt', 'r')
text = f.read()
f.close()
print text

执行输出:

1
2
the first line: hello world in the new file.
the sencond line: this is also the second line.

f = open('namefile.txt', 'w')这段代码的执行:如果有这个namefile.txt文件,那就将现有的namefile.txt文件里面的内容全部自动清空;如果没有这个namefile.txt文件,那就自动新建一个namefile.txt文件。

写一行(在原有文件后面追加写入)

1
2
3
4
5
6
7
8
f = open('namefile.txt', 'w+')
f.write('the last line: hello world in the new file.\n')
f.close()

f = open('namefile.txt', 'r')
text = f.read()
f.close()
print text

输出:

1
2
3
the first line: hello world in the new file.
the sencond line: this is also the second line.
the last line: hello world in the new file.

实战:从字幕文件中提取字幕内容

github源代码网址:https://github.com/AoboJaing/youtube-srt-to-txt

如何获取字幕文件

参考网站:https://www.youtube.com/watch?v=d9ctCc2AXCw

视频网站: https://www.youtube.com/

字幕提取网站:http://mo.dbxdb.com/setting.html

设计思路

输入是英文字幕文件和中文字幕文件,输出是英文配中文的txt文件

英文字幕文件

Alt text

中文字幕文件

Alt text

输出:英文配中文的txt文件

Alt text

代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# coding : utf-8

import linecache

file_srt = open('Servos - working principle and homemade types.srt', 'r')
file_txt = open('newfile.txt', 'w')

cout=1
for (num, value) in enumerate(file_srt):
    if cout == 5:
        cout = 1
    if cout == 3:
        file_txt.write(linecache.getline('en-Servos - working principle and homemade types.srt', num+1))
        file_txt.write(value)
    cout += 1

file_srt.close()
file_txt.close()

运行输出

1
2
3
4
5
6
7
8
9
10
Youtube subtitles download by mo.dbxdb.com
Youtube subtitles download by mo.dbxdb.com
In this video I would like to explain the functionality of servos and how to convert conventional DC motors into homebuilt servos.
在这部影片中,我想解释一下舵机以及如何传统的直流电动机转换成自制伺服系统的功能。
A servo is a device that produces motion accordant to a command signal from a control system.
伺服是,从一个控制系统产生运动一致来的命令信号的装置。
Usually an electric motor is used to create a mechanical force and the servomechanism rotates at a velocity that approximates the command signal.
一般的电动机被用来创建一个机械力和伺服机构在近似于指令信号的速度旋转。
...
...

PyCharm 软件 安装 插件( Plugins) --- 举例:安装Markdown 插件(即:让PyCharm 软件支持 .md 文件)


我使用的 PyCharm 软件的版本:2016.1.4


参考网站:

https://www.jetbrains.com/help/pycharm/2016.1/installing-updating-and-uninstalling-repository-plugins.html


PyCharm 软件添加 plugins 的图文操作(这里以添加 Markdown 插件)

Step 1 . 启动 PyCharm 软件

Step 2 . 打开 设置Setting) 窗口。(操作:File -> Setting 或者 按快捷键 Ctrl + Alt + S

Step 3 . 在搜索框里面搜索: plugins

Alt text

Step 4 . 点击 Install JetBrains plugins…

Alt text

Step 5 . 在新弹出来的窗口的搜索框里,输入:Markdown。 点击 Install ,进行安装。

Alt text

Step 6 . 下载需要翻墙

Alt text

Alt text

Alt text

Step 7 . 安装完成 Markdown 插件后,需要重启 PyCharm 软件,插件才能生效

注意: 安装成功的插件会自动使能(enable


测试

Alt text


C# 002 浏览(或叫:选择)、打开 文件和文件夹(或叫:目录)


  • 我使用的电脑:Windows 10 64位
  • 使用的Visual Studio 软件: VS2010

GitHub源代码地址: https://github.com/AoboJaing/Browse_Open_file_folder


准备工作

设计GUI界面:

Alt text


参考网站: http://www.cnblogs.com/szytwo/archive/2012/03/21/2410041.html

浏览(或叫:选择)文件夹(或叫:目录)

1
2
3
4
5
6
7
        FolderBrowserDialog dialog = new FolderBrowserDialog();
        dialog.Description = "请选择文件路径";
        if (dialog.ShowDialog() == DialogResult.OK)
        {
            string foldPath = dialog.SelectedPath;
            textBox1.Text = foldPath;
        }

打开 文件夹

1
        System.Diagnostics.Process.Start("Explorer.exe", textBox1.Text);

浏览(或叫:选择)文件

双击 Button2(浏览)按钮,将下面的代码复制到button2_Click()事件函数里面:

1
2
3
4
5
6
7
8
9
        OpenFileDialog fileDialog = new OpenFileDialog();
        fileDialog.Multiselect = true;
        fileDialog.Title = "请选择文件";
        fileDialog.Filter="所有文件(*.*)|*.*";
        if (fileDialog.ShowDialog() == DialogResult.OK)
        {
            string file = fileDialog.FileName;
            textBox2.Text = file;
        }

打开文件

参考网站:https://zhidao.baidu.com/question/413230762.html

1
2
        //System.Diagnostics.Process.Start("notepad++.exe", textBox2.Text);
        System.Diagnostics.Process.Start("XMP.exe", textBox2.Text);

这是一个使用C#来使用其他软件打开响应的文件的函数:System.Diagnostics.Process.Start()

其他软件:notepad.exe是记事本、notepad++.exenotepad++文本编辑器软件、XMP.exe是迅雷看看播放器软件。

运行效果

Alt text


C# 001 --- 正确的删除一个控件的事件函数 --- 解决错误: “A”不包含“B”的定义,并且找不到可接受类型为“A”的第一个参数的扩展方法“B”(是否缺少 Using 指令或程序集引用?)


先添加一个控件。比如添加一个GroupBox控件。

Alt text

当然,这个控件你不需要任何事件函数,但是如果你已经双击这个控件,开始编辑这个控件的事件函数了,那么这个时候要删除这个控件的事件函数需要2步:

Step 1 . Form11.cs 文件中,将这个控件所有的事件函数删除。对于我们这个例子,删除的代码是:

1
2
3
4
    private void groupBox1_Enter(object sender, EventArgs e)
    {

    }

如果这个时候,你运行程序会出错:

1
错误    1    WindowsFormsApplication1_demo.Form1”不包含“groupBox1_Enter”的定义,并且找不到可接受类型为“WindowsFormsApplication1_demo.Form1”的第一个参数的扩展方法“groupBox1_Enter(是否缺少 using 指令或程序集引用?) 

它提示你:你已经给groupBox1这个控件对象定义了一个groupBox1_Enter的方法了,但是编译器却没有找到这个函数。为什么没有找到?因为刚刚我们给它删除了。所以第2步:

Step 2 . 解决方案资源管理器,打开:Form1.Designer.cs文件:

Alt text

你会看到,一个小加号:

Alt text

点开这个小加号,里面就是所有空间的参数和方法的定义汇总。我们找到对应控件的事件函数:

Alt text

VS 软件已经将有错误的地方,用波浪线标注了。我们直接删除这一行,即可:

1
        this.groupBox1.Enter += new System.EventHandler(this.groupBox1_Enter);

现在,再运行程序,就不会有错误了。

Auto Control 003 自动控制原理 自动控制的数学模型 ---实例讲解

本篇博客中的公式支持不完整,请您访问这个链接:http://blog.csdn.net/github_35160620/article/details/52938197


这篇博客,在上一篇的基础上,针对 自动控制的数学模型 的重要考点,举一些典型的例题,加以解析,巩固大家对 自动控制的数学模型的掌握。

PID调节器 — 自动控制原理中最简单、最经典、最有用的调节器

我们先来看第一道题:

一有源网络如下图所示,要求:

  1. 写出系统的微分方程;
  2. 求系统的传递函数;
  3. 说明此电网络在校正中的作用。

Alt text

解:

这一道题,给了一个有源网络,要求建立它的两种形式的数学模型(一种是在时域当时所对应的微分方程;还有一种是复频域当中所对应的传递函数)。并且让我们分析:如果这个电网络放在了系统当中,将会给系统的性能产生何种的校正作用。

这种类型的题,我们会经常见到。要么是以有源网络的形式,要么是以无源网络的形式出现。 要解决这样的一类问题,一般有两种方法。

第一种方法:先写出在时域中所对应的微分方程组。比如是针对这样的有源网络而言,我们要充分利用到这个理想运算放大器它的续断和虚段的原理,根据:流入A节点的电流和流出这个节点的电流相同,同时在运算放大器的同向和反向输入端又没有电流流入。这样的话,我们可以在时域当中列出它的方程,然后消去中间变量。最终得到一个只和输入和输出有关的微分方程。

还有一种方法,是我们在上一篇博客当中提醒大家,在考试中经常会使用到的方法。这种方式是这样的:不管是有源还是无源网络,我们都可以利用复阻抗的方法,将电网络当中所对应的电阻、电感、电容用复阻抗来表示,然后用运算法直接列出复频域当中所对应的方程组,然后在直接的消元或者结合框框图,求出系统的传递函数。

一般情况下,遇到的电网络,不管是有源还是无源,我们都提议使用第二种方法会比较简单。

我们现在来看看这道题。对于这样的有源网络而言。由于表述这个系统的数学模型:微分方程和传递函数之间是可以相互转换的,所以我们不管是求出来哪一种形式的数学模型,传递函数也好、微分方程也好,只要求出来一种,另外一种也就没有问题了。对于这样道题,我们来看看。

首先我们把这个有源网络当中所有的R、C 全部用 复阻抗 的形式来表示。所对应的电阻是不变的,而电容将它转换为 $\frac {1}{CS}$ 。这样,不管是输出信号、输入信号就都可以使用复频域的形式来表示了。

Alt text

当把电路转换为这样的形式之后,我们就可以接着往下做了。对于 A 点而言,由于流入它的电流等于流出它的电流。所以我们有:

$$\frac{u{r}(s) - u{A}(s)}{R{3}} = \frac{u{A}(s) - u_1(s)}{R{1} + \frac{1}{C{1}S}}$$

(这样就得到的复频域里面的第一个方程了。)

我们在往下看 ,对于C点而言,这是一个电网络,所以对于C 点,我们一样可以利用基尔霍夫电流定律:流入 C 点的电流应该等于流出 C 点的电流之和。

$$\frac{u{A}(s) - u_1(s)}{R{1} + \frac{1}{C{1}S}} = \frac{u{1}(s) - 0}{\frac{1}{C{2}S}} + \frac{u{1}(s) - u{C}(s)}{R{2}}$$

这样对于 AC 这两点而言,我们都列写出来的它们所对应的电流平衡方程,而理想的有源运放同时又满足:A 点 和 B 点 是等电位的,等于0。

$$u{A} = u{B} = 0$$

这样的话,由这样的三个方程,我们消去中间变量,$u_{1}(s)$$u_{A}(s)$,这样可以得到下面的关系式:

Alt text 这里有一个负号,这里我们要做一个特别说明 :由于现在这个题中的有源运放的输入信号是加在反向输入端($-$),所以会有一个负号存在,但是这样的一个元器件,或者说这样的一个有源网络加在电路当中以后,我们知道信号一旦进过它(有源运放的反向输入端)以后,会产生一个反向作用就可以了,我们并不需要再传递函数当中额外的留意负号的存在,所以这个传递函数,我们可以进一步将它化简为:

系统的传递函数,最终化简得到:

Alt text

一旦这个有源网络给定了,所以 R1R2R3的参数也就确定下来了。所以这个组合,只要有源网络不变,它们的 组合的值就不会发生改变,在典型环节当中,我们认为它是一个比例环节P

Alt text

而公式中间的部分,我们观察它,它是一个:一个常数 乘以 一个所对应的微分环节,我们在典型环节中把它叫做:微分环节(D = ($K_{I}S$))

Alt text

在来看最后一部分,我们可以将它写做:$K_{I}\frac{1}{s}$ 。相当于一个积分常数 与 积分环节相乘。典型环节当中,我们把它叫做积分环节(I)。

Alt text

所以,这样的一个有源网络,它们组合起来以后,形成了一个经典控制理论当中最重要的调节器:我们把它叫做:PID调节器

这个PID可以这样来理解:在经典控制理论当中,我们所有的问题基本上,都是围绕着这样的一种调节器展开的,而这种调节器在整个控制领域的应是非常非常的广泛。

好,现在我们已经建立了这个图中有源网络的传递函数,并且分析了这样一个有源网络在系统当中实际上就是一个PID调节器。那么这个PID调节器的每一个部分对系统性能的影响表现在哪里呢?

首先,我们来看P 比例部分。比例部分的存在可以改变一个系统的系统增益,而一个系统的系统增益发生了改变,那么所对应的稳态性能(比如说:是否稳定),或者稳态误差的大小,都有可能会改变。

而微分部分的存在,它可以加快系统的响应速度。

而积分 部分的存在,它可以降低系统的误差。

所以,每一个部分在系统中的影响,你需要格外的清楚,当然PID调节器,我们在日后的博客中,还会再次介绍。

当我们建立起来了系统的传递函数以后,再想求它时域当中的数学模型 — 微分方程,就没有什么困难了。我们可以将传递函数当中所有的 复变量s微分算子 来代替。也就是说,把所有的s置换成$\frac {d}{dt} \leftarrow s$

我们可以得到传递函数 将上面的比例部分使用$K{P}$ 来表示、微分部分使用$K{D}s$来表示、积分部分使用$K_{I} \frac {1}{s}$来表示。

$$\varphi (s) = \frac {u{c}(s)}{u{r}(s)} = K{P} + K{D}s + K_{I} \frac {1}{s}$$

现在,我们就可以还原回时域当中。这样,我们就可以得到时域当中所对应的微分方程:

$$u{c}(t) = K{P}u{r}(t) + K{D} \frac {du{r}(t)}{d{t}} + K{I}\int u{r}(t)d_{t}$$

(当然,在微分方程当中,积分符号的存在,在微分方程中是不常见的。所以,我们可以对微分方程的两侧再求一次导。) 可以得到:

$$\frac {du{c}(t)}{dt} = K{P} \frac {du{r}(t)}{dt} + K{D} \frac {d^{2}u{r}(t)}{dt^{2}} + K{I} u_{r}(t)$$

那这样是一个微分方程是不是我们时域当中微分方程的标准形式呢?不是。 微分方程应该在右侧的公式里面,通过求导从高到底的形式来表示。

$$\frac {du{c}(t)}{dt} = K{D} \frac {d^{2}u{r}(t)}{dt^{2}} + K{P} \frac {du{r}(t)}{dt} + K{I} u_{r}(t)$$

所以现在,我们得到了一个二阶的常系数的线性的微分方程。这是这个有源网络在时域当中所对应的数学模型(微分方程)。

第2道

Alt text

我们上一篇博客里面有说过:如何来建立系统的动态结构图。我们说过:可以分两步走:第一步:化整为零;第二步:积零为整

所谓化整为零:把一个复杂的系统划分为若干个子系统,列出来每一个子系统所对应的微分方程或者复频域当中的代数方程。要注意的是:前后两个子系统之间是不是存在信号的彼此联系,也就是说:后一个子系统是不是前一个子系统所对应的负载。在完成了化整为零这一步之后,就开始做积零为整这一步,我们需要按照信号流动的单向性把我们所对应的环节相互连接起来,构成我们整个系统的动态结构图。

我们现在解的这道典型例题,系统不再是以原理图的形式给你了。而是以微分方程或者是代数方程的形式给你的,那么系统的微分方程一旦了解以后,我们应如何建立系统的动态结构图?并且进一步求取系统的传递函数呢?并且在传递函数中,我们要注意,这个系统的传递函数不止一个: $\frac {C(s)}{R(s)}$ 、$\frac {C(s)}{N{1}(s)}$、$\frac {C(s)}{N{2}(s)}$

这些传递函数,我们来观察一下,从它的表型形式,我们发现。这道题最终得到的动态结构图,它的输入信号肯定是不止一个的,它既有给定参考输入$R(s)$,同时也会存在扰动输入$N{1}(s)$、$N{2}(s)$ ,那么对于此类的题型,我们要如何解决呢? 其实这种问题也非常简单。我们来观察一下这一组微分方程,在我们动态结构图当中,常见到的组成部分有这样几个:

比较环节

Alt text

所谓的比较环节,是指两个或者两个以上的信号在这一点相遇以后,(什么点?比较点,我们使用小圈来表示。)所对应的比较点的输出(输出将会是输入信号的叠加)。

Alt text

除了比较点之外,再我们的动态结构图当中,还有一个重要的组成部分:方框:

Alt text

而方框的存在相当于一个乘法器。它表示:任意的信号在经过方框以后,所对应的输出都应该用这个信号乘以方框所对应的传递函数。

Alt text

动态结构图除了这两个组成部分之外,还有一个组成部分,我们把它叫做:引出点。

Alt text

引出点是指:从同一个信号线上面的不同位置引出来几路信号,而引出来的这几路信号它的大小、性质是完全一样的。

Alt text

我们的动态结构图也就这三个基本组成部分。那么这三个组成部分对应我们微分方程中运算是什么呢?

比较点:对应 加减运算

方框: 对应 乘法运算

引出点:相同的信号,从哪个位置出来,我们就清楚了。

现在我们回到这道题当中来,我们来看看第一个微分方程($x{1}(t) = r(t) - c(t) + n{1}(t)$)。这个微分方程实质上是一个代数方程。在这个方程中只涉及到了加和减的计算,这个计算在我们动态结构图当中,实际上就相当于只遇到了比较点。

这个比较点的输出信号我们假设是 $x{1}(t)$ ,这个比较点的信号是有三路信号叠加而成的,一路我们假设是参考输入信号$r(t)$,还有一路是来至于系统的输出$c(t)$ 。注意 $r(t)$ 和 $c(t)$ 之间是减的关系,所以$c(t)$ 在这里有一个负号;此外,还有一路信号是来至 $n{1}(t)$。

现在,我们就利用了一个比较点,将第一个代数方程所描述的关系已经表达出来了。

Alt text


怎么由$x{1}(t)$得到$x{2}(t)$?

它是经过了一个比例环节($x{2}(t) = K{1}x{1}(t)$),也就是说 $x{1}(t)$ 这个信号经过了K1 倍的放大以后,得到了 $x_{2}(t)$。

Alt text


再来看第三个方程($X{3}(t) = x{2}(t) - x_{5}(t)$),第三个方程仍然涉及到的是一个叠加运算。仍然是遇到了一个比较环节,这个比较环节是哪两个信号进行比较呢?

$x{2}(t)$ 和负的 $x{5}(t)$ 。这两路信号在这里做了一个比较。比较以后的输出是 $x_{3}(t)$。

Alt text


继续看第4个方程($T \frac {dx{4}(t)}{dt} = x{3}(t)$)。 如何从$x{3}$ 变成 $x{4}$ 呢?

我们可以考虑对这样的式子做一个变形。 我们将它转换到复频域当中,这样,我们有: 一阶微分对应的是一个 s。也就是说,如果我们想通过 $x{3}$得到$x{4}$,实际上,我们需要经过一个环节的传递,这个环节是一个积分环节。我们现在把这样的积分环节带到动态结构图当前去。 $x{3}(t)$ 经过了一个积分环节($\frac{1}{TS}$)之后,得到了一个输出信号: $x{4}(t)$。

Alt text


在来观察一下第5个方程($x{5}(t) = x{4}(t) - K{2}n{2}(t)$):

在这个方程当中,所对应的输出信号是$x{5}(t)$,这个方程又是两路信号的叠加。 哪两路呢?一路是来至于 $x{4}(t)$,还有一路是来至于$n{2}(t)$,并且这个$n{2}(t)$ 是经历了一个比例环节 $K{2}$,这样的两个环节相互比较得到了输出信号 $x{5}(t)$ Alt text


最后一个方程($K{0}x{5}(t) = \frac {d^{2}c(t)}{dt^{2}} + \frac {dc(t)}{dt}$)。最后这个方程里面仍然有微分符的存在。我们在动态结构图当中,每一个方框里出现的只能使传递函数,所以,我们要这个微分方程所对应的传递函数找到。它的传递函数是什么呢?

现在这个环节,它的输出是$c(s)$ ,输入是$x_{5}(s)$ 。从这个方程中我们可以得到:

传递函数就是这样的: $G(s) = \frac {K_{0}}{s^{2} + s}$。

现在我们就发现了。从 $x_{5}(t)$ 经过一个二阶环节以后得到的整个系统的输出 $c(s)$。

Alt text


我们现在来观察一下整个系统的动态结构图。在前面也有一个 $c(t)$。最后一步就是:相同的信号进行合并。同理$x_{5}(t)$ 的两个信号线也要进行合并。

Alt text

这样整个系统的动态结构图,我们就画出来了。


再画结构图的时候,大家要注意一点:如果在遇到微分符号的 存在,就是给你的是微分方程,你需要先把它单个的微分方程做拉氏变换,求出单个环节所对应的传递函数,把这个传递函数写到相应的方框里面去。

在画出了这个系统的动态结构图之后, 我们继续看下面的问题:要求系统的传递函数。如何求呢?

这个系统有三个输入信号,分别是:参考输入 $r(t)$、扰动信号 $n{1}(t)$、和扰动信号 $n{2}(t)$。而我们需要求的传递函数就是分别针对于这三个输入信号的。

一般 情况下,如果没有特加说明,我们经典控制理论当中所涉及到的系统都是线性控制系统。线性系统有它非常重要的两个性质:叠加性 和 齐次性。

只有同时满足了 叠加性 和 齐次性 的系统才叫做:线性系统。

其中 这个叠加性意味着:如果这个线性系统它在多个信号的作用下,那么这个时候系统的输出就应该等于:这多个信号各自单独作用所对应输出的叠加。也就是说在这样的一个系统当中,整个系统的输出应该等于:$C(t) = C{r}(t) + C{n1}(t) + C_{n2}(t)$。

这个时候,如果我们要求某个信号单独作用所对应的传递函数,对于线性系统而言,我们可以假设:其他的输入信号都等于0.

也就是说:如果我们要求参考输入 $r(s)$所对应的输出,我们可以先假设:$n{1}(t) = n{2}(t) = 0$(表示:此刻他们都不存在,都等于零)。那么这个时候,只有参考输入信号单独作用在系统上,而求这个传递函数,我们是不是需要对这样的一个动态结构图进行简化呢?当时是可以的。但是我们更提倡大家使用Mason公式直接来做,因为Mason公式只要我们能找到前向通道,找到独立回路,这个时候多么复杂的系统,它的传递函数我们都可以很容易的获得。

比如说,我们现在来求:参考输入作用下,系统的传递函数($\frac {C(s)}{R(s)}$),我们来观察一下:从参考输入到系统的输出,所经过的前向通道只有一个。这条前向通道它的增益是多少呢?就等于:这条前向通道所经历的所有环节传递函数的乘积。

$$n{1}(t) = n{2}(t) = 0$$ $$P{1} = K{1} \cdot \frac {1}{Ts} \cdot \frac {K{0}}{s(s+1)} = \frac {K{0}K_{1}}{Ts^{2}(s+1)}$$

好了前向通道只有一条。接着我们在来看看独立回路:在这个系统中,它存在两个独立回路。

Alt text

这两个回路所对应的回路增益分别是多少呢?

首先看回路1。回路1所对应的回路增益它等于:

$$L{1} = -\frac{1}{Ts}$$ $$L{2} = -K{1} \cdot \frac {1}{Ts} \cdot \frac{K{0}}{s^{2} + s} = -\frac {K{0}K{1}}{Ts^{2}(s+1)}$$

而且我们发现:这个两个回路之间有相互接触的部分,所以我们很容易的得到这个系统的特征多项式等于:

$$\triangle = 1 - L{1} - L{2} = 1 + \frac {1}{Ts} + \frac {K{0}K{1}}{Ts^{2}(s+1)}$$

这条系统只有一条前向通道,而且这条前向通道和两个回路多有接触部分,所以它所对应的余因式就等于1

$$\triangle _{1} = 1$$

这样话,我们可以得到这个系统在参考输入信号作用下,系统的传递函数等于:前向通道增益乘上它所对应的余因式 比上 系统的特征多项式

$$\frac {C(s)}{R(s)} = \frac {P{1}\cdot \triangle {1}}{\triangle} $$

将 $\triangle$ 、$P{1}$、$\triangle{1}$ 代入上式,也就等于:(整理)

$$\frac {C(s)}{R(s)} = \frac {P{1}\cdot \triangle {1}}{\triangle} = \frac {K{0}K{1}}{Ts^{2}(s+1) + s(s+1) + K{0}K{1}}$$

这给式子就是我们来求的第一个传递函数($\frac {C(s)}{R(s)}$)。

我们发现,这是一个三阶系统。(其实,我们在微分方程组里面也能发现。构成这个微分方程有一个1阶的,有一个2阶的 ,这些信号(x1x2x5)之间是彼此串联的。所以:这个是一个一阶系统串联了一个二阶系统,构成了一个三阶系统。)


接下来我们再来看看,在扰动信号 n1 作用下的传递函数。

当我们求扰动信号作用下的传递函数,我们此时可以假设 :参考输入信号等于零,另外一个扰动信号也等于零($r(t) = 0 、 n_{2}(t) = 0$)。

这个时候我们来观察,从扰动信号n1输入到系统的输出C,我们发现,n1r 所处的位置是完全一样的,所以n1的传递函数是和r的传递函数是完全一样的。($\frac {C(s)}{R(s)}$ 已经求得了。)

$$\frac {C(s)}{N_{1}(s)} = \frac {C(s)}{R(s)}$$


现在再来看 n2 的传递函数。求这个扰动的传递函数,我们可以先假设,rn1 的参考输入都不存在。即等于零($r(t) = 0 、 n_{1}(t) = 0$)。

n2 到达系统的输出,它所通过的前向通道,我们发现只有一个。

这条前向通道的增益等于:

$$P{1} = - K{2} \cdot \frac {K_{0}}{s(s+1)}$$

再来看,系统的回路没有变。所以,不管是哪个参考信号作用下,系统的传递函数,只要系统的结构不变,它的传递函数的分母多项式,也就是系统它的特征多项式是不会发生改变的。 (这一点,我们会在结果中,会得到验证。)

我们现在在观察,从 n2 到输出 c ,它的前向通道前面也有和两个回路相互接触的部分,所以对应的余因式仍然是等于1

$$\triangle_{1} = 1$$

因此,所对应的传递函数,仍然等于:(分母是刚刚求出来的特征多项式。)

$$\frac {C(s)}{N{2}(s)} = \frac {P{1}\cdot \triangle _{1}}{\triangle}$$

$$\frac {C(s)}{N{2}(s)} = \frac {- K{2} \cdot \frac {K{0}}{s(s+1)}}{1 + \frac {1}{Ts} + \frac {K{0}K_{1}}{Ts^{2}(s+1)}}$$

这样,我们对这样的单输出多输入的系统, 对每一个输入信号作用下的传递函数,我们都很容易获取了。


总结:

这道题,我们要掌握这样几个问题:

  1. 首先是怎么样从微分方程来建立动态结构图,这种建立只要按照信号流动的单向性,我们把每一个方程所对应的典型的环节都画出来,然后按照信号流图的单向性,相互连接。整个系统的动态结构图,我们就知道了。
  2. 建立起了动态结构图以后,只要能够牢牢的把握线性系统的叠加性原理,那么每一个信号单独作用下的传递函数,我们就知道了。

再来一道例题

系统的方框图如下,试求系统的闭环传递函数。

Alt text

题型分析:本题是从结构图求传递函数的一般题型,这种题型一般有三种方法可以解决:即结构图变换、Mason 公式,以及变量代换的方法。

解题:

给了我们系统的动态结构图,让我们求系统的闭环传递函数。

一般,遇到这样的题型,我们的解决办法有三种:

1 . 我们可以通过对动态结构图进行化简,从而求得系统的闭环传递函数。但是这种方法在遇到了一些问题的时候, 并不好用。什么样的问题呢? 在这个题当中,涉及到了引出点和比较点。

(引出点,比较点,引出点)

Alt text

它们之间是相互交叉的,也就是说:不管我们是做比较点的前移和后移,还是做引出点的前移和后移,是必会经过一些比较点或者是引出点。那么在这个时候,就非常容易出错。所以,这种方法只有对一些简单的动态结构图,我们可以采用。如果遇到较为复杂的,像现在这种,引出点和比较点相互交叉的情况下呢,我们不提倡大家用这种方法。

2 . 还有一种方法,就是使用 Mason 公式的方法。这种方法,不管针对于动态结构图也好,信号流图也能使用。我们只要在动态结构图或者信号流图当中,能够找到从输入到输出所对应的前向通道以及所对应的单独回路,那么这个时候,牢记公式就应该可以很容易的求解系统的传递函数。

3 . 第三种方法:变量代换。它和我们高中学过的代数很像。我们之前讲过:构成系统动态结构图的环节有三种:比较点、引出点、还有方框。比较点相当于我们代数运算当中的加或者减,而方框相当于我们代数运算当中的乘法。所以,我们只要运用一些中间变量,把我们的方框也好,比较点也好,还原为原来的代数运算。那么这个时候,只要列出来了所对应的这组代数方程,消去中间变量,就可以求得系统的传递函数。但是这种方法不是我们在大学阶段应该掌握的,所以就不提倡大家使用。

所以这样的话,只要遇到了动态结构图的化简或者 信号流图的化简,我们提倡大家就使用Mason公式

那么对于这道题,我们来观察一下,我们现在要求系统的闭环函数,这个时候,系统的输入信号是r(s) ,输出信号是 c(s) 。从输入到输出,所进过的前向通道有几条?有三条 。

第一条前向通道:

Alt text

所对应的前向通道的增益是:$P{1} = G{2}(s)$ 。

前向通道的增益的求法:我们使用前向通道所进过的所有环节所对应的传递函数乘起来,就是该前向通道的通道增益了。

第二条前向通道:

Alt text

所对应的前向通道的增益是:

$$P{2} = G{1}G_{2}$$

第三条前向通道:

Alt text

所对应的前向通道的增益是:

$$P{3} = G{1}$$

现在,前向通道现在我们找完了。现在看看系统当中有没有回路。首先,我们来观察一下,这有一个小回路

Alt text

所对应的回路增益,我们使用 $L_{1}$ 来表示:

$$L{1} = -G{1}$$

除了这个小回路之外,还存在一个大回路,$L_{2}$

Alt text

它所对应的回路增益是:

$$L{2} = -G{1}G_{2}$$

第三个回路:

Alt text

增益:

$$L{3} = -G{1}$$

按照回路的定义,信号的流动都是单项流动的,所以所有的回路我们就找完了。


注意: 往往我们习惯犯的错误是:先把动态结构图转换为信号流图,再在信号流图中使用Mason公式。这个时候就非常容易出现一种错误。我们拿到了动态结构图之后,我们不提倡把它转为信号流图,我们只需要在动态结构图中,使用信号流图的单向性来找前向通道,来找独立回路,就可以了)

刚刚,我们已经找到了前向通道和独立回路, 那么这个时候,我们观察这三个独立回路之前在下面这段是相互接触的。所以不存在两两或者三三互不接触的回路。

Alt text

因此,所对应的特征式就等于:

$$\triangle = 1 = L{1} - L{2} - L{3} = 1 + 2G{1} + G{1}G{2}$$

而我们刚才的三条前向通道,它和我们三个回路之间都存在相互交叉的部分,因此所对应的余因式 都等于 1

$$\triangle{1} = \triangle{2} = \triangle_{3} = 1$$


这样,整个系统的闭环传递函数,我们就很容易的可以获得。(利用了 Mason 公式 )

$$\varphi(s) = \frac {C(s)}{R(s)} = \frac {P{1} \triangle{1} + P{2} \triangle{2} + P{3} \triangle{3}}{\triangle} = \frac {G{2} + G{1}G{2} + G{1}}{1 + 2G{1} + G{1}G_{2}}$$



总结:

这个系统一定要是一个线性系统。只要是线性系统,它就一定满足叠加性的原理。

所谓的叠加性:在参考给定,以及扰动输入共同作用下的输出,就应该等于,参考输入单独作用下的输出 叠加上 扰动输入单独作用下的输出

而在分布求他们各自的传递函数的时候,我们要把握一点,求某一个信号单独作用的时候,我们要假设其他的输入是等于0的。