跳转至

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 个子样的权重。

\[ \Delta\theta_{\text{补偿}} = \sum_{j=1}^{N} c_{N,j} \cdot (\Delta\theta_j \times \Delta\theta_{j+1}) \]

4. 舒勒频率

惯导水平回路有一个天然的谐振频率叫舒勒频率,只要设计的惯导回路满足这个频率,车辆加减速就不会引起位置振荡发散:

\[ \omega_s = \sqrt{\frac{g_0}{R_e}} \approx 1.24 \times 10^{-3} \text{ rad/s} \quad \Rightarrow \quad T_s \approx 84.4 \text{ 分钟} \]

📝 逐行注释

函数声明与版权 (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();

🔍 断点调试建议

推荐断点设置:

  1. 第22行(glv.Re赋值后):观察 Re=6378137f≈0.00335wie≈7.292e-5 三个核心值是否正确。若你传入了自定义参数,核对是否生效。
  2. 第47行(舒勒频率):查看 glv.ws ≈ 0.00124 rad/s,计算周期 2π/glv.ws ≈ 5065秒 ≈ 84.4分钟,和教科书对得上就对了。
  3. 第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,一致就对了。
  4. 第90行(cs系数):查看 glv.cs(1,1) = 2/3 ≈ 0.6667,如果 glv.ns=2 对应 glv.cs(1,:),确认 glv.csmax=6
  5. 第102行(默认位置)glv.pos0(1)/glv.deg ≈ 34.034°(北纬),pos0(2)/glv.deg ≈ 108.775°(东经),pos0(3)=450(米海拔)。

❌ 初学者最容易踩的坑

  1. deg 写反:180/π 还是 π/180? glv.deg = π/180 ≈ 0.01745。很多人直觉 "180度 = π 弧度,所以 1度 = 180/π",完全反了!正确写法:角度数 × glv.deg = 弧度数。如果写反 30° 会被转成 1718 rad ≈ 273 圈,姿态直接飞。

  2. 单位换算到底是乘还是除? 统一规则:小单位 → 大单位(SI) 时,因子一定 < 1(比如 1° 很小,glv.deg ≈ 0.017 < 1)。所以永远是 "物理量(以X为单位) × glv.X" = SI 单位值。比如 100 μg 零偏 → 写 100 * glv.ug,不要除以。

  3. glv.ug 和 glv.mGal 混淆 1 μg = 9.78e-6 m/s²,而 1 mGal = 1e-5 m/s² = 1.02 μg。两者量级接近但不相等!重力偏差用 mGal,IMU零偏用 μg,不要混用。

  4. 默认位置是西工大长安校区,不是你自己的位置! 第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.dph0.5 * glv.deg / sqrt(3600)1 * glv.dph / glv.g01 * glv.mg100 * 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
3. 验收标准:和你手算的差值的相对误差 < 1e-12。

参考答案(数量级): - 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