- 博客(50)
- 资源 (5)
- 收藏
- 关注

原创 【从零开始实现stm32无刷电机FOC】【实践】【7.2/7 完整代码编写】
本节使用stm32cubemx配置外设,生成keil工程,代码适配本文的硬件电路板。
2024-09-29 17:32:32
13515
26
原创 【扩展卡尔曼滤波理论推导与实践】【理论】【1/3 前言】
扩展卡尔曼滤波,【扩展】是指在标准卡尔曼滤波基础上扩展算法而来。标准卡尔曼滤波是建立在二阶弹簧阻尼质量块系统上的线性模型,最明显的是状态转移方程和测量方程是线性的。将系统模型笼统地建模为弹簧阻尼质量块系统,这是不准确的;很多场景测量模型不是线性倍数关系,在那些场景下是不准确的。扩展卡尔曼滤波就是为了解决这类非线性问题的。
2024-12-26 21:00:13
1123
原创 【卡尔曼滤波理论推导与实践】【理论】【5/5 实践】
卡尔曼滤波要人工调节的参数包括初值、Q、R,就和调PID参数一样,要调出一个好的参数还是不容易的。文章中的电机进行电机速度数据滤波测试,设置为纯电流控制模式,对速度进行卡尔曼滤波,设置了。结果如下图,红色数据为测量出来的电机速度,绿色数据为卡尔曼滤波之后的速度。这些矩阵都只有一维,退化成一个数了,协方差矩阵退化成方差了。
2024-12-22 15:21:46
854
原创 【卡尔曼滤波理论推导与实践】【理论】【4/5 公式总结】
模型噪声和测量噪声的协方差矩阵,是人为假设的,这也是需要调参的点。卡尔曼的推导过程中将卡尔曼增益做了一个变换。是最优估计值,是卡尔曼滤波的最终输出值。是状态转移矩阵,是人为建模给定的。是控制矩阵,是人为建模给定的。左乘、右乘、转置是一样的,
2024-12-22 15:20:58
830
原创 【卡尔曼滤波理论推导与实践】【理论】【3.2/5 卡尔曼增益02】
用测量值修正系统模型值,得到当前轮次的最优估计值。再将该最优估计值当作下一轮的系统模型输入,继续进行下一轮的最优估计,如此迭代进行。到此为止,所有东西都被推导出来了,能看到这是一轮迭代求解的过程,下一节对公式进行整理,也就是卡尔曼滤波的5个公式。是一个模型噪声的协方差矩阵,是人为假定的常数,是已知的,记做。上节推导得到的两个表达式如下,注意只是将。等式右边全是上轮迭代得到的已知数,但是。代入表达式,即可得到最优估计时的。等号右边都是上轮迭代得出的值,的表达式,将最优估计时的。根据协方差定义的公式,
2024-12-22 15:20:12
616
原创 【卡尔曼滤波理论推导与实践】【理论】【3.1/5 卡尔曼增益01】
上节,推导得到了状态空间方程,可以得到系统模型值了。目前核心思想中的【修正】这个概念还处于迷雾中,本节对此进行推导。往下看之前,如果让你来原创,你会怎么用表达式将【测量值修正系统模型值】这句话的逻辑清晰地写出来?有差值才有【修正】,而差值是测量值和系统模型之间的差,是在被修正值的基础上加这个差值,因此这是一个关于测量值和系统模型值的逻辑。【修正】的逻辑应当是这样的:将测量值与模型值的差作为修正值,乘个系数后,叠加到模型值,这就是卡尔曼滤波的【修正】。这个系数,被称为卡尔曼增益。
2024-12-22 15:18:47
1307
原创 【卡尔曼滤波理论推导与实践】【理论】【2/5 状态空间方程】
测量值是我们测量得到的,这个是已知的。系统模型现在还没有建模,本节建立系统模型,系统模型值就是系统模型计算得到的值。由于一阶微分表述的是当前量与当前量的导数的关系,离散后具有有迭代的性质,符合状态转移理念,因此我们要想办法将上面这个二阶微分方程转换为一阶微分方程,当然二阶量就无法作为状态的一员了。大部分情况下,会使用弹簧阻尼质量块这个模型进行分析,大部分物理现象被抽象概括成这个模型,当然不一定准确,但是具有一定的普适性。,这就是系统模型所谓的【描述了上一轮次的状态与本轮次状态的转换关系】。
2024-12-22 15:17:38
1041
原创 【卡尔曼滤波理论推导与实践】【前言】【1/5 前言】
滤波是在一串有先后顺序的观测值中尽量估计出接近真值的操作。估计出的值是最优估计值,每收到一个杂乱数据都算出一个最优估计值,即每轮次都有最优估计值。当然,真值永远也无法知道。现在看这个思想是符合自然逻辑的,卡尔曼提出来了并用数学语言进行描述,这就是人家的创新之处。这样,每轮次的最优估计值都算出来了。
2024-12-22 15:17:08
423
原创 【从零开始实现stm32无刷电机FOC】【实践】【7.1/7 硬件设计】
为了承载和验证本文的FOC代码工程,本节设计了一个简易的三相无刷电机,主控采用非常常用的stm32f103c8t6单片机,电机编码器采用MT6701,电机采用22xx系列云台电机,驱动电路采用集成驱动芯片DRV8313,电流传感器采用INA199A1在线采样。该使用无工具快拆装设计,到手即可直接快速手拧安装拆卸。
2024-09-29 17:30:28
5127
5
原创 【从零开始实现stm32无刷电机FOC】【实践】【6/7 CMSIS-DSP】
CMSIS-DSP库是ARM开源的、对ARM处理器优化的数学库,本文使用了其提供的三角函数、反park变换函数、park变换函数、clarke变换函数、PID控制器。CMSIS-DSP原始代码仓库是,官方对其的介绍是一个针对Cortex-M和Cortex-A内核优化的嵌入式系统计算库,此处的DSP不是指的硬件,而是数字处理的意思。
2024-07-18 22:59:24
3600
4
原创 【从零开始实现stm32无刷电机FOC】【实践】【5/7 stm32 adc外设的高级用法】
本节介绍的adc外设高级用法用于电机电流控制。从前面几节可知,电机力矩来自于转子的q轴受磁力,而磁场强度与电流成正比,也就是说电机力矩与q轴电流成正相关,控制了q轴电流就是控制了电机力矩。从前文电流控制内容可知,q轴电流从三个相线电流计算得到,三个相线电流通过电流采样单元连接到stm32的adc接口得到。这里要注意,本文全文没有提到过dq轴电压或相线的电压,因为相线电阻会随着温度而改变,而电流才是决定磁场强度。
2024-07-16 22:06:45
3955
5
原创 【从零开始实现stm32无刷电机FOC】【实践】【4/7 stm32高级定时器】
本节对stm32高级定时器中可用于FOC控制的配置项进行了介绍,并尽量开启了TIM1的完整功能,请根据自己的电路环境以及配置项说明图进行配置项的删减,比如是否开启互补和死区功能、是否开启刹车功能、死区时间的修改等等。从上图看到,半桥的上功率管和下功率管不能同时导通,否则功率管会由于短路流经大量电流被烧毁(电机绕组有电阻在,不算短路),因此上下两个的功率管的pwm要求互补导通。下图是定时器配置为上下计数模式的pwm产生示意图,定时器当前计数值与设定的比较线(值)的比较关系控制定时器通道的输出。
2024-07-11 23:14:01
6113
3
原创 【从零开始实现stm32无刷电机FOC】【理论】【3/7 位置、速度、电流控制】
上一节,通过对SVPWM的推导,我们获得了控制电机转子任意受力的能力。本节,我们选用上节得到的转子dq轴解耦的SVPWM形式,对转子受力进行合理控制,实现FOC电机控制的最终目标:位置、速度、电流控制。
2024-07-09 21:43:23
5483
5
原创 【从零开始实现stm32无刷电机FOC】【理论】【2/7 SVPWM数学模型】
本节推导了svpwm数学模型,得到了目标磁矢量的生成函数。
2024-05-22 22:46:36
6132
30
原创 Keil 厂商DFP pack实现原理
直接复制别人的厂商文件夹到这里也是相同的效果,比如这里复制了一份ArteryTek的文件夹命名为ArteryTek2,打开Keil时会提示ArteryTek2相应的信息,说明Keil会扫描这个目录下的文件夹。在Keil中用鼠标选择芯片型号操作的原理是读取解析厂商文件夹下对应型号文件夹中的pdsc文件(pack description),这个文件写着芯片的介绍文字、外设功能库的路径、debug时寄存器文件的路径等等芯片相关的信息,Keil读取出这些信息后显示到Keil界面上供程序员鼠标点选。
2023-10-12 11:40:52
664
原创 串口硬件流控RTS、CTS
硬件流控机制:发送端在发送前需要检查自身的CTS,CTS低电平为可以发送。接收端RTS连接到发送端的CTS,接收端准备好接收后拉低自己的RTS即拉低发送R端的CTS。设置流控模式后,芯片内部自动完成以上机制,CTS为高时,即使程序运行发送函数,实际上并不会发送。当接收端的串口处理速度过低时,会丢失数据,因此考虑增加一种通知的机制来告诉发送端是否可以发送,即增加了RTS(Require To Send)和CTS(Clear To Send)信号线。
2023-10-11 14:01:21
2311
原创 MOS管各种概念(三个极、沟道、衬底、电流方向、箭头方向、耗尽型和增强型、寄生二极管、封装引脚)
MOS管各种概念(三个极、沟道、衬底、电流方向、箭头方向、耗尽型和增强型、寄生二极管)
2023-10-09 11:02:37
26182
5
原创 WSL2中的ROS2与windows中的webots通信失败的问题
windows中在【控制面板\系统和安全\Windows Defender 防火墙\允许的应用】中,将webots-bin的专用和公用都勾选上,即可解决问题。
2023-06-14 00:04:41
498
原创 opencv 快速简单二值化的做法
大家在网上搜索opencv二进制,很多人会告诉你用threshold等函数。这类函数虽然支持自适应等功能,但是参数比较多,有点复杂。我们只要简单二值化的时候可以用以下做法:Mat img = imread("a.png", IMREAD_GRAYSCALE)<100;...
2022-03-06 16:34:40
3132
原创 windows平台,mingw64编译环境下的socket使用
代码并不重要,主要看最后的编译命令://test.cpp#include <winsock2.h>#include <iostream>using namespace std;int main(){ WSADATA ws; WSAStartup(MAKEWORD(2, 2), &ws); SOCKET s = socket(AF_INET, SOCK_STREAM, 0); SOCKADDR_IN addrSrv; add
2021-07-05 14:18:01
3207
原创 windows平台,mingw64编译使用matplotlibcpp
编译以下代码://test.cpp#include "matplotlibcpp.h"namespace plt = matplotlibcpp;int main() { plt::plot({1,3,2,4}); plt::show();}编译命令:g++ test.cpp -DWITHOUT_NUMPY -ID:\application\miniconda3\include -LD:\application\miniconda3 -lpython38注意自行更改pytho
2021-07-05 13:44:38
404
原创 linux平台的三种动态库路径设置方法
方法一:LD_LIBRARY_PATHexport LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/your/path建议在~/.profile最后增加一行,写入上述命令。方法二:/etc/ld.so.conf用sudo权限在/etc/ld.so.conf文件最后新增一行动态库路径,比如写入/usr/local/lib。然后命令行运行sudo ldconfig。方法三:gcc添加编译选项-Wl,-rpath=/your/path:/your/path2比如gcc
2021-05-18 15:11:06
4847
原创 从零开始使用交叉编译开发树莓派驱动hello world
【以下命令没有特别说明,皆在上位机端运行(wsl不原生支持树莓派官方的32位编译器,自行查找资料折腾)。】1.交叉编译环境准备arm设备性能低,一般不在arm板上编译东西,所以使用交叉编译。此处上位机为linux pc。kernel源码:运行uname -r查看当前树莓派的内核版本。并下载相应版本的内核git clone git://github.com/raspberrypi/linux.git。compiler chain:git clone git://github.com/raspberr
2021-04-07 12:57:18
350
原创 【简洁清晰】使用ssh自带的反向代理功能,实现访问内网设备的任意端口,包括ssh、vnc等
机器A:内网设备机器B:中转设备,用来转发,最好有公网ip机器C:任意设备,客户端,用来访问机器A,就是你正在用的电脑0.自行配置好[机器A>>机器B]、[机器C>>机器A]、[机器C>>机器B]的ssh密码或密钥。1.配置机器B:将/etc/ssh/sshd_config中的GatewayPorts设置为yes,重启sshdsudo systemctl restart sshd.service2.配置机器A:机器A运行命令:ssh -fNR [中转
2021-03-14 19:31:42
2493
1
原创 Windows使用mingw64编译安装opencv
准备(自行准备)1.1. opencv源码1.2. mingw641.3. cmake编译2.1. 生成makefile在opencv源码目录新建build文件夹,进入build文件夹,powershell运行cmake -G "MinGW Makefiles" -D CMAKE_INSTALL_PREFIX=D:/选择你想要安装到的路径 -D OPENCV_ALLOCATOR_STATS_COUNTER_TYPE=int64_t ..命令解释:生成mingw格式的makfile,指定op.
2020-12-06 16:28:50
943
1
原创 无需putty等第三方ssh软件,纯ssh通过转发X11到xming运行服务器的gui程序
【本地是linux平台】1. 本地是wsl等无gui的系统客户端依次运行:export DISPLAY=localhost:0.0如果不想每次都输入这个命令,要写在.bashrc(或.zshrc等)中,写在.profile不顶用。ssh -X hyz@192.168.xxx.xxx或者在~/.ssh/config中的主机参数里加上ForwardX11 yes,只需加这个服务器端设置服务器端无需设置,不要听网上其他乱七八糟的教程,sshd_config中关于X11的任何选项都不要动
2020-11-26 19:17:10
1792
原创 novnc无法连接realVNC服务端,浏览器code(1006)
解决方法:用超级权限进入realVNC的Options,将“Unix password”改为“VNC password”,然后重启电脑。感谢https://github.com/novnc/noVNC/issues/1438
2020-11-09 16:42:38
2694
原创 linux系统的ssh和sshd常用配置
由于本人记性极差,每次配置新系统的ssh都要去网上查,特此记录,方便以后查阅。服务器:生成一对ssh密钥命令:ssh-keygen。添加客户端的公钥:手动添加。服务器打开(没有此文件则新建),将客户端的 ~/.ssh/id_rsa.pub(没有则在客户端运行ssh-keygen新建)里的内容复制到服务器端的 ~/.ssh/authorized_keys文件里(没有这个文件则新建)。注意authorized_keys里每个公钥之间都要空一行,最后一行必须是空行。自动添加。客户端运行ssh-co
2020-11-05 20:26:20
338
原创 C++中的强制类型转换:static_cast、const_cast、reinterpret_cast、dynamic_cast
在C++中,用括号方式进行强制类型转换是旧式的,比如(int)1.666。现代的做法是用四种cast,static_cast、const_cast、reinterpret_cast、dynamic_cast,语法是cast-name(expression)。1. static_cast用于基础简单类之间的转换,比如int,double,char之间。也用于有血缘关系的类指针的转换,这意味着char* 于int* 无法转换。其他指针层级的转换请使用reinterpret_cast。2. const
2020-10-14 10:58:50
203
原创 gcc/g++ 生成、使用动态库/静态库
生成动态库:gcc -shared so.c -o libso.so有时候会报错提示加上-fPIC(-flag position-independent code,为了生成位置无关代码,用全局偏移的方式,一份动态库即可给多份主程序使用,细节自己网上查吧),加上就行了。libso.so文件注意lib前缀和.so后缀。动态库命名格式是规定好的,细节自己网上查。使用动态库:gcc main.c -L. -lso -Wl,-rpath=/home/me/test【-L】编译时动态库所在的目录。
2020-10-11 10:59:55
999
原创 c/c++ 数组名是指针吗?使用汇编分析
结论在前:数组名是纯地址值,不是指针。反汇编的方法分析:void fun(int *a,int *b){}int main(){ int a[]={1}; int bb=1; int *b=&bb; fun(a,b); fun(a,&bb);}使用g++ -g temp.cpp编译出二进制,并使用objdump -S a.out进行反汇编,以下为截取的部分汇编代码: int a[]={1}; 1177: c7 45 f4 01
2020-10-09 17:27:13
462
1
原创 C++ 通过类继承的多态实现原理以及虚函数表改写时机
class Parent{public: virtual void func() { cout << "Parent" << endl; }};class Child : public Parent{public: void func_child() { cout << "func_child" << endl; } void func() { cout << "Child" << endl; }};int
2020-10-06 16:10:58
329
原创 C++ 虚函数多态的意义
假设A是父类,里面有virtual fun()。B、C是public继承的子类,override了fun()。创建对象引用,多态有以下代码:B b;C c;A& n=b;A& m=c; n.fun();m.fun();我在想,多态有什么意义呢?为什么要把子类引用给父类呢?这不是多次一举吗?直接B& n=b; C& m=c; 他不香吗?反正都是两行代码,分配的内存空间也是一样大小的,性能也没有差别。说白了,多态的意义就在于写代码更通解,并能够减
2020-10-05 19:57:50
259
原创 termux 修改自定义字体
termux 运行chfont可修改预设的二十几种字体,接下来的操作可以添加自己的字体。将字体文件复制到~/.termux/fonts/里,再运行chfont就能看到自己的字体了。实际上,chfont命令运行的是.termux/fonts.sh,这个命令修改了.termux/font.ttf文件。...
2020-09-20 19:53:07
9137
原创 vscode的tasks.json使用pkg-config的方法
以下是在命令行中使用pkg-config的方法g++ test.cpp `pkg-config --cflags --libs opencv`但是如果在tasks.json的编译选项中直接加入"`pkg-config --cflags --libs opencv`"会导致编译报错。解决办法:tasks.json里的编译参数要使用下面的写法"`pkg-config","--libs","--cflags","opencv`",...
2020-07-12 19:17:18
2091
4
opencv.zip
2020-12-06
libopencv_world450.dll.a
2020-12-06
libopencv_world450.dll
2020-12-06
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人