<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0">
    <channel>
            <title>Sweet的笔记</title>
            <link>http://susweet.cn</link>
                <description>这个人有点懒，他是个学生，他只会摸鱼，并且从来不写个性签名。</description>
        <generator>Halo 1.5.2</generator>
        <lastBuildDate>Mon, 24 Jul 2023 14:24:54 CST</lastBuildDate>
                <item>
                    <title>
                        <![CDATA[PMSM滑模观测器]]>
                    </title>
                    <link>http://susweet.cn/archives/pmsm-hua-mo-guan-ce-qi</link>
                    <description>
                            <![CDATA[<blockquote><p>文章中的公式未整理好，现在看很乱。</p></blockquote><p>对系统f ̇=f(x), x∈R^n，若存在平面s(x_1,x_2,…,x_n )，当s(x_1,x_2,…,x_n )&gt;0时，s ̇&lt;0，且s(x_1,x_2,…,x_n )&lt;0时，s ̇&gt;0，则系统会趋近于超平面s=0。系统状态会先到达滑模面，然后在滑模面上滑动。<br />一般取李亚普洛夫函数V(x)=1/2 s^2，并且为了保证系统在有限时间内可以到达滑模面，需要保证V ̇(x)=ss ̇&lt;-δ，δ为任意小的正数。<br />要求保证：<br />1. s(x)可微<br />2. s(0)=0</p><p>电机滑模观测器推导<br />电机的电压电流模型为<br />[■(u_α@u_β )]=R_s [■(i_α@i_β )]+[■(L_d&amp;0@0&amp;L_d )]  d/dt [■(i_α@i_β )]+[■(0&amp;ω_e (L_d-L_q )@〖-ω〗_e (L_d-L_q )&amp;0)][■(i_α@i_β )]+[(L_d-L_q )(ω_e i_d-d/dt i_q )+φ_f ω_e ][■(-sinθ@cosθ)]<br />一般考虑(L_d=L_q )，简写上述方程，有：<br />U=R_s I+L_d  d/dt I-E<br />变换为：<br />d/dt I=-R_s/L_d  I+1/L_d  U-1/L_d  E<br />取滑模面为s=e_I=I ̂-I，输入设计为V=h·sign(s)：<br />d/dt I ̂  ̇=-R_s/L_d  I ̂+1/L_d  U-1/L_d  V<br />s ̇=-R_s/L_d  e_I (t)+1/L_d (E-V)<br />若要求系统收敛，需要满足要求ss ̇&lt;0：<br />e_I (t)(-R_s/L_d  e_I (t)+1/L_d  (E-h·sign(s)))&lt;0<br />可以得到h的取值范围为：<br />h&gt;R_s |e(t)|+E·sign(e(t))<br />仿真模型：<br /><img src="/upload/2023/07/%E5%9B%BE%E7%89%87-1690178819961.png" alt="图片-1690178819961" /></p>]]>
                    </description>
                    <pubDate>Mon, 24 Jul 2023 14:07:29 CST</pubDate>
                </item>
                <item>
                    <title>
                        <![CDATA[Code Composer Studio (CCS)报错program will not fit into available memory （280049C）（#10099-D）]]>
                    </title>
                    <link>http://susweet.cn/archives/codecomposerstudioccs报错programwillnotfitintoavailablememory280049c</link>
                    <description>
                            <![CDATA[<blockquote><p>可以解决，但不知道会不会引起其他问题。</p></blockquote><p>项目需要，移植一份W25Q16的底层到280049C中。但是源代码里有一个极大的变量（如下代码），用于保存页的数据。<br /><img src="/upload/2022/09/image-1662435361132.png" alt="image-1662435361132" /><br />如果使用默认的cmd文件编译，会产生报错：</p><pre><code class="language-">error #10099-D: program will not fit into available memory, or the section contains a call site that requires a trampoline that can&#39;t be generated for this section. run placement with alignment/blocking fails for section &quot;.bss&quot; size 0x11b4 page 1.  Available memory ranges:   RAMLS5       size: 0x800        unused: 0x800        max hole: 0x800     </code></pre><p>双击报错定位到代码：<br /><img src="/upload/2022/09/image-1662435615103.png" alt="image-1662435615103" /><br />是分配到RAMLS5的空间不够。<br />查看其分配的空间（在同一个cmd文件中往上一点）：</p><pre><code class="language-">PAGE 1 :   BOOT_RSVD       : origin = 0x000002, length = 0x0000F1     /* Part of M0, BOOT rom will use this for stack */   RAMM1           : origin = 0x000400, length = 0x0003F8     /* on-chip RAM block M1 *///   RAMM1_RSVD      : origin = 0x0007F8, length = 0x000008     /* Reserve and do not use for code as per the errata advisory &quot;Memory: Prefetching Beyond Valid Memory&quot; */   RAMLS5      : origin = 0x00A800, length = 0x000800   RAMLS6      : origin = 0x00B000, length = 0x000800   RAMLS7      : origin = 0x00B800, length = 0x000800   RAMGS0      : origin = 0x00C000, length = 0x002000   RAMGS1      : origin = 0x00E000, length = 0x002000   RAMGS2      : origin = 0x010000, length = 0x002000   RAMGS3      : origin = 0x012000, length = 0x001FF8//   RAMGS3_RSVD : origin = 0x013FF8, length = 0x000008     /* Reserve and do not use for code as per the errata advisory &quot;Memory: Prefetching Beyond Valid Memory&quot; */</code></pre><p>发现还有RAMLS6、RAMLS7两块空间。<br />查看Memory Allocation，确认其实RAMLS5、RAMLS6、RAMLS7远远没有用完，所以可以将其合并起来用于存放这个变量。<br /><img src="/upload/2022/09/image-1662435990639.png" alt="image-1662435990639" /></p><p>将代码改为：（去掉下面两个空间，将所有空间合并到RAMLS5中）</p><pre><code class="language-">   RAMLS5      : origin = 0x00A800, length = 0x001800//   RAMLS6      : origin = 0x00B000, length = 0x000800//   RAMLS7      : origin = 0x00B800, length = 0x000800   RAMGS0      : origin = 0x00C000, length = 0x002000   RAMGS1      : origin = 0x00E000, length = 0x002000   RAMGS2      : origin = 0x010000, length = 0x002000   RAMGS3      : origin = 0x012000, length = 0x001FF8</code></pre><p>并重新编译，成功通过。<br /><img src="/upload/2022/09/image-1662436066246.png" alt="image-1662436066246" /><br />查看Memory Allocation，如下：<br /><img src="/upload/2022/09/image-1662436101411.png" alt="image-1662436101411" /></p><p>可以的话还是尽量避免使用占用太大的变量吧，毕竟单片机资源还是很有限的。</p>]]>
                    </description>
                    <pubDate>Tue, 06 Sep 2022 11:32:08 CST</pubDate>
                </item>
                <item>
                    <title>
                        <![CDATA[CCS中IQmath库报错（_IQ24div(long, long)没有定义）]]>
                    </title>
                    <link>http://susweet.cn/archives/ccs中iqmath库报错iq24divlonglong没有定义</link>
                    <description>
                            <![CDATA[<h2 id="%E9%97%AE%E9%A2%98%E7%8E%B0%E8%B1%A1" tabindex="-1">问题现象</h2><p>CCS中IQmath库报错（_IQ24div(long, long)没有定义）unresolved symbols remain</p><p><img src="/upload/2022/09/image.png" alt="image" /></p><p>经过多天的反复尝试，终于知道问题在哪了。iqmath是C的，但是我的代码都是使用C++的，所以在link的时候会找不到。</p><h2 id="%E8%A7%A3%E5%86%B3%E6%96%B9%E6%A1%88" tabindex="-1">解决方案</h2><p>在#include的时候用extern “C”告诉编译器这个函数是C的函数即可。</p><pre><code class="language-C++">#ifdef __cplusplusextern &quot;C&quot; {#endif#include &quot;IQmathLib.h&quot;#ifdef __cplusplus}#endif</code></pre><p>重新编译成功通过：<br /><img src="/upload/2022/09/image-1663072339171.png" alt="image-1663072339171" /></p><p>但是我对比了一下用上iqmath之后速度还慢了，不懂为啥：）<br /><img src="/upload/2022/09/image-1663073246173.png" alt="image-1663073246173" /></p>]]>
                    </description>
                    <pubDate>Sat, 03 Sep 2022 10:56:10 CST</pubDate>
                </item>
                <item>
                    <title>
                        <![CDATA[解决python中cv2无法自动补全的方法]]>
                    </title>
                    <link>http://susweet.cn/archives/解决python中cv2无法自动补全的方法</link>
                    <description>
                            <![CDATA[<blockquote><p>网上有其他方法，我试了一下没成功。这里仅提供我自己能用的方法，仅供参考。</p></blockquote><h2 id="" tabindex="-1"></h2><p>开始尝试用anaconda直接安装openCV，但是安装好之后无法自动补全。按照网上一些方法也没有成功。这时，我想起我另一台电脑上的环境是可以正常补全的，所以悄咪咪的去看了一下，得到了解决方案。</p><h2 id="-1" tabindex="-1"></h2><p>1、首先，先将在anaconda中安装好的openCV卸载；<br /><img src="/upload/2022/08/image.png" alt="image" /></p><p>2、然后打开anaconda的命令窗口（最好用管理员权限打开）；<br /><img src="/upload/2022/08/image-1661219679852.png" alt="image-1661219679852" /></p><p>3、这里需要切换到你需要安装cv的环境；</p><pre><code class="language-"> conda activate 你的环境</code></pre><p><img src="/upload/2022/08/image-1661219603911.png" alt="image-1661219603911" /></p><p>4、安装opencv-python，在命令窗口输入命令：</p><pre><code class="language-">pip install opencv-python</code></pre><p><img src="/upload/2022/08/image-1661219805425.png" alt="image-1661219805425" /><br />安装成功后会有提示。</p><p>到这里，整个安装过程就结束了。</p><h2 id="-2" tabindex="-1"></h2><p>这时，你再回到anaconda navigator搜索opencv，会发现opencv-python已经安装好了。<br /><img src="/upload/2022/08/image-1661219957729.png" alt="image-1661219957729" /><br />这个库在anaconda navigator中搜索安装是找不到的，得在命令中才能安装，我也不清楚为啥。<br />再回到你用的ide里面，我这里用的是vscode，</p><pre><code class="language-">import cv2</code></pre><p>再输出cv2.就会发现此时已经有自动补全了。<br /><img src="/upload/2022/08/1661220229979.png" alt="1661220229979" /></p>]]>
                    </description>
                    <pubDate>Tue, 23 Aug 2022 09:42:29 CST</pubDate>
                </item>
                <item>
                    <title>
                        <![CDATA[使用GM6020电机参数的Simulink电机控制仿真记录]]>
                    </title>
                    <link>http://susweet.cn/archives/gm6020电机simulink仿真记录</link>
                    <description>
                            <![CDATA[<blockquote><p>随手记记，并不是很严谨的文章，只是作为一次尝试。</p></blockquote><p>模型结构如下：<br /><img src="/upload/2022/07/image-1658996356940.png" alt="image-1658996356940" /><br />电流环阶跃响应曲线。<br /><img src="/upload/2022/07/image-1658996320777.png" alt="image-1658996320777" /><br />发现响应曲线初始段有个短暂的反向。问师兄说是因为这个系统不是最小相位系统，存在不稳定零点导致的。<br /><img src="/upload/2022/07/image-1658996651172.png" alt="image-1658996651172" /><br />使用的是5段式的SVPWM。如上图所示。上图中下半是采样和计算的触发信号，配合Simulink中的C++ block（代码如下，嵌入Simulink的方法我在之前的文章中写过，有兴趣可以参考交流一下），实现将单片机的运行模式搬到电脑上仿真。</p><pre><code class="language-C++">void loop_ctrl(double PID_param[6], double target[2], double current[2], signed char sync_singal[1], double Systime[1], double output[2]){     //...do some things    if(!states &amp;&amp; (sync_singal[0]))    {        //...do some things    }    states = sync_singal[0];}</code></pre><p>电机三相电流：<br /><img src="/upload/2022/07/image-1658997116350.png" alt="image-1658997116350" /></p><p>速度位置双闭环结果：<br /><img src="/upload/2022/07/image-1658998657926.png" alt="image-1658998657926" /></p><p>效果一般，慢慢来吧。</p>]]>
                    </description>
                    <pubDate>Thu, 28 Jul 2022 16:20:56 CST</pubDate>
                </item>
                <item>
                    <title>
                        <![CDATA[RMer的日常#03]]>
                    </title>
                    <link>http://susweet.cn/archives/rmer-de-ri-chang-03</link>
                    <description>
                            <![CDATA[<blockquote><p>只要思想不滑坡，办法总比困难多。</p></blockquote><p>机械组是实验室的珍贵资源，我们电控也要要学会自己解决装配问题。😃<br /><img src="/upload/2022/04/IMG_20190729_055106-416c91be00c945a885cdc03e7aeac7b0.jpg" alt="IMG_20190729_055106" /></p>]]>
                    </description>
                    <pubDate>Mon, 27 Jun 2022 00:39:28 CST</pubDate>
                </item>
                <item>
                    <title>
                        <![CDATA[RMer的日常#02]]>
                    </title>
                    <link>http://susweet.cn/archives/rmer-de-ri-chang-02</link>
                    <description>
                            <![CDATA[<blockquote><p>98%的队伍在这里被打败，然后变得更强。总决赛加油。</p></blockquote><p>(❁´◡`❁)<em>✲ﾟ</em><br /><img src="/upload/2022/06/IMG_20220625_202708.jpg" alt="IMG_20220625_202708" /></p>]]>
                    </description>
                    <pubDate>Sun, 26 Jun 2022 02:01:22 CST</pubDate>
                </item>
                <item>
                    <title>
                        <![CDATA[RMer的日常]]>
                    </title>
                    <link>http://susweet.cn/archives/rmer-de-ri-chang</link>
                    <description>
                            <![CDATA[<blockquote><p>如果你有个清晰的目标，那不妨冲一冲。即使还没有飞到终点的实力，但你又怎么会知道不会有一根哨兵轨道助你一臂之力呢。</p></blockquote><p>😃<br /><img src="/upload/2022/06/77d5a0fa77fe3a1f29bfc6ac5c090d3.jpg" alt="77d5a0fa77fe3a1f29bfc6ac5c090d3" /></p>]]>
                    </description>
                    <pubDate>Thu, 23 Jun 2022 22:08:50 CST</pubDate>
                </item>
                <item>
                    <title>
                        <![CDATA[新版Keil V5无法编译旧版Keil V5的程序]]>
                    </title>
                    <link>http://susweet.cn/archives/xin-ban-keilv5-wu-fa-bian-yi-jiu-ban-keilv5-de-cheng-xu</link>
                    <description>
                            <![CDATA[<blockquote><p>小问题，很容易就会发现是编译器的问题，不过我这里稍微写一下。我这里写得不好，就是给自己看看而已。网上有其他大神有更清晰的解决方案，我可以给你推荐一个https://www.jianshu.com/p/bff9bd75210c 。</p></blockquote><h2 id="%E5%85%88%E5%94%A0%E5%97%91%E5%87%A0%E5%8F%A5" tabindex="-1">先唠嗑几句</h2><p>最新我发现安装最新的Keil μVision V5编译以前的代码。完了，这急着编译了。<br />但是没有办法，编译不了我又能怎么办呢，只能看看是什么问题咯。打开项目配置一看，发现问题了，ARM Complier一栏里赫然写着V6.18。<br /><img src="/upload/2022/06/image-1655991159184.png" alt="image-1655991159184" /><br />我这程序之前都是用V5的编译器编译的。那好办，换成V5的就行了呗，easy。打开下拉框，嗯？？？我的V5呢，咋没有了。才知道原来新版的Keil已经没有V5的编译器了，现在改代码吧，来不及。那他没有我还不能自己装一个吗？<br />于是一顿操作（指去百度一顿搜索，便找到了答案）</p><h2 id="%E5%8A%A8%E6%89%8B%E5%B9%B2%E6%B4%BB" tabindex="-1">动手干活</h2><p>1、首先我们需要在官网下载一个V5版本的编译器<br />地址：<a href="https://developer.arm.com/downloads/-/legacy-compilers" target="_blank">https://developer.arm.com/downloads/-/legacy-compilers</a><br />下图中随意一个都可以，只是我挑了一个最新的。<br /><img src="/upload/2022/06/image-1655991522627.png" alt="image-1655991522627" /></p><p>2、安装<br />你可以安装到任何你喜欢的地方。但我习惯按照习惯安装在Keil的路径里头ARM文件夹里。<br /><img src="/upload/2022/06/image-1655991643956.png" alt="image-1655991643956" /></p><p>3、配置项目<br />打开你的一个项目，点这个按钮<br /><img src="/upload/2022/06/image-1655991725485.png" alt="image-1655991725485" /><br />选择Folders/Extensions<br /><img src="/upload/2022/06/image-1655991775574.png" alt="image-1655991775574" /><br />在这里找到你刚刚安装的编译器，添加进来就可以修改啦。</p><h2 id="%E5%86%99%E5%9C%A8%E5%90%8E%E9%9D%A2%E7%9A%84%E8%AF%9D" tabindex="-1">写在后面的话</h2><p>其实这个问题最合理的解决方案是修改代码。因为代码在V6的编译器中不通过，其实也意味着代码可能存在不规范的问题。如果你有能力修改代码，那我更倾向与建议使用更新的编译器，人总是要向前看的不是么。我后面也修改了代码，现在我的代码在6代的编译器也是可以通过的。那这个解决方案是没有意义了么，也不是。因为很多新手刚刚拿到一份别人给的例程，他们可能还没有足够的能力去修改，他们想要得到的只是代码跑起来。毕竟网上很多代码还是只能在旧的标准里面跑不是么？</p>]]>
                    </description>
                    <pubDate>Thu, 23 Jun 2022 21:51:20 CST</pubDate>
                </item>
                <item>
                    <title>
                        <![CDATA[使用VSCode编写STM32代码并调试]]>
                    </title>
                    <link>http://susweet.cn/archives/shi-yong-vscode-bian-xie-stm32-dai-ma-bing-diao-shi</link>
                    <description>
                            <![CDATA[<blockquote><p>文章将会慢慢更新，如果你看到这句话，说明还没有完全更新完。</p></blockquote><p>首先，我还是非常喜欢用Keil的。我从初中开始接触Keil V3，到现在的V5。虽然跟其他IDE比起来界面是旧了一些，但还是在进步的。而且功能非常齐全，完全可以应付常规的开发，更重要的是他的资料和生态非常完善，你遇到的问题基本都能在网上找到答案。<br /><img src="/upload/2022/06/image.png" alt="image" /><br />但是嘛，我还是打算折腾一下一些新的方案。生活总是需要一些新鲜感的，看久了Keil的界面腻了。另外，我老喜欢VSCode的黑暗模式了。<br /><img src="/upload/2022/06/1655989413530.png" alt="1655989413530" /></p><h2 id="%E6%96%B9%E6%A1%88%E9%80%89%E6%8B%A9" tabindex="-1">方案选择</h2><p>在网上大致搜索了一下，常见的方案有直接用STM32CubeMX生成makefile（参考：<a href="https://blog.csdn.net/ben_black/article/details/109906781%EF%BC%89" target="_blank">https://blog.csdn.net/ben_black/article/details/109906781）</a> 和导入Keil的工程（参考：<a href="https://blog.csdn.net/qq_49295302/article/details/124628016%EF%BC%89" target="_blank">https://blog.csdn.net/qq_49295302/article/details/124628016）</a><br />考虑到我本身就装好了Keil，之前也有很多工程是基于Keil的，并且我也懒得自己去写json，所以干脆选择了第二种方案。（后面我验证过的方案都会在这里总结一下）</p><h2 id="%E7%8E%AF%E5%A2%83%E5%87%86%E5%A4%87" tabindex="-1">环境准备</h2><p>无论你采用的是哪种方案，有些基本的环境都是要准备的。<br />1、VSCode<br />2、STM32CubeMX<br />3、MinGW-w64<br />4、arm-none-eabi-gcc<br />5、OpenOCD<br />安装好这些工具之后，记得在环境变量里头添加对应的路径，如果可以的话，最好在cmd或者power shell里头验证一下是否安装成功。</p><h2 id="%E6%96%B9%E6%A1%88%E4%B8%80%EF%BC%9A%E7%9B%B4%E6%8E%A5%E4%BD%BF%E7%94%A8embedded-ide%E6%8F%92%E4%BB%B6%E5%AF%BC%E5%85%A5keil%E5%B7%A5%E7%A8%8B" tabindex="-1">方案一：直接使用Embedded IDE插件导入Keil工程</h2><p>1、这里首先需要安装两个插件：<br />Embedded IDE与Cortex-Debug<br /><img src="/upload/2022/06/image-1655990095102.png" alt="image-1655990095102" /><br /><img src="/upload/2022/06/image-1655990111782.png" alt="image-1655990111782" /><br />2、插件配置：<br />首先打开Embedded IDE的配置：<br /><img src="/upload/2022/06/image-1655990488964.png" alt="image-1655990488964" /><br />修改编译器对应的地址。这里要根据你之前安装的Keil或者是arm-none-eabi-gcc的实际位置进行修改，你的配置很可能会和我的不一样。<br /><img src="/upload/2022/06/image-1655990605095.png" alt="image-1655990605095" /><br />将“编译完成后将.axf转换为.elf的复选框勾上；<br /><img src="/upload/2022/06/image-1655990685447.png" alt="image-1655990685447" /><br />修改OpenOCD的路径；<br /><img src="/upload/2022/06/image-1655990720223.png" alt="image-1655990720223" /></p>]]>
                    </description>
                    <pubDate>Thu, 23 Jun 2022 20:56:43 CST</pubDate>
                </item>
                <item>
                    <title>
                        <![CDATA[VSCode上安装PlatformIO踩坑]]>
                    </title>
                    <link>http://susweet.cn/archives/vscode-shang-an-zhuang-platformio-cai-keng</link>
                    <description>
                            <![CDATA[<blockquote><p>之前安装PlatformIO一直都没有成功，也没有在意。最近突然一时兴起要把他装好。</p></blockquote><p>错误：<br /><img src="/upload/2022/06/833fd224eea2aa1d7f115c7a139edbb.png" alt="833fd224eea2aa1d7f115c7a139edbb" /><br />VSCode显示找不到我的python。我这里的python是用anaconda安装的，并没有加入到环境变量，所以这里找不到也在我的意料之中。<br />于是我按照上面的提示，将我的虚拟环境中的Python的地址写入，但是错误依旧。反复安装了几次都还是这样。<br />但是我在conda的环境下反倒安装成功了。<br /><img src="/upload/2022/06/98429b32bd3e999b6d14dd337e60221.png" alt="98429b32bd3e999b6d14dd337e60221" /><br />那可能是系统环境的问题？于是我尝试加入系统环境变量，依然没有解决。</p><p>于是使用win10应用商店重新安装一次python，在cmd中已经能找到了，说明系统变量设置没有问题，但是这里的错误没变。</p><p>最后将商店中安装的版本卸载了，在官网上重新下载安装包安装，加入系统变量，才最终解决了。<br />😃</p>]]>
                    </description>
                    <pubDate>Tue, 21 Jun 2022 19:37:22 CST</pubDate>
                </item>
                <item>
                    <title>
                        <![CDATA[线性时不变系统与基础解集和基础解阵其状态转移阵的证明]]>
                    </title>
                    <link>http://susweet.cn/archives/线性时不变系统与基础解集和基础解阵其状态转移阵的证明</link>
                    <description>
                            <![CDATA[<h2 id="%E7%90%86%E8%AE%BA%E8%AE%A1%E7%AE%97" tabindex="-1">理论计算</h2><p>对于一般的线性是不变系统，可以用状态空间方程表达为：<br /><img src="/upload/2022/05/image-1652959100493.png" alt="image-1652959100493" /><br />因为只考虑零输入状态响应，因此，上式可以简化为：<br /><img src="/upload/2022/05/image-1652959138449.png" alt="image-1652959138449" /><br />选状态空间中一组基底{\(x_1,x_2,⋯,x_n\)}，则系统输入可以表达为\(x(t_0 )=α_1 x_1+α_2 x_2+⋯+α_n x_n\)。设对于任意\(t\)时刻，分别输入{\(x_1,x_2,⋯,x_n\)}，其输出为{\(x_1 (t),x_2 (t),⋯,x_n (t)\)}。输出的{\(x_1 (t),x_2 (t),⋯,x_n (t)\)}依然线性无关。因此，系统输出可以由{\(x_1 (t),x_2 (t),⋯,x_n (t)\)}线性表达。由线性系统的叠加性，可以得到：<br /><img src="/upload/2022/05/image-1652959448248.png" alt="image-1652959448248" /><br />记<img src="/upload/2022/05/image-1652959555415.png" alt="image-1652959555415" />，则x(t)表示为：<br /><img src="/upload/2022/05/image-1652959578309.png" alt="image-1652959578309" /><br />由此可以看出，线性时不变系统的在t时刻的响应，对应着基底在t时刻的响应的线性组合，组合系数有初始状态与{\(x_1,x_2,⋯,x_n\)}的关系一致。<br />设该系统的状态转移方阵为<br /><img src="/upload/2022/05/image-1652959613995.png" alt="image-1652959613995" /><br />其中\(Φ(t,t_0 )=[φ_1 (t,t_0 ),φ_2 (t,t_0 ),⋯,φ_n (t,t_0 )]\)，\(φ_i (t,t_0 )\)为原方程的解，且其输入为\((0,⋯,1,⋯,0)\)（第i个元素为1）。<br />因此，最终可以得到：<br /><img src="/upload/2022/05/image-1652959717984.png" alt="image-1652959717984" /><br />对于系统：<br /><img src="/upload/2022/05/image-1652959740495.png" alt="image-1652959740495" /><br />在\(X ̇(t)=AX(t)\)两边同时乘\(Φ(t_0,t)\)，有：<br /><img src="/upload/2022/05/image-1652959780825.png" alt="image-1652959780825" /><br /><img src="/upload/2022/05/image-1652959798950.png" alt="image-1652959798950" /><br />对等式从\(t_0\)到\(t\)积分，有<br /><img src="/upload/2022/05/image-1652959965656.png" alt="image-1652959965656" /><br />所以，最终可得：<br /><img src="/upload/2022/05/image-1652959992652.png" alt="image-1652959992652" /><br />而根据定义，有<img src="/upload/2022/05/image-1652960029148.png" alt="image-1652960029148" />，<img src="/upload/2022/05/image-1652960042051.png" alt="image-1652960042051" />为系统的解，因此有：<br /><img src="/upload/2022/05/image-1652960054679.png" alt="image-1652960054679" /><br />两边同时左乘一个\(e^(-At)\)有：<br /><img src="/upload/2022/05/image-1652960071926.png" alt="image-1652960071926" /><br />可得：<br /><img src="/upload/2022/05/image-1652960083631.png" alt="image-1652960083631" /><br />又因为该系统为线性是不变系统，因此，有性质：<br /><img src="/upload/2022/05/image-1652960096796.png" alt="image-1652960096796" /><br />所以，可以得到：<br /><img src="/upload/2022/05/image-1652960105788.png" alt="image-1652960105788" /><br />由此，可以将上式从t_0到t积分，有：<br /><img src="/upload/2022/05/image-1652960113588.png" alt="image-1652960113588" /><br />所以，最终可以得到：<br /><img src="/upload/2022/05/image-1652960140388.png" alt="image-1652960140388" /></p><h2 id="%E7%B3%BB%E7%BB%9F%E4%BB%BF%E7%9C%9F%E9%AA%8C%E8%AF%81" tabindex="-1">系统仿真验证</h2><p>如图所示的是一个常见的弹簧阻尼系统，在弹簧失效长度内以及阻尼器运动限位范围内，该系统可以看作是一个线性时不变系统，且因为系统的输出只取决于过去与当前输入，跟将来的输入无关，因此该系统为“因果”系统。其中，取m=1kg，C=5N·s/m，K=6N/m。取物体受到的拉力F为输入，物体位移x为系统输出。<br /><img src="/upload/2022/05/image-1652960176879.png" alt="image-1652960176879" /><br />图1 线性阻尼系统示意图<br />在MATLAB的Simulink中，建立物理模型如下图2所示，其中包含弹簧元件、阻尼器元件以及质量元件等。仿真参数如表1所示。<br /><img src="/upload/2022/05/image-1652960188103.png" alt="image-1652960188103" /><br />图2 系统在Simulink中的物理模型</p><p><img src="/upload/2022/05/image-1652960305682.png" alt="image-1652960305682" /><br />由动力学相关的公式，可以得到系统的微分方程为：<br /><img src="/upload/2022/05/image-1652960328970.png" alt="image-1652960328970" /><br />\(将物体移动距离x作为x_1，物体的移动速度作为x_2，可以有：\)<br /><img src="/upload/2022/05/image-1652960388854.png" alt="image-1652960388854" /><br />因为需要验证的系统为零输入响应，所以上式又简化为：<br /><img src="/upload/2022/05/image-1652960407210.png" alt="image-1652960407210" /><br />所以，系统矩阵A为：<br /><img src="/upload/2022/05/image-1652960417770.png" alt="image-1652960417770" /><br />所以：<br /><img src="/upload/2022/05/image-1652960433338.png" alt="image-1652960433338" /><br />得出状态矩阵<img src="/upload/2022/05/image-1652960445005.png" alt="image-1652960445005" />的特征根与特征向量为：<br /><img src="/upload/2022/05/image-1652960475408.png" alt="image-1652960475408" /><br />所以有：<br /><img src="/upload/2022/05/image-1652960487230.png" alt="image-1652960487230" /><br />所以：<br /><img src="/upload/2022/05/image-1652960500604.png" alt="image-1652960500604" /><br />因此将状态方程化为约当标准型：<br /><img src="/upload/2022/05/image-1652960521137.png" alt="image-1652960521137" /><br />所以系统零输入响应为：<br /><img src="/upload/2022/05/image-1652960531464.png" alt="image-1652960531464" /><br />同样的，在\(t_0时刻的初始状态，有：\)<br /><img src="/upload/2022/05/image-1652960551704.png" alt="image-1652960551704" /><br />所以，有：<br /><img src="/upload/2022/05/image-1652960560886.png" alt="image-1652960560886" /><br />当初始条件为<img src="/upload/2022/05/image-1652960572630.png" alt="image-1652960572630" />时，计算可得输出响应应为：<img src="/upload/2022/05/image-1652960587780.png" alt="image-1652960587780" />。如图3所示：<br /><img src="/upload/2022/05/image-1652960602169.png" alt="image-1652960602169" /><br />(a)输出的理论值<br /><img src="/upload/2022/05/image-1652960609858.png" alt="image-1652960609858" /><br />(b)输出的仿真计算值<br /><img src="/upload/2022/05/image-1652960667347.png" alt="image-1652960667347" /><br />© 各个状态的变化<br />图3 初始状态为\(X=[1 0]^T\)时的输出<br />当初始条件为<img src="/upload/2022/05/image-1652960734969.png" alt="image-1652960734969" />时，计算可得系统的响应为:<img src="/upload/2022/05/image-1652960748586.png" alt="image-1652960748586" />，如图4所示：<br /><img src="/upload/2022/05/image-1652960767073.png" alt="image-1652960767073" /><br />(a)输出的理论值<br /><img src="/upload/2022/05/image-1652960770997.png" alt="image-1652960770997" /><br />(b)输出的仿真计算值<br /><img src="/upload/2022/05/image-1652960778867.png" alt="image-1652960778867" /><br />© 各个状态的变化<br />图4 初始状态为\(X=[0 1]^T\)时的输出</p><p>而系统在初始条件为<img src="/upload/2022/05/image-1652960869556.png" alt="image-1652960869556" />时，可以得到其输出响应与单独输入的关系如图5所示：<br /><img src="/upload/2022/05/image-1652960881340.png" alt="image-1652960881340" /><br />（a）各个状态的变化<br /><img src="/upload/2022/05/image-1652960885714.png" alt="image-1652960885714" /><br />（b）系统的总输出<br />图5 初始状态为\(X=[1 1]^T\)时的输出及分别输入的比较</p><p>因此，对于状态空间中一组基底{\(x_1,x_2,⋯,x_n\)}，则系统输入可以表达为\(x(t_0 )=α_1 x_1+α_2 x_2+⋯+α_n x_n\)。在任意t时刻，分别输入{\(x_1,x_2,⋯,x_n\)}，其输出为{\(x_1 (t),x_2 (t),⋯,x_n (t)\)}。输出的{\(x_1 (t),x_2 (t),⋯,x_n (t)\)}依然线性无关。系统的输出对应着基底在t时刻的响应的线性组合，组合系数有初始状态与{\(x_1,x_2,⋯,x_n\)}的关系一致。</p><p>使用状态转移阵\(e^{A(t-t_0 )}\) 进行验证。<br />令初始状态为<img src="/upload/2022/05/image-1652960993757.png" alt="image-1652960993757" />，验证其在不同时刻的响应与计算值比较。<br /><img src="/upload/2022/05/image-1652961004774.png" alt="image-1652961004774" /><br />计算可以得到在t=0.5时，有<br /><img src="/upload/2022/05/image-1652961015921.png" alt="image-1652961015921" /><br />使用simulink仿真结果如下图6所示：<br /><img src="/upload/2022/05/image-1652961022096.png" alt="image-1652961022096" /><br />图6 系统在t=0.5时的状态<br />结果与计算值一致。<br />计算可以得到在t=1时，有<br /><img src="/upload/2022/05/image-1652961032889.png" alt="image-1652961032889" /><br />使用simulink仿真结果如下图7所示：<br /><img src="/upload/2022/05/image-1652961041409.png" alt="image-1652961041409" /><br />图7 系统在t=1时的状态<br />以上结果可以看出，状态转移阵\(e^{A(t-t_0 )}\) 计算的结果与仿真一致。验证了\(e^{A(t-t_0 )}\) 确实是它的状态转移阵。</p>]]>
                    </description>
                    <pubDate>Thu, 19 May 2022 19:19:32 CST</pubDate>
                </item>
                <item>
                    <title>
                        <![CDATA[Halo数学公式显示支持]]>
                    </title>
                    <link>http://susweet.cn/archives/halo数学公式显示支持</link>
                    <description>
                            <![CDATA[<blockquote><p>樱花主题是支持数学公式的，但我一开始不知道，所以引入mathjax尝试解决问题（只能电脑显示，手机显示还是会乱）。那本文就仅做参考吧。万一你用的主题不支持数学公式，还能有办法解决。</p></blockquote><p>在博客设置，其他设置中的head引入以下内容：</p><pre><code class="language-">&lt;script type=&quot;text/javascript&quot; async         src=&quot;https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.5/MathJax.js?config=TeX-MML-AM_CHTML&quot;&gt;&lt;/script&gt;&lt;script type=&quot;text/x-mathjax-config&quot;&gt;  MathJax.Hub.Config({tex2jax: {inlineMath: [[&#39;$&#39;,&#39;$&#39;], [&#39;\\(&#39;,&#39;\\)&#39;]]}});&lt;/script&gt;</code></pre><p><img src="/upload/2022/05/image-1652154417863.png" alt="image-1652154417863" /></p><p>对应数学公式使用“<img src="/upload/2022/05/image-1652154894239.png" alt="image-1652154894239" />”或者“<img src="/upload/2022/05/image-1652154853209.png" alt="image-1652154853209" />”括起来，就可以在预览中看到公式了。（文章编辑页面右边的实时显示窗口是显示不对的，另外我使用“$$”的时候也有些小问题，所以只用了括号。）</p><p>就像这样：<br /><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>E</mi><mo>=</mo><mi>m</mi><msup><mi>c</mi><mn>2</mn></msup></mrow><annotation encoding="application/x-tex">E=mc^2</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.68333em;vertical-align:0em;"></span><span class="mord mathnormal" style="margin-right:0.05764em;">E</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.8141079999999999em;vertical-align:0em;"></span><span class="mord mathnormal">m</span><span class="mord"><span class="mord mathnormal">c</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8141079999999999em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">2</span></span></span></span></span></span></span></span></span></span></span><br />\(v_t ^2-v_0 ^2=2as\)<br /><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msubsup><mi>v</mi><mi>t</mi><mn>2</mn></msubsup><mo>−</mo><msubsup><mi>v</mi><mn>0</mn><mn>2</mn></msubsup><mo>=</mo><mn>2</mn><mi>a</mi><mi>s</mi></mrow><annotation encoding="application/x-tex">v_t ^2-v_0 ^2=2as</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1.061108em;vertical-align:-0.247em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.03588em;">v</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.8141079999999999em;"><span style="top:-2.4530000000000003em;margin-left:-0.03588em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight">t</span></span></span><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">2</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.247em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">−</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:1.0622159999999998em;vertical-align:-0.24810799999999997em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.03588em;">v</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.8141079999999999em;"><span style="top:-2.4518920000000004em;margin-left:-0.03588em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">0</span></span></span><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">2</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.24810799999999997em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.64444em;vertical-align:0em;"></span><span class="mord">2</span><span class="mord mathnormal">a</span><span class="mord mathnormal">s</span></span></span></span><br /><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>E</mi><mo>=</mo><msub><mo>∫</mo><mo stretchy="false">(</mo></msub><mo>−</mo><mi mathvariant="normal">∞</mi><msup><mo stretchy="false">)</mo><mi mathvariant="normal">∞</mi></msup><mtext>▒〖</mtext><msup><mi>f</mi><mn>2</mn></msup><mo stretchy="false">(</mo><mi>t</mi><mo stretchy="false">)</mo><mi>d</mi><mi>t</mi><mtext>〗</mtext><mo>=</mo><mn>1</mn><mi mathvariant="normal">/</mi><mn>2</mn><mi>π</mi><msub><mo>∫</mo><mo stretchy="false">(</mo></msub><mo>−</mo><mi mathvariant="normal">∞</mi><msup><mo stretchy="false">)</mo><mi mathvariant="normal">∞</mi></msup><mtext>▒〖</mtext><mi mathvariant="normal">∣</mi><mi>F</mi><mo stretchy="false">(</mo><mi>ω</mi><mo stretchy="false">)</mo><msup><mi mathvariant="normal">∣</mi><mn>2</mn></msup><mi>d</mi><mi>ω</mi><mtext>〗</mtext></mrow><annotation encoding="application/x-tex">E=∫_(-∞)^∞▒〖f^2 (t)dt〗=1/2π ∫_(-∞)^∞▒〖|F(ω)|^2 dω〗</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.68333em;vertical-align:0em;"></span><span class="mord mathnormal" style="margin-right:0.05764em;">E</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:1.344928em;vertical-align:-0.5308200000000001em;"></span><span class="mop"><span class="mop op-symbol small-op" style="margin-right:0.19445em;position:relative;top:-0.0005599999999999772em;">∫</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.16917999999999989em;"><span style="top:-2.3441799999999997em;margin-left:-0.19445em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mopen mtight">(</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.5308200000000001em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord">−</span><span class="mord">∞</span><span class="mclose"><span class="mclose">)</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.664392em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">∞</span></span></span></span></span></span></span></span><span class="mord">▒</span><span class="mord cjk_fallback">〖</span><span class="mord"><span class="mord mathnormal" style="margin-right:0.10764em;">f</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8141079999999999em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">2</span></span></span></span></span></span></span></span><span class="mopen">(</span><span class="mord mathnormal">t</span><span class="mclose">)</span><span class="mord mathnormal">d</span><span class="mord mathnormal">t</span><span class="mord cjk_fallback">〗</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:1.344928em;vertical-align:-0.5308200000000001em;"></span><span class="mord">1</span><span class="mord">/</span><span class="mord">2</span><span class="mord mathnormal" style="margin-right:0.03588em;">π</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mop"><span class="mop op-symbol small-op" style="margin-right:0.19445em;position:relative;top:-0.0005599999999999772em;">∫</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.16917999999999989em;"><span style="top:-2.3441799999999997em;margin-left:-0.19445em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mopen mtight">(</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.5308200000000001em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord">−</span><span class="mord">∞</span><span class="mclose"><span class="mclose">)</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.664392em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">∞</span></span></span></span></span></span></span></span><span class="mord">▒</span><span class="mord cjk_fallback">〖</span><span class="mord">∣</span><span class="mord mathnormal" style="margin-right:0.13889em;">F</span><span class="mopen">(</span><span class="mord mathnormal" style="margin-right:0.03588em;">ω</span><span class="mclose">)</span><span class="mord"><span class="mord">∣</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8141079999999999em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">2</span></span></span></span></span></span></span></span><span class="mord mathnormal">d</span><span class="mord mathnormal" style="margin-right:0.03588em;">ω</span><span class="mord cjk_fallback">〗</span></span></span></span><br />（显然第一个显示的有误，但是我还没搞清楚哪里出了问题，先用第二种方法吧）</p><pre><code class="language-">$E=mc^2$\\(v_t ^2-v_0 ^2=2as\\)</code></pre>]]>
                    </description>
                    <pubDate>Tue, 10 May 2022 11:45:04 CST</pubDate>
                </item>
                <item>
                    <title>
                        <![CDATA[代码里中文注释变成锟斤拷啦]]>
                    </title>
                    <link>http://susweet.cn/archives/dai-ma-li-zhong-wen-zhu-shi-bian-cheng-kun-jin-kao-la</link>
                    <description>
                            <![CDATA[<blockquote><p><strong>首先强调一下，如果代码的中文已经变成”锟斤拷“了的话，本文中的方法无法帮助你恢复。为此我表示十分抱歉。但是本文提供了避免代码锟斤拷的方法，希望能够帮到你。</strong></p></blockquote><p>本文仅仅介绍了”锟斤拷“的形成和避免方法。但是如果你的代码中的中文只是变为了“�”，那希望本文提供的思路可以帮助到你。如果你有其他想法或者更好的方法，欢迎在评论区中提出，我们一起来讨论。</p><p>其实这个问题困扰我老久了，因为一直来使用git可视化软件合并的时候，时不时就会出现这个问题。之前也没有深究，只知道是编码问题，偶尔合并下如果变成了锟斤拷就手动修复一下。但是最近的项目因为需求迭代速度快（就是老是改需求），所以合并的次数会比较多，所以还是解决下吧。</p><p><img src="/upload/2022/05/image-1652146971635.png" alt="image-1652146971635" /></p><h1 id="%E5%BD%A2%E6%88%90%E5%8E%9F%E5%9B%A0" tabindex="-1">形成原因</h1><p>中文变成锟斤拷的原因不是很复杂。我现在用的IDE设置的默认编码格式是GB2312，是国内常用的中文编码格式。因此，我在这里创建保存的文件都是使用GB2312编码的。</p><p><img src="/upload/2022/05/image-1652147062477.png" alt="image-1652147062477" /></p><p>但是在git中，使用的却是utf-8。所以，在这里查看文件，中文字符就会变成“�”。这是由于utf-8中没有对应编码的字符，于是默认使用了“�”替代未知字符（当然也有时候utf-8正好有对应编码的符号，所以可以看到除了问号，还会有一些其他符号出现）。当我使用它保存文件的时候，代码里面的中文就真的变成了“�”。</p><p><img src="/upload/2022/05/image-1652147425549.png" alt="image-1652147425549" /></p><p>这时候如果重新用IDE打开，IDE还是以GB2312的编码格式打开，那连续的“�”就会变成我们常见的锟斤拷锟斤拷。</p><p><img src="/upload/2022/05/image-1652147697726.png" alt="image-1652147697726" /></p><p>一开始我以为是我使用的GitKraken是不支持中文编码的。但是在翻看其他代码的时候，我发现有些居然是可以正常的显示中文。于是确定了，它是支持中文编码的。</p><h1 id="%E8%A7%A3%E5%86%B3%E6%96%B9%E6%B3%95" tabindex="-1">解决方法</h1><p>对于已经变成锟斤拷的代码，确实不知道有什么方法，我都是手动修复的（如果各位大佬有什么好方法的话可以推荐一下）。但是，对于没有变成锟斤拷的代码，只要将编码格式换成utf-8，那后面再用git合并也不会锟斤拷了。这里我选择使用VSCode重新保存，当然这里只要能将编码转成utf-8，用什么软件转都可以。<br />首先需要使用文件实际的编码将文件打开（比如在我当前的场景下我使用的编码是GB2312，我需要先将文件用GB2312打开）<br /><img src="/upload/2022/07/image.png" alt="image" /><br />（如果你也是用VSCode，可以点击右下角这个文件编码格式，这里不一定是utf-8）<br /><img src="/upload/2022/07/image-1657180900072.png" alt="image-1657180900072" /><br />选择【通过编码重新打开】<br /><img src="/upload/2022/07/image-1657180746831.png" alt="image-1657180746831" /><br />我这里按照我的情况选择【GB2312】，你需要对应自己的情况。一般VSCode通过内容猜测的选项就是可以的了，但是并不确定。<br /><img src="/upload/2022/07/image-1657180962697.png" alt="image-1657180962697" /><br />此时正常来说，你的文章中的中文应该会恢复正常显示。<br />然后再次选择右下角刚刚那个编码模式，选择【通过编码保存】并选择【utf-8】即可。<br /><img src="/upload/2022/05/image-1652148329424.png" alt="image-1652148329424" /></p><p><img src="/upload/2022/05/image-1652148385081.png" alt="image-1652148385081" /></p><p>这时候GitKraken里面已经正常显示代码中的中文注释了。（我试了一下Sourcetree里面也是一样的）</p><p><img src="/upload/2022/05/image-1652148543365.png" alt="image-1652148543365" /></p><p>但是这个时候有可能IDE这边会变成乱码（也有可能不会），但是没有关系，把IDE这边也改为utf-8编码就可以了。<br />（虽然说utf-8编码文件会更大，不过为了避免以后还会出现锟斤拷，我已经将项目下所有文件的编码格式都改成utf-8了）</p>]]>
                    </description>
                    <pubDate>Tue, 10 May 2022 10:19:19 CST</pubDate>
                </item>
                <item>
                    <title>
                        <![CDATA[典型线性系统——弹簧阻尼系统的Adams仿真与Simulink仿真]]>
                    </title>
                    <link>http://susweet.cn/archives/dian-xing-xian-xing-xi-tong--dan-huang-zu-ni-xi-tong-de-adams-fang-zhen-yu-simulink-fang-zhen</link>
                    <description>
                            <![CDATA[<blockquote><p>写在前面的话：本文只涉及仿真验证结果，无详细仿真过程。这不是一篇仿真的教程。</p></blockquote><p>如图所示的是一个常见的弹簧阻尼系统，在弹簧失效长度内以及阻尼器运动限位范围内，该系统可以看作是一个线性时不变系统，且因为系统的输出只取决于过去与当前输入，跟将来的输入无关，因此该系统为“因果”系统。其中，取m=70kg，C = 160N·s/m，K=10000N/m。取物体受到的拉力F为输入，物体位移x为系统输出。<br /><img src="/upload/2022/05/image-1651664379362.png" alt="image-1651664379362" /><br />由动力学相关的公式，可以得到系统的微分方程为：<br /><img src="/upload/2022/05/image-1651664399615.png" alt="image-1651664399615" /><br />整理上述方程，并进行拉氏变换，可得：<br /><img src="/upload/2022/05/image-1651664418528.png" alt="image-1651664418528" /><br />因此，系统的传递函数为：<br /><img src="/upload/2022/05/image-1651664437260.png" alt="image-1651664437260" /></p><h2 id="%E7%B3%BB%E7%BB%9F%E7%9A%84%E5%9F%BA%E6%9C%AC%E7%89%B9%E6%80%A7%E7%9A%84%E7%90%86%E8%AE%BA%E8%AE%A1%E7%AE%97" tabindex="-1">系统的基本特性的理论计算</h2><h3 id="%E9%BD%90%E6%AC%A1%E6%80%A7%E7%9A%84%E7%90%86%E8%AE%BA%E9%AA%8C%E8%AF%81%EF%BC%9A" tabindex="-1">齐次性的理论验证：</h3><p>假设输入为F(t)时系统输出为x(t)，则当系统的输入为aF(s)时，代入式 1，则有：<br /><img src="/upload/2022/05/image-1651664545593.png" alt="image-1651664545593" /><br />可得：<br /><img src="/upload/2022/05/image-1651664567320.png" alt="image-1651664567320" /><br />因此：<br /><img src="/upload/2022/05/image-1651664584158.png" alt="image-1651664584158" /><br />可得，当输入为aF(t)时，输出为ax(t)。</p><h3 id="%E5%8F%A0%E5%8A%A0%E6%80%A7%E7%9A%84%E7%90%86%E8%AE%BA%E9%AA%8C%E8%AF%81%EF%BC%9A" tabindex="-1">叠加性的理论验证：</h3><p>假设有该系统在输入为F<sub>1</sub>(t)时，输出为x<sub>1</sub>(t)；输入为F<sub>2</sub>(t)时，系统的输出为x<sub>2</sub>(t)，可得到等式：<br /><img src="/upload/2022/05/image-1651664739858.png" alt="image-1651664739858" /><br />所以，有：<br /><img src="/upload/2022/05/image-1651664782546.png" alt="image-1651664782546" /><br />所以：<br /><img src="/upload/2022/05/image-1651664811703.png" alt="image-1651664811703" /><br />可得：<br /><img src="/upload/2022/05/image-1651664835290.png" alt="image-1651664835290" /><br />因此，可知当系统的输入为F<sub>1</sub>(t)+F<sub>2</sub>(t)时，系统的输出为x<sub>1</sub>(t)+x<sub>2</sub>(t)，符合叠加性原理。</p><h2 id="%E5%BC%B9%E7%B0%A7%E9%98%BB%E5%B0%BC%E7%B3%BB%E7%BB%9F%E5%BB%BA%E6%A8%A1%E4%B8%8E%E4%BB%BF%E7%9C%9F%E4%B8%8E%E6%80%A7%E8%B4%A8%E9%AA%8C%E8%AF%81%EF%BC%9A" tabindex="-1">弹簧阻尼系统建模与仿真与性质验证：</h2><p>本次仿真所使用的系统参数如下表所示：<br /><img src="/upload/2022/05/image-1651664954427.png" alt="image-1651664954427" /></p><h3 id="%E7%B3%BB%E7%BB%9F%E6%95%B0%E5%AD%A6%E6%A8%A1%E5%9E%8B%E5%BB%BA%E6%A8%A1" tabindex="-1">系统数学模型建模</h3><p><img src="/upload/2022/05/image-1651664997939.png" alt="image-1651664997939" /><br />可以将其转化为如下模型：<br /><img src="/upload/2022/05/image-1651665359531.png" alt="image-1651665359531" /><br />或者直接使用传递函数进行仿真：<br /><img src="/upload/2022/05/image-1651665379921.png" alt="image-1651665379921" /><br />这两个模型是完全等效的。因为第一个模型看起来更直观，后文的验证将在第一个模型的基础上进行。</p><h3 id="%E7%B3%BB%E7%BB%9F%E7%9A%84%E7%89%A9%E7%90%86%E6%A8%A1%E5%9E%8B%E5%BB%BA%E6%A8%A1" tabindex="-1">系统的物理模型建模</h3><p>与数学模型一样，本文在物理模型的建立时，同样采用了两个不同的方法进行交叉验证。其中第一个为使用 Simulink 中的机械模型进行建模验证（如图 4）；另一个使用了 Adams 软件（如图 5），直接建模实体进行验证。<br /><img src="/upload/2022/05/image-1651665449017.png" alt="image-1651665449017" /><br /><img src="/upload/2022/05/image-1651665464743.png" alt="image-1651665464743" /><br />为了验证两个系统的等效性，方便后面的仿真，这里分别对 Simulink 的物理模型与 Adams 的实物模型输入一个<img src="/upload/2022/05/image-1651665509733.png" alt="image-1651665509733" />的阶跃信号，其输出分别如下：<br /><img src="/upload/2022/05/image-1651665531589.png" alt="image-1651665531589" /><br /><img src="/upload/2022/05/image-1651665545727.png" alt="image-1651665545727" /><br />由图 6 与图 7 可以看出，这两个系统实际是等效的，后文的物理模型验证中，主要使用了 Adams 的模型进行仿真，以进行两个软件的交叉验证，进一步确定数学模型的正确性。</p><h3 id="%E9%BD%90%E6%AC%A1%E6%80%A7%E7%9A%84%E6%A8%A1%E5%9E%8B%E9%AA%8C%E8%AF%81%EF%BC%9A" tabindex="-1">齐次性的模型验证：</h3><p>齐次性的验证中，将使用输入<img src="/upload/2022/05/image-1651665621674.png" alt="image-1651665621674" />与<img src="/upload/2022/05/image-1651665658626.png" alt="image-1651665658626" />对系统进行验证。通过传递函数理论计算，可以得到这两个输入得到的理论输出分别为：<br /><img src="/upload/2022/05/image-1651665681174.png" alt="image-1651665681174" /><br /><img src="/upload/2022/05/image-1651665699614.png" alt="image-1651665699614" /><br />显然可以得到x<sub>2</sub>(t)= 2x<sub>1</sub>(t)的结果。<br />将上文中的框图修改成以下样式进行验证：<br /><img src="/upload/2022/05/image-1651665761342.png" alt="image-1651665761342" /><br />其中的阶跃函数为<img src="/upload/2022/05/image-1651665807597.png" alt="image-1651665807597" />，得到的结果为：<br /><img src="/upload/2022/05/image-1651665823112.png" alt="image-1651665823112" /><br />由上图可以看到，当输入信号通过一个 2 倍的增益后，系统的输出也变为原来的 2 倍。因此，该系统符合齐次性原理。<br />同样的，我们在 Adams 的仿真模型中分别输入两个成比例的阶跃函数，观察其输出结果：<br /><img src="/upload/2022/05/image-1651665870171.png" alt="image-1651665870171" /><br />为了进一步确认在不同的输入下，系统都符合齐次性的性质，因此更换其他类型的输入，比如输入一个随机函数，再次进行验证。<br /><img src="/upload/2022/05/image-1651665896558.png" alt="image-1651665896558" /><br />以上的计算结果与仿真结果均验证了系统符合齐次性的性质，符合预期结果。</p><h3 id="%E5%8F%A0%E5%8A%A0%E6%80%A7%E7%9A%84%E6%A8%A1%E5%9E%8B%E9%AA%8C%E8%AF%81%EF%BC%9A" tabindex="-1">叠加性的模型验证：</h3><p>在系统的叠加性的验证中，分别向系统输入三个函数，F<sub>1</sub>(t)、F<sub>2</sub>(t)以及F<sub>3</sub>(t)。其中，<img src="/upload/2022/05/image-1651666083533.png" alt="image-1651666083533" />。<br />通过理论计算，可以得到：<br /><img src="/upload/2022/05/image-1651666118921.png" alt="image-1651666118921" /><br /><img src="/upload/2022/05/image-1651666139256.png" alt="image-1651666139256" /><br />由上式，可以得到x<sub>3</sub>(t)=x<sub>1</sub>(t)+x<sub>2</sub>(t)，由此可以验证该系统符合叠加性原理。<br />与验证齐次性相似，将系统框图修改成以下状态：<br /><img src="/upload/2022/05/image-1651666186603.png" alt="image-1651666186603" /><br />通过上述模型，可以得到以下结果（如图 13 所示）。可以看出，系统输入F<sub>3</sub>(t)的结果（图 13 中下一曲线）与分别输入F<sub>1</sub>(t)、F<sub>2</sub>(t)，再将输出叠加的结果（图13 中上一曲线中的红色曲线）一致。<br /><img src="/upload/2022/05/image-1651666237729.png" alt="image-1651666237729" /><br />在 Adams 模型中验证叠加性，我们同样的分别向系统输入信号F<sub>1</sub>(t)、F<sub>2</sub>(t)以及F<sub>3</sub>(t)，可以得到以下输出<br /><img src="/upload/2022/05/image-1651666268950.png" alt="image-1651666268950" /><br />可以得到x<sub>3</sub>(t)=x<sub>1</sub>(t)+x<sub>2</sub>(t)，由此可以验证该系统符合叠加性原理。同时，可以验证在 Adams 中的模型输出与在 MATLAB 中 Simulink 的输出结果完全一致。<br />另外，我们可以同样的输入随机函数来再次验证该系统的叠加性。<br /><img src="/upload/2022/05/image-1651666308111.png" alt="image-1651666308111" /></p><h2 id="%E6%80%BB%E7%BB%93" tabindex="-1">总结</h2><p>通过上述计算与验证，可以看出本次使用的弹簧阻尼系统是一个线性系统。</p>]]>
                    </description>
                    <pubDate>Wed, 04 May 2022 19:52:49 CST</pubDate>
                </item>
                <item>
                    <title>
                        <![CDATA[SolidWorks零件变形动画的制作（如弹簧、橡胶零件）]]>
                    </title>
                    <link>http://susweet.cn/archives/solidworks-ling-jian-bian-xing-dong-hua-de-zhi-zao--ru-dan-huang--xiang-jiao-ling-jian-</link>
                    <description>
                            <![CDATA[<blockquote><p>之前做课设的时候想用的功能，但是当时没找到方法。所以记录下方便以后查找。</p></blockquote><p>话说我那次做课设，主要的任务是使用SolidWorks进行曲面建模。但是，我因为做太快了，老师给了追加的任务，做动画。我当时需要建模的零件是这样的：<br /><img src="/upload/2022/05/image-1651566029382.png" alt="image-1651566029382" /><br />建模的过程没有遇到太大的困难，就是先这样，再这样，最后这样，<br /><img src="/upload/2022/05/image-1651566177799.png" alt="image-1651566177799" /><br />然后再添加一点细节就建好了。<br /><img src="/upload/2022/05/image-1651566233334.png" alt="image-1651566233334" /></p><p>老师看完之后很开心，觉得我工作不饱和，于是快快乐乐地又给我增加了点任务，把装配体的动画做了。SolidWorks本来做配合的动画倒也不难，我也做过。除了电脑比较卡之外，之前也没遇到其他问题。但是这次这个零件是个橡胶件。做动画的时候还涉及到零件本身变形。没做过呀，咋办。网上找了很久资料也没有找到很详细的。头疼。<br />终于经过我的反复摸索，搞清楚了这类动画要怎么做了。<br />其实也不是说很难，只要知道了就很简单，就是不知道的话就想不清楚。<br />一直以来，大家都告诉我使用SolidWorks建模的时候，尺寸一定要完全定义，不然容易出问题。这个说法大多数时候是对的，我也建议建模的过程中要把尺寸定义完全，这样后面再修改特征的时候就不容易出错。但是，这次的情况是个特例，需要变形的零件在建模的时候，要变形的尺寸不能进行定义，要在装配体中的关键帧里才进行定义。</p><p>这里拿我的这个课设作例子。<br />共有3个零件组成。其中需要变形的是这个零件：<br /><img src="/upload/2022/05/image-1651567166628.png" alt="image-1651567166628" /><br />它是一个橡胶材质的碗装零件，作用是按钮的回弹。我设想的是变形部分是箭头所指的斜面，其在按键下压的时候，竖直高度减小。因此，要先将对应的特征尺寸定义删除。也就是图中的尺寸1mm。<br /><img src="/upload/2022/05/image-1651567339415.png" alt="image-1651567339415" /><br />我这里有两个相似的结构，另一边也是类似处理。</p><p>到这里，就可以回到装配体了（如果没有就创建一下），在左边特征栏打开上面删掉尺寸的草图，在装配体这里重新定义这个尺寸。这里我定义的是与上面的零件重合。这样这个草图就会回到完全定义的状态。<br /><img src="/upload/2022/05/image-1651568564415.png" alt="image-1651568564415" /></p><p>另外我还有一个距离配合，方便做动画的时候修改。<br /><img src="/upload/2022/05/image-1651568735517.png" alt="image-1651568735517" /></p><p>在SolidWorks底栏右键添加新的算例。<br /><img src="/upload/2022/05/image-1651567900346.png" alt="image-1651567900346" /></p><p>然后在时间轴上找到上面提到的距离配合，在时间轴上对应点打上关键帧的键码，并在键码上修改该配合的距离。<br /><img src="/upload/2022/05/image-1651568846023.png" alt="image-1651568846023" /></p><p>最后重新计算运动算例，就可以看到得到的动画了。<br /><img src="/upload/2022/05/image-1651568904471.png" alt="image-1651568904471" /></p>]]>
                    </description>
                    <pubDate>Tue, 03 May 2022 16:11:19 CST</pubDate>
                </item>
                <item>
                    <title>
                        <![CDATA[不完全能控系统的能控子空间]]>
                    </title>
                    <link>http://susweet.cn/archives/能控子空间推导</link>
                    <description>
                            <![CDATA[<p>对于系统：</p><p><img src="/upload/2022/05/image-1651545498945.png" alt="image-1651545498945" /></p><p>由于系统不完全可控，因此<img src="/upload/2022/05/image-1651545529616.png" alt="image-1651545529616" />，记<img src="/upload/2022/05/image-1651545545744.png" alt="image-1651545545744" />，则可以从中抽出k个线性不相关的向量，作为基底。分别记为：</p><p><img src="/upload/2022/05/image-1651545563134.png" alt="image-1651545563134" /></p><p>则<img src="/upload/2022/05/image-1651545587041.png" alt="image-1651545587041" />均可由<img src="/upload/2022/05/image-1651545563134.png" alt="image-1651545563134" />线性表示。</p><p>已知<img src="/upload/2022/05/image-1651545629564.png" alt="image-1651545629564" />均可由<img src="/upload/2022/05/image-1651545648239.png" alt="image-1651545648239" />线性表示，因此，他们可以直接由<img src="/upload/2022/05/image-1651545563134.png" alt="image-1651545563134" />线性表示。<br />此外，可以再取(n-k)个与<img src="/upload/2022/05/image-1651545563134.png" alt="image-1651545563134" />不相关，并且互相之间也不相关的变量，记为<img src="/upload/2022/05/image-1651546121056.png" alt="image-1651546121056" />。取<img src="/upload/2022/05/image-1651546145258.png" alt="image-1651546145258" />，显然，Q是满秩矩阵。</p><p>以<img src="/upload/2022/05/image-1651546203685.png" alt="image-1651546203685" />作为基底，由于<img src="/upload/2022/05/image-1651546229713.png" alt="image-1651546229713" />均可由<img src="/upload/2022/05/image-1651546248262.png" alt="image-1651546248262" />线性表示，因此有：<br /><img src="/upload/2022/05/image-1651546258616.png" alt="image-1651546258616" /></p><p>后面取的<img src="/upload/2022/05/image-1651548050270.png" alt="image-1651548050270" />左乘A后虽然不能仅用q_1  q_2  ⋯q_k线性表示，但可以使用所有q，即<img src="/upload/2022/05/image-1651548081960.png" alt="image-1651548081960" />线性表示。因此，有：<br /><img src="/upload/2022/05/image-1651548098605.png" alt="image-1651548098605" /></p><p>因此，合并上述式子，可以得到：<br /><img src="/upload/2022/05/image-1651548116906.png" alt="image-1651548116906" /></p><p>因为B也与<img src="/upload/2022/05/image-1651548135885.png" alt="image-1651548135885" />线性相关，因此：<br /><img src="/upload/2022/05/image-1651548152669.png" alt="image-1651548152669" /><br />相似的，可以得到：<br /><img src="/upload/2022/05/image-1651548168670.png" alt="image-1651548168670" /><br />因此，系统可以表示为：<br /><img src="/upload/2022/05/image-1651548202311.png" alt="image-1651548202311" /><br />展开可以得到：<br /><img src="/upload/2022/05/image-1651548185324.png" alt="image-1651548185324" /><br />只取¯X_1为状态展开一个状态的子空间，¯X_2状态取为0。此时的空间，即为题目需要求证的空间。上式退化为：<br /><img src="/upload/2022/05/image-1651548224294.png" alt="image-1651548224294" /><br />此时，系统的能控性矩阵为：<br /><img src="/upload/2022/05/image-1651548240033.png" alt="image-1651548240033" /><br />而变换后的整个系统的能空性矩阵为：<br /><img src="/upload/2022/05/image-1651548254524.png" alt="image-1651548254524" /><br />变换前后，系统能控性不变，因此：<br /><img src="/upload/2022/05/image-1651548270086.png" alt="image-1651548270086" /></p><p>此时，对于子系统来说，<img src="/upload/2022/05/image-1651548289316.png" alt="image-1651548289316" />必能由<img src="/upload/2022/05/image-1651548306501.png" alt="image-1651548306501" />线性表示，因此，<img src="/upload/2022/05/image-1651548329141.png" alt="image-1651548329141" />也能由<img src="/upload/2022/05/image-1651548346672.png" alt="image-1651548346672" />线性表示。即后面的相必与前面k项线性相关。又因为<img src="/upload/2022/05/image-1651548498301.png" alt="image-1651548498301" />，所以前面k项线性不相关。因此可以推出：<br /><img src="/upload/2022/05/image-1651548520973.png" alt="image-1651548520973" /><br />子系统能控性矩阵满秩，因此子系统完全能控，因此<img src="/upload/2022/05/image-1651548538573.png" alt="image-1651548538573" />中的<img src="/upload/2022/05/image-1651548552117.png" alt="image-1651548552117" />表示了能控子空间的状态。</p><p>举例说明：<br />对于系统：<img src="/upload/2022/05/image-1651548580607.png" alt="image-1651548580607" />，<br />其中，<img src="/upload/2022/05/image-1651548597429.png" alt="image-1651548597429" />。<br />验证<img src="/upload/2022/05/image-1651548616356.png" alt="image-1651548616356" />中的<img src="/upload/2022/05/image-1651548638076.png" alt="image-1651548638076" />为其能控子系统。<br />求得：<img src="/upload/2022/05/image-1651548672737.png" alt="image-1651548672737" /><br />所以能控性矩阵为：<br /><img src="/upload/2022/05/image-1651548687787.png" alt="image-1651548687787" /><br />其秩为：<img src="/upload/2022/05/image-1651548704708.png" alt="image-1651548704708" /><br />因此，系统不完全能控。在能控性矩阵中，取出<img src="/upload/2022/05/image-1651548723498.png" alt="image-1651548723498" />，再取一个与他们都不相关的变量<img src="/upload/2022/05/image-1651548749426.png" alt="image-1651548749426" />，组成矩阵<img src="/upload/2022/05/image-1651548765521.png" alt="image-1651548765521" />。<br /><img src="/upload/2022/05/image-1651548788458.png" alt="image-1651548788458" /><br /><img src="/upload/2022/05/image-1651548814298.png" alt="image-1651548814298" /><br />其中，<img src="/upload/2022/05/image-1651548830512.png" alt="image-1651548830512" /><br />可以得到该系统的能控性矩阵为<br /><img src="/upload/2022/05/image-1651548844640.png" alt="image-1651548844640" /><br />其秩显然为2，因此完全能控。因此可以说明<img src="/upload/2022/05/image-1651548865247.png" alt="image-1651548865247" />中的<img src="/upload/2022/05/image-1651548882331.png" alt="image-1651548882331" />表示了能控子空间的状态。</p>]]>
                    </description>
                    <pubDate>Tue, 03 May 2022 10:40:58 CST</pubDate>
                </item>
                <item>
                    <title>
                        <![CDATA[通过MATLAB进行系统辨识]]>
                    </title>
                    <link>http://susweet.cn/archives/通过matlab进行系统辨识</link>
                    <description>
                            <![CDATA[<h2 id="%E4%BC%AA%E9%9A%8F%E6%9C%BA%E5%BA%8F%E5%88%97%E8%BE%A8%E8%AF%86%E8%84%89%E5%86%B2%E5%93%8D%E5%BA%94" tabindex="-1">伪随机序列辨识脉冲响应</h2><p>在经典控制理论中，一个线性时不变系统的输入x(t)与输出y(t)我们可以用如下公式来表示。<br /><img src="/upload/2022/05/image-1651542779909.png" alt="image-1651542779909" /><br />其中，g(t)为该线性系统的脉冲响应函数。由于系统脉冲响应的拉氏变换即为系统传递函数。因此在理想的情况下，只需要向系统输入理想脉冲，并记录系统输出，即可得到系统传递函数，完成系统建模。如下狄拉克公式所示。<br /><img src="/upload/2022/05/image-1651542845739.png" alt="image-1651542845739" /><br />然而，在实际应用时，不存在理想的脉冲函数，直接用近似理想的脉冲函数进行激励得到的结果并不准确。<br />考虑到理想白噪声信号的自相关函数在时移t=0时为无穷，而在时移t≠0的时候为零。因此可以使用白噪声信号替代脉冲信号进行测试。若此时输入白噪声，则由Wiener-Hopf公式，有：<br /><img src="/upload/2022/05/image-1651542871699.png" alt="image-1651542871699" /><br />因为白噪声的自相关函数为 <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msub><mi>R</mi><mrow><mi>x</mi><mi>x</mi></mrow></msub><mo stretchy="false">(</mo><mi>t</mi><mo stretchy="false">)</mo><mo>=</mo><msup><mi>σ</mi><mn>2</mn></msup><mi>δ</mi><mo stretchy="false">(</mo><mi>t</mi><mo stretchy="false">)</mo></mrow><annotation encoding="application/x-tex">R_{xx} (t)=σ^2δ(t)</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.00773em;">R</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.151392em;"><span style="top:-2.5500000000000003em;margin-left:-0.00773em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight">x</span><span class="mord mathnormal mtight">x</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mopen">(</span><span class="mord mathnormal">t</span><span class="mclose">)</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:1.064108em;vertical-align:-0.25em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.03588em;">σ</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8141079999999999em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">2</span></span></span></span></span></span></span></span><span class="mord mathnormal" style="margin-right:0.03785em;">δ</span><span class="mopen">(</span><span class="mord mathnormal">t</span><span class="mclose">)</span></span></span></span> ，因此，上式又可以表示为：<br /><img src="/upload/2022/05/image-1651542908768.png" alt="image-1651542908768" /><br />因此可以看出，我们可以通过白噪声的响应，求出系统的脉冲响应函数，从而进行系统建模。<br />不过，白噪声依然是理想信号，并不能用于实际实践中。<br />m序列与白噪声类似，也是一种随机信号。但是m序列可以由人工生成，适合在实际生产中应用。</p><h2 id="matlab%E7%B3%BB%E7%BB%9F%E8%BE%A8%E8%AF%86" tabindex="-1">MATLAB系统辨识</h2><p>通过对系统输入M随机序列，得到响应曲线。这里随意选取一个系统举例。<br />通过自相关函数关系，可以将随机序列生成的输出，转为系统离散脉冲响应。然后可以按照以下流程进行系统辨识。</p><p><img src="/upload/2022/05/image-1652065393935.png" alt="image-1652065393935" /></p><pre><code class="language-">Rxy = zeros(idt_data_num,1);for k = 1:idt_data_num  t_temp = 0;  for i = 1:idt_data_num      k2 = k+i-1;      k2 = k2-idt_data_num*(k2&gt;idt_data_num);      t_temp = t_temp+sys_in(i)*sys_out(k2);  end  Rxy(k) = t_temp;endRxy = Rxy/idt_data_num;markov = Rxy/sys_in(1)^2;figure;plot(markov);title(&#39;系统脉冲响应曲线&#39;);</code></pre><p>得到的结果如下图。<br /><img src="/upload/2022/05/image-1651543308184.png" alt="image-1651543308184" /></p><p>接着我们可以开始构造Hankel矩阵。离散脉冲响应序列可以与离散的Markov系数一一对应。因此可以取100个值构造50阶Hankel矩阵，并作平衡实现，进行降阶处理。</p><pre><code class="language-">matrix_degree = 50;HANKEL = hankel(markov(2:end));H_nn = HANKEL(1:matrix_degree,1:matrix_degree);H_nn1 = HANKEL(1:matrix_degree,2:matrix_degree+1);[~,S,~]=svd(H_nn,0);figure;stem(1:matrix_degree,diag(S.^0.5));title(&#39;Hankel特征值（SVD分解）&#39;);grid on</code></pre><p>上述得到的矩阵通过奇异值分解，可以得到奇异值由大到小排列如图。<br /><img src="/upload/2022/05/image-1651543733079.png" alt="image-1651543733079" /><br />显然可以看出，前3个奇异值显著高于其他奇异值。因此可以考虑设定系统阶次需要高于3阶，经过分别对3-5阶的系统进行辨识，最终选择设置为4阶系统。</p><p>由于奇异值分解后可以得到公式：<br /><img src="/upload/2022/05/image-1651543972477.png" alt="image-1651543972477" /><br />又同样有Hankel矩阵可以分解为能观性矩阵与能控性矩阵乘法，记作T_1。即：<br /><img src="/upload/2022/05/image-1651543994051.png" alt="image-1651543994051" /><br />将n阶hankel矩阵向后移1位记作T_2=H(n+1,n+1)，有：<br /><img src="/upload/2022/05/image-1651544011998.png" alt="image-1651544011998" /><br />由此，可以得到我们的能观性矩阵O为：<br /><img src="/upload/2022/05/image-1651544034177.png" alt="image-1651544034177" /><br />同样，能控性矩阵可以求得为：<br /><img src="/upload/2022/05/image-1651544063100.png" alt="image-1651544063100" /><br />求得上述系统通过3阶离散系统拟合后的结果，转为连续系统。并可以求得系统传递函数。</p><pre><code class="language-">hankel_degree=4[u,s,v]=svd(H_nn,0);S=s.^0.5;Obs=u*SCtl=S*v&#39;A=Obs\H_nn1/Ctl;B=Ctl(:,1);C=Obs(1,:);A=A(1:hankel_degree,1:hankel_degree);B=B(1:hankel_degree,1);C=C(1,1:hankel_degree);D=0;sysd=ss(A,B,C,D,0.01);sys=d2c(sysd);</code></pre><p>绘制出伯德图，幅值和相位均能较好地拟合出实际系统。</p><pre><code class="language-">Gs=tf(sys)[mag,phase,tout]=bode(Gs);figure(2)% bode(Gs);subplot(2,1,1)semilogx(tout,20*log10(abs(mag(:))),&#39;color&#39;,[1,0.1,0.1]);ylabel(&#39;幅值&#39;,&#39;FontSize&#39;,11);grid onhold onsubplot(2,1,2)phase1=ones(size(phase,3),1);for i=1:size(phase,3)    phase1(i,1)=phase(1,1,i)*phase1(i,1);endsemilogx(tout,phase1-720,&#39;color&#39;,[1,0.1,0.1]);ylabel(&#39;相位&#39;,&#39;FontSize&#39;,11);grid onhold on;[Txy,F]=tfestimate(sys_in,sys_out,[],[],[],100);angley = 180*angle(Txy)/pi;gb = size(angley,1);for i=2:1:gb    if abs(angley(i)-angley(i-1))&gt;180        angley(i)= angley(i)-360;    end    if abs(angley(i)-angley(i-1))&gt;180        angley(i)= angley(i)-360;    end%     if abs(angley(i)-angley(i-1))&gt;180%         angley(i)= angley(i)-360;%     end%     if abs(angley(i)-angley(i-1))&gt;180%         angley(i)= angley(i)-360;%     endendfigure(2);subplot(2,1,1);title(&#39;系统伯德图&#39;,&#39;FontSize&#39;,13 );semilogx(2*pi*F,20*log10(abs(Txy)),&#39;b&#39;);legend(&#39;辨识系统&#39;,&#39;原始系统&#39;,&#39;FontSize&#39;,10)subplot(2,1,2);semilogx(2*pi*F,angley,&#39;b&#39;);legend(&#39;辨识系统&#39;,&#39;原始系统&#39;,&#39;FontSize&#39;,10)</code></pre><p><img src="/upload/2022/05/image-1651544210362.png" alt="image-1651544210362" /><br />当然，在频域上的系统拟合不好直接看出效果，因此我们可以在时域系统上进行对比。将一开始的M序列输入拟合的系统中，查看结果。</p><pre><code class="language-">yy=lsim(c2d(sys,0.01),sys_in(1:300));plot(yy,&#39;r&#39;);grid onhold onplot(sys_out(1:300),&#39;b&#39;);title(&#39;系统时域响应图&#39;,&#39;FontSize&#39;,12);legend(&#39;辨识系统&#39;,&#39;原始系统&#39;,&#39;FontSize&#39;,10)% xlim([0 182])% ylim([-37.7 30.0])figure;ZPK = zpk(sys)zplane(ZPK.z{:},ZPK.p{:})grid on;save(&#39;系统辨识.mat&#39;,&#39;sys&#39;)margin(ZPK)</code></pre><p><img src="/upload/2022/05/image-1651544374086.png" alt="image-1651544374086" /></p>]]>
                    </description>
                    <pubDate>Tue, 03 May 2022 09:57:07 CST</pubDate>
                </item>
                <item>
                    <title>
                        <![CDATA[使用MATLAB的simulink进行无刷电机仿真]]>
                    </title>
                    <link>http://susweet.cn/archives/shi-yong-matlab-de-simulink-jin-xing-wu-shua-dian-ji-fang-zhen</link>
                    <description>
                            <![CDATA[<blockquote><p>先开个坑，后面再填。<br />这个坑我会填的，因为这就是我的研究生方向。</p></blockquote><p>不得不说，MATLAB真的是个神器啊。功能强大，只要想做的，基本都能做到。可惜我自己本科的时候，专业并不是控制，而是机械，因此很少用到MATLAB，除了有一节视觉识别的课程上稍微写了一点点东西之外，对这个软件一无所知。我实际开始接触这个软件并使用，是在大四跨专业保研成功后，进实验室搬砖开始。<br />在MATLAB上进行电机控制仿真，我们主要使用的是Simulink的功能，配合S-Function，用C语言编写控制代码来实现。这样的好处是，在C语言通用性的支持下，把控制代码移植到其他平台上实际应用会很方便。<br />在MATLAB中配置S-function的CPP编译器会有点坑，需要去安装对应MATLAB版本的编译器，并配置好系统变量。</p><p>配置完成后，可以在matlab中运行如下代码，会自动生成对应的C++ block模块。</p><pre><code class="language-Script">%本文件用于模块的初始化设置 %legacy_code(&#39;help&#39;);%打开help文档setenv(&#39;MW_MINGW64_LOC&#39;,&#39;C:\mingw-w64\x86_64-6.3.0-win32-seh-rt_v5-rev2\mingw64&#39;);mex -setup C++;def = legacy_code(&#39;initialize&#39;);         %定义参数集变量def.SFunctionName = &#39;bldc_ctl&#39;;  %定义s-function名称def.SourceFiles = {&#39;motor_ctrl.cpp&#39;,&#39;Tool_Filter.cpp&#39;,&#39;Tool_PID.cpp&#39;};          %定义源文件def.HeaderFiles = {&#39;motor_ctrl.hpp&#39;,&#39;Tool_Filter.hpp&#39;,&#39;Tool_PID.hpp&#39;};          %定义头文件def.HostLibFiles = {&#39;&#39;};                   %定义库文件def.TargetLibFiles = {&#39;&#39;};def.IncPaths = {&#39;..\Function&#39;};     %定义头文件路径  若在目录下则不需设置def.SrcPaths = {&#39;..\Function&#39;};      %定义源文件路径def.LibPaths = {&#39;&#39;};     %定义库文件路径def.InitializeConditionsFcnSpec = &#39;void Motor_init(void)&#39;;     %初始化函数定义def.StartFcnSpec = &#39;&#39;;                                   %启动函数定义def.OutputFcnSpec = &#39;void Motor_ctrl(double u1[3], int8 u2[1], double u3[1], double u4[2], double u5[1], double y1[3], double y2[13])&#39;   %输出函数定义def.TerminateFcnSpec = &#39;&#39;;                               %停止函数定义def.Options.language = &#39;C++&#39;;def.SampleTime = [1e-6];   %定义采样时间   若不设置则与输入的采样时间相同cd(&#39;generate&#39;);%legacy_code(&#39;sfcn_cmex_generate&#39;, def);         %生成文件%legacy_code(&#39;compile&#39;, def);                    %编译文件%legacy_code(&#39;slblock_generate&#39;, def);           %封装为模块% legacy_code(&#39;sfcn_tlc_generate&#39;, def);           %生成tlc文件legacy_code(&#39;generate_for_sim&#39;, def);       %完成s-function文件的生成，编译，模块封装% legacy_code(&#39;rtwmakecfg_generate&#39;, def);   %生成m文件cd(&#39;../&#39;)</code></pre><p>如果一切顺利，那么生成对应的模块大概会像这个样子：<br /><img src="/upload/2022/05/image.png" alt="image" /><br />也可能会不太像，跟上面的代码配置相关。</p><p>待续。</p>]]>
                    </description>
                    <pubDate>Fri, 22 Apr 2022 11:15:05 CST</pubDate>
                </item>
                <item>
                    <title>
                        <![CDATA[指针式CPU与内存占用表DIY]]>
                    </title>
                    <link>http://susweet.cn/archives/指针cpu与内存占用表diy</link>
                    <description>
                            <![CDATA[<blockquote><p>这个项目是受到B站一个视频启发而做的。Up主他其实是有开源了整套方案的，但是作为一个整天摸鱼的大学生，这种东西肯定还是自己重新实现一遍有意思啦。<br />参考视频地址：<a href="https://www.bilibili.com/video/BV1jL4y1x7gx?share_source=copy_web" target="_blank">https://www.bilibili.com/video/BV1jL4y1x7gx?share_source=copy_web</a></p></blockquote><p>既然决定要自己动手做，第一步那得首先确定要用什么硬件。我本身最熟悉的单片机应该是STM32的，使用STM32配合STM32CubeMX程序实现起来也简单。原先我的计划是，pc端的上位机直接通过串口将数据发送到单片机显示。但是现在芯片的价格实在太高了，以前几块钱就能买到的最小系统板都涨了不少，那我也没必要为了那么简单的功能使用显然会资源过剩的单片机了。</p><p>最终我选用了esp8266作为控制芯片。当然，既然都选了esp8266了，那数据交换只用串口不用网络就说不过去了。起码也得使用http get或者post。有可能的话最好还要使用mqtt进行通信。</p><p><img src="/upload/2022/04/IMG_20220422_105503-f401da08eb7b4c268ce0223f88dbea3c.jpg" alt="简单测试一下" /><br />目前项目PC端代码可以在我的Gitee上找到。</p><p>获取内存占用代码：</p><pre><code class="language-C++">/*内存使用率*///windows 内存 使用率  DWORD getWin_MemUsage(void){MEMORYSTATUSEX ms;ms.dwLength = sizeof(ms);GlobalMemoryStatusEx(&amp;ms);//cout &lt;&lt; left &lt;&lt; setw(17) &lt;&lt; &quot;内存占用率：&quot; &lt;&lt; setw(3) &lt;&lt; ms.dwMemoryLoad &lt;&lt; &quot;%&quot; &lt;&lt; endl;return ms.dwMemoryLoad;}</code></pre><p>获取CPU占用率代码：</p><pre><code class="language-C++">FILETIME preidleTime;FILETIME prekernelTime;FILETIME preuserTime;FILETIME idleTime;FILETIME kernelTime;FILETIME userTime;int get_CPU_usage_init(void){    res = GetSystemTimes(&amp;idleTime, &amp;kernelTime, &amp;userTime);    preidleTime = idleTime;    prekernelTime = kernelTime;    preuserTime = userTime;    return 0;}int get_CPU_usage(void){    res = GetSystemTimes(&amp;idleTime, &amp;kernelTime, &amp;userTime);    __int64 idle = CompareFileTime(preidleTime, idleTime);    __int64 kernel = CompareFileTime(prekernelTime, kernelTime);    __int64 user = CompareFileTime(preuserTime, userTime);    int cpu = (kernel + user - idle) * 100 / (kernel + user);    //cout &lt;&lt; kernel &lt;&lt; &quot;     &quot; &lt;&lt; user &lt;&lt; &quot;     &quot; &lt;&lt; idle &lt;&lt; endl;    preidleTime = idleTime;    prekernelTime = kernelTime;    preuserTime = userTime;    return cpu;}</code></pre><p>上位机与单片机通信可选http get或者是mqtt进行。目前已实现通过get来获取。这部分代码参考了网上的资料。但是网上找到的资料有些在我的环境下get失败。另外还有无响应时卡住、长时间运行卡住等小问题。所以进行了一点点的修改优化。<br />通信代码：</p><pre><code class="language-C++">#define IPSTR &quot;192.168.1.112&quot; //服务器IP地址;#define PORT 80 //服务器端口;#define BUFSIZE 1024class httpClient {std::string host;std::string path;std::string post_content;public:std::string httpSend(std::string httpHeader);std::string httpGet(std::string host, std::string path);std::string httpPost(std::string host, std::string path, std::string post_content);};std::string httpClient::httpSend(std::string httpHeader) {//POST请求方式std::string ret = &quot;&quot;; // 返回Http Response// 开始进行socket初始化WSADATA wData;::WSAStartup(MAKEWORD(2, 2), &amp;wData);SOCKET clientSocket = socket(AF_INET, 1, 0);struct sockaddr_in ServerAddr = { 0 };ServerAddr.sin_addr.s_addr = inet_addr(IPSTR);ServerAddr.sin_port = htons(PORT);ServerAddr.sin_family = AF_INET;int errNo = connect(clientSocket, (sockaddr*)&amp;ServerAddr, sizeof(ServerAddr));if (errNo == 0) {errNo = send(clientSocket, httpHeader.c_str(), httpHeader.length(), 0);//发送头文件 if (errNo &gt; 0) {std::cout &lt;&lt; &quot;发送成功&quot; &lt;&lt; std::endl;}else {std::cout &lt;&lt; &quot;errNo:&quot; &lt;&lt; errNo &lt;&lt; std::endl;// socket环境清理::WSACleanup();return ret;}// 接收char bufRecv[3069] = { 0 };errNo = recv(clientSocket, bufRecv, 3069, 0);if (errNo &gt; 0) {ret = bufRecv;// 如果接收成功，则返回接收的数据内容char* p;char* delims = { &quot;\n&quot; };p = strtok(bufRecv, &quot;\n&quot;);int i = 0;while (p != NULL) {if (i == 13) {ret = p;}i++;p = strtok(NULL, delims);}// socket环境清理::WSACleanup();return ret;}else {std::cout &lt;&lt; &quot;errNo:&quot; &lt;&lt; errNo &lt;&lt; std::endl;// socket环境清理::WSACleanup();return ret;}}else {errNo = WSAGetLastError();std::cout &lt;&lt; &quot;errNo:&quot; &lt;&lt; errNo &lt;&lt; std::endl;// socket环境清理::WSACleanup();return ret;}}/** Get 请求 */std::string httpClient::httpGet(std::string host, std::string path) {std::string httpHeader;httpHeader =&quot;GET &quot; + path + &quot; HTTP/1.1\r\n&quot;&quot;Host: &quot; + host + &quot;\r\n&quot;&quot;User-Agent: IE or Chrome\r\n&quot;&quot;Accept-Type: */*\r\n&quot;&quot;Connection: Close\r\n\r\n&quot;;return httpSend(httpHeader);}/** Post 请求 */std::string httpClient::httpPost(std::string host, std::string path, std::string post_content) {std::string httpHeader;char lenChar[16]; //这个长度根据需要吧sprintf(lenChar, &quot;%d&quot;, (int)post_content.length());std::string len(lenChar);httpHeader =&quot;POST &quot; + path + &quot; HTTP/1.1\r\n&quot;&quot;Accept-Encoding: gzip, deflate&quot;&quot;Host: &quot; + host + &quot;\r\n&quot;&quot;Connection: keep-alive\r\n&quot;&quot;Content-Type: application/x-www-form-urlencoded\r\n&quot;&quot;Content-Length: &quot; + len + &quot;\r\n\r\n&quot;+ post_content;return httpSend(httpHeader);}</code></pre><p>esp8266是在arduino的平台上开发的，参考代码：</p><pre><code class="language-">#include &lt;ESP8266WiFi.h&gt;#include &lt;WiFiClient.h&gt;#include &lt;ESP8266WebServer.h&gt;#include &lt;ESP8266mDNS.h&gt;#include &quot;Ticker.h&quot;#ifndef STASSID#define STASSID &quot;wifi_ssid&quot;#define STAPSK  &quot;wifi_密码&quot;#endifconst char* ssid     = STASSID;const char* password = STAPSK;int cpu_usage = 0;int mem_usage = 0;int cpu_usage_display = 0;int mem_usage_display = 0;Ticker displayTicker; //建立一个需要定时调度的对象ESP8266WebServer server(80);const int led = LED_BUILTIN;const String postForms = &quot;&lt;html&gt;\  &lt;head&gt;\    &lt;title&gt;ESP8266 Web Server POST handling&lt;/title&gt;\    &lt;style&gt;\      body { background-color: #cccccc; font-family: Arial, Helvetica, Sans-Serif; Color: #000088; }\    &lt;/style&gt;\  &lt;/head&gt;\  &lt;body&gt;\    &lt;h1&gt;POST plain text to /postplain/&lt;/h1&gt;&lt;br&gt;\    &lt;form method=\&quot;post\&quot; enctype=\&quot;text/plain\&quot; action=\&quot;/postplain/\&quot;&gt;\      &lt;input type=\&quot;text\&quot; name=\&#39;{\&quot;hello\&quot;: \&quot;world\&quot;, \&quot;trash\&quot;: \&quot;\&#39; value=\&#39;\&quot;}\&#39;&gt;&lt;br&gt;\      &lt;input type=\&quot;submit\&quot; value=\&quot;Submit\&quot;&gt;\    &lt;/form&gt;\    &lt;h1&gt;POST form data to /postform/&lt;/h1&gt;&lt;br&gt;\    &lt;form method=\&quot;post\&quot; enctype=\&quot;application/x-www-form-urlencoded\&quot; action=\&quot;/postform/\&quot;&gt;\      &lt;input type=\&quot;text\&quot; name=\&quot;hello\&quot; value=\&quot;world\&quot;&gt;&lt;br&gt;\      &lt;input type=\&quot;text\&quot; name=\&quot;sweet\&quot; value=\&quot;summer\&quot;&gt;&lt;br&gt;\      &lt;input type=\&quot;text\&quot; name=\&quot;cpu_usage\&quot; value=\&quot;50\&quot;&gt;&lt;br&gt;\      &lt;input type=\&quot;text\&quot; name=\&quot;mem_usage\&quot; value=\&quot;60\&quot;&gt;&lt;br&gt;\      &lt;input type=\&quot;submit\&quot; value=\&quot;Submit\&quot;&gt;\    &lt;/form&gt;\    &lt;h1&gt;update device data&lt;/h1&gt;&lt;br&gt;\    &lt;form method=\&quot;post\&quot; enctype=\&quot;application/x-www-form-urlencoded\&quot; action=\&quot;/device/\&quot;&gt;\      &lt;input type=\&quot;text\&quot; name=\&quot;cpu_usage\&quot; value=\&quot;50\&quot;&gt;&lt;br&gt;\      &lt;input type=\&quot;text\&quot; name=\&quot;mem_usage\&quot; value=\&quot;60\&quot;&gt;&lt;br&gt;\      &lt;input type=\&quot;submit\&quot; value=\&quot;Submit\&quot;&gt;\    &lt;/form&gt;\  &lt;/body&gt;\&lt;/html&gt;&quot;;void tickerHandle() //到时间时需要执行的任务{  if((cpu_usage*10+cpu_usage_display*9)/10 == cpu_usage_display &amp;&amp; cpu_usage_display &gt; (cpu_usage*10))  {    cpu_usage_display--;  }  else if((cpu_usage*10+cpu_usage_display*9)/10 == cpu_usage_display &amp;&amp; cpu_usage_display &lt; (cpu_usage*10))  {    cpu_usage_display++;  }  else  {    cpu_usage_display = (cpu_usage*10+cpu_usage_display*9)/10;  }  analogWrite(15, cpu_usage_display*105/100);  // D8}void handleRoot() {  digitalWrite(led, 1);  server.send(200, &quot;text/html&quot;, postForms);  digitalWrite(led, 0);}void handlePlain() {  if (server.method() != HTTP_POST) {    digitalWrite(led, 1);    server.send(405, &quot;text/plain&quot;, &quot;Method Not Allowed&quot;);    digitalWrite(led, 0);  } else {    digitalWrite(led, 1);    server.send(200, &quot;text/plain&quot;, &quot;POST body was:\n&quot; + server.arg(&quot;plain&quot;));    digitalWrite(led, 0);  }}void handleForm() {  if (server.method() != HTTP_POST) {    digitalWrite(led, 1);    server.send(405, &quot;text/plain&quot;, &quot;Method Not Allowed&quot;);    digitalWrite(led, 0);  } else {    digitalWrite(led, 1);    String message = &quot;POST form was:\n&quot;;    for (uint8_t i = 0; i &lt; server.args(); i++) {      message += &quot; &quot; + server.argName(i) + &quot;: &quot; + server.arg(i) + &quot;\n&quot;;    }    server.send(200, &quot;text/plain&quot;, message);    digitalWrite(led, 0);  }}void handleDevice() {  if (server.method() != HTTP_POST) {    digitalWrite(led, 1);    server.send(405, &quot;text/plain&quot;, &quot;Method Not Allowed&quot;);    digitalWrite(led, 0);  } else {    digitalWrite(led, 1);    String message = &quot;POST form was:\n&quot;;    for (uint8_t i = 0; i &lt; server.args(); i++) {      message += &quot; &quot; + server.argName(i) + &quot;: &quot; + server.arg(i) + &quot;\n&quot;;      if(server.argName(i) == &quot;cpu_usage&quot;)      {        cpu_usage = server.arg(i).toInt();        Serial.print(&quot;cpu usage:&quot;);        Serial.println(cpu_usage);      }      else if(server.argName(i) == &quot;mem_usage&quot;)      {        mem_usage = server.arg(i).toInt();        Serial.print(&quot;mem usage:&quot;);        Serial.println(mem_usage);      }    }    server.send(200, &quot;text/plain&quot;, message);    Serial.println(&quot;=====================================================&quot;);    digitalWrite(led, 0);  }}void handleNotFound() {  digitalWrite(led, 1);  String message = &quot;File Not Found\n\n&quot;;  message += &quot;URI: &quot;;  message += server.uri();  message += &quot;\nMethod: &quot;;  message += (server.method() == HTTP_GET) ? &quot;GET&quot; : &quot;POST&quot;;  message += &quot;\nArguments: &quot;;  message += server.args();  message += &quot;\n&quot;;  for (uint8_t i = 0; i &lt; server.args(); i++) {    message += &quot; &quot; + server.argName(i) + &quot;: &quot; + server.arg(i) + &quot;\n&quot;;  }  server.send(404, &quot;text/plain&quot;, message);  digitalWrite(led, 0);}void setup(void) {  pinMode(led, OUTPUT);  digitalWrite(led, 0);  analogWriteFreq(1000);  analogWriteRange(1100);  pinMode(15, OUTPUT);  analogWrite(15, 0);  // D8  Serial.begin(115200);  WiFi.begin(ssid, password);  Serial.println(&quot;&quot;);  // Wait for connection  while (WiFi.status() != WL_CONNECTED) {    delay(500);    Serial.print(&quot;.&quot;);  }  Serial.println(&quot;&quot;);  Serial.print(&quot;Connected to &quot;);  Serial.println(ssid);  Serial.print(&quot;IP address: &quot;);  Serial.println(WiFi.localIP());  if (MDNS.begin(&quot;sweet&quot;)) {    Serial.println(&quot;MDNS responder started&quot;);  }  server.on(&quot;/&quot;, handleRoot);  server.on(&quot;/postplain/&quot;, handlePlain);  server.on(&quot;/postform/&quot;, handleForm);  server.on(&quot;/device/&quot;,handleDevice);  server.onNotFound(handleNotFound);  server.begin();  Serial.println(&quot;HTTP server started&quot;);  displayTicker.attach(0.1,tickerHandle);}void loop(void) {  server.handleClient();  MDNS.update();}</code></pre><p>目前测试正常。</p><p>待续。。。</p>]]>
                    </description>
                    <pubDate>Fri, 22 Apr 2022 10:51:53 CST</pubDate>
                </item>
    </channel>
</rss>