UdpLaser.cpp 8.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352
  1. #include "UdpLaser.h"
  2. #include <stdlib.h>
  3. #include <unistd.h>
  4. RegisterLaser(Udp);
  5. CUdpLaser::CUdpLaser(int id, Laser_proto::laser_parameter laser_param)
  6. :Laser_base(id,laser_param)
  7. {
  8. }
  9. CUdpLaser::~CUdpLaser()
  10. {
  11. }
  12. //雷达链接设备,为3个线程添加线程执行函数。
  13. Error_manager CUdpLaser::connect_laser()
  14. {
  15. std::string ip = m_laser_param.laser_ip();
  16. int port = m_laser_param.laser_port();
  17. int remoteport = m_laser_param.laser_port_remote();
  18. if (ip == "" || port < 0)
  19. return Error_manager(Error_code::PARAMETER_ERROR, Error_level::MINOR_ERROR,
  20. " m_laser_param PARAMRTER_ERROR ");
  21. //��ʼ��Socket
  22. //WSAStartup(MAKEWORD(1, 1), &m_wsd);
  23. //����Socket����
  24. m_socket = socket(AF_INET, SOCK_DGRAM, 0);
  25. if (m_socket <= 0)
  26. return Error_manager(Error_code::ERROR, Error_level::MINOR_ERROR,
  27. " m_socket PARAMRTER_ERROR ");
  28. struct sockaddr_in sddr_udp;
  29. sddr_udp.sin_family = AF_INET;
  30. sddr_udp.sin_addr.s_addr = htons(INADDR_ANY);
  31. sddr_udp.sin_port = htons(port);
  32. m_send_addr.sin_family = AF_INET;
  33. m_send_addr.sin_addr.s_addr = inet_addr(ip.c_str());
  34. m_send_addr.sin_port = htons(remoteport);
  35. if(-1==bind(m_socket, (struct sockaddr *)&sddr_udp, sizeof(struct sockaddr)))
  36. return Error_manager(Error_code::ERROR, Error_level::MINOR_ERROR,
  37. " bind m_socket ERROR ");
  38. return Laser_base::connect_laser();
  39. }
  40. //雷达断开链接,释放3个线程
  41. Error_manager CUdpLaser::disconnect_laser()
  42. {
  43. if (m_socket > 0)
  44. {
  45. close(m_socket);
  46. //WSACleanup();
  47. m_socket = -1;
  48. }
  49. return Laser_base::disconnect_laser();
  50. }
  51. //对外的接口函数,负责接受并处理任务单,
  52. //input:p_laser_task 雷达任务单,基类的指针,指向子类的实例,(多态)
  53. //注:这个函数为虚函数,实际的处理任务的代码由子类重载并实现。
  54. Error_manager CUdpLaser::execute_task(Task_Base* p_laser_task)
  55. {
  56. }
  57. //检查雷达状态,是否正常运行
  58. Error_manager CUdpLaser::check_laser()
  59. {
  60. }
  61. //雷达的启动接口函数, 让雷达进行扫描,一般需要子类重载,不同的雷达开始方式不同。
  62. Error_manager CUdpLaser::start_scan()
  63. {
  64. std::lock_guard<std::mutex> lk(m_mutex);
  65. if (!this->is_ready())
  66. return Error_manager(Error_code::ERROR, Error_level::MINOR_ERROR,
  67. "is_ready error ");
  68. const char* sendMsg = (char*)"$SLSSTA*0A\r\n";
  69. if (Send(sendMsg, strlen(sendMsg)))
  70. {
  71. m_laser_statu = LASER_BUSY;
  72. return Laser_base::start_scan();
  73. }
  74. return Error_manager(Error_code::ERROR, Error_level::MINOR_ERROR,
  75. " Send error ");
  76. }
  77. //雷达的停止接口函数, 让雷达停止扫描,一般需要子类重载,不同的雷达结束方式不同。
  78. Error_manager CUdpLaser::stop_scan()
  79. {
  80. const char sendMsg[] = "$SLSSTP*1B\r\n";
  81. std::lock_guard<std::mutex> lk(m_mutex);
  82. if (Send(sendMsg, strlen(sendMsg)))
  83. return Error_code::SUCCESS;
  84. return Error_manager(Error_code::ERROR, Error_level::MINOR_ERROR,
  85. " Send error ");
  86. }
  87. //结束任务单,stop之后,要检查线程状态和数据结果,然后才能 end_task
  88. Error_manager CUdpLaser::end_task()
  89. {
  90. }
  91. Buf_type CUdpLaser::transform_buf_to_points(Binary_buf* pData, std::vector<CPoint3D>& points)
  92. {
  93. ////ƴ���ϴ�δ�������
  94. Buf_type type = BUF_UNKNOW;
  95. Binary_buf frame;
  96. if (m_last_data.get_length() > 0)
  97. {
  98. if (pData)
  99. frame = m_last_data + (*pData);
  100. else
  101. frame = m_last_data;
  102. m_last_data = Binary_buf();
  103. }
  104. else if (pData)
  105. {
  106. frame = (*pData);
  107. }
  108. else
  109. {
  110. return type;
  111. }
  112. int head = FindHead(frame.get_buf(), frame.get_length());
  113. int tail = FindTail(frame.get_buf(), frame.get_length());
  114. if (tail >= 0)
  115. {
  116. if (tail < frame.get_length() - 1) //���������
  117. {
  118. m_last_data = Binary_buf(frame.get_buf() + tail + 1, frame.get_length() - tail - 1);
  119. }
  120. if (head >= 0 && head < tail)
  121. {
  122. ////���
  123. Binary_buf data(frame.get_buf() + head, tail - head + 1);
  124. if (data.is_equal_front( "$SLSSTP"))
  125. type = BUF_STOP;
  126. else if (data.is_equal_front( "$SLSSTA"))
  127. type = BUF_START;
  128. else if (data.is_equal_front( "$SCLRDY"))
  129. type = BUF_READY;
  130. else if (data.is_equal_front( "$SHWERR"))
  131. type = BUF_ERROR;
  132. else if (data.is_equal_front( "$N"))
  133. type = BUF_DATA;
  134. if (type == BUF_DATA)
  135. {
  136. ////��������
  137. points.clear();
  138. if (data.get_length() <= 29)
  139. return type;
  140. ////����
  141. unsigned char angle_1 = 0;
  142. unsigned char angle_2 = 0;
  143. memcpy(&angle_1, (data.get_buf())+26, 1);
  144. memcpy(&angle_2, (data.get_buf())+27, 1);
  145. float beta_a = float(angle_1 * 256 + angle_2)*0.01;
  146. float start_angle = 0.0;
  147. float freq = 0.0;
  148. std::vector<float> distance;
  149. if (GetData(&data, distance, freq, start_angle))
  150. {
  151. float beta = (beta_a)*DEGREES;
  152. float sin_beta = sin(beta);
  153. float cos_beta = cos(beta);
  154. for (int i = 0; i < distance.size(); ++i)
  155. {
  156. if (distance[i] < 0.001)
  157. continue;
  158. float alpha = (start_angle + i*freq - 90.0) * DEGREES;
  159. float sin_alpha = sin(alpha);
  160. float cos_alpha = cos(alpha);
  161. float x = distance[i] * sin_alpha;
  162. float y = distance[i] * cos_alpha * sin_beta;
  163. float z = distance[i] * cos_alpha * cos_beta;
  164. points.push_back(CPoint3D(x, y, z));
  165. }
  166. //points.push_back(CPoint3D(double(distance.size()), start_angle, freq));
  167. }
  168. }
  169. }
  170. }
  171. else if (head >= 0)
  172. {
  173. m_last_data = Binary_buf(frame.get_buf() + head, frame.get_length() - head);
  174. }
  175. return type;
  176. }
  177. bool CUdpLaser::receive_buf_to_queue(Binary_buf& data)
  178. {
  179. char buf[4096 * 10] = { 0 };
  180. int bytesRead = Recv(buf, 4096);
  181. if (bytesRead > 0)
  182. {
  183. Binary_buf bin_data(buf, bytesRead);
  184. data = bin_data;
  185. return true;
  186. }
  187. return false;
  188. }
  189. int CUdpLaser::FindHead(char* buf, int b_len)
  190. {
  191. int i = 0;
  192. if (b_len < 2)
  193. return 0;
  194. for (i = 0; i <= b_len; i++)
  195. {
  196. if (b_len > 10)
  197. {
  198. if (buf[i] == '$'&& buf[i + 1] == 'N' && buf[i + 7] == 'S'
  199. &&buf[i + 8] == '5'&&buf[i + 9] == '1'&&buf[i + 10] == '1')
  200. return i;
  201. }
  202. if (b_len >7)
  203. {
  204. if (buf[i] == '$'&& buf[i + 1] == 'S'&&buf[i + 7]=='*')
  205. return i;
  206. }
  207. }
  208. return -1;
  209. }
  210. int CUdpLaser::FindTail(char* buf, int b_len)
  211. {
  212. int i = 0;
  213. for (i = 0; i <= b_len; i++)
  214. {
  215. if (b_len >=i+ 5)
  216. {
  217. if (buf[i] == '*' && buf[i + 3] == '\r'&&buf[i + 4] == '\n')
  218. return i+4;
  219. }
  220. }
  221. return -9999999;
  222. }
  223. bool CUdpLaser::Send(const char* sendbuf, int len)
  224. {
  225. int ret = 0;
  226. do
  227. {
  228. ret = sendto(m_socket, sendbuf, strlen(sendbuf), 0, (struct sockaddr*)&m_send_addr, sizeof(struct sockaddr));
  229. } while (ret < 0);
  230. return ret == len;
  231. }
  232. int CUdpLaser::Recv(char* recvbuf, int len)
  233. {
  234. struct sockaddr_in sddr_from;
  235. socklen_t clientLen = sizeof(sddr_from);
  236. int ret = 0;
  237. do
  238. {
  239. ret = recvfrom(m_socket, recvbuf, 4096, 0, (struct sockaddr*)&sddr_from, &clientLen);
  240. } while (ret < 0);
  241. return ret;
  242. }
  243. bool CUdpLaser::GetData(Binary_buf* pData, std::vector<float>& distance,
  244. float& freq, float& start_angle)
  245. {
  246. struct stData
  247. {
  248. const char* data;
  249. int length;
  250. };
  251. std::vector<struct stData> strDatas;
  252. int start = 0;
  253. int end = 0;
  254. int LMDscandata_index = -1;
  255. for (int i = 0; i < pData->get_length(); ++i)
  256. {
  257. if ((*pData)[i] == ' ')
  258. {
  259. end = i;
  260. if (end > start)
  261. {
  262. struct stData strData;
  263. // strData.data = (*pData + start);
  264. strData.data = (pData->get_buf() + start);
  265. strData.length = end - start;
  266. strDatas.push_back(strData);
  267. if (strncmp(strData.data, "LMDscandata", 11) == 0)
  268. LMDscandata_index = strDatas.size() - 1;
  269. }
  270. end = i + 1;
  271. start = end;
  272. }
  273. }
  274. if (strDatas.size() > 26 + LMDscandata_index - 1)
  275. {
  276. struct stData start_angle_str = strDatas[23 + LMDscandata_index - 1];
  277. long start_angle_l = Str0x2Long(start_angle_str.data, start_angle_str.length);
  278. start_angle = float(start_angle_l)*0.01;
  279. struct stData freq_str = strDatas[24 + LMDscandata_index - 1];
  280. long freq_l = Str0x2Long(freq_str.data, freq_str.length);
  281. freq = float(freq_l)*0.0001;
  282. struct stData count_str = strDatas[25 + LMDscandata_index - 1];
  283. long count = Str0x2Long(count_str.data, count_str.length);
  284. if (strDatas.size() >= 26 + LMDscandata_index - 1 + count)
  285. {
  286. for (int i = 26 + LMDscandata_index - 1; i < 26 + LMDscandata_index - 1 + count; ++i)
  287. {
  288. float dis = float(Str0x2Long(strDatas[i].data, strDatas[i].length));
  289. distance.push_back(dis);
  290. }
  291. return true;
  292. }
  293. }
  294. return false;
  295. }
  296. long CUdpLaser::Str0x2Long(const char* data, int len)
  297. {
  298. long sum = 0;
  299. for (int i = 0; i < len; ++i)
  300. {
  301. char c = data[i];
  302. int n = 0;
  303. if (c >= 48 && c <= 57)
  304. n = c - 48;
  305. else if (c >= 65 && c <= 70)
  306. n = c - 65 + 10;
  307. sum += n*pow(16, len - i - 1);
  308. }
  309. return sum;
  310. }