AUV-Coop-Assembly
Master Thesis for Robotics Engineering. Cooperative peg-in-hole assembly with two underwater vehicles guided by vision
robotVisionInterface.cpp
1 #include "header/robotVisionInterface.h"
2 
3 
11 RobotVisionInterface::RobotVisionInterface(ros::NodeHandle nh, std::string robotName)
12 {
13 
14  this->robotName = robotName;
15  this->topicRoot = "/uwsim/" + robotName + "/";
16 
17  std::cout << "[" << robotName <<"][ROBOT_VISION_INTERFACE] Start"<<std::endl;
18 
19  pubTwist = nh.advertise<geometry_msgs::TwistStamped>((topicRoot + "twist_command"),1);
20 
21  image_transport::ImageTransport it(nh);
22  subLeftImage = it.subscribe(topicRoot + "cameraL", 1, &RobotVisionInterface::imageLeftCallback, this);
23  subRightImage = it.subscribe(topicRoot + "cameraR", 1, &RobotVisionInterface::imageRightCallback, this);
24  subRangeRightImage = it.subscribe(topicRoot + "rangeCameraR", 1, &RobotVisionInterface::imageRangeRightCallback, this);
25 }
26 
27 
28 int RobotVisionInterface::init(){
29 
30  if(!ros::ok()){
31  return -1;
32  }
33 
34  //Wait to transform wTv to be ready (or fail if wait more than 3 sec)
35  std::string topic = "/" + robotName;
36  tfListener.waitForTransform("world", topic, ros::Time(0), ros::Duration(3.0));
37 
38  //Wait for images to be ready (ie : the callbacks are called at least once)
39  ros::Rate loop_rate(100); //100Hz
40  while (leftImage == NULL) {
41 
42  std::cout << "[" << robotName <<"][ROBOT_VISION_INTERFACE] No left images yet..." << std::endl;
43  ros::spinOnce();
44  loop_rate.sleep();
45  }
46 
47  while (rightImage == NULL) {
48 
49  std::cout << "[" << robotName <<"][ROBOT_VISION_INTERFACE] No right images yet..." << std::endl;
50  ros::spinOnce();
51  loop_rate.sleep();
52  }
53 
54 
55  std::cout << "[" << robotName <<"][ROBOT_VISION_INTERFACE] Init done" << std::endl;
56 
57  return 0;
58 }
59 
60 int RobotVisionInterface::getwTv(Eigen::Matrix4d* wTv_eigen){
61 
62  if(!ros::ok()){
63  return -1;
64  }
65 
66  tf::StampedTransform wTv_tf;
67 
68  std::string topic = "/" + robotName;
69  try {
70  tfListener.lookupTransform("world", topic, ros::Time(0), wTv_tf);
71 
72  } catch (tf::TransformException &ex) {
73  ROS_ERROR("%s",ex.what());
74  ros::Duration(1.0).sleep();
75  }
76 
77  *wTv_eigen = CONV::transfMatrix_tf2eigen(wTv_tf);
78 
79  return 0;
80 }
81 
82 
83 int RobotVisionInterface::sendyDot(std::vector<double> yDot){
84 
85  if(!ros::ok()){
86  return -1;
87  }
88  if (yDot.size() != 6){
89  std::cout << "[" << robotName <<"][ROBOT_VISION_INTERFACE] yDot must be of size 6 instead of "
90  << yDot.size() << std::endl;
91  return -2;
92  }
93 
94  geometry_msgs::TwistStamped twist;
95  twist.twist.linear.x=yDot.at(0);
96  twist.twist.linear.y=yDot.at(1);
97  twist.twist.linear.z=yDot.at(2);
98  twist.twist.angular.x=yDot.at(3);
99  twist.twist.angular.y=yDot.at(4);
100  twist.twist.angular.z=yDot.at(5);
101 
102  pubTwist.publish(twist);
103  return 0;
104 }
105 
106 
107 
116 
117 //sensor_msgs::image_encodings::MONO8 old second argument of toCvCopy (neded for detection with templ match)
118  cv_bridge::CvImagePtr imageCVPtr =
119  cv_bridge::toCvCopy(leftImage, sensor_msgs::image_encodings::MONO8);
120  *imageCV = imageCVPtr.get()->image;
121  //cut top part of image where a piece of auv is visible and can distract cv algos
122  //note: doing this camera param are changed: -60px for v0 element
123  (*imageCV) = (*imageCV)(cv::Rect(0, 60, (*imageCV).cols, (*imageCV).rows-60));
124  return 0;
125 
126 }
127 
128 int RobotVisionInterface::getRightImage(cv::Mat *imageCV){
129 
130  cv_bridge::CvImagePtr imageCVPtr =
131  cv_bridge::toCvCopy(rightImage, sensor_msgs::image_encodings::MONO8);
132  *imageCV = imageCVPtr.get()->image;
133  //cut top part of image where a piece of auv is visible and can distract cv algos
134  //note: doing this camera param are changed: -60px for v0 element
135  (*imageCV) = (*imageCV)(cv::Rect(0, 60, (*imageCV).cols, (*imageCV).rows-60));
136  return 0;
137 
138 }
139 
140 int RobotVisionInterface::getRangeRightImage(cv::Mat *imageCV){
141 
142  cv_bridge::CvImagePtr imageCVPtr =
143  cv_bridge::toCvCopy(rangeRightImage, "32FC1");
144  *imageCV = imageCVPtr.get()->image;
145 
146  return 0;
147 
148 }
149 
155 void RobotVisionInterface::imageLeftCallback(const sensor_msgs::ImageConstPtr& msg)
156 {
157  leftImage = msg;
158 }
159 
160 void RobotVisionInterface::imageRightCallback(const sensor_msgs::ImageConstPtr& msg)
161 {
162  rightImage = msg;
163 }
164 
165 void RobotVisionInterface::imageRangeRightCallback(const sensor_msgs::ImageConstPtr& msg)
166 {
167  rangeRightImage = msg;
168 }
void imageLeftCallback(const sensor_msgs::ImageConstPtr &msg)
RobotVisionInterface::imageLeftCallback store in member class the image arrived, process it only when...
int getLeftImage(cv::Mat *imageCV)
RobotVisionInterface::getLeftImage for now convert in 8bit grayscale image.
RobotVisionInterface(ros::NodeHandle nh, std::string robotName)
RobotVisionInterface::RobotInterfaceVision Constructor.