00001 #include "ros/ros.h"
00002 #include "std_msgs/String.h"
00003 #include <sstream>
00004 #include <sensor_msgs/JointState.h>
00005
00006
00007 #include <stdio.h>
00008 #include <string.h>
00009 #include <sys/socket.h>
00010 #include <arpa/inet.h>
00011
00012 #include "ROSLANData.h"
00013
00014
00015 #include <nav_msgs/Odometry.h>
00016 #include <geometry_msgs/Twist.h>
00017 #include <drc_podo_connector/DRC_HEAD_CMD.h>
00018 #include <drc_podo_connector/SendPos.h>
00019
00020 #include <tf/transform_broadcaster.h>
00021 #include <tf/transform_listener.h>
00022
00023
00024 #define PODO_ADDR "10.12.3.30"
00025
00026 #define PODO_PORT 5000
00027
00028 const float D2Rf = 0.0174533;
00029 const float R2Df = 57.2957802;
00030 char ip[20];
00031
00032 int sock = 0;
00033 struct sockaddr_in server;
00034
00035 pthread_t LANTHREAD_t;
00036 int threadWorking = false;
00037 int connectionStatus = false;
00038
00039
00040 int CreateSocket(const char *addr, int port);
00041 int Connect2Server();
00042 void* LANThread(void*);
00043 void NewRXData();
00044
00045 LAN_PODO2ROS RXData;
00046 LAN_ROS2PODO TXData;
00047
00048 int RXDataSize;
00049 int TXDataSize;
00050 void* RXBuffer;
00051 void* TXBuffer;
00052
00053
00054 sensor_msgs::JointState joint_state;
00055 ros::Publisher joint_pub;
00056 ros::Publisher head_cmd_pub;
00057 ros::Publisher odom_pub;
00058
00059
00060 tf::TransformBroadcaster *podom_broadcaster;
00061 tf::TransformBroadcaster *pfootprint_broadcaster;
00062
00063 ros::Subscriber base_move_sub;
00064 ros::Subscriber obj_pos_sub;
00065
00066
00067 void base_move_callback(const geometry_msgs::Twist::ConstPtr &msg){
00068 if(connectionStatus){
00069 TXData.vx = msg->linear.x;
00070 TXData.vth = -msg->angular.z;
00071
00072 write(sock, &TXData, TXDataSize);
00073
00074 }
00075 }
00076
00077 void send_pos_callback(const drc_podo_connector::SendPos::ConstPtr &msg){
00078 std::cout << "send_pos_callback" << std::endl;
00079 if(connectionStatus){
00080 tf::TransformListener listener;
00081 tf::StampedTransform streaming;
00082 std::string b_stream = "Sensor_streaming";
00083 std::string b_tor = "Body_TORSO";
00084 ros::Duration timeout(0.05);
00085 try{
00086 listener.waitForTransform(b_tor, b_stream, ros::Time(0), ros::Duration(0.05));
00087 listener.lookupTransform(b_tor, b_stream, ros::Time(0), streaming);
00088
00089 tf::Transform tempTF;
00090 tf::Transform objTF;
00091 objTF.setIdentity();
00092 objTF.setOrigin(tf::Vector3(msg->x, msg->y, msg->z));
00093 tempTF.mult(streaming, objTF);
00094
00095 TXData.pos[0] = tempTF.getOrigin().x();
00096 TXData.pos[1] = tempTF.getOrigin().y();
00097 TXData.pos[2] = tempTF.getOrigin().z();
00098
00099 write(sock, &TXData, TXDataSize);
00100 std::cout << TXData.pos[0] << ", " << TXData.pos[1] << ", " << TXData.pos[2] << std::endl;
00101 }catch(tf::TransformException &ex){
00102
00103 }
00104 }
00105 }
00106
00107
00108 int main(int argc, char **argv)
00109 {
00110 std::cout << "\033[1;32m===================================" << std::endl;
00111 std::cout << " Now Start the PODOConnetor..!!" << std::endl << std::endl;
00112 std::cout << " Developer: Jeongsoo Lim" << std::endl;
00113 std::cout << " E-mail : yjs0497@kaist.ac.kr" << std::endl;
00114 std::cout << "===================================\033[0m" << std::endl;
00115
00116 ros::init(argc, argv, "podo_connector");
00117 ros::NodeHandle n;
00118 joint_pub = n.advertise<sensor_msgs::JointState>("joint_states", 1);
00119 head_cmd_pub = n.advertise<drc_podo_connector::DRC_HEAD_CMD>("drc_head_cmd", 1);
00120 odom_pub = n.advertise<nav_msgs::Odometry>("odom", 20);
00121
00122 base_move_sub = n.subscribe("/cmd_vel", 10, base_move_callback);
00123 obj_pos_sub = n.subscribe("send_pos_topic", 10, send_pos_callback);
00124
00125 tf::TransformBroadcaster odom_broadcaster;
00126 podom_broadcaster = &odom_broadcaster;
00127 tf::TransformBroadcaster footprint_broadcaster;
00128 pfootprint_broadcaster = &footprint_broadcaster;
00129
00130
00131 joint_state.name.resize(NO_OF_JOINTS+9*2+4+1+4);
00132 joint_state.position.resize(NO_OF_JOINTS+9*2+4+1+4);
00133 for(int i=0; i<NO_OF_JOINTS; i++){
00134 if(i == RHAND || i == LHAND)
00135 continue;
00136 joint_state.name[i] = JointNameList[i];
00137 }
00138 joint_state.name[RHAND] = "RFWH";
00139 joint_state.name[LHAND] = "LFWH";
00140
00141 joint_state.name[NO_OF_JOINTS + 0] = "LHAND_a1";
00142 joint_state.name[NO_OF_JOINTS + 1] = "LHAND_a2";
00143 joint_state.name[NO_OF_JOINTS + 2] = "LHAND_a3";
00144 joint_state.name[NO_OF_JOINTS + 3] = "LHAND_b1";
00145 joint_state.name[NO_OF_JOINTS + 4] = "LHAND_b2";
00146 joint_state.name[NO_OF_JOINTS + 5] = "LHAND_b3";
00147 joint_state.name[NO_OF_JOINTS + 6] = "LHAND_c1";
00148 joint_state.name[NO_OF_JOINTS + 7] = "LHAND_c2";
00149 joint_state.name[NO_OF_JOINTS + 8] = "LHAND_c3";
00150
00151 joint_state.name[NO_OF_JOINTS + 9 + 0] = "RHAND_a1";
00152 joint_state.name[NO_OF_JOINTS + 9 + 1] = "RHAND_a2";
00153 joint_state.name[NO_OF_JOINTS + 9 + 2] = "RHAND_a3";
00154 joint_state.name[NO_OF_JOINTS + 9 + 3] = "RHAND_b1";
00155 joint_state.name[NO_OF_JOINTS + 9 + 4] = "RHAND_b2";
00156 joint_state.name[NO_OF_JOINTS + 9 + 5] = "RHAND_b3";
00157 joint_state.name[NO_OF_JOINTS + 9 + 6] = "RHAND_c1";
00158 joint_state.name[NO_OF_JOINTS + 9 + 7] = "RHAND_c2";
00159 joint_state.name[NO_OF_JOINTS + 9 + 8] = "RHAND_c3";
00160
00161 joint_state.name[NO_OF_JOINTS + 18 + 0] = "RAFT";
00162 joint_state.name[NO_OF_JOINTS + 18 + 1] = "LAFT";
00163 joint_state.name[NO_OF_JOINTS + 18 + 2] = "RWFT";
00164 joint_state.name[NO_OF_JOINTS + 18 + 3] = "LWFT";
00165
00166 joint_state.name[NO_OF_JOINTS + 18 + 4] = "head_joint";
00167
00168 joint_state.name[NO_OF_JOINTS + 18 + 5] = "RFWH";
00169 joint_state.name[NO_OF_JOINTS + 18 + 6] = "LFWH";
00170 joint_state.name[NO_OF_JOINTS + 18 + 7] = "RFUNI";
00171 joint_state.name[NO_OF_JOINTS + 18 + 8] = "LFUNI";
00172
00173
00174 ros::Rate loop_rate(50);
00175
00176
00177 FILE *fpNet = NULL;
00178 fpNet = fopen("/home/hubo/catkin_ws/src/drc_hubo/ros/settings/network.txt", "r");
00179 if(fpNet == NULL){
00180 std::cout << ">>> Network File Open Error..!!" << std::endl;
00181 sprintf(ip, PODO_ADDR);
00182 }else{
00183 std::cout << ">>> Network File Open Success..!!" << std::endl;
00184 fscanf(fpNet, "%s", ip);
00185 fclose(fpNet);
00186 }
00187
00188 if(CreateSocket(ip, PODO_PORT)){
00189 ROS_INFO("Created Socket..");
00190
00191 RXDataSize = sizeof(LAN_PODO2ROS);
00192 TXDataSize = sizeof(LAN_ROS2PODO);
00193 RXBuffer = (void*)malloc(RXDataSize);
00194 TXBuffer = (void*)malloc(TXDataSize);
00195 int threadID = pthread_create(&LANTHREAD_t, NULL, &LANThread, NULL);
00196 if(threadID < 0){
00197 ROS_ERROR("Create Thread Error..");
00198 return 0;
00199 }
00200 }else{
00201 ROS_ERROR("Create Socket Error..");
00202 ROS_ERROR("Terminate Node..");
00203 return 0;
00204 }
00205
00206
00207
00208 tf::TransformListener listener;
00209 tf::StampedTransform left;
00210 tf::StampedTransform right;
00211 ros::Time tzero(0);
00212
00213 while(ros::ok()){
00214 ros::spinOnce();
00215
00216
00217 if(RXData.JointEncoder[RKN] > 145.0 && RXData.JointEncoder[LKN] > 145.0){
00218 try{
00219 listener.lookupTransform("Body_TORSO", "Body_LWH", tzero, left);
00220 listener.lookupTransform("Body_TORSO", "Body_RWH", tzero, right);
00221
00222 float x = (left.getOrigin().x() + right.getOrigin().x()) / 2.0;
00223 float y = (left.getOrigin().y() + right.getOrigin().y()) / 2.0;
00224 float z = (left.getOrigin().z() + right.getOrigin().z()) / 2.0 - 0.06;
00225 pfootprint_broadcaster->sendTransform(
00226 tf::StampedTransform(
00227 tf::Transform(
00228 tf::Quaternion(0,0,0,1),
00229 tf::Vector3(-x,-y,-z)),
00230 ros::Time::now(),
00231 "base_footprint",
00232 "Body_TORSO"));
00233
00234 }catch(tf::TransformException &ex){
00235
00236 }
00237 }
00238
00239 else{
00240 try{
00241 listener.lookupTransform("Body_RAFT", "Body_TORSO", tzero, right);
00242 listener.lookupTransform("Body_LAFT", "Body_TORSO", tzero, left);
00243
00244 float x, y, z;
00245 if(fabs(left.getOrigin().z()-right.getOrigin().z()) < 0.03){
00246 x = (left.getOrigin().x() + right.getOrigin().x()) / 2.0;
00247 y = (left.getOrigin().y() + right.getOrigin().y()) / 2.0;
00248 z = (left.getOrigin().z() + right.getOrigin().z()) / 2.0 + 0.05;
00249
00250 pfootprint_broadcaster->sendTransform(
00251 tf::StampedTransform(
00252 tf::Transform(
00253
00254 tf::Quaternion(0,0,0,1),
00255 tf::Vector3(x, y, z)),
00256 ros::Time::now(),
00257 "base_footprint",
00258 "Body_TORSO"));
00259 }else if(right.getOrigin().z() > left.getOrigin().z()){
00260 x = right.getOrigin().x();
00261 y = right.getOrigin().y();
00262 z = right.getOrigin().z() + 0.05;
00263
00264 pfootprint_broadcaster->sendTransform(
00265 tf::StampedTransform(
00266 tf::Transform(
00267
00268 tf::Quaternion(0,0,0,1),
00269 tf::Vector3(x, y, z)),
00270 ros::Time::now(),
00271 "base_footprint",
00272 "Body_TORSO"));
00273 }else if(left.getOrigin().z() > right.getOrigin().z()){
00274 x = left.getOrigin().x();
00275 y = left.getOrigin().y();
00276 z = left.getOrigin().z() + 0.05;
00277
00278 pfootprint_broadcaster->sendTransform(
00279 tf::StampedTransform(
00280 tf::Transform(
00281
00282 tf::Quaternion(0,0,0,1),
00283 tf::Vector3(x, y, z)),
00284 ros::Time::now(),
00285 "base_footprint",
00286 "Body_TORSO"));
00287 }
00288
00289 }catch(tf::TransformException &ex){
00290
00291 }
00292 }
00293
00294 loop_rate.sleep();
00295 }
00296 return 0;
00297 }
00298
00299
00300 int CreateSocket(const char *addr, int port){
00301 sock = socket(AF_INET, SOCK_STREAM, 0);
00302 if(sock == -1){
00303 return false;
00304 }
00305 server.sin_addr.s_addr = inet_addr(addr);
00306 server.sin_family = AF_INET;
00307 server.sin_port = htons(port);
00308
00309 int optval = 1;
00310 setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval));
00311 setsockopt(sock, SOL_SOCKET, SO_REUSEPORT, &optval, sizeof(optval));
00312
00313 return true;
00314 }
00315
00316
00317 int Connect2Server(){
00318 if(connect(sock, (struct sockaddr*)&server, sizeof(server)) < 0){
00319 return false;
00320 }
00321 std::cout << "Client connect to server!! (PODO_CONNECTOR)" << std::endl;
00322 return true;
00323 }
00324
00325 void NewRXData(){
00326 joint_state.header.stamp = ros::Time::now();
00327 for(int i=0; i<NO_OF_JOINTS; i++){
00328 if(i == RHAND || i == LHAND){
00329 joint_state.position[i] = 0.0;
00330 continue;
00331 }
00332 joint_state.position[i] = RXData.JointEncoder[i] * D2Rf;
00333 }
00334 joint_state.position[LEB] += -20.0 * D2Rf;
00335 joint_state.position[REB] += -20.0 * D2Rf;
00336 joint_state.position[RSR] += -15.0 * D2Rf;
00337 joint_state.position[LSR] += 15.0 * D2Rf;
00338
00339 for(int i=0; i<9; i++){
00340 joint_state.position[NO_OF_JOINTS + i] = RXData.JointEncoder[LHAND] * D2Rf;
00341 joint_state.position[NO_OF_JOINTS + 9 + i] = RXData.JointEncoder[RHAND] *D2Rf;
00342 }
00343 joint_state.position[NO_OF_JOINTS + 18 + 0] = 0.0;
00344 joint_state.position[NO_OF_JOINTS + 18 + 1] = 0.0;
00345 joint_state.position[NO_OF_JOINTS + 18 + 2] = 0.0;
00346 joint_state.position[NO_OF_JOINTS + 18 + 3] = 0.0;
00347
00348 joint_state.position[NO_OF_JOINTS + 18 + 4] = 0.0;
00349
00350 joint_state.position[NO_OF_JOINTS + 18 + 5] = 0.0;
00351 joint_state.position[NO_OF_JOINTS + 18 + 6] = 0.0;
00352 joint_state.position[NO_OF_JOINTS + 18 + 7] = 0.0;
00353 joint_state.position[NO_OF_JOINTS + 18 + 8] = 0.0;
00354
00355 joint_pub.publish(joint_state);
00356
00357
00358
00359
00360
00361
00362 geometry_msgs::Quaternion odom_quat = tf::createQuaternionMsgFromYaw(RXData.odom_theta);
00363
00364
00365 geometry_msgs::TransformStamped odom_trans;
00366 odom_trans.header.stamp = ros::Time::now();
00367 odom_trans.header.frame_id = "odom";
00368 odom_trans.child_frame_id = "base_footprint";
00369
00370 odom_trans.transform.translation.x = RXData.odom_x;
00371 odom_trans.transform.translation.y = RXData.odom_y;
00372 odom_trans.transform.translation.z = 0.0;
00373 odom_trans.transform.rotation = odom_quat;
00374
00375
00376 podom_broadcaster->sendTransform(odom_trans);
00377
00378
00379 nav_msgs::Odometry odom;
00380 odom.header.stamp = ros::Time::now();
00381 odom.header.frame_id = "odom";
00382
00383
00384 odom.pose.pose.position.x = RXData.odom_x;
00385 odom.pose.pose.position.y = RXData.odom_y;
00386 odom.pose.pose.position.z = 0.0;
00387 odom.pose.pose.orientation = odom_quat;
00388
00389
00390 odom.child_frame_id = "base_link";
00391 odom.twist.twist.linear.x = RXData.vx;
00392 odom.twist.twist.linear.y = RXData.vy;
00393 odom.twist.twist.angular.z = RXData.vth;
00394
00395
00396 odom_pub.publish(odom);
00397
00398
00399 drc_podo_connector::DRC_HEAD_CMD cmd;
00400 switch(RXData.cmd.cmd){
00401 case 1:
00402 cmd.cmd = 1;
00403 cmd.start_pos = RXData.cmd.param_f[0];
00404 cmd.end_pos = RXData.cmd.param_f[1];
00405 cmd.timeMs = RXData.cmd.param_f[2];
00406 head_cmd_pub.publish(cmd);
00407 break;
00408 case 2:
00409 cmd.cmd = 2;
00410 cmd.end_pos = RXData.cmd.param_f[0];
00411 head_cmd_pub.publish(cmd);
00412 break;
00413 }
00414 }
00415
00416 void* LANThread(void *){
00417 threadWorking = true;
00418
00419 unsigned int tcp_status = 0x00;
00420 int tcp_size = 0;
00421 int connectCnt = 0;
00422
00423 while(threadWorking){
00424 usleep(100);
00425 if(tcp_status == 0x00){
00426
00427 if(sock == 0){
00428 CreateSocket(ip, PODO_PORT);
00429 }
00430 if(Connect2Server()){
00431 tcp_status = 0x01;
00432 connectionStatus = true;
00433 connectCnt = 0;
00434 }else{
00435 if(connectCnt%10 == 0)
00436 std::cout << "Connect to Server Failed.." << std::endl;
00437 connectCnt++;
00438 }
00439 usleep(1000*1000);
00440 }
00441 if(tcp_status == 0x01){
00442
00443 tcp_size = read(sock, RXBuffer, RXDataSize);
00444 if(tcp_size == RXDataSize){
00445 memcpy(&RXData, RXBuffer, RXDataSize);
00446 NewRXData();
00447 }
00448
00449 if(tcp_size == 0){
00450 tcp_status = 0x00;
00451 connectionStatus = false;
00452 close(sock);
00453 sock = 0;
00454 std::cout << "Socket Disconnected.." << std::endl;
00455 }
00456 }
00457 }
00458 return NULL;
00459 }