vscan_server.cpp
Go to the documentation of this file.
1 // ros msgs && opencv
2 #include "ros/ros.h"
3 #include "geometry_msgs/Twist.h"
4 #include "gazebo_msgs/SetModelState.h"
5 #include "gazebo_msgs/GetModelState.h"
6 #include "sensor_msgs/CameraInfo.h"
7 #include <image_transport/image_transport.h>
8 #include "std_msgs/String.h"
9 #include <sensor_msgs/Image.h>
10 #include <sensor_msgs/image_encodings.h>
11 #include <cv_bridge/cv_bridge.h>
12 
13 #include <opencv2/opencv.hpp>
14 #include <opencv2/core/core.hpp>
15 #include <opencv2/highgui/highgui.hpp>
16 #include <opencv2/imgproc/imgproc.hpp>
17 
18 #include <stdio.h>
19 #include <stdlib.h>
20 #include <fstream>
21 #include <sstream>
22 #include <sys/types.h>
23 #include <netinet/in.h>
24 #include <sys/socket.h>
25 #include <sys/wait.h>
26 #include <pthread.h>
27 #include <netinet/tcp.h>
28 
29 using namespace std;
30 
31 #define PI 3.1415926
32 
33 #define SERVPORT 3333
35 struct sockaddr_in my_addr;
36 struct sockaddr_in remote_addr;
37 const int MAXRECV = 10240;
38 #define BACKLOG 10
39 
40 int rbtnum = 3;
41 float camera_height = 1.1;
42 
43 cv::Mat rgbImg;
44 cv::Mat shortImg(480, 640, CV_16UC1);
45 bool rgb_ready = false;
46 bool depth_ready = false;
47 
48 // image transport
49 image_transport::ImageTransport* it;
50 // rgbd data from topics
51 vector<cv::Mat> crt_rgb_images(rbtnum);
52 vector<cv::Mat> crt_depth_images(rbtnum);
53 // subscribers
54 vector<image_transport::Subscriber> subsColor(rbtnum);
55 vector<image_transport::Subscriber> subsDepth(rbtnum);
56 
59 float pose[7];
60 bool pose_ready = false;
61 
62 const float camera_factor = 1000;
63 const float camera_cx = 320.500000;
64 const float camera_cy = 240.500000;
65 const float camera_fx = 554.382713;
66 const float camera_fy = 554.382713;
67 
68 const int times = 1.0;
69 float rbt_v = 1.0/times - 0.01;
70 
71 //const double move_distance_rate = 1;
72 
73 // data offline rcv writer
74 ofstream ofs_off;
75 
76 string int2str(int n)
77 {
78  stringstream ss;
79  string s;
80  ss<<n;
81  ss>>s;
82  return s;
83 }
84 
85 int str2int(string s)
86 {
87  stringstream ss(s);
88  int number;
89  ss>>number;
90  return number;
91 }
92 
93 // color frame callback. 2018-09-10. no mem leak. 2018-09-19.
94 void rgbImageCallback(const sensor_msgs::ImageConstPtr& msg, const std::string &rbtID)
95 {
96  printf("rgb callback, robot index: %s\n", rbtID.c_str());
97 
98  int rbtIndex = str2int(rbtID);
99 
100  cv_bridge::CvImagePtr cvImgPtr;
101  cv::Mat rgbPass;
102 
103  try
104  {
105  cvImgPtr = cv_bridge::toCvCopy(msg, sensor_msgs::image_encodings::BGR8);
106  rgbPass = cvImgPtr->image;
107  }
108  catch(cv_bridge::Exception& e)
109  {
110  ROS_ERROR("cv_bridge exception: %s", e.what());
111  }
112 
113  crt_rgb_images[rbtIndex] = rgbPass;
114 }
115 
116 // depth frame callback. 2018-09-10. no mem leak. 2018-09-19.
117 void depthImageCallback(const sensor_msgs::ImageConstPtr& msg, const std::string &rbtID)
118 {
119  printf("depth callback, robot index: %s\n", rbtID.c_str());
120 
121  int rbtIndex = str2int(rbtID);
122 
123  cv_bridge::CvImagePtr cvImgPtr;
124  cv::Mat depthImg;
125 
126  try
127  {
128  cvImgPtr = cv_bridge::toCvCopy(msg, sensor_msgs::image_encodings::TYPE_32FC1);
129  depthImg = cvImgPtr->image;
130  }
131  catch(cv_bridge::Exception& e)
132  {
133  ROS_ERROR("cv_bridge exception: %s", e.what());
134  }
135 
136  cv::Mat shortPass(480, 640, CV_16UC1);
137 
138  for (int i = 0; i < 480; ++i)
139  {
140  for (int j = 0; j < 640; ++j)
141  {
142  shortPass.ptr<short>(i)[j] = (short)(depthImg.ptr<float>(i)[j] * 1000);
143  }
144  }
145  crt_depth_images[rbtIndex] = shortPass;
146 }
147 
148 // pose
149 void callForPose(int id){
150  gazebo_msgs::GetModelState getmodelstate;
151  char s[10];
152  sprintf(s, "robot_%d", id);
153  getmodelstate.request.model_name = (std::string) s;
154  //ROS_INFO("call server to get pose");
155  if (gclient.call(getmodelstate))
156  {
157  //ROS_INFO("success");
158  }
159  else
160  {
161  ROS_ERROR("Failed to call service");
162  }
163  pose[0] = getmodelstate.response.pose.position.x;
164  pose[1] = getmodelstate.response.pose.position.y;
165  pose[2] = getmodelstate.response.pose.position.z;
166  pose[3] = getmodelstate.response.pose.orientation.x;
167  pose[4] = getmodelstate.response.pose.orientation.y;
168  pose[5] = getmodelstate.response.pose.orientation.z;
169  pose[6] = getmodelstate.response.pose.orientation.w;
170  pose_ready = true;
171 }
172 
173 void setForPose(int id, float x, float y, float z, float qx, float qy, float qz, float qw){
174 
175  printf("set pose for robot %d...", id);
176 
177  gazebo_msgs::SetModelState setmodelstate;
178 
179  char s[10];
180  sprintf(s, "robot_%d", id);
181  geometry_msgs::Pose posemsg;
182  posemsg.position.x = x;
183  posemsg.position.y = y;
184  posemsg.position.z = z;
185  posemsg.orientation.x = qx;
186  posemsg.orientation.y = qy;
187  posemsg.orientation.z = qz;
188  posemsg.orientation.w = qw;
189  gazebo_msgs::ModelState modelstate;
190  modelstate.pose = posemsg;
191  modelstate.model_name = (std::string) s;
192  setmodelstate.request.model_state = modelstate;
193  if (sclient.call(setmodelstate)){}
194  else
195  ROS_ERROR("Failed to call service");
196 
197  printf(" succeed.\n");
198 }
199 
200 void infoCallback(const sensor_msgs::CameraInfoConstPtr &msg){
201 
202  //printf("cx: %lf, cy: %lf, fx: %lf, fy: %lf\n", msg->K[2], msg->K[5], msg->K[0], msg->K[4]);
203 
204  //printf("fx: %lf\n", msg->K[0]);
205 }
206 
207 // recv
208 int recvData(const int client_fd, char buf[], int len)
209 {
210  memset (buf, 0, len);
211 
212  int i=0;
213  while(i<len){
214  char buf_tem[MAXRECV];
215  memset (buf_tem, 0, MAXRECV);
216  int status = recv(client_fd, buf_tem, MAXRECV, 0);
217  memcpy(buf+i, buf_tem, status);
218  i = i+status;
219 
220  //printf("i:%d\n", i);
221  //printf("len:%d\n", len);
222  //printf("status:%d\n", status);
223 
224  if ( status == -1 )
225  {
226  printf("status == -1 errno == %s in Socket::recv\n",errno);
227  return 0;
228  }
229  else if( status == 0 )
230  {
231  //stop(client_fd);
232  //return 0;
233  break;
234  }
235  else if(len<=MAXRECV+1)
236  {
237  break;
238  }
239  /*else
240  {
241  return status;
242  }*/
243  }
244 }
245 
246 // send
247 bool sendData(const int client_fd, const char *ch, const int len)
248 {
249  int status = send(client_fd, ch, len, 0);
250  if ( status == -1 )
251  {
252  return false;
253  }
254  else
255  {
256  return true;
257  }
258 }
259 
260 // send data. 2018-09-17
261 int sendTotalData(const int client_fd, const char *buf, const int len){
262 
263  int total = 0; // how many bytes we've sent
264  int bytesleft = len; // how many we have left to send
265  int n;
266 
267  while(total < len) {
268  n = send(client_fd, buf+total, bytesleft, 0);
269  if (n == -1) { break; }
270  total += n;
271  bytesleft -= n;
272  }
273 
274  return n==-1 ? 0:1; // return -1 onm failure, 0 on success
275 }
276 
277 // socket get rgbd
278 bool getRGBD(int client_fd){
279 
280  ros::spinOnce();
281 
282  ros::Rate rate(1); // 1hz
283 
284  rate.sleep();
285 
286 
287  // rgb
288  {
289  int data_len = 480 * 640 * 3 * sizeof(uchar) * rbtnum;
290  char* rgbData = (char *)malloc(data_len);
291 //if(rgbData == NULL) printf("malloc failed\n");
292  while(!rgbData)
293  {
294  usleep(100000);
295  rgbData = (char *)malloc(data_len);
296  }
297 
298  // for multi robot
299  int ind = 0;
300  for (int rid = 0; rid < rbtnum; ++rid)
301  {
302  for (int i = 0; i < 480; ++i)
303  {
304  for (int j = 0; j < 640; ++j)
305  {
306  memcpy(&rgbData[ind], &crt_rgb_images[rid].ptr<cv::Vec3b>(i)[j][0], sizeof(uchar));
307  ind+=sizeof(uchar);
308  memcpy(&rgbData[ind], &crt_rgb_images[rid].ptr<cv::Vec3b>(i)[j][1], sizeof(uchar));
309  ind+=sizeof(uchar);
310  memcpy(&rgbData[ind], &crt_rgb_images[rid].ptr<cv::Vec3b>(i)[j][2], sizeof(uchar));
311  ind+=sizeof(uchar);
312  }
313  }
314  }
315 
316  int rtnCode = sendTotalData(client_fd, rgbData, data_len);
317  printf("rgb data %d byte send back done. rtnCode = %d\n", data_len, rtnCode);
318  free(rgbData);
319 
320  }
321  // depth
322  {
323  int data_len = 480 * 640 * sizeof(short) * rbtnum;
324  char* depthData = (char *)malloc(data_len);
325  while(!depthData)
326  {
327  usleep(100000);
328  depthData = (char *)malloc(data_len);
329  }
330 
331  // for multi robot
332  int ind = 0;
333  for (int rid = 0; rid < rbtnum; ++rid)
334  {
335  for (int i = 0; i < 480; ++i)
336  {
337  for (int j = 0; j < 640; ++j)
338  {
339  memcpy(&depthData[ind], &crt_depth_images[rid].ptr<short>(i)[j], sizeof(short));
340  ind+=sizeof(short);
341  }
342  }
343  }
344 
345  //int rtnCode = sendData(client_fd, depthData, data_len);
346  int rtnCode = sendTotalData(client_fd, depthData, data_len);
347  printf("depth data %d byte send back done. rtnCode = %d\n", data_len, rtnCode);
348  free(depthData);
349 
350  }
351 
352  return true;
353 }
354 
355 // socket get depth
356 bool getDepth(int client_fd){
357 
358  printf("this method is abandoned");
359  getchar();
360 
361  return true;
362 }
363 
364 // socket get pose
366 {
367  printf("\ngetPose: ...\n");
368  int data_len = 7 * sizeof(float) * rbtnum;
369  char* poseData = (char *)malloc(data_len);
370  while(!poseData)
371  {
372  usleep(100000);
373  poseData = (char *)malloc(data_len);
374  }
375  // for multi robot
376  int ind = 0;
377  for (int rid = 0; rid < rbtnum; ++rid)
378  {
379  callForPose(rid);
380  for (int i = 0; i < 7; ++i)
381  {
382  memcpy(&poseData[ind], &pose[i], sizeof(float));
383  ind+=sizeof(float);
384  }
385  }
386  //int rtnCode = sendData(client_fd, poseData, data_len);
387  int rtnCode = sendTotalData(client_fd, poseData, data_len);
388  //printf("pose data %d byte send back done. rtnCode = %d\n", data_len, rtnCode);
389  ind = 0;
390  for (int rid = 0; rid < rbtnum; ++rid)
391  {
392  for (int i = 0; i < 7; ++i)
393  {
394  float temp;
395  memcpy(&temp, &poseData[ind], sizeof(float));
396  ind+=sizeof(float);
397 printf("%f ", temp);
398  }
399 printf("\n");
400  }
401  free(poseData);
402  printf("getPose: done.\n");
403  return true;
404 }
405 
406 void goToPose(float x0 , float y0, float qx0, float qy0, float qz0, float qw0,
407  float x1 , float y1, float qx1, float qy1, float qz1, float qw1,
408  float x2 , float y2, float qx2, float qy2, float qz2, float qw2){
409  printf("\ngoToPose\n");
410  //printf("set to x0=%f y0=%f x1=%f y1=%f x2=%f y2=%f\n", x0, y0, x1, y1, x2, y2);
411  // rotation try
412  // pose0
413  callForPose(0);
414  float originTheta0 = acos(pose[6])*2;
415  if(pose[5]<0)
416  originTheta0 = -originTheta0;
417  float objectTheta0 = acos(qw0)*2;
418  if(qz0<0)
419  objectTheta0 = -objectTheta0;
420  float dTheta0 = objectTheta0 - originTheta0;
421  float dx0 = rbt_v * (x0 - pose[0]);
422  float dy0 = rbt_v * (y0 - pose[1]);
423  // pose1
424  callForPose(1);
425  float originTheta1 = acos(pose[6])*2;
426  if(pose[5]<0)
427  originTheta1 = -originTheta1;
428  float objectTheta1 = acos(qw1)*2;
429  if(qz1<0)
430  objectTheta1 = -objectTheta1;
431  float dTheta1 = objectTheta1 - originTheta1;
432  float dx1 = rbt_v * (x1 - pose[0]);
433  float dy1 = rbt_v * (y1 - pose[1]);
434  // pose2
435  callForPose(2);
436  float originTheta2 = acos(pose[6])*2;
437  if(pose[5]<0)
438  originTheta2 = -originTheta2;
439  float objectTheta2 = acos(qw2)*2;
440  if(qz2<0)
441  objectTheta2 = -objectTheta2;
442  float dTheta2 = objectTheta2 - originTheta2;
443  float dx2 = rbt_v * (x2 - pose[0]);
444  float dy2 = rbt_v * (y2 - pose[1]);
445  for (int i = 0; i < times; ++i)
446  {
447  float ox = 0.0, oy = 0.0, oz = 1.0;
448  // pose 0
449  callForPose(0);
450  float crtTheta0 = acos(pose[6])*2;
451  if(pose[5]<0)
452  crtTheta0 = -crtTheta0;
453  float temp_theta0 = crtTheta0 + dTheta0/times;
454  setForPose(0, pose[0], pose[1], camera_height, ox*sin(temp_theta0/2), oy*sin(temp_theta0/2), oz*sin(temp_theta0/2), cos(temp_theta0/2));
455  // pose 1
456  callForPose(1);
457  float crtTheta1 = acos(pose[6])*2;
458  if(pose[5]<0)
459  crtTheta1 = -crtTheta1;
460  float temp_theta1 = crtTheta1 + dTheta1/times;
461  setForPose(1, pose[0], pose[1], camera_height, ox*sin(temp_theta1/2), oy*sin(temp_theta1/2), oz*sin(temp_theta1/2), cos(temp_theta1/2));
462  // pose 2
463  callForPose(2);
464  float crtTheta2 = acos(pose[6])*2;
465  if(pose[5]<0)
466  crtTheta2 = -crtTheta2;
467  float temp_theta2 = crtTheta2 + dTheta2/times;
468  setForPose(2, pose[0], pose[1], camera_height, ox*sin(temp_theta2/2), oy*sin(temp_theta2/2), oz*sin(temp_theta2/2), cos(temp_theta2/2));
469  // send to socket
470  ros::spinOnce();
471  ros::Rate rate(1);
472  //ros::Rate rate(10); // 01-09.
473  rate.sleep();
474  //getDepth(client_fd);
475  getPose(client_fd);
477  }
478  // move
479  for (int i = 0; i < times; ++i){
480  //0
481  callForPose(0);
482  float tx0 = pose[0] + dx0;
483  float ty0 = pose[1] + dy0;
484  //1
485  callForPose(1);
486  float tx1 = pose[0] + dx1;
487  float ty1 = pose[1] + dy1;
488  //2
489  callForPose(2);
490  float tx2 = pose[0] + dx2;
491  float ty2 = pose[1] + dy2;
492  setForPose(0, tx0, ty0, camera_height, qx0, qy0, qz0, qw0);
493  setForPose(1, tx1, ty1, camera_height, qx1, qy1, qz1, qw1);
494  setForPose(2, tx2, ty2, camera_height, qx2, qy2, qz2, qw2);
495  // send to socket
496  ros::spinOnce();
497  ros::Rate rate(1);
498  //ros::Rate rate(10); // 01-09.
499  rate.sleep();
500  //getDepth(client_fd);
502  getRGBD(client_fd);
503  }
504  printf("goToPose: done.\n");
505 }
506 
507 // socket move to views
509 
510  printf("\nfunc move_to_views begin\n");
511 
512  // receive data
513  int data_len = rbtnum * 7 * sizeof(float);
514  char* poseData = (char *)malloc(data_len);
515  while(!poseData)
516  {
517  usleep(100000);
518  poseData = (char *)malloc(data_len);
519  }
520  //printf("before recv\n");
521  int rcv_len = recvData(client_fd, poseData, data_len); // recv
522  //printf("after recv\n");
523  float pass_pose[rbtnum][7];
524  int ind = 0;
525 
526  // move: set poses to views
527  for (int id = 0; id < rbtnum; ++id)
528  {
529  float set_pose[7];
530  for (int i = 0; i < 7; ++i)
531  {
532  memcpy(&set_pose[i], &poseData[ind], sizeof(float));
533  memcpy(&pass_pose[id][i], &poseData[ind], sizeof(float));
534  ind+=sizeof(float);
535  }
536  setForPose(id,
537  set_pose[0], set_pose[1], set_pose[2],
538  set_pose[3], set_pose[4], set_pose[5], set_pose[6]);
539  //printf("pose for robot%d: %f, %f, %f, %f, %f, %f, %f\n", id,
540  // set_pose[0], set_pose[1], set_pose[2],
541  // set_pose[3], set_pose[4], set_pose[5], set_pose[6]);
542  }
543 
544  // free
545  free(poseData);
546 
547  printf("func move_to_views end\n\n");
548 
549  // update rgbd and pose topic
550 
551  ros::spinOnce();
552  ros::Rate rate(1);
553  rate.sleep();
554 
555  return true;
556 }
557 
558 // socket set pose
559 bool setPose(int client_fd){
560  printf("\nsetPose\n");
561  int data_len = rbtnum * 7 * sizeof(float);
562  char* poseData = (char *)malloc(data_len);
563  while(!poseData)
564  {
565  usleep(100000);
566  poseData = (char *)malloc(data_len);
567  }
568  int rcv_len = recvData(client_fd, poseData, data_len);
569  float pass_pose[rbtnum][7];
570  int ind = 0;
571  for (int id = 0; id < rbtnum; ++id)
572  {
573  float set_pose[7];
574  for (int i = 0; i < 7; ++i)
575  {
576  memcpy(&set_pose[i], &poseData[ind], sizeof(float));
577  memcpy(&pass_pose[id][i], &poseData[ind], sizeof(float));
578  ind+=sizeof(float);
579  }
580  }
581  goToPose(
582  pass_pose[0][0], pass_pose[0][1], pass_pose[0][3], pass_pose[0][4], pass_pose[0][5], pass_pose[0][6],
583  pass_pose[1][0], pass_pose[1][1], pass_pose[1][3], pass_pose[1][4], pass_pose[1][5], pass_pose[1][6],
584  pass_pose[2][0], pass_pose[2][1], pass_pose[2][3], pass_pose[2][4], pass_pose[2][5], pass_pose[2][6]);
585  free(poseData);
586  printf("\nsetPose: done.\n");
587  return true;
588 }
589 
590 //vector< vector< vector<float> > > send_poses;
592  float x;
593  float y;
594  float z;
595  PositionInGazebo(float ix, float iy, float iz){
596  x = ix;
597  y = iy;
598  z = iz;
599  }
600 };
601 vector< vector< PositionInGazebo > > path_poses;
602 vector< PositionInGazebo > task_poses;
603 
604 // set path
605 bool setPath(int client_fd){
606  /*
608  path_poses.clear();
609  path_poses.resize(rbtnum);
610  // recv path data
611  for (int rid = 0; rid < rbtnum; ++rid)
612  {
613  char len_data[sizeof(int)];
614  recvData(client_fd, len_data, sizeof(int));//recv data lenth
615  int data_len = 0;
616  memcpy(&data_len, &len_data, sizeof(int));
617  char path_data[MAXRECV];
618  recvData(client_fd, path_data, data_len);// recv path data
619  // memcpy to path_poses
620  int path_size = ceil(data_len/3/sizeof(float));
621  int ind = 0;
622  for (int pid = 0; pid < path_size; ++pid)
623  {
624  float x, y, z;
625  memcpy(&x, &path_data[ind], sizeof(float));
626  ind+=sizeof(float);
627  memcpy(&y, &path_data[ind], sizeof(float));
628  ind+=sizeof(float);
629  memcpy(&z, &path_data[ind], sizeof(float));
630  ind+=sizeof(float);
631  PositionInGazebo crt_p = PositionInGazebo(x, y, z);
632  path_poses[rid].push_back(crt_p);
633  }
634  }
635  // compute path distance for each robot
636  vector<float> path_dises;
637  double min_dis = DBL_MAX;
638  int min_rid = -1;
639  for (int rid = 0; rid < rbtnum; ++rid)
640  {
641  if(path_poses[rid].size() == 1){ // if dont have move path
642  path_dises.push_back(0);
643  continue;
644  }
645  float path_dis = 0;
646  for (int pid = 0; pid < path_poses[rid].size()-1; ++pid)
647  {
648  path_dis+=
649  sqrt(
650  (path_poses[rid][pid].x-path_poses[rid][pid+1].x)*(path_poses[rid][pid].x-path_poses[rid][pid+1].x)
651  +
652  (path_poses[rid][pid].y-path_poses[rid][pid+1].y)*(path_poses[rid][pid].y-path_poses[rid][pid+1].y));
653  }
654  path_dises.push_back(path_dis);
655  }
656  // compute min distance path
657  for (int rid = 0; rid < path_dises.size(); ++rid)
658  {
659  printf("rbt%d path distance = %f\n", rid, path_dises[rid]);
660  if(min_dis>path_dises[rid]){
661  min_dis = path_dises[rid];
662  min_rid = rid;
663  }
664  }
665  printf("min_dis = %f\n", min_dis);
666  {//move_distance_rate
667  min_rid = -1;
668  min_dis *= move_distance_rate;
669  }
670  // move robots
671  for (int rid = 0; rid < rbtnum; ++rid)
672  {
673  // move for no path robot
674  if(path_poses[rid].size() == 1){
675 
676  callForPose(rid);
677  float obj_x=.1, obj_y=.1, crt_x = .1, crt_y = .1;
678  obj_x = task_poses[rid].x;
679  obj_y = task_poses[rid].y;
680  crt_x = pose[0];
681  crt_y = pose[1];
682  float dir_theta;
683  printf("fabs(obj_x - crt_x)=%f fabs(obj_y - crt_y)=%f\n", fabs(obj_x - crt_x), fabs(obj_y - crt_y));
684  if(fabs(obj_x - crt_x) < 0.2 && fabs(obj_y - crt_y) < 0.2){ // task_pose == rbt pose
685  float originTheta = acos(pose[6])*2;
686  if(pose[5]<0)
687  originTheta = -originTheta;
688  dir_theta = originTheta+PI/3;
689  if(dir_theta>PI)
690  dir_theta = -PI + dir_theta - PI;
691  printf("turn PI/3\n");
692  }else{// task_pose != rbt pose
693  // compute direction
694  float dx = obj_x - crt_x;
695  float dy = obj_y - crt_y;
696  // compute rotation
697  if (dx > 0){
698  if(dy == 0){
699  dir_theta = 0;
700  }
701  else{
702  dir_theta = atan(dy / dx);
703  }
704  }
705  else if (dx == 0){
706  if(dy > 0){
707  dir_theta = PI/2;
708  }
709  else if (dy == 0){
710  dir_theta = 0; // need to modify to origin direction
711  }
712  else{// dy < 0
713  dir_theta = -PI/2;
714  }
715  }
716  else{ // dx < 0
717  if(dy>0){
718  dir_theta = PI - fabs(atan(dy / dx));
719  }
720  else if(dy == 0){
721  dir_theta = PI;
722  }
723  else{// dy < 0
724  dir_theta = -(PI - fabs(atan(dy / dx)));
725  }
726  }
727  }
728 
729  setForPose(rid, crt_x, crt_y, camera_height, 0.0*sin(dir_theta/2), 0.0*sin(dir_theta/2), 1.0*sin(dir_theta/2), cos(dir_theta/2));
730  printf("rbt%d dont move\n", rid);
731  printf("rbt%d set to (%f, %f)\n", rid, crt_x, crt_y);
732 
733  continue;
734  }
735  // move for min robot
736  if(rid == min_rid){
737  int node_num = path_poses[rid].size();
738  // compute direction
739  float dx = task_poses[rid].x - path_poses[rid][node_num-1].x;
740  float dy = task_poses[rid].y - path_poses[rid][node_num-1].y;
741  // float dx = path_poses[rid][node_num-1].x - path_poses[rid][node_num-2].x;
742  // float dy = path_poses[rid][node_num-1].y - path_poses[rid][node_num-2].y;
743  float dir_theta;
744  // compute rotation
745  if (dx > 0){
746  if(dy == 0){
747  dir_theta = 0;
748  }
749  else{
750  dir_theta = atan(dy / dx);
751  }
752  }
753  else if (dx == 0){
754  if(dy > 0){
755  dir_theta = PI/2;
756  }
757  else if (dy == 0){
758  dir_theta = 0; // need to modify to origin direction
759  }
760  else{// dy < 0
761  dir_theta = -PI/2;
762  }
763  }
764  else{ // dx < 0
765  if(dy>0){
766  dir_theta = PI - fabs(atan(dy / dx));
767  }
768  else if(dy == 0){
769  dir_theta = PI;
770  }
771  else{// dy < 0
772  dir_theta = -(PI - fabs(atan(dy / dx)));
773  }
774  }
775  // set pose
776  setForPose(rid, path_poses[rid][node_num-1].x, path_poses[rid][node_num-1].y, camera_height, 0.0*sin(dir_theta/2), 0.0*sin(dir_theta/2), 1.0*sin(dir_theta/2), cos(dir_theta/2));
777  printf("rbt%d min\n", rid);
778  printf("rbt%d set to (%f, %f)\n", rid, path_poses[rid][node_num-1].x, path_poses[rid][node_num-1].y);
779  }
780  // move for not min robot
781  else{
782  float obj_x=.1, obj_y=.1, crt_x = .1, crt_y = .1, lst_x=.1, lst_y=.1;
783  float crt_dis = 0;
784  for (int pid = 0; pid < path_poses[rid].size()-1; ++pid) // find obj position and lst position
785  {
786  float tmp_dis =
787  sqrt(
788  (path_poses[rid][pid].x-path_poses[rid][pid+1].x)*(path_poses[rid][pid].x-path_poses[rid][pid+1].x)
789  +
790  (path_poses[rid][pid].y-path_poses[rid][pid+1].y)*(path_poses[rid][pid].y-path_poses[rid][pid+1].y));
791  crt_dis += tmp_dis;
792  //printf(" rbt%d crt_dis = %f\n", rid, crt_dis);
793  if(crt_dis == min_dis){
794  //printf(" rbt%d crt_dis == min_dis\n", rid);
795  obj_x = task_poses[rid].x;
796  obj_y = task_poses[rid].y;
797  crt_x = path_poses[rid][pid+1].x;
798  crt_y = path_poses[rid][pid+1].y;
799  // obj_x = path_poses[rid][pid+1].x;
800  // obj_y = path_poses[rid][pid+1].y;
801  // lst_x = path_poses[rid][pid].x;
802  // lst_y = path_poses[rid][pid].y;
803  break;
804  }
805  if(crt_dis > min_dis){
806  //printf(" rbt%d crt_dis > min_dis\n", rid);
807  crt_dis -= tmp_dis;
808  float res_dis = min_dis - crt_dis;
809  {// temp use this
810  obj_x = task_poses[rid].x;
811  obj_y = task_poses[rid].y;
812  crt_x = path_poses[rid][pid+1].x;
813  crt_y = path_poses[rid][pid+1].y;
814  // obj_x = path_poses[rid][pid+1].x;
815  // obj_y = path_poses[rid][pid+1].y;
816  // lst_x = path_poses[rid][pid].x;
817  // lst_y = path_poses[rid][pid].y;
818  }
819  {
820  // to do?
821  }
822 
823  break;
824  }
825  }
826  // compute direction
827  float dx = obj_x - crt_x;
828  float dy = obj_y - crt_y;
829  float dir_theta;
830  // compute rotation
831  if (dx > 0){
832  if(dy == 0){
833  dir_theta = 0;
834  }
835  else{
836  dir_theta = atan(dy / dx);
837  }
838  }
839  else if (dx == 0){
840  if(dy > 0){
841  dir_theta = PI/2;
842  }
843  else if (dy == 0){
844  dir_theta = 0; // need to modify to origin direction
845  }
846  else{// dy < 0
847  dir_theta = -PI/2;
848  }
849  }
850  else{ // dx < 0
851  if(dy>0){
852  dir_theta = PI - fabs(atan(dy / dx));
853  }
854  else if(dy == 0){
855  dir_theta = PI;
856  }
857  else{// dy < 0
858  dir_theta = -(PI - fabs(atan(dy / dx)));
859  }
860  }
861  // set pose
862  setForPose(rid, crt_x, crt_y, camera_height, 0.0*sin(dir_theta/2), 0.0*sin(dir_theta/2), 1.0*sin(dir_theta/2), cos(dir_theta/2));
863  printf("rbt%d not min\n", rid);
864  printf("rbt%d set to (%f, %f)\n", rid, crt_x, crt_y);
865  }
866  }
867  // get scans // send to socket
868  ros::spinOnce();
869  ros::Rate rate(1);
870  //ros::Rate rate(10); // 01-09.
871  rate.sleep();
872  getPose(client_fd);
873  getRGBD(client_fd);
874 
875  //getchar();
876 
877  printf("move correctly\n");
878 
879  //*/
880 
881  return true;
882 }
883 
884 // set up
886 
887  printf("scanning surroundings...\n");
888 
889  //float cover_angle = PI/3;
890  for (int i = 0; i < 6; ++i)
891  {
892  for (int rid = 0; rid < rbtnum; ++rid)
893  {
894  callForPose(rid);
895  float originTheta = acos(pose[6])*2;
896  if(pose[5]<0)
897  originTheta = -originTheta;
898  float dir_theta = originTheta+PI/3;
899  if(dir_theta>PI)
900  dir_theta = -PI + dir_theta - PI;
901  setForPose(rid, pose[0], pose[1], camera_height,
902  0.0*sin(dir_theta/2), 0.0*sin(dir_theta/2), 1.0*sin(dir_theta/2), cos(dir_theta/2));
903 
904  printf("robot_%d turned 60 degree.\n", rid);
905  }
906  // get scans // send to socket
907  printf("ros sleep and spin once to get pose and rgbd...\n");
908  ros::spinOnce();
909  ros::Rate rate(1);
910  //ros::Rate rate(10); // 01-09.
911  rate.sleep();
912  //printf("ros getting pose...\n");
913  getPose(client_fd);
914  //printf("ros getting rgbd...\n");
915  getRGBD(client_fd);
916  }
917 
918  return true;
919 }
920 
921 // set task positions
923  task_poses.clear();
924 
925  // recv data
926  int data_len = rbtnum*2*sizeof(float);
927  char otp_data[MAXRECV];
928  recvData(client_fd, otp_data, data_len);// recv otp data
929 
930  // memcpy to task_poses
931  int ind = 0;
932  for (int rid = 0; rid < rbtnum; ++rid)
933  {
934  float x, y;
935  memcpy(&x, &otp_data[ind], sizeof(float));
936  ind+=sizeof(float);
937  memcpy(&y, &otp_data[ind], sizeof(float));
938  ind+=sizeof(float);
939 
941  task_poses.push_back(crt_p);
942  }
943 
944  return true;
945 }
946 
947 // change robot number
949 {
950  // change robot number
951  rbtnum = number;
952  // re initialization
953  {
954  // frame data.
955  crt_rgb_images.clear();
956  crt_rgb_images.resize(rbtnum);
957  crt_depth_images.clear();
958  crt_depth_images.resize(rbtnum);
959  for (int rid = 0; rid < rbtnum; ++rid)
960  {
961  crt_rgb_images[rid] = cv::Mat(480, 640, CV_8UC3);
962  crt_depth_images[rid] = cv::Mat(480, 640, CV_16UC1);
963  }
964  // ros topics. RGBD.
965  subsColor.clear();
966  subsColor.resize(rbtnum);
967  subsDepth.clear();
968  subsDepth.resize(rbtnum);
969  for (int rid = 0; rid < rbtnum; ++rid)
970  {
971  { // color
972  char topicName[100];
973  sprintf(topicName, "camera%d/rgb/image_raw", rid);
974  //subsColor[rid] = it.subscribe(topicName, 1, boost::bind(rgbImageCallback, _1, int2str(rid)));
975  subsColor[rid] = it->subscribe(topicName, 1, boost::bind(rgbImageCallback, _1, int2str(rid)));
976  }
977  {// depth
978  char topicName[100];
979  sprintf(topicName, "camera%d/depth/image_raw", rid);
980  //subsDepth[rid] = it.subscribe(topicName, 1, boost::bind(depthImageCallback, _1, int2str(rid)));
981  subsDepth[rid] = it->subscribe(topicName, 1, boost::bind(depthImageCallback, _1, int2str(rid)));
982  }
983  }
984  }
985  // end.
986  return;
987 }
988 
989 // change robot number
991 {
992  // recv robot number
993  int data_len = sizeof(int);
994  char recv_data[MAXRECV];
995  recvData(client_fd, recv_data, data_len);
996  int number = rbtnum;
997  memcpy(&number, &recv_data[0], sizeof(int));
998  // change number
1000  printf("changed robot number: %d\n", rbtnum);
1001  return true;
1002 }
1003 
1004 // thread
1005 void *thread(void *ptr)
1006 {
1007  int client = *(int *)ptr;
1008  bool stopped=false;
1009  while(!stopped)
1010  {
1011  char message [MAXRECV+1];
1012  printf("wait for a command...\n");
1013  if(recvData(client_fd, message, MAXRECV+1))
1014  {
1015  printf("message: %s\n", message);
1016  if(message!=NULL&&strlen(message)!=0)
1017  {
1018  printf("command message: %c\n", message[0]);
1019  switch(message[0])
1020  {
1021  case '0':
1022  {
1023  printf("ask for depth\n");
1025  break;
1026  }
1027  case '1':
1028  {
1029  printf("ask for pose\n");
1030  getPose(client_fd);
1031  break;
1032  }
1033  case '2':
1034  {
1035  printf("ask to set pose\n");
1036  setPose(client_fd);
1037  break;
1038  }
1039  case '3':
1040  {
1041  printf("ask for rgbd\n");
1042  getRGBD(client_fd);
1043  break;
1044  }
1045  case '4':
1046  {
1047  printf("ask to set path\n");
1048  setPath(client_fd);
1049  break;
1050  }
1051  case '5':
1052  {
1053  printf("set up surroundings\n");
1055  break;
1056  }
1057  case '6':
1058  {
1059  printf("ask to set task positions\n");
1061  break;
1062  }
1063  case 'm':
1064  {
1065  printf("move_to_views\n");
1067  break;
1068  }
1069  case 'e':
1070  {
1071  printf("command: stop the socket thread\n");
1072  stopped = true;
1073  break;
1074  }
1075  case 'n':
1076  {
1077  printf("check robot number\n");
1079  break;
1080  }
1081  default:
1082  {
1083  printf("invalid command\n");
1084  break;
1085  }
1086  }
1087  }
1088  }
1089  usleep(100000); // 100 ms
1090  }
1091  printf("thread stop done.\n");
1092  return 0;
1093 }
1094 
1095 // enter point
1096 int main(int argc, char **argv){
1097 
1098  printf("this new workspace\n");
1099  //getchar();
1100 
1101  // set up ros env
1102  ros::init(argc, argv, "octo_navi");
1103  ros::NodeHandle n;
1104  it = new image_transport::ImageTransport(n); // need release manually.
1105 
1106  // // write
1107  // ofs_off.open("/home/dsy/catkin_ws/src/virtual_scan/data/offline/pose_history.txt");
1108  // //ofs_off.close();
1109 
1110  // input robot number
1111  {
1112  ifstream ifs("/home/bamboo/catkin_ws/src/virtual_scan/config_nrbt.txt");
1113  ifs>>rbtnum;
1114  ifs.close();
1115  printf("robot number = %d\n", rbtnum);
1116  }
1117 
1118  // initialization
1119  {
1120  // frame data.
1121  crt_rgb_images.clear();
1122  crt_rgb_images.resize(rbtnum);
1123  crt_depth_images.clear();
1124  crt_depth_images.resize(rbtnum);
1125  for (int rid = 0; rid < rbtnum; ++rid)
1126  {
1127  crt_rgb_images[rid] = cv::Mat(480, 640, CV_8UC3);
1128  crt_depth_images[rid] = cv::Mat(480, 640, CV_16UC1);
1129  }
1130  // ros topics. RGBD.
1131  subsColor.clear();
1132  subsColor.resize(rbtnum);
1133  subsDepth.clear();
1134  subsDepth.resize(rbtnum);
1135  for (int rid = 0; rid < rbtnum; ++rid)
1136  {
1137  { // color
1138  char topicName[100];
1139  sprintf(topicName, "camera%d/rgb/image_raw", rid);
1140  //subsColor[rid] = it.subscribe(topicName, 1, boost::bind(rgbImageCallback, _1, int2str(rid)));
1141  subsColor[rid] = it->subscribe(topicName, 1, boost::bind(rgbImageCallback, _1, int2str(rid)));
1142  }
1143  {// depth
1144  char topicName[100];
1145  sprintf(topicName, "camera%d/depth/image_raw", rid);
1146  //subsDepth[rid] = it.subscribe(topicName, 1, boost::bind(depthImageCallback, _1, int2str(rid)));
1147  subsDepth[rid] = it->subscribe(topicName, 1, boost::bind(depthImageCallback, _1, int2str(rid)));
1148  }
1149  }
1150  }
1151 
1152  // kinect calibration
1153  //ros::Subscriber calib_sub = n.subscribe("camera/depth/camera_info", 1, infoCallback);
1154 
1155  // services: pose
1156  gclient = n.serviceClient<gazebo_msgs::GetModelState>("/gazebo/get_model_state");
1157  sclient = n.serviceClient<gazebo_msgs::SetModelState>("/gazebo/set_model_state");
1158 
1159  // // test callback func
1160  // ros::spin();
1161  // return 0;
1162 
1163  // socket
1164  if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1)
1165  {
1166  perror("socket");
1167  exit(1);
1168  }
1169  my_addr.sin_family=AF_INET;
1170  my_addr.sin_port=htons(SERVPORT);
1171  my_addr.sin_addr.s_addr = INADDR_ANY;
1172  bzero(&(my_addr.sin_zero),8);
1173  if (bind(sockfd, (struct sockaddr *)&my_addr, sizeof(struct sockaddr)) == -1)
1174  {
1175  perror("bind");
1176  exit(1);
1177  }
1178  if (listen(sockfd, BACKLOG) == -1)
1179  {
1180  perror("listen");
1181  exit(1);
1182  }
1183 
1184  // set keepalive
1185  {
1186  int keepAlive = 1; // enable keepalive
1187  int keepIdle = 60; // 60 second
1188  int keepInterval = 5; // 5 second
1189  int keepCount = 3;
1190  setsockopt(client_fd, SOL_SOCKET, SO_KEEPALIVE, (void *)&keepAlive, sizeof(keepAlive));
1191  setsockopt(client_fd, SOL_TCP, TCP_KEEPIDLE, (void*)&keepIdle, sizeof(keepIdle));
1192  setsockopt(client_fd, SOL_TCP, TCP_KEEPINTVL, (void *)&keepInterval, sizeof(keepInterval));
1193  setsockopt(client_fd, SOL_TCP, TCP_KEEPCNT, (void *)&keepCount, sizeof(keepCount));
1194  }
1195 
1196  // disable nagle
1197  {
1198  int flag = 1;
1199  if(setsockopt(sockfd, IPPROTO_TCP, TCP_NODELAY, (char*)&flag, sizeof(int))<0){
1200  printf("disable nagle failed\n");
1201  }
1202  }
1203 
1204  while (1)
1205  {
1206  sin_size = sizeof(my_addr);
1207 
1208  printf("%s\n", "waiting for a connection");
1209 
1210  client_fd = accept(sockfd, (struct sockaddr*)&remote_addr, (socklen_t *) &sin_size);
1211 
1212  if (client_fd == -1)
1213  {
1214  perror("failed");
1215  continue;
1216  }
1217 
1218  printf("%s\n", "received a connection");
1219 
1220  // set keepalive
1221  {
1222  int keepAlive = 1;
1223  int keepIdle = 60;
1224  int keepInterval = 5;
1225  int keepCount = 3;
1226  setsockopt(client_fd, SOL_SOCKET, SO_KEEPALIVE, (void *)&keepAlive, sizeof(keepAlive));
1227  setsockopt(client_fd, SOL_TCP, TCP_KEEPIDLE, (void*)&keepIdle, sizeof(keepIdle));
1228  setsockopt(client_fd, SOL_TCP, TCP_KEEPINTVL, (void *)&keepInterval, sizeof(keepInterval));
1229  setsockopt(client_fd, SOL_TCP, TCP_KEEPCNT, (void *)&keepCount, sizeof(keepCount));
1230  }
1231 
1232  // disable nagle
1233  {
1234  int flag = 1;
1235  if(setsockopt(client_fd, IPPROTO_TCP, TCP_NODELAY, (char*)&flag, sizeof(int))<0){
1236  printf("disable nagle failed\n");
1237  }
1238  }
1239 
1240  pthread_t id;
1241  int ret = pthread_create(&id, NULL, thread, &client_fd);
1242  if(ret!=0)
1243  {
1244  printf("Create pthread error: %s\n", strerror(ret));
1245  continue;
1246  }
1247 
1248  printf("succeed connected.\n");
1249 
1250  usleep(100000);
1251  }
1252 
1253  return 0;
1254 }
const float camera_cy
ServiceClient serviceClient(const std::string &service_name, bool persistent=false, const M_string &header_values=M_string())
int rbtnum
int recvData(const int client_fd, char buf[], int len)
const int MAXRECV
cv::Mat shortImg(480, 640, CV_16UC1)
vector< PositionInGazebo > task_poses
int sin_size
int client_fd
int main(int argc, char **argv)
bool depth_ready
void change_robot_number_local(int number)
XmlRpcServer s
ROSCPP_DECL void init(int &argc, char **argv, const std::string &name, uint32_t options=0)
void setForPose(int id, float x, float y, float z, float qx, float qy, float qz, float qw)
cv::Mat rgbImg
bool call(MReq &req, MRes &res)
bool move_to_views(int client_fd)
#define PI
bool getRGBD(int client_fd)
void * thread(void *ptr)
float camera_height
bool pose_ready
string int2str(int n)
vector< image_transport::Subscriber > subsColor(rbtnum)
bool setTaskPositions(int client_fd)
#define SERVPORT
ros::ServiceClient gclient
void depthImageCallback(const sensor_msgs::ImageConstPtr &msg, const std::string &rbtID)
const float camera_cx
int str2int(string s)
ofstream ofs_off
int sendTotalData(const int client_fd, const char *buf, const int len)
vector< vector< PositionInGazebo > > path_poses
int sockfd
void callForPose(int id)
bool getDepth(int client_fd)
#define BACKLOG
float rbt_v
const int times
void infoCallback(const sensor_msgs::CameraInfoConstPtr &msg)
bool sleep()
ros::ServiceClient sclient
image_transport::ImageTransport * it
bool getPose(int client_fd)
bool sendData(const int client_fd, const char *ch, const int len)
void goToPose(float x0, float y0, float qx0, float qy0, float qz0, float qw0, float x1, float y1, float qx1, float qy1, float qz1, float qw1, float x2, float y2, float qx2, float qy2, float qz2, float qw2)
void rgbImageCallback(const sensor_msgs::ImageConstPtr &msg, const std::string &rbtID)
const float camera_fy
bool change_robot_number(int client_fd)
bool scanSurroundings(int client_fd)
const float camera_fx
PositionInGazebo(float ix, float iy, float iz)
vector< cv::Mat > crt_rgb_images(rbtnum)
struct sockaddr_in remote_addr
bool setPath(int client_fd)
const float camera_factor
bool rgb_ready
struct sockaddr_in my_addr
ROSCPP_DECL void spinOnce()
#define ROS_ERROR(...)
vector< cv::Mat > crt_depth_images(rbtnum)
float pose[7]
bool setPose(int client_fd)
vector< image_transport::Subscriber > subsDepth(rbtnum)


virtual_scan
Author(s):
autogenerated on Mon Feb 28 2022 23:02:06