main.cpp
Go to the documentation of this file.
00001 /*********************************************************************
00002  * Software License Agreement (BSD License)
00003  *
00004  *  Copyright (c) 2013, JSK Lab at University of Tokyo
00005  *  All rights reserved.
00006  *
00007  *  Redistribution and use in source and binary forms, with or without
00008  *  modification, are permitted provided that the following conditions
00009  *  are met:
00010  *
00011  *   * Redistributions of source code must retain the above copyright
00012  *     notice, this list of conditions and the following disclaimer.
00013  *   * Redistributions in binary form must reproduce the above
00014  *     copyright notice, this list of conditions and the following
00015  *     disclaimer in the documentation and/o2r other materials provided
00016  *     with the distribution.
00017  *   * Neither the name of the University of Tokyo nor the names of its
00018  *     contributors may be used to endorse or promote products derived
00019  *     from this software without specific prior written permission.
00020  *
00021  *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
00022  *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
00023  *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
00024  *  FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
00025  *  COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
00026  *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
00027  *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
00028  *  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
00029  *  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00030  *  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
00031  *  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
00032  *  POSSIBILITY OF SUCH DAMAGE.
00033  *********************************************************************/
00034 
00035 #include <stdio.h>
00036 #include <stdlib.h>
00037 #include <getopt.h>
00038 #include "ros/ros.h"
00039 #include <execinfo.h>
00040 #include <signal.h>
00041 #include <sys/mman.h>
00042 #include <sys/types.h>
00043 #include <sys/stat.h>
00044 #include <unistd.h>
00045 #include <fcntl.h>
00046 #include <pthread.h>
00047 #include <boost/asio.hpp>
00048 #include <boost/bind.hpp>
00049 #include <boost/asio/io_service.hpp>
00050 #include <open_controllers_interface/open_controllers_interface.h>
00051 #include <std_srvs/Empty.h>
00052 #include <boost/shared_ptr.hpp>
00053 #include <boost/accumulators/accumulators.hpp>
00054 #include <boost/accumulators/statistics/stats.hpp>
00055 #include <boost/accumulators/statistics/max.hpp>
00056 #include <boost/accumulators/statistics/mean.hpp>
00057 #include <boost/thread.hpp>
00058 #include <boost/filesystem.hpp>
00059 #include <diagnostic_updater/DiagnosticStatusWrapper.h>
00060 #include <pr2_controller_manager/controller_manager.h>
00061 #include <diagnostic_msgs/DiagnosticArray.h>
00062 
00063 #include <std_srvs/Empty.h>
00064 
00065 #include <realtime_tools/realtime_publisher.h>
00066 #include <std_msgs/Float64.h>
00067 #define BCAP_CONNECTION_UDP 1
00068 #include "b-Cap.c"
00069 
00070 #define DEFAULT_SERVER_IP_ADDRESS               "133.11.216.196"                /* Your controller IP address */
00071 #define DEFAULT_SERVER_PORT_NUM                 5007
00072 #define DEFAULT_UDP_TIMEOUT (10 * 1000)
00073 #define CLOCK_PRIO 0
00074 #define CONTROL_PRIO 0
00075 
00076 #define RAD2DEG(x) ((x) * 180.0 / M_PI)
00077 #define DEG2RAD(x) ((x) / 180.0 * M_PI)
00078 
00079 class DensoController : public OpenControllersInterface::OpenController
00080 {
00081 public:
00082   DensoController() :
00083       OpenControllersInterface::OpenController(), need_exit(false), loop(true)
00084   {
00085   }
00086 #define SAFE_EXIT(exit_code) {                  \
00087     ROS_FATAL("fatal error has occurred");      \
00088     quitRequest();              \
00089   }
00090 
00091   void start()
00092   {
00093     OpenController::start();
00094   }
00095   bool loop;
00096 private:
00097   char* server_ip_address;
00098   int server_port_number;
00099   // for bCap parameters
00100   int iSockFD;
00101   u_int lhController;
00102   u_int lhRobot;
00103   int udp_timeout;
00104   bool need_exit;
00105 public:
00109   void bCapOpen()
00110   {
00111     BCAP_HRESULT hr = BCAP_S_OK;
00112     hr = bCap_Open(server_ip_address, server_port_number, &iSockFD); /* Init socket  */
00113     if (FAILED(hr))
00114     {
00115       ROS_FATAL("bCap_Open failed\n");
00116       exit(1);
00117     }
00118   }
00119 
00120   void bCapControllerConnect()
00121   {
00122     BCAP_HRESULT hr = BCAP_S_OK;
00123     hr = bCap_ControllerConnect(iSockFD, (char*)"", (char*)"caoProv.DENSO.VRC", server_ip_address, (char*)"",
00124                                 &lhController);
00125     if (FAILED(hr))
00126     {
00127       ROS_FATAL("bCap_ControllerConnect failed\n");
00128       exit(1);
00129     }
00130   }
00131 
00132   void bCapClearError()
00133   {
00134     BCAP_HRESULT hr = BCAP_S_OK;
00135     long lResult;
00136     hr = bCap_ControllerExecute(iSockFD, lhController, (char*)"ClearError", (char*)"", &lResult);
00137     ROS_INFO("clearError %02x %02x", hr, lResult);
00138   }
00139 
00140   BCAP_HRESULT bCapGetRobot()
00141   {
00142     BCAP_HRESULT hr = BCAP_S_OK;
00143     long lResult;
00144     hr = bCap_ControllerGetRobot(iSockFD, lhController, (char*)"", (char*)"", &lhRobot); /* Get robot handle */
00145     ROS_INFO("GetRobot %02x %02x", hr, lhRobot);
00146     return hr;
00147   }
00148 
00149   BCAP_HRESULT bCapRobotExecute(char* command, char* arg)
00150   {
00151     BCAP_HRESULT hr = BCAP_S_OK;
00152     long lResult;
00153     hr = bCap_RobotExecute(iSockFD, lhRobot, command, arg, &lResult);
00154     return hr;
00155   }
00156 
00157   void bCapTakearm()
00158   {
00159     BCAP_HRESULT hr = bCapRobotExecute("Takearm", "");
00160     if (FAILED(hr))
00161     {
00162       ROS_FATAL("failed to takearm");
00163       exit(1);
00164     }
00165   }
00166 
00167   void bCapSetExternalSpeed(char* arg)
00168   {
00169     BCAP_HRESULT hr = bCapRobotExecute("ExtSpeed", arg);
00170     if (FAILED(hr))
00171     {
00172       ROS_FATAL("failed to bCapSetExternalSpeed");
00173       exit(1);
00174     }
00175   }
00176 
00177   BCAP_HRESULT bCapMotor(bool command)
00178   {
00179     BCAP_HRESULT hr = BCAP_S_OK;
00180     if (command)
00181     {
00182       hr = bCapRobotExecute("Motor", "1");
00183     }
00184     else
00185     {
00186       hr = bCapRobotExecute("Motor", "0");
00187     }
00188     return hr;
00189   }
00190 
00191   std::vector<double> bCapCurJnt()
00192   {
00193     double dJnt[8];
00194     BCAP_HRESULT hr = BCAP_E_FAIL;
00195     std::vector<double> ret;
00196     while (FAILED(hr))
00197     {
00198       hr = bCap_RobotExecute(iSockFD, lhRobot, "CurJnt", "", &dJnt);
00199       if (SUCCEEDED(hr))
00200       {
00201         for (int i = 0; i < 8; i++)
00202           ret.push_back(dJnt[i]);
00203         fprintf(stderr, "CurJnt : %f %f %f %f %f %f\n", dJnt[0], dJnt[1], dJnt[2], dJnt[3], dJnt[4], dJnt[5], dJnt[6]);
00204         break;
00205       }
00206       else
00207       {
00208         fprintf(stderr, "failed to read joint angles, retry\n");
00209       }
00210     }
00211     return ret;
00212   }
00213 
00214   BCAP_HRESULT bCapSlvChangeMode(char* arg)
00215   {
00216     long lResult;
00217     BCAP_HRESULT hr = bCap_RobotExecute(iSockFD, lhRobot, "slvChangeMode", arg, &lResult);
00218     fprintf(stderr, "slvChangeMode %02x %02x\n", hr, lResult);
00219     return hr;
00220   }
00221 
00222   BCAP_HRESULT bCapRobotSlvMove(BCAP_VARIANT* pose, BCAP_VARIANT* result)
00223   {
00224     //ROS_INFO("bCapRobotSlvMove");
00225     // ROS_INFO("sending angle: %f %f %f %f %f %f",
00226     //          pose->Value.DoubleArray[0],
00227     //          pose->Value.DoubleArray[1],
00228     //          pose->Value.DoubleArray[2],
00229     //          pose->Value.DoubleArray[3],
00230     //          pose->Value.DoubleArray[4],
00231     //          pose->Value.DoubleArray[5]);
00232 
00233     // struct timeval tv;
00234     // tv.tv_sec = 0;
00235     // tv.tv_usec = 1000 * 1;
00236     // setsockopt(iSockFD, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv));
00237     extern int failed_to_send_packet;
00238     struct timespec tick, before;
00239     static std::vector<double> prev_angle;
00240     static std::vector<double> prev_vel;
00241     static struct timespec prev_time;
00242     std::vector<double> current_angle;
00243     std::vector<double> current_vel;
00244     std::vector<double> current_acc;
00245     for (size_t i = 0; i < 6; i++)
00246     {
00247       current_angle.push_back(pose->Value.DoubleArray[i]);
00248     }
00249 
00250     char* command = (char*)"slvMove";
00251     clock_gettime(CLOCK_MONOTONIC, &tick);
00252     BCAP_HRESULT hr = bCap_RobotExecute2(iSockFD, lhRobot, command, pose, result);
00253     clock_gettime(CLOCK_MONOTONIC, &before);
00254     static const int NSEC_PER_SECOND = 1e+9;
00255     //static const int USEC_PER_SECOND = 1e6;
00256     double roundtrip = (before.tv_sec + double(before.tv_nsec) / NSEC_PER_SECOND)
00257         - (tick.tv_sec + double(tick.tv_nsec) / NSEC_PER_SECOND);
00258 
00259     if (prev_angle.size() > 0)
00260     {
00261       double tm = (tick.tv_sec + double(tick.tv_nsec) / NSEC_PER_SECOND)
00262           - (prev_time.tv_sec + double(prev_time.tv_nsec) / NSEC_PER_SECOND);
00263       for (size_t i = 0; i < 6; i++)
00264       {
00265         current_vel.push_back((current_angle[i] - prev_angle[i]) / tm);
00266       }
00267     }
00268     if (prev_vel.size() > 0)
00269     {
00270       double tm = (tick.tv_sec + double(tick.tv_nsec) / NSEC_PER_SECOND)
00271           - (prev_time.tv_sec + double(prev_time.tv_nsec) / NSEC_PER_SECOND);
00272       for (size_t i = 0; i < 6; i++)
00273       {
00274         current_acc.push_back((current_vel[i] - prev_vel[i]) / tm);
00275       }
00276     }
00277 
00278     prev_time = tick;
00279     ROS_INFO("current angle: %f %f %f %f %f %f", current_angle[0], current_angle[1], current_angle[2], current_angle[3],
00280              current_angle[4], current_angle[5]);
00281 
00282     // if (current_vel.size() > 0) {
00283     //   ROS_INFO("current vel: %f %f %f %f %f %f",
00284     //            current_vel[0],
00285     //            current_vel[1],
00286     //            current_vel[2],
00287     //            current_vel[3],
00288     //            current_vel[4],
00289     //            current_vel[5]);
00290     //   }
00291     //   if (prev_vel.size() > 0) {
00292     //     ROS_INFO("prev vel: %f %f %f %f %f %f",
00293     //            prev_vel[0],
00294     //            prev_vel[1],
00295     //            prev_vel[2],
00296     //            prev_vel[3],
00297     //            prev_vel[4],
00298     //            prev_vel[5]);
00299     //   }
00300     // if (current_acc.size() > 0) {
00301     //     ROS_INFO("current acc: %f %f %f %f %f %f",
00302     //            current_acc[0],
00303     //            current_acc[1],
00304     //            current_acc[2],
00305     //            current_acc[3],
00306     //            current_acc[4],
00307     //            current_acc[5]);
00308     //   }
00309 
00310     if (failed_to_send_packet)
00311     {
00312       fprintf(stderr, "roundtrip: %f\n", roundtrip);
00313       setUDPTimeout(0, udp_timeout);
00314 
00315       // print the angle
00316       // if (prev_angle.size() > 0) {
00317       //   ROS_INFO("prev angle: %f %f %f %f %f %f",
00318       //            prev_angle[0],
00319       //            prev_angle[1],
00320       //            prev_angle[2],
00321       //            prev_angle[3],
00322       //            prev_angle[4],
00323       //            prev_angle[5]);
00324       // }
00325       // ROS_INFO("current angle: %f %f %f %f %f %f",
00326       //          current_angle[0],
00327       //          current_angle[1],
00328       //          current_angle[2],
00329       //          current_angle[3],
00330       //          current_angle[4],
00331       //          current_angle[5]);
00332     }
00333     if (FAILED(hr))
00334     {
00335       // hr = bCapRobotExecute("stopLog", "");
00336       // if (FAILED(hr)) {
00337       //   fprintf(stderr, "failed to disable logging mode\n");
00338       // }
00339       ROS_FATAL("bCapRobotSlvMove");
00340       if (hr == BCAP_E_BUF_FULL)
00341       {
00342         ROS_WARN("buffer over flow slvMove %02x", hr);
00343       }
00344       else
00345       {
00346         ROS_WARN("failed to send slvMove %02x", hr);
00347       }
00348       finalize();
00349       cleanupPidFile();
00350       kill(getpid(), SIGKILL);
00351     }
00352 
00353     // memoize prev angle
00354     prev_angle = current_angle;
00355     prev_vel = current_vel;
00356     return hr;
00357   }
00358 
00359   virtual void finalizeHW()
00360   {
00361     ROS_INFO("finalizeHW is called");
00362     if (!dryrunp)
00363     {
00364       setUDPTimeout(2, 0);
00365       sleep(1);
00366       long lResult;
00367       BCAP_HRESULT hr = BCAP_S_OK;
00368       //bCapClearError();
00369       // disable logging mode
00370       hr = bCapRobotExecute("stopLog", "");
00371       if (FAILED(hr))
00372       {
00373         fprintf(stderr, "failed to disable logging mode\n");
00374       }
00375 
00376       hr = bCapSlvChangeMode((char*)"0");
00377       if (FAILED(hr))
00378       {
00379         fprintf(stderr, "failed to change slave mode\n");
00380       }
00381       hr = bCapMotor(false);
00382       if (FAILED(hr))
00383       {
00384         fprintf(stderr, "failed to motor off\n");
00385       }
00386       else
00387       {
00388         fprintf(stderr, "successed to motor off\n");
00389       }
00390       hr = bCap_RobotExecute(iSockFD, lhRobot, (char*)"Givearm", (char*)"", &lResult);
00391       if (FAILED(hr))
00392       {
00393         fprintf(stderr, "failed to give arm\n");
00394       }
00395       else
00396       {
00397         fprintf(stderr, "successed to give arm\n");
00398       }
00399       hr = bCap_RobotRelease(iSockFD, lhRobot); /* Release robot handle */
00400       if (FAILED(hr))
00401       {
00402         fprintf(stderr, "failed to release the robot\n");
00403       }
00404       else
00405       {
00406         fprintf(stderr, "successed to release the robot\n");
00407       }
00408       hr = bCap_ControllerDisconnect(iSockFD, lhController);
00409       if (FAILED(hr))
00410       {
00411         fprintf(stderr, "failed to disconnect from the controller\n");
00412       }
00413       else
00414       {
00415         fprintf(stderr, "successed to disconnect from the controller\n");
00416       }
00417       /* Stop b-CAP service (Very important in UDP/IP connection) */
00418       hr = bCap_ServiceStop(iSockFD);
00419       if (FAILED(hr))
00420       {
00421         fprintf(stderr, "failed to stop the service\n");
00422       }
00423       else
00424       {
00425         fprintf(stderr, "successed to stop the service\n");
00426       }
00427       sleep(1);
00428       hr = bCap_Close(iSockFD);
00429       if (FAILED(hr))
00430       {
00431         fprintf(stderr, "failed to close bCap\n");
00432       }
00433       else
00434       {
00435         fprintf(stderr, "successed to close bCap\n");
00436       }
00437     }
00438     fprintf(stderr, "finalizing done\n");
00439   }
00440 
00441   bool updateJoints(struct timespec* spec_result)
00442   {
00443     static bool initialp = true;
00444     bool errorp = false;
00445     if (initialp)
00446     {
00447       ROS_INFO("first loop");
00448 
00449       initialp = false;
00450       std::vector<double> cur_jnt;
00451       if (!dryrunp)
00452       {
00453         ROS_INFO("hoge");
00454         cur_jnt = bCapCurJnt();
00455         BCAP_VARIANT vntPose, vntResult;
00456         vntPose.Type = VT_R8 | VT_ARRAY;
00457         vntPose.Arrays = 8;
00458         for (int i = 0; i < 8; i++)
00459         {
00460           vntPose.Value.DoubleArray[i] = cur_jnt[i];
00461         }
00462         BCAP_HRESULT hr = BCAP_S_OK;
00463         while (hr == 0 && g_halt_requested == false)
00464         {
00465           hr = bCapRobotSlvMove(&vntPose, &vntResult);
00466           ROS_INFO("initialize slvmove");
00467         }
00468         ROS_INFO("initialization done");
00469       }
00470       // fill ac
00471       int i = 0;
00472       for (OpenControllersInterface::TransmissionIterator it = cm->model_.transmissions_.begin();
00473           it != cm->model_.transmissions_.end(); ++it)
00474       { // *** js and ac must be consistent
00475         pr2_hardware_interface::Actuator *ac = hw->getActuator((*it)->actuator_names_[0]);
00476         if (!dryrunp)
00477         {
00478           ac->state_.position_ = DEG2RAD(cur_jnt[i]);
00479         }
00480         else
00481         {
00482           ac->state_.position_ = 0;
00483         }
00484         i++;
00485       }
00486     }
00487     // build vntPose
00488     BCAP_VARIANT vntPose;
00489     vntPose.Type = VT_R8 | VT_ARRAY;
00490     vntPose.Arrays = 8;
00491     {
00492       int i = 0;
00493       for (OpenControllersInterface::TransmissionIterator it = cm->model_.transmissions_.begin();
00494           it != cm->model_.transmissions_.end(); ++it)
00495       { // *** js and ac must be consistent
00496         pr2_mechanism_model::JointState *js = cm->state_->getJointState((*it)->joint_names_[0]);
00497         pr2_hardware_interface::Actuator *ac = hw->getActuator((*it)->actuator_names_[0]);
00498         // ROS_INFO("js: %f, ac: %f", js->commanded_effort_, ac->state_.position_);
00499         double target_angle = RAD2DEG(ac->state_.position_);
00500         //if (i > 1) {     // moves only the 6-3rd joints
00501         if (true)
00502         {
00503           target_angle = RAD2DEG(ac->state_.position_ + js->commanded_effort_);
00504           // check min/max
00505 #define SAFE_OFFSET_DEG 1
00506           if (RAD2DEG(cm->state_->model_->robot_model_.getJoint((*it)->joint_names_[0])->limits->lower)
00507               + SAFE_OFFSET_DEG > target_angle)
00508           {
00509             ROS_WARN("too small joint angle! %f", target_angle);
00510             target_angle = RAD2DEG(
00511                 cm->state_->model_->robot_model_.getJoint((*it)->joint_names_[0])->limits->lower) + SAFE_OFFSET_DEG;
00512           }
00513           else if (RAD2DEG(cm->state_->model_->robot_model_.getJoint((*it)->joint_names_[0])->limits->upper)
00514               - SAFE_OFFSET_DEG < target_angle)
00515           {
00516             ROS_WARN("too large joint angle! %f", target_angle);
00517             target_angle = RAD2DEG(
00518                 cm->state_->model_->robot_model_.getJoint((*it)->joint_names_[0])->limits->upper) - SAFE_OFFSET_DEG;
00519           }
00520           //ROS_INFO("target_angle: %f", target_angle);
00521         }
00522         else
00523         {
00524           target_angle = RAD2DEG(ac->state_.position_);
00525         }
00526         vntPose.Value.DoubleArray[i] = target_angle;
00527         i++;
00528       }
00529     }
00530 
00531     // send vntPose
00532     BCAP_VARIANT vntReturn;
00533     if (!dryrunp)
00534     {
00535       if (spec_result)
00536       {
00537         clock_gettime(CLOCK_REALTIME, spec_result);
00538       }
00539       BCAP_HRESULT hr = bCapRobotSlvMove(&vntPose, &vntReturn);
00540       if (hr == 0xF200501)
00541       {
00542         //ROS_INFO("buf is filled, OK");
00543       }
00544       else
00545       {
00546         while (hr == 0 && g_halt_requested == false)
00547         { // 0 means that there is empty buffer
00548           fprintf(stderr, "buf space found, re-send the angles to the controller\n");
00549           //ROS_WARN("buf space found, re-send the angles to the controller");
00550           if (spec_result)
00551           {
00552             clock_gettime(CLOCK_REALTIME, spec_result);
00553           }
00554           hr = bCapRobotSlvMove(&vntPose, &vntReturn);
00555           if (hr == 0xF200501)
00556           {
00557             ROS_WARN("buf is filled");
00558           }
00559         }
00560       }
00561     }
00562 
00563     hw->current_time_ = ros::Time::now(); // ???
00564     if (!errorp)
00565     {
00566       int i = 0;
00567       for (OpenControllersInterface::TransmissionIterator it = cm->model_.transmissions_.begin();
00568           it != cm->model_.transmissions_.end(); ++it)
00569       { // *** js and ac must be consistent
00570         pr2_mechanism_model::JointState *js = cm->state_->getJointState((*it)->joint_names_[0]);
00571         pr2_hardware_interface::Actuator *ac = hw->getActuator((*it)->actuator_names_[0]);
00572         ac->state_.velocity_ = 0;
00573         if (!dryrunp)
00574         { // if not in the dryrun mode, we just copy the vntReturn value
00575           ac->state_.position_ = DEG2RAD(vntReturn.Value.DoubleArray[i]);
00576         }
00577         else
00578         { // if in the dryrun mode, we just copy the target value
00579           double target_angle = ac->state_.position_ + js->commanded_effort_;
00580           ac->state_.position_ = target_angle;
00581         }
00582         i++;
00583       }
00584     }
00585     return !errorp;
00586   }
00587 
00588   void setUDPTimeout(long sec, long usec)
00589   {
00590 #ifdef BCAP_CONNECTION_UDP
00591     struct timeval tv;
00592     tv.tv_sec = sec;
00593     tv.tv_usec = usec;
00594     if (setsockopt(iSockFD, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv)) < 0)
00595     {
00596       perror("Error");
00597     }
00598 #endif
00599   }
00600 
00601   void bCapServerStart()
00602   {
00603     BCAP_HRESULT hr = bCap_ServiceStart(iSockFD); /* Start b-CAP service */
00604     if (FAILED(hr))
00605     {
00606       ROS_FATAL("bCap_ServiceStart failed\n");
00607       SAFE_EXIT(1);
00608     }
00609   }
00610 
00614   void initializeHW()
00615   {
00616 
00617     hw = new pr2_hardware_interface::HardwareInterface();
00618     hw->addActuator(new pr2_hardware_interface::Actuator("j1_motor"));
00619     hw->addActuator(new pr2_hardware_interface::Actuator("j2_motor"));
00620     hw->addActuator(new pr2_hardware_interface::Actuator("j3_motor"));
00621     hw->addActuator(new pr2_hardware_interface::Actuator("j4_motor"));
00622     hw->addActuator(new pr2_hardware_interface::Actuator("j5_motor"));
00623     hw->addActuator(new pr2_hardware_interface::Actuator("flange_motor"));
00624     // // Create controller manager
00625     //pr2_controller_manager::ControllerManager cm(ec.hw_);
00626     cm = boost::shared_ptr<pr2_controller_manager::ControllerManager>(
00627         new pr2_controller_manager::ControllerManager(hw));
00628 
00629     // for denso connection
00630     if (!dryrunp)
00631     {
00632       need_exit = true;
00633       ROS_INFO("bCapOpen");
00634       bCapOpen();
00635       ROS_INFO("bCapServerStart");
00636       setUDPTimeout(2, 0); // 200msec
00637       bCapServerStart();
00638       ROS_INFO("bCapControllerConnect");
00639       bCapControllerConnect();
00640       ROS_INFO("bCapClearError");
00641       bCapClearError();
00642       ROS_INFO("bCapGetRobot");
00643       bCapGetRobot();
00644       ROS_INFO("bCapTakearm");
00645       bCapTakearm();
00646       ROS_INFO("bCapSetExternalSpeed");
00647       bCapSetExternalSpeed((char*)"80.0");
00648 
00649       {
00650         ROS_WARN("bCapMotor On");
00651         BCAP_HRESULT hr = bCapMotor(true);
00652         if (FAILED(hr))
00653         {
00654           ROS_FATAL("failed to motor on");
00655           finalize();
00656           SAFE_EXIT(1);
00657         }
00658       }
00659       // sleep(15);
00660       // // read joint angles sometimes to skip illegal values
00661       std::vector<double> cur_jnt = bCapCurJnt();
00662       // 100 * 50m = 5000
00663       // for (int i = 0; i < 5000 / 20; i++) {
00664       //   cur_jnt = bCapCurJnt();
00665       // }
00666 
00667       // enable logging
00668       {
00669         BCAP_HRESULT hr = bCapRobotExecute("clearLog", "");
00670         if (FAILED(hr))
00671         {
00672           ROS_FATAL("failed to enable logging mode");
00673           SAFE_EXIT(1);
00674         }
00675       }
00676 
00677       // enable logging
00678       // {
00679       //   BCAP_HRESULT hr = bCapRobotExecute("startLog", "");
00680       //   if (FAILED(hr)) {
00681       //     ROS_FATAL("failed to start logging mode");
00682       //     SAFE_EXIT(1);
00683       //   }
00684       // }
00685 
00686       need_exit = false;
00687       {
00688         BCAP_HRESULT hr = bCapSlvChangeMode((char*)"514"); // 0x202
00689         //BCAP_HRESULT hr = bCapSlvChangeMode((char*)"258"); // 0x102
00690         if (FAILED(hr))
00691         {
00692           ROS_FATAL("failed to change slave mode");
00693           SAFE_EXIT(1);
00694         }
00695       }
00696 
00697       //sleep(5);
00698       // fill ac
00699       int i = 0;
00700       for (OpenControllersInterface::TransmissionIterator it = cm->model_.transmissions_.begin();
00701           it != cm->model_.transmissions_.end(); ++it)
00702       { // *** js and ac must be consistent
00703         pr2_hardware_interface::Actuator *ac = hw->getActuator((*it)->actuator_names_[0]);
00704         ac->state_.position_ = DEG2RAD(cur_jnt[i]); // degree -> degree
00705         i++;
00706       }
00707       setUDPTimeout(0, udp_timeout);
00708       sleep(5);
00709       bCapCurJnt();
00710       bCapCurJnt();
00711       bCapCurJnt();
00712       // for (int i = 0; i < 5; i++)
00713       //   bCapRobotSlvMove(&vntPose, &vntResult);
00714       // hr = bCapRobotSlvMove(&vntPose, &vntResult);
00715       // if (hr == 0) {
00716       //   ROS_WARN("buf space found");
00717       // }
00718       // hr = bCapRobotSlvMove(&vntPose, &vntResult);
00719       // if (hr == 0) {
00720       //   ROS_WARN("buf space found");
00721       // }
00722     }
00723   }
00724 
00725   void initializeROS(ros::NodeHandle& node)
00726   {
00727     //TODO (Trivial) Since all of the tasks done within this method don't seem to be ROS-specific,
00728     //     moving them to somewhere else might make more sense.
00729 
00730     // Determine ip address of the robot's embedded machine.
00731     std::string server_ip_address_str;
00732     if (!node.getParam("server_ip", server_ip_address_str))
00733     {
00734       server_ip_address = (char*)DEFAULT_SERVER_IP_ADDRESS;
00735     }
00736     else
00737     {
00738       server_ip_address = (char*)malloc(sizeof(char) * (server_ip_address_str.length() + 1));
00739       for (size_t i = 0; i < server_ip_address_str.length(); i++)
00740       {
00741         server_ip_address[i] = server_ip_address_str.at(i);
00742       }
00743       server_ip_address[server_ip_address_str.length()] = '\0';
00744     }
00745 
00746     // Determine the pre-set port number used to communicate the robot's embedded computer via bCap.
00747     if (!node.getParam("server_port", server_port_number))
00748     {
00749       server_port_number = DEFAULT_SERVER_PORT_NUM;
00750     }
00751 
00752     ROS_WARN("server: %s:%d", server_ip_address, server_port_number);
00753 
00754     // Determine the pre-set UDP timeout length.
00755     if (!node.getParam("udp_timeout", udp_timeout))
00756     {
00757       udp_timeout = DEFAULT_UDP_TIMEOUT;
00758     }
00759     ROS_WARN("udp_timeout: %d micro sec", udp_timeout);
00760   }
00761 
00762   void quitRequest()
00763   {
00764     fprintf(stderr, "DensoController::quitRequest\n");
00765     OpenController::quitRequest(); // call super class
00766     fprintf(stderr, "DensoController::quitRequest called\n");
00767     if (need_exit)
00768     {
00769       exit(1);
00770     }
00771   }
00772 };
00773 
00774 DensoController g_controller;
00775 void quitRequested(int sigint)
00776 {
00777   // do nothing
00778   std::cerr << "quitRequested" << std::endl;
00779   g_controller.quitRequest();
00780   ros::shutdown();
00781 }
00782 
00783 int main(int argc, char *argv[])
00784 {
00785   // Keep the kernel from swapping us out
00786   OpenControllersInterface::OpenController::initRT();
00787 
00788   // Initialize ROS and parse command-line arguments
00789   ros::init(argc, argv, "denso_controller",
00790             // quitRequested is used as a SIGINT handler instead of the handler prepared by ROS.
00791             ros::init_options::NoSigintHandler);
00792   // Parse options
00793   //g_options.program_ = argv[0];
00794   g_controller.parseArguments(argc, argv);
00795   if (optind < argc)
00796   {
00797     g_controller.Usage("Extra arguments");
00798   }
00799 
00800   // do these work?
00801   signal(SIGTERM, quitRequested);
00802   signal(SIGINT, quitRequested);
00803   signal(SIGHUP, quitRequested);
00804   int rv = 1;
00805   // Set up realtime context, start ROS processes, load robot description.
00806   g_controller.initialize();
00807   boost::thread t(&DensoController::start, &g_controller);
00808   {
00809     //OpenControllersInterface::Finalizer finalizer(&g_controller);
00810     ros::Rate loop_rate(100);
00811     while (ros::ok())
00812     {
00813       ros::spinOnce();
00814       loop_rate.sleep();
00815     }
00816     fprintf(stderr, "ROS has been terminated\n");
00817     t.join();
00818     fprintf(stderr, "start thread has been terminated\n");
00819     g_controller.finalize();
00820   }
00821 
00822   g_controller.cleanupPidFile();
00823   return rv;
00824 }
00825 


denso_controller
Author(s): Ryohei Ueda
autogenerated on Wed Aug 26 2015 11:21:21