Sick511FileLaser.cpp 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297
  1. #include "Sick511FileLaser.h"
  2. #include <unistd.h>
  3. RegisterLaser(Sick511File);
  4. CSick511FileLaser::CSick511FileLaser(int id, Automatic::stLaserCalibParam laser_param)
  5. :CLaser(id, laser_param)
  6. ,m_start_read(false)
  7. {
  8. }
  9. CSick511FileLaser::~CSick511FileLaser()
  10. {
  11. if (m_stream_read.is_open())
  12. m_stream_read.close();
  13. }
  14. bool CSick511FileLaser::Connect()
  15. {
  16. std::string ip = m_laser_param.laser_ip();
  17. char file[255] = { 0 };
  18. sprintf(file, "%s/laser%d.data", ip.c_str(), m_id + 1);
  19. if (m_stream_read.is_open())
  20. {
  21. m_stream_read.close();
  22. }
  23. m_stream_read.open(file, ios::in | ios::binary);
  24. if (!m_stream_read.good())
  25. return false;
  26. bool ret= CLaser::Connect();
  27. m_statu = eLaser_ready;
  28. m_file = file;
  29. return ret;
  30. }
  31. void CSick511FileLaser::Disconnect()
  32. {
  33. if(m_stream_read.is_open())
  34. m_stream_read.close();
  35. return CLaser::Disconnect();
  36. }
  37. bool CSick511FileLaser::Start()
  38. {
  39. std::lock_guard<std::mutex> lk(m_mutex);
  40. if (!this->IsReady())
  41. return false;
  42. m_start_read = true;
  43. return CLaser::Start();
  44. }
  45. bool CSick511FileLaser::Stop()
  46. {
  47. std::lock_guard<std::mutex> lk(m_mutex);
  48. m_start_read = false;
  49. return true;
  50. }
  51. DATA_type CSick511FileLaser::Data2PointXYZ(CBinaryData* pData, std::vector<CPoint3D>& points)
  52. {
  53. ////拼接上次未打包数据
  54. DATA_type type = eUnknow;
  55. CBinaryData frame;
  56. if (m_last_data.Length() > 0)
  57. {
  58. if (pData)
  59. frame = m_last_data + (*pData);
  60. else
  61. frame = m_last_data;
  62. m_last_data = CBinaryData();
  63. }
  64. else if(pData)
  65. {
  66. frame = (*pData);
  67. }
  68. else
  69. {
  70. return type;
  71. }
  72. int head = FindHead(frame.Data(), frame.Length());
  73. int tail = FindTail(frame.Data(), frame.Length());
  74. if (tail >= 0)
  75. {
  76. if (tail < frame.Length() - 1) //包尾后还有数据
  77. {
  78. m_last_data = CBinaryData(frame + tail + 1, frame.Length() - tail - 1);
  79. }
  80. if (head >= 0 && head < tail)
  81. {
  82. ////解包
  83. CBinaryData data(frame + head, tail - head + 1);
  84. if (data == "$SLSSTP")
  85. type = eStop;
  86. else if (data == "$SLSSTA")
  87. type = eStart;
  88. else if (data == "$SCLRDY")
  89. type = eReady;
  90. else if (data == "$SHWERR")
  91. type = eHerror;
  92. else if (data == "$N")
  93. type = eData;
  94. if (type == eData)
  95. {
  96. ////解析数据
  97. points.clear();
  98. if (data.Length() <= 29)
  99. return type;
  100. ////解析
  101. unsigned char angle_1 = 0;
  102. unsigned char angle_2 = 0;
  103. memcpy(&angle_1, (data)+26, 1);
  104. memcpy(&angle_2, (data)+27, 1);
  105. float beta_a = float(angle_1 * 256 + angle_2)*0.01;
  106. float start_angle = 0.0;
  107. float freq = 0.0;
  108. std::vector<float> distance;
  109. if (GetData(&data, distance, freq, start_angle))
  110. {
  111. float beta = (beta_a)*DEGREES;
  112. float sin_beta = sin(beta);
  113. float cos_beta = cos(beta);
  114. for (int i = 0; i < distance.size(); ++i)
  115. {
  116. if (distance[i] < 0.001)
  117. continue;
  118. float alpha = (start_angle + i*freq - 90.0) * DEGREES;
  119. float sin_alpha = sin(alpha);
  120. float cos_alpha = cos(alpha);
  121. float x = distance[i] * sin_alpha;
  122. float y = distance[i] * cos_alpha * sin_beta;
  123. float z = distance[i] * cos_alpha * cos_beta;
  124. points.push_back(CPoint3D(x, y, z));
  125. }
  126. //points.push_back(CPoint3D(double(distance.size()), start_angle, freq));
  127. }
  128. }
  129. else if (type == eStop)
  130. {
  131. m_statu = eLaser_ready;
  132. }
  133. }
  134. }
  135. else if (head >= 0)
  136. {
  137. m_last_data = CBinaryData(frame + head, frame.Length() - head);
  138. }
  139. return type;
  140. }
  141. bool CSick511FileLaser::RecvData(CBinaryData& data)
  142. {
  143. if (m_start_read == false)
  144. return false;
  145. if (!m_stream_read.is_open())
  146. return false;
  147. if (m_stream_read.eof())
  148. {
  149. Stop();
  150. m_stream_read.close();
  151. usleep(100*1000);
  152. m_stream_read.open(m_file.c_str(), ios::in | ios::binary);
  153. }
  154. char buf[512] = { 0 };
  155. m_stream_read.read(buf, 512);
  156. int count = m_stream_read.gcount();
  157. if (count > 0)
  158. {
  159. CBinaryData bin_data(buf, count);
  160. data = bin_data;
  161. return true;
  162. }
  163. return false;
  164. }
  165. int CSick511FileLaser::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 CSick511FileLaser::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 CSick511FileLaser::GetData(CBinaryData* pData, std::vector<float>& distance,
  200. float& freq, float& start_angle)
  201. {
  202. struct stData
  203. {
  204. const char* data;
  205. int length;
  206. };
  207. std::vector<struct stData> strDatas;
  208. int start = 0;
  209. int end = 0;
  210. int LMDscandata_index = -1;
  211. for (int i = 0; i < pData->Length(); ++i)
  212. {
  213. if ((*pData)[i] == ' ')
  214. {
  215. end = i;
  216. if (end > start)
  217. {
  218. struct stData strData;
  219. strData.data = (*pData + start);
  220. strData.length = end - start;
  221. strDatas.push_back(strData);
  222. if (strncmp(strData.data, "LMDscandata", 11) == 0)
  223. LMDscandata_index = strDatas.size() - 1;
  224. }
  225. end = i + 1;
  226. start = end;
  227. }
  228. }
  229. if (strDatas.size() > 26 + LMDscandata_index - 1)
  230. {
  231. struct stData start_angle_str = strDatas[23 + LMDscandata_index - 1];
  232. long start_angle_l = Str0x2Long(start_angle_str.data, start_angle_str.length);
  233. start_angle = float(start_angle_l)*0.01;
  234. struct stData freq_str = strDatas[24 + LMDscandata_index - 1];
  235. long freq_l = Str0x2Long(freq_str.data, freq_str.length);
  236. freq = float(freq_l)*0.0001;
  237. struct stData count_str = strDatas[25 + LMDscandata_index - 1];
  238. long count = Str0x2Long(count_str.data, count_str.length);
  239. if (strDatas.size() >= 26 + LMDscandata_index - 1 + count)
  240. {
  241. for (int i = 26 + LMDscandata_index - 1; i < 26 + LMDscandata_index - 1 + count; ++i)
  242. {
  243. float dis = float(Str0x2Long(strDatas[i].data, strDatas[i].length));
  244. distance.push_back(dis);
  245. }
  246. return true;
  247. }
  248. }
  249. return false;
  250. }
  251. long CSick511FileLaser::Str0x2Long(const char* data, int len)
  252. {
  253. long sum = 0;
  254. for (int i = 0; i < len; ++i)
  255. {
  256. char c = data[i];
  257. int n = 0;
  258. if (c >= 48 && c <= 57)
  259. n = c - 48;
  260. else if (c >= 65 && c <= 70)
  261. n = c - 65 + 10;
  262. sum += n*pow(16, len - i - 1);
  263. }
  264. return sum;
  265. }