geo_pos_conv.cpp 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421
  1. /*
  2. * Copyright 2015-2019 Autoware Foundation. All rights reserved.
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. */
  16. #include <gnss/geo_pos_conv.hpp>
  17. #include <iostream>
  18. #include <cmath>
  19. #include <eigen3/Eigen/Dense>
  20. using namespace Eigen;
  21. using namespace std;
  22. geo_pos_conv::geo_pos_conv()
  23. : m_x(0)
  24. , m_y(0)
  25. , m_z(0)
  26. , m_lat(0)
  27. , m_lon(0)
  28. , m_h(0)
  29. , m_PLato(0)
  30. , m_PLo(0)
  31. {
  32. }
  33. double geo_pos_conv::x() const
  34. {
  35. return m_x;
  36. }
  37. double geo_pos_conv::y() const
  38. {
  39. return m_y;
  40. }
  41. double geo_pos_conv::z() const
  42. {
  43. return m_z;
  44. }
  45. void geo_pos_conv::set_plane(double lat, double lon)
  46. {
  47. m_PLato = lat;
  48. m_PLo = lon;
  49. }
  50. void geo_pos_conv::set_plane(int num)
  51. {
  52. int lon_deg, lon_min, lat_deg, lat_min; // longitude and latitude of origin of each plane in Japan
  53. if (num == 0)
  54. {
  55. lon_deg = 0;
  56. lon_min = 0;
  57. lat_deg = 0;
  58. lat_min = 0;
  59. }
  60. else if (num == 1)
  61. {
  62. lon_deg = 33;
  63. lon_min = 0;
  64. lat_deg = 129;
  65. lat_min = 30;
  66. }
  67. else if (num == 2)
  68. {
  69. lon_deg = 33;
  70. lon_min = 0;
  71. lat_deg = 131;
  72. lat_min = 0;
  73. }
  74. else if (num == 3)
  75. {
  76. lon_deg = 36;
  77. lon_min = 0;
  78. lat_deg = 132;
  79. lat_min = 10;
  80. }
  81. else if (num == 4)
  82. {
  83. lon_deg = 33;
  84. lon_min = 0;
  85. lat_deg = 133;
  86. lat_min = 30;
  87. }
  88. else if (num == 5)
  89. {
  90. lon_deg = 36;
  91. lon_min = 0;
  92. lat_deg = 134;
  93. lat_min = 20;
  94. }
  95. else if (num == 6)
  96. {
  97. lon_deg = 36;
  98. lon_min = 0;
  99. lat_deg = 136;
  100. lat_min = 0;
  101. }
  102. else if (num == 7)
  103. {
  104. lon_deg = 36;
  105. lon_min = 0;
  106. lat_deg = 137;
  107. lat_min = 10;
  108. }
  109. else if (num == 8)
  110. {
  111. lon_deg = 36;
  112. lon_min = 0;
  113. lat_deg = 138;
  114. lat_min = 30;
  115. }
  116. else if (num == 9)
  117. {
  118. lon_deg = 36;
  119. lon_min = 0;
  120. lat_deg = 139;
  121. lat_min = 50;
  122. }
  123. else if (num == 10)
  124. {
  125. lon_deg = 40;
  126. lon_min = 0;
  127. lat_deg = 140;
  128. lat_min = 50;
  129. }
  130. else if (num == 11)
  131. {
  132. lon_deg = 44;
  133. lon_min = 0;
  134. lat_deg = 140;
  135. lat_min = 15;
  136. }
  137. else if (num == 12)
  138. {
  139. lon_deg = 44;
  140. lon_min = 0;
  141. lat_deg = 142;
  142. lat_min = 15;
  143. }
  144. else if (num == 13)
  145. {
  146. lon_deg = 44;
  147. lon_min = 0;
  148. lat_deg = 144;
  149. lat_min = 15;
  150. }
  151. else if (num == 14)
  152. {
  153. lon_deg = 26;
  154. lon_min = 0;
  155. lat_deg = 142;
  156. lat_min = 0;
  157. }
  158. else if (num == 15)
  159. {
  160. lon_deg = 26;
  161. lon_min = 0;
  162. lat_deg = 127;
  163. lat_min = 30;
  164. }
  165. else if (num == 16)
  166. {
  167. lon_deg = 26;
  168. lon_min = 0;
  169. lat_deg = 124;
  170. lat_min = 0;
  171. }
  172. else if (num == 17)
  173. {
  174. lon_deg = 26;
  175. lon_min = 0;
  176. lat_deg = 131;
  177. lat_min = 0;
  178. }
  179. else if (num == 18)
  180. {
  181. lon_deg = 20;
  182. lon_min = 0;
  183. lat_deg = 136;
  184. lat_min = 0;
  185. }
  186. else if (num == 19)
  187. {
  188. lon_deg = 26;
  189. lon_min = 0;
  190. lat_deg = 154;
  191. lat_min = 0;
  192. }
  193. else if (num == 100)
  194. {
  195. // 根据组合导航信息填写
  196. lon_deg = 21; // 请填写纬度的度
  197. lon_min = 33; // 请填写纬度的分
  198. lat_deg = 108; // 请填写经度的度
  199. lat_min = 26; // 请填写经度的分
  200. }
  201. // swap longitude and latitude
  202. m_PLo = M_PI * (static_cast<double>(lat_deg) + static_cast<double>(lat_min) / 60.0) / 180.0;
  203. m_PLato = M_PI * (static_cast<double>(lon_deg) + static_cast<double>(lon_min) / 60.0) / 180;
  204. }
  205. void geo_pos_conv::set_xyz(double cx, double cy, double cz)
  206. {
  207. m_x = cx;
  208. m_y = cy;
  209. m_z = cz;
  210. conv_xyz2llh();
  211. }
  212. void geo_pos_conv::set_llh_nmea_degrees(double latd, double lond, double h)
  213. {
  214. double lat, lad, lod, lon;
  215. // 1234.56 -> 12'34.56 -> 12+ 34.56/60
  216. if (latd > 0)
  217. {
  218. lad = floor(latd / 100.);
  219. }
  220. else
  221. {
  222. lad = ceil(latd / 100.);
  223. }
  224. lat = latd - lad * 100.;
  225. if (lond > 0)
  226. {
  227. lod = floor(lond / 100.);
  228. }
  229. else
  230. {
  231. lod = ceil(lond / 100.);
  232. }
  233. lon = lond - lod * 100.;
  234. // Changing Longitude and Latitude to Radians
  235. m_lat = (lad + lat / 60.0) * M_PI / 180;
  236. m_lon = (lod + lon / 60.0) * M_PI / 180;
  237. m_h = h;
  238. conv_llh2xyz();
  239. }
  240. void geo_pos_conv::llh_to_xyz(double lat, double lon, double ele)
  241. {
  242. m_lat = lat * M_PI / 180;
  243. m_lon = lon * M_PI / 180;
  244. m_h = ele;
  245. conv_llh2xyz();
  246. }
  247. void geo_pos_conv::conv_llh2xyz(void)
  248. {
  249. double PS; //
  250. double PSo; //
  251. double PDL; //
  252. double Pt; //
  253. double PN; //
  254. double PW; //
  255. double PB1, PB2, PB3, PB4, PB5, PB6, PB7, PB8, PB9;
  256. double PA, PB, PC, PD, PE, PF, PG, PH, PI;
  257. double Pe; //
  258. double Pet; //
  259. double Pnn; //
  260. double AW, FW, Pmo;
  261. Pmo = 0.9999;
  262. /*WGS84 Parameters*/
  263. AW = 6378137.0; // Semimajor Axis
  264. FW = 1.0 / 298.257222101; // 298.257223563 //Geometrical flattening
  265. Pe = static_cast<double>(std::sqrt(2.0 * FW - std::pow(FW, 2)));
  266. Pet = static_cast<double>(std::sqrt(std::pow(Pe, 2) / (1.0 - std::pow(Pe, 2))));
  267. PA = static_cast<double>(1.0 + 3.0 / 4.0 * std::pow(Pe, 2) + 45.0 / 64.0 * std::pow(Pe, 4) +
  268. 175.0 / 256.0 * std::pow(Pe, 6) + 11025.0 / 16384.0 * std::pow(Pe, 8) + 43659.0 / 65536.0 *
  269. std::pow(Pe, 10) + 693693.0 / 1048576.0 * std::pow(Pe, 12) + 19324305.0 / 29360128.0 * std::pow(Pe, 14) +
  270. 4927697775.0 / 7516192768.0 * std::pow(Pe, 16));
  271. PB = static_cast<double>(3.0 / 4.0 * std::pow(Pe, 2) + 15.0 / 16.0 * std::pow(Pe, 4) + 525.0 / 512.0 *
  272. std::pow(Pe, 6) + 2205.0 / 2048.0 * std::pow(Pe, 8) + 72765.0 / 65536.0 * std::pow(Pe, 10) + 297297.0 / 262144.0 *
  273. std::pow(Pe, 12) + 135270135.0 / 117440512.0 * std::pow(Pe, 14) + 547521975.0 / 469762048.0 * std::pow(Pe, 16));
  274. PC = static_cast<double>(15.0 / 64.0 * std::pow(Pe, 4) + 105.0 / 256.0 * std::pow(Pe, 6) + 2205.0 / 4096.0 *
  275. std::pow(Pe, 8) + 10395.0 / 16384.0 * std::pow(Pe, 10) + 1486485.0 / 2097152.0 * std::pow(Pe, 12) +
  276. 45090045.0 / 58720256.0 * std::pow(Pe, 14) + 766530765.0 / 939524096.0 * std::pow(Pe, 16));
  277. PD = static_cast<double>(35.0 / 512.0 * std::pow(Pe, 6) + 315.0 / 2048.0 * std::pow(Pe, 8) + 31185.0 / 131072.0 *
  278. std::pow(Pe, 10) + 165165.0 / 524288.0 * std::pow(Pe, 12) + 45090045.0 / 117440512.0 * std::pow(Pe, 14) +
  279. 209053845.0 / 469762048.0 * std::pow(Pe, 16));
  280. PE = static_cast<double>(315.0 / 16384.0 * std::pow(Pe, 8) + 3465.0 / 65536.0 * std::pow(Pe, 10) +
  281. 99099.0 / 1048576.0 * std::pow(Pe, 12) + 4099095.0 / 29360128.0 * std::pow(Pe, 14) + 348423075.0 / 1879048192.0 *
  282. std::pow(Pe, 16));
  283. PF = static_cast<double>(693.0 / 131072.0 * std::pow(Pe, 10) + 9009.0 / 524288.0 * std::pow(Pe, 12) +
  284. 4099095.0 / 117440512.0 * std::pow(Pe, 14) + 26801775.0 / 469762048.0 * std::pow(Pe, 16));
  285. PG = static_cast<double>(3003.0 / 2097152.0 * std::pow(Pe, 12) + 315315.0 / 58720256.0 * std::pow(Pe, 14) +
  286. 11486475.0 / 939524096.0 * std::pow(Pe, 16));
  287. PH = static_cast<double>(45045.0 / 117440512.0 * std::pow(Pe, 14) + 765765.0 / 469762048.0 * std::pow(Pe, 16));
  288. PI = static_cast<double>(765765.0 / 7516192768.0 * std::pow(Pe, 16));
  289. PB1 = static_cast<double>(AW) * (1.0 - std::pow(Pe, 2)) * PA;
  290. PB2 = static_cast<double>(AW) * (1.0 - std::pow(Pe, 2)) * PB / -2.0;
  291. PB3 = static_cast<double>(AW) * (1.0 - std::pow(Pe, 2)) * PC / 4.0;
  292. PB4 = static_cast<double>(AW) * (1.0 - std::pow(Pe, 2)) * PD / -6.0;
  293. PB5 = static_cast<double>(AW) * (1.0 - std::pow(Pe, 2)) * PE / 8.0;
  294. PB6 = static_cast<double>(AW) * (1.0 - std::pow(Pe, 2)) * PF / -10.0;
  295. PB7 = static_cast<double>(AW) * (1.0 - std::pow(Pe, 2)) * PG / 12.0;
  296. PB8 = static_cast<double>(AW) * (1.0 - std::pow(Pe, 2)) * PH / -14.0;
  297. PB9 = static_cast<double>(AW) * (1.0 - std::pow(Pe, 2)) * PI / 16.0;
  298. PS = static_cast<double>(PB1) * m_lat + PB2 * std::sin(2.0 * m_lat) + PB3 * std::sin(4.0 * m_lat) + PB4 *
  299. std::sin(6.0 * m_lat) + PB5 * std::sin(8.0 * m_lat) + PB6 * std::sin(10.0 * m_lat) + PB7 * std::sin(12.0 * m_lat) +
  300. PB8 * std::sin(14.0 * m_lat) + PB9 * std::sin(16.0 * m_lat);
  301. PSo = static_cast<double>(PB1) * m_PLato + PB2 * std::sin(2.0 * m_PLato) + PB3 * std::sin(4.0 * m_PLato) + PB4 *
  302. std::sin(6.0 * m_PLato) + PB5 * std::sin(8.0 * m_PLato) + PB6 * std::sin(10.0 * m_PLato) + PB7 *
  303. std::sin(12.0 * m_PLato) + PB8 * std::sin(14.0 * m_PLato) + PB9 * std::sin(16.0 * m_PLato);
  304. PDL = static_cast<double>(m_lon) - m_PLo;
  305. Pt = static_cast<double>(std::tan(m_lat));
  306. PW = static_cast<double>(std::sqrt(1.0 - std::pow(Pe, 2) * std::pow(std::sin(m_lat), 2)));
  307. PN = static_cast<double>(AW) / PW;
  308. Pnn = static_cast<double>(std::sqrt(std::pow(Pet, 2) * std::pow(std::cos(m_lat), 2)));
  309. m_x = static_cast<double>(((PS - PSo) + (1.0 / 2.0) * PN * std::pow(std::cos(m_lat), 2.0) * Pt * std::pow(PDL, 2.0) +
  310. (1.0 / 24.0) * PN * std::pow(std::cos(m_lat), 4) * Pt *
  311. (5.0 - std::pow(Pt, 2) + 9.0 * std::pow(Pnn, 2) + 4.0 * std::pow(Pnn, 4)) * std::pow(PDL, 4) -
  312. (1.0 / 720.0) * PN * std::pow(std::cos(m_lat), 6) * Pt *
  313. (-61.0 + 58.0 * std::pow(Pt, 2) - std::pow(Pt, 4) - 270.0 * std::pow(Pnn, 2) + 330.0 *
  314. std::pow(Pt, 2) * std::pow(Pnn, 2)) *
  315. std::pow(PDL, 6) - (1.0 / 40320.0) * PN * std::pow(std::cos(m_lat), 8) * Pt *
  316. (-1385.0 + 3111 * std::pow(Pt, 2) - 543 * std::pow(Pt, 4) + std::pow(Pt, 6)) * std::pow(PDL, 8)) * Pmo);
  317. m_y = static_cast<double>((PN * std::cos(m_lat) * PDL -
  318. 1.0 / 6.0 * PN * std::pow(std::cos(m_lat), 3) * (-1 + std::pow(Pt, 2) - std::pow(Pnn, 2)) * std::pow(PDL, 3) -
  319. 1.0 / 120.0 * PN * std::pow(std::cos(m_lat), 5) *
  320. (-5.0 + 18.0 * std::pow(Pt, 2) - std::pow(Pt, 4) - 14.0 * std::pow(Pnn, 2) + 58.0 * std::pow(Pt, 2) *
  321. std::pow(Pnn, 2)) * std::pow(PDL, 5) -
  322. 1.0 / 5040.0 * PN * std::pow(std::cos(m_lat), 7) *
  323. (-61.0 + 479.0 * std::pow(Pt, 2) - 179.0 * std::pow(Pt, 4) + std::pow(Pt, 6)) * std::pow(PDL, 7)) * Pmo);
  324. m_z = m_h;
  325. // float x=((m_x +0.05)*100);
  326. // m_x=(int)x;m_x/=100;
  327. // float y=((m_y+0.05)*100);
  328. // m_y=(int)y;m_y/=100;
  329. // float z=((m_z+0.05)*100);
  330. // m_z=(int)z;m_z/=100;
  331. Matrix3f R;
  332. RowVector3f T;
  333. RowVector3f m_3;
  334. RowVector3f m_4;
  335. m_3 << m_y, m_x, m_z;
  336. //R << -0.99968197,0.02245818,0.01147087,
  337. //-0.02351187, //-0.99451152,-0.10195115,
  338. //0.00911827,-0.10218843,0.99472327;
  339. // R << 1,0,0,0,1,0,0,0,1;
  340. // 1213
  341. R << 0.99951947,0.03044596,0.0058198,-0.0309692,0.98883653,0.14575054,-0.00131732,-0.14586074,0.98930425;
  342. // 1209
  343. // R << 0.99989083,0.01341525,0.00619421,-0.01375076,0.99823686,0.05774151,-0.00540867,-0.05782038,0.99831235;
  344. // R << 0.99296001,0.11836079,0.00459846,-0.11840988,0.99288611,0.01250104,-0.00308611,-0.01295754,0.99991129;
  345. // R << 0.99286137,0.11918958,0.00448735,-0.11923041,0.99281298,0.01031932,-0.00322515,-0.01078068,0.99993669;
  346. // R << 0.99084307,0.13500673,0.00178633,-0.1348253,0.99004595,-0.04038763,-0.00722115,0.03977696,0.99918249;
  347. // R << 0.99078697,0.13415613,-0.01852888,-0.13532921,0.9860102,-0.09731338,0.00521448,0.09892433,0.9950813;
  348. // float x = 3.12909;
  349. // float y = 3.13609;
  350. // // float z = -1.365258;
  351. // float z = -1.365258+3.1415926;
  352. // //std::cout << eulerAngle /* (180 / 3.14) */ << std::endl;
  353. // Eigen::AngleAxisf rollAngle(AngleAxisf(x, Vector3f::UnitX()));
  354. // Eigen::AngleAxisf pitchAngle(AngleAxisf(y, Vector3f::UnitY()));
  355. // Eigen::AngleAxisf yawAngle(AngleAxisf(z, Vector3f::UnitZ()));
  356. // // Eigen::Matrix3d rotation_matrix;
  357. // R = rollAngle * pitchAngle * yawAngle;
  358. // std::cout << R << std::endl;
  359. // T << 493.85435101,1293.37698787,-1140.07271488;
  360. // T << 0,0,0;
  361. // 1213
  362. T << -732.43173303,-1210.60356777,191.86543091;
  363. // 1209
  364. // T << -705.80646672,-1238.00285777,89.81833518;
  365. // T << -834.82725677,-1157.98330612,28.22562205;
  366. // T << -835.96328914,-1157.19952746,25.56658815;
  367. // T << -857.30577788,-1143.1203693,-30.77452311;
  368. // T << -855.39785832,-1139.69844527,-115.14625126;
  369. m_4 = m_3 * R.transpose() + T;
  370. m_x = m_4[1];
  371. m_y = m_4[0];
  372. m_z = m_4[2];
  373. }
  374. void geo_pos_conv::conv_xyz2llh(void)
  375. {
  376. // n/a
  377. }