概率分布
前言
概率分布(probability distribution)是给出事件发生的概率的函数,它是一种通过样本空间(sample space)和事件的概率描述随机事件的方式,下面有一些需要了解到的概念
边缘分布
假设有一个和两个变量相关的概率分布 p(x,y)p(x,y)p(x,y) ,关于其中一个特定变量的边缘分布则为给定其他变量的条件概率分布如下
p(x)=∑yp(x,y)=∑yp(x∣y)p(y)p(x)=\sum_yp(x,y)=\sum_yp(x\vert y)p(y)
p(x)=y∑p(x,y)=y∑p(x∣y)p(y)
偏度
偏度(Skewness)衡量数据分布的对称性,计算公式如下
Skewness=E[(x−μ)3]σ3Skewness=\frac{E[(x-\mu)^3]}{\sigma^3}
Skewness=σ3E[(x−μ)3]
μ\muμ 是均值
σ\sigmaσ 是标准差
EEE 是期望值
Skewness=0Skewness=0Skewness=0 分布对称
Skewness>0Skewness>0Skewness>0 分布 ...
机器学习—监督学习
前言
监督学习是利用一组已知类别的样本(即已标注的训练数据)来调整分类器(或模型)的参数,使其达到所要求的性能。在监督学习中,每个训练样本都包含一个输入对象(如向量、图像、文本等)和一个期望的输出值(也称为标签或监督信号)。模型通过学习这些输入输出对之间的关系,从而能够对新的、未标注的数据进行预测或分类
监督学习的原理基于模型对输入数据的学习过程。通常一个监督学习算法会使用某种数学模型(如神经网络、决策树、支持向量机等)来拟合训练数据。通过调整模型的参数,使其在训练数据上达到最佳性能(如最小化损失函数),从而能够对新的数据进行准确的预测或分类
统计检验
均值检验(T 检验)
T 检验的原理是通过计算 T 统计量来比较两个样本均值之间的差异是否超出了随机误差范围,从而判断差异是否显著。它基于样本数据,通过计算 T 统计量和对应的P值,来判断两组数据的均值是否存在显著差异
T 检验类型
单一样本:用于检验一个样本的均值是否与一个已知的总体均值存在显著差异
μ=∑nxinxˉ=∑kxiks=∑(xi−xˉ)n−1T=xˉ−μsn\mu=\frac{\sum^n x_i}{n}\\\b ...
机器人轨迹规划
三次多项式插值轨迹
三次多项式
位置表达式
q(t)=k0+k1t+k2t2+k3t3q(t)=k_0+k_1t+k_2t^2+k_3t^3
q(t)=k0+k1t+k2t2+k3t3
速度表达式
q˙(t)=k1+2k2t+3k3t2\dot{q}(t)=k_1+2k_2t+3k_3t^2
q˙(t)=k1+2k2t+3k3t2
加速度表达式
q¨(t)=2k2+6k3t\ddot{q}(t)=2k_2+6k_3t
q¨(t)=2k2+6k3t
其中 k0∼k3k_0\sim k_3k0∼k3 是未知系数
计算
给定起始和结束的位置,速度和轨迹的时间,可以构造出如下几个方程
q(t0)=q0q(t1)=q1q˙(t0)=q˙0q˙(t1)=q˙1t1−t0=Tq(t_0)=q_0\\q(t_1)=q_1\\\dot{q}(t_0)=\dot{q}_0\\\dot{q}(t_1)=\dot{q}_1\\t_1-t_0=T
q(t0)=q0q(t1)=q1q˙(t0)=q˙0q˙(t1)=q˙1t1−t0=T
假设初始时间 t0t_ ...
利用tensorflow.keras搭建神经网络
前言
介绍
在无数深度学习的框架中,Keras 是为人类设计的 API,它提供一致且简单的 API,它将常见用例所需的用户操作数量降至最低,并且在用户错误时提供清晰和可操作的反馈
Keras 与底层深度学习语言(特别是 TensorFlow)集成在一起,所以它可以让用户实现任何可以用基础语言编写的东西
安装
首先是安装 Python,然后安装对应的包即可
1pip install tensorflow
神经网络
神经元模型
神经元模型是组成神经网络的最基本单位,它起初来源于人体,模仿人体的神经元,功能也与人体的神经元一致,得到信号的输入,经过数据处理,然后给出一个结果作为输出或者作为下一个神经元的输入
神经元可以单方向的传输信号,一个神经元有多个树突,只有一个轴突,轴突尾端有多个轴突末梢给其他多个神经元传递信息
一个简化的神经元模型如下,是一个包含输入,输出与计算的模型。输入对应着神经元的树突,计算对应着细胞核,而输出对应着轴突。连接是神经元中最重要的东西,每一个连接上都有一个权重,一个神经网络的训练算法就是让权重的值调整到最佳,以使得整个网络的预测效果最好
123456789101 ...
Spline
Bezier Curves
Lerp
由两个点组成的 Bezier Curve,定义表达式如下
P(t)=(1−t)P0+tP1P(t)=(1-t)P_0+tP_1
P(t)=(1−t)P0+tP1
Quadratic Bezier Curve
由三个点组成的 Bezier Curve。该曲线中,每两个相邻点之间通过 Lerp 连接,得到中间点,而中间点经过 Lerp 处理之后可以得到最终的位置点
P(t)=(1−t)((1−t)P0+tP1)+t((1−t)P1+tP2)P(t)=(1−t)2P0+2t(1−t)P1+t2P2P(t)=(1-t)((1-t)P_0+tP_1)+t((1-t)P_1+tP_2)\\P(t)=(1-t)^2P_0+2t(1-t)P_1+t^2P_2
P(t)=(1−t)((1−t)P0+tP1)+t((1−t)P1+tP2)P(t)=(1−t)2P0+2t(1−t)P1+t2P2
Cubix Bezier Curve
由四个点组成的 Bezier Curve。同上述 Quadratic Bezier Curve 类似,定义表达式如下
P ...
ubuntu上配置ipopt和casadi求解二次规划
前言
二次规划问题是是很多机器人控制器中所涉及到的问题,好的求解方式也非常重要。这里使用 casadi 来实现二次规划的求解
ipopt 安装
安装依赖
由于需要编译 C++,所以需要一些基础的依赖
1234apt-get updateapt-get -y upgradeapt install build-essentialapt-get install -y gcc g++ gfortran git patch wget pkg-config liblapack-dev libmetis-dev libblas-dev vim
下载所需要的代码文件
一共有 5 个比较重要的包
12345git clone https://github.com/coin-or/Ipopt.git # ipoptgit clone https://github.com/coin-or-tools/ThirdParty-ASL.git # ThirdParty-ASLgit clone https://github.com/coin-or-tools/ThirdParty-HSL.git # ThirdP ...
Linux系统配置clash
前言
在 Linux 上进行项目开发时,经常会用到 github 来进行对项目的管理,但是苦于没有好的代理,经过一番查找,找到了 clash,是一个非常好用的代理软件
安装支持
主要是需要用到 curl 工具,所以直接在命令行中输入如下代码即可
1sudo apt-get install curl
安装clash
文件下载: https://zywang.lanzn.com/iPMwp2aneodc
下载完成之后,直接将其解压到 Documents 目录下,保证自己不会误删这个文件
使用clash
使用 ctrl-alt-t 打开终端,然后进入该文件目录中,按照里面的 readme.md 文件做一些配置
在终端输入
1vim .env
使用 vim 修改该配置文件,将其中的 CLASH_URL 修改为自己的订阅地址,并且将 CLASH_SECRET 设置为一个比较简单的就行,例如 123。然后保存退出即可
之后在终端中输入
1sudo bash start.sh
启动程序,然后会出现如下情况,并且会有一些开始使用的提示
然后如果是初次使用的话,需要进行一些基础的配置
在终端中输入如下 ...
clang-tidy配置
前言
介绍
Clang-Tidy 是一个由 LLVM 项目提供的开源静态分析工具,用于进行静态代码分析和代码质量改进。利用 Clang 编译器强大的功能来对 C++ 代码进行静态分析,并且提供一系列代码改进建议和警告
Clang-Tidy 是基于 Clang 的 AST 抽象语法树进行分析的,并且能检测到许多常见的编码错误和代码风格问题,包括语法,逻辑,性能问题和风格问题等
安装
windows
Download LLVM releases
直接从上述网站上找到一个对应的发行版安装即可
然后在命令行中输入如下指令来查看是否安装完成,一般来说安装完成之后需要重新启动一下
1clang-tidy -version
ubuntu
LLVM
根据该文章的内容来安装
安装最新版 LLVM,需要注意,该指令只能在 bash 中使用
1sudo bash -c "$(wget -O - https://apt.llvm.org/llvm.sh)"
安装 Clang-format
1apt-get install clang-18 clang-tools-18 clang-18-d ...
clang-format配置
前言
简介
Clang-format 是一种代码格式化的工具,可以用来格式化各种代码,支持的语言如下
C/C++
Java
JavaScript
Objective-C
Protobuf
C#
Clang-format 的配置文件可以取名为 .clang-format 或者 _clang-format ,该文件被放在项目的根目录下,一般来说 Clang-format 会自己去寻找配置文件的
安装
windows
Download LLVM releases
直接从上述网站上找到一个对应的发行版安装即可
然后在命令行中输入如下指令来查看是否安装完成,一般来说安装完成之后需要重新启动一下
1clang-format -version
ubuntu
LLVM
根据该文章的内容来安装
安装最新版 LLVM,需要注意,该指令只能在 bash 中使用
1sudo bash -c "$(wget -O - https://apt.llvm.org/llvm.sh)"
安装 Clang-format
1apt-get install clang-18 clang-tools-1 ...
STM32CubeMX入门
前言
cubemx是一个可以自动生成代码的单片机学习和使用的软件,非常方便,但同时配置时需要注意芯片以及外设的各个引脚的配置以及使用情况
C语言:内存四区
下载
直接在官网上下载
基础配置 RCC 配置
需要完成的如下
新建工程,选择 MCU 或者 ST 芯片
在右侧查找自己所使用的芯片型号,然后选择对应的芯片
打开 RCC,将始终源设置为外部时钟,有两种即 HSE 和 LSE,即高速外部时钟和低速外部时钟。如果板子上添加有晶振的话一般需要此设置,一般是设置外部高速时钟为谐振器(包括晶振和陶瓷)。
然后配置时钟树
一个需要注意的问题
如果在中文路径下,在生成代码之后,在第一次编译时会有一个报错,就是找不到对应的启动文件,报错的具体内容为 xxx.sct(7): error: L6236E: No section matches selector - no section to be FIRST/LAST.
实际上这个错误就是就是 startup 开头的汇编文件 startup_stm32f407xx.s 没有添加到整个项目中,这个文件是用来启动整个项目的,这个文件可以在该项目地址下 ...
GPIO八种工作模式
前言
简介
GPIO 是通用输入输出端口的简称,可以通过软件控制其输出和输入。stm32 芯片的 GPIO 引脚与外部设备相连来实现与外部的通信,控制以及信息的采集功能
上拉和下拉
当闭合上图中的 VDD 处的开/关时,此时设置为上拉通路导通,这时候如果不接入外设或者电路断开时,整条回路的电压时断路时的电压,也就相当于电阻不存在,这时候中间处的电平被拉高为 VDD 的电平,也就是处于高电平
如果闭合 VSS 处的开关时,也就是打开下拉电阻,这时候没有外部输入的时候,中间点处电压为 VSS
实际上在 stm32 内部的上拉实际上是一个弱上拉,也就是通过上拉电阻的电流很小,如果想要输出一个大电流,就需要外接上拉电阻了,其实就是增加导线的输出电流。而对于下拉电阻,是让 stm32 的 CPU 引脚输出低电平,结果由于后续电路影响输出的低电平达不到 GND。这时候接入下拉电阻是为了降低导线的输出电流。当上下拉电阻都不开启,此时是浮空模式,引脚的电压是不确定的,此模式下的管脚电压会时不时改变
在 stm32 中上下拉以及浮空模式的配置是通过 GPIOx_CRL 和 GPIOx_CRH 寄存器控 ...
IIR滤波器设计
前言
IIR(Infinite Impulse Response)数字滤波器是指无限长冲激响应数字滤波器,因其具有良好的幅频响应特性,被广泛应用于通信、控制、生物医学、振动分析、雷达和声呐等领域
IIR滤波器的设计可以通过设计一个模拟滤波器,进而利用脉冲响应不变法或者双线性变换法来进行数字滤波器的设计。
设计思路
通常利用模拟滤波器的理论和设计方法来设计 IIR 数字滤波器。设计过程是:先根据技术指标要求设计出一个相应的模拟低通滤波器,得到模拟低通滤波器的传递函数 H(s)H(s)H(s) ,然后再按照一定的转换关系将设计好的模拟滤波器的传递函数转换为数字滤波器的系统函数 H(z)H(z)H(z) 。转换方法有两种:脉冲响应不变法和双线性映射法
利用模拟滤波器设计数字滤波器,就是从已知的模拟滤波器传递函数 H(s)H(s)H(s) 设计数字滤波器传递函数 H(z)H(z)H(z) ,这是一个由 s 平面到 z 平面的映射变换,这种映射变换应该遵循两个基本原则
H(z)H(z)H(z) 的频响要能模仿 H(s)H(s)H(s) 的频响,即 s 平面的虚轴应该能映射到 z 平面的单位圆 ...
C语言可变参数的原理及实现
前言
使用过 C 语言的人都会知道 printf 函数,它的参数中有固定参数 format 和可变参数 ... ,那 format 后面的参数个数不确定,类型也不确定,这些参数都存放在栈中。在 format 中在特定的位置指定对应可变参数的类型,也就是根据 format 里的格式依次将数据取出
原理
所有可变参数都存放在栈中。在 format 中在特定的位置指定对应可变参数的类型,也就是根据 format 里的格式依次将数据取出。而取出的动作需要用到 va_arg va_list va_end 这些宏定义,而且取出可变参数的时候,就相当于是指针指向栈中存放数据的位置,然后将指针不断移动来取出数据。
所以就需要对应着可变参数的数量,一定要注意,一旦出现可变参数数量不对应的情况,那就会产生 crash ,主要还是由于参数的数量如果少于使用参数的数量时,就会导致访问栈内存溢出,从而导致 crash
由于参数分为两个部分:固定参数和可变参数,至少需要有一个固定参数,可变参数的数量可以有多个,声明中使用 ... 表示
va_list
1typedef char * va_list;
实际上就是一 ...
AT&T汇编基础语法
前言
参考
x86 Assembly Guide
编译
编译汇编语言可以使用 GNU 编译器 gcc 和 汇编器 as 或者 gas。一个快速了解汇编语言的方式就是去看编译器输出的汇编程序。使用 gcc -S a.c 可以将 C 语言编译为汇编语言,就可以查看对应的汇编语言了。使用 gcc a.s 就可以把对应的的汇编语言编译为可执行文件了。使用 gcc a.s -c 或者 as a.s 可以将汇编语言编译为可重定位目标文件
例如在 C 语言中经典的 hello world 程序
12345#include <stdio.h>int main() { printf("hello, world"); return 0;}
编译为汇编代码为
123456789101112131415161718192021222324252627282930313233343536373839404142434445 .file "a.c" .text .section .rodata.LC0: .string "hel ...
bochs+gdb调试工具链
前言
bochs 中自带一个反汇编器,这只能查看可执行文件的反汇编之后的指令,但是如果书写 C 语言的话,就使得调试非常麻烦(无计可施),所以利用 bochs 来写操作系统还是挺困难的,同时也没有办法查看各个变量的状态和 cpu 的状态。一旦遇到问题就很被动,所以介绍一个 bochs+gdb 的一个调试工具链
bochs安装与配置
安装环境
123sudo apt-get install g++ sudo apt-get install makesudo apt-get install libx11-dev xserver-xorg-dev xorg-dev
安装 bochs
123456wget https://udomain.dl.sourceforge.net/project/bochs/bochs/2.6.8/bochs-2.6.8.tar.gztar zxvf bochs-2.6.8.tar.gzcd bochs-2.6.8/./configure --prefix=/your_path/bochs --enable-gdb-stub --enable-disasm --en ...
gcc内置原子操作
前言
Gcc 4.1.2版本之后,对 X86 或 X86-64 支持内置原子操作。也就是不需要引入第三方库(如pthread)的锁保护,即可对1、2、4、8字节的数值或指针类型,进行原子加/减/与/或/异或等操作
__sync 接口
具体信息查看 Built-in functions for atomic memory access
type __sync_fetch_and_add (type *ptr, type value, ...) 将 value 加到 *ptr 上,并且结果保存在 *ptr 上,返回操作之前的 *ptr 的值
type __sync_fetch_and_sub (type *ptr, type value, ...) 从 *ptr 减去 value ,结果保存到 *ptr ,并返回操作之前 *ptr 的值
type __sync_fetch_and_or (type *ptr, type value, ...) 将 *ptr 与 value 相或操作,结果保存在 *ptr 中,返回操作之前 *ptr 的值
type __sync_fetch_and_and ...
xv6-kernel上
前言
由于 xv6-kernel 的代码是在 qemu+riscv 中进行仿真的,所以首先我们需要安装 qemu 和 riscv 仿真工具链
riscv工具链
下载源码
源码地址为
risc-v
也可以直接使用 git 指令下载
1git clone https://gitcode.com/riscv-collab/riscv-gnu-toolchain/overview
这里直接下载默认分支
下载模块
打开下载的源码目录下,找到名为 .gitmodules 的文件,这里面就是每个子模块的路径和分支。如果没有梯子,就可以根据其对应的名字在 Gitee 上查找对应的模块,然后直接将其下载到 riscv-gnu-toolchain 这个文件夹下,但是对应的模块要下载到对应的文件夹里。不仅如此,还需要下载该模块对应的分支,分支一定不能错。可以使用如下指令
1git clone -b branch_name url module_name
其中 branch_name 是分支名称, url 是下载链接,也就是 Gitee 上对应的模块的仓库地址, module_name 就是需要将这个模块放入 ...
xv6-kernel下
xv6
内核模式的中断处理
当一个进程获得一个 trap 时,会调用 stvec 寄存器中存储的 uservec 然后进入 usertrap 函数,在函数中会进入内核处理状态,并且将内核中断向量 kernelvec 写入到 stvec 寄存器中。所以在内核模式下发生中断的话会进入 kernelvec ,然后进入 kerneltrap 中。处理结束之后再从中退出到主管模式中去。在 usertrapret 中会将 uservec 写入 stvec 寄存器,然后退出用户模式,以此来保证用户模式下发生中断会在用户中断处理中进行处理
kernelvec
这个是在内核模式下发生中断时运行的第一行代码,这里将会保存原先的内核寄存器,然后进入 kerneltrap 函数进行处理中断,然后返回之后重新加载寄存器,回到原来的进程继续处理
123456789101112131415161718192021222324252627.globl kerneltrap.globl kernelvec.align 4kernelvec: # 将栈指针减少 256 个字节,相当于是向下走 256 个字节 ...















