impl_gps.cpp 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348
  1. #include <perception_sf/sensor_gps.h>
  2. #include <decition/gnss_coordinate_convert.h>
  3. #include <control/can.h>
  4. #include <QDebug>
  5. #include <QNetworkDatagram>
  6. static double cast_8_byte_to_double(const uint8_t *b);
  7. static float cast_4_byte_to_float(const uint8_t *b);
  8. static int32_t cast_3_byte_to_int32(const uint8_t *b);
  9. void iv::perception::GPSSensor::processSensor()
  10. {
  11. return;
  12. //todo GPS/惯导 设备接口 对接
  13. /*Initialize udp server, listen on port 3000.*/
  14. /*int sockfd;
  15. struct sockaddr_in addr;
  16. socklen_t addrlen;
  17. sockfd = socket(AF_INET, SOCK_DGRAM, 0);
  18. if (sockfd < 0)
  19. {
  20. printf("socket failed\n");
  21. exit(EXIT_FAILURE);
  22. }
  23. addrlen = sizeof(struct sockaddr_in);
  24. bzero(&addr, addrlen);
  25. addr.sin_family = AF_INET;
  26. addr.sin_addr.s_addr = htonl(INADDR_ANY);
  27. addr.sin_port = htons(3000);
  28. if (bind(sockfd, (struct sockaddr*)(&addr), addrlen) < 0)
  29. {
  30. printf("bind fail\n");
  31. exit(EXIT_FAILURE);
  32. }*/
  33. QUdpSocket *udpsocket;//summer
  34. udpsocket = new QUdpSocket();
  35. udpsocket->bind(QHostAddress::Any, 3000);
  36. // udpsocket->bind(3000);
  37. /* if(!udpsocket->waitForConnected())
  38. {
  39. printf("bind fail\n");
  40. exit(EXIT_FAILURE);
  41. }*/
  42. char *Buf = new char[100] ;//summer unsigned char - char
  43. memset(Buf,0,100);
  44. unsigned char recvBuf[100] = {0};
  45. /*UDP initialization done. Next prepare for receiving data.*/
  46. iv::GPSData data(new iv::GPS_INS);
  47. int x, y, z;
  48. //iv::CarStatus currentCarStatus;
  49. //ODS("\n\n\n------>thread gps: %X\n\n\n\n", GetCurrentThreadId());
  50. while (!boost::this_thread::interruption_requested()) {
  51. int rec = 0;
  52. if(udpsocket->hasPendingDatagrams())
  53. {
  54. // std::cout<<"have data."<<std::endl;
  55. QNetworkDatagram datagram = udpsocket->receiveDatagram();
  56. QByteArray ba = datagram.data();
  57. if(ba.size() != NOUTPUT_PACKET_LENGTH)
  58. {
  59. continue;
  60. }
  61. else
  62. {
  63. rec = NOUTPUT_PACKET_LENGTH;
  64. memcpy(recvBuf,ba.data(),NOUTPUT_PACKET_LENGTH);
  65. }
  66. datagram.clear();
  67. }
  68. else
  69. {
  70. #ifdef Q_OS_LINUX
  71. usleep(1000);
  72. #endif
  73. #ifdef WIN32
  74. boost::this_thread::sleep(boost::posix_time::milliseconds(1));
  75. // Sleep(5);
  76. #endif
  77. continue;
  78. // std::cout<<"running."<<std::endl;
  79. // std::this_thread::sleep_for(std::chrono::milliseconds(1));
  80. }
  81. /* if(udpsocket->waitForReadyRead())
  82. rec = udpsocket->read(Buf,100);
  83. //recvBuf = (unsigned char*)Buf;
  84. convertStrToUnChar(Buf,recvBuf);//summer */
  85. //int rec = recvfrom(sockfd, recvBuf, 100, 0, (struct sockaddr *)(&addr), &addrlen);
  86. /*Check the receiving data*/
  87. //There must be 72 bytes in one package.
  88. if (rec != NOUTPUT_PACKET_LENGTH) {
  89. printf("ERR: rec must be 72 bytes\n");
  90. continue;
  91. }
  92. if (recvBuf[PI_SYNC] != NCOM_SYNC) {
  93. printf("ERR: head always be 0xE7\n");
  94. continue;
  95. }
  96. data->ins_status = recvBuf[PI_INS_NAV_MODE];
  97. if(data->ins_status == 0x0B)continue;
  98. //31.1150882 121.2211320 356.9
  99. //31.1150844 121.2210996 356.9 VV7_3
  100. /* Start decoding
  101. Details in ncomman.pdf
  102. Byte | 0 | 1-20 | 21 | 22 | 23-60 | 61 | 62 | 63-70 | 71
  103. Description | Sync | BatchA | NaviStatus | ChkSum1 | BatchB | ChkSum2 | StatusCh | BatchS | ChkSum3
  104. */
  105. //start decoding -> Batch A
  106. //Time is transmitted as milliseconds into the current GPS minute. The range is 0–59, 999 ms.
  107. /*
  108. Acceleration x is the host object’s acceleration in the x-direction
  109. (i.e.after the IMU to host attitude matrix has been applied).
  110. It is a signed word in units of 1 × 10^(−4) m / (s^2)
  111. */
  112. x = cast_3_byte_to_int32(recvBuf + PI_ACCEL_X);
  113. y = cast_3_byte_to_int32(recvBuf + PI_ACCEL_Y);
  114. z = cast_3_byte_to_int32(recvBuf + PI_ACCEL_Z);
  115. if (x != INV_INT_24) data->accel_x = x * ACC2MPS2;
  116. if (y != INV_INT_24) data->accel_y = y * ACC2MPS2;
  117. if (z != INV_INT_24) data->accel_z = z * ACC2MPS2;
  118. /*
  119. Angular rate x is the host object’s angular rate about its x-axis
  120. (i.e. after the IMU to host attitude matrix has been applied).
  121. It is a signed word in units of 1 × 10−5 radians/s
  122. */
  123. x = cast_3_byte_to_int32(recvBuf + PI_ANG_RATE_X);
  124. y = cast_3_byte_to_int32(recvBuf + PI_ANG_RATE_Y);
  125. z = cast_3_byte_to_int32(recvBuf + PI_ANG_RATE_Z);
  126. if (x != INV_INT_24) data->ang_rate_x = x * (RATE2RPS * RAD2DEG);
  127. if (y != INV_INT_24) data->ang_rate_y = y * (RATE2RPS * RAD2DEG);
  128. if (z != INV_INT_24) data->ang_rate_z = z * (RATE2RPS * RAD2DEG);
  129. /*
  130. The navigation status byte value should be 0–7, 10 or 20–22 to be valid
  131. for customer use. See page 10. A value of 11 indicates the packet
  132. follows NCOM structure-B and should be ignored.
  133. */
  134. data->ins_status = recvBuf[PI_INS_NAV_MODE];
  135. //navi_status refer to imu status 2 3 4.
  136. //check this out in page 11 table 5.
  137. /*
  138. Checksum 1 allows the software to verify the integrity of bytes 1–21.
  139. The sync byte is ignored. In low-latency applications the inertial
  140. measurements in Batch A can be used to update a previous solution
  141. without waiting for the rest of the packet to be received. Contact Oxford
  142. Technical Solutions for source code to perform this function.
  143. */
  144. //31.1150796 121.2211047 355.8
  145. //start decoding Batch B
  146. /*
  147. Position, orientation and velocity output. See Table 6, for a detailed
  148. description.
  149. */
  150. /*Byte23-30. The Latitude of the INS. It is a double in units of radians.*/
  151. /*Byte31-38. Longitude of the INS. It is a double in units of radians.*/
  152. /*Byte39-42. Altitude of the INS. It is a float in units of metres.*/
  153. /*double latitude;
  154. double longitude;
  155. memcpy(&latitude, recvBuf + 23, sizeof(double));
  156. memcpy(&longitude, recvBuf + 31, sizeof(double));
  157. latitude = latitude * 180.0 / M_PI;
  158. longitude = longitude * 180.0 / M_PI;
  159. printf("lat= %.20lf lon= %.20lf | sizeof(float)=%d\n", latitude, longitude, sizeof(float));
  160. */
  161. data->gps_lat = cast_8_byte_to_double(recvBuf + PI_POS_LAT) * RAD2DEG;
  162. data->gps_lng = cast_8_byte_to_double(recvBuf + PI_POS_LON) * RAD2DEG;
  163. data->gps_z = cast_4_byte_to_float(recvBuf + PI_POS_ALT);
  164. /*Byte43-45. Byte46-48. Byte49-51. Velocity in units of 1 × 10^−4 m/s.*/
  165. x = cast_3_byte_to_int32(recvBuf + PI_VEL_N);
  166. y = cast_3_byte_to_int32(recvBuf + PI_VEL_E);
  167. z = cast_3_byte_to_int32(recvBuf + PI_VEL_D);
  168. if (x != INV_INT_24) data->vel_N = x * VEL2MPS;
  169. if (y != INV_INT_24) data->vel_E = y * VEL2MPS;
  170. if (z != INV_INT_24) data->vel_D = z * VEL2MPS;
  171. /*Byte52-54. Heading in units of 1 × 10−6 radians. Range ±pi.*/
  172. /*Byte55-57. Pitch in units of 1 × 10−6 radians. Range ±pi/2.*/
  173. /*Byte58-60. Roll in units of 1 × 10−6 radians. Range ±pi.*/
  174. x = cast_3_byte_to_int32(recvBuf + PI_ORIEN_H);
  175. y = cast_3_byte_to_int32(recvBuf + PI_ORIEN_P);
  176. z = cast_3_byte_to_int32(recvBuf + PI_ORIEN_R);
  177. if (x != INV_INT_24) data->ins_heading_angle = x * (ANG2RAD * RAD2DEG);
  178. if (y != INV_INT_24) data->ins_pitch_angle = y * (ANG2RAD * RAD2DEG);
  179. if (z != INV_INT_24) data->ins_roll_angle = z * (ANG2RAD * RAD2DEG);
  180. #ifdef VV7_2
  181. data->ins_heading_angle = data->ins_heading_angle+1.9;
  182. #endif
  183. #ifdef VV7_3
  184. data->ins_heading_angle = data->ins_heading_angle-1.0;
  185. #endif
  186. if(data->ins_heading_angle>360)data->ins_heading_angle = data->ins_heading_angle-360;
  187. if (data->ins_heading_angle < 0.0)
  188. data->ins_heading_angle += 360.0;
  189. if (recvBuf[PI_CHANNEL_INDEX] == PI_CHANNEL_INDEX) {
  190. data->rtk_status = recvBuf[PI_RTK_STATUS];
  191. data->gps_satelites_num = recvBuf[PI_SAT_NUM];
  192. }
  193. ServiceCarStatus.mRTKStatus = data->rtk_status;
  194. if (data->ins_status != 4) {
  195. data->valid = IMU_STATUS_ERR;
  196. } else if (data->rtk_status != 3 && data->rtk_status != 5 && data->rtk_status != 6) {
  197. data->valid = RTK_STATUS_ERR;
  198. } else {
  199. data->valid = RTK_IMU_OK;
  200. }
  201. GaussProjCal(data->gps_lng, data->gps_lat, &data->gps_x, &data->gps_y);
  202. ////从can中读取当前车速
  203. //data->speed = ServiceCarStatus.speed;
  204. if(data->ins_status != 0x0B)data->speed = sqrt(data->vel_N*data->vel_N + data->vel_E * data->vel_E)*3.6;
  205. else continue;
  206. if(data->gps_lat<0||data->gps_lat>90){
  207. continue;
  208. }
  209. ServiceCarStatus.speed = data->speed;
  210. // qDebug("speed x is %g",ServiceCarStatus.speed);
  211. if(data->ins_status == 4)
  212. signal_gps_data->operator()(data); //传输数据
  213. ServiceCarStatus.location->gps_lat = data->gps_lat;
  214. ServiceCarStatus.location->gps_lng = data->gps_lng;
  215. ServiceCarStatus.location->ins_heading_angle = data->ins_heading_angle;
  216. ServiceCarStatus.location->gps_x = data->gps_x;
  217. ServiceCarStatus.location->gps_y = data->gps_y;
  218. ServiceCarStatus.location->rtk_status = data->rtk_status;
  219. ServiceCarStatus.location->ins_status = data->ins_status;
  220. // std::cout<<"lat = "<<ServiceCarStatus.location->gps_lat<<std::endl;
  221. }
  222. //close(sockfd);
  223. udpsocket->close();
  224. }
  225. static double cast_8_byte_to_double(const uint8_t *b)
  226. {
  227. union { double x; uint8_t c[8]; } u;
  228. u.c[0] = b[0];
  229. u.c[1] = b[1];
  230. u.c[2] = b[2];
  231. u.c[3] = b[3];
  232. u.c[4] = b[4];
  233. u.c[5] = b[5];
  234. u.c[6] = b[6];
  235. u.c[7] = b[7];
  236. return u.x;
  237. }
  238. static float cast_4_byte_to_float(const uint8_t *b)
  239. {
  240. union { float x; uint8_t c[4]; } u;
  241. u.c[0] = b[0];
  242. u.c[1] = b[1];
  243. u.c[2] = b[2];
  244. u.c[3] = b[3];
  245. return u.x;
  246. }
  247. static int32_t cast_3_byte_to_int32(const uint8_t *b)
  248. {
  249. union { int32_t x; uint8_t c[4]; } u;
  250. u.c[1] = b[0];
  251. u.c[2] = b[1];
  252. u.c[3] = b[2];
  253. return u.x >> 8;
  254. }
  255. void iv::perception::GPSSensor::convertStrToUnChar(char* str, unsigned char* UnChar)
  256. {
  257. int i = strlen(str), j = 0, counter = 0;
  258. char c[2];
  259. unsigned int bytes[2];
  260. for (j = 0; j < i; j += 2)
  261. {
  262. if(0 == j % 2)
  263. {
  264. c[0] = str[j];
  265. c[1] = str[j + 1];
  266. sscanf(c, "%02x" , &bytes[0]);
  267. UnChar[counter] = bytes[0];
  268. counter++;
  269. }
  270. }
  271. }
  272. void iv::perception::GPSSensor::UpdateGPSIMU(iv::gps::gpsimu xgpsimu)
  273. {
  274. iv::GPSData data(new iv::GPS_INS);
  275. data->ins_status = xgpsimu.ins_state();
  276. data->rtk_status = xgpsimu.rtk_state();
  277. data->accel_x = xgpsimu.acce_x();
  278. data->accel_y = xgpsimu.acce_y();
  279. data->accel_z = xgpsimu.acce_z();
  280. data->ang_rate_x = xgpsimu.gyro_x();
  281. data->ang_rate_y = xgpsimu.gyro_y();
  282. data->ang_rate_z = xgpsimu.gyro_z();
  283. data->gps_lat = xgpsimu.lat();
  284. data->gps_lng = xgpsimu.lon();
  285. data->gps_z = xgpsimu.height();
  286. data->ins_heading_angle = xgpsimu.heading();
  287. data->ins_pitch_angle = xgpsimu.pitch();
  288. data->ins_roll_angle = xgpsimu.roll();
  289. data->speed = sqrt(pow(xgpsimu.ve(),2)+pow(xgpsimu.vn(),2)) * 3.6;
  290. GaussProjCal(data->gps_lng, data->gps_lat, &data->gps_x, &data->gps_y);
  291. ServiceCarStatus.mRTKStatus = data->rtk_status;
  292. ServiceCarStatus.mfGPSAcc = xgpsimu.acc_calc();
  293. ServiceCarStatus.speed = data->speed;
  294. // qDebug("speed x is %g",ServiceCarStatus.speed);
  295. if(data->ins_status == 4)
  296. {
  297. signal_gps_data->operator()(data); //传输数据
  298. }
  299. ServiceCarStatus.location->gps_lat = data->gps_lat;
  300. ServiceCarStatus.location->gps_lng = data->gps_lng;
  301. ServiceCarStatus.location->ins_heading_angle = data->ins_heading_angle;
  302. ServiceCarStatus.location->gps_x = data->gps_x;
  303. ServiceCarStatus.location->gps_y = data->gps_y;
  304. ServiceCarStatus.location->rtk_status = data->rtk_status;
  305. ServiceCarStatus.location->ins_status = data->ins_status;
  306. }