00001 #include "aubo_new_driver/aubo_realtime_communication.h"
00002 #include "aubo_new_driver/do_output.h"
00003
00004 AuboRealtimeCommunication::AuboRealtimeCommunication(
00005 std::condition_variable& msg_cond, std::string host) {
00006 robot_state_ = new RobotState(msg_cond);
00007 bzero((char *) &serv_addr_, sizeof(serv_addr_));
00008 sockfd_ = socket(AF_INET, SOCK_STREAM, 0);
00009 if (sockfd_ < 0) {
00010 print_fatal("ERROR opening socket");
00011 }
00012 server_ = gethostbyname(host.c_str());
00013 if (server_ == NULL) {
00014 print_fatal("ERROR, no such host");
00015 }
00016 serv_addr_.sin_family = AF_INET;
00017 bcopy((char *) server_->h_addr, (char *)&serv_addr_.sin_addr.s_addr, server_->h_length);
00018
00019 serv_addr_.sin_port = htons(8899);
00020 flag_ = 1;
00021 setsockopt(sockfd_, IPPROTO_TCP, TCP_NODELAY, (char *) &flag_, sizeof(int));
00022 setsockopt(sockfd_, IPPROTO_TCP, TCP_QUICKACK, (char *) &flag_, sizeof(int));
00023 setsockopt(sockfd_, SOL_SOCKET, SO_REUSEADDR, (char *) &flag_, sizeof(int));
00024 fcntl(sockfd_, F_SETFL, O_NONBLOCK);
00025 connected_ = false;
00026 keepalive_ = false;
00027 }
00028
00029 bool AuboRealtimeCommunication::start() {
00030 fd_set writefds;
00031 struct timeval timeout;
00032
00033 keepalive_ = true;
00034 print_debug("Realtime port: Connecting...");
00035
00036 connect(sockfd_, (struct sockaddr *) &serv_addr_, sizeof(serv_addr_));
00037
00038 FD_ZERO(&writefds);
00039 FD_SET(sockfd_, &writefds);
00040 timeout.tv_sec = 10;
00041 timeout.tv_usec = 0;
00042 select(sockfd_ + 1, NULL, &writefds, NULL, &timeout);
00043 unsigned int flag_len;
00044 getsockopt(sockfd_, SOL_SOCKET, SO_ERROR, &flag_, &flag_len);
00045 if (flag_ < 0) {
00046 print_fatal("Error connecting to RT port 8899");
00047 return false;
00048 }
00049 sockaddr_in name;
00050 socklen_t namelen = sizeof(name);
00051 int err = getsockname(sockfd_, (sockaddr*) &name, &namelen);
00052 if (err < 0) {
00053 print_fatal("Could not get local IP");
00054 close(sockfd_);
00055 return false;
00056 }
00057 char str[18];
00058 inet_ntop(AF_INET, &name.sin_addr, str, 18);
00059 local_ip_ = str;
00060 comThread_ = std::thread(&AuboRealtimeCommunication::run, this);
00061
00062 return true;
00063 }
00064
00065 void AuboRealtimeCommunication::halt() {
00066 keepalive_ = false;
00067 comThread_.join();
00068 }
00069
00070 void AuboRealtimeCommunication::addCommandToQueue(std::string inp) {
00071 int bytes_written;
00072 if (inp.back() != '\n') {
00073 inp.append("\n");
00074 }
00075 if (connected_)
00076 {
00077 bytes_written = write(sockfd_, inp.c_str(), inp.length());
00078 }
00079 else
00080 print_error("Could not send command \"" +inp + "\". The robot is not connected! Command is discarded" );
00081 }
00082
00083
00084 void AuboRealtimeCommunication::setSpeed(double q0, double q1, double q2,
00085 double q3, double q4, double q5, double acc) {
00086 char cmd[1024];
00087
00088 sprintf(cmd,
00089 "speedj([%1.5f, %1.5f, %1.5f, %1.5f, %1.5f, %1.5f], %f)\n",
00090 q0, q1, q2, q3, q4, q5, acc);
00091
00092 print_info((std::string)cmd);
00093
00094
00095
00096
00097 }
00098
00099 void AuboRealtimeCommunication::setMessagePush(bool flag) {
00100 char cmd[128];
00101 sprintf(cmd, "{\"command\":\"enableMessagePush\",\"data\":{\"value\":%s}}\n",flag ? "true" : "false");
00102
00103 addCommandToQueue((std::string) (cmd));
00104 }
00105
00106 void AuboRealtimeCommunication::getRobotPosition() {
00107 char cmd[128];
00108 sprintf(cmd,"{\"command\":\"getRobotPos\"}\n");
00109 addCommandToQueue((std::string) (cmd));
00110 }
00111
00112 void AuboRealtimeCommunication::getRobotJointStatus() {
00113 char cmd[128];
00114 sprintf(cmd,"{\"command\":\"getRobotJointStatus\"}\n");
00115 addCommandToQueue((std::string) (cmd));
00116 }
00117
00118 void AuboRealtimeCommunication::getRobotSystemStatus() {
00119 char cmd[128];
00120 sprintf(cmd,"{\"command\":\"getRobotSystemStatus\"}\n");
00121 addCommandToQueue((std::string) (cmd));
00122 }
00123
00124 void AuboRealtimeCommunication::getRobotEndSpeed() {
00125 char cmd[128];
00126 sprintf(cmd,"{\"command\":\"getRobotEndSpeed\"}\n");
00127 addCommandToQueue((std::string) (cmd));
00128 }
00129
00130
00131 void AuboRealtimeCommunication::run() {
00132 uint8_t buf[2048];
00133 int bytes_read;
00134 bzero(buf, 2048);
00135 struct timeval timeout;
00136 fd_set readfds;
00137 FD_ZERO(&readfds);
00138 FD_SET(sockfd_, &readfds);
00139 print_debug("Realtime port: Got connection");
00140 connected_ = true;
00141 int time = 0;
00142
00143 setMessagePush(true);
00144
00145 while (keepalive_) {
00146 while (connected_ && keepalive_) {
00147
00148 timeout.tv_sec = 0;
00149 timeout.tv_usec = 50000;
00150 select(sockfd_ + 1, &readfds, NULL, NULL, &timeout);
00151
00152 bzero(buf, 2048);
00153
00154 bytes_read = read(sockfd_, buf, 2048);
00155
00156
00157 if (bytes_read > 0) {
00158 setsockopt(sockfd_, IPPROTO_TCP, TCP_QUICKACK, (char *) &flag_,
00159 sizeof(int));
00160 time = 0;
00161 robot_state_->unpack(buf);
00162 }
00163 else
00164 {
00165 time = time + 1;
00166
00167 if(time > 100)
00168 {
00169 connected_ = false;
00170 close(sockfd_);
00171 time = 0;
00172 }
00173 }
00174
00175 if(connected_ == true)
00176 {
00177
00178 }
00179 }
00180
00181 if (keepalive_) {
00182
00183 print_warning("Realtime port: No connection. Is controller crashed? Will try to reconnect in 10 seconds...");
00184 sockfd_ = socket(AF_INET, SOCK_STREAM, 0);
00185 if (sockfd_ < 0) {
00186 print_fatal("ERROR opening socket");
00187 }
00188 flag_ = 1;
00189 setsockopt(sockfd_, IPPROTO_TCP, TCP_NODELAY, (char *) &flag_,
00190 sizeof(int));
00191 setsockopt(sockfd_, IPPROTO_TCP, TCP_QUICKACK, (char *) &flag_,
00192 sizeof(int));
00193
00194 setsockopt(sockfd_, SOL_SOCKET, SO_REUSEADDR, (char *) &flag_,
00195 sizeof(int));
00196 fcntl(sockfd_, F_SETFL, O_NONBLOCK);
00197
00198 while (keepalive_ && !connected_) {
00199 std::this_thread::sleep_for(std::chrono::seconds(10));
00200 fd_set writefds;
00201
00202 connect(sockfd_, (struct sockaddr *) &serv_addr_,
00203 sizeof(serv_addr_));
00204 FD_ZERO(&writefds);
00205 FD_SET(sockfd_, &writefds);
00206 select(sockfd_ + 1, NULL, &writefds, NULL, NULL);
00207 unsigned int flag_len;
00208 getsockopt(sockfd_, SOL_SOCKET, SO_ERROR, &flag_, &flag_len);
00209 if (flag_ < 0) {
00210 print_error("Error re-connecting to RT port 8899. Is controller started? Will try to reconnect in 10 seconds...");
00211 } else {
00212 connected_ = true;
00213 print_info("Realtime port: Reconnected");
00214 }
00215 }
00216 }
00217 }
00218 setSpeed(0.0, 0.0, 0.0, 0.0, 0.0, 0.0,100);
00219 close(sockfd_);
00220 }
00221
00222
00223 std::string AuboRealtimeCommunication::getLocalIp() {
00224 return local_ip_;
00225 }