00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035 #include <stdio.h>
00036 #include <stdlib.h>
00037 #include <getopt.h>
00038 #include <map>
00039 #include "ros/ros.h"
00040 #include <execinfo.h>
00041 #include <signal.h>
00042 #include <sys/mman.h>
00043 #include <sys/types.h>
00044 #include <sys/stat.h>
00045 #include <unistd.h>
00046 #include <fcntl.h>
00047 #include <pthread.h>
00048 #include <boost/asio.hpp>
00049 #include <boost/bind.hpp>
00050 #include <boost/asio/io_service.hpp>
00051 #include <open_controllers_interface/open_controllers_interface.h>
00052 #include <std_srvs/Empty.h>
00053 #include <boost/shared_ptr.hpp>
00054 #include <boost/accumulators/accumulators.hpp>
00055 #include <boost/accumulators/statistics/stats.hpp>
00056 #include <boost/accumulators/statistics/max.hpp>
00057 #include <boost/accumulators/statistics/mean.hpp>
00058 #include <boost/thread.hpp>
00059 #include <boost/filesystem.hpp>
00060 #include <boost/pointer_cast.hpp>
00061 #include <diagnostic_updater/DiagnosticStatusWrapper.h>
00062 #include <pr2_controller_manager/controller_manager.h>
00063 #include <diagnostic_msgs/DiagnosticArray.h>
00064
00065 #include <std_srvs/Empty.h>
00066
00067 #include <realtime_tools/realtime_publisher.h>
00068 #include <std_msgs/Float64.h>
00069 #define BCAP_CONNECTION_UDP 1
00070 #include "utf8.h"
00071 #include "b-Cap.h"
00072
00073 #define DEFAULT_SERVER_IP_ADDRESS "133.11.216.196"
00074 #define DEFAULT_SERVER_PORT_NUM 5007
00075 #define DEFAULT_UDP_TIMEOUT (10 * 1000)
00076 #define CLOCK_PRIO 0
00077 #define CONTROL_PRIO 0
00078
00079 #define RAD2DEG(x) ((x) * 180.0 / M_PI)
00080 #define DEG2RAD(x) ((x) * M_PI / 180.0)
00081
00082 class DensoController : public OpenControllersInterface::OpenController
00083 {
00084 class DensoControllerStatus : public OpenControllersInterface::ControllerStatus {
00085 public:
00086 DensoControllerStatus(BCAP_HRESULT hr): hr_(hr){};
00087 DensoControllerStatus(u_int error_code): hr_((BCAP_HRESULT)error_code){};
00088 virtual ~DensoControllerStatus(){};
00089 virtual bool isHealthy(){
00090 return SUCCEEDED(hr_);
00091 }
00092 BCAP_HRESULT hr_;
00093 };
00094 typedef boost::shared_ptr<DensoControllerStatus> DensoControllerStatusPtr;
00095
00096 public:
00097 DensoController() :
00098 OpenControllersInterface::OpenController()
00099 {
00100 prev_angle_.resize(6);
00101 prev_vel_.resize(6);
00102 }
00103 #define SAFE_EXIT(exit_code) { \
00104 ROS_FATAL("fatal error has occurred"); \
00105 quitRequest(); \
00106 }
00107
00108 virtual ~DensoController(){}
00109
00110 void start()
00111 {
00112 OpenController::start();
00113 }
00114 private:
00115 std::string server_ip_address_;
00116 int server_port_number_;
00117
00118 int iSockFD_;
00119 u_int lhController_;
00120 u_int lhRobot_;
00121 int udp_timeout_;
00122 std::map<std::string, u_int> var_handlers_;
00123 std::map<std::string, u_short> var_types_;
00124 char errdesc_buffer_[2048];
00125
00126 std::vector<double> prev_angle_;
00127 std::vector<double> prev_vel_;
00128 struct timespec prev_time_;
00129
00130 public:
00134 BCAP_HRESULT bCapOpen()
00135 {
00136 BCAP_HRESULT hr = BCAP_S_OK;
00137 hr = bCap_Open(server_ip_address_.c_str(), server_port_number_, &iSockFD_);
00138 return hr;
00139 }
00140
00141 BCAP_HRESULT bCapClose()
00142 {
00143 BCAP_HRESULT hr = BCAP_S_OK;
00144 hr = bCap_Close(iSockFD_);
00145 return hr;
00146 }
00147
00148 BCAP_HRESULT bCapControllerConnect()
00149 {
00150 BCAP_HRESULT hr = BCAP_S_OK;
00151 hr = bCap_ControllerConnect(iSockFD_, (char*)"", (char*)"caoProv.DENSO.VRC", (char*)(server_ip_address_.c_str()), (char*)"",
00152 &lhController_);
00153 return hr;
00154 }
00155
00156 BCAP_HRESULT bCapControllerDisConnect()
00157 {
00158 BCAP_HRESULT hr = BCAP_S_OK;
00159 hr = bCap_ControllerDisconnect(iSockFD_, lhController_);
00160 return hr;
00161 }
00162
00163 BCAP_HRESULT bCapClearError()
00164 {
00165 BCAP_HRESULT hr = BCAP_S_OK;
00166 long lResult;
00167 hr = bCap_ControllerExecute(iSockFD_, lhController_, (char*)"ClearError", (char*)"", &lResult);
00168 ROS_INFO("clearError %02x %02x", hr, lResult);
00169 return hr;
00170 }
00171
00172 BCAP_HRESULT bCapGetRobot()
00173 {
00174 BCAP_HRESULT hr = BCAP_S_OK;
00175 long lResult;
00176 hr = bCap_ControllerGetRobot(iSockFD_, lhController_, (char*)"", (char*)"", &lhRobot_);
00177 ROS_INFO("GetRobot %02x %02x", hr, lhRobot_);
00178 return hr;
00179 }
00180 BCAP_HRESULT bCapReleaseRobot()
00181 {
00182 BCAP_HRESULT hr = BCAP_S_OK;
00183 hr = bCap_RobotRelease(iSockFD_, lhRobot_);
00184 return hr;
00185 }
00186
00187 BCAP_HRESULT bCapRobotExecute(char* command, char* arg)
00188 {
00189 BCAP_HRESULT hr = BCAP_S_OK;
00190 long lResult;
00191 hr = bCap_RobotExecute(iSockFD_, lhRobot_, command, arg, &lResult);
00192 return hr;
00193 }
00194
00195 BCAP_HRESULT bCapTakearm()
00196 {
00197 BCAP_VARIANT takearmparam, takearmresult;
00198 takearmparam.Type = VT_I4 | VT_ARRAY;
00199 takearmparam.Arrays = 2;
00200 ((u_int*)(&takearmparam.Value.LongValue))[0] = 0;
00201 ((u_int*)(&takearmparam.Value.LongValue))[1] = 1;
00202 BCAP_HRESULT hr;
00203
00204 hr = bCap_RobotExecute2(iSockFD_, lhRobot_, "Takearm", &takearmparam, &takearmresult);
00205
00206 return hr;
00207 }
00208
00209 BCAP_HRESULT bCapGiveArm()
00210 {
00211 BCAP_VARIANT lResult;
00212 BCAP_HRESULT hr;
00213 hr = bCap_RobotExecute(iSockFD_, lhRobot_, (char*)"Givearm", (char*)"", &lResult);
00214 return hr;
00215 }
00216
00217 BCAP_HRESULT bCapSetExternalSpeed(float arg)
00218 {
00219 BCAP_HRESULT hr;
00220 BCAP_VARIANT extspeedparam, extspeedresult;
00221 extspeedparam.Type = VT_R4 | VT_ARRAY;
00222 extspeedparam.Arrays = 1;
00223 extspeedparam.Value.FloatValue = arg;
00224
00225
00226
00227 hr = bCap_RobotExecute2(iSockFD_, lhRobot_, "ExtSpeed", &extspeedparam, &extspeedresult);
00228
00229
00230 return hr;
00231 }
00232
00233 void bCapInitializeVariableHandlers()
00234 {
00235 var_handlers_.insert(std::map<std::string, u_int>::value_type("MODE",bCapControllerGetVariable("@MODE")));
00236 var_handlers_.insert(std::map<std::string, u_int>::value_type("ERROR_CODE",bCapControllerGetVariable("@ERROR_CODE")));
00237 var_handlers_.insert(std::map<std::string, u_int>::value_type("ERROR_DESCRIPTION",bCapControllerGetVariable("@ERROR_DESCRIPTION")));
00238 var_handlers_.insert(std::map<std::string, u_int>::value_type("VERSION",bCapControllerGetVariable("@VERSION")));
00239 var_handlers_.insert(std::map<std::string, u_int>::value_type("SPEED",bCapRobotGetVariable("@SPEED")));
00240 var_handlers_.insert(std::map<std::string, u_int>::value_type("ACCEL",bCapRobotGetVariable("@ACCEL")));
00241 var_handlers_.insert(std::map<std::string, u_int>::value_type("DECEL",bCapRobotGetVariable("@DECEL")));
00242 var_handlers_.insert(std::map<std::string, u_int>::value_type("JSPEED",bCapRobotGetVariable("@JSPEED")));
00243 var_handlers_.insert(std::map<std::string, u_int>::value_type("JACCEL",bCapRobotGetVariable("@JACCEL")));
00244 var_handlers_.insert(std::map<std::string, u_int>::value_type("JDECEL",bCapRobotGetVariable("@JDECEL")));
00245 var_handlers_.insert(std::map<std::string, u_int>::value_type("EXTSPEED",bCapRobotGetVariable("@EXTSPEED")));
00246 var_handlers_.insert(std::map<std::string, u_int>::value_type("EXTACCEL",bCapRobotGetVariable("@EXTACCEL")));
00247 var_handlers_.insert(std::map<std::string, u_int>::value_type("EXTDECEL",bCapRobotGetVariable("@EXTDECEL")));
00248 var_handlers_.insert(std::map<std::string, u_int>::value_type("SERVO_ON",bCapRobotGetVariable("@SERVO_ON")));
00249 var_handlers_.insert(std::map<std::string, u_int>::value_type("BUSY_STATUS",bCapControllerGetVariable("@BUSY_STATUS")));
00250 var_handlers_.insert(std::map<std::string, u_int>::value_type("CURRENT_TIME",bCapControllerGetVariable("@CURRENT_TIME")));
00251 var_handlers_.insert(std::map<std::string, u_int>::value_type("LOCK",bCapControllerGetVariable("@LOCK")));
00252 var_handlers_.insert(std::map<std::string, u_int>::value_type("EMERGENCY_STOP",bCapControllerGetVariable("@EMERGENCY_STOP")));
00253
00254 var_types_.insert(std::map<std::string, u_short>::value_type("ERROR_CODE", VT_I4));
00255 var_types_.insert(std::map<std::string, u_short>::value_type("MODE", VT_I4));
00256 var_types_.insert(std::map<std::string, u_short>::value_type("ERROR_DESCRIPTION", VT_BSTR));
00257 var_types_.insert(std::map<std::string, u_short>::value_type("VERSION", VT_BSTR));
00258 var_types_.insert(std::map<std::string, u_short>::value_type("SPEED", VT_R4));
00259 var_types_.insert(std::map<std::string, u_short>::value_type("ACCEL", VT_R4));
00260 var_types_.insert(std::map<std::string, u_short>::value_type("DECEL", VT_R4));
00261 var_types_.insert(std::map<std::string, u_short>::value_type("JSPEED", VT_R4));
00262 var_types_.insert(std::map<std::string, u_short>::value_type("JACCEL", VT_R4));
00263 var_types_.insert(std::map<std::string, u_short>::value_type("JDECEL", VT_R4));
00264 var_types_.insert(std::map<std::string, u_short>::value_type("EXTSPEED", VT_R4));
00265 var_types_.insert(std::map<std::string, u_short>::value_type("EXTACCEL", VT_R4));
00266 var_types_.insert(std::map<std::string, u_short>::value_type("EXTDECEL", VT_R4));
00267 var_types_.insert(std::map<std::string, u_short>::value_type("BUSY_STATUS", VT_BOOL));
00268 var_types_.insert(std::map<std::string, u_short>::value_type("CURRENT_TIME", VT_DATE));
00269 var_types_.insert(std::map<std::string, u_short>::value_type("LOCK", VT_BOOL));
00270 var_types_.insert(std::map<std::string, u_short>::value_type("EMERGENCY_STOP", VT_BOOL));
00271 }
00272
00273 u_int bCapControllerGetVariable(const std::string& varname)
00274 {
00275 BCAP_HRESULT hr = BCAP_S_OK;
00276 u_int varresult;
00277 hr = bCap_ControllerGetVariable(iSockFD_, lhController_, (char*)(varname.c_str()), (char*)"", &varresult);
00278 if(FAILED(hr)) {
00279 ROS_WARN("failed to controller get variable '%s' hr:%02x result:%02x", varname.c_str(), hr, varresult);
00280 }
00281 return varresult;
00282 }
00283
00284 u_int bCapRobotGetVariable(const std::string& varname)
00285 {
00286 BCAP_HRESULT hr = BCAP_S_OK;
00287 u_int varresult;
00288 hr = bCap_RobotGetVariable(iSockFD_, lhRobot_, (char*)(varname.c_str()), (char*)"", &varresult);
00289 if(FAILED(hr)) {
00290 ROS_WARN("failed to controller get variable '%s' hr:%02x result:%02x", varname.c_str(), hr, varresult);
00291 }
00292 return varresult;
00293 }
00294
00295 bool bCapGetBoolVariable(const std::string& var_name)
00296 {
00297 bool var = 0;
00298 if( var_types_.find(var_name.c_str()) != var_types_.end() ) {
00299 BCAP_HRESULT hr = bCap_VariableGetValue(iSockFD_, var_handlers_[var_name.c_str()], &var);
00300 if( FAILED(hr) ) {
00301 ROS_WARN("Failed to get %s, return 0 instead.", var_name.c_str());
00302 return 0;
00303 }
00304 return var;
00305 }
00306 ROS_WARN("No handler for %s, return 0 instead.", var_name.c_str());
00307 return 0;
00308 }
00309
00310 u_int bCapGetIntegerVariable(const std::string& var_name)
00311 {
00312 u_int var = 0;
00313 if( var_types_.find(var_name.c_str()) != var_types_.end() ) {
00314 BCAP_HRESULT hr = bCap_VariableGetValue(iSockFD_, var_handlers_[var_name.c_str()], &var);
00315 if( FAILED(hr) ) {
00316 ROS_WARN("Failed to get %s, return 0 instead.", var_name.c_str());
00317 return 0;
00318 }
00319 return var;
00320 }
00321 ROS_WARN("No handler for %s, return 0 instead.", var_name.c_str());
00322 return 0;
00323 }
00324
00325 u_int __errorcode__;
00326 u_int bCapGetErrorCode()
00327 {
00328
00329 __errorcode__ = 0;
00330 if( var_types_.find("ERROR_CODE") != var_types_.end() ) {
00331 BCAP_HRESULT hr = bCap_VariableGetValue(iSockFD_, var_handlers_["ERROR_CODE"], &__errorcode__);
00332 if( FAILED(hr) ) {
00333 ROS_WARN("Failed to get ERROR_CODE, return %02x instead.", hr);
00334 return hr;
00335 }
00336 return __errorcode__;
00337 }
00338 ROS_WARN("ERROR_CODE is not in variable handlers");
00339 return 0;
00340 }
00341
00342
00343 u_int bCapGetMode()
00344 {
00345 return bCapGetIntegerVariable("MODE");
00346 }
00347
00348 bool bCapGetEmergencyStop()
00349 {
00350 return bCapGetBoolVariable("EMERGENCY_STOP");
00351 }
00352
00353 u_int bCapErrorDescription(std::string& errormsg)
00354 {
00355 if( var_types_.find("ERROR_DESCRIPTION") != var_types_.end() ) {
00356 BCAP_HRESULT hr = bCap_VariableGetValue(iSockFD_, var_handlers_["ERROR_DESCRIPTION"], errdesc_buffer_);
00357 errormsg = errdesc_buffer_;
00358
00359
00360 size_t strlen = 0;
00361 while(strlen<2000) {
00362 if( *((uint16_t*)errdesc_buffer_+strlen) == 0 ) {
00363 break;
00364 }
00365 ++strlen;
00366 }
00367
00368 ROS_INFO("raw error description: %s", errdesc_buffer_);
00369 try {
00370 utf8::utf16to8((uint16_t*)errdesc_buffer_, (uint16_t*)errdesc_buffer_+strlen, std::back_inserter(errormsg));
00371 } catch (utf8::invalid_utf16& e) {
00372 errormsg = errdesc_buffer_;
00373 }
00374 return hr;
00375 }
00376 ROS_WARN("ERROR_DESCRIPTION is not in variable handlers");
00377 return 0;
00378 }
00379
00380
00381 BCAP_HRESULT bCapMotor(bool command)
00382 {
00383 BCAP_HRESULT hr = BCAP_S_OK;
00384 BCAP_VARIANT motorarmparam, motorarmresult;
00385 motorarmparam.Type = VT_I4 | VT_ARRAY;
00386 motorarmparam.Arrays = 2;
00387 if (command)
00388 {
00389
00390 ((u_int*)(&motorarmparam.Value.LongValue))[0] = 1;
00391 ((u_int*)(&motorarmparam.Value.LongValue))[1] = 0;
00392
00393 hr = bCap_RobotExecute2(iSockFD_, lhRobot_, "Motor", &motorarmparam, &motorarmresult);
00394 }
00395 else
00396 {
00397
00398 ((u_int*)(&motorarmparam.Value.LongValue))[0] = 0;
00399 ((u_int*)(&motorarmparam.Value.LongValue))[1] = 1;
00400
00401 hr = bCap_RobotExecute2(iSockFD_, lhRobot_, "Motor", &motorarmparam, &motorarmresult);
00402 }
00403 return hr;
00404 }
00405
00406 BCAP_HRESULT bCapCurJnt(std::vector<double>& jointvalues)
00407 {
00408 jointvalues.resize(8);
00409 BCAP_HRESULT hr = BCAP_E_FAIL;
00410 hr = bCap_RobotExecute(iSockFD_, lhRobot_, "CurJnt", "", &jointvalues[0]);
00411 return hr;
00412 }
00413
00414 BCAP_HRESULT bCapSlvChangeMode(u_int arg)
00415 {
00416
00417
00418 BCAP_HRESULT hr;
00419 BCAP_VARIANT slvchangeparam, slvchangeresult;
00420 slvchangeparam.Type = VT_I4;
00421 slvchangeparam.Arrays = 1;
00422 slvchangeparam.Value.LongValue = arg;
00423 hr = bCap_RobotExecute2(iSockFD_, lhRobot_, "slvChangeMode", &slvchangeparam, &slvchangeresult);
00424
00425 return hr;
00426 }
00427
00428 BCAP_HRESULT bCapRobotSlvMove(BCAP_VARIANT* pose, BCAP_VARIANT* result)
00429 {
00430
00431
00432
00433
00434
00435
00436
00437
00438
00439
00440
00441
00442 extern int failed_to_send_packet;
00443 struct timespec tick, before;
00444 std::vector<double> current_angle;
00445 std::vector<double> current_vel;
00446 std::vector<double> current_acc;
00447 for (size_t i = 0; i < 6; i++)
00448 {
00449 current_angle.push_back(pose->Value.DoubleArray[i]);
00450 }
00451
00452 char* command = (char*)"slvMove";
00453 clock_gettime(CLOCK_MONOTONIC, &tick);
00454 BCAP_HRESULT hr = bCap_RobotExecute2(iSockFD_, lhRobot_, command, pose, result);
00455
00456 if (FAILED(hr)) {
00457 ROS_WARN("failed to slvmove, errorcode: %02x", hr);
00458 }
00459
00460 clock_gettime(CLOCK_MONOTONIC, &before);
00461 static const int NSEC_PER_SECOND = 1e+9;
00462
00463 double roundtrip = (before.tv_sec + double(before.tv_nsec) / NSEC_PER_SECOND)
00464 - (tick.tv_sec + double(tick.tv_nsec) / NSEC_PER_SECOND);
00465
00466 if (prev_angle_.size() > 0)
00467 {
00468 double tm = (tick.tv_sec + double(tick.tv_nsec) / NSEC_PER_SECOND)
00469 - (prev_time_.tv_sec + double(prev_time_.tv_nsec) / NSEC_PER_SECOND);
00470 current_vel.resize(6);
00471 for (size_t i = 0; i < 6; i++)
00472 {
00473 current_vel.at(i) = (current_angle[i] - prev_angle_[i]) / tm;
00474 }
00475 }
00476 if (prev_vel_.size() > 0)
00477 {
00478 double tm = (tick.tv_sec + double(tick.tv_nsec) / NSEC_PER_SECOND)
00479 - (prev_time_.tv_sec + double(prev_time_.tv_nsec) / NSEC_PER_SECOND);
00480 current_acc.resize(6);
00481 for (size_t i = 0; i < 6; i++)
00482 {
00483 current_acc.at(i) = (current_vel[i] - prev_vel_[i]) / tm;
00484 }
00485 }
00486
00487 prev_time_ = tick;
00488
00489
00490
00491
00492
00493
00494
00495
00496
00497
00498
00499
00500
00501
00502
00503
00504
00505
00506
00507
00508
00509
00510
00511
00512
00513
00514
00515
00516
00517
00518
00519 if (failed_to_send_packet)
00520 {
00521 ROS_WARN(" roundtrip: %f", roundtrip);
00522 setUDPTimeout((udp_timeout_ / 1000), (udp_timeout_ % 1000) * 1000);
00523
00524
00525
00526
00527
00528
00529
00530
00531
00532
00533
00534
00535
00536
00537
00538
00539
00540
00541 }
00542
00543
00544 for (size_t i = 0; i < 6; i++) {
00545 prev_angle_.at(i) = current_angle.at(i);
00546 prev_vel_.at(i) = current_vel.at(i);
00547
00548 }
00549 return hr;
00550 }
00551
00552 BCAP_HRESULT bCapFillBuffer()
00553 {
00554 ROS_WARN("try to fill buffer");
00555 BCAP_HRESULT hr;
00556 std::vector<double> cur_jnt;
00557 hr = bCapCurJnt(cur_jnt);
00558 BCAP_VARIANT vntPose, vntResult;
00559 vntPose.Type = VT_R8 | VT_ARRAY;
00560 vntPose.Arrays = 8;
00561 for (int i = 0; i < 8; i++)
00562 {
00563 vntPose.Value.DoubleArray[i] = cur_jnt[i];
00564 }
00565
00566
00567 for (int i = 0; i < 4; i++) {
00568 hr = bCapRobotSlvMove(&vntPose, &vntResult);
00569 if (FAILED(hr)) {
00570 return hr;
00571 }
00572 }
00573 }
00574
00575 BCAP_HRESULT bCapReflectRealState() {
00576
00577 std::vector<double> cur_jnt;
00578 BCAP_HRESULT hr;
00579 hr = bCapCurJnt(cur_jnt);
00580 int i = 0;
00581 for (OpenControllersInterface::TransmissionIterator it = cm_->model_.transmissions_.begin();
00582 it != cm_->model_.transmissions_.end(); ++it)
00583 {
00584 pr2_hardware_interface::Actuator *ac = hw_->getActuator((*it)->actuator_names_[0]);
00585 ac->state_.position_ = DEG2RAD(cur_jnt[i]);
00586 i++;
00587 }
00588 return hr;
00589 }
00590
00591 virtual void finalizeHW()
00592 {
00593 ROS_INFO("finalizeHW is called");
00594 if (!dryrunp_)
00595 {
00596 setUDPTimeout(2, 0);
00597 boost::this_thread::sleep(boost::posix_time::milliseconds(1000));
00598 long lResult;
00599 BCAP_HRESULT hr = BCAP_S_OK;
00600
00601
00602 hr = bCapSlvChangeMode(0);
00603 if (FAILED(hr))
00604 {
00605 ROS_WARN("failed to change slave mode");
00606 SAFE_EXIT(1);
00607 }
00608
00609
00610
00611
00612
00613
00614
00615
00616 hr = bCapMotor(false);
00617 if (FAILED(hr))
00618 {
00619 ROS_WARN("failed to motor off");
00620 }
00621 else
00622 {
00623 ROS_INFO("successed to motor off");
00624 }
00625 hr = bCapGiveArm();
00626 if (FAILED(hr))
00627 {
00628 ROS_WARN("failed to give arm");
00629 }
00630 else
00631 {
00632 ROS_INFO("successed to give arm");
00633 }
00634 hr = bCapReleaseRobot();
00635 if (FAILED(hr))
00636 {
00637 ROS_WARN("failed to release the robot");
00638 }
00639 else
00640 {
00641 ROS_INFO( "successed to release the robot");
00642 }
00643 hr = bCapControllerDisConnect();
00644 if (FAILED(hr))
00645 {
00646 ROS_WARN("failed to disconnect from the controller");
00647 }
00648 else
00649 {
00650 ROS_INFO("successed to disconnect from the controller");
00651 }
00652
00653 hr = bCapServerStop();
00654 if (FAILED(hr))
00655 {
00656 ROS_WARN("failed to stop the service");
00657 }
00658 else
00659 {
00660 ROS_INFO("successed to stop the service");
00661 }
00662 boost::this_thread::sleep(boost::posix_time::milliseconds(1000));
00663 hr = bCapClose();
00664 if (FAILED(hr))
00665 {
00666 ROS_WARN("failed to close bCap");
00667 }
00668 else
00669 {
00670 ROS_INFO("successed to close bCap");
00671 }
00672 }
00673 ROS_INFO("finalizing finished");
00674 }
00675
00676 OpenControllersInterface::ControllerStatusPtr updateJoints(struct timespec* spec_result)
00677 {
00678
00679 BCAP_VARIANT vntPose;
00680 vntPose.Type = VT_R8 | VT_ARRAY;
00681 vntPose.Arrays = 8;
00682 {
00683 int i = 0;
00684 for (OpenControllersInterface::TransmissionIterator it = cm_->model_.transmissions_.begin();
00685 it != cm_->model_.transmissions_.end(); ++it)
00686 {
00687 pr2_mechanism_model::JointState *js = cm_->state_->getJointState((*it)->joint_names_[0]);
00688 pr2_hardware_interface::Actuator *ac = hw_->getActuator((*it)->actuator_names_[0]);
00689
00690 double target_angle = RAD2DEG(ac->state_.position_);
00691 if (true)
00692 {
00693 target_angle = RAD2DEG(ac->state_.position_ + js->commanded_effort_);
00694
00695 #define SAFE_OFFSET_DEG 1
00696 if (RAD2DEG(cm_->state_->model_->robot_model_.getJoint((*it)->joint_names_[0])->limits->lower)
00697 + SAFE_OFFSET_DEG > target_angle)
00698 {
00699 ROS_WARN("too small joint angle! %f", target_angle);
00700 target_angle = RAD2DEG(
00701 cm_->state_->model_->robot_model_.getJoint((*it)->joint_names_[0])->limits->lower) + SAFE_OFFSET_DEG;
00702 }
00703 else if (RAD2DEG(cm_->state_->model_->robot_model_.getJoint((*it)->joint_names_[0])->limits->upper)
00704 - SAFE_OFFSET_DEG < target_angle)
00705 {
00706 ROS_WARN("too large joint angle! %f", target_angle);
00707 target_angle = RAD2DEG(
00708 cm_->state_->model_->robot_model_.getJoint((*it)->joint_names_[0])->limits->upper) - SAFE_OFFSET_DEG;
00709 }
00710
00711 }
00712 else
00713 {
00714 target_angle = RAD2DEG(ac->state_.position_);
00715 }
00716 vntPose.Value.DoubleArray[i] = target_angle;
00717 i++;
00718 }
00719 }
00720 ROS_DEBUG("target angles: %f %f %f %f %f %f", vntPose.Value.DoubleArray[0], vntPose.Value.DoubleArray[1], vntPose.Value.DoubleArray[2], vntPose.Value.DoubleArray[3], vntPose.Value.DoubleArray[4], vntPose.Value.DoubleArray[5]);
00721 vntPose.Value.DoubleArray[6] = 0;
00722 vntPose.Value.DoubleArray[7] = 0;
00723
00724 DensoControllerStatusPtr status;
00725 BCAP_VARIANT vntReturn;
00726 if (!dryrunp_)
00727 {
00728 if (spec_result)
00729 {
00730 clock_gettime(CLOCK_REALTIME, spec_result);
00731 }
00732
00733 u_int errorcode;
00734 errorcode = bCapGetErrorCode();
00735 if (FAILED(errorcode)) {
00736 ROS_WARN("bad status! robot needs recovery! hr: %02x", errorcode);
00737 status.reset(new DensoControllerStatus(errorcode));
00738 return boost::static_pointer_cast<OpenControllersInterface::ControllerStatus>(status);
00739 }
00740 BCAP_HRESULT hr = bCapRobotSlvMove(&vntPose, &vntReturn);
00741 ROS_DEBUG("updateJoints hr: %02x", hr);
00742 if (hr == 0xF200501)
00743 {
00744 ROS_DEBUG("buf is filled, it's fine.");
00745 status.reset(new DensoControllerStatus(BCAP_S_OK));
00746 }
00747 else if (FAILED(hr))
00748 {
00749 status.reset(new DensoControllerStatus(hr));
00750 }
00751 else
00752 {
00753
00754
00755
00756
00757
00758
00759
00760
00761
00762
00763
00764
00765
00766
00767
00768 status.reset(new DensoControllerStatus(hr));
00769 }
00770 } else {
00771
00772 status.reset(new DensoControllerStatus(BCAP_S_OK));
00773 for (size_t i = 0; i < 16; i++) {
00774 vntReturn.Value.DoubleArray[i] = vntPose.Value.DoubleArray[i];
00775 }
00776
00777 }
00778
00779 ROS_DEBUG("current angles: %f %f %f %f %f %f", vntReturn.Value.DoubleArray[0], vntReturn.Value.DoubleArray[1], vntReturn.Value.DoubleArray[2], vntReturn.Value.DoubleArray[3], vntReturn.Value.DoubleArray[4], vntReturn.Value.DoubleArray[5]);
00780 hw_->current_time_ = ros::Time::now();
00781 {
00782 int i = 0;
00783 for (OpenControllersInterface::TransmissionIterator it = cm_->model_.transmissions_.begin();
00784 it != cm_->model_.transmissions_.end(); ++it)
00785 {
00786 pr2_mechanism_model::JointState *js = cm_->state_->getJointState((*it)->joint_names_[0]);
00787 pr2_hardware_interface::Actuator *ac = hw_->getActuator((*it)->actuator_names_[0]);
00788 ac->state_.velocity_ = DEG2RAD(prev_vel_.at(i));
00789 if (!dryrunp_)
00790 {
00791 ac->state_.position_ = DEG2RAD(vntReturn.Value.DoubleArray[i]);
00792 }
00793 else
00794 {
00795 double target_angle = ac->state_.position_ + js->commanded_effort_;
00796 ac->state_.position_ = target_angle;
00797 }
00798 i++;
00799 }
00800 }
00801 return boost::static_pointer_cast<OpenControllersInterface::ControllerStatus>(status);
00802 }
00803
00804
00805 OpenControllersInterface::ControllerStatusPtr recoverController()
00806 {
00807 #define CAST_STATUS(hr) \
00808 boost::static_pointer_cast<OpenControllersInterface::ControllerStatus>(DensoControllerStatusPtr(new DensoControllerStatus(hr)))
00809
00810 ROS_WARN("try to recover controller...");
00811 u_int errorcode;
00812 std::string errormsg;
00813
00814 errorcode = bCapGetErrorCode();
00815 bCapErrorDescription(errormsg);
00816
00817 ROS_INFO("errormsg: %s", errormsg.c_str());
00818
00819 if (errorcode == BCAP_E_UNEXPECTED)
00820 {
00821 ROS_FATAL("Unexpected Error occured. no way to recover!");
00822 return CAST_STATUS(errorcode);
00823 }
00824
00825 if (errorcode >= 0x83204071 && errorcode <= 0x83204078)
00826 {
00827 ROS_INFO("joint angle is over the software limit.");
00828 ROS_INFO("currently, there is no way to recover, quit.");
00829
00830 return CAST_STATUS(BCAP_E_FAIL);
00831 }
00832 if (errorcode >= 0x84204081 && errorcode <= 0x842040A8)
00833 {
00834 ROS_INFO("joint angle velocity is over the software limit.");
00835 ROS_INFO("currently, there is no way to recover, quit.");
00836
00837 return CAST_STATUS(BCAP_E_FAIL);
00838 }
00839 if (errorcode >= 0x84204051 && errorcode <= 0x84204058)
00840 {
00841 ROS_INFO("joint angle velocity(sent) is over the software limit.");
00842
00843
00844
00845 BCAP_HRESULT hr;
00846 hr = bCapClearError();
00847 if (FAILED(hr)) {
00848 ROS_WARN("failed to clear error %02x", hr);
00849 return CAST_STATUS(hr);
00850 }
00851 hr = bCapGiveArm();
00852 if (FAILED(hr)) {
00853 ROS_WARN("failed to give arm %02x", hr);
00854 return CAST_STATUS(hr);
00855 }
00856
00857
00858
00859
00860
00861
00862
00863
00864
00865
00866 boost::this_thread::sleep(boost::posix_time::milliseconds(2000));
00867 hr = bCapTakearm();
00868 if (FAILED(hr)) {
00869 ROS_WARN("failed to take arm %02x", hr);
00870 return CAST_STATUS(hr);
00871 }
00872 hr = bCapMotor(true);
00873 if (FAILED(hr)) {
00874 ROS_WARN("failed to turn on motor %02x", hr);
00875 return CAST_STATUS(hr);
00876 }
00877 hr = bCapSlvChangeMode(0x202);
00878 if (FAILED(hr)) {
00879 ROS_WARN("failed to change to slvmode %02x", hr);
00880 return CAST_STATUS(hr);
00881 }
00882 return CAST_STATUS(BCAP_S_OK);
00883 }
00884 if (errorcode >= 0x84204041 && errorcode <= 0x84204048)
00885 {
00886 ROS_INFO("joint angle acceleration is over the software limit.");
00887 ROS_INFO("currently, there is no way to recover, quit.");
00888
00889 return CAST_STATUS(BCAP_E_FAIL);
00890 }
00891
00892
00893 if (errorcode == 0x83204231)
00894 {
00895 ROS_INFO("invalid command was sent and everything stopped, needs to restart everything");
00896
00897 return CAST_STATUS(BCAP_E_FAIL);
00898 }
00899
00900 if (errorcode == 0x81501003)
00901 {
00902 ROS_INFO("motor is off, turn on");
00903 BCAP_HRESULT hr = bCapMotor(true);
00904 return CAST_STATUS(hr);
00905 }
00906
00907 if (errorcode == 0x84201482)
00908 {
00909
00910
00911
00912 BCAP_HRESULT hr;
00913 hr = bCapMotor(false);
00914 if (FAILED(hr)) {
00915 ROS_WARN("failed to turn off motor %02x", hr);
00916 return CAST_STATUS(hr);
00917 }
00918 hr = bCapGiveArm();
00919 if (FAILED(hr)) {
00920 ROS_WARN("failed to give arm %02x", hr);
00921 return CAST_STATUS(hr);
00922 }
00923 hr = bCapReleaseRobot();
00924 if (FAILED(hr)) {
00925 ROS_WARN("failed to release robot %02x", hr);
00926 return CAST_STATUS(hr);
00927 }
00928 hr = bCapControllerDisConnect();
00929 if (FAILED(hr)) {
00930 ROS_WARN("failed to disconnect controller %02x", hr);
00931 return CAST_STATUS(hr);
00932 }
00933 hr = bCapServerStop();
00934 if (FAILED(hr)) {
00935 ROS_WARN("failed to stop bcap service %02x", hr);
00936 return CAST_STATUS(hr);
00937 }
00938 boost::this_thread::sleep(boost::posix_time::milliseconds(1000));
00939 hr = bCapClose();
00940 if (FAILED(hr)) {
00941 ROS_WARN("failed to close bcap socket %02x", hr);
00942 return CAST_STATUS(hr);
00943 }
00944 hr = bCapOpen();
00945 if (FAILED(hr)) {
00946 ROS_WARN("failed to open socket %02x", hr);
00947 return CAST_STATUS(hr);
00948 }
00949 setUDPTimeout(2, 0);
00950 hr = bCapServerStart();
00951 if (FAILED(hr)) {
00952 ROS_WARN("failed to start service %02x", hr);
00953 return CAST_STATUS(hr);
00954 }
00955 hr = bCapControllerConnect();
00956 if (FAILED(hr)) {
00957 ROS_WARN("failed to connect controller %02x", hr);
00958 return CAST_STATUS(hr);
00959 }
00960 hr = bCapClearError();
00961 if (FAILED(hr)) {
00962 ROS_WARN("failed to clear error %02x", hr);
00963 return CAST_STATUS(hr);
00964 }
00965 hr = bCapGetRobot();
00966 if (FAILED(hr)) {
00967 ROS_WARN("failed to get robot %02x", hr);
00968 return CAST_STATUS(hr);
00969 }
00970 hr = bCapTakearm();
00971 if (FAILED(hr)) {
00972 ROS_WARN("failed to take arm %02x", hr);
00973 return CAST_STATUS(hr);
00974 }
00975 hr = bCapMotor(true);
00976 if (FAILED(hr))
00977 {
00978 ROS_WARN("failed to turn on motor %02x", hr);
00979 return CAST_STATUS(hr);
00980 }
00981 hr = bCapRobotExecute("clearLog", "");
00982 if (FAILED(hr))
00983 {
00984 ROS_FATAL("failed to clear logging");
00985 return CAST_STATUS(hr);
00986 }
00987 hr = bCapSlvChangeMode(0x202);
00988 if (FAILED(hr))
00989 {
00990 ROS_FATAL("failed to change slave mode");
00991 return CAST_STATUS(hr);
00992 }
00993 hr = bCapFillBuffer();
00994 if (FAILED(hr))
00995 {
00996 ROS_FATAL("failed to fill bcap buffer");
00997 return CAST_STATUS(hr);
00998 }
00999 hr = bCapReflectRealState();
01000 if (FAILED(hr))
01001 {
01002 ROS_FATAL("failed to reflect real robot state into controller manager");
01003 return CAST_STATUS(hr);
01004 }
01005 setUDPTimeout((udp_timeout_ / 1000), (udp_timeout_ % 1000) * 1000);
01006
01007 return CAST_STATUS(hr);
01008 }
01009
01010 if (errorcode == 0x84201486)
01011 {
01012 u_int mode;
01013 boost::this_thread::sleep(boost::posix_time::milliseconds(2000));
01014 while(!g_quit_)
01015 {
01016 mode = bCapGetMode();
01017 if (mode != 3) {
01018
01019 ROS_WARN("waiting until you set back to auto");
01020 boost::this_thread::sleep(boost::posix_time::milliseconds(2000));
01021 } else {
01022 bool estop = bCapGetEmergencyStop();
01023 if (estop) {
01024 ROS_WARN("please turn off emergency stop");
01025 boost::this_thread::sleep(boost::posix_time::milliseconds(2000));
01026 continue;
01027 } else {
01028 break;
01029 }
01030 }
01031 }
01032
01033 BCAP_HRESULT hr;
01034 hr = bCapControllerConnect();
01035 if (FAILED(hr)) {
01036 ROS_WARN("failed to connect controller %02x", hr);
01037 return CAST_STATUS(hr);
01038 }
01039 hr = bCapClearError();
01040 if (FAILED(hr)) {
01041 ROS_WARN("failed to clear error %02x", hr);
01042 return CAST_STATUS(hr);
01043 }
01044 hr = bCapGiveArm();
01045 if (FAILED(hr)) {
01046 ROS_WARN("failed to give arm %02x", hr);
01047 return CAST_STATUS(hr);
01048 }
01049 hr = bCapGetRobot();
01050 if (FAILED(hr)) {
01051 ROS_WARN("failed to get robot %02x", hr);
01052 return CAST_STATUS(hr);
01053 }
01054 boost::this_thread::sleep(boost::posix_time::milliseconds(2000));
01055 hr = bCapTakearm();
01056 if (FAILED(hr)) {
01057 ROS_WARN("failed to take arm %02x", hr);
01058 return CAST_STATUS(hr);
01059 }
01060 hr = bCapMotor(true);
01061 if (FAILED(hr)) {
01062 ROS_WARN("failed to turn on motor %02x", hr);
01063 return CAST_STATUS(hr);
01064 }
01065 hr = bCapSlvChangeMode(0x202);
01066 if (FAILED(hr)) {
01067 ROS_WARN("failed to change to slvmode %02x", hr);
01068 return CAST_STATUS(hr);
01069 }
01070 hr = bCapFillBuffer();
01071 if (FAILED(hr)) {
01072 ROS_WARN("failed to fill buffer in slave mode");
01073 return CAST_STATUS(hr);
01074 }
01075 hr = bCapReflectRealState();
01076 if (FAILED(hr)) {
01077 ROS_WARN("failed to reflect real state");
01078 return CAST_STATUS(hr);
01079 }
01080 return CAST_STATUS(BCAP_S_OK);
01081 }
01082 if (errorcode == 0x83500121)
01083 {
01084 ROS_INFO("robot is not in slavemode, try to change it");
01085 BCAP_HRESULT hr;
01086 hr = bCapClearError();
01087 if (FAILED(hr)) return CAST_STATUS(hr);
01088 hr = bCapMotor(true);
01089 if (FAILED(hr)) {
01090 ROS_WARN("failed to turn on motor, cannot recover");
01091 return CAST_STATUS(hr);
01092 }
01093 hr = bCapRobotExecute("clearLog", "");
01094 if (FAILED(hr)) {
01095 ROS_WARN("failed to clear log");
01096 return CAST_STATUS(hr);
01097 }
01098 hr = bCapSlvChangeMode(0x202);
01099 if (FAILED(hr)) {
01100 ROS_WARN("failed to change slvmode, cannot recover");
01101 return CAST_STATUS(hr);
01102 }
01103 hr = bCapFillBuffer();
01104 if (FAILED(hr)) {
01105 ROS_WARN("failed to fill buffer in slave mode");
01106 return CAST_STATUS(hr);
01107 }
01108 hr = bCapReflectRealState();
01109 if (FAILED(hr)) {
01110 ROS_WARN("failed to reflect real state");
01111 return CAST_STATUS(hr);
01112 }
01113 return CAST_STATUS(hr);
01114 }
01115 if (errorcode == 0x83501032)
01116 {
01117
01118 ROS_INFO("invalid command when the robot is in slave mode, disable slave mode");
01119 BCAP_HRESULT hr = bCapSlvChangeMode(0);
01120 return CAST_STATUS(hr);
01121 }
01122
01123 if (errorcode == 0x81501025)
01124 {
01125 ROS_INFO("do not send message while an error is occuring");
01126 BCAP_HRESULT hr = bCapClearError();
01127 return CAST_STATUS(hr);
01128 }
01129
01130 return CAST_STATUS(BCAP_S_OK);
01131 #undef CAST_STATUS(hr)
01132 }
01133
01134 void setUDPTimeout(long sec, long usec)
01135 {
01136 #ifdef BCAP_CONNECTION_UDP
01137 struct timeval tv;
01138 tv.tv_sec = sec;
01139 tv.tv_usec = usec;
01140 if (setsockopt(iSockFD_, SOL_SOCKET, SO_SNDTIMEO, &tv, sizeof(tv)) < 0)
01141 {
01142 ROS_WARN("Failed to set send timeout");
01143 }
01144 if (setsockopt(iSockFD_, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv)) < 0)
01145 {
01146 ROS_WARN("Failed to set recv timeout");
01147 }
01148 #endif
01149 }
01150
01151 BCAP_HRESULT bCapServerStart()
01152 {
01153 BCAP_HRESULT hr = bCap_ServiceStart(iSockFD_);
01154 return hr;
01155 }
01156 BCAP_HRESULT bCapServerStop()
01157 {
01158 BCAP_HRESULT hr = bCap_ServiceStop(iSockFD_);
01159 return hr;
01160 }
01161
01165 void initializeCM()
01166 {
01167 hw_ = new pr2_hardware_interface::HardwareInterface();
01168 hw_->addActuator(new pr2_hardware_interface::Actuator("j1_motor"));
01169 hw_->addActuator(new pr2_hardware_interface::Actuator("j2_motor"));
01170 hw_->addActuator(new pr2_hardware_interface::Actuator("j3_motor"));
01171 hw_->addActuator(new pr2_hardware_interface::Actuator("j4_motor"));
01172 hw_->addActuator(new pr2_hardware_interface::Actuator("j5_motor"));
01173 hw_->addActuator(new pr2_hardware_interface::Actuator("flange_motor"));
01174
01175
01176 cm_ = boost::shared_ptr<pr2_controller_manager::ControllerManager>(
01177 new pr2_controller_manager::ControllerManager(hw_));
01178 }
01179
01183 void initializeHW()
01184 {
01185
01186 if (!dryrunp_)
01187 {
01188 BCAP_HRESULT hr;
01189 ROS_INFO("bCapOpen");
01190 hr = bCapOpen();
01191 if(FAILED(hr))
01192 {
01193 ROS_FATAL("failed to open bCap socket. Exitting...");
01194 ROS_FATAL("make sure that your robot is connected to %s:%d", server_ip_address_.c_str(), server_port_number_);
01195 exit(1);
01196 }
01197 setUDPTimeout(2, 0);
01198 ROS_INFO("bCapServerStart");
01199 hr = bCapServerStart();
01200 if(FAILED(hr))
01201 {
01202 ROS_FATAL("failed to start bCap server. Exitting...");
01203 exit(1);
01204 }
01205 ROS_INFO("bCapControllerConnect");
01206 hr = bCapControllerConnect();
01207 if(FAILED(hr))
01208 {
01209 ROS_FATAL("failed to connect bCap controller. Exitting...");
01210 exit(1);
01211 }
01212 ROS_INFO("bCapClearError");
01213 hr = bCapClearError();
01214 if(FAILED(hr))
01215 {
01216 ROS_FATAL("failed to clear bCap error. Exitting...");
01217 exit(1);
01218 }
01219 ROS_INFO("bCapGetRobot");
01220 hr = bCapGetRobot();
01221 if(FAILED(hr))
01222 {
01223 ROS_FATAL("failed to get bCap robot. Exitting...");
01224 exit(1);
01225 }
01226 ROS_INFO("bCapTakearm");
01227 hr = bCapTakearm();
01228 if(FAILED(hr))
01229 {
01230 ROS_FATAL("failed to take bCap arm. Exitting...");
01231 exit(1);
01232 }
01233 ROS_INFO("bCapSetExternalSpeed");
01234 hr = bCapSetExternalSpeed(100.0);
01235 if(FAILED(hr))
01236 {
01237 ROS_FATAL("failed to set external speed. Exitting...");
01238 exit(1);
01239 }
01240
01241 bCapInitializeVariableHandlers();
01242
01243 {
01244 ROS_WARN("bCapMotor On");
01245 hr = bCapMotor(true);
01246 if (FAILED(hr))
01247 {
01248 u_int errorcode;
01249 std::string errormsg;
01250 errorcode = bCapGetErrorCode();
01251 bCapErrorDescription(errormsg);
01252 ROS_INFO("errormsg: %s", errormsg.c_str());
01253 ROS_WARN("failed to motor on, errorcode: %02x, errormsg: %s", errorcode, errormsg.c_str());
01254
01255 finalize();
01256 SAFE_EXIT(1);
01257 }
01258 }
01259
01260
01261 hr = bCapRobotExecute("clearLog", "");
01262 if (FAILED(hr))
01263 {
01264 ROS_FATAL("failed to enable logging mode");
01265 SAFE_EXIT(1);
01266 }
01267
01268
01269
01270
01271
01272
01273
01274
01275
01276
01277 hr = bCapSlvChangeMode(0x202);
01278
01279 if (FAILED(hr))
01280 {
01281 ROS_FATAL("failed to change slave mode");
01282 SAFE_EXIT(1);
01283 }
01284
01285 ROS_INFO("initialize bCap slave connection");
01286 hr = bCapFillBuffer();
01287 if (FAILED(hr))
01288 {
01289 ROS_FATAL("failed to fill bcap buffer");
01290 SAFE_EXIT(1);
01291 }
01292 ROS_INFO("bCap slave initialization done");
01293
01294 hr = bCapReflectRealState();
01295 if (FAILED(hr))
01296 {
01297 ROS_FATAL("failed to reflect real robot state into controller manager");
01298 SAFE_EXIT(1);
01299 }
01300 setUDPTimeout((udp_timeout_ / 1000), (udp_timeout_ % 1000) * 1000);
01301 }
01302 }
01303
01304 void initializeROS(ros::NodeHandle& node)
01305 {
01306
01307
01308
01309
01310 if (!node.getParam("server_ip", server_ip_address_))
01311 {
01312 server_ip_address_ = (char*)DEFAULT_SERVER_IP_ADDRESS;
01313 }
01314
01315
01316 if (!node.getParam("server_port", server_port_number_))
01317 {
01318 server_port_number_ = DEFAULT_SERVER_PORT_NUM;
01319 }
01320
01321 if (!dryrunp_)
01322 {
01323 ROS_INFO("server: %s:%d", server_ip_address_.c_str(), server_port_number_);
01324 }
01325
01326
01327 if (!node.getParam("udp_timeout", udp_timeout_))
01328 {
01329 udp_timeout_ = DEFAULT_UDP_TIMEOUT;
01330 }
01331 if (!dryrunp_)
01332 {
01333 ROS_INFO("udp_timeout: %d micro sec", udp_timeout_);
01334 }
01335 }
01336
01337 void quitRequest()
01338 {
01339 ROS_INFO("denso_controller received a quit request");
01340 OpenController::quitRequest();
01341 ros::shutdown();
01342 }
01343 };
01344
01345 DensoController g_controller;
01346 void quitRequested(int sigint)
01347 {
01348
01349 ROS_WARN("request quit to denso controller using signal");
01350 g_controller.quitRequest();
01351 }
01352
01353 int main(int argc, char *argv[])
01354 {
01355
01356 OpenControllersInterface::OpenController::initRT();
01357
01358
01359 ros::init(argc, argv, "denso_controller",
01360
01361 ros::init_options::NoSigintHandler);
01362
01363
01364 g_controller.parseArguments(argc, argv);
01365 if (optind < argc)
01366 {
01367 g_controller.Usage("Extra arguments");
01368 }
01369
01370
01371 signal(SIGTERM, quitRequested);
01372 signal(SIGINT, quitRequested);
01373 signal(SIGHUP, quitRequested);
01374 int rv = 1;
01375
01376 g_controller.initialize();
01377 boost::thread t(&DensoController::start, &g_controller);
01378 {
01379 OpenControllersInterface::Finalizer finalizer(&g_controller);
01380 ros::Rate loop_rate(100);
01381 while (ros::ok())
01382 {
01383 ros::spinOnce();
01384 loop_rate.sleep();
01385 }
01386 ROS_WARN("ROS has been terminated");
01387 t.join();
01388 ROS_WARN("start thread has been terminated");
01389 }
01390
01391 g_controller.cleanupPidFile();
01392 return 0;
01393 }
01394