casicAgnssAidIni.c 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
  1. #include "luat_base.h"
  2. #include "luat_casic_gnss.h"
  3. #define LUAT_LOG_TAG "casic"
  4. #include "luat_log.h"
  5. /************************************************************
  6. 函数名称:isLeapYear
  7. 函数功能:闰年判断。判断规则:四年一闰,百年不闰,四百年再闰。
  8. 函数输入:year,待判断年份
  9. 函数输出:1, 闰年,0,非闰年(平年)
  10. ************************************************************/
  11. static int isLeapYear(int year)
  12. {
  13. if ((year & 0x3) != 0)
  14. { // 如果year不是4的倍数,一定是平年
  15. return 0;
  16. }
  17. else if ((year % 400) == 0)
  18. { // year是400的倍数
  19. return 1;
  20. }
  21. else if ((year % 100) == 0)
  22. { // year是100的倍数
  23. return 0;
  24. }
  25. else
  26. { // year是4的倍数
  27. return 1;
  28. }
  29. }
  30. /*************************************************************************
  31. 函数名称: gregorian2SvTime
  32. 函数功能: 时间格式转换, 需要考虑UTC跳秒修正
  33. 输入的时间格式是常规的年月日时分秒格式的时间;
  34. 转换后的时间格式是GPS时间格式,用周数和周内时表示,GPS的时间起点是1980.1.6
  35. GPS时间没有闰秒修正,是连续的时间,而常规时间是经过闰秒修正的
  36. 2016年的闰秒修正值是17秒
  37. 函数输入: pDateTime, 结构体指针,年月日时分秒格式的时间
  38. 函数输出: pAidIni, 结构体指针,周数和周内时(或者天数和天内时)时间格式
  39. *************************************************************************/
  40. static void gregorian2SvTime(DATETIME_STR *pDateTime, AID_INI_STR *pAidIni)
  41. {
  42. int DayMonthTable[12] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
  43. int i, dn, wn;
  44. uint64_t tod, tow;
  45. // 天内时间
  46. tod = pDateTime->hour * 3600 + pDateTime->minute * 60 + pDateTime->second;
  47. // 参考时间: 1980.1.6
  48. dn = pDateTime->day;
  49. // 年->天
  50. for (i = 1980; i < (pDateTime->year); i++)
  51. {
  52. if (isLeapYear(i))
  53. {
  54. dn += 366;
  55. }
  56. else
  57. {
  58. dn += 365;
  59. }
  60. }
  61. dn -= 6;
  62. // 月->天
  63. if (isLeapYear(pDateTime->year))
  64. {
  65. DayMonthTable[1] = 29;
  66. }
  67. for (i = 1; i < pDateTime->month; i++)
  68. {
  69. dn += DayMonthTable[i - 1];
  70. }
  71. // 周数+周内时间
  72. wn = (dn / 7); // 周数
  73. tow = (dn % 7) * 86400 + tod + 17; // 周内时间,闰秒修正
  74. if (tow >= 604800)
  75. {
  76. wn++;
  77. tow -= 604800;
  78. }
  79. pAidIni->wn = wn;
  80. pAidIni->tow = tow;
  81. }
  82. /*************************************************************************
  83. 函数名称:casicAgnssAidIni
  84. 函数功能:把辅助位置和辅助时间打包成专用的数据格式。二进制信息格式化,并输出
  85. 函数输入:dateTime,日期与时间,包括有效标志(1有效)
  86. lla, 经纬度标志,包括有效标志(1有效)
  87. 函数输出:aidIniMsg[66],字符数组,辅助信息数据包,长度固定
  88. *************************************************************************/
  89. void casicAgnssAidIni(DATETIME_STR *dateTime, POS_LLA_STR *lla, char aidIniMsg[66])
  90. {
  91. AID_INI_STR aidIni = {0};
  92. int ckSum, i;
  93. int *pDataBuff = (int *)&aidIni;
  94. gregorian2SvTime(dateTime, &aidIni);
  95. LLOGD("date time %d %d %d %d %d %d", dateTime->year, dateTime->month, dateTime->day, dateTime->hour, dateTime->minute, dateTime->second);
  96. LLOGD("lat %7f", lla->lat);
  97. LLOGD("lng %7f", lla->lon);
  98. LLOGD("lls %s, time %s", lla->valid ? "ok" : "no", dateTime->valid ? "ok" : "no");
  99. aidIni.df = 0;
  100. aidIni.xOrLat = lla->lat;
  101. aidIni.yOrLon = lla->lon;
  102. aidIni.zOrAlt = lla->alt;
  103. aidIni.fAcc = 0;
  104. aidIni.posAcc = 0;
  105. aidIni.tAcc = 0;
  106. aidIni.timeSource = 0;
  107. aidIni.flags = 0x20; // 位置格式是LLA格式,高度无效,频率和位置精度估计无效
  108. aidIni.flags = aidIni.flags | ((lla->valid == 1) << 0); // BIT0:位置有效标志
  109. aidIni.flags = aidIni.flags | ((dateTime->valid == 1) << 1); // BIT1:时间有效标志
  110. // 辅助数据打包
  111. ckSum = 0x010B0038;
  112. for (i = 0; i < 14; i++)
  113. {
  114. ckSum += pDataBuff[i];
  115. }
  116. aidIniMsg[0] = 0xBA;
  117. aidIniMsg[1] = 0xCE;
  118. aidIniMsg[2] = 0x38; // LENGTH
  119. aidIniMsg[3] = 0x00;
  120. aidIniMsg[4] = 0x0B; // CLASS ID
  121. aidIniMsg[5] = 0x01; // MESSAGE ID
  122. memcpy(&aidIniMsg[6], (char *)(&aidIni), 56);
  123. memcpy(&aidIniMsg[62], (char *)(&ckSum), 4);
  124. return;
  125. }