data_engine.cpp
Go to the documentation of this file.
1 #include "data_engine.h"
2 #include <iostream>
3 
4 using namespace std;
5 
6 typedef unsigned char uchar;
7 
8 bool send_success = false;
9 bool reply_success = false;
10 
11 // initialization: connect socket.
13 {
14  sockClient = socket(AF_INET, SOCK_STREAM, 0);
15  struct sockaddr_in serveraddr;
16  bzero(&serveraddr, sizeof(serveraddr));
17  serveraddr.sin_family = AF_INET;
18  serveraddr.sin_port = htons(PORT);
19  inet_pton(AF_INET, server_ip, &serveraddr.sin_addr);
20 
21  printf("connecting server...");
22  if(connect(sockClient, (struct sockaddr*)&serveraddr, sizeof(serveraddr)) == -1)
23  {
24  printf("failed.\n");
25  return false;
26  }
27  printf("connected.\n");
28 
29  return true;
30 }
31 //*/
32 
33 // send thread
34 void socketSendThread(int sockClient, char* data, int data_lengh)
35 {
36  cerr<<"command message "<<data<<endl;
37  int rtn_num = send(sockClient, data, data_lengh, 0);
38  cerr << "socket_send_thread: send command to server ... ";
39  send_success = true;
40  sleep(1);
41  while (!reply_success)
42  {
43  cerr<<"command message "<<data<<endl;
44  int rtn_num = send(sockClient, data, data_lengh, 0);
45  cerr << "socket_send_thread: send command to server ... ";
46  sleep(1);
47  }
48  return;
49 }
50 
51 // stop a connection thread
52 void stopThread(int sockClient)
53 {
54  // send command
55  char sendData[1];
56  sendData[0] = 'e';
57  //send(sockClient, sendData, 1, 0); // send command
58  thread send_task(socketSendThread, sockClient, sendData, 1); // send command
59  send_task.detach(); // execute the thread
60 }
61 
62 // get rgbd
64 {
65 
66 // test
67  sleep(0.1);
68  stopThread(sockClient);
69  create_connection();
70 
71 getRGBDFromGazebo_begin:
72  cerr << "getting rgbd data..." << endl;
73  // command: ask for rgbd data
74  char sendData[1];
75  sendData[0] = '3';
76  //send(sockClient, sendData, 1, 0); // send command
77  send_success = false;
78  reply_success = false;
79  thread send_task(socketSendThread, sockClient, sendData, 1); // send command
80  send_task.detach();
81  while(!send_success) sleep(0.1);
82  // recive data
83  // rgb
84  {
85  // rcv package
86  int data_len = (480 * 640 * 3 * (sizeof(uchar)) * rbt_num);
87  char* rcvData = new char[data_len];
88  int n = 0;
89  int count = 0;
90  char pkgData[MAXRECV];
91  n = 0;
92  count = 0;
93  while (1)
94  {
95  // break point
96  if (count == data_len) // 2018-07-26
97  break; // 2018-07-26
98 
99  // for last package
100  if (count + MAXRECV >= data_len) // next package is the last package
101  {
102  n = recv(sockClient, pkgData, data_len - count, 0); // recive #(data_len - count) data
103  //cout<<"last packeg len "<<n<<endl;
104  int rst = n;
105  while (rst < data_len - count){
106  memcpy(&rcvData[count], &pkgData, rst);
107  count += rst;
108  //rst = data_len - count;
109  //rst = recv(sockClient, pkgData, rst, 0); // recive #(data_len - count) data
110  rst = recv(sockClient, pkgData, data_len - count, 0); // recive #(data_len - count) data, 2018-07-26
111  }
112  // rst >= data_len - count
113  if (rst > data_len - count)
114  {
115  cout << "error: recieve more than data_len." << endl;
116  //getchar();
117  memcpy(&rcvData[count], &pkgData, data_len - count);
118  count += rst;
119  break;
120  }
121  memcpy(&rcvData[count], &pkgData, rst);
122  count += rst;
123  break;
124  }
125 
126  // recv
127  n = recv(sockClient, pkgData, MAXRECV, 0);
128  //cout<<"recved "<< n <<" byte"<<endl;
129  if (n>0) reply_success = true;
130 
131  // check for errors
132  if (n <= 0)
133  {
134  cout << "n = " << n << ", data_len = " << data_len << ", count = " << count << endl;
135  if (n == -1)
136  {
137  //int err = errno;
138  //cout << "error code: " << err << endl; // err: 10060
139  delete [] rcvData;
140  // reset connection
141  stopThread(sockClient);
142  create_connection();
143  goto getRGBDFromGazebo_begin;
144  }
145  break;
146  }
147  else
148  {
149  if (n == -1) // test 2018-09-10
150  {
151  cout << "before memcpy..." << endl;
152  //getchar();
153  }
154  memcpy(&rcvData[count], &pkgData, n); // error? most time works well, sometimes results in access vialation reading location. 2018-09-10 update: access vialation reading location because of n == -1.
155  count += n;
156  if (n == -1) // test 2018-09-10
157  {
158  cout << "after memcpy, count = " << count << ", n = " << n << endl;
159  //getchar();
160  }
161  }
162  }
163  //cout<<"successfully recved rgb package."<<endl;
164 
165  // convert package data to rgb images
166  int ind = 0;
167  for (int id = 0; id < rbt_num; id++)
168  {
169  for (int i = 0; i < 480; i++)
170  {
171  for (int j = 0; j < 640; j++)
172  {
173  memcpy(&m_rgb[id].ptr<cv::Vec3b>(i)[j][2], &rcvData[ind], sizeof(uchar));
174  ind += sizeof(uchar);
175  memcpy(&m_rgb[id].ptr<cv::Vec3b>(i)[j][1], &rcvData[ind], sizeof(uchar));
176  ind += sizeof(uchar);
177  memcpy(&m_rgb[id].ptr<cv::Vec3b>(i)[j][0], &rcvData[ind], sizeof(uchar));
178  ind += sizeof(uchar);
179  }
180  }
181  }
182  delete [] rcvData;
183  }
184 
185  // depth
186  {
187  // rcv package
188  int data_len = (480 * 640 * (sizeof(short)) * rbt_num);
189  char* rcvData = new char[data_len];
190  int n = 0;
191  int count = 0;
192  char pkgData[MAXRECV];
193  n = 0;
194  count = 0;
195  while (1){
196  if (count + MAXRECV >= data_len){
197  n = recv(sockClient, pkgData, data_len - count, 0);
198  int rst = n;
199  while (rst < data_len - count){
200  memcpy(&rcvData[count], &pkgData, rst);
201  count += rst;
202  rst = data_len - count;
203  rst = recv(sockClient, pkgData, rst, 0);
204  }
205  memcpy(&rcvData[count], &pkgData, rst);
206  count += rst;
207  break;
208  }
209  n = recv(sockClient, pkgData, MAXRECV, 0);
210  memcpy(&rcvData[count], &pkgData, n);
211  count += n;
212  }
213  // cpy to depth
214  int ind = 0;
215  for (int id = 0; id < rbt_num; id++)
216  {
217  for (int i = 0; i < 480; i++)
218  {
219  for (int j = 0; j < 640; j++)
220  {
221  memcpy(&m_depth[id].ptr<ushort>(i)[j], &rcvData[ind], sizeof(short));
222  ind += sizeof(short);
223  }
224  }
225  }
226  delete [] rcvData;
227  }
228 
229 /*
230  // test show img
231  for (int id = 0; id < rbt_num; id++)
232  {
233  cv::imshow("get rgb", m_rgb[id]);
234  cv::imshow("get depth", m_depth[id]);
235  cv::waitKey(0);
236  }
237 //*/
238 
239  cerr << "done." << endl;
240  return true;
241 }
242 
243 // get pose
245 {
246  // set up: rcv data
247  int data_len = (7 * sizeof(float) * rbt_num);
248  char* rcvData = new char[data_len];
249  char pkgData[MAXRECV];
250 
251 // test
252  sleep(0.1);
253  stopThread(sockClient);
254  create_connection();
255 
256 getPoseFromLinux_begin:
257 
258  cerr << "getting pose data ... " << endl;
259 
260  // command: ask for pose data
261  char sendData[1];
262  sendData[0] = '1';
263  //send(sockClient, sendData, 1, 0); // send command
264  send_success = false;
265  reply_success = false;
266  thread send_task(socketSendThread, sockClient, sendData, 1); // send command
267  send_task.detach(); // execute the thread
268  while(!send_success) sleep(0.1);
269  int n = 0; // recv return code
270  int count = 0; // recved data length
271  // start to recv data
272  while (1)
273  {
274  // the last package
275  if (count + MAXRECV >= data_len)
276  {
277  n = recv(sockClient, pkgData, data_len - count, 0);
278  //cout << "the last pkg: data_len - count: " << data_len - count << ", n: " << n << endl;
279  if (n>0) reply_success = true;
280  if (n < 0)
281  {
282  if (count == data_len) // finish transfer
283  break;
284  cout << "count = " << count << endl;
285  cerr << "recv return < 0, input to retry..." << endl;
286  //int err = WSAGetLastError();
287  //cout << "error code: " << err << endl; // err: 10060
288  // reset connection
289  stopThread(sockClient);
290  create_connection();
291  goto getPoseFromLinux_begin;
292  }
293  int rst = n;
294  while (rst < data_len - count){
295  memcpy(&rcvData[count], &pkgData, rst);
296  count += rst;
297  rst = data_len - count;
298  rst = recv(sockClient, pkgData, rst, 0);
299  }
300  memcpy(&rcvData[count], &pkgData, rst);
301  count += rst;
302  break;
303  }
304  // packages before the last package. recv #MAXRECV data, record into rcvData.
305  n = recv(sockClient, pkgData, MAXRECV, 0);
306  memcpy(&rcvData[count], &pkgData, n);
307  count += n;
308  }
309  // cpy to pose
310  int ind = 0;
311  for (int id = 0; id < rbt_num; id++)
312  {
313  for (int i = 0; i < 7; i++)
314  {
315  memcpy(&m_pose[id][i], &rcvData[ind], sizeof(float));
316  ind += sizeof(float);
317  }
318  }
319  // test
320  for (int rid = 0; rid < rbt_num; rid++)
321  {
322  cerr<<"pose "<<rid<<":"<<endl;
323  for (int vid = 0; vid < 7; ++vid)
324  {
325  cerr<<m_pose[rid][vid]<<" ";
326  }
327  cerr<<endl;
328  if (m_pose[rid][3]==m_pose[rid][4]&&m_pose[rid][4]==m_pose[rid][5]&&m_pose[rid][5]==m_pose[rid][6])
329  {
330  cerr<<m_pose[rid][0]<<" "<<m_pose[rid][1]<<" "<<m_pose[rid][2]<<" "<<m_pose[rid][3]<<" "<<m_pose[rid][4]<<" "<<m_pose[rid][5]<<" "<<m_pose[rid][6]<<" "<<endl;
331  //getchar();getchar();getchar();
332  stopThread(sockClient);
333  create_connection();
334  goto getPoseFromLinux_begin;
335  }
336  if (__isnan(m_pose[rid][0]))
337  {
338  cerr<<m_pose[rid][0]<<" "<<m_pose[rid][1]<<" "<<m_pose[rid][2]<<" "<<m_pose[rid][3]<<" "<<m_pose[rid][4]<<" "<<m_pose[rid][5]<<" "<<m_pose[rid][6]<<" "<<endl;
339  //getchar();getchar();getchar();
340  stopThread(sockClient);
341  create_connection();
342  goto getPoseFromLinux_begin;
343  }
344  }
345  delete [] rcvData;
346  cerr << "done." << endl;
347  return true;
348 }
349 
351 {
352  cerr << "waitting for rgbd data ... ";
353  // recive data
354  // rgb
355  {
356  // rcv data
357  int data_len = (480 * 640 * 3 * (sizeof(uchar)) * rbt_num);
358  char* rcvData = new char[data_len];
359  int n = 0;
360  int count = 0;
361  char pkgData[MAXRECV];
362  // rbt0
363  n = 0;
364  count = 0;
365  while (1){
366  //if (count == data_len)
367  // break;
368  if (count + MAXRECV >= data_len){
369  n = recv(sockClient, pkgData, data_len - count, 0);
370  //cout << "the last pkg: data_len - count: " << data_len - count << ", n: " << n << endl;
371  int rst = n;
372  while (rst < data_len - count){
373  memcpy(&rcvData[count], &pkgData, rst);
374  count += rst;
375  rst = data_len - count;
376  rst = recv(sockClient, pkgData, rst, 0);
377  }
378  memcpy(&rcvData[count], &pkgData, rst);
379  count += rst;
380  break;
381  }
382  n = recv(sockClient, pkgData, MAXRECV, 0);
383  //if (count + n <= data_len)
384  memcpy(&rcvData[count], &pkgData, n);
385  //else
386  // memcpy(&rcvData[count], &pkgData, data_len - count);
387  count += n;
388  }
389  // cpy to rgb
390  int ind = 0;
391  for (int id = 0; id < rbt_num; id++)
392  {
393  for (int i = 0; i < 480; i++)
394  {
395  for (int j = 0; j < 640; j++)
396  {
397  memcpy(&m_rgb[id].ptr<cv::Vec3b>(i)[j][2], &rcvData[ind], sizeof(uchar));
398  ind += sizeof(uchar);
399  memcpy(&m_rgb[id].ptr<cv::Vec3b>(i)[j][1], &rcvData[ind], sizeof(uchar));
400  ind += sizeof(uchar);
401  memcpy(&m_rgb[id].ptr<cv::Vec3b>(i)[j][0], &rcvData[ind], sizeof(uchar));
402  ind += sizeof(uchar);
403  }
404  }
405  }
406  delete [] rcvData;
407  }
408 
409  //{// test show img
410  // for (int rid = 0; rid < rbt_num; rid++)
411  // {
412  // char name[10];
413  // sprintf(name, "rgb_%d", rid);
414  // cv::imshow(name, rgb[rid]);
415  // cv::waitKey(0);
416  // }
417  //}
418 
419  // depth
420  {
421  // rcv data
422  int data_len = (480 * 640 * (sizeof(short)) * rbt_num);
423  char* rcvData = new char[data_len];
424  int n = 0;
425  int count = 0;
426  char pkgData[MAXRECV];
427  // rbt0
428  n = 0;
429  count = 0;
430  while (1){
431  //if (count == data_len)
432  // break;
433  if (count + MAXRECV >= data_len){
434  n = recv(sockClient, pkgData, data_len - count, 0);
435  //cout << "the last pkg: data_len - count: " << data_len - count << ", n: " << n << endl;
436  int rst = n;
437  while (rst < data_len - count){
438  memcpy(&rcvData[count], &pkgData, rst);
439  count += rst;
440  rst = data_len - count;
441  rst = recv(sockClient, pkgData, rst, 0);
442  }
443  memcpy(&rcvData[count], &pkgData, rst);
444  count += rst;
445  break;
446  }
447  n = recv(sockClient, pkgData, MAXRECV, 0);
448  //if (count + n <= data_len)
449  memcpy(&rcvData[count], &pkgData, n);
450  //else
451  // memcpy(&rcvData[count], &pkgData, data_len - count);
452  count += n;
453  }
454  // cpy to depth
455  int ind = 0;
456  for (int id = 0; id < rbt_num; id++)
457  {
458  for (int i = 0; i < 480; i++)
459  {
460  for (int j = 0; j < 640; j++)
461  {
462  memcpy(&m_depth[id].ptr<ushort>(i)[j], &rcvData[ind], sizeof(short));
463  ind += sizeof(short);
464  }
465  }
466  }
467  delete [] rcvData;
468  }
469 
471  //for (int id = 0; id < rbt_num; id++)
472  //{
473  // cv::imwrite("depth.png", depth[id]);
474  // cv::imshow("get rgb", rgb[id]);
475  // cv::imshow("get depth", depth[id]);
476  // cv::waitKey(0);
477  //}
478 
479  cerr << "done" << endl;
480  return true;
481 }
482 
484 {
485  cerr << "waitting for pose data ... ";
486  // rcv data
487  int data_len = (7 * sizeof(float) * rbt_num);
488  char* rcvData = new char[data_len];
489  int n = 0;
490  int count = 0;
491  char pkgData[MAXRECV];
492  while (1){
493  if (count + MAXRECV >= data_len){
494  n = recv(sockClient, pkgData, data_len - count, 0);
495  //cout << "the last pkg: data_len - count: " << data_len - count << ", n: " << n << endl;
496  int rst = n;
497  while (rst < data_len - count){
498  memcpy(&rcvData[count], &pkgData, rst);
499  count += rst;
500  rst = data_len - count;
501  rst = recv(sockClient, pkgData, rst, 0);
502  }
503  memcpy(&rcvData[count], &pkgData, rst);
504  count += rst;
505  break;
506  }
507  /*if (count + MAXRECV >= data_len){
508  n = recv(sockClient, pkgData, data_len - count, 0);
509  cout << "the last pkg: data_len - count: " << data_len - count << ", n: " << n << endl;
510  memcpy(&rcvData[count], &pkgData, n);
511  count += n;
512  break;
513  }*/
514  n = recv(sockClient, pkgData, MAXRECV, 0);
515  //cout << ""
516  //if (count + n <= data_len)
517  memcpy(&rcvData[count], &pkgData, n);
518  //else
519  // memcpy(&rcvData[count], &pkgData, data_len - count);
520  count += n;
521  }
522  //cout << "final count: " << count << endl;
523  // cpy to pose
524  int ind = 0;
525  for (int id = 0; id < rbt_num; id++)
526  {
527  for (int i = 0; i < 7; i++)
528  {
529  memcpy(&m_pose[id][i], &rcvData[ind], sizeof(float));
530  ind += sizeof(float);
531  }
532  /*cout << "pose" << id << ": " << endl;
533  for (int i = 0; i < 7; i++){
534  cout << pose[id][i] << " ";
535  }
536  cout << endl;*/
537  }
538 
539  delete [] rcvData;
540  cerr << "done" << endl;
541  return true;
542 }
543 
544 // ask to set up surroundings, use to initialization
546 {
547  // ask for data
548  char sendData[1];
549  sendData[0] = '5';
550  send(sockClient, sendData, 1, 0);
551 }
552 
553 // move to views
554 bool DataEngine::socket_move_to_views(vector<vector<double>> poses)
555 {
556 // test
557  sleep(0.1);
558  stopThread(sockClient);
559  create_connection();
560  // ask to set poses
561  char sendData[1];
562  sendData[0] = 'm';
563  send(sockClient, sendData, 1, 0);
564  sleep(0.1);
565  // send poses data
566  int data_len = rbt_num * 7 * sizeof(float);
567  char* poseData = new char[data_len];
568  int ind = 0;
569  for (int rid = 0; rid < rbt_num; rid++)
570  {
571  for (int i = 0; i < 7; i++)
572  {
573  float pass = (float)poses[rid][i];
574  memcpy(&poseData[ind], &pass, sizeof(float));
575  ind += sizeof(float);
576  }
577  }
578  int rtn_num = send(sockClient, poseData, data_len, 0);
579  // free
580  delete [] poseData;
581  return true;
582 }
583 
584 // set up scan envir, not finished
586 {
587  scanSurroundingsCmd();
588  for (int i = 0; i < 6; i++)
589  {
590  rcvPoseFromServer();
591  rcvRGBDFromServer();
592  fuseScans2MapAndTree(); // insert scans multi-robot to tree
593  projectOctree2Map(); // project to 2d
594  }
595 }
596 
597 // coordinate system transfer
598 pair<Eigen::MatrixXd, Eigen::Vector3d> DataEngine::coord_trans_7f_rt(vector<float> pose)
599 {
600  Eigen::Quaternion<double> q((double)pose[6], (double)pose[3], (double)pose[4], (double)pose[5]);
601  Eigen::MatrixXd r = q.toRotationMatrix();
602  Eigen::Vector3d t(pose[0], pose[1], pose[2]);
603  return pair<Eigen::MatrixXd, Eigen::Vector3d>(r, t);
604 }
605 
606 // coordinate system transfer
608 {
609  pair<Eigen::MatrixXd, Eigen::Vector3d> rt = coord_trans_7f_rt(pose);
610  Eigen::MatrixXd r = rt.first;
611  Eigen::Vector3d t = rt.second;
612  double theta = asin(pose[5]) * 2;
613  Eigen::Vector3d origin(0, 0, 0); // gazebo coordinate
614  origin = r*origin + t;
615  //rbtpose[rbt_id].coordinate = cv::Point2f(-origin[1], origin[0]);
616  // to img coordinate, then to OT coordinate
617  double nodesize = map_cellsize;
618  double scale = nodesize / map_cellsize;
619  // u行v列
620  double v = ((-origin[1] - xmin_oc_g) / nodesize)*scale;
621  double u = ((zmax_oc_g - origin[0]) / nodesize)*scale;
622  if (u < 0)
623  u = 0;
624  if (v < 0)
625  v = 0;
626  if(__isnan(v)||__isnan(u)||__isnan(theta))
627  {
628  cerr<<"se2 nan: "<<v<<" "<<u<<" "<<theta<<endl;
629  cerr<<pose[0]<<" "<<pose[1]<<" "<<pose[2]<<" "<<pose[3]<<" "<<pose[4]<<" "<<pose[5]<<" "<<pose[6]<<" "<<endl;
630  getchar();getchar();getchar();
631  exit(-1);
632  }
633  return iro::SE2(v, -u, theta);
634 }
635 
636 // coordinate transformation: oc2cell return (row, col)
637 Eigen::Vector2i DataEngine::coord_trans_oc2cell(Eigen::Vector3d p_oc)
638 {
639  Eigen::Vector2i result = Eigen::Vector2i::Zero(2, 1);
640  result[1] = (int)((p_oc[0] - xmin_oc_g) / map_cellsize);//列
641  result[0] = (int)((zmax_oc_g - p_oc[2]) / map_cellsize);//行
642  if (result[0] < 0) result[0] = 0;
643  if (result[0] >= map_rows) result[0] = map_rows - 1;
644  if (result[1] < 0) result[1] = 0;
645  if (result[1] >= map_cols) result[1] = map_cols - 1;
646  return result;
647 }
648 
649 // coordinate transformation: oc2cell return (row, col)
650 Eigen::Vector2i DataEngine::coord_trans_oc2cell(Eigen::Vector3d p_oc, double node_size, int scale)
651 {
652  Eigen::Vector2i result = Eigen::Vector2i::Zero(2, 1);
653  result[1] = (int)((p_oc[0] - xmin_oc_g) / node_size)*scale;//列
654  result[0] = (int)((zmax_oc_g - p_oc[2]) / node_size)*scale;//行
655  return result;
656 }
657 
658 // coordinate system transfer: se22gazebo
660 {
661  // set up
662  vector<double> result;
663  result.resize(7);
664  // convert
665  double v = pose.translation().x();
666  double u = -pose.translation().y();
667  if (v < 10 || u < 10)
668  {
669  cerr << "error: out of boundary" << endl;
670  getchar();
671  }
672  double octree_x = v * map_cellsize + xmin_oc_g;
673  double octree_z = zmax_oc_g - u * map_cellsize;
674  double theta = pose.rotation().angle();
675  Eigen::Quaternion<double> q(cos(theta / 2), 0.0, 0.0, sin(theta / 2));
676  Eigen::MatrixXd r = q.toRotationMatrix();
677  Eigen::Vector3d t(octree_z, -octree_x, g_camera_height);
678  result[0] = octree_z;
679  result[1] = -octree_x;
680  result[2] = g_camera_height;
681  result[3] = 0.0;
682  result[4] = 0.0;
683  result[5] = sin(theta / 2);
684  result[6] = cos(theta / 2);
685  return result;
686 }
687 
688 // project octree 2 map, not finished
690 {
691  // label free cells in cellmap according to octree
692  for (octomap::OcTree::leaf_iterator it = m_recon3D.m_tree->begin_leafs(), end = m_recon3D.m_tree->end_leafs(); it != end; ++it)
693  {
694  // out boundary
695  if (fabs(it.getY()) > project_max_height)
696  continue;
697  // coordinate
698  double nodesize = it.getSize();
699  int scale = nodesize / map_cellsize;
700  int v = (int)((it.getX() - xmin_oc_g) / nodesize)*scale;
701  int u = (int)((zmax_oc_g - it.getZ()) / nodesize)*scale;
702  if (u < 0)
703  u = 0;
704  if (v < 0)
705  v = 0;
706  if (m_recon2D.m_cellmap[u][v].isScanned) // 防止离太近导致occupied被错误的标记为free
707  continue;
708  m_recon2D.m_cellmap[u][v].coordinate.x = it.getX();
709  m_recon2D.m_cellmap[u][v].coordinate.y = it.getZ();
710  // free
711  if (m_recon3D.m_tree->search(it.getKey())->getOccupancy() < 0.5 && -it.getY() < free_voxel_porject_height)
712  { // 该voxel为free
713  //if (!m_recon2D.m_cellmap[u][v].isScanned) // new free
714  // explore_counter++;
715  m_recon2D.m_cellmap[u][v].isScanned = true;
716  m_recon2D.m_cellmap[u][v].isOccupied = false;
717  m_recon2D.m_cellmap[u][v].isFree = true;
718  if (scale != 1)
719  {
720  for (int i = 0; i < scale; i++)
721  {
722  for (int j = 0; j < scale; j++)
723  {
724  if (!m_recon2D.m_cellmap[u + i][v + j].isOccupied)
725  {
726  m_recon2D.m_cellmap[u + i][v + j].isScanned = true;
727  m_recon2D.m_cellmap[u + i][v + j].coordinate.x = it.getX();
728  m_recon2D.m_cellmap[u + i][v + j].coordinate.y = it.getZ();
729  m_recon2D.m_cellmap[u + i][v + j].isOccupied = false;
730  m_recon2D.m_cellmap[u + i][v + j].isFree = true;
731  }
732  }
733  }
734  }
735  }
736  }
737  // label occupied cells in cellmap according to octree
738  for (octomap::OcTree::leaf_iterator it = m_recon3D.m_tree->begin_leafs(), end = m_recon3D.m_tree->end_leafs(); it != end; ++it)
739  {
740  // out boundary
741  if (fabs(it.getY()) > project_max_height || fabs(it.getY()) < project_min_height)
742  continue;
743  // coordinate
744  double nodesize = it.getSize();
745  int scale = nodesize / map_cellsize;
746  int v = (int)((it.getX() - xmin_oc_g) / nodesize)*scale;
747  int u = (int)((zmax_oc_g - it.getZ()) / nodesize)*scale;
748  if (u < 0)
749  u = 0;
750  if (v < 0)
751  v = 0;
752  m_recon2D.m_cellmap[u][v].coordinate.x = it.getX();
753  m_recon2D.m_cellmap[u][v].coordinate.y = it.getZ();
754  // occupied
755  //if (tree->search(it.getKey())->getOccupancy() > 0.5 && it.getY() < -0.2)
756  if (m_recon3D.m_tree->search(it.getKey())->getOccupancy() > 0.5)
757  { // 该voxel为occupied
758  // need new iteration check
759  {
760  //if (!cellmap[u][v].isScanned) // new occupied
761  // explore_counter++;
762  //if (cellmap[u][v].isScanned && cellmap[u][v].isFree) // new collision
763  // explore_counter += 2;
764  }
765  m_recon2D.m_cellmap[u][v].isScanned = true;
766  m_recon2D.m_cellmap[u][v].isOccupied = true;
767  m_recon2D.m_cellmap[u][v].isFree = false;
768  if (scale != 1)
769  {
770  for (int i = 0; i < scale; i++)
771  {
772  for (int j = 0; j < scale; j++)
773  {
774  m_recon2D.m_cellmap[u + i][v + j].isScanned = true;
775  m_recon2D.m_cellmap[u + i][v + j].coordinate.x = it.getX();
776  m_recon2D.m_cellmap[u + i][v + j].coordinate.y = it.getZ();
777  m_recon2D.m_cellmap[u + i][v + j].isOccupied = true;
778  m_recon2D.m_cellmap[u + i][v + j].isFree = false;
779  }
780  }
781  }
782  }
783  }
784  // label free cells in cellmap that octomap not record
785  for (int cid = 0; cid < m_free_space_contours2d.size(); cid++)
786  {
787  if (m_free_space_contours2d[cid].empty()) continue;
788  for (int r = 0; r < map_rows; r++)
789  {
790  for (int c = 0; c < map_cols; c++)
791  {
792  if (!m_recon2D.m_cellmap[r][c].isScanned)
793  {
794  if (cv::pointPolygonTest(m_free_space_contours2d[cid], cv::Point(c, r), false) >= 0)
795  { // inside
796  m_recon2D.m_cellmap[r][c].isScanned = true;
797  m_recon2D.m_cellmap[r][c].isFree = true;
798  m_recon2D.m_cellmap[r][c].isOccupied = false;
799  }
800  }
801  }
802  }
803  }
804 
805  // fill small holes in known region
806  fillTrivialHolesKnownRegion();
807 
808  // scene boundary constraint. avoid robots move out of boundary to infinite unknown space.
809  if (!g_scene_boundary.empty())
810  {
811  for (int r = 0; r < map_rows; r++)
812  {
813  for (int c = 0; c < map_cols; c++)
814  {
815  // if a scanned cell is out of boundary, set to 'scanned & occupied'
816  if (m_recon2D.m_cellmap[r][c].isScanned)
817  {
818  if (cv::pointPolygonTest(g_scene_boundary, cv::Point(c, r), false) <= 0) // out_of_boundary or on_boundary
819  {
820  m_recon2D.m_cellmap[r][c].isScanned = false;
821  m_recon2D.m_cellmap[r][c].isFree = false;
822  m_recon2D.m_cellmap[r][c].isOccupied = true;
823  //cerr<<"voxel out of boundary."<<endl; getchar(); getchar(); getchar();
824  }
825  /*
826  else if (cv::pointPolygonTest(g_scene_boundary, cv::Point(c, r), true) < 2) // add and then commented. 20200311.
827  {
828  m_recon2D.m_cellmap[r][c].isScanned = false;
829  m_recon2D.m_cellmap[r][c].isFree = false;
830  m_recon2D.m_cellmap[r][c].isOccupied = true;
831  //cerr<<"voxel out of boundary."<<endl; getchar(); getchar(); getchar();
832  }
833  //*/
834  }
835  }
836  }
837  }
838 
839 // todo: uncertainty 2d
840 
841  return;
842 }
843 //*/
844 
845 // find free contours that octomap cant handle, not finished
846 void DataEngine::findExtraFreeSpace(int rid, cv::Mat depth, vector<float> pose)
847 {
848  // set up
849  cv::Mat dpth = depth.clone();
850 
851  // convert pose to rt
852  pair<Eigen::MatrixXd, Eigen::Vector3d> rt = coord_trans_7f_rt(pose);
853  Eigen::MatrixXd r = rt.first;
854  Eigen::Vector3d t = rt.second;
855 
856  // depth_img 2 vector: use to find free space
857  cv::Mat depth_vec = cv::Mat::zeros(1, dpth.cols, CV_8UC1);
858  for (int c = 0; c < dpth.cols; c++)
859  {
860  bool value_valid = false;
861  for (int r = 0; r < dpth.rows; r++)
862  {
863  //if (depth.ptr<ushort>(r)[c] <= scan_max_range && depth.ptr<ushort>(r)[c] != 0)
864  if (dpth.ptr<ushort>(r)[c] != 0)
865  {
866  value_valid = true;
867  break;
868  }
869  }
870  if (value_valid)
871  depth_vec.ptr<uchar>(0)[c] = 255;
872  }
873  vector<int> free_indexes;
874  for (int crt = 0; crt < depth_vec.cols; crt++)
875  {
876  if (depth_vec.ptr<uchar>(0)[crt] == 0)
877  free_indexes.push_back(crt);
878  }
879  vector<pair<int, int>> free_spaces;
880  //cerr << "free_indexes.size() = " << free_indexes.size() << endl;
881  if (free_indexes.size() > 1)
882  {
883  //cout << "free_indexes.size() > 1" << endl;
884  int begin_index = -1;
885  int end_index = -1;
886  for (int crt = 0; crt < free_indexes.size(); crt++)
887  {
888  if (crt == 0){ // the first point
889  begin_index = free_indexes[crt];
890  continue;
891  }
892  int last = crt - 1;
893  if (free_indexes[crt] - free_indexes[last] > 1)
894  { // at this time, last is the end point of this group,crt is the beg point of next group
895  end_index = free_indexes[last];
896  if (begin_index != end_index)
897  free_spaces.push_back(pair<int, int>(begin_index, end_index));
898  begin_index = free_indexes[crt];
899  }
900  if (crt == free_indexes.size() - 1){ // the last point
901  end_index = free_indexes[crt];
902  if (begin_index != end_index)
903  free_spaces.push_back(pair<int, int>(begin_index, end_index));
904  }
905  }
906  }
907  //cerr << "free_spaces.size() = " << free_spaces.size() << endl;
908  if (!free_spaces.empty())
909  {
910  //cout << "!free_spaces.empty()" << endl;
911  // free space contour
912  for (int sid = 0; sid < free_spaces.size(); sid++)
913  {
914  vector<cv::Point> space_contour;
915  double nodesize = map_cellsize;
916  int scale = nodesize / map_cellsize;
917  // right end point
918  {
919  // r [0] c [free_spaces[sid].second];
920  ushort d = scan_max_range;
921  // compute coordinate, octomap camera coord system
922  double z = double(d) / camera_factor;
923  double x = (free_spaces[sid].second - camera_cx) * z / camera_fx;
924  double y = (0 - camera_cy) * z / camera_fy;
925  Eigen::Vector3d p;
926  p[0] = z, p[1] = -x, p[2] = -y; // convert to gazebo camera coord system
927  p = r*p + t; // convert to gazebo world coord system
928  -p[1], -p[2], p[0]; // convert to octomap world coord system
929  int v = (int)((-p[1] - xmin_oc_g) / nodesize)*scale;
930  int u = (int)((zmax_oc_g - p[0]) / nodesize)*scale;
931  if (u < 0)
932  u = 0;
933  if (v < 0)
934  v = 0;
935  // u v
936  space_contour.push_back(cv::Point(v, u));
937  }
938  // left end point
939  {
940  // r [0] c [free_spaces[sid].first];
941  ushort d = scan_max_range;
942  double z = double(d) / camera_factor;
943  double x = (free_spaces[sid].first - camera_cx) * z / camera_fx;
944  double y = (0 - camera_cy) * z / camera_fy;
945  Eigen::Vector3d p;
946  p[0] = z, p[1] = -x, p[2] = -y;
947  p = r*p + t;
948  int v = (int)((-p[1] - xmin_oc_g) / nodesize)*scale;
949  int u = (int)((zmax_oc_g - p[0]) / nodesize)*scale;
950  if (u < 0)
951  u = 0;
952  if (v < 0)
953  v = 0;
954  space_contour.push_back(cv::Point(v, u));
955  }
956  // camera point
957  {
958  double z = 0;
959  double x = 0;
960  double y = 0;
961  Eigen::Vector3d p;
962  p[0] = z, p[1] = -x, p[2] = -y;
963  p = r*p + t;
964  int v = (int)((-p[1] - xmin_oc_g) / nodesize)*scale;
965  int u = (int)((zmax_oc_g - p[0]) / nodesize)*scale;
966  if (u < 0)
967  u = 0;
968  if (v < 0)
969  v = 0;
970  space_contour.push_back(cv::Point(v, u));
971  }
972  m_free_space_contours2d[rid] = space_contour; // save
973  }
974 /*
975  // draw contours
976  cerr<<"show contours 2d"<<endl;
977  cv::Mat pc_resultImage = cv::Mat::zeros(map_rows, map_cols, CV_8U);
978  cv::drawContours(pc_resultImage, m_free_space_contours2d, -1, cv::Scalar(255, 0, 255));
979  cv::imshow("space_contours", pc_resultImage);
980  cv::waitKey(0);
981 //*/
982  }
983  return;
984 }
985 //*/
986 
987 // compute ideal frustum
988 vector<cv::Point> DataEngine::loadIdealFrustum(Eigen::MatrixXd r, Eigen::Vector3d t)
989 {
990  vector<cv::Point> result;
991  // right end point
992  {
993  // r [0] c [free_spaces[sid].second];
994  ushort d = scan_max_range;
995  double z = double(d) / camera_factor;
996  double x = (map_cols - 1 - camera_cx) * z / camera_fx;
997  double y = (0 - camera_cy) * z / camera_fy;
998  Eigen::Vector3d p_cam;
999  p_cam[0] = x; p_cam[1] = y; p_cam[2] = z;
1000  Eigen::Vector3d p_gz;
1001  p_gz[0] = p_cam.z(), p_gz[1] = -p_cam.x(), p_gz[2] = -p_cam.y(); // 转到gazebo的相机坐标系
1002  p_gz = r*p_gz + t; // 转到gazebo的世界坐标系
1003  Eigen::Vector3d p_oc;
1004  p_oc[0] = -p_gz[1]; p_oc[1] = -p_gz[2]; p_oc[2] = p_gz[0]; // 转到octomap的世界坐标系,在octomap中的坐标
1005  double node_size = map_cellsize;
1006  int scale = node_size / map_cellsize;
1007  Eigen::Vector2i rc = coord_trans_oc2cell(p_oc, node_size, scale);
1008  int v = rc[1];//列
1009  int u = rc[0];//行
1010  if (u < 0)
1011  u = 0;
1012  if (v < 0)
1013  v = 0;
1014  // u行v列
1015  result.push_back(cv::Point(v, u));
1016  }
1017  // left end point
1018  {
1019  // r [0] c [free_spaces[sid].first];
1020  ushort d = scan_max_range;
1021  double z = double(d) / camera_factor;
1022  double x = (0 - camera_cx) * z / camera_fx;
1023  double y = (0 - camera_cy) * z / camera_fy;
1024  Eigen::Vector3d p;
1025  p[0] = z, p[1] = -x, p[2] = -y; // 转到gazebo的相机坐标系
1026  p = r*p + t; // 转到gazebo的世界坐标系
1027  -p[1], -p[2], p[0]; // 转到octomap的世界坐标系
1028  double nodesize = map_cellsize;
1029  int scale = nodesize / map_cellsize;
1030  int v = (int)((-p[1] - xmin_oc_g) / nodesize)*scale;
1031  int u = (int)((zmax_oc_g - p[0]) / nodesize)*scale;
1032  if (u < 0)
1033  u = 0;
1034  if (v < 0)
1035  v = 0;
1036  // u行v列
1037  result.push_back(cv::Point(v, u));
1038  }
1039  // camera end point
1040  {
1041  double z = 0;
1042  double x = 0;
1043  double y = 0;
1044  Eigen::Vector3d p;
1045  p[0] = z, p[1] = -x, p[2] = -y; // 转到gazebo的相机坐标系
1046  p = r*p + t; // 转到gazebo的世界坐标系
1047  -p[1], -p[2], p[0]; // 转到octomap的世界坐标系
1048  double nodesize = map_cellsize;
1049  int scale = nodesize / map_cellsize;
1050  int v = (int)((-p[1] - xmin_oc_g) / nodesize)*scale;
1051  int u = (int)((zmax_oc_g - p[0]) / nodesize)*scale;
1052  if (u < 0)
1053  u = 0;
1054  if (v < 0)
1055  v = 0;
1056  // u行v列
1057  result.push_back(cv::Point(v, u));
1058  }
1059  return result;
1060 }
1061 
1062 // fill trivial holes in known region
1064 {
1065  cv::Mat cellmap_mat = cv::Mat::zeros(map_rows, map_cols, CV_8UC3);
1066  for (int r = 0; r < cellmap_mat.rows; r++)
1067  {
1068  for (int c = 0; c < cellmap_mat.cols; c++)
1069  {
1070  if (m_recon2D.m_cellmap[r][c].isScanned){
1071  if (m_recon2D.m_cellmap[r][c].isFree)
1072  cellmap_mat.ptr<cv::Vec3b>(r)[c][1] = 255;
1073  else
1074  cellmap_mat.ptr<cv::Vec3b>(r)[c][2] = 255;
1075  }
1076  }
1077  }
1078  // resize to fill hole
1079  cv::Mat trans_mat(map_rows * 2, map_cols * 2, CV_8UC3);
1080  cv::resize(cellmap_mat, trans_mat, trans_mat.size(), 0, 0);
1081  // color correct
1082  for (int r = 0; r < trans_mat.rows; r++)
1083  {
1084  for (int c = 0; c < trans_mat.cols; c++)
1085  {
1086  if (trans_mat.ptr<cv::Vec3b>(r)[c][1] > trans_mat.ptr<cv::Vec3b>(r)[c][2]){ // free
1087  trans_mat.ptr<cv::Vec3b>(r)[c][2] = 0;
1088  trans_mat.ptr<cv::Vec3b>(r)[c][1] = 255;
1089  trans_mat.ptr<cv::Vec3b>(r)[c][0] = 0;
1090  }
1091  else if (trans_mat.ptr<cv::Vec3b>(r)[c][1] < trans_mat.ptr<cv::Vec3b>(r)[c][2]){ // occupied
1092  trans_mat.ptr<cv::Vec3b>(r)[c][2] = 255;
1093  trans_mat.ptr<cv::Vec3b>(r)[c][1] = 0;
1094  trans_mat.ptr<cv::Vec3b>(r)[c][0] = 0;
1095  }
1096  }
1097  }
1098  cv::resize(trans_mat, cellmap_mat, cellmap_mat.size(), 0, 0);
1099  // color correct
1100  for (int r = 0; r < cellmap_mat.rows; r++)
1101  {
1102  for (int c = 0; c < cellmap_mat.cols; c++)
1103  {
1104  if (cellmap_mat.ptr<cv::Vec3b>(r)[c][1] > cellmap_mat.ptr<cv::Vec3b>(r)[c][2]){ // free
1105  cellmap_mat.ptr<cv::Vec3b>(r)[c][2] = 0;
1106  cellmap_mat.ptr<cv::Vec3b>(r)[c][1] = 255;
1107  cellmap_mat.ptr<cv::Vec3b>(r)[c][0] = 0;
1108  }
1109  else if (cellmap_mat.ptr<cv::Vec3b>(r)[c][1] < cellmap_mat.ptr<cv::Vec3b>(r)[c][2]){ // occupied
1110  cellmap_mat.ptr<cv::Vec3b>(r)[c][2] = 255;
1111  cellmap_mat.ptr<cv::Vec3b>(r)[c][1] = 0;
1112  cellmap_mat.ptr<cv::Vec3b>(r)[c][0] = 0;
1113  }
1114  }
1115  }
1116  // fill holes inside frustum
1117  for (int rid = 0; rid < rbt_num; rid++)
1118  {
1119  if (m_frustum_contours[rid].size() == 0)
1120  {
1121  cerr << "empty frustum." << endl;
1122  getchar(); getchar(); getchar();
1123  continue;
1124  }
1125  // find bbx
1126  int minX = 999999;
1127  int minY = 999999;
1128  int maxX = 0;
1129  int maxY = 0;
1130  for (int pid = 0; pid < m_frustum_contours[rid].size(); pid++)
1131  {
1132  if (m_frustum_contours[rid][pid].x > maxX)
1133  maxX = m_frustum_contours[rid][pid].x;
1134  if (m_frustum_contours[rid][pid].y > maxY)
1135  maxY = m_frustum_contours[rid][pid].y;
1136  if (m_frustum_contours[rid][pid].x < minX)
1137  minX = m_frustum_contours[rid][pid].x;
1138  if (m_frustum_contours[rid][pid].y < minY)
1139  minY = m_frustum_contours[rid][pid].y;
1140  }
1141  // extract iner cells
1142  cv::Mat inerCellMap = cv::Mat::zeros(map_rows, map_cols, CV_8UC1);
1143  for (int r = minY; r <= maxY; r++)
1144  {
1145  for (int c = minX; c <= maxX; c++)
1146  {
1147  if (m_recon2D.m_cellmap[r][c].isScanned) // scanned cell
1148  {
1149  if (cv::pointPolygonTest(m_frustum_contours[rid], cv::Point(c, r), false) >= 0) // inside the robot view
1150  {
1151  inerCellMap.ptr<uchar>(r)[c] = 255;
1152  }
1153  }
1154  }
1155  }
1156  // contours
1157  vector<vector<cv::Point>> contours;
1158  vector<cv::Vec4i> hierarchy;
1159  cv::findContours(inerCellMap, contours, hierarchy, CV_RETR_TREE, CV_CHAIN_APPROX_SIMPLE);// tree, simple
1160  for (int cid = 0; cid < contours.size(); cid++)
1161  {
1162  if (contours[cid].size() <= 4) continue;
1163  for (int r = minY; r <= maxY; r++)
1164  {
1165  for (int c = minX; c <= maxX; c++)
1166  {
1167  if (!m_recon2D.m_cellmap[r][c].isScanned) // maybe a hole.
1168  {
1169  if (cv::pointPolygonTest(contours[cid], cv::Point(c, r), false) >= 0) // inside the known region
1170  {
1171  if (cellmap_mat.ptr<cv::Vec3b>(r)[c][1] == 255) // free
1172  {
1173  m_recon2D.m_cellmap[r][c].isScanned = true;
1174  m_recon2D.m_cellmap[r][c].isFree = true;
1175  m_recon2D.m_cellmap[r][c].isOccupied = false;
1176  }
1177  else if (cellmap_mat.ptr<cv::Vec3b>(r)[c][2] == 255) // occupied
1178  {
1179  m_recon2D.m_cellmap[r][c].isScanned = true;
1180  m_recon2D.m_cellmap[r][c].isFree = false;
1181  m_recon2D.m_cellmap[r][c].isOccupied = true;
1182  }
1183  } // inside the known region
1184  } // maybe a hole
1185  } // c
1186  } // r
1187  } // known region contour
1188  } // frustum iter
1189 //*/
1190  return;
1191 }
1192 
1193 // fuse scans by multi-robot, not finished
1195 {
1196  cerr<<"fuseScans2MapAndTree..."<<endl;
1197  for (int rid = 0; rid < rbt_num; ++rid)
1198  {
1199  // update octree
1200  cerr<<"insertAFrame2Tree..."<<endl;
1201  insertAFrame2Tree(m_depth[rid], m_pose[rid]);
1202  // find extra free space that octree cant record
1203  findExtraFreeSpace(rid, m_depth[rid], m_pose[rid]);
1204 
1205  // todo: uncertainty
1206 
1207  // todo: surface normal
1208 
1209  // update robot poses
1210  m_pose2d[rid] = coord_trans_7f_se2(m_pose[rid]);
1211  // update robot viewports
1212  pair<Eigen::MatrixXd, Eigen::Vector3d> rt = coord_trans_7f_rt(m_pose[rid]);
1213  m_frustum_contours[rid] = loadIdealFrustum(rt.first, rt.second);
1214  }
1215 
1216  // todo: keyframe count
1217 
1218  return;
1219 }
1220 
1221 // insert a frame to octree
1222 void DataEngine::insertAFrame2Tree(cv::Mat & depth, vector<float> pose)
1223 {
1224  double tb = clock(); // timing
1225  // check nan
1226  for (int i = 0; i < pose.size(); ++i)
1227  {
1228  if (__isnan(pose[i]))
1229  {
1230  cerr<<"pose nan:"<<endl;
1231  cerr<<pose[0]<<" "<<pose[1]<<" "<<pose[2]<<" "<<pose[3]<<" "<<pose[4]<<" "<<pose[5]<<" "<<pose[6]<<" "<<endl;
1232  getchar();getchar();getchar();
1233  exit(-1);
1234  }
1235  }
1236  if (pose[3]==pose[4] && pose[4]==pose[5] && pose[5]==pose[6])
1237  {
1238  cerr<<"invalid pose"<<endl;
1239  cerr<<pose[0]<<" "<<pose[1]<<" "<<pose[2]<<" "<<pose[3]<<" "<<pose[4]<<" "<<pose[5]<<" "<<pose[6]<<" "<<endl;
1240  getchar();getchar();getchar();
1241  exit(-1);
1242  }
1243 
1244  // set up
1245  octomap::Pointcloud* pc = new octomap::Pointcloud();
1246  for (int r = 0; r < depth.rows; r++)
1247  {
1248  for (int c = 0; c < depth.cols; c++)
1249  {
1250  if (depth.ptr<ushort>(r)[c] > scan_max_range) // cut off
1251  depth.ptr<ushort>(r)[c] = 0;
1252  // depth error? infinite was set to 1000?
1253  if (depth.ptr<ushort>(r)[c] == 1000) // 1000 mm
1254  depth.ptr<ushort>(r)[c] = 0;
1255  // depth error? infinite was set to 1000?
1256 /*
1257  if (method_num == 30) // add noise
1258  {
1259  if (depth.ptr<ushort>(r)[c] > 100 && depth.ptr<ushort>(r)[c] < 200)
1260  {
1261  //cerr << "origin " << depth.ptr<ushort>(r)[c] << endl;
1262  short noise = (rand() % 100 - 50);
1263  //cerr << "noise " << noise << endl;
1264  depth.ptr<ushort>(r)[c] = (ushort)depth.ptr<ushort>(r)[c] + noise;
1265  //cerr << "noised " << depth.ptr<ushort>(r)[c] << endl;
1266  }
1267  else if (depth.ptr<ushort>(r)[c] > 2000)
1268  {
1269  short noise = (rand() % 200 - 100); // +-100mm
1270  //cerr << "noise " << noise << endl;
1271  depth.ptr<ushort>(r)[c] = (ushort)depth.ptr<ushort>(r)[c] + noise;
1272  }
1273  }
1274 //*/
1275  }
1276  }
1277  // convert pose to rt
1278  Eigen::Quaternion<double> q((double)pose[6], (double)pose[3], (double)pose[4], (double)pose[5]);
1279  Eigen::MatrixXd r = q.toRotationMatrix();
1280  Eigen::Vector3d t(pose[0], pose[1], pose[2]);
1281 /*
1282  // check nan
1283  for (int i = 0; i < 3; ++i)
1284  {
1285  for (int j = 0; j < 3; ++j)
1286  {
1287  if(__isnan(r(i, j)))
1288  {
1289  cerr<<"pose nan"<<endl;
1290  cerr<<"r"<<endl<<r<<endl;
1291  cerr<<pose[0]<<" "<<pose[1]<<" "<<pose[2]<<" "<<pose[3]<<" "<<pose[4]<<" "<<pose[5]<<" "<<pose[6]<<" "<<endl;
1292  getchar();getchar();getchar();
1293  exit(-1);
1294  }
1295  }
1296  }
1297  for (int i = 0; i < 3; ++i)
1298  {
1299  if (__isnan(t[i]))
1300  {
1301  cerr<<"pose nan"<<endl;
1302  cerr<<"t"<<endl<<t.transpose()<<endl;
1303  cerr<<pose[0]<<" "<<pose[1]<<" "<<pose[2]<<" "<<pose[3]<<" "<<pose[4]<<" "<<pose[5]<<" "<<pose[6]<<" "<<endl;
1304  getchar();getchar();getchar();
1305  exit(-1);
1306  }
1307  }
1308 //*/
1309  // convert depth img to point cloud in octomap global coordinate
1310  for (int m = 0; m < depth.rows; m++){
1311  for (int n = 0; n < depth.cols; n++){
1312  // (m,n) d
1313  ushort d = depth.ptr<ushort>(m)[n];
1314  if (d == 0)
1315  continue;
1316  if (d > scan_max_range) //test: remove some far pixels max value 4913
1317  continue;
1318  // 3d position in octomap local(camera) coordinate
1319  double z = double(d) / camera_factor;
1320  double x = (n - camera_cx) * z / camera_fx;
1321  double y = (m - camera_cy) * z / camera_fy;
1322  //cout << "camera local coord " << x << ", " << y << ", " << z << endl;
1323  Eigen::Vector3d p;
1324  p[0] = z, p[1] = -x, p[2] = -y; // gazebo local(camera) coordinate
1325  p = r*p + t; // gazebo world coordinate
1326  if (__isnan(p[0])||__isnan(p[1])||__isnan(p[2]))
1327  {
1328  cerr<<"point nan in pc"<<endl;
1329  getchar();getchar();getchar();
1330  continue;
1331  }
1332 //*/
1333  pc->push_back(-p[1], -p[2], p[0]); // convert to octomap world coordinate, then insert to pc
1334  }
1335  }
1336  Eigen::Vector3d origin(0, 0, 0);
1337  origin = r*origin + t; //-origin[1], -origin[2], origin[0]; // octomap world coordinate
1338 /*
1339  if (__isnan(origin[0])||__isnan(origin[1])||__isnan(origin[2]))
1340  {
1341  cerr<<"pose nan"<<endl;
1342  getchar();getchar();getchar();
1343  exit(-1);
1344  }
1345  else
1346 //*/
1347  {
1348  // inset into tree
1349  //m_recon3D.m_tree->insertPointCloudRays(pc, octomap::point3d(-origin[1], -origin[2], origin[0])); // openmp inside their code.
1350  m_recon3D.m_tree->insertPointCloud(pc, octomap::point3d(-origin[1], -origin[2], origin[0])); // cause error. cause error? it works well 2018-12-26.
1351  // update tree occupancy
1352  m_recon3D.m_tree->updateInnerOccupancy();
1353  }
1354  delete pc;
1355  double te = clock(); // timing
1356  cerr << "inserted a frame to octree, timing " << (te - tb)/CLOCKS_PER_SEC << " s" << endl;
1357  return;
1358 }
1359 
1360 // vis
1362 {
1363  cv::Mat vis_mat = cv::Mat::zeros(map_rows, map_cols, CV_8UC3);
1364  for (int r = 0; r < vis_mat.rows; r++)
1365  {
1366  for (int c = 0; c < vis_mat.cols; c++)
1367  {
1368  if (m_recon2D.m_cellmap[r][c].isScanned)
1369  {
1370  if (m_recon2D.m_cellmap[r][c].isFree)
1371  vis_mat.ptr<cv::Vec3b>(r)[c][1] = 255;
1372  else
1373  vis_mat.ptr<cv::Vec3b>(r)[c][2] = 255;
1374  }
1375  }
1376  }
1377  return vis_mat;
1378 }
1379 
1380 // show
1382 {
1383  cv::Mat vis_mat = visCellMap();
1384  cv::imshow("2d", vis_mat);
1385  cv::waitKey(0);
1386  return vis_mat;
1387 }
1388 
1389 // show
1391 {
1392  // recon
1393  cv::Mat vis_mat = visCellMap();
1394  // robot
1395  for (int rid = 0; rid < rbt_num; ++rid)
1396  {
1397  cv::circle(vis_mat, cv::Point(round(m_pose2d[rid].translation().x()), round(-m_pose2d[rid].translation().y())), 1, CV_RGB(255, 255, 255));
1398  cv::circle(vis_mat, cv::Point(round(m_pose2d[rid].translation().x()), round(-m_pose2d[rid].translation().y())), 3, CV_RGB(0, 0, 255));
1399  }
1400  cv::imshow("statement2d", vis_mat);
1401  cv::waitKey(0);
1402  return vis_mat;
1403 }
d
unsigned char uchar
Definition: data_engine.cpp:6
iro::SE2 coord_trans_7f_se2(std::vector< float > pose)
EIGEN_DEVICE_FUNC const CosReturnType cos() const
cv::Mat visCellMap()
#define PORT
Definition: data_engine.h:112
float g_camera_height
Definition: global.cpp:15
std::vector< cv::Point > g_scene_boundary
Definition: global.cpp:19
void projectOctree2Map()
std::vector< cv::Point > loadIdealFrustum(Eigen::MatrixXd r, Eigen::Vector3d t)
const Eigen::Rotation2Dd & rotation() const
Definition: se2.h:63
void fuseScans2MapAndTree()
bool rcvPoseFromServer()
const float zmax_oc_g
Definition: data_engine.h:44
int rbt_num
Definition: co_scan.cpp:15
Eigen::Vector2i coord_trans_oc2cell(Eigen::Vector3d p_oc)
std::vector< double > coord_trans_se22gazebo(iro::SE2 pose)
const double free_voxel_porject_height
Definition: data_engine.h:49
void SetUpSurroundings()
bool getRGBDFromServer()
Definition: data_engine.cpp:63
void insertAFrame2Tree(cv::Mat &depth, std::vector< float > pose)
void scanSurroundingsCmd()
const double project_min_height
Definition: data_engine.h:48
std::pair< Eigen::MatrixXd, Eigen::Vector3d > coord_trans_7f_rt(std::vector< float > pose)
const float map_cellsize
Definition: data_engine.h:39
const int map_rows
Definition: data_engine.h:40
cv::Mat showStatement()
void findExtraFreeSpace(int rid, cv::Mat depth, std::vector< float > pose)
void stopThread(int sockClient)
Definition: data_engine.cpp:52
bool reply_success
Definition: data_engine.cpp:9
bool create_connection()
Definition: data_engine.cpp:12
const int map_cols
Definition: data_engine.h:41
bool socket_move_to_views(std::vector< std::vector< double >> poses)
The quaternion class used to represent 3D orientations and rotations.
Definition: se2.h:49
bool send_success
Definition: data_engine.cpp:8
const double project_max_height
Definition: data_engine.h:47
bool rcvRGBDFromServer()
cv::Mat showCellMap()
EIGEN_DEVICE_FUNC Matrix3 toRotationMatrix() const
Definition: Quaternion.h:532
bool getPoseFromServer()
void socketSendThread(int sockClient, char *data, int data_lengh)
Definition: data_engine.cpp:34
EIGEN_DEVICE_FUNC Scalar angle() const
Definition: Rotation2D.h:78
EIGEN_DEVICE_FUNC const AsinReturnType asin() const
const float xmin_oc_g
Definition: data_engine.h:43
const Eigen::Vector2d & translation() const
Definition: se2.h:59
void fillTrivialHolesKnownRegion()
struct thread_data * data
Definition: tsp.cpp:10
EIGEN_DEVICE_FUNC const SinReturnType sin() const
EIGEN_DEVICE_FUNC const RoundReturnType round() const


co_scan
Author(s):
autogenerated on Mon Feb 28 2022 23:00:41