00001 #include <unistd.h>
00002 #include <iostream>
00003 #include <cstdlib>
00004 #include <cstring>
00005 #include <vector>
00006 #include "hrpsys/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
00014 #include <hrpUtil/Eigen3d.h>
00015
00016 typedef hrpsys_gazebo_msgs::JointCommand JointCommand;
00017 typedef hrpsys_gazebo_msgs::RobotState RobotState;
00018
00019 static ros::NodeHandle* rosnode;
00020 static ros::Publisher pub_joint_command;
00021 static ros::Subscriber sub_robot_state;
00022 static JointCommand jointcommand;
00023 static JointCommand initial_jointcommand;
00024
00025 static RobotState js;
00026 static int init_sub_flag = FALSE;
00027
00028 static std::vector<double> command;
00029 static std::vector<double> prev_command;
00030 static std::vector<std::vector<double> > forces;
00031 static std::vector<std::vector<double> > gyros;
00032 static std::vector<std::vector<double> > accelerometers;
00033 static std::vector<std::vector<double> > attitude_sensors;
00034 static std::vector<std::vector<double> > force_offset;
00035 static std::vector<std::vector<double> > gyro_offset;
00036 static std::vector<std::vector<double> > accel_offset;
00037 static std::vector<int> power;
00038 static std::vector<int> servo;
00039 static bool isLocked = false;
00040 static int frame = 0;
00041 static timespec g_ts;
00042 static long g_period_ns=1000000;
00043 static ros::Time rg_ts;
00044
00045 #define CHECK_JOINT_ID(id) if ((id) < 0 || (id) >= number_of_joints()) return E_ID
00046 #define CHECK_FORCE_SENSOR_ID(id) if ((id) < 0 || (id) >= number_of_force_sensors()) return E_ID
00047 #define CHECK_ACCELEROMETER_ID(id) if ((id) < 0 || (id) >= number_of_accelerometers()) return E_ID
00048 #define CHECK_GYRO_SENSOR_ID(id) if ((id) < 0 || (id) >= number_of_gyro_sensors()) return E_ID
00049 #define CHECK_ATTITUDE_SENSOR_ID(id) if ((id) < 0 || (id) >= number_of_attitude_sensors()) return E_ID
00050
00051 #define JOINT_ID_REAL2MODEL(id) joint_real2model_vec[id]
00052 #define JOINT_ID_MODEL2REAL(id) joint_id_model2real(id)
00053 #define NUM_OF_REAL_JOINT (joint_real2model_vec.size())
00054
00055 static std::map<int, int> joint_model2real_map;
00056 static std::vector<int> joint_real2model_vec;
00057
00058 static inline int joint_id_model2real(int id)
00059 {
00060 std::map< int, int>::iterator it = joint_model2real_map.find (id);
00061
00062 if (it == joint_model2real_map.end()) {
00063 return -1;
00064 } else {
00065 return it->second;
00066 }
00067 }
00068
00069 #ifdef __APPLE__
00070 typedef int clockid_t;
00071 #define CLOCK_MONOTONIC 0
00072 #include <mach/mach_time.h>
00073 int clock_gettime(clockid_t clk_id, struct timespec *tp)
00074 {
00075 if (clk_id != CLOCK_MONOTONIC) return -1;
00076
00077 uint64_t clk;
00078 clk = mach_absolute_time();
00079
00080 static mach_timebase_info_data_t info = {0,0};
00081 if (info.denom == 0) mach_timebase_info(&info);
00082
00083 uint64_t elapsednano = clk * (info.numer / info.denom);
00084
00085 tp->tv_sec = elapsednano * 1e-9;
00086 tp->tv_nsec = elapsednano - (tp->tv_sec * 1e9);
00087 return 0;
00088 }
00089
00090 #define TIMER_ABSTIME 0
00091 int clock_nanosleep(clockid_t clk_id, int flags, struct timespec *tp,
00092 struct timespec *remain)
00093 {
00094 if (clk_id != CLOCK_MONOTONIC || flags != TIMER_ABSTIME) return -1;
00095
00096 static mach_timebase_info_data_t info = {0,0};
00097 if (info.denom == 0) mach_timebase_info(&info);
00098
00099 uint64_t clk = (tp->tv_sec*1e9 + tp->tv_nsec)/(info.numer/info.denom);
00100
00101 mach_wait_until(clk);
00102 return 0;
00103 }
00104 #endif
00105
00106
00107 int number_of_joints()
00108 {
00109 return (int)command.size();
00110 }
00111
00112 int number_of_force_sensors()
00113 {
00114 return (int)forces.size();
00115 }
00116
00117 int number_of_gyro_sensors()
00118 {
00119 return (int)gyros.size();
00120 }
00121
00122 int number_of_accelerometers()
00123 {
00124 return (int)accelerometers.size();
00125 }
00126
00127 int number_of_attitude_sensors()
00128 {
00129 return (int)attitude_sensors.size();
00130 }
00131
00132 int set_number_of_joints(int num)
00133 {
00134 std::cerr << ";; IOB / set num of joint = " << num << std::endl;
00135 command.resize(num);
00136 prev_command.resize(num);
00137 power.resize(num);
00138 servo.resize(num);
00139 for (int i=0; i<num; i++){
00140 command[i] = power[i] = servo[i] = prev_command[i] = 0;
00141 }
00142 return TRUE;
00143 }
00144
00145 int set_number_of_force_sensors(int num)
00146 {
00147 forces.resize(num);
00148 force_offset.resize(num);
00149 for (unsigned int i=0; i<forces.size();i++){
00150 forces[i].resize(6);
00151 force_offset[i].resize(6);
00152 for (int j=0; j<6; j++){
00153 forces[i][j] = 0;
00154 force_offset[i][j] = 0;
00155 }
00156 }
00157 return TRUE;
00158 }
00159
00160 int set_number_of_gyro_sensors(int num)
00161 {
00162 gyros.resize(num);
00163 gyro_offset.resize(num);
00164 for (unsigned int i=0; i<gyros.size();i++){
00165 gyros[i].resize(3);
00166 gyro_offset[i].resize(3);
00167 for (int j=0; j<3; j++){
00168 gyros[i][j] = 0.0;
00169 gyro_offset[i][j] = 0.0;
00170 }
00171 }
00172 return TRUE;
00173 }
00174
00175 int set_number_of_accelerometers(int num)
00176 {
00177 accelerometers.resize(num);
00178 accel_offset.resize(num);
00179 for (unsigned int i=0; i<accelerometers.size();i++){
00180 accelerometers[i].resize(3);
00181 accel_offset[i].resize(3);
00182 for (int j=0; j<3; j++){
00183 accelerometers[i][j] = j == 2 ? 9.81 : 0.0;
00184 accel_offset[i][j] = 0;
00185 }
00186 }
00187 return TRUE;
00188 }
00189
00190 int set_number_of_attitude_sensors(int num)
00191 {
00192 attitude_sensors.resize(num);
00193 for (unsigned int i=0; i<attitude_sensors.size();i++){
00194 attitude_sensors[i].resize(3);
00195 for (int j=0; j<3; j++){
00196 attitude_sensors[i][j] = 0.0;
00197 }
00198 }
00199 return TRUE;
00200 }
00201
00202 int read_power_state(int id, int *s)
00203 {
00204 CHECK_JOINT_ID(id);
00205 *s = power[id];
00206 return TRUE;
00207 }
00208
00209 int write_power_command(int id, int com)
00210 {
00211 CHECK_JOINT_ID(id);
00212 power[id] = com;
00213 return TRUE;
00214 }
00215
00216 int read_power_command(int id, int *com)
00217 {
00218 CHECK_JOINT_ID(id);
00219 *com = power[id];
00220 return TRUE;
00221 }
00222
00223 int read_servo_state(int id, int *s)
00224 {
00225 CHECK_JOINT_ID(id);
00226 *s = servo[id];
00227 return TRUE;
00228 }
00229
00230 int read_servo_alarm(int id, int *a)
00231 {
00232 CHECK_JOINT_ID(id);
00233 *a = 0;
00234 return TRUE;
00235 }
00236
00237 int read_control_mode(int id, joint_control_mode *s)
00238 {
00239 CHECK_JOINT_ID(id);
00240 *s = JCM_POSITION;
00241 return TRUE;
00242 }
00243
00244 int write_control_mode(int id, joint_control_mode s)
00245 {
00246 CHECK_JOINT_ID(id);
00247 return TRUE;
00248 }
00249
00250 int read_actual_angle(int id, double *angle)
00251 {
00252 CHECK_JOINT_ID(id);
00253
00254 if(init_sub_flag){
00255 if (JOINT_ID_MODEL2REAL(id) < 0) {
00256 *angle = command[id];
00257 }else{
00258 *angle = js.position[JOINT_ID_MODEL2REAL(id)];
00259 }
00260 }else{
00261 *angle = command[id];
00262 }
00263 return TRUE;
00264 }
00265
00266 int read_actual_angles(double *angles)
00267 {
00268 for (int i=0; i<number_of_joints(); i++){
00269 read_actual_angle(i, &angles[i]);
00270 }
00271 return TRUE;
00272 }
00273
00274 int read_actual_torques(double *torques)
00275 {
00276 if(init_sub_flag) {
00277 for(int i=0; i<number_of_joints(); i++){
00278 if(JOINT_ID_MODEL2REAL(i) < 0) {
00279 *(torques+i) = -1;
00280 }else{
00281 *(torques+i) = js.effort[JOINT_ID_MODEL2REAL(i)];
00282 }
00283 }
00284 }
00285
00286 return TRUE;
00287 }
00288
00289 int read_command_torque(int id, double *torque)
00290 {
00291 return FALSE;
00292 }
00293
00294 int write_command_torque(int id, double torque)
00295 {
00296 return FALSE;
00297 }
00298
00299 int read_command_torques(double *torques)
00300 {
00301 return FALSE;
00302 }
00303
00304 int read_command_angle(int id, double *angle)
00305 {
00306 CHECK_JOINT_ID(id);
00307 *angle = command[id];
00308 return TRUE;
00309 }
00310
00311 int write_command_angle(int id, double angle)
00312 {
00313 CHECK_JOINT_ID(id);
00314 command[id] = angle;
00315 return TRUE;
00316 }
00317
00318 int read_command_angles(double *angles)
00319 {
00320 for (int i=0; i<number_of_joints(); i++){
00321 angles[i] = command[i];
00322 }
00323 return TRUE;
00324 }
00325
00326 int write_command_angles(const double *angles)
00327 {
00328 for (int i=0; i<number_of_joints(); i++){
00329 prev_command[i] = command[i];
00330 command[i] = angles[i];
00331 }
00332
00333 jointcommand.header.stamp = ros::Time::now();
00334
00335 for (int i=0; i<NUM_OF_REAL_JOINT; i++) {
00336 jointcommand.position[i] = command[JOINT_ID_REAL2MODEL(i)];
00337 jointcommand.velocity[i] = (command[JOINT_ID_REAL2MODEL(i)] - prev_command[JOINT_ID_REAL2MODEL(i)]) / (g_period_ns * 1e-9);
00338
00339 }
00340
00341 pub_joint_command.publish(jointcommand);
00342
00343 ros::spinOnce();
00344
00345 return TRUE;
00346 }
00347
00348 int read_pgain(int id, double *gain)
00349 {
00350 if(JOINT_ID_MODEL2REAL(id) < 0) {
00351 std::cerr << ";;; read pgain: " << id << " failed." << std::endl;
00352 }else{
00353 int iid = JOINT_ID_MODEL2REAL(id);
00354 *(gain) = jointcommand.kp_position[iid] / initial_jointcommand.kp_position[iid];
00355
00356 }
00357 return TRUE;
00358 }
00359
00360 int write_pgain(int id, double gain)
00361 {
00362
00363 if(JOINT_ID_MODEL2REAL(id) < 0) {
00364 std::cerr << ";;; write pgain: " << id << " failed." << std::endl;
00365 }else{
00366 int iid = JOINT_ID_MODEL2REAL(id);
00367 jointcommand.kp_position[iid] =
00368 gain * initial_jointcommand.kp_position[iid];
00369
00370 }
00371 return TRUE;
00372 }
00373
00374 int read_dgain(int id, double *gain)
00375 {
00376 if(JOINT_ID_MODEL2REAL(id) < 0) {
00377
00378 }else{
00379 int iid = JOINT_ID_MODEL2REAL(id);
00380 *(gain) = jointcommand.kd_position[iid] / initial_jointcommand.kd_position[iid];
00381
00382 }
00383 return TRUE;
00384 }
00385
00386 int write_dgain(int id, double gain)
00387 {
00388 if(JOINT_ID_MODEL2REAL(id) < 0) {
00389
00390 }else{
00391 int iid = JOINT_ID_MODEL2REAL(id);
00392 jointcommand.kd_position[iid] =
00393 gain * initial_jointcommand.kd_position[iid];
00394
00395 }
00396 return TRUE;
00397 }
00398
00399 int read_force_sensor(int id, double *forces)
00400 {
00401 CHECK_FORCE_SENSOR_ID(id);
00402
00403
00404
00405
00406 #if 0
00407 std::vector<geometry_msgs::Wrench*> fsensors;
00408 fsensors.push_back(&(js.l_hand));
00409 fsensors.push_back(&(js.r_hand));
00410 fsensors.push_back(&(js.l_foot));
00411 fsensors.push_back(&(js.r_foot));
00412 if(init_sub_flag){
00413 forces[0] = fsensors[id]->force.x + force_offset[id][0];
00414 forces[1] = fsensors[id]->force.y + force_offset[id][1];
00415 forces[2] = fsensors[id]->force.z + force_offset[id][2];
00416 forces[3] = fsensors[id]->torque.x + force_offset[id][3];
00417 forces[4] = fsensors[id]->torque.y + force_offset[id][4];
00418 forces[5] = fsensors[id]->torque.z + force_offset[id][5];
00419 }
00420 #endif
00421 return TRUE;
00422 }
00423
00424 int read_gyro_sensor(int id, double *rates)
00425 {
00426 CHECK_GYRO_SENSOR_ID(id);
00427
00428
00429
00430
00431 #if 0
00432 if(init_sub_flag){
00433
00434 Eigen::Quaternion<double> q(js.orientation.w,
00435 js.orientation.x,
00436 js.orientation.y,
00437 js.orientation.z);
00438 hrp::Vector3 rpy = hrp::rpyFromRot(q.toRotationMatrix());
00439 rates[0] = rpy[0];
00440 rates[1] = rpy[1];
00441 rates[2] = rpy[2];
00442
00443
00444
00445
00446
00447
00448
00449 } else {
00450
00451 rates[0] = rates[1] = rates[2] = 0.0;
00452 }
00453 #endif
00454 return TRUE;
00455 }
00456
00457 int read_accelerometer(int id, double *accels)
00458 {
00459 CHECK_ACCELEROMETER_ID(id);
00460 #if 0
00461
00462
00463
00464
00465
00466 if(init_sub_flag){
00467 accels[0] = js.linear_acceleration.x
00468 + 0.01 + accel_offset[id][0];
00469 accels[1] = js.linear_acceleration.y
00470 + 0.01 + accel_offset[id][1];
00471 accels[2] = js.linear_acceleration.z
00472 + 0.01 + accel_offset[id][2];
00473 } else {
00474
00475 accels[0] = accels[1] = 0.0;
00476 accels[2] = 9.8;
00477 }
00478 #endif
00479 return TRUE;
00480 }
00481
00482 int read_touch_sensors(unsigned short *onoff)
00483 {
00484 return FALSE;
00485 }
00486
00487 int read_attitude_sensor(int id, double *att)
00488 {
00489 return FALSE;
00490 }
00491
00492 int read_current(int id, double *mcurrent)
00493 {
00494 return FALSE;
00495 }
00496
00497 int read_current_limit(int id, double *v)
00498 {
00499 return FALSE;
00500 }
00501
00502 int read_currents(double *currents)
00503 {
00504 return FALSE;
00505 }
00506
00507 int read_gauges(double *gauges)
00508 {
00509 return FALSE;
00510 }
00511
00512 int read_command_velocity(int id, double *vel)
00513 {
00514 return FALSE;
00515 }
00516
00517 int write_command_velocity(int id, double vel)
00518 {
00519 return FALSE;
00520 }
00521
00522 int read_command_velocities(double *vels)
00523 {
00524 return FALSE;
00525 }
00526
00527 int write_command_velocities(double *vels)
00528 {
00529 return FALSE;
00530 }
00531
00532 int read_temperature(int id, double *v)
00533 {
00534 return FALSE;
00535 }
00536
00537 int write_servo(int id, int com)
00538 {
00539 servo[id] = com;
00540 return TRUE;
00541 }
00542
00543 int write_dio(unsigned short buf)
00544 {
00545 return FALSE;
00546 }
00547
00548
00549 static void setJointStates(const RobotState::ConstPtr &_js) {
00550 ROS_DEBUG(";; subscribe JointState");
00551 js = *_js;
00552 init_sub_flag = TRUE;
00553 }
00554
00555 int open_iob(void)
00556 {
00557 static bool isInitialized = false;
00558 if ( isInitialized ) return TRUE;
00559
00560 std::cerr << ";; Open IOB / start " << std::endl;
00561
00562
00563 int joint_id_real2model[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
00564 10, 11, 12, 13, 14, 15, 16, 17, 18, 19,
00565 20, 21, 22, 23, 24, 25, 26, 27, 28 };
00566
00567 joint_real2model_vec.resize(0);
00568 for(int i = 0; i < sizeof(joint_id_real2model)/sizeof(joint_id_real2model[0]); i++) {
00569 joint_real2model_vec.push_back(joint_id_real2model[i]);
00570 joint_model2real_map[joint_id_real2model[i]] = i;
00571 }
00572
00573 std::map<std::string, std::string> arg;
00574 ros::init(arg, "hrpsys_gazebo_iob", ros::init_options::NoSigintHandler);
00575
00576 rosnode = new ros::NodeHandle();
00577
00578 unsigned int n = NUM_OF_REAL_JOINT;
00579
00580 initial_jointcommand.position.resize(n);
00581 initial_jointcommand.velocity.resize(n);
00582
00583 initial_jointcommand.effort.resize(0);
00584 initial_jointcommand.kp_position.resize(n);
00585 initial_jointcommand.ki_position.resize(n);
00586 initial_jointcommand.kd_position.resize(n);
00587
00588 initial_jointcommand.kp_velocity.resize(0);
00589 initial_jointcommand.i_effort_min.resize(n);
00590 initial_jointcommand.i_effort_max.resize(n);
00591
00592 std::string namestr("hrpsys_gazebo_configuration");
00593
00594 XmlRpc::XmlRpcValue param_val;
00595 std::vector<std::string> joint_lst;
00596 rosnode->getParam(namestr + "/joints", param_val);
00597 if (param_val.getType() == XmlRpc::XmlRpcValue::TypeArray) {
00598 for(unsigned int s = 0; s < param_val.size(); s++) {
00599 std::string nstr = param_val[s];
00600
00601 joint_lst.push_back(nstr);
00602 }
00603 } else {
00604
00605 }
00606
00607 for (unsigned int i = 0; i < joint_lst.size(); ++i) {
00608 std::string joint_ns(namestr);
00609 joint_ns += ("/gains/" + joint_lst[i] + "/");
00610
00611 double p_val = 0, i_val = 0, d_val = 0, i_clamp_val = 0;
00612 std::string p_str = std::string(joint_ns)+"p";
00613 std::string i_str = std::string(joint_ns)+"i";
00614 std::string d_str = std::string(joint_ns)+"d";
00615 std::string i_clamp_str = std::string(joint_ns)+"i_clamp";
00616 if (!rosnode->getParam(p_str, p_val) ||
00617 !rosnode->getParam(i_str, i_val) ||
00618 !rosnode->getParam(d_str, d_val) ||
00619 !rosnode->getParam(i_clamp_str, i_clamp_val)) {
00620 ROS_ERROR("couldn't find a param for %s", joint_ns.c_str());
00621 continue;
00622 }
00623
00624 initial_jointcommand.kp_position[i] = p_val;
00625 initial_jointcommand.ki_position[i] = i_val;
00626 initial_jointcommand.kd_position[i] = d_val;
00627 initial_jointcommand.i_effort_min[i] = -i_clamp_val;
00628 initial_jointcommand.i_effort_max[i] = i_clamp_val;
00629 initial_jointcommand.velocity[i] = 0;
00630
00631
00632 }
00633
00634 std::string robotname;
00635 std::string rname_str = std::string(namestr) + "/robotname";
00636 rosnode->getParam(rname_str, robotname);
00637
00638 initial_jointcommand.desired_controller_period_ms = static_cast<unsigned int>(g_period_ns * 1e-6);
00639
00640 pub_joint_command = rosnode->advertise <JointCommand> (robotname + "/joint_command", 1, true);
00641
00642
00643 ros::SubscribeOptions jointStatesSo =
00644 ros::SubscribeOptions::create<RobotState>(robotname + "/robot_state", 1, setJointStates,
00645 ros::VoidPtr(), rosnode->getCallbackQueue());
00646
00647
00648
00649
00650
00651
00652 jointStatesSo.transport_hints =
00653 ros::TransportHints().unreliable().reliable().tcpNoDelay(true);
00654 sub_robot_state = rosnode->subscribe(jointStatesSo);
00655
00656 std::cerr << "JointState IOB is opened" << std::endl;
00657 for (int i=0; i < number_of_joints(); i++){
00658 command[i] = 0.0;
00659 power[i] = OFF;
00660 servo[i] = OFF;
00661 }
00662 clock_gettime(CLOCK_MONOTONIC, &g_ts);
00663 rg_ts = ros::Time::now();
00664
00665 jointcommand = initial_jointcommand;
00666 isInitialized = true;
00667 std::cerr << number_of_joints() << " / " << initial_jointcommand.position.size() << " / " << NUM_OF_REAL_JOINT << std::endl;
00668 std::cerr << ";; Open IOB / finish " << std::endl;
00669 return TRUE;
00670 }
00671
00672 int close_iob(void)
00673 {
00674 std::cerr << ";; IOB is closed" << std::endl;
00675 return TRUE;
00676 }
00677
00678 int reset_body(void)
00679 {
00680 for (int i=0; i<number_of_joints(); i++){
00681 power[i] = servo[i] = OFF;
00682 }
00683 return TRUE;
00684 }
00685
00686 int joint_calibration(int id, double angle)
00687 {
00688 return FALSE;
00689 }
00690
00691 int read_gyro_sensor_offset(int id, double *offset)
00692 {
00693 for (int i=0; i<3; i++){
00694 offset[i] = gyro_offset[id][i];
00695 }
00696 return TRUE;
00697 }
00698
00699 int write_gyro_sensor_offset(int id, double *offset)
00700 {
00701 for (int i=0; i<3; i++){
00702 gyro_offset[id][i] = offset[i];
00703 }
00704 return TRUE;
00705 }
00706
00707 int read_accelerometer_offset(int id, double *offset)
00708 {
00709 for (int i=0; i<3; i++){
00710 offset[i] = accel_offset[id][i];
00711 }
00712 return TRUE;
00713 }
00714
00715 int write_accelerometer_offset(int id, double *offset)
00716 {
00717 for (int i=0; i<3; i++){
00718 accel_offset[id][i] = offset[i];
00719 }
00720 return TRUE;
00721 }
00722
00723 int read_force_offset(int id, double *offsets)
00724 {
00725 for (int i=0; i<6; i++){
00726 offsets[i] = force_offset[id][i];
00727 }
00728 return TRUE;
00729 }
00730
00731 int write_force_offset(int id, double *offsets)
00732 {
00733 for (int i=0; i<6; i++){
00734 force_offset[id][i] = offsets[i];
00735 }
00736 return TRUE;
00737 }
00738
00739 int write_attitude_sensor_offset(int id, double *offset)
00740 {
00741 return FALSE;
00742 }
00743
00744 int read_calib_state(int id, int *s)
00745 {
00746 CHECK_JOINT_ID(id);
00747 int v = id/2;
00748 *s = v%2==0 ? ON : OFF;
00749 return TRUE;
00750 }
00751
00752 int lock_iob()
00753 {
00754 if (isLocked) return FALSE;
00755
00756
00757 return TRUE;
00758 }
00759 int unlock_iob()
00760 {
00761 isLocked = false;
00762 return TRUE;
00763 }
00764
00765 int read_lock_owner(pid_t *pid)
00766 {
00767 return FALSE;
00768 }
00769
00770 int read_limit_angle(int id, double *angle)
00771 {
00772 return FALSE;
00773 }
00774
00775 int read_angle_offset(int id, double *angle)
00776 {
00777 return FALSE;
00778 }
00779
00780 int write_angle_offset(int id, double angle)
00781 {
00782 return FALSE;
00783 }
00784
00785 int read_ulimit_angle(int id, double *angle)
00786 {
00787 return FALSE;
00788 }
00789 int read_llimit_angle(int id, double *angle)
00790 {
00791 return FALSE;
00792 }
00793 int read_encoder_pulse(int id, double *ec)
00794 {
00795 return FALSE;
00796 }
00797 int read_gear_ratio(int id, double *gr)
00798 {
00799 return FALSE;
00800 }
00801 int read_torque_const(int id, double *tc)
00802 {
00803 return FALSE;
00804 }
00805 int read_torque_limit(int id, double *limit)
00806 {
00807 return FALSE;
00808 }
00809
00810 unsigned long long read_iob_frame()
00811 {
00812 ++frame;
00813 return frame;
00814 }
00815
00816 int number_of_substeps()
00817 {
00818 return 1;
00819 }
00820
00821 int read_power(double *voltage, double *current)
00822 {
00823 *voltage = ((double)random()-RAND_MAX/2)/(RAND_MAX/2)*1+48;
00824 *current = ((double)random()-RAND_MAX/2)/(RAND_MAX/2)*0.5+1;
00825 return TRUE;
00826 }
00827
00828 int read_driver_temperature(int id, unsigned char *v)
00829 {
00830 *v = id * 2;
00831 return TRUE;
00832 }
00833
00834 void timespec_add_ns(timespec *ts, long ns)
00835 {
00836 ts->tv_nsec += ns;
00837 while (ts->tv_nsec > 1e9){
00838 ts->tv_sec += 1;
00839 ts->tv_nsec -= 1e9;
00840 }
00841 }
00842
00843 double timespec_compare(timespec *ts1, timespec *ts2)
00844 {
00845 double dts = ts1->tv_sec - ts2->tv_sec;
00846 double dtn = ts1->tv_nsec - ts2->tv_nsec;
00847 return dts*1e9+dtn;
00848 }
00849
00850 int wait_for_iob_signal()
00851 {
00852 ros::Time rnow;
00853 ros::Duration tm = ros::Duration(0, g_period_ns);
00854 ros::WallDuration wtm = ros::WallDuration(0, 100000);
00855 while ((rnow = ros::Time::now()) < rg_ts) {
00856 wtm.sleep();
00857 }
00858
00859 rg_ts += tm;
00860 if ((rg_ts - rnow).toSec() <= 0) {
00861 fprintf(stderr, "iob::overrun (%f[ms]), w:%f -> %f\n",
00862 (rnow - rg_ts).toSec()*1000, rnow.toSec(), rg_ts.toSec());
00863 do {
00864 rg_ts += tm;
00865 } while ((rg_ts - rnow).toSec() <= 0);
00866 }
00867
00868 return 0;
00869 }
00870
00871 size_t length_of_extra_servo_state(int id)
00872 {
00873 return 0;
00874 }
00875
00876 int read_extra_servo_state(int id, int *state)
00877 {
00878 return TRUE;
00879 }
00880
00881 int set_signal_period(long period_ns)
00882 {
00883 g_period_ns = period_ns;
00884 return TRUE;
00885 }
00886
00887 long get_signal_period()
00888 {
00889 return g_period_ns;
00890 }
00891
00892 int initializeJointAngle(const char *name, const char *option)
00893 {
00894 sleep(3);
00895 return TRUE;
00896 }
00897
00898 int read_digital_input(char *dinput)
00899 {
00900 return 0;
00901 }
00902
00903 int write_digital_output(const char *doutput)
00904 {
00905 return 0;
00906 }
00907
00908 int length_digital_input(void)
00909 {
00910 return 0;
00911 }
00912
00913 int length_digital_output(void)
00914 {
00915 return 0;
00916 }