GPS定位中WGS84转平面坐标,因区域不同导致无法使用。

tech2022-07-08  202

由于采用的是 Japan rectangular coordinate system,所以在其他区域并不准确,于是借此机会重新推导一下高斯投影正算。 先明确一下相关参数及其关系: 长半径: a a a 短半径: b b b 扁率: f = a − b a f={a-b \over a} f=aab 第一偏心率: e = a 2 − b 2 a e={\sqrt{a^2-b^2} \over a} e=aa2b2 第二偏心率: e ′ = a 2 − b 2 b e'={\sqrt{a^2-b^2} \over b} e=ba2b2 第一辅助函数: W = 1 − e 2 s i n 2 B W=\sqrt{1-e^2sin^2B} W=1e2sin2B 第二辅助函数: V = 1 + e ′ 2 c o s 2 B V=\sqrt{1+e'^2cos^2B} V=1+e2cos2B 卯酉圈曲率半径: N = a W = c V N={a \over W} = {c \over V} N=Wa=Vc

下面结合GPS定位的开源代码:

/*WGS84 Parameters*/ //长半径 AW = 6378137.0; //扁率 FW = 1.0 / 298.257222101; //椭球第一偏心率 e Pe = static_cast<double>(std::sqrt(2.0 * FW - std::pow(FW, 2))); //第二偏心率 e' Pet = static_cast<double>(std::sqrt(std::pow(Pe, 2) / (1.0 - std::pow(Pe, 2))));

在这里Pe的形式似乎与上面定义的第一偏心率有所不同,但是经过结合扁率f的化简就可以发现,实质上是一样的,在此就不再详细推导。

接下来是计算子午圈弧长: X = a ( 1 − e 2 ) [ A ′ B 2 − B 1 ρ − B ′ ( s i n 2 B 2 − s i n 2 B 1 ) + C ′ ( s i n 4 B 2 − s i n 4 B 1 ) X=a(1-e^2)[A'{B_2-B_1 \over \rho} - B'(sin2B_2-sin2B_1)+C'(sin4B_2-sin4B_1) X=a(1e2)[AρB2B1B(sin2B2sin2B1)+C(sin4B2sin4B1) − D ′ ( s i n 6 B 2 − s i n 6 B 1 ) + E ′ ( s i n 8 B 2 − s i n 8 B 1 ) − F ′ ( s i n 10 B 2 − s i n B 1 ) + . . . ] -D'(sin6B_2-sin6B_1)+E'(sin8B_2-sin8B_1)-F'(sin10B_2-sinB_1)+...] D(sin6B2sin6B1)+E(sin8B2sin8B1)F(sin10B2sinB1)+...] 其中 ρ = 3600 ∗ 180 / P I \rho = 3600*180/ PI ρ=3600180/PI A ′ = 1 + 3 4 e 2 + 45 64 e 4 + 175 256 e 6 + 11025 16384 e 8 + 43659 65536 e 10 A'=1+{3\over 4}e^2+{45\over 64}e^4+{175\over 256}e^6+{11025\over 16384}e^8+{43659\over 65536}e^{10} A=1+43e2+6445e4+256175e6+1638411025e8+6553643659e10 B ′ = 3 8 e 2 + 15 32 e 4 + 525 1024 e 6 + 2205 4096 e 8 + 72765 131072 e 10 B'={3\over 8}e^2+{15\over 32}e^4+{525\over 1024}e^6+{2205\over 4096}e^8+{72765\over 131072}e^{10} B=83e2+3215e4+1024525e6+40962205e8+13107272765e10 C ′ = 15 256 e 4 + 105 1024 e 6 + 2205 16384 e 8 + 10395 65536 e 10 C'={15\over 256}e^4+{105\over 1024}e^6+{2205\over 16384}e^8+{10395\over 65536}e^{10} C=25615e4+1024105e6+163842205e8+6553610395e10 D ′ = 35 3072 e 6 + 105 4096 e 8 + 10395 262144 e 10 D'={35\over 3072}e^6+{105\over 4096}e^8+{10395\over 262144}e^{10} D=307235e6+4096105e8+26214410395e10 E ′ = 315 131072 e 8 + 3465 524288 e 10 E'={315\over 131072}e^8+{3465\over 524288}e^{10} E=131072315e8+5242883465e10 F ′ = 639 1310720 e 10 F'={639\over 1310720}e^{10} F=1310720639e10

原理相同,精度可能会有所提升。到此计算的到子午圈弧长,其中日本区域划分为19个,因此可在plane=20的情况下,将附近某个点经纬度设置成原点,即 B 1 B_1 B1,其中 B 2 B_2 B2为接收到的经纬度信息。

其中在高斯投影正算中使用卯酉圈曲率半径,但是由于根据不同经纬度查所代表的实际距离并不相同,因此在我理解下,需要改变这个值来使精度更高,对于纬度来说全球相差不多,但是经度相差较高,具体可以通过网站查找你所在区域每1度所代表的实际距离。 参考文章:Autoware 中 GPS 定位问题 - 简书

Length Of A Degree Of LatitudeAnd Longitude Calculator 通过网上查询资料,得到该区域每1经度所代表的实际距离:95285.86。 由于在源码中,经纬度都换算成了弧度制,在这我们也将距离换成经度的每1弧度所代表的实际距离:

ORGIN_POINT_LON_LENGTH = 95285.86/180*M_PI;

同理纬度也是,然后替换原有代码,直接用经纬度差乘上该地区实际距离:

m_x = static_cast<double>((m_lon - lon_org)*ORGIN_POINT_LON_LENGTH); m_y = static_cast<double>((m_lat - lat_org)*ORGIN_POINT_LAT_LENGTH);

最后将原点于初始位置经纬度设置大致相同,建图时需要将此时的原点记录下,因为地图建立在map下,导航时需要将此事的GPS POSE转换到和建图时同一坐标系下,也可以添加World坐标系,通过World->Map的TF和World->Base_link的TF将其关联。

最新回复(0)