glvf.m 逐行注释 Wiki (PSINS)¶
配套源码: glvf.m 所属层级: L0基础 前置依赖: 无(这是整个工具箱第一个要读的文件) 学习目标: 读完后你应能回答哪3个问题 1. glv 全局变量结构体里存了哪几大类参数? 2. 为什么单位换算里 deg = π/180 而不是 180/π? 3. 圆锥补偿系数表 cs 的第一行 [2,0,0,0,0]/3 对应什么物理含义?
🧩 函数作用一句话¶
初始化PSINS工具箱全局结构体glv,统一地球参数、单位换算、补偿系数。
📐 数学原理 / 物理意义¶
glvf(Global Variable Function)是整个PSINS工具箱的"参数总入口",它把所有导航解算会反复用到的常量打包成一个叫 glv 的全局结构体,避免每次都手写魔法数字(比如 7.29e-5、6378137 等)。
1. WGS-84 椭球模型¶
地球不是正球而是椭球,WGS-84 定义了三个核心参数: - 长半轴 \(R_e\) = 6378137 m(赤道半径) - 扁率 \(f = (R_e - R_p)/R_e\) = 1/298.257 - 地球自转角速率 \(\omega_{ie}\) = 7.2921151467e-5 rad/s
由此派生出: - 短半轴:\(R_p = (1-f) \cdot R_e\) - 第一偏心率:\(e = \sqrt{2f - f^2}\),描述椭球偏离球体的程度 - 第二偏心率:\(e' = \sqrt{R_e^2 - R_p^2}/R_p\)
2. 单位换算体系¶
惯导里单位极其混乱:角度有度/分/秒/弧度,时间有秒/小时,加速度有g/ mGal/μg,角速度有°/h、°/s、rad/s。glvf 把它们统一成 国际标准单位(SI)下的换算因子。核心规律:
规则:
glv.X表示 "1个X单位 等于多少 SI 单位"。 例如glv.deg = π/180意思是 1° = π/180 rad。
所以如果你手头有个 30°,要转成弧度就写 30 * glv.deg,而不是除法。
3. 圆锥/划船误差补偿系数表¶
捷联惯导里,姿态更新如果用多个角增量子样(subsample),需要做圆锥误差补偿。经典双子样算法的补偿系数是 2/3,三子样是 9/20 和 27/20,以此类推。glv.cs(i,j) 就是 i+1 子样算法下第 j 个子样的权重。
4. 舒勒频率¶
惯导水平回路有一个天然的谐振频率叫舒勒频率,只要设计的惯导回路满足这个频率,车辆加减速就不会引起位置振荡发散:
📝 逐行注释¶
函数声明与版权 (L1-18)¶
| 行号 | 原代码 | 中文注释 | 公式/备注 |
|---|---|---|---|
| 1 | function glv1 = glvf(Re, f, wie) | 定义函数,可选输入地球三参数,返回全局结构体副本 | 也会把 glv 设为 global |
| 2-10 | % PSINS Toolbox global variable... | 函数说明注释 | 原型 glv=glvf(Re,f,wie) |
| 12-14 | % Copyright(c) 2009-2014... | 版权信息,西北工业大学 严恭敏老师 | 最后修改 2014/03/09 |
| 15 | global glv | 将 glv 声明为全局变量 | 其他函数用 global glv 就能读到 |
| 16-18 | if ~exist('Re','var'), Re=[]; end | 三个输入参数如果没传,就设为空矩阵 | 后面统一用默认值填充 |
【第一部分】WGS84 地球基本参数 (L19-31)¶
| 行号 | 原代码 | 中文注释 | 公式/备注 |
|---|---|---|---|
| 19 | if isempty(Re), Re=6378137; end | 默认长半轴 = WGS-84 赤道半径 | \(R_e\) = 6378137 m,记住这个数 |
| 20 | if isempty(f), f=1/298.257; end | 默认扁率 | \(f = 1/298.257223563\),这里简写 |
| 21 | if isempty(wie), wie=7.2921151467e-5; end | 默认地球自转角速率 | \(\omega_{ie}\) ≈ 7.292e-5 rad/s |
| 22 | glv.Re = Re; | 长半轴存入 glv | 单位:m |
| 23 | glv.f = f; | 扁率存入 glv | 无单位 |
| 24 | glv.Rp = (1-glv.f)*glv.Re; | 短半轴(极地半径) | \(R_p = (1-f)R_e\) ≈ 6356752 m |
| 25 | glv.e = sqrt(2*glv.f-glv.f^2); glv.e2 = glv.e^2; | 第一偏心率及其平方 | \(e = \sqrt{2f-f^2}\),\(e^2\) ≈ 0.006694 |
| 26 | glv.ep = sqrt(glv.Re^2-glv.Rp^2)/glv.Rp; glv.ep2 = glv.ep^2; | 第二偏心率及其平方 | \(e' = \sqrt{R_e^2-R_p^2}/R_p\),用于卯酉圈曲率半径公式 |
| 27 | glv.GM = 3.986004418e14; | 地球引力常数×地球质量 | \(GM\) = 3.986e14 m³/s²,开普勒轨道计算用 |
| 28 | glv.J2 = 1.08262982131*10^-3; | 地球重力场二阶带谐系数 | J₂ ≈ 1.0826e-3,地球扁率的引力体现 |
| 29 | glv.J4 = -2.37091120053*10^-6; | 四阶带谐系数 | 高阶重力场修正用 |
| 30 | glv.J6 = 6.08346498882*10^-9; | 六阶带谐系数 | 更高阶修正 |
| 31 | glv.wie = wie; | 地球自转角速率存入 glv | 其他函数读 glv.wie |
【第二部分】常用单位换算 (L33-86,挑 10 个重点讲解,其余同上模式)¶
总体规律:L33-86 全部是 "1个X单位 = glv.X 个 SI 单位" 的换算因子。 SI 标准:角度→rad,时间→s,加速度→m/s²,角速度→rad/s。
| 行号 | 原代码 | 中文注释 | 公式/备注 |
|---|---|---|---|
| 32 | glv.meru = glv.wie/1000; | 毫地球速率单位(meru) | 1 meru = 0.001 ωᵢₑ ≈ 7.29e-8 rad/s |
| 33 | glv.g0 = 9.7803267715; | 赤道海平面重力加速度标准值 | g₀ ≈ 9.78 m/s²(不是 9.81!) |
| 34 | m = Re*glv.wie^2/glv.g0; glv.beta = 5/2*m-f-17/14*m*f; | 计算 Somigliana 重力公式的辅助参数 | m = ω²Rₑ/g₀ ≈ 1/289,β 用于正常重力计算 |
| 35 | glv.beta1 = (5*m*f-f^2)/8; glv.beta2 = 3.086e-6; glv.beta3 = 8.08e-9; | 重力高度改正相关参数 | β₂ = 3.086e-6 m⁻¹s⁻²,高度每升1m重力约减这么多 |
| 36 | glv.mg = 1.0e-3*glv.g0; | 毫g(毫重力加速度单位) | 1 mg = 10⁻³ g₀ ≈ 9.78e-3 m/s² |
| 37 | glv.ug = 1.0e-6*glv.g0; | 微克(加计零偏常用单位) | 1 μg = 10⁻⁶ g₀ ≈ 9.78e-6 m/s² |
| 38 | glv.ugph = glv.ug/3600; | μg每小时(加计随机游走单位) | MEMS加计典型值 ~100 μg/√h |
| 39 | glv.mGal = 1.0e-3*0.01; | 毫伽(重力勘探单位) | 1 mGal = 1 cm/s² ≈ 1.02e-6 g₀ |
| 40 | glv.uGal = glv.mGal/1000; | 微伽 | 1 μGal = 10⁻⁸ m/s² |
| 41-43 | glv.ugpg, glv.ugpg2, glv.ugpg3 | μg/g 的一/二/三次方 | 加计标度因数误差单位 ppm 级别 |
| 44-46 | glv.gs, glv.mgs, glv.ugs | g·秒(速度增量单位) | 速度增量 Δv = 比力 × 时间,1 g·s ≈ 9.78 m/s |
| 47 | glv.ws = 1/sqrt(glv.Re/glv.g0); | 舒勒角频率 | ωₛ = √(g₀/Rₑ) ≈ 1.24e-3 rad/s,T≈84.4min |
| 48 | glv.ppm = 1.0e-6; | 百万分之一(标度因数误差单位) | 1 ppm = 1e-6 |
| 49 | glv.deg = pi/180; | 角度→弧度换算 | 1° = π/180 rad,记死:乘deg! |
| 50 | glv.min = glv.deg/60; | 弧分→弧度 | 1' = (π/180)/60 rad |
| 51 | glv.sec = glv.min/60; | 弧秒→弧度 | 1" ≈ 4.85e-6 rad |
| 52 | glv.mas = glv.sec/1000; | 毫弧秒→弧度 | 光纤陀螺角度随机游走 ~0.001°/√h 级 |
| 53 | glv.hur = 3600; | 1小时=3600秒 | 时间换算:1 hur = 3600 s |
| 54 | glv.dps = pi/180/1; | 度/秒 → rad/s | 1 dps = π/180 rad/s,MEMS陀螺零偏~10dps |
| 55 | glv.mdps = glv.dps/1000; | 毫度/秒 → rad/s | 战术级陀螺 ~1 mdps |
| 56-57 | glv.rps, glv.rpm | 转/秒、转/分 → rad/s | 1 rps = 2π rad/s |
| 58 | glv.dph = glv.deg/glv.hur; | 度/小时 → rad/s(陀螺零偏经典单位) | 1 dph = π/(180×3600) ≈ 4.85e-6 rad/s |
| 59 | glv.pdph = 0.01*glv.dph; | 0.01度/小时 → rad/s | 导航级陀螺 ≤ 0.01 dph |
| 60-61 | glv.dpss, glv.dpsh | 度/√s、度/√h → rad/√Hz 类 | 角度随机游走(ARW)单位 |
| 62 | glv.dphpsh = glv.dph/sqrt(glv.hur); | (°/h)/√h → 角度随机游走 | 1 (°/h)/√h ≈ 2.33e-10 rad/√s |
| 63 | glv.dph2 = glv.dph/glv.hur; | (°/h)/h → 角加速度(陀螺斜坡) | 偏置不稳定性的漂移率 |
| 64-66 | glv.secpg, secpdps2, secprps2 | 弧秒/g、弧秒/(°/s²) 等 | 陀螺 g 灵敏度、角加速度灵敏度 |
| 67 | glv.Hz = 1/1; | 赫兹(采样频率单位基准) | 1 Hz = 1 s⁻¹ |
| 68 | glv.secpsHz = glv.sec/glv.Hz; | 弧秒/√Hz → 角度随机游走 | 数据手册常写 arcsec/√Hz |
| 69 | glv.dphpsHz = glv.dph/glv.Hz; | (°/h)/√Hz → ARW | 注意 dphpsHz 是除以 Hz(= 1/√Hz) |
| 70-71 | glv.dphpg, glv.dphpg2 | (°/h)/g、(°/h)/g² | 陀螺 g 灵敏度(线振动引起零偏) |
| 72 | glv.ugpsHz = glv.ug/sqrt(glv.Hz); | μg/√Hz → 加计速度随机游走 | MEMS加计典型值 ~100 μg/√Hz |
| 73-80 | glv.mpspsh, ugpsh, ugph, ugphpsh, gxs, mpsh, ppmpsh | 各种 √h 随机游走单位 | 同上模式:分子SI化 + 除以 √(3600) |
| 81 | glv.mil = 2*pi/6000; | 密位(军事角度单位) | 1 密位 = 2π/6000 rad |
| 82-83 | glv.mm, glv.um | 毫米、微米 | 1 mm = 1e-3 m,1 μm = 1e-6 m |
| 84 | glv.nm = 1853; | 海里 | 1 海里 = 1853 m(国标1852,这里严老师用1853) |
| 85 | glv.kn = glv.nm/glv.hur; | 节(航海速度单位) | 1 节 = 1海里/小时 ≈ 0.5148 m/s |
| 86 | glv.kmph = 1000/glv.hur; | 公里每小时 → m/s | 1 km/h ≈ 0.2778 m/s |
【第三部分】圆锥补偿系数表 (L88-97)¶
| 行号 | 原代码 | 中文注释 | 公式/备注 |
|---|---|---|---|
| 88 | glv.wm_1=[0,0,0]; glv.vm_1=[0,0,0]; | 上一个陀螺/加计采样角增量、速度增量缓存 | 多子样补偿需要前一次的值 |
| 89 | glv.cs = [ | 圆锥&划船补偿系数表开始 | N子样 → 第N-1行 |
| 90 | [2, 0, 0, 0, 0]/3 | 2子样系数:第一个子样权重 2/3 | 经典双子样补偿 Δθ×Δθ₂ 的系数 = 2/3 |
| 91 | [9, 27, 0, 0, 0]/20 | 3子样系数:[9/20, 27/20, 0, ...] | 三子样算法,两交叉项分别加权 |
| 92 | [54, 92, 214, 0, 0]/105 | 4子样系数 | 精度更高,但需要更多IMU子样 |
| 93 | [250, 525, 650, 1375, 0]/504 | 5子样系数 | |
| 94 | [2315, 4558, 7296, 7834, 15797]/4620 | 6子样系数(最高精度) | 高精度激光陀螺惯导才用得到 |
| 95 | glv.csmax = size(glv.cs,1)+1; | 最大子样数 = 5行+1 = 6子样 | |
| 96 | glv.csCompensate = 1; | 默认开启圆锥补偿 | 设为0则关闭补偿(对比用) |
| 97 | glv.ns = 2; | 默认子样数 = 2(双子样) | 即 cs(1,:) 被使用 |
【第四部分】初始默认位置与导航参数 (L98-110)¶
| 行号 | 原代码 | 中文注释 | 公式/备注 |
|---|---|---|---|
| 98 | glv.v0 = [0;0;0]; | 3×1 零速度向量常值 | 写 zeros(3,1) 太啰嗦 |
| 99 | glv.qI = [1;0;0;0]; | 单位四元数(姿态=零偏差) | q = [cos(θ/2); n·sin(θ/2)],θ=0 时就是 [1;0;0;0] |
| 100 | glv.I33 = eye(3); glv.o33 = zeros(3); | 3×3 单位矩阵、3×3 零矩阵常值 | 提高代码可读性 |
| 101 | % glv.pos0 = [34.246048*glv.deg; 108.909664*glv.deg; 380]; | (已注释)西工大老实验室位置 | 老校区 lat=34.246°, lon=108.910°, h=380m |
| 102 | glv.pos0 = [34.034310*glv.deg; 108.775427*glv.deg; 450]; | 默认初始位置:西工大长安校区 | lat=34.034°, lon=108.775°, h=450m |
| 103 | glv.eth = []; glv.eth = earth(glv.pos0); | 先清空再调用 earth() 计算初始地球参数 | 这是 earth.m 函数的首次出场! |
| 104 | glv.t0 = 0; | 初始仿真时间 = 0 秒 | |
| 105 | glv.tscale = 1; | 时间缩放:1=秒, 60=分, 3600=时 | 画图时用小时作横轴就设 3600 |
| 106 | glv.isfig = 1; | 是否画图:1=画图, 0=不画图 | 批处理仿真时设 0 提速 |
| 107 | glv.gfix = []; glv.dgn = []; | 辅助空结构体(DR/组合导航用) | |
| 108 | %% | 代码分节符(MATLAB中可独立运行此节) | |
| 109 | [glv.rootpath, glv.datapath, glv.mytestflag] = psinsenvi; | 调用 psinsenvi 获取工具箱路径与数据目录 | rootpath = PSINS根目录 |
| 110 | glv1 = glv; | 将全局结构体拷贝一份作为返回值 | 两种用法:glvf(); 或 myglv = glvf(); |
🔍 断点调试建议¶
推荐断点设置:
- 第22行(glv.Re赋值后):观察
Re=6378137,f≈0.00335,wie≈7.292e-5三个核心值是否正确。若你传入了自定义参数,核对是否生效。 - 第47行(舒勒频率):查看
glv.ws ≈ 0.00124rad/s,计算周期 2π/glv.ws ≈ 5065秒 ≈ 84.4分钟,和教科书对得上就对了。 - 第49、54、58行(deg/dps/dph):验证 1° = glv.deg ≈ 0.01745 rad;1 dps ≈ 0.01745 rad/s;1 dph ≈ 4.848e-6 rad/s。再手算 15°/h ≈ wie(地球自转 15.041°/h 左右),glv.wie/glv.dph ≈ 15.041,一致就对了。
- 第90行(cs系数):查看
glv.cs(1,1) = 2/3 ≈ 0.6667,如果glv.ns=2对应glv.cs(1,:),确认glv.csmax=6。 - 第102行(默认位置):
glv.pos0(1)/glv.deg ≈ 34.034°(北纬),pos0(2)/glv.deg ≈ 108.775°(东经),pos0(3)=450(米海拔)。
❌ 初学者最容易踩的坑¶
-
deg 写反:180/π 还是 π/180?
glv.deg = π/180 ≈ 0.01745。很多人直觉 "180度 = π 弧度,所以 1度 = 180/π",完全反了!正确写法:角度数 × glv.deg = 弧度数。如果写反 30° 会被转成 1718 rad ≈ 273 圈,姿态直接飞。 -
单位换算到底是乘还是除? 统一规则:小单位 → 大单位(SI) 时,因子一定 < 1(比如 1° 很小,glv.deg ≈ 0.017 < 1)。所以永远是 "物理量(以X为单位) × glv.X" = SI 单位值。比如 100 μg 零偏 → 写
100 * glv.ug,不要除以。 -
glv.ug 和 glv.mGal 混淆
1 μg = 9.78e-6 m/s²,而1 mGal = 1e-5 m/s² = 1.02 μg。两者量级接近但不相等!重力偏差用 mGal,IMU零偏用 μg,不要混用。 -
默认位置是西工大长安校区,不是你自己的位置! 第102行是西工大经纬度,你在别的城市跑仿真记得改
glv.pos0,否则初始地球参数里的 g、RM、RN、wnie 都错(比如 g 随纬度变,差几千公里能差 0.05 m/s²)。
🎯 配套练习¶
练习1:手算单位换算再 MATLAB 验证¶
题目: 某 MEMS 陀螺指标:零偏稳定性 = 10 °/h,角度随机游走 = 0.5 (°/√h),g灵敏度 = 1 (°/h)/g。 某 MEMS 加计指标:零偏 = 1 mg,速度随机游走 = 100 μg/√Hz。 分别把它们全部转成 SI 单位(rad/s、rad/√s、rad/(s²)、m/s²、m/s²/√Hz)。
步骤: 1. 手算:10 * glv.dph、0.5 * glv.deg / sqrt(3600)、1 * glv.dph / glv.g0、1 * glv.mg、100 * glv.ugpsHz。 2. 开 MATLAB 运行:
glvf();
gyro_bias = 10 * glv.dph
gyro_arw = 0.5 * glv.deg / sqrt(glv.hur) % 注意和 glv.dphpsh 的关系
gyro_g_sens = 1 * glv.dph / glv.g0 % 即 glv.dphpg
acc_bias = 1 * glv.mg
acc_vrw = 100 * glv.ugpsHz
参考答案(数量级): - gyro_bias ≈ 4.848e-5 rad/s - gyro_arw ≈ 1.164e-4 rad/√h = 1.94e-6 rad/√s - gyro_g_sens ≈ 4.957e-7 rad/(s²) ≈ 5e-7 - acc_bias ≈ 9.78e-3 m/s² - acc_vrw ≈ 9.78e-4 m/s²/√Hz