ur_driver.cpp
Go to the documentation of this file.
00001 /*
00002  * ur_driver.cpp
00003  *
00004  * Copyright 2015 Thomas Timm Andersen
00005  *
00006  * Licensed under the Apache License, Version 2.0 (the "License");
00007  * you may not use this file except in compliance with the License.
00008  * You may obtain a copy of the License at
00009  *
00010  *     http://www.apache.org/licenses/LICENSE-2.0
00011  *
00012  * Unless required by applicable law or agreed to in writing, software
00013  * distributed under the License is distributed on an "AS IS" BASIS,
00014  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00015  * See the License for the specific language governing permissions and
00016  * limitations under the License.
00017  */
00018 
00019 #include "ur_modern_driver/ur_driver.h"
00020 
00021 UrDriver::UrDriver(std::condition_variable& rt_msg_cond,
00022                 std::condition_variable& msg_cond, std::string host,
00023                 unsigned int reverse_port, double servoj_time,
00024                 unsigned int safety_count_max, double max_time_step, double min_payload,
00025                 double max_payload, double servoj_lookahead_time, double servoj_gain) :
00026                 REVERSE_PORT_(reverse_port), maximum_time_step_(max_time_step), minimum_payload_(
00027                                 min_payload), maximum_payload_(max_payload), servoj_time_(
00028                                 servoj_time), servoj_lookahead_time_(servoj_lookahead_time), servoj_gain_(servoj_gain) {
00029         char buffer[256];
00030         struct sockaddr_in serv_addr;
00031         int n, flag;
00032 
00033         firmware_version_ = 0;
00034         reverse_connected_ = false;
00035         executing_traj_ = false;
00036         rt_interface_ = new UrRealtimeCommunication(rt_msg_cond, host,
00037                         safety_count_max);
00038         new_sockfd_ = -1;
00039         sec_interface_ = new UrCommunication(msg_cond, host);
00040 
00041         incoming_sockfd_ = socket(AF_INET, SOCK_STREAM, 0);
00042         if (incoming_sockfd_ < 0) {
00043                 print_fatal("ERROR opening socket for reverse communication");
00044         }
00045         bzero((char *) &serv_addr, sizeof(serv_addr));
00046 
00047         serv_addr.sin_family = AF_INET;
00048         serv_addr.sin_addr.s_addr = INADDR_ANY;
00049         serv_addr.sin_port = htons(REVERSE_PORT_);
00050         flag = 1;
00051         setsockopt(incoming_sockfd_, IPPROTO_TCP, TCP_NODELAY, (char *) &flag,
00052                         sizeof(int));
00053         setsockopt(incoming_sockfd_, SOL_SOCKET, SO_REUSEADDR, &flag, sizeof(int));
00054         if (bind(incoming_sockfd_, (struct sockaddr *) &serv_addr,
00055                         sizeof(serv_addr)) < 0) {
00056                 print_fatal("ERROR on binding socket for reverse communication");
00057         }
00058         listen(incoming_sockfd_, 5);
00059 }
00060 
00061 std::vector<double> UrDriver::interp_cubic(double t, double T,
00062                 std::vector<double> p0_pos, std::vector<double> p1_pos,
00063                 std::vector<double> p0_vel, std::vector<double> p1_vel) {
00064         /*Returns positions of the joints at time 't' */
00065         std::vector<double> positions;
00066         for (unsigned int i = 0; i < p0_pos.size(); i++) {
00067                 double a = p0_pos[i];
00068                 double b = p0_vel[i];
00069                 double c = (-3 * p0_pos[i] + 3 * p1_pos[i] - 2 * T * p0_vel[i]
00070                                 - T * p1_vel[i]) / pow(T, 2);
00071                 double d = (2 * p0_pos[i] - 2 * p1_pos[i] + T * p0_vel[i]
00072                                 + T * p1_vel[i]) / pow(T, 3);
00073                 positions.push_back(a + b * t + c * pow(t, 2) + d * pow(t, 3));
00074         }
00075         return positions;
00076 }
00077 
00078 bool UrDriver::doTraj(std::vector<double> inp_timestamps,
00079                 std::vector<std::vector<double> > inp_positions,
00080                 std::vector<std::vector<double> > inp_velocities) {
00081         std::chrono::high_resolution_clock::time_point t0, t;
00082         std::vector<double> positions;
00083         unsigned int j;
00084 
00085         if (!UrDriver::uploadProg()) {
00086                 return false;
00087         }
00088         executing_traj_ = true;
00089         t0 = std::chrono::high_resolution_clock::now();
00090         t = t0;
00091         j = 0;
00092         while ((inp_timestamps[inp_timestamps.size() - 1]
00093                         >= std::chrono::duration_cast<std::chrono::duration<double>>(t - t0).count())
00094                         and executing_traj_) {
00095                 while (inp_timestamps[j]
00096                                 <= std::chrono::duration_cast<std::chrono::duration<double>>(
00097                                                 t - t0).count() && j < inp_timestamps.size() - 1) {
00098                         j += 1;
00099                 }
00100                 positions = UrDriver::interp_cubic(
00101                                 std::chrono::duration_cast<std::chrono::duration<double>>(
00102                                                 t - t0).count() - inp_timestamps[j - 1],
00103                                 inp_timestamps[j] - inp_timestamps[j - 1], inp_positions[j - 1],
00104                                 inp_positions[j], inp_velocities[j - 1], inp_velocities[j]);
00105                 UrDriver::servoj(positions);
00106 
00107                 // oversample with 4 * sample_time
00108                 std::this_thread::sleep_for(
00109                                 std::chrono::milliseconds((int) ((servoj_time_ * 1000) / 4.)));
00110                 t = std::chrono::high_resolution_clock::now();
00111         }
00112         executing_traj_ = false;
00113         //Signal robot to stop driverProg()
00114         UrDriver::closeServo(positions);
00115         return true;
00116 }
00117 
00118 void UrDriver::servoj(std::vector<double> positions, int keepalive) {
00119         if (!reverse_connected_) {
00120                 print_error(
00121                                 "UrDriver::servoj called without a reverse connection present. Keepalive: "
00122                                                 + std::to_string(keepalive));
00123                 return;
00124         }
00125         unsigned int bytes_written;
00126         int tmp;
00127         unsigned char buf[28];
00128         for (int i = 0; i < 6; i++) {
00129                 tmp = htonl((int) (positions[i] * MULT_JOINTSTATE_));
00130                 buf[i * 4] = tmp & 0xff;
00131                 buf[i * 4 + 1] = (tmp >> 8) & 0xff;
00132                 buf[i * 4 + 2] = (tmp >> 16) & 0xff;
00133                 buf[i * 4 + 3] = (tmp >> 24) & 0xff;
00134         }
00135         tmp = htonl((int) keepalive);
00136         buf[6 * 4] = tmp & 0xff;
00137         buf[6 * 4 + 1] = (tmp >> 8) & 0xff;
00138         buf[6 * 4 + 2] = (tmp >> 16) & 0xff;
00139         buf[6 * 4 + 3] = (tmp >> 24) & 0xff;
00140         bytes_written = write(new_sockfd_, buf, 28);
00141 }
00142 
00143 void UrDriver::stopTraj() {
00144         executing_traj_ = false;
00145         rt_interface_->addCommandToQueue("stopj(10)\n");
00146 }
00147 
00148 bool UrDriver::uploadProg() {
00149         std::string cmd_str;
00150         char buf[128];
00151         cmd_str = "def driverProg():\n";
00152 
00153         sprintf(buf, "\tMULT_jointstate = %i\n", MULT_JOINTSTATE_);
00154         cmd_str += buf;
00155 
00156         cmd_str += "\tSERVO_IDLE = 0\n";
00157         cmd_str += "\tSERVO_RUNNING = 1\n";
00158         cmd_str += "\tcmd_servo_state = SERVO_IDLE\n";
00159         cmd_str += "\tcmd_servo_q = [0.0, 0.0, 0.0, 0.0, 0.0, 0.0]\n";
00160         cmd_str += "\tdef set_servo_setpoint(q):\n";
00161         cmd_str += "\t\tenter_critical\n";
00162         cmd_str += "\t\tcmd_servo_state = SERVO_RUNNING\n";
00163         cmd_str += "\t\tcmd_servo_q = q\n";
00164         cmd_str += "\t\texit_critical\n";
00165         cmd_str += "\tend\n";
00166         cmd_str += "\tthread servoThread():\n";
00167         cmd_str += "\t\tstate = SERVO_IDLE\n";
00168         cmd_str += "\t\twhile True:\n";
00169         cmd_str += "\t\t\tenter_critical\n";
00170         cmd_str += "\t\t\tq = cmd_servo_q\n";
00171         cmd_str += "\t\t\tdo_brake = False\n";
00172         cmd_str += "\t\t\tif (state == SERVO_RUNNING) and ";
00173         cmd_str += "(cmd_servo_state == SERVO_IDLE):\n";
00174         cmd_str += "\t\t\t\tdo_brake = True\n";
00175         cmd_str += "\t\t\tend\n";
00176         cmd_str += "\t\t\tstate = cmd_servo_state\n";
00177         cmd_str += "\t\t\tcmd_servo_state = SERVO_IDLE\n";
00178         cmd_str += "\t\t\texit_critical\n";
00179         cmd_str += "\t\t\tif do_brake:\n";
00180         cmd_str += "\t\t\t\tstopj(1.0)\n";
00181         cmd_str += "\t\t\t\tsync()\n";
00182         cmd_str += "\t\t\telif state == SERVO_RUNNING:\n";
00183 
00184         if (sec_interface_->robot_state_->getVersion() >= 3.1)
00185                 sprintf(buf, "\t\t\t\tservoj(q, t=%.4f, lookahead_time=%.4f, gain=%.0f)\n",
00186                                 servoj_time_, servoj_lookahead_time_, servoj_gain_);
00187         else
00188                 sprintf(buf, "\t\t\t\tservoj(q, t=%.4f)\n", servoj_time_);
00189         cmd_str += buf;
00190 
00191         cmd_str += "\t\t\telse:\n";
00192         cmd_str += "\t\t\t\tsync()\n";
00193         cmd_str += "\t\t\tend\n";
00194         cmd_str += "\t\tend\n";
00195         cmd_str += "\tend\n";
00196 
00197         sprintf(buf, "\tsocket_open(\"%s\", %i)\n", ip_addr_.c_str(),
00198                         REVERSE_PORT_);
00199         cmd_str += buf;
00200 
00201         cmd_str += "\tthread_servo = run servoThread()\n";
00202         cmd_str += "\tkeepalive = 1\n";
00203         cmd_str += "\twhile keepalive > 0:\n";
00204         cmd_str += "\t\tparams_mult = socket_read_binary_integer(6+1)\n";
00205         cmd_str += "\t\tif params_mult[0] > 0:\n";
00206         cmd_str += "\t\t\tq = [params_mult[1] / MULT_jointstate, ";
00207         cmd_str += "params_mult[2] / MULT_jointstate, ";
00208         cmd_str += "params_mult[3] / MULT_jointstate, ";
00209         cmd_str += "params_mult[4] / MULT_jointstate, ";
00210         cmd_str += "params_mult[5] / MULT_jointstate, ";
00211         cmd_str += "params_mult[6] / MULT_jointstate]\n";
00212         cmd_str += "\t\t\tkeepalive = params_mult[7]\n";
00213         cmd_str += "\t\t\tset_servo_setpoint(q)\n";
00214         cmd_str += "\t\tend\n";
00215         cmd_str += "\tend\n";
00216         cmd_str += "\tsleep(.1)\n";
00217         cmd_str += "\tsocket_close()\n";
00218         cmd_str += "\tkill thread_servo\n";
00219         cmd_str += "end\n";
00220 
00221         rt_interface_->addCommandToQueue(cmd_str);
00222         return UrDriver::openServo();
00223 }
00224 
00225 bool UrDriver::openServo() {
00226         struct sockaddr_in cli_addr;
00227         socklen_t clilen;
00228         clilen = sizeof(cli_addr);
00229         new_sockfd_ = accept(incoming_sockfd_, (struct sockaddr *) &cli_addr,
00230                         &clilen);
00231         if (new_sockfd_ < 0) {
00232                 print_fatal("ERROR on accepting reverse communication");
00233                 return false;
00234         }
00235         reverse_connected_ = true;
00236         return true;
00237 }
00238 void UrDriver::closeServo(std::vector<double> positions) {
00239         if (positions.size() != 6)
00240                 UrDriver::servoj(rt_interface_->robot_state_->getQActual(), 0);
00241         else
00242                 UrDriver::servoj(positions, 0);
00243 
00244         reverse_connected_ = false;
00245         close(new_sockfd_);
00246 }
00247 
00248 bool UrDriver::start() {
00249         if (!sec_interface_->start())
00250                 return false;
00251         firmware_version_ = sec_interface_->robot_state_->getVersion();
00252         rt_interface_->robot_state_->setVersion(firmware_version_);
00253         if (!rt_interface_->start())
00254                 return false;
00255         ip_addr_ = rt_interface_->getLocalIp();
00256         print_debug(
00257                         "Listening on " + ip_addr_ + ":" + std::to_string(REVERSE_PORT_)
00258                                         + "\n");
00259         return true;
00260 
00261 }
00262 
00263 void UrDriver::halt() {
00264         if (executing_traj_) {
00265                 UrDriver::stopTraj();
00266         }
00267         sec_interface_->halt();
00268         rt_interface_->halt();
00269         close(incoming_sockfd_);
00270 }
00271 
00272 void UrDriver::setSpeed(double q0, double q1, double q2, double q3, double q4,
00273                 double q5, double acc) {
00274         rt_interface_->setSpeed(q0, q1, q2, q3, q4, q5, acc);
00275 }
00276 
00277 std::vector<std::string> UrDriver::getJointNames() {
00278         return joint_names_;
00279 }
00280 
00281 void UrDriver::setJointNames(std::vector<std::string> jn) {
00282         joint_names_ = jn;
00283 }
00284 
00285 void UrDriver::setToolVoltage(unsigned int v) {
00286         char buf[256];
00287         sprintf(buf, "sec setOut():\n\tset_tool_voltage(%d)\nend\n", v);
00288         rt_interface_->addCommandToQueue(buf);
00289         print_debug(buf);
00290 }
00291 void UrDriver::setFlag(unsigned int n, bool b) {
00292         char buf[256];
00293         sprintf(buf, "sec setOut():\n\tset_flag(%d, %s)\nend\n", n,
00294                         b ? "True" : "False");
00295         rt_interface_->addCommandToQueue(buf);
00296         print_debug(buf);
00297 }
00298 void UrDriver::setDigitalOut(unsigned int n, bool b) {
00299         char buf[256];
00300         if (firmware_version_ < 2) {
00301                 sprintf(buf, "sec setOut():\n\tset_digital_out(%d, %s)\nend\n", n,
00302                                 b ? "True" : "False");
00303     } else if (n > 15) {
00304         sprintf(buf,
00305                 "sec setOut():\n\tset_tool_digital_out(%d, %s)\nend\n",
00306                 n - 16, b ? "True" : "False");
00307         } else if (n > 7) {
00308         sprintf(buf, "sec setOut():\n\tset_configurable_digital_out(%d, %s)\nend\n",
00309                                 n - 8, b ? "True" : "False");
00310 
00311         } else {
00312                 sprintf(buf, "sec setOut():\n\tset_standard_digital_out(%d, %s)\nend\n",
00313                                 n, b ? "True" : "False");
00314 
00315         }
00316         rt_interface_->addCommandToQueue(buf);
00317         print_debug(buf);
00318 
00319 }
00320 void UrDriver::setAnalogOut(unsigned int n, double f) {
00321         char buf[256];
00322         if (firmware_version_ < 2) {
00323                 sprintf(buf, "sec setOut():\n\tset_analog_out(%d, %1.4f)\nend\n", n, f);
00324         } else {
00325                 sprintf(buf, "sec setOut():\n\tset_standard_analog_out(%d, %1.4f)\nend\n", n, f);
00326         }
00327 
00328         rt_interface_->addCommandToQueue(buf);
00329         print_debug(buf);
00330 }
00331 
00332 bool UrDriver::setPayload(double m) {
00333         if ((m < maximum_payload_) && (m > minimum_payload_)) {
00334                 char buf[256];
00335                 sprintf(buf, "sec setOut():\n\tset_payload(%1.3f)\nend\n", m);
00336                 rt_interface_->addCommandToQueue(buf);
00337                 print_debug(buf);
00338                 return true;
00339         } else
00340                 return false;
00341 }
00342 
00343 void UrDriver::setMinPayload(double m) {
00344         if (m > 0) {
00345                 minimum_payload_ = m;
00346         } else {
00347                 minimum_payload_ = 0;
00348         }
00349 
00350 }
00351 void UrDriver::setMaxPayload(double m) {
00352         maximum_payload_ = m;
00353 }
00354 void UrDriver::setServojTime(double t) {
00355         if (t > 0.008) {
00356                 servoj_time_ = t;
00357         } else {
00358                 servoj_time_ = 0.008;
00359         }
00360 }
00361 void UrDriver::setServojLookahead(double t){
00362         if (t > 0.03) {
00363                 if (t < 0.2) {
00364                         servoj_lookahead_time_ = t;
00365                 } else {
00366                         servoj_lookahead_time_ = 0.2;
00367                 }
00368         } else {
00369                 servoj_lookahead_time_ = 0.03;
00370         }
00371 }
00372 void UrDriver::setServojGain(double g){
00373         if (g > 100) {
00374                         if (g < 2000) {
00375                                 servoj_gain_ = g;
00376                         } else {
00377                                 servoj_gain_ = 2000;
00378                         }
00379                 } else {
00380                         servoj_gain_ = 100;
00381                 }
00382 }


ur_modern_driver
Author(s): Thomas Timm Andersen
autogenerated on Wed Apr 3 2019 02:55:31