00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
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
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
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
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 }