AUV-Coop-Assembly
Master Thesis for Robotics Engineering. Cooperative peg-in-hole assembly with two underwater vehicles guided by vision
robotInterface.cpp
1 #include "header/robotInterface.h"
2 
3 
9 RobotInterface::RobotInterface(ros::NodeHandle nh, std::string robotName)
10 {
11 
12  this->robotName = robotName;
13  this->topicRoot = "/uwsim/" + robotName + "/";
14 
15  std::cout << "[" << robotName <<"][ROBOT_INTERFACE] Start"<<std::endl;
16 
17  pubTwist = nh.advertise<geometry_msgs::TwistStamped>((topicRoot + "twist_command"),1);
18  pubJoint = nh.advertise<sensor_msgs::JointState>((topicRoot + "joint_command"),1);
19 
20  subJointState = nh.subscribe(topicRoot+"joint_state", 1, &RobotInterface::subJointStateCallback, this);
21 
22  //force_priv.resize(3, 0.0); //0 for default value
23  //torque_priv.resize(3, 0.0);
24  vectorForceQueue.resize(3);
25  vectorTorqueQueue.resize(3);
26  for (int i =0; i<3; i++){ //3 becuase x y z directions
27  vectorForceQueue.at(i) = boost::circular_buffer<double>(NELEMENTQUEUEFOR);
28  vectorTorqueQueue.at(i) = boost::circular_buffer<double>(NELEMENTQUEUETOR);
29  }
30 
31  //subForceTorque = nh.subscribe(topicRoot+"forceSensorPeg", 1, &RobotInterface::subForceTorqueCallback, this);
32 
33  //hard-coded name for topic, beacuse both robot read from a single force sensor
34  subForceTorque = nh.subscribe("/uwsim/g500_A/forceSensorPeg", 1, &RobotInterface::subForceTorqueCallback, this);
35 }
36 
37 
38 int RobotInterface::init(){
39 
40  if(!ros::ok()){
41  return -1;
42  }
43 
44 
45  //Wait to transform wTv to be ready (or fail if wait more than 3 sec)
46  std::string topic = "/" + robotName;
47  tfListener.waitForTransform("world", topic, ros::Time(0), ros::Duration(3.0));
48 
49  //Wait to joint state to be ready (ie : the callback is called at least once)
50  ros::Rate rate(100);
51  while (jState_priv.size()==0){
52  std::cout << "[" << robotName <<"][ROBOT_INTERFACE] Waiting for Jstate..."
53  <<std::endl;
54  ros::spinOnce();
55  rate.sleep();
56  }
57 
58  std::cout << "[" << robotName <<"][ROBOT_INTERFACE] Init done" << std::endl;
59  return 0;
60 }
61 
62 int RobotInterface::getwTv(Eigen::Matrix4d* wTv_eigen){
63 
64  if(!ros::ok()){
65  return -1;
66  }
67 
68  tf::StampedTransform wTv_tf;
69 
70  std::string topic = "/" + robotName;
71  try {
72  tfListener.lookupTransform("world", topic, ros::Time(0), wTv_tf);
73 
74  } catch (tf::TransformException &ex) {
75  ROS_ERROR("%s",ex.what());
76  ros::Duration(1.0).sleep();
77  }
78 
79 // std::cout << "rosinterface :\n "
80 // << wTv_tf.getBasis().getRow(0).getX() << " " << wTv_tf.getBasis().getRow(0).getY() << " " << wTv_tf.getBasis().getRow(0).getZ() << "\n"
81 // << wTv_tf.getBasis().getRow(1).getX() << " " << wTv_tf.getBasis().getRow(1).getY() << " " << wTv_tf.getBasis().getRow(1).getZ() << "\n"
82 // << wTv_tf.getBasis().getRow(2).getX() <<" " << wTv_tf.getBasis().getRow(2).getY() << " " << wTv_tf.getBasis().getRow(2).getZ() << "\n"
83 // << "\n\n";
84 
85 // std::cout << "rosinterface :\n "
86  // << wTv_tf.getRotation().getX() << " " << wTv_tf.getRotation().getY() << " " << wTv_tf.getRotation().getZ() << " " << wTv_tf.getRotation().getW() << "\n";
87 
88  *wTv_eigen = CONV::transfMatrix_tf2eigen(wTv_tf);
89 
90  return 0;
91 }
92 
93 
94 void RobotInterface::subJointStateCallback(const sensor_msgs::JointState& js)
95 {
96  jState_priv = js.position;
97 }
98 
105 int RobotInterface::getJointState(std::vector<double> *jState){
106 
107  if(!ros::ok()){
108  return -1;
109  }
110 
111  *jState = jState_priv;
112  return 0;
113 }
114 
119 void RobotInterface::subForceTorqueCallback(const geometry_msgs::WrenchStamped& msg){
120 
121  //std::vector<double> force_priv(3); //with queues they dont need to be member of class
122  //force_priv.at(0) = msg.wrench.force.x;
123  //force_priv.at(1) = msg.wrench.force.y;
124  //force_priv.at(2) = msg.wrench.force.z;
125  vectorForceQueue.at(0).push_back(msg.wrench.force.x);
126  vectorForceQueue.at(1).push_back(msg.wrench.force.y);
127  vectorForceQueue.at(2).push_back(msg.wrench.force.z);
128 
129 
130  //std::vector<double> torque_priv(3);
131  //torque_priv.at(0) = msg.wrench.torque.x;
132  //torque_priv.at(1) = msg.wrench.torque.y;
133  //torque_priv.at(2) = msg.wrench.torque.z;
134  vectorTorqueQueue.at(0).push_back(msg.wrench.torque.x);
135  vectorTorqueQueue.at(1).push_back(msg.wrench.torque.y);
136  vectorTorqueQueue.at(2).push_back(msg.wrench.torque.z);
137 }
138 
139 
140 int RobotInterface::getForceTorque(Eigen::Vector3d *force, Eigen::Vector3d *torque){
141 
142  if (vectorForceQueue.at(0).size() == 0){ // no sensor data yet
143  *force << 0, 0, 0;
144  *torque << 0, 0, 0;
145  return 1;
146  }
147 
148  std::vector<double> sumForces (3);
149  std::vector<double> sumTorques (3);
150 
151  for (int i=0; i<3; i++){
152  sumForces.at(i) = std::accumulate(vectorForceQueue.at(i).begin(), vectorForceQueue.at(i).end(), 0.0); //0 init the sum to 0
153  sumTorques.at(i) = std::accumulate(vectorTorqueQueue.at(i).begin(), vectorTorqueQueue.at(i).end(), 0.0); //0 init the sum to 0
154 
155  sumForces.at(i) /= vectorForceQueue.at(i).size();
156  sumTorques.at(i) /= vectorTorqueQueue.at(i).size();
157  }
158 
159 
160  *force = CONV::vector_std2Eigen(sumForces);
161  *torque = CONV::vector_std2Eigen(sumTorques);
162  return 0;
163 }
164 
165 
166 
167 int RobotInterface::sendyDot(std::vector<double> yDot){
168 
169  if(!ros::ok()){
170  return -1;
171  }
172  sensor_msgs::JointState js;
173  js.name.push_back(std::string("Slew"));
174  js.velocity.push_back(yDot.at(0));
175  js.name.push_back(std::string("Shoulder"));
176  js.velocity.push_back(yDot.at(1));
177  js.name.push_back(std::string("Elbow"));
178  js.velocity.push_back(yDot.at(2));
179  js.name.push_back(std::string("JawRotate"));
180  js.velocity.push_back(yDot.at(3));
181  geometry_msgs::TwistStamped twist;
182  twist.twist.linear.x=yDot.at(4);
183  twist.twist.linear.y=yDot.at(5);
184  twist.twist.linear.z=yDot.at(6);
185  twist.twist.angular.x=yDot.at(7);
186  twist.twist.angular.y=yDot.at(8);
187  twist.twist.angular.z=yDot.at(9);
188 
189  pubJoint.publish(js);
190  pubTwist.publish(twist);
191  return 0;
192 
193 }
194 
195 
196 
197 //int RobotInterface::getwTjoints(std::vector<Eigen::Matrix4d> *wTjoints) {
198 // if(!ros::ok()){
199 // return -1;
200 // }
201 
202 // std::vector<tf::StampedTransform> wTJoints_tf(ARM_DOF);
203 
204 // try {
205 // for(int i=0; i<ARM_DOF; i++){
206 // std::ostringstream s;
207 // s << (i+1);
208 // const std::string si(s.str());
209 // std::string topic = "/" + robotName +"/part" + si;
210 // if (i==3){
211 // topic += "_base";
212 // }
213 // tfListener.lookupTransform("world", topic, ros::Time(0), wTJoints_tf[i]);
214 // }
215 
216 
217 // } catch (tf::TransformException &ex) {
218 // ROS_ERROR("%s",ex.what());
219 // ros::Duration(1.0).sleep();
220 // }
221 
222 // for(int i=0; i<ARM_DOF; i++){
223 // wTjoints->push_back(CONV::transfMatrix_tf2eigen(wTJoints_tf[i]));
224 // }
225 
226 
227 // return 0;
228 //}
229 
int getJointState(std::vector< double > *jState)
robotInterface::getJointState
RobotInterface(ros::NodeHandle nh, std::string robotName)
robotInterface::robotInterface Constructor