Odriver 之测速
传感器
绝对磁编码器
绝对磁编码器比较简单,直接读寄存器就可以。实际使用中需要配合径向冲磁的磁铁使用,且最好能远离其他可能造成磁场变化的器件;其次需要注意角度更新频率,动态特性等参数。
线性霍尔传感器
对于线性霍尔传感器一般是需要进行校准的,其使用方法一般是两个传感器呈 80 度对称分布,同样需要配合径向冲磁的磁铁使用。
当磁铁旋转一周的时候,线性霍尔的传感器的输出应该正好是一个正弦信号,但是正弦的幅值需要校准,让传感器旋转一周分别获取最大值和最小值,这样就可以重构一周的信号与位置的关系。单个传感器就可以获取全部位置角度的信息,但是单个传感器存在一个问题,就是在正弦波的极点处值的变化非常小,而在线性区域变化则比较明显,因此使用两个传感器呈 90 度摆放则可以解决这个问题。如下图:
如果 a 传感器取 sin 值为 hall_sin,b 传感器取 cos 值为 hall_cos,则最终的角度为 atan2f(hall_sin, hall_cos)。
123456789101112131415161718192021/** * @brief Hall Sensor read ang ...
odriver 之 SVM
源码
SVM 函数的 alpha 和 beta 的值是经过了标幺化,基准值为 (最大相电压),也就是说 alpha 和 beta 的范围是 [-1,1]。约束:alpha-beta 向量的大小不得大于 $ $。
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118// Compute rising edge timings (0.0 - 1.0) as a function of alpha-beta// as per the magnitude invariant clarke transform// The magnitude of the al ...
FOC 电流采样
采样点
在基尔霍夫定律下,三相电流的合应该等于 0,因此只需要获取亮相电流就可以重构出完整的三相电流。
对于 STM32 一般通过高级定时器的 channel4 作为 ADC 的触发源,对于下桥臂电流采样,需要在下桥臂 MOS 管导筒的时候才能去采样,而且需要在 MOS 管导通时间以及电流稳定后才能采样到比较可靠的电流。
当 \(\Delta_1\) 大于两倍的 $T_{dead} + T_{on} + T_{ring} + T_{conv} $ 那么在 PWM Freq Middle 时刻出发 ADC 转换也是足够转换 3 相中任意的一相。
当 \(\Delta_1\) 大于$T_{dead} + T_{on} + T_{ring} + T_{conv} 那么从 CCRmax 之后开始转换也是可以转换 3 相中任意的一相。
当 \(\Delta_2\) > \(\Delta_0\) > \(\Delta_1\) 那么导通最短的那一相就没有足够的转换时间了,那么只能转换导通时间长的那两相。
\(\Delta_1\) < \(\Delta_0\) 和 \(\Del ...
差速轮运动学解算
差速轮运动学模型
机器人坐标系下的变换
运动特性为两轮差速驱动,其底部后方两个同构驱动轮的转动为其提供动力,前方的随动轮起支撑作用并不推动其运动,如下图两轮差速驱动示意图所示。
机器人的运动简化模型如图 4-1 所示,X 轴正方向为前进、Y 轴正方向为左平移、Z 轴正方向为逆时针。机器人两个轮子之间的间距为 D,机器人 X 轴和 Z 轴的速度分别为:\(V_x\)和\(V_z\) ,机器人左轮和右轮的速度分别为:\(V_l\) 和\(V_r\)。
假设机器人往一个左前的方向行进了一段距离,设机器人的右轮比左轮多走的距离近似为 K, 以机器人的轮子上的点作为参考点做延长参考线,可得:\(θ_1 = θ_2\) 。由于这个\(Δ_t\) 很小,因此角度的变化量\(θ_1\) 也很小,因此有近似公式:
\[
\theta_{2} \approx \sin \left(\theta_{2}\right)=\frac{K}{D}
\]
由数学分析可以得到下面的式子:
\[
\begin{equation}
\mathrm{K}=\left(\mathrm{V}_{\mathrm{R}}-\m ...
Valgrind 检测 C++内存泄漏
Valgrind 的介绍
Valgrind 可以用来检测程序是否有非法使用内存的问题,例如访问未初始化的内存、访问数组时越界、忘记释放动态内存等问题。在 Linux 可以使用下面的命令安装 Valgrind:
123456$ wget ftp://sourceware.org/pub/valgrind/valgrind-3.13.0.tar.bz2$ bzip2 -d valgrind-3.13.0.tar.bz2$ tar -xf valgrind-3.13.0.tar$ cd valgrind-3.13.0$ ./configure && make$ sudo make install
检测内存泄漏
C 语言
Valgrind 可以用来检测程序在哪个位置发生内存泄漏,例如下面的程序:
123456#include <stdlib.h>int main(){ int *array = malloc(sizeof(int)); return 0;}
编译程序时,需要加上-g 选项:
1$ gcc -g -o main_c main.c
使用 Va ...
应用崩溃调试分析
前言
应用崩溃,各种空指针等大概是应用开发过程中最常遇到的问题了。而我们传统的调试利器 syslog 能快速解决 90%的问题,但是对于那些低概率,需要老化几十小时才能复现到的问题通过 syslog 就很难定位到问题了。这时如果可以提供一种情景再现的方式将应用崩溃现场的调用栈以及栈内数据给展现出来那么对于我们定位问题是大有帮助的。而笔者最近就遇到大量这种(基本都是老化过程中遇到的低概率)问题,于是这里尝试提供一种方法来快速定位问题。当然这类问题都是一个路子,掌握这种分析方法以后遇到这类问题就都可以轻松处理了。
本文提供的一种解决方案是通过 gdb+core dump 文件分析调试方法,具体如下:
开启 core dump 功能
在 init 脚本的 start_service 中添加
1procd_set_param limits core="unlimited"
这样一条代码,例如 xxxapp 中的添加如下:
或者直接在 shell 中执行:
12ulimit -c unlimitedecho "/tmp/core-%e-%p-%t" > /proc/sys/kernel ...
C/C++内存泄露分析过程
前言
最近在工作中遇到了一些内存泄露问题,虽然泄露速度很慢,但是对于小型嵌入式设备而言资源本身就很紧张而且过 72h 老化测试过不了。于是寻找一些内存泄露检测工具辅助查找内存泄露问题,此处只使用了 leaktracer 这个开源库来帮助查找内存泄露问题。
leaktracer 概述
LeakTracer 是在检查 C/C++ 程序内存泄漏时编写的一个小工具。 要使用 LeakTracer,请使用提供的 LeakCheck 脚本运行您的程序。它使用 LD_PRELOAD 特性在你的函数之上“覆盖”一些函数(不需要重新编译)。如果您的平台不支持 LD_PRELOAD,您可以将 LeakTracer.o 对象文件添加到 Makefile 中的对象并运行您的应用程序。 LeakTracer 利用 gdb 去输出发生内存泄露所发生的位置,它是通过 override operator new, operator delete, operator malloc, operator free 来实现检测。
用法
加载 leaktracer 库的 3 种方法:
将您的程序链接到 libleaktra ...
一个 oops 分析实例
最近出现了比较多的内核崩溃的问题,之前也曾转发过网上一篇关于内核崩溃问题的跟踪方法,我在这里借 xxx 提供的这个死机现场,再给大家描述一下这类问题的分析方法和 debug 过程,也希望能让大家真正掌握这类问题的调试方法。让大家明白,内核崩溃问题的调试方法其实也就是这样一些固定的套路。问题的分析过程如下:
确认死机现场
12345678910111213[56400.437450] Unable to handle kernel paging request at virtual address f7fe44a1[56400.440040] pgd = d112c000[56400.440040] [f7fe44a1] *pgd=00000000[56400.440040] Internal error: Oops: 5 [#1] PREEMPT SMP ARM[56400.440040] Modules linked in: 8188eu gt82x mma8452 rtl8150 mcs7830 qf9700 asix sunxi_keyboard sw_device vfe_v ...
概率论与数理统计
原图
概率论基本概念
概率的派别
对于概率的定义有几个主流的派别:
频率派: 频率派认为如果频率存在稳定性,即当\(n\to\infty\)时下面极限存在(下面这个写法只是示意,后面介绍大数定律的时候会给出严格的定义),就得到了概率(用 Probability 的首字母 P 来表示): \[
P(正面)=\lim_{n\to\infty}P_{n}(正面)
\]
古典派: 如果因为无知,使得我们没有办法判断哪一个结果会比另外一个结果更容易出现,那么应该给予它们相同的概率,此称为不充分理由原则(Insufficient Reason Principle)。以不充分理由原则为基础,经由拉普拉斯:之手,确立了古典概率的定义,即: 未知的概率都为等概率
主观派: 最后介绍下主观派,主观派认为概率是信念强度(degree of belief)。比如说,我个人相信 20 年后人类从网络时代进入人工智能时代的概率为 70%.
三个流派大概有以下的区别: \[
\begin{array}{c|c}
\hline
\quad\quad&\quad\color{or ...
线性代数
原图
向量空间
向量
n 个有序的数\(a_1,a_2,...,a_n\)所组成的数组称为\(n\) 维向量,这\(n\)个数称为该向量的\(n\)个分量,第\(i\)个数\(a_i\)称为第\(i\)个分量。\(n\)维向量可写成一行,也可写成一列。分别称为行向量和列向量:
n 维列向量:
\[
\begin{pmatrix}a_1\\a_2\\\vdots\\a_n\end{pmatrix}
\]
与 n 维行向量:
\[
(a_1,a_2,...,a_n)\quad 或、quad \begin{pmatrix}a_1&a_2&\cdots&a_n\end{pmatrix}
\]
\(n\)也称为该向量的维数。
向量的基本运算法则
\[
\begin{array}{c|c}
\hline
\\
\quad 加法、quad & \quad\begin{aligned} 交换律、\ 结合律 \end{aligned}\quad & \quad\begin{aligned}\boldsymbol{v}+\bold ...