UdpLaser.cpp 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322
  1. #include "UdpLaser.h"
  2. #include <stdlib.h>
  3. #include <unistd.h>
  4. RegisterLaser(Udp);
  5. CUdpLaser::CUdpLaser(int id, Automatic::stLaserCalibParam laser_param)
  6. :CLaser(id,laser_param)
  7. {
  8. }
  9. CUdpLaser::~CUdpLaser()
  10. {
  11. }
  12. bool CUdpLaser::Connect()
  13. {
  14. std::string ip = m_laser_param.laser_ip();
  15. int port = m_laser_param.laser_port();
  16. int remoteport = m_laser_param.laser_port_remote();
  17. if (ip == "" || port < 0)
  18. return false;
  19. //初始化Socket
  20. //WSAStartup(MAKEWORD(1, 1), &m_wsd);
  21. //创建Socket对象
  22. m_socket = socket(AF_INET, SOCK_DGRAM, 0);
  23. if (m_socket <= 0)
  24. return false;
  25. struct sockaddr_in sddr_udp;
  26. sddr_udp.sin_family = AF_INET;
  27. sddr_udp.sin_addr.s_addr = htons(INADDR_ANY);
  28. sddr_udp.sin_port = htons(port);
  29. m_send_addr.sin_family = AF_INET;
  30. m_send_addr.sin_addr.s_addr = inet_addr(ip.c_str());
  31. m_send_addr.sin_port = htons(remoteport);
  32. if(-1==bind(m_socket, (struct sockaddr *)&sddr_udp, sizeof(struct sockaddr)))
  33. return false;
  34. return CLaser::Connect();
  35. }
  36. void CUdpLaser::Disconnect()
  37. {
  38. if (m_socket > 0)
  39. {
  40. close(m_socket);
  41. //WSACleanup();
  42. m_socket = -1;
  43. }
  44. return CLaser::Disconnect();
  45. }
  46. bool CUdpLaser::Start()
  47. {
  48. std::lock_guard<std::mutex> lk(m_mutex);
  49. if (!this->IsReady())
  50. return false;
  51. char* sendMsg = "$SLSSTA*0A\r\n";
  52. if (Send(sendMsg, strlen(sendMsg)))
  53. {
  54. m_statu = eLaser_busy;
  55. return CLaser::Start();
  56. }
  57. return false;
  58. }
  59. bool CUdpLaser::Stop()
  60. {
  61. char sendMsg[] = "$SLSSTP*1B\r\n";
  62. std::lock_guard<std::mutex> lk(m_mutex);
  63. if (Send(sendMsg, strlen(sendMsg)))
  64. return true;
  65. return false;
  66. }
  67. DATA_type CUdpLaser::Data2PointXYZ(CBinaryData* pData, std::vector<CPoint3D>& points)
  68. {
  69. ////拼接上次未打包数据
  70. DATA_type type = eUnknow;
  71. CBinaryData frame;
  72. if (m_last_data.Length() > 0)
  73. {
  74. if (pData)
  75. frame = m_last_data + (*pData);
  76. else
  77. frame = m_last_data;
  78. m_last_data = CBinaryData();
  79. }
  80. else if (pData)
  81. {
  82. frame = (*pData);
  83. }
  84. else
  85. {
  86. return type;
  87. }
  88. int head = FindHead(frame.Data(), frame.Length());
  89. int tail = FindTail(frame.Data(), frame.Length());
  90. if (tail >= 0)
  91. {
  92. if (tail < frame.Length() - 1) //包尾后还有数据
  93. {
  94. m_last_data = CBinaryData(frame + tail + 1, frame.Length() - tail - 1);
  95. }
  96. if (head >= 0 && head < tail)
  97. {
  98. ////解包
  99. CBinaryData data(frame + head, tail - head + 1);
  100. if (data == "$SLSSTP")
  101. type = eStop;
  102. else if (data == "$SLSSTA")
  103. type = eStart;
  104. else if (data == "$SCLRDY")
  105. type = eReady;
  106. else if (data == "$SHWERR")
  107. type = eHerror;
  108. else if (data == "$N")
  109. type = eData;
  110. if (type == eData)
  111. {
  112. ////解析数据
  113. points.clear();
  114. if (data.Length() <= 29)
  115. return type;
  116. ////解析
  117. unsigned char angle_1 = 0;
  118. unsigned char angle_2 = 0;
  119. memcpy(&angle_1, (data)+26, 1);
  120. memcpy(&angle_2, (data)+27, 1);
  121. float beta_a = float(angle_1 * 256 + angle_2)*0.01;
  122. float start_angle = 0.0;
  123. float freq = 0.0;
  124. std::vector<float> distance;
  125. if (GetData(&data, distance, freq, start_angle))
  126. {
  127. float beta = (beta_a)*DEGREES;
  128. float sin_beta = sin(beta);
  129. float cos_beta = cos(beta);
  130. for (int i = 0; i < distance.size(); ++i)
  131. {
  132. if (distance[i] < 0.001)
  133. continue;
  134. float alpha = (start_angle + i*freq - 90.0) * DEGREES;
  135. float sin_alpha = sin(alpha);
  136. float cos_alpha = cos(alpha);
  137. float x = distance[i] * sin_alpha;
  138. float y = distance[i] * cos_alpha * sin_beta;
  139. float z = distance[i] * cos_alpha * cos_beta;
  140. points.push_back(CPoint3D(x, y, z));
  141. }
  142. //points.push_back(CPoint3D(double(distance.size()), start_angle, freq));
  143. }
  144. }
  145. }
  146. }
  147. else if (head >= 0)
  148. {
  149. m_last_data = CBinaryData(frame + head, frame.Length() - head);
  150. }
  151. return type;
  152. }
  153. bool CUdpLaser::RecvData(CBinaryData& data)
  154. {
  155. char buf[4096 * 10] = { 0 };
  156. int bytesRead = Recv(buf, 4096);
  157. if (bytesRead > 0)
  158. {
  159. CBinaryData bin_data(buf, bytesRead);
  160. data = bin_data;
  161. return true;
  162. }
  163. return false;
  164. }
  165. int CUdpLaser::FindHead(char* buf, int b_len)
  166. {
  167. int i = 0;
  168. if (b_len < 2)
  169. return NULL;
  170. for (i = 0; i <= b_len; i++)
  171. {
  172. if (b_len > 10)
  173. {
  174. if (buf[i] == '$'&& buf[i + 1] == 'N' && buf[i + 7] == 'S'
  175. &&buf[i + 8] == '5'&&buf[i + 9] == '1'&&buf[i + 10] == '1')
  176. return i;
  177. }
  178. if (b_len >7)
  179. {
  180. if (buf[i] == '$'&& buf[i + 1] == 'S'&&buf[i + 7]=='*')
  181. return i;
  182. }
  183. }
  184. return -1;
  185. }
  186. int CUdpLaser::FindTail(char* buf, int b_len)
  187. {
  188. int i = 0;
  189. for (i = 0; i <= b_len; i++)
  190. {
  191. if (b_len >=i+ 5)
  192. {
  193. if (buf[i] == '*' && buf[i + 3] == '\r'&&buf[i + 4] == '\n')
  194. return i+4;
  195. }
  196. }
  197. return -9999999;
  198. }
  199. bool CUdpLaser::Send(char* sendbuf, int len)
  200. {
  201. int ret = 0;
  202. do
  203. {
  204. ret = sendto(m_socket, sendbuf, strlen(sendbuf), 0, (struct sockaddr*)&m_send_addr, sizeof(struct sockaddr));
  205. } while (ret < 0);
  206. return ret == len;
  207. }
  208. int CUdpLaser::Recv(char* recvbuf, int len)
  209. {
  210. struct sockaddr_in sddr_from;
  211. socklen_t clientLen = sizeof(sddr_from);
  212. int ret = 0;
  213. do
  214. {
  215. ret = recvfrom(m_socket, recvbuf, 4096, 0, (struct sockaddr*)&sddr_from, &clientLen);
  216. } while (ret < 0);
  217. return ret;
  218. }
  219. bool CUdpLaser::GetData(CBinaryData* pData, std::vector<float>& distance,
  220. float& freq, float& start_angle)
  221. {
  222. struct stData
  223. {
  224. const char* data;
  225. int length;
  226. };
  227. std::vector<struct stData> strDatas;
  228. int start = 0;
  229. int end = 0;
  230. int LMDscandata_index = -1;
  231. for (int i = 0; i < pData->Length(); ++i)
  232. {
  233. if ((*pData)[i] == ' ')
  234. {
  235. end = i;
  236. if (end > start)
  237. {
  238. struct stData strData;
  239. strData.data = (*pData + start);
  240. strData.length = end - start;
  241. strDatas.push_back(strData);
  242. if (strncmp(strData.data, "LMDscandata", 11) == 0)
  243. LMDscandata_index = strDatas.size() - 1;
  244. }
  245. end = i + 1;
  246. start = end;
  247. }
  248. }
  249. if (strDatas.size() > 26 + LMDscandata_index - 1)
  250. {
  251. struct stData start_angle_str = strDatas[23 + LMDscandata_index - 1];
  252. long start_angle_l = Str0x2Long(start_angle_str.data, start_angle_str.length);
  253. start_angle = float(start_angle_l)*0.01;
  254. struct stData freq_str = strDatas[24 + LMDscandata_index - 1];
  255. long freq_l = Str0x2Long(freq_str.data, freq_str.length);
  256. freq = float(freq_l)*0.0001;
  257. struct stData count_str = strDatas[25 + LMDscandata_index - 1];
  258. long count = Str0x2Long(count_str.data, count_str.length);
  259. if (strDatas.size() >= 26 + LMDscandata_index - 1 + count)
  260. {
  261. for (int i = 26 + LMDscandata_index - 1; i < 26 + LMDscandata_index - 1 + count; ++i)
  262. {
  263. float dis = float(Str0x2Long(strDatas[i].data, strDatas[i].length));
  264. distance.push_back(dis);
  265. }
  266. return true;
  267. }
  268. }
  269. return false;
  270. }
  271. long CUdpLaser::Str0x2Long(const char* data, int len)
  272. {
  273. long sum = 0;
  274. for (int i = 0; i < len; ++i)
  275. {
  276. char c = data[i];
  277. int n = 0;
  278. if (c >= 48 && c <= 57)
  279. n = c - 48;
  280. else if (c >= 65 && c <= 70)
  281. n = c - 65 + 10;
  282. sum += n*pow(16, len - i - 1);
  283. }
  284. return sum;
  285. }