main.cpp 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174
  1. #include <QCoreApplication>
  2. #include "modulecomm.h"
  3. #include "xmlparam.h"
  4. #include "odom.pb.h"
  5. #include "gpsimu.pb.h"
  6. #include <iostream>
  7. #include <memory>
  8. #include "math/gnss_coordinate_convert.h"
  9. #include <cmath>
  10. struct Quaternion {
  11. double w, x, y, z;
  12. };
  13. struct EulerAngles {
  14. double roll, pitch, yaw;
  15. };
  16. EulerAngles ToEulerAngles(Quaternion q) {
  17. EulerAngles angles;
  18. // roll (x-axis rotation)
  19. double sinr_cosp = 2 * (q.w * q.x + q.y * q.z);
  20. double cosr_cosp = 1 - 2 * (q.x * q.x + q.y * q.y);
  21. angles.roll = std::atan2(sinr_cosp, cosr_cosp);
  22. // pitch (y-axis rotation)
  23. double sinp = 2 * (q.w * q.y - q.z * q.x);
  24. if (std::abs(sinp) >= 1)
  25. angles.pitch = std::copysign(M_PI / 2, sinp); // use 90 degrees if out of range
  26. else
  27. angles.pitch = std::asin(sinp);
  28. // yaw (z-axis rotation)
  29. double siny_cosp = 2 * (q.w * q.z + q.x * q.y);
  30. double cosy_cosp = 1 - 2 * (q.y * q.y + q.z * q.z);
  31. angles.yaw = std::atan2(siny_cosp, cosy_cosp);
  32. return angles;
  33. }
  34. Quaternion ToQuaternion(double yaw, double pitch, double roll) // yaw (Z), pitch (Y), roll (X)
  35. {
  36. // Abbreviations for the various angular functions
  37. double cy = cos(yaw * 0.5);
  38. double sy = sin(yaw * 0.5);
  39. double cp = cos(pitch * 0.5);
  40. double sp = sin(pitch * 0.5);
  41. double cr = cos(roll * 0.5);
  42. double sr = sin(roll * 0.5);
  43. Quaternion q;
  44. q.w = cy * cp * cr + sy * sp * sr;
  45. q.x = cy * cp * sr - sy * sp * cr;
  46. q.y = sy * cp * sr + cy * sp * cr;
  47. q.z = sy * cp * cr - cy * sp * sr;
  48. return q;
  49. }
  50. //原文链接:https://blog.csdn.net/xiaoma_bk/article/details/79082629
  51. static double glon0,glat0,gheight0,ghead0;
  52. static void * gpa;
  53. void ListenODOM(const char * strdata,const unsigned int nSize,const unsigned int index,const QDateTime * dt,const char * strmemname)
  54. {
  55. (void)&index;
  56. (void)dt;
  57. (void)strmemname;
  58. iv::ros::odom xodom;
  59. if(xodom.ParseFromArray(strdata,nSize) == false)
  60. {
  61. std::cout<<" ListenODOM Fail. "<<std::endl;
  62. return;
  63. }
  64. std::cout<<" velocity : "<<xodom.twist_linear().x()<<std::endl;
  65. iv::gps::gpsimu xgpsimu;
  66. xgpsimu.set_msgtime(xodom.timestamp() );
  67. xgpsimu.set_speed(xodom.twist_linear().x());
  68. EulerAngles xAng;
  69. Quaternion quat;
  70. quat.x = xodom.pose_orientation().x();
  71. quat.y = xodom.pose_orientation().y();
  72. quat.z = xodom.pose_orientation().z();
  73. quat.w = xodom.pose_orientation().w();
  74. xAng = ToEulerAngles(quat);
  75. double x_o,y_o;
  76. GaussProjCal(glon0,glat0,&x_o,&y_o);
  77. double lon,lat;
  78. double hdg_o = (90 - ghead0)*M_PI/180.0;
  79. double rel_x = xodom.pose_position().x() * cos(hdg_o) - xodom.pose_position().y() * sin(hdg_o);
  80. double rel_y = xodom.pose_position().x() * sin(hdg_o) + xodom.pose_position().y() * cos(hdg_o);
  81. GaussProjInvCal(x_o + rel_x,y_o + rel_y,&lon,&lat);
  82. double hdg_c = hdg_o + xAng.yaw;
  83. hdg_c = M_PI/2.0 - hdg_c;
  84. double heading = hdg_c * 180.0/M_PI;
  85. while(heading < 0)heading = heading + 360;
  86. while(heading >360)heading = heading - 360;
  87. xgpsimu.set_lat(lat);
  88. xgpsimu.set_lon(lon);
  89. xgpsimu.set_height(xodom.pose_position().z() + gheight0);
  90. xgpsimu.set_heading(heading);
  91. xgpsimu.set_pitch(xAng.pitch);
  92. xgpsimu.set_roll(xAng.roll);
  93. double vx,vy;
  94. vx = fabs(xodom.twist_linear().x() *cos(xAng.yaw)
  95. + xodom.twist_linear().y() * sin(xAng.yaw));
  96. vy = fabs(xodom.twist_linear().x() *sin(xAng.yaw)
  97. + xodom.twist_linear().y() * cos(xAng.yaw));
  98. double ve = vx * cos(hdg_o) - vy * sin(hdg_o);
  99. double vn = vx * sin(hdg_o) + vy * cos(hdg_o);
  100. double vd = xodom.twist_linear().z() * (-1);
  101. xgpsimu.set_ve(ve);
  102. xgpsimu.set_vn(vn);
  103. xgpsimu.set_vd(vd);
  104. xgpsimu.set_ins_state(4);
  105. xgpsimu.set_rtk_state(6);
  106. xgpsimu.set_satnum1(1);
  107. xgpsimu.set_satnum2(1);
  108. int nbytesize = xgpsimu.ByteSize();
  109. std::shared_ptr<char> str_ptr = std::shared_ptr<char>(new char[nbytesize]);
  110. if(xgpsimu.SerializeToArray(str_ptr.get(),nbytesize))
  111. {
  112. iv::modulecomm::ModuleSendMsg(gpa,str_ptr.get(),nbytesize);
  113. }
  114. else
  115. {
  116. std::cout<<" ListenODOM Serizlize Error."<<std::endl;
  117. }
  118. }
  119. void GetParam(std::string strpath)
  120. {
  121. iv::xmlparam::Xmlparam xp(strpath);
  122. glon0 = xp.GetParam("lon0",117.3548316);
  123. glat0 = xp.GetParam("lat0",39.0677445);
  124. ghead0 = 360.0;
  125. gheight0 = 0.0;
  126. }
  127. int main(int argc, char *argv[])
  128. {
  129. QCoreApplication a(argc, argv);
  130. GetParam("./driver_odomtogpsimu");
  131. gpa = iv::modulecomm::RegisterSend("hcp2_gpsimu",10000,1);
  132. iv::modulecomm::RegisterRecv("odom_ros",ListenODOM);
  133. return a.exec();
  134. }