podo_connector.cpp
Go to the documentation of this file.
00001 #include "ros/ros.h"
00002 #include "std_msgs/String.h"
00003 #include <sstream>
00004 #include <sensor_msgs/JointState.h>
00005 
00006 // for socket client
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 //#define PODO_ADDR       "127.0.0.1"
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         //ROS_ERROR("%f, %f", msg->linear.x, msg->angular.z);
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             //ROS_WARN("%s",ex.what());
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"; // use for foot passive wheel
00139     joint_state.name[LHAND] = "LFWH"; // use for foot passive wheel
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     // Create Socket ---------------------
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         // Wheel Mode
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 //                std::cout << "Wheel Mode: " << x << ", " << y << ", " << z << std::endl;
00234             }catch(tf::TransformException &ex){
00235                 //ROS_WARN("%s",ex.what());
00236             }
00237         }
00238         // Walking Mode
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 //                                        tf::Quaternion(q.x, q.y, q.z, q.w),
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 //                                        tf::Quaternion(q.x, q.y, q.z, q.w),
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 //                                        tf::Quaternion(q.x, q.y, q.z, q.w),
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                 //ROS_WARN("%s",ex.what());
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     // Wheel Mode
00361 //    if(RXData.JointEncoder[RKN] > 145.0 && RXData.JointEncoder[LKN] > 145.0){
00362         geometry_msgs::Quaternion odom_quat = tf::createQuaternionMsgFromYaw(RXData.odom_theta);
00363 
00364         //first, we'll publish the transform over tf
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";   // "wheel_center";
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         //send the transform
00376         podom_broadcaster->sendTransform(odom_trans);
00377 
00378         //next, we'll publish the odometry message over ROS
00379         nav_msgs::Odometry odom;
00380         odom.header.stamp = ros::Time::now();
00381         odom.header.frame_id = "odom";
00382 
00383         //set the position
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         //set the velocity
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         //publish the message
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             // If client was not connected
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             // If client was connected
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 }


drc_podo_connector
Author(s): JeongsooLim , SeungwooHong
autogenerated on Sat Jul 22 2017 02:25:35