00001 #include <unistd.h>
00002 #include <iostream>
00003 #include <cstdlib>
00004 #include <cstring>
00005 #include <vector>
00006 #include "io/iob.h"
00007
00008 #include <ros/ros.h>
00009 #include <boost/algorithm/string.hpp>
00010
00011 #include <hrpsys_gazebo_msgs/JointCommand.h>
00012 #include <hrpsys_gazebo_msgs/RobotState.h>
00013 #include <hrpsys_gazebo_msgs/SyncCommand.h>
00014
00015 #include <hrpUtil/Eigen3d.h>
00016
00017 typedef hrpsys_gazebo_msgs::JointCommand JointCommand;
00018 typedef hrpsys_gazebo_msgs::RobotState RobotState;
00019
00020 static ros::NodeHandle* rosnode;
00021
00022 static ros::ServiceClient serv_command;
00023 static ros::Publisher pub_joint_command;
00024 static ros::Subscriber sub_robot_state;
00025 static bool iob_synchronized;
00026 static bool start_robothw = false;
00027 static bool use_velocity_feedback = false;
00028
00029 static JointCommand jointcommand;
00030 static JointCommand initial_jointcommand;
00031
00032 static RobotState js;
00033 static bool init_sub_flag = false;
00034
00035 static std::vector<double> command;
00036 static std::vector<double> prev_command;
00037 static std::vector<std::vector<double> > forces;
00038 static std::vector<std::vector<double> > gyros;
00039 static std::vector<std::vector<double> > accelerometers;
00040 static std::vector<std::vector<double> > attitude_sensors;
00041 static std::vector<std::vector<double> > force_offset;
00042 static std::vector<std::vector<double> > gyro_offset;
00043 static std::vector<std::vector<double> > accel_offset;
00044 static std::vector<int> power;
00045 static std::vector<int> servo;
00046 static bool isLocked = false;
00047 static unsigned long long frame = 0;
00048 static timespec g_ts;
00049 static long g_period_ns=1000000;
00050 static long overwrite_g_period_ns = -1;
00051 static ros::Time rg_ts;
00052 static int num_of_substeps = 1;
00053
00054 #define CHECK_JOINT_ID(id) if ((id) < 0 || (id) >= number_of_joints()) return E_ID
00055 #define CHECK_FORCE_SENSOR_ID(id) if ((id) < 0 || (id) >= number_of_force_sensors()) return E_ID
00056 #define CHECK_ACCELEROMETER_ID(id) if ((id) < 0 || (id) >= number_of_accelerometers()) return E_ID
00057 #define CHECK_GYRO_SENSOR_ID(id) if ((id) < 0 || (id) >= number_of_gyro_sensors()) return E_ID
00058 #define CHECK_ATTITUDE_SENSOR_ID(id) if ((id) < 0 || (id) >= number_of_attitude_sensors()) return E_ID
00059
00060 #define JOINT_ID_REAL2MODEL(id) joint_real2model_vec[id]
00061 #define JOINT_ID_MODEL2REAL(id) joint_id_model2real(id)
00062 #define NUM_OF_REAL_JOINT (joint_real2model_vec.size())
00063
00064 #define USE_SERVO_ON 0
00065
00066 static std::map<int, int> joint_model2real_map;
00067 static std::vector<int> joint_real2model_vec;
00068
00069 static inline int joint_id_model2real(int id)
00070 {
00071 std::map< int, int>::iterator it = joint_model2real_map.find (id);
00072
00073 if (it == joint_model2real_map.end()) {
00074 return -1;
00075 } else {
00076 return it->second;
00077 }
00078 }
00079
00080 static inline void tick_service_command()
00081 {
00082
00083 hrpsys_gazebo_msgs::SyncCommandRequest req;
00084
00085 hrpsys_gazebo_msgs::SyncCommandResponse res;
00086
00087 serv_command.call(req, res);
00088
00089 js = res.robot_state;
00090 }
00091
00092 #ifdef __APPLE__
00093 typedef int clockid_t;
00094 #define CLOCK_MONOTONIC 0
00095 #include <mach/mach_time.h>
00096 int clock_gettime(clockid_t clk_id, struct timespec *tp)
00097 {
00098 if (clk_id != CLOCK_MONOTONIC) return -1;
00099
00100 uint64_t clk;
00101 clk = mach_absolute_time();
00102
00103 static mach_timebase_info_data_t info = {0,0};
00104 if (info.denom == 0) mach_timebase_info(&info);
00105
00106 uint64_t elapsednano = clk * (info.numer / info.denom);
00107
00108 tp->tv_sec = elapsednano * 1e-9;
00109 tp->tv_nsec = elapsednano - (tp->tv_sec * 1e9);
00110 return 0;
00111 }
00112
00113 #define TIMER_ABSTIME 0
00114 int clock_nanosleep(clockid_t clk_id, int flags, struct timespec *tp,
00115 struct timespec *remain)
00116 {
00117 if (clk_id != CLOCK_MONOTONIC || flags != TIMER_ABSTIME) return -1;
00118
00119 static mach_timebase_info_data_t info = {0,0};
00120 if (info.denom == 0) mach_timebase_info(&info);
00121
00122 uint64_t clk = (tp->tv_sec*1e9 + tp->tv_nsec)/(info.numer/info.denom);
00123
00124 mach_wait_until(clk);
00125 return 0;
00126 }
00127 #endif
00128
00129
00130 int number_of_joints()
00131 {
00132 return (int)command.size();
00133 }
00134
00135 int number_of_force_sensors()
00136 {
00137 return (int)forces.size();
00138 }
00139
00140 int number_of_gyro_sensors()
00141 {
00142 return (int)gyros.size();
00143 }
00144
00145 int number_of_accelerometers()
00146 {
00147 return (int)accelerometers.size();
00148 }
00149
00150 int number_of_attitude_sensors()
00151 {
00152 return (int)attitude_sensors.size();
00153 }
00154
00155 int set_number_of_joints(int num)
00156 {
00157 std::cerr << ";; IOB / set num of joint = " << num << std::endl;
00158 command.resize(num);
00159 prev_command.resize(num);
00160 power.resize(num);
00161 servo.resize(num);
00162 for (int i=0; i<num; i++){
00163 command[i] = power[i] = servo[i] = prev_command[i] = 0;
00164 }
00165 return TRUE;
00166 }
00167
00168 int set_number_of_force_sensors(int num)
00169 {
00170 std::cerr << ";; set_number_of_force_sensors = " << num << std::endl;
00171 forces.resize(num);
00172 force_offset.resize(num);
00173 for (unsigned int i=0; i<forces.size();i++){
00174 forces[i].resize(6);
00175 force_offset[i].resize(6);
00176 for (int j=0; j<6; j++){
00177 forces[i][j] = 0;
00178 force_offset[i][j] = 0;
00179 }
00180 }
00181 return TRUE;
00182 }
00183
00184 int set_number_of_gyro_sensors(int num)
00185 {
00186 std::cerr << ";; set_number_of_gyro_sensors = " << num << std::endl;
00187 gyros.resize(num);
00188 gyro_offset.resize(num);
00189 for (unsigned int i=0; i<gyros.size();i++){
00190 gyros[i].resize(3);
00191 gyro_offset[i].resize(3);
00192 for (int j=0; j<3; j++){
00193 gyros[i][j] = 0.0;
00194 gyro_offset[i][j] = 0.0;
00195 }
00196 }
00197 return TRUE;
00198 }
00199
00200 int set_number_of_accelerometers(int num)
00201 {
00202 std::cerr << ";; set_number_of_number_of_accelerometers = " << num << std::endl;
00203 accelerometers.resize(num);
00204 accel_offset.resize(num);
00205 for (unsigned int i=0; i<accelerometers.size();i++){
00206 accelerometers[i].resize(3);
00207 accel_offset[i].resize(3);
00208 for (int j=0; j<3; j++){
00209 accelerometers[i][j] = j == 2 ? 9.81 : 0.0;
00210 accel_offset[i][j] = 0;
00211 }
00212 }
00213 return TRUE;
00214 }
00215
00216 int set_number_of_attitude_sensors(int num)
00217 {
00218 attitude_sensors.resize(num);
00219 for (unsigned int i=0; i<attitude_sensors.size();i++){
00220 attitude_sensors[i].resize(3);
00221 for (int j=0; j<3; j++){
00222 attitude_sensors[i][j] = 0.0;
00223 }
00224 }
00225 return TRUE;
00226 }
00227
00228 int read_power_state(int id, int *s)
00229 {
00230 CHECK_JOINT_ID(id);
00231 *s = power[id];
00232 return TRUE;
00233 }
00234
00235 int write_power_command(int id, int com)
00236 {
00237 CHECK_JOINT_ID(id);
00238 power[id] = com;
00239 return TRUE;
00240 }
00241
00242 int read_power_command(int id, int *com)
00243 {
00244 CHECK_JOINT_ID(id);
00245 *com = power[id];
00246 return TRUE;
00247 }
00248
00249 int read_servo_state(int id, int *s)
00250 {
00251 CHECK_JOINT_ID(id);
00252 *s = servo[id];
00253 return TRUE;
00254 }
00255
00256 int read_servo_alarm(int id, int *a)
00257 {
00258 CHECK_JOINT_ID(id);
00259 *a = 0;
00260 return TRUE;
00261 }
00262
00263 int read_control_mode(int id, joint_control_mode *s)
00264 {
00265 CHECK_JOINT_ID(id);
00266 *s = JCM_POSITION;
00267 return TRUE;
00268 }
00269
00270 int write_control_mode(int id, joint_control_mode s)
00271 {
00272 CHECK_JOINT_ID(id);
00273 return TRUE;
00274 }
00275
00276 int read_actual_angle(int id, double *angle)
00277 {
00278 CHECK_JOINT_ID(id);
00279
00280 if(init_sub_flag){
00281 if (JOINT_ID_MODEL2REAL(id) < 0) {
00282 *angle = command[id];
00283 }else{
00284 *angle = js.position[JOINT_ID_MODEL2REAL(id)];
00285 }
00286 }else{
00287 *angle = command[id];
00288 }
00289 return TRUE;
00290 }
00291
00292 int read_actual_angles(double *angles)
00293 {
00294 for (int i=0; i<number_of_joints(); i++){
00295 read_actual_angle(i, &angles[i]);
00296 }
00297 return TRUE;
00298 }
00299
00300 int read_actual_torques(double *torques)
00301 {
00302 if(init_sub_flag) {
00303 for(int i=0; i<number_of_joints(); i++){
00304 if(JOINT_ID_MODEL2REAL(i) < 0) {
00305 *(torques+i) = -1;
00306 }else{
00307 *(torques+i) = js.effort[JOINT_ID_MODEL2REAL(i)];
00308 }
00309 }
00310 }
00311
00312 return TRUE;
00313 }
00314
00315 int read_command_torque(int id, double *torque)
00316 {
00317 return FALSE;
00318 }
00319
00320 int write_command_torque(int id, double torque)
00321 {
00322 return FALSE;
00323 }
00324
00325 int read_command_torques(double *torques)
00326 {
00327 return FALSE;
00328 }
00329
00330 int write_command_torques(const double *torques)
00331 {
00332 return FALSE;
00333 }
00334
00335 int read_command_angle(int id, double *angle)
00336 {
00337 CHECK_JOINT_ID(id);
00338 *angle = command[id];
00339 return TRUE;
00340 }
00341
00342 int write_command_angle(int id, double angle)
00343 {
00344 CHECK_JOINT_ID(id);
00345 command[id] = angle;
00346 return TRUE;
00347 }
00348
00349 int read_command_angles(double *angles)
00350 {
00351 for (int i=0; i<number_of_joints(); i++){
00352 angles[i] = command[i];
00353 }
00354 return TRUE;
00355 }
00356
00357 int write_command_angles(const double *angles)
00358 {
00359
00360 for (int i=0; i<number_of_joints(); i++){
00361 prev_command[i] = command[i];
00362 command[i] = angles[i];
00363 }
00364
00365 JointCommand send_com(jointcommand);
00366 bool servo_on = true;
00367
00368 send_com.header.stamp = ros::Time::now();
00369
00370 for (int i=0; i<NUM_OF_REAL_JOINT; i++) {
00371 #if USE_SERVO_ON
00372 if (servo[JOINT_ID_REAL2MODEL(i)] > 0) {
00373 send_com.position[i] = command[JOINT_ID_REAL2MODEL(i)];
00374 send_com.velocity[i] = (command[JOINT_ID_REAL2MODEL(i)] - prev_command[JOINT_ID_REAL2MODEL(i)]) / (overwrite_g_period_ns * 1e-9);
00375 } else {
00376 servo_on = false;
00377 }
00378 #else
00379 send_com.position[i] = command[JOINT_ID_REAL2MODEL(i)];
00380 send_com.velocity[i] = (command[JOINT_ID_REAL2MODEL(i)] - prev_command[JOINT_ID_REAL2MODEL(i)]) / (overwrite_g_period_ns * 1e-9);
00381 #endif
00382 }
00383
00384 if (iob_synchronized) {
00385 hrpsys_gazebo_msgs::SyncCommandRequest req;
00386 if (servo_on) {
00387 req.joint_command = send_com;
00388 }
00389 hrpsys_gazebo_msgs::SyncCommandResponse res;
00390
00391 serv_command.call(req, res);
00392
00393 js = res.robot_state;
00394 init_sub_flag = true;
00395 } else {
00396 if(servo_on) {
00397 pub_joint_command.publish(send_com);
00398 }
00399 ros::spinOnce();
00400 }
00401 if (!start_robothw) {
00402 frame = 0;
00403 start_robothw = true;
00404 }
00405
00406 return TRUE;
00407 }
00408
00409 int read_pgain(int id, double *gain)
00410 {
00411 if(JOINT_ID_MODEL2REAL(id) < 0) {
00412 std::cerr << ";;; read pgain: " << id << " failed." << std::endl;
00413 }else{
00414 int iid = JOINT_ID_MODEL2REAL(id);
00415 if (!use_velocity_feedback) {
00416 *(gain) = jointcommand.kp_position[iid] / initial_jointcommand.kp_position[iid];
00417
00418 } else {
00419 if (initial_jointcommand.kpv_position[iid] <= 0) {
00420 *(gain) = 1.0;
00421 } else {
00422 *(gain) = jointcommand.kpv_position[iid] / initial_jointcommand.kpv_position[iid];
00423 }
00424 }
00425 }
00426 return TRUE;
00427 }
00428
00429 int write_pgain(int id, double gain)
00430 {
00431
00432 if(JOINT_ID_MODEL2REAL(id) < 0) {
00433 std::cerr << ";;; write pgain: " << id << " failed." << std::endl;
00434 }else{
00435 int iid = JOINT_ID_MODEL2REAL(id);
00436 if(!use_velocity_feedback) {
00437 jointcommand.kp_position[iid] = gain * initial_jointcommand.kp_position[iid];
00438
00439 } else {
00440 jointcommand.kpv_position[iid] = gain * initial_jointcommand.kpv_position[iid];
00441 }
00442 }
00443 return TRUE;
00444 }
00445
00446 int read_dgain(int id, double *gain)
00447 {
00448 if(JOINT_ID_MODEL2REAL(id) < 0) {
00449
00450 }else{
00451 int iid = JOINT_ID_MODEL2REAL(id);
00452 if (!use_velocity_feedback) {
00453 *(gain) = jointcommand.kd_position[iid] / initial_jointcommand.kd_position[iid];
00454
00455 } else {
00456 if(initial_jointcommand.kpv_velocity[iid] <= 0) {
00457 *(gain) = 1.0;
00458 } else {
00459 *(gain) = jointcommand.kpv_velocity[iid] / initial_jointcommand.kpv_velocity[iid];
00460 }
00461 }
00462 }
00463 return TRUE;
00464 }
00465
00466 int write_dgain(int id, double gain)
00467 {
00468 if(JOINT_ID_MODEL2REAL(id) < 0) {
00469
00470 }else{
00471 int iid = JOINT_ID_MODEL2REAL(id);
00472 if (!use_velocity_feedback) {
00473 jointcommand.kd_position[iid] =
00474 gain * initial_jointcommand.kd_position[iid];
00475
00476 } else {
00477 jointcommand.kpv_velocity[iid] =
00478 gain * initial_jointcommand.kpv_velocity[iid];
00479 }
00480 }
00481 return TRUE;
00482 }
00483
00484 int read_force_sensor(int id, double *forces)
00485 {
00486 CHECK_FORCE_SENSOR_ID(id);
00487
00488 if (id >= js.sensors.size()) {
00489 return E_ID;
00490 }
00491 if (init_sub_flag) {
00492 forces[0] = js.sensors[id].force.x + force_offset[id][0];
00493 forces[1] = js.sensors[id].force.y + force_offset[id][1];
00494 forces[2] = js.sensors[id].force.z + force_offset[id][2];
00495 forces[3] = js.sensors[id].torque.x + force_offset[id][3];
00496 forces[4] = js.sensors[id].torque.y + force_offset[id][4];
00497 forces[5] = js.sensors[id].torque.z + force_offset[id][5];
00498 } else {
00499 forces[0] = forces[1] = forces[2] = forces[3] = forces[4] = forces[5] = 0.0;
00500 }
00501 return TRUE;
00502 }
00503
00504 int read_gyro_sensor(int id, double *rates)
00505 {
00506 CHECK_GYRO_SENSOR_ID(id);
00507 if(init_sub_flag){
00508 if (id >= js.Imus.size()) {
00509 return E_ID;
00510 }
00511 #if 0
00512 Eigen::Quaternion<double> q(js.Imus[id].orientation.w,
00513 js.Imus[id].orientation.x,
00514 js.Imus[id].orientation.y,
00515 js.Imus[id].orientation.z);
00516 hrp::Vector3 rpy = hrp::rpyFromRot(q.toRotationMatrix());
00517 rates[0] = rpy[0];
00518 rates[1] = rpy[1];
00519 rates[2] = rpy[2];
00520 #endif
00521 rates[0] = js.Imus[id].angular_velocity.x + gyro_offset[id][0];
00522 rates[1] = js.Imus[id].angular_velocity.y + gyro_offset[id][1];
00523 rates[2] = js.Imus[id].angular_velocity.z + gyro_offset[id][2];
00524 } else {
00525
00526 rates[0] = rates[1] = rates[2] = 0.0;
00527 }
00528
00529 return TRUE;
00530 }
00531
00532 int read_accelerometer(int id, double *accels)
00533 {
00534 CHECK_ACCELEROMETER_ID(id);
00535
00536 if(init_sub_flag){
00537 if (id >= js.Imus.size()) {
00538 return E_ID;
00539 }
00540 accels[0] = js.Imus[id].linear_acceleration.x + accel_offset[id][0];
00541 accels[1] = js.Imus[id].linear_acceleration.y + accel_offset[id][1];
00542 accels[2] = js.Imus[id].linear_acceleration.z + accel_offset[id][2];
00543 } else {
00544
00545
00546 accels[0] = accels[1] = 0.0;
00547 accels[2] = -9.8;
00548 }
00549 return TRUE;
00550 }
00551
00552 int read_touch_sensors(unsigned short *onoff)
00553 {
00554 return FALSE;
00555 }
00556
00557 int read_attitude_sensor(int id, double *att)
00558 {
00559 return FALSE;
00560 }
00561
00562 int read_current(int id, double *mcurrent)
00563 {
00564 return FALSE;
00565 }
00566
00567 int read_current_limit(int id, double *v)
00568 {
00569 return FALSE;
00570 }
00571
00572 int read_currents(double *currents)
00573 {
00574 return FALSE;
00575 }
00576
00577 int read_gauges(double *gauges)
00578 {
00579 return FALSE;
00580 }
00581
00582 int read_actual_velocity(int id, double *vel)
00583 {
00584
00585 return FALSE;
00586 }
00587
00588 int read_command_velocity(int id, double *vel)
00589 {
00590
00591 return FALSE;
00592 }
00593
00594 int write_command_velocity(int id, double vel)
00595 {
00596
00597 return FALSE;
00598 }
00599
00600 int read_actual_velocities(double *vels)
00601 {
00602
00603 return FALSE;
00604 }
00605
00606 int read_command_velocities(double *vels)
00607 {
00608
00609 return FALSE;
00610 }
00611
00612 int write_command_velocities(const double *vels)
00613 {
00614
00615 return FALSE;
00616 }
00617
00618 int read_temperature(int id, double *v)
00619 {
00620 return FALSE;
00621 }
00622
00623 int write_servo(int id, int com)
00624 {
00625 std::cerr << "servo: id: " << id;
00626 std::cerr << "(" << servo.size() << ")";
00627 std::cerr << " - " << com << std::endl;
00628 servo[id] = com;
00629 return TRUE;
00630 }
00631
00632 int write_dio(unsigned short buf)
00633 {
00634 return FALSE;
00635 }
00636
00637
00638 static void setJointStates(const RobotState::ConstPtr &_js) {
00639 ROS_DEBUG("[iob] subscribe RobotState");
00640 js = *_js;
00641 init_sub_flag = true;
00642
00643
00644
00645 }
00646
00647 int open_iob(void)
00648 {
00649 static bool isInitialized = false;
00650 if ( isInitialized ) return TRUE;
00651 isInitialized = true;
00652
00653 std::cerr << "[iob] Open IOB / start " << std::endl;
00654
00655 std::string node_name;
00656 {
00657 char *ret = getenv("HRPSYS_GAZEBO_IOB_NAME");
00658 if (ret != NULL) {
00659 node_name.assign(ret);
00660 } else {
00661 node_name = "hrpsys_gazebo_iob";
00662 }
00663 std::cerr << "[iob] set node name : " << node_name << std::endl;
00664 }
00665
00666 std::map<std::string, std::string> arg;
00667 ros::init(arg, "hrpsys_gazebo_iob", ros::init_options::NoSigintHandler);
00668 rosnode = new ros::NodeHandle();
00669 ros::WallDuration(0.5).sleep();
00670
00671 std::string controller_name;
00672 {
00673 char *ret = getenv("HRPSYS_GAZEBO_CONFIGURATION");
00674 if (ret != NULL) {
00675 controller_name.assign(ret);
00676 } else {
00677 controller_name = "hrpsys_gazebo_configuration";
00678 }
00679 ROS_INFO_STREAM( "[iob] set controller_name : " << controller_name);
00680 }
00681 std::string robotname;
00682 {
00683 char *ret = getenv("HRPSYS_GAZEBO_ROBOTNAME");
00684 if (ret != NULL) {
00685 robotname.assign(ret);
00686
00687 controller_name = robotname + "/" + controller_name;
00688 } else {
00689 std::string rname_str = std::string(controller_name) + "/robotname";
00690 rosnode->getParam(rname_str, robotname);
00691 }
00692 if (robotname.empty()) {
00693 ROS_ERROR("[iob] did not find robot_name");
00694 robotname = "default";
00695 }
00696 ROS_INFO_STREAM( "[iob] set robot_name : " << robotname);
00697 }
00698
00699 {
00700 char *ret = getenv("HRPSYS_GAZEBO_IOB_SYNCHRONIZED");
00701 if (ret != NULL) {
00702 std::string ret_str(ret);
00703 if (ret_str.size() > 0) {
00704 iob_synchronized = true;
00705 }
00706 } else {
00707 iob_synchronized = false;
00708 }
00709 if(rosnode->hasParam(controller_name + "/use_synchronized_command")) {
00710 rosnode->getParam(controller_name + "/use_synchronized_command", iob_synchronized);
00711 }
00712 if(iob_synchronized) ROS_INFO("[iob] use synchronized command");
00713 }
00714 {
00715 char *ret = getenv("HRPSYS_GAZEBO_IOB_SUBSTEPS");
00716 if (ret != NULL) {
00717 int num = atoi(ret);
00718 if (num > 0) {
00719 num_of_substeps = num;
00720 ROS_INFO("[iob] use substeps %d", num);
00721 }
00722 }
00723 if(rosnode->hasParam(controller_name + "/iob_substeps")) {
00724 rosnode->getParam(controller_name + "/iob_substeps", num_of_substeps);
00725 ROS_INFO("[iob] use substeps %d", num_of_substeps);
00726 }
00727 }
00728 {
00729 if(rosnode->hasParam(controller_name + "/iob_rate")) {
00730 double rate = 0;
00731 rosnode->getParam(controller_name + "/iob_rate", rate);
00732 overwrite_g_period_ns = (long) ((1000 * 1000 * 1000) / rate);
00733 fprintf(stderr, "iob::period %d\n", overwrite_g_period_ns);
00734 ROS_INFO("[iob] period_ns %d", overwrite_g_period_ns);
00735 }
00736 }
00737
00738 joint_real2model_vec.resize(0);
00739
00740 if (rosnode->hasParam(controller_name + "/joint_id_list")) {
00741 XmlRpc::XmlRpcValue param_val;
00742 rosnode->getParam(controller_name + "/joint_id_list", param_val);
00743 if (param_val.getType() == XmlRpc::XmlRpcValue::TypeArray) {
00744 for(int i = 0; i < param_val.size(); i++) {
00745 int num = param_val[i];
00746 joint_real2model_vec.push_back(num);
00747 }
00748 } else {
00749 ROS_WARN("[iob] %s/joint_id_list is not list of integer", controller_name.c_str());
00750 }
00751 } else {
00752 ROS_DEBUG("[iob] %s/joint_id_list is nothing", controller_name.c_str());
00753 }
00754 if (rosnode->hasParam(controller_name + "/use_velocity_feedback")) {
00755 bool ret;
00756 rosnode->getParam(controller_name + "/use_velocity_feedback", ret);
00757 use_velocity_feedback = ret;
00758 if(ret) {
00759 ROS_INFO("[iob] use_velocity_feedback");
00760 }
00761 }
00762 XmlRpc::XmlRpcValue param_val;
00763 std::vector<std::string> joint_lst;
00764 rosnode->getParam(controller_name + "/joints", param_val);
00765 if (param_val.getType() == XmlRpc::XmlRpcValue::TypeArray) {
00766 for(unsigned int s = 0; s < param_val.size(); s++) {
00767 std::string nstr = param_val[s];
00768 ROS_DEBUG("add joint: %s", nstr.c_str());
00769 joint_lst.push_back(nstr);
00770 }
00771 } else {
00772 ROS_ERROR("[iob] %s/joints is not list of joint name", controller_name.c_str());
00773 }
00774
00775 if (joint_real2model_vec.size() == 0) {
00776 for(unsigned int i = 0; i < joint_lst.size(); i++) {
00777 joint_real2model_vec.push_back(i);
00778 }
00779 } else if (joint_real2model_vec.size() != joint_lst.size()) {
00780 ROS_ERROR("[iob] size differece on joint_id_list and joints (%ld, %ld)",
00781 joint_real2model_vec.size(), joint_lst.size());
00782 }
00783
00784 for(unsigned int i = 0; i < joint_real2model_vec.size(); i++) {
00785 joint_model2real_map[joint_real2model_vec[i]] = i;
00786 }
00787
00788 unsigned int n = NUM_OF_REAL_JOINT;
00789
00790 initial_jointcommand.position.resize(n);
00791 initial_jointcommand.velocity.resize(n);
00792
00793 initial_jointcommand.effort.resize(0);
00794
00795 if(!use_velocity_feedback) {
00796 initial_jointcommand.kp_position.resize(n);
00797 initial_jointcommand.ki_position.resize(n);
00798 initial_jointcommand.kd_position.resize(n);
00799 initial_jointcommand.kp_velocity.resize(n);
00800 initial_jointcommand.i_effort_min.resize(n);
00801 initial_jointcommand.i_effort_max.resize(n);
00802 } else {
00803 initial_jointcommand.kpv_position.resize(n);
00804 initial_jointcommand.kpv_velocity.resize(n);
00805 }
00806
00807 for (unsigned int i = 0; i < joint_lst.size(); ++i) {
00808 std::string joint_ns(controller_name);
00809 joint_ns += ("/gains/" + joint_lst[i] + "/");
00810
00811 if (!use_velocity_feedback) {
00812 double p_val = 0, i_val = 0, d_val = 0, i_clamp_val = 0, vp_val = 0;
00813 std::string p_str = std::string(joint_ns)+"p";
00814 std::string i_str = std::string(joint_ns)+"i";
00815 std::string d_str = std::string(joint_ns)+"d";
00816 std::string i_clamp_str = std::string(joint_ns)+"i_clamp";
00817 std::string vp_str = std::string(joint_ns)+"vp";
00818 if (!rosnode->getParam(p_str, p_val)) {
00819 ROS_WARN("[iob] couldn't find a P param for %s", joint_ns.c_str());
00820 }
00821 if (!rosnode->getParam(i_str, i_val)) {
00822 ROS_WARN("[iob] couldn't find a I param for %s", joint_ns.c_str());
00823 }
00824 if (!rosnode->getParam(d_str, d_val)) {
00825 ROS_WARN("[iob] couldn't find a D param for %s", joint_ns.c_str());
00826 }
00827 if (!rosnode->getParam(i_clamp_str, i_clamp_val)) {
00828 ROS_WARN("[iob] couldn't find a I_CLAMP param for %s", joint_ns.c_str());
00829 }
00830 if (!rosnode->getParam(vp_str, vp_val)) {
00831 ROS_WARN("[iob] couldn't find a VP param for %s", joint_ns.c_str());
00832 }
00833
00834 initial_jointcommand.kp_position[i] = p_val;
00835 initial_jointcommand.ki_position[i] = i_val;
00836 initial_jointcommand.kd_position[i] = d_val;
00837 initial_jointcommand.i_effort_min[i] = -i_clamp_val;
00838 initial_jointcommand.i_effort_max[i] = i_clamp_val;
00839 initial_jointcommand.velocity[i] = 0;
00840
00841 initial_jointcommand.kp_velocity[i] = vp_val;
00842 } else {
00843
00844 double p_v_val = 0, vp_v_val = 0;
00845 std::string p_v_str = std::string(joint_ns) + "p_v";
00846 std::string vp_v_str = std::string(joint_ns) + "vp_v";
00847 if (!rosnode->getParam(p_v_str, p_v_val)) {
00848 ROS_WARN("[iob] couldn't find a P_V param for %s", joint_ns.c_str());
00849 }
00850 if (!rosnode->getParam(vp_v_str, vp_v_val)) {
00851 ROS_WARN("[iob] couldn't find a VP_V param for %s", joint_ns.c_str());
00852 }
00853 initial_jointcommand.kpv_position[i] = p_v_val;
00854 initial_jointcommand.kpv_velocity[i] = vp_v_val;
00855 }
00856 }
00857
00858 initial_jointcommand.desired_controller_period_ms =
00859 static_cast<unsigned int>(overwrite_g_period_ns * 1e-6);
00860
00861 if (iob_synchronized) {
00862 serv_command =
00863 ros::service::createClient<hrpsys_gazebo_msgs::SyncCommand> (robotname + "/iob_command", true);
00864 ROS_INFO_STREAM("[iob] waiting service " << robotname << "/iob_command");
00865 serv_command.waitForExistence();
00866 ROS_INFO_STREAM("[iob] found service " << robotname << "/iob_command");
00867 } else {
00868 pub_joint_command = rosnode->advertise <JointCommand> (robotname + "/joint_command", 1, true);
00869
00870
00871 ros::SubscribeOptions jointStatesSo =
00872 ros::SubscribeOptions::create<RobotState>(robotname + "/robot_state", 1, setJointStates,
00873 ros::VoidPtr(), rosnode->getCallbackQueue());
00874
00875
00876
00877
00878
00879
00880
00881
00882
00883 jointStatesSo.transport_hints =
00884 ros::TransportHints().reliable().tcpNoDelay(true);
00885 sub_robot_state = rosnode->subscribe(jointStatesSo);
00886 }
00887
00888 for (int i=0; i < number_of_joints(); i++){
00889 command[i] = 0.0;
00890 power[i] = OFF;
00891 servo[i] = OFF;
00892 }
00893 clock_gettime(CLOCK_MONOTONIC, &g_ts);
00894 rg_ts = ros::Time::now();
00895
00896 jointcommand = initial_jointcommand;
00897 std::cerr << "[iob] " << number_of_joints() << " / " << initial_jointcommand.position.size() << " / " << NUM_OF_REAL_JOINT << std::endl;
00898
00899 if (iob_synchronized) {
00900 hrpsys_gazebo_msgs::SyncCommandRequest req;
00901 req.joint_command = jointcommand;
00902 hrpsys_gazebo_msgs::SyncCommandResponse res;
00903 std::cerr << "[iob] first service call" << std::endl;
00904 serv_command.call(req, res);
00905 std::cerr << "[iob] first service returned" << std::endl;
00906 js = res.robot_state;
00907 init_sub_flag = true;
00908 } else {
00909 std::cerr << "[iob] block until subscribing first robot_state";
00910 ros::Time start_tm = ros::Time::now();
00911 ros::Rate rr(100);
00912 ros::spinOnce();
00913 while (!init_sub_flag) {
00914 if ((ros::Time::now() - start_tm).toSec() > 5.0) {
00915 std::cerr << "[iob] timeout for waiting robot_state";
00916 break;
00917 }
00918 std::cerr << ".";
00919 rr.sleep();
00920 ros::spinOnce();
00921 }
00922 }
00923
00924 std::cerr << std::endl << "[iob] Open IOB / finish " << std::endl;
00925
00926 return TRUE;
00927 }
00928
00929 int close_iob(void)
00930 {
00931 std::cerr << "[iob] IOB is closed" << std::endl;
00932 return TRUE;
00933 }
00934
00935 int reset_body(void)
00936 {
00937 for (int i=0; i<number_of_joints(); i++){
00938 power[i] = servo[i] = OFF;
00939 }
00940 return TRUE;
00941 }
00942
00943 int joint_calibration(int id, double angle)
00944 {
00945 return FALSE;
00946 }
00947
00948 int read_gyro_sensor_offset(int id, double *offset)
00949 {
00950 for (int i=0; i<3; i++){
00951 offset[i] = gyro_offset[id][i];
00952 }
00953 return TRUE;
00954 }
00955
00956 int write_gyro_sensor_offset(int id, double *offset)
00957 {
00958 for (int i=0; i<3; i++){
00959 gyro_offset[id][i] = offset[i];
00960 }
00961 return TRUE;
00962 }
00963
00964 int read_accelerometer_offset(int id, double *offset)
00965 {
00966 for (int i=0; i<3; i++){
00967 offset[i] = accel_offset[id][i];
00968 }
00969 return TRUE;
00970 }
00971
00972 int write_accelerometer_offset(int id, double *offset)
00973 {
00974 for (int i=0; i<3; i++){
00975 accel_offset[id][i] = offset[i];
00976 }
00977 return TRUE;
00978 }
00979
00980 int read_force_offset(int id, double *offsets)
00981 {
00982 for (int i=0; i<6; i++){
00983 offsets[i] = force_offset[id][i];
00984 }
00985 return TRUE;
00986 }
00987
00988 int write_force_offset(int id, double *offsets)
00989 {
00990 for (int i=0; i<6; i++){
00991 force_offset[id][i] = offsets[i];
00992 }
00993 return TRUE;
00994 }
00995
00996 int write_attitude_sensor_offset(int id, double *offset)
00997 {
00998 return FALSE;
00999 }
01000
01001 int read_calib_state(int id, int *s)
01002 {
01003 CHECK_JOINT_ID(id);
01004 int v = id/2;
01005 *s = v%2==0 ? ON : OFF;
01006 return TRUE;
01007 }
01008
01009 int lock_iob()
01010 {
01011 if (isLocked) return FALSE;
01012
01013
01014 return TRUE;
01015 }
01016 int unlock_iob()
01017 {
01018 isLocked = false;
01019 return TRUE;
01020 }
01021
01022 int read_lock_owner(pid_t *pid)
01023 {
01024 return FALSE;
01025 }
01026
01027 int read_limit_angle(int id, double *angle)
01028 {
01029 return FALSE;
01030 }
01031
01032 int read_angle_offset(int id, double *angle)
01033 {
01034 return FALSE;
01035 }
01036
01037 int write_angle_offset(int id, double angle)
01038 {
01039 return FALSE;
01040 }
01041
01042 int read_ulimit_angle(int id, double *angle)
01043 {
01044 return FALSE;
01045 }
01046 int read_llimit_angle(int id, double *angle)
01047 {
01048 return FALSE;
01049 }
01050 int read_encoder_pulse(int id, double *ec)
01051 {
01052 return FALSE;
01053 }
01054 int read_gear_ratio(int id, double *gr)
01055 {
01056 return FALSE;
01057 }
01058 int read_torque_const(int id, double *tc)
01059 {
01060 return FALSE;
01061 }
01062 int read_torque_limit(int id, double *limit)
01063 {
01064 return FALSE;
01065 }
01066
01067 unsigned long long read_iob_frame()
01068 {
01069 ++frame;
01070 if (iob_synchronized && start_robothw) {
01071 if(frame % num_of_substeps != 0) {
01072 tick_service_command();
01073 }
01074 }
01075 return frame;
01076 }
01077
01078 int number_of_substeps()
01079 {
01080 if (iob_synchronized) {
01081 return num_of_substeps;
01082 } else {
01083 return 1;
01084 }
01085 }
01086
01087 int read_power(double *voltage, double *current)
01088 {
01089 *voltage = ((double)random()-RAND_MAX/2)/(RAND_MAX/2)*1+48;
01090 *current = ((double)random()-RAND_MAX/2)/(RAND_MAX/2)*0.5+1;
01091 return TRUE;
01092 }
01093
01094 int read_driver_temperature(int id, unsigned char *v)
01095 {
01096 *v = id * 2;
01097 return TRUE;
01098 }
01099
01100 void timespec_add_ns(timespec *ts, long ns)
01101 {
01102 ts->tv_nsec += ns;
01103 while (ts->tv_nsec > 1e9){
01104 ts->tv_sec += 1;
01105 ts->tv_nsec -= 1e9;
01106 }
01107 }
01108
01109 double timespec_compare(timespec *ts1, timespec *ts2)
01110 {
01111 double dts = ts1->tv_sec - ts2->tv_sec;
01112 double dtn = ts1->tv_nsec - ts2->tv_nsec;
01113 return dts*1e9+dtn;
01114 }
01115
01116 int wait_for_iob_signal()
01117 {
01118 if (iob_synchronized) {
01119
01120 if (start_robothw) {
01121
01122 }
01123
01124 return 0;
01125 } else {
01126
01127 ros::Time rnow;
01128 ros::Duration tm = ros::Duration(0, overwrite_g_period_ns);
01129 ros::WallDuration wtm = ros::WallDuration(0, 100000);
01130 while ((rnow = ros::Time::now()) < rg_ts) {
01131 wtm.sleep();
01132 }
01133
01134 if ((rg_ts - rnow).toSec() < 0) {
01135 if((rg_ts + tm).toSec() - rnow.toSec() < 0) {
01136 fprintf(stderr, "iob::critical overrun (%f[ms]), w:%f -> %f\n",
01137 (rnow - rg_ts).toSec()*1000, rnow.toSec(), rg_ts.toSec());
01138 }
01139 do {
01140 rg_ts += tm;
01141 } while ((rg_ts - rnow).toSec() <= 0);
01142 } else {
01143 rg_ts += tm;
01144 }
01145
01146
01147 return 0;
01148 }
01149
01150 return 0;
01151 }
01152
01153 size_t length_of_extra_servo_state(int id)
01154 {
01155 return 0;
01156 }
01157
01158 int read_extra_servo_state(int id, int *state)
01159 {
01160 return TRUE;
01161 }
01162
01163 int set_signal_period(long period_ns)
01164 {
01165 g_period_ns = period_ns;
01166 if(overwrite_g_period_ns < 0) {
01167 overwrite_g_period_ns = g_period_ns;
01168 }
01169 return TRUE;
01170 }
01171
01172 long get_signal_period()
01173 {
01174 return g_period_ns;
01175 }
01176
01177 int initializeJointAngle(const char *name, const char *option)
01178 {
01179 sleep(3);
01180 return TRUE;
01181 }
01182
01183 int read_digital_input(char *dinput)
01184 {
01185 return 0;
01186 }
01187
01188 int write_digital_output(const char *doutput)
01189 {
01190 return 0;
01191 }
01192
01193 int length_digital_input(void)
01194 {
01195 return 0;
01196 }
01197
01198 int write_digital_output_with_mask(const char *doutput, const char *mask)
01199 {
01200 return FALSE;
01201 }
01202
01203 int length_digital_output(void)
01204 {
01205 return 0;
01206 }
01207
01208 int read_digital_output(char *doutput)
01209 {
01210 return 0;
01211 }
01212