00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #include "ur_modern_driver/ur_communication.h"
00020
00021 UrCommunication::UrCommunication(std::condition_variable& msg_cond,
00022 std::string host) {
00023 robot_state_ = new RobotState(msg_cond);
00024 bzero((char *) &pri_serv_addr_, sizeof(pri_serv_addr_));
00025 bzero((char *) &sec_serv_addr_, sizeof(sec_serv_addr_));
00026 pri_sockfd_ = socket(AF_INET, SOCK_STREAM, 0);
00027 if (pri_sockfd_ < 0) {
00028 print_fatal("ERROR opening socket pri_sockfd");
00029 }
00030 sec_sockfd_ = socket(AF_INET, SOCK_STREAM, 0);
00031 if (sec_sockfd_ < 0) {
00032 print_fatal("ERROR opening socket sec_sockfd");
00033 }
00034 server_ = gethostbyname(host.c_str());
00035 if (server_ == NULL) {
00036 print_fatal("ERROR, unknown host");
00037 }
00038 pri_serv_addr_.sin_family = AF_INET;
00039 sec_serv_addr_.sin_family = AF_INET;
00040 bcopy((char *) server_->h_addr, (char *)&pri_serv_addr_.sin_addr.s_addr, server_->h_length);
00041 bcopy((char *) server_->h_addr, (char *)&sec_serv_addr_.sin_addr.s_addr, server_->h_length);
00042 pri_serv_addr_.sin_port = htons(30001);
00043 sec_serv_addr_.sin_port = htons(30002);
00044 flag_ = 1;
00045 setsockopt(pri_sockfd_, IPPROTO_TCP, TCP_NODELAY, (char *) &flag_,
00046 sizeof(int));
00047 setsockopt(pri_sockfd_, IPPROTO_TCP, TCP_QUICKACK, (char *) &flag_,
00048 sizeof(int));
00049 setsockopt(pri_sockfd_, SOL_SOCKET, SO_REUSEADDR, (char *) &flag_,
00050 sizeof(int));
00051 setsockopt(sec_sockfd_, IPPROTO_TCP, TCP_NODELAY, (char *) &flag_,
00052 sizeof(int));
00053 setsockopt(sec_sockfd_, IPPROTO_TCP, TCP_QUICKACK, (char *) &flag_,
00054 sizeof(int));
00055 setsockopt(sec_sockfd_, SOL_SOCKET, SO_REUSEADDR, (char *) &flag_,
00056 sizeof(int));
00057 fcntl(sec_sockfd_, F_SETFL, O_NONBLOCK);
00058 connected_ = false;
00059 keepalive_ = false;
00060 }
00061
00062 bool UrCommunication::start() {
00063 keepalive_ = true;
00064 uint8_t buf[512];
00065 unsigned int bytes_read;
00066 std::string cmd;
00067 bzero(buf, 512);
00068 print_debug("Acquire firmware version: Connecting...");
00069 if (connect(pri_sockfd_, (struct sockaddr *) &pri_serv_addr_,
00070 sizeof(pri_serv_addr_)) < 0) {
00071 print_fatal("Error connecting to get firmware version");
00072 return false;
00073 }
00074 print_debug("Acquire firmware version: Got connection");
00075 bytes_read = read(pri_sockfd_, buf, 512);
00076 setsockopt(pri_sockfd_, IPPROTO_TCP, TCP_QUICKACK, (char *) &flag_,
00077 sizeof(int));
00078 robot_state_->unpack(buf, bytes_read);
00079
00080 std::this_thread::sleep_for(std::chrono::milliseconds(500));
00081 char tmp[64];
00082 sprintf(tmp, "Firmware version detected: %.7f", robot_state_->getVersion());
00083 print_debug(tmp);
00084 close(pri_sockfd_);
00085
00086 print_debug(
00087 "Switching to secondary interface for masterboard data: Connecting...");
00088
00089 fd_set writefds;
00090 struct timeval timeout;
00091
00092 connect(sec_sockfd_, (struct sockaddr *) &sec_serv_addr_,
00093 sizeof(sec_serv_addr_));
00094 FD_ZERO(&writefds);
00095 FD_SET(sec_sockfd_, &writefds);
00096 timeout.tv_sec = 10;
00097 timeout.tv_usec = 0;
00098 select(sec_sockfd_ + 1, NULL, &writefds, NULL, &timeout);
00099 unsigned int flag_len;
00100 getsockopt(sec_sockfd_, SOL_SOCKET, SO_ERROR, &flag_, &flag_len);
00101 if (flag_ < 0) {
00102 print_fatal("Error connecting to secondary interface");
00103 return false;
00104 }
00105 print_debug("Secondary interface: Got connection");
00106 comThread_ = std::thread(&UrCommunication::run, this);
00107 return true;
00108 }
00109
00110 void UrCommunication::halt() {
00111 keepalive_ = false;
00112 comThread_.join();
00113 }
00114
00115 void UrCommunication::run() {
00116 uint8_t buf[2048];
00117 int bytes_read;
00118 bzero(buf, 2048);
00119 struct timeval timeout;
00120 fd_set readfds;
00121 FD_ZERO(&readfds);
00122 FD_SET(sec_sockfd_, &readfds);
00123 connected_ = true;
00124 while (keepalive_) {
00125 while (connected_ && keepalive_) {
00126 timeout.tv_sec = 0;
00127 timeout.tv_usec = 500000;
00128 select(sec_sockfd_ + 1, &readfds, NULL, NULL, &timeout);
00129 bytes_read = read(sec_sockfd_, buf, 2048);
00130 if (bytes_read > 0) {
00131 setsockopt(sec_sockfd_, IPPROTO_TCP, TCP_QUICKACK,
00132 (char *) &flag_, sizeof(int));
00133 robot_state_->unpack(buf, bytes_read);
00134 } else {
00135 connected_ = false;
00136 robot_state_->setDisconnected();
00137 close(sec_sockfd_);
00138 }
00139 }
00140 if (keepalive_) {
00141
00142 print_warning("Secondary port: No connection. Is controller crashed? Will try to reconnect in 10 seconds...");
00143 sec_sockfd_ = socket(AF_INET, SOCK_STREAM, 0);
00144 if (sec_sockfd_ < 0) {
00145 print_fatal("ERROR opening secondary socket");
00146 }
00147 flag_ = 1;
00148 setsockopt(sec_sockfd_, IPPROTO_TCP, TCP_NODELAY, (char *) &flag_,
00149 sizeof(int));
00150 setsockopt(sec_sockfd_, IPPROTO_TCP, TCP_QUICKACK, (char *) &flag_,
00151 sizeof(int));
00152 setsockopt(sec_sockfd_, SOL_SOCKET, SO_REUSEADDR, (char *) &flag_,
00153 sizeof(int));
00154 fcntl(sec_sockfd_, F_SETFL, O_NONBLOCK);
00155 while (keepalive_ && !connected_) {
00156 std::this_thread::sleep_for(std::chrono::seconds(10));
00157 fd_set writefds;
00158
00159 connect(sec_sockfd_, (struct sockaddr *) &sec_serv_addr_,
00160 sizeof(sec_serv_addr_));
00161 FD_ZERO(&writefds);
00162 FD_SET(sec_sockfd_, &writefds);
00163 select(sec_sockfd_ + 1, NULL, &writefds, NULL, NULL);
00164 unsigned int flag_len;
00165 getsockopt(sec_sockfd_, SOL_SOCKET, SO_ERROR, &flag_,
00166 &flag_len);
00167 if (flag_ < 0) {
00168 print_error("Error re-connecting to port 30002. Is controller started? Will try to reconnect in 10 seconds...");
00169 } else {
00170 connected_ = true;
00171 print_info("Secondary port: Reconnected");
00172 }
00173 }
00174 }
00175 }
00176
00177
00178 std::this_thread::sleep_for(std::chrono::milliseconds(500));
00179 close(sec_sockfd_);
00180 }
00181