Go to the documentation of this file.00001 #include "ixis_imcs01_driver/ixis_imcs01_driver.h"
00002
00003
00004 #include <sys/ioctl.h>
00005 #include <sys/stat.h>
00006 #include <sys/time.h>
00007 #include <sys/types.h>
00008 #include <fcntl.h>
00009
00010 #include <ros/ros.h>
00011
00012 static constexpr int ROBOT_MAX_ENCODER_COUNTS {65535};
00013 static constexpr double MAX_LIN_VEL {1.11};
00014
00015 IxisImcs01Driver::IxisImcs01Driver(std::string port_name)
00016 : imcs01_fd_(-1)
00017 {
00018 rear_last_encoder_counts_.resize(2);
00019 rear_delta_encoder_counts_.resize(2);
00020 state_.position.resize(3);
00021 state_.velocity.resize(3);
00022 state_.effort.resize(3);
00023 state_.name.resize(3);
00024 for (size_t i; i < 3; ++i) {
00025 rear_last_encoder_counts_[i] = 0;
00026 rear_delta_encoder_counts_[i] = -1;
00027 state_.position[i] = 0.0;
00028 state_.velocity[i] = 0.0;
00029 state_.effort[i] = 0;
00030 }
00031 state_.name[0] = "rear_right";
00032 state_.name[1] = "rear_left";
00033 state_.name[2] = "front";
00034 this->openPort(port_name);
00035 }
00036
00037 IxisImcs01Driver::~IxisImcs01Driver()
00038 {
00039 this->closePort();
00040 }
00041
00042 int IxisImcs01Driver::openPort(std::string port_name)
00043 {
00044 imcs01_fd_ = open(port_name.c_str(), O_RDWR);
00045 if(imcs01_fd_ < 0){
00046 ROS_ERROR_STREAM("iMCs01 Open Error : " << port_name);
00047 exit(-1);
00048 }else{
00049 this->setImcs01();
00050 }
00051 return 0;
00052 }
00053
00054 int IxisImcs01Driver::closePort()
00055 {
00056 cmd_ccmd_.offset[0] = 65535;
00057 cmd_ccmd_.offset[1] = 32767;
00058 cmd_ccmd_.offset[2] = 32767;
00059 cmd_ccmd_.offset[3] = 32767;
00061 if (imcs01_fd_ > 0){
00062 write(imcs01_fd_, &cmd_ccmd_, sizeof(cmd_ccmd_));
00063 tcsetattr(imcs01_fd_, TCSANOW, &oldtio_imcs01_);
00064 close(imcs01_fd_);
00065 }
00066 }
00067
00068 int IxisImcs01Driver::setImcs01()
00069 {
00070 tcgetattr(imcs01_fd_, &oldtio_imcs01_);
00071 if(ioctl(imcs01_fd_, URBTC_CONTINUOUS_READ) < 0){
00072 ROS_ERROR_STREAM("iMCs01 ioctl URBTC_CONTINUOUS_READ error");
00073 exit(-1);
00074 }
00075 if(ioctl(imcs01_fd_, URBTC_BUFREAD) < 0){
00076 ROS_ERROR_STREAM("iMCs01 ioctl URBTC_BUFREAD error");
00077
00078 }
00079
00080 cmd_ccmd_.selout = SET_SELECT | CH0 | CH1 | CH2 | CH3;
00081 cmd_ccmd_.selin = SET_SELECT;
00082 cmd_ccmd_.setoffset = CH0 | CH1 | CH2 | CH3;
00083 cmd_ccmd_.offset[0] = 58981;
00084 cmd_ccmd_.offset[1] = 58981;
00085 cmd_ccmd_.offset[2] = 58981;
00086 cmd_ccmd_.offset[3] = 58981;
00087 cmd_ccmd_.setcounter = CH0 | CH1 | CH2 | CH3;
00088 cmd_ccmd_.counter[1] = -3633;
00089 cmd_ccmd_.counter[2] = 0;
00090 cmd_ccmd_.posneg = SET_POSNEG | CH0 | CH1 | CH2 | CH3;
00091 cmd_ccmd_.breaks = SET_BREAKS | CH0 | CH1 | CH2 | CH3;
00092 cmd_ccmd_.magicno = 0x00;
00093
00094 if (ioctl(imcs01_fd_, URBTC_COUNTER_SET) < 0){
00095 ROS_ERROR_STREAM("Faild to ioctl: URBTC_COUNTER_SET");
00096 exit(-1);
00097 }
00098 if (write(imcs01_fd_, &cmd_ccmd_, sizeof(cmd_ccmd_)) < 0){
00099 ROS_ERROR_STREAM("Faild to ioctl: Faild to write");
00100 exit(-1);
00101 }
00102 cmd_ccmd_.setcounter = 0;
00103 ROS_INFO_STREAM( "iMCs01 is Connected.");
00104 return 0;
00105 }
00106
00107 int IxisImcs01Driver::update()
00108 {
00109 std::lock_guard<std::mutex> lck {communication_mutex_};
00110 if(read(imcs01_fd_, &received_data_, sizeof(received_data_))
00111 != sizeof(received_data_)){
00112
00113 return -1;
00114 }else{
00115 this->parseEncoderTime();
00116 this->parseFrontEncoderCounts();
00117 this->parseRearEncoderCounts();
00118 return 0;
00119 }
00120 }
00121
00122 int IxisImcs01Driver::parseEncoderTime()
00123 {
00124 delta_encoder_time_ = (double)(received_data_.time) - last_encoder_time_;
00125
00126 if(delta_encoder_time_ < 0){
00127 delta_encoder_time_ = 65535 - (last_encoder_time_ - received_data_.time);
00128 }
00129 delta_encoder_time_ = delta_encoder_time_ / 1000.0;
00130 last_encoder_time_ = (double)(received_data_.time);
00131 return 0;
00132 }
00133
00134 int IxisImcs01Driver::parseFrontEncoderCounts()
00135 {
00136 int steer_encoder_counts = (int)received_data_.ct[1];
00137 state_.position[JOINT_INDEX_FRONT] = steer_encoder_counts*M_PI*67.0/3633.0/180.0;
00138
00139 return 0;
00140 }
00141
00142 int IxisImcs01Driver::parseRearEncoderCounts()
00143 {
00144 int rear_encoder_counts[2]{(int)received_data_.ct[2], -(int)received_data_.ct[3]};
00145
00146 for(int i = 0; i < 2; ++i){
00147 if(rear_delta_encoder_counts_[i] == -1
00148 || rear_encoder_counts[i] == rear_last_encoder_counts_[i]){
00149
00150 rear_delta_encoder_counts_[i] = 0;
00151
00152 }else{
00153 rear_delta_encoder_counts_[i] = rear_encoder_counts[i] - rear_last_encoder_counts_[i];
00154
00155
00156 if(rear_delta_encoder_counts_[i] > ROBOT_MAX_ENCODER_COUNTS/10){
00157 rear_delta_encoder_counts_[i] = rear_delta_encoder_counts_[i] - ROBOT_MAX_ENCODER_COUNTS;
00158 }
00159 if(rear_delta_encoder_counts_[i] < -ROBOT_MAX_ENCODER_COUNTS/10){
00160 rear_delta_encoder_counts_[i] = rear_delta_encoder_counts_[i] + ROBOT_MAX_ENCODER_COUNTS;
00161 }
00162 }
00163 rear_last_encoder_counts_[i] = rear_encoder_counts[i];
00164
00165
00166
00167
00168 state_.position[i] += rear_delta_encoder_counts_[i]*0.0238;
00169 state_.velocity[i] = (rear_delta_encoder_counts_[i]*0.0238/delta_encoder_time_);
00170 }
00171
00172 return 0;
00173 }
00174
00175 sensor_msgs::JointState IxisImcs01Driver::getJointState()
00176 {
00177 return state_;
00178 }
00179
00180 int IxisImcs01Driver::controlRearWheel(double rear_speed)
00181 {
00182 static int forward_stop_cnt = 0;
00183 static int back_stop_cnt = 0;
00184 static int max_spped_x = 3.0;
00185 static double average_spped_x = 0;
00186 static double u = 32767.0;
00187 double duty = 0;
00188
00189 if (0.0 <= rear_speed && rear_speed <= 0.05){
00190 u = 32767.0;
00191 average_spped_x = 0;
00192 this->writeOffsetCmd(RunningMode::FORWARD, (unsigned short)u);
00193 running_state_ = RunningState::FORWARD_STOP;
00194 return 0;
00195 }
00196
00197
00198 if (rear_speed >= 0.0){
00199 double rear_speed_m_s = MIN(rear_speed, MAX_LIN_VEL);
00200 if ((running_state_ == RunningState::FORWARD
00201 || running_state_ == RunningState::FORWARD_STOP) &&
00202 (state_.velocity[JOINT_INDEX_REAR_LEFT] >= 0
00203 || state_.velocity[JOINT_INDEX_REAR_RIGHT] >= 0)){
00204
00205 average_spped_x = (average_spped_x + rear_speed)/2.0;
00206 u = 32767.0 + 32767.0 * average_spped_x *1.0;
00207 duty = MIN(u, 60000);
00208 duty = MAX(duty, 32767);
00209 this->writeOffsetCmd(RunningMode::FORWARD, (unsigned short)duty);
00210 running_state_ = RunningState::FORWARD;
00211
00212 }else{
00213
00214
00215 duty = 32767;
00216 this->writeOffsetCmd(RunningMode::FORWARD, duty);
00217 average_spped_x = 0;
00218
00219 if ((state_.velocity[JOINT_INDEX_REAR_LEFT] == 0.0
00220 && state_.velocity[JOINT_INDEX_REAR_RIGHT] == 0.0 )){
00221 running_state_ = RunningState::FORWARD_STOP;
00222 forward_stop_cnt = 0;
00223 duty = 32767;
00224 this->writeOffsetCmd(RunningMode::FORWARD, duty);
00225 for (int i = 0; i < 300; ++i){ usleep(1000); }
00226
00227 }else{
00228 running_state_ = RunningState::OTHERWISE;
00229 forward_stop_cnt++;
00230
00231 }
00232 }
00233 }else{
00234
00235 average_spped_x = 0;
00236 if (running_state_ == RunningState::BACK_STOP ||
00237 running_state_ == RunningState::BACK){
00238
00239 duty = 60000;
00240 this->writeOffsetCmd(RunningMode::BACK, duty);
00241 running_state_ = RunningState::BACK;
00242
00243 }else{
00244
00245 if (back_stop_cnt >= 10){
00246 running_state_ = RunningState::BACK_STOP;
00247 back_stop_cnt = 0;
00248 duty = 32767;
00249 this->writeOffsetCmd(RunningMode::BACK, duty);
00250 for (int i = 0; i < 300; ++i){ usleep(1000); }
00251
00252 }else{
00253 usleep(50000);
00254 duty = 32767;
00255 this->writeOffsetCmd(RunningMode::FORWARD, duty);
00256 running_state_ = RunningState::OTHERWISE;
00257 back_stop_cnt++;
00258
00259 }
00260 }
00261 }
00262 }
00263
00264 int IxisImcs01Driver::writeOffsetCmd(RunningMode mode,
00265 unsigned short duty)
00266 {
00267 switch (mode) {
00268 case RunningMode::FORWARD : {
00269
00270 cmd_ccmd_.offset[0] = 65535;
00271
00272 break;
00273 }
00274 case RunningMode::BACK : {
00275
00276 cmd_ccmd_.offset[0] = 32767;
00277
00278 break;
00279 }
00280 default:
00281 break;
00282 }
00283 cmd_ccmd_.offset[1] = duty;
00284
00285 std::lock_guard<std::mutex> lck {communication_mutex_};
00286 if (write(imcs01_fd_, &cmd_ccmd_, sizeof(cmd_ccmd_)) < 0){
00287 ROS_ERROR_STREAM("iMCs01 write fail.");
00288 return -1;
00289 }else{
00290 return 0;
00291 }
00292 }