Sick511FileLaser.cpp 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323
  1. #include "Sick511FileLaser.h"
  2. #include <unistd.h>
  3. RegisterLaser(Sick511File);
  4. CSick511FileLaser::CSick511FileLaser(int id, Laser_proto::laser_parameter laser_param)
  5. :Laser_base(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. //雷达链接设备,为3个线程添加线程执行函数。
  15. Error_manager CSick511FileLaser::connect_laser()
  16. {
  17. std::string ip = m_laser_param.laser_ip();
  18. char file[255] = { 0 };
  19. sprintf(file, "%s/laser%d.data", ip.c_str(), m_laser_id + 1);
  20. if (m_stream_read.is_open())
  21. {
  22. m_stream_read.close();
  23. }
  24. m_stream_read.open(file, ios::in | ios::binary);
  25. if (!m_stream_read.good())
  26. return Error_manager(Error_code::ERROR, Error_level::MINOR_ERROR,
  27. "m_stream_read.open error ");
  28. m_laser_statu = LASER_READY;
  29. m_file = file;
  30. return Laser_base::connect_laser();
  31. }
  32. //雷达断开链接,释放3个线程
  33. Error_manager CSick511FileLaser::disconnect_laser()
  34. {
  35. if(m_stream_read.is_open())
  36. m_stream_read.close();
  37. return Laser_base::disconnect_laser();
  38. }
  39. //对外的接口函数,负责接受并处理任务单,
  40. //input:p_laser_task 雷达任务单,基类的指针,指向子类的实例,(多态)
  41. //注:这个函数为虚函数,实际的处理任务的代码由子类重载并实现。
  42. Error_manager CSick511FileLaser::execute_task(Task_Base* p_laser_task)
  43. {
  44. }
  45. //检查雷达状态,是否正常运行
  46. Error_manager CSick511FileLaser::check_laser()
  47. {
  48. }
  49. //雷达的启动接口函数, 让雷达进行扫描,一般需要子类重载,不同的雷达开始方式不同。
  50. Error_manager CSick511FileLaser::start_scan()
  51. {
  52. std::lock_guard<std::mutex> lk(m_mutex);
  53. if (!this->is_ready())
  54. return Error_manager(Error_code::ERROR, Error_level::MINOR_ERROR,
  55. " is_ready error ");
  56. m_start_read = true;
  57. return Laser_base::start_scan();
  58. }
  59. //雷达的停止接口函数, 让雷达停止扫描,一般需要子类重载,不同的雷达结束方式不同。
  60. Error_manager CSick511FileLaser::stop_scan()
  61. {
  62. std::lock_guard<std::mutex> lk(m_mutex);
  63. m_start_read = false;
  64. return Error_code::SUCCESS;
  65. }
  66. //结束任务单,stop之后,要检查线程状态和数据结果,然后才能 end_task
  67. Error_manager CSick511FileLaser::end_task()
  68. {
  69. }
  70. Buf_type CSick511FileLaser::transform_buf_to_points(Binary_buf* pData, std::vector<CPoint3D>& points)
  71. {
  72. ////ƴ���ϴ�δ�������
  73. Buf_type type = BUF_UNKNOW;
  74. Binary_buf frame;
  75. if (m_last_data.get_length() > 0)
  76. {
  77. if (pData)
  78. frame = m_last_data + (*pData);
  79. else
  80. frame = m_last_data;
  81. m_last_data = Binary_buf();
  82. }
  83. else if(pData)
  84. {
  85. frame = (*pData);
  86. }
  87. else
  88. {
  89. return type;
  90. }
  91. int head = FindHead(frame.get_buf(), frame.get_length());
  92. int tail = FindTail(frame.get_buf(), frame.get_length());
  93. if (tail >= 0)
  94. {
  95. if (tail < frame.get_length() - 1) //���������
  96. {
  97. m_last_data = Binary_buf(frame.get_buf() + tail + 1, frame.get_length() - tail - 1);
  98. }
  99. if (head >= 0 && head < tail)
  100. {
  101. ////���
  102. Binary_buf data(frame.get_buf() + head, tail - head + 1);
  103. if (data.is_equal_front( "$SLSSTP"))
  104. type = BUF_STOP;
  105. else if (data.is_equal_front( "$SLSSTA"))
  106. type = BUF_START;
  107. else if (data.is_equal_front( "$SCLRDY"))
  108. type = BUF_READY;
  109. else if (data.is_equal_front( "$SHWERR"))
  110. type = BUF_ERROR;
  111. else if (data.is_equal_front( "$N"))
  112. type = BUF_DATA;
  113. if (type == BUF_DATA)
  114. {
  115. ////��������
  116. points.clear();
  117. if (data.get_length() <= 29)
  118. return type;
  119. ////����
  120. unsigned char angle_1 = 0;
  121. unsigned char angle_2 = 0;
  122. memcpy(&angle_1, (data.get_buf())+26, 1);
  123. memcpy(&angle_2, (data.get_buf())+27, 1);
  124. float beta_a = float(angle_1 * 256 + angle_2)*0.01;
  125. float start_angle = 0.0;
  126. float freq = 0.0;
  127. std::vector<float> distance;
  128. if (GetData(&data, distance, freq, start_angle))
  129. {
  130. float beta = (beta_a)*DEGREES;
  131. float sin_beta = sin(beta);
  132. float cos_beta = cos(beta);
  133. for (int i = 0; i < distance.size(); ++i)
  134. {
  135. if (distance[i] < 0.001)
  136. continue;
  137. float alpha = (start_angle + i*freq - 90.0) * DEGREES;
  138. float sin_alpha = sin(alpha);
  139. float cos_alpha = cos(alpha);
  140. float x = distance[i] * sin_alpha;
  141. float y = distance[i] * cos_alpha * sin_beta;
  142. float z = distance[i] * cos_alpha * cos_beta;
  143. points.push_back(CPoint3D(x, y, z));
  144. }
  145. //points.push_back(CPoint3D(double(distance.size()), start_angle, freq));
  146. }
  147. }
  148. else if (type == BUF_STOP)
  149. {
  150. m_laser_statu = LASER_READY;
  151. }
  152. }
  153. }
  154. else if (head >= 0)
  155. {
  156. m_last_data = Binary_buf(frame.get_buf() + head, frame.get_length() - head);
  157. }
  158. return type;
  159. }
  160. bool CSick511FileLaser::receive_buf_to_queue(Binary_buf& data)
  161. {
  162. if (m_start_read == false)
  163. return false;
  164. if (!m_stream_read.is_open())
  165. return false;
  166. if (m_stream_read.eof())
  167. {
  168. stop_scan();
  169. m_stream_read.close();
  170. usleep(100*1000);
  171. m_stream_read.open(m_file.c_str(), ios::in | ios::binary);
  172. }
  173. char buf[512] = { 0 };
  174. m_stream_read.read(buf, 512);
  175. int count = m_stream_read.gcount();
  176. if (count > 0)
  177. {
  178. Binary_buf bin_data(buf, count);
  179. data = bin_data;
  180. return true;
  181. }
  182. return false;
  183. }
  184. int CSick511FileLaser::FindHead(char* buf, int b_len)
  185. {
  186. int i = 0;
  187. if (b_len < 2)
  188. return 0;
  189. for (i = 0; i <= b_len; i++)
  190. {
  191. if (b_len > 10)
  192. {
  193. if (buf[i] == '$'&& buf[i + 1] == 'N' && buf[i + 7] == 'S'
  194. &&buf[i + 8] == '5'&&buf[i + 9] == '1'&&buf[i + 10] == '1')
  195. return i;
  196. }
  197. if (b_len > 7)
  198. {
  199. if (buf[i] == '$'&& buf[i + 1] == 'S'&&buf[i + 7] == '*')
  200. return i;
  201. }
  202. }
  203. return -1;
  204. }
  205. int CSick511FileLaser::FindTail(char* buf, int b_len)
  206. {
  207. int i = 0;
  208. for (i = 0; i <= b_len; i++)
  209. {
  210. if (b_len >= i + 5)
  211. {
  212. if (buf[i] == '*' && buf[i + 3] == '\r'&&buf[i + 4] == '\n')
  213. return i + 4;
  214. }
  215. }
  216. return -9999999;
  217. }
  218. bool CSick511FileLaser::GetData(Binary_buf* pData, std::vector<float>& distance,
  219. float& freq, float& start_angle)
  220. {
  221. struct stData
  222. {
  223. const char* data;
  224. int length;
  225. };
  226. std::vector<struct stData> strDatas;
  227. int start = 0;
  228. int end = 0;
  229. int LMDscandata_index = -1;
  230. for (int i = 0; i < pData->get_length(); ++i)
  231. {
  232. if ((*pData)[i] == ' ')
  233. {
  234. end = i;
  235. if (end > start)
  236. {
  237. struct stData strData;
  238. // strData.data = (*pData + start);
  239. strData.data = ( pData->get_buf() + 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 CSick511FileLaser::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. }