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 "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"
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
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);
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);
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
00225
00226
00227
00228
00229
00230
00231
00232
00233
00234
00235
00236
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
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
00283
00284
00285
00286
00287
00288
00289
00290
00291
00292
00293
00294
00295
00296
00297
00298
00299
00300
00301
00302
00303
00304
00305
00306
00307
00308
00309
00310 if (failed_to_send_packet)
00311 {
00312 fprintf(stderr, "roundtrip: %f\n", roundtrip);
00313 setUDPTimeout(0, udp_timeout);
00314
00315
00316
00317
00318
00319
00320
00321
00322
00323
00324
00325
00326
00327
00328
00329
00330
00331
00332 }
00333 if (FAILED(hr))
00334 {
00335
00336
00337
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
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
00369
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);
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
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
00471 int i = 0;
00472 for (OpenControllersInterface::TransmissionIterator it = cm->model_.transmissions_.begin();
00473 it != cm->model_.transmissions_.end(); ++it)
00474 {
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
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 {
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
00499 double target_angle = RAD2DEG(ac->state_.position_);
00500
00501 if (true)
00502 {
00503 target_angle = RAD2DEG(ac->state_.position_ + js->commanded_effort_);
00504
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
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
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
00543 }
00544 else
00545 {
00546 while (hr == 0 && g_halt_requested == false)
00547 {
00548 fprintf(stderr, "buf space found, re-send the angles to the controller\n");
00549
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 {
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 {
00575 ac->state_.position_ = DEG2RAD(vntReturn.Value.DoubleArray[i]);
00576 }
00577 else
00578 {
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);
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
00625
00626 cm = boost::shared_ptr<pr2_controller_manager::ControllerManager>(
00627 new pr2_controller_manager::ControllerManager(hw));
00628
00629
00630 if (!dryrunp)
00631 {
00632 need_exit = true;
00633 ROS_INFO("bCapOpen");
00634 bCapOpen();
00635 ROS_INFO("bCapServerStart");
00636 setUDPTimeout(2, 0);
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
00660
00661 std::vector<double> cur_jnt = bCapCurJnt();
00662
00663
00664
00665
00666
00667
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
00678
00679
00680
00681
00682
00683
00684
00685
00686 need_exit = false;
00687 {
00688 BCAP_HRESULT hr = bCapSlvChangeMode((char*)"514");
00689
00690 if (FAILED(hr))
00691 {
00692 ROS_FATAL("failed to change slave mode");
00693 SAFE_EXIT(1);
00694 }
00695 }
00696
00697
00698
00699 int i = 0;
00700 for (OpenControllersInterface::TransmissionIterator it = cm->model_.transmissions_.begin();
00701 it != cm->model_.transmissions_.end(); ++it)
00702 {
00703 pr2_hardware_interface::Actuator *ac = hw->getActuator((*it)->actuator_names_[0]);
00704 ac->state_.position_ = DEG2RAD(cur_jnt[i]);
00705 i++;
00706 }
00707 setUDPTimeout(0, udp_timeout);
00708 sleep(5);
00709 bCapCurJnt();
00710 bCapCurJnt();
00711 bCapCurJnt();
00712
00713
00714
00715
00716
00717
00718
00719
00720
00721
00722 }
00723 }
00724
00725 void initializeROS(ros::NodeHandle& node)
00726 {
00727
00728
00729
00730
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
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
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();
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
00778 std::cerr << "quitRequested" << std::endl;
00779 g_controller.quitRequest();
00780 ros::shutdown();
00781 }
00782
00783 int main(int argc, char *argv[])
00784 {
00785
00786 OpenControllersInterface::OpenController::initRT();
00787
00788
00789 ros::init(argc, argv, "denso_controller",
00790
00791 ros::init_options::NoSigintHandler);
00792
00793
00794 g_controller.parseArguments(argc, argv);
00795 if (optind < argc)
00796 {
00797 g_controller.Usage("Extra arguments");
00798 }
00799
00800
00801 signal(SIGTERM, quitRequested);
00802 signal(SIGINT, quitRequested);
00803 signal(SIGHUP, quitRequested);
00804 int rv = 1;
00805
00806 g_controller.initialize();
00807 boost::thread t(&DensoController::start, &g_controller);
00808 {
00809
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