TcpLaser.cpp 6.5 KB

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