Go to the documentation of this file.00001 #include "no_collision_alg.h"
00002
00003 #include<math.h>
00004 #include<tf/tf.h>
00005 #include<algorithm>
00006
00007 NoCollisionAlgorithm::NoCollisionAlgorithm(void)
00008 {
00009
00010 this->MIN_SAFE_DISTANCE_ = 0.4;
00011 this->LASER_SAFE_DIST_ = 0.8;
00012 this->VT_MAX_ = 0.7;
00013 this->T_ACC_ = 0.5;
00014 this->DIST_TOL_ = 0.01;
00015
00016 this->MIN_SAFE_ANGLE_ = 10.0*M_PI/180.0;
00017 this->VR_MAX_ = 1.0;
00018 this->R_ACC_ = 30.0;
00019 this->ANGLE_TOL_ = 0.1;
00020
00021 this->OA_CONE_ANGLE_ = 100.0*M_PI/180.0;
00022 this->MAX_ANGLE_TO_STOP_ = 60.0*M_PI/180.0;
00023
00024 this->current_vt_ = 0.0;
00025 this->target_vt_ = this->VT_MAX_;
00026 this->desired_vt_ = this->VT_MAX_;
00027 this->acc_dist_ = 0.0;
00028 this->deacc_dist_ = 0.0;
00029 this->target_dist_ = 0.0;
00030 this->current_dist_ = 0.0;
00031 this->vt_state_ = traj_idle;
00032
00033
00034 this->current_vr_ = 0.0;
00035 this->target_vr_ = this->VR_MAX_;
00036 this->desired_vr_ = this->VR_MAX_;
00037 this->acc_angle_ = 0.0;
00038 this->deacc_angle_ = 0.0;
00039 this->target_angle_ = 0.0;
00040 this->current_angle_ = 0.0;
00041 this->vr_state_ = traj_idle;
00042 this->heading = 0.0;
00043 }
00044
00045 NoCollisionAlgorithm::~NoCollisionAlgorithm(void)
00046 {
00047 }
00048
00049 void NoCollisionAlgorithm::fromCartesian2Polar(const geometry_msgs::Point & p, float & module, float & angle)
00050 {
00051 module = sqrt( p.x*p.x + p.y*p.y );
00052 angle = atan2( p.y, p.x );
00053 }
00054
00055 void NoCollisionAlgorithm::fromPolar2Cartesian(const float & module,const float & angle,geometry_msgs::Point & p)
00056 {
00057 p.x=module*cos(angle);
00058 p.y=module*sin(angle);
00059 }
00060
00061 void NoCollisionAlgorithm::updateTranslationTrajParams(void)
00062 {
00063 float total_dist;
00064
00065
00066 this->acc_dist_=fabs((this->desired_vt_-this->current_vt_)*(this->desired_vt_-this->current_vt_)/(2*this->T_ACC_)+this->current_vt_*(this->desired_vt_-this->current_vt_)/(this->T_ACC_));
00067 this->deacc_dist_=fabs(this->desired_vt_*this->desired_vt_/(2*this->T_ACC_));
00068 total_dist=this->acc_dist_+this->deacc_dist_;
00069 if(fabs(total_dist)>fabs(this->current_dist_))
00070 this->target_vt_=sqrt(this->T_ACC_*fabs(this->current_dist_)+this->current_vt_*this->current_vt_/2);
00071 else
00072 this->target_vt_=this->desired_vt_;
00073 ROS_INFO("Target translational speed: %f, Acceleration distance: %f, Deceleration distance: %f",this->target_vt_,this->acc_dist_,this->deacc_dist_);
00074 }
00075
00076 void NoCollisionAlgorithm::updateRotationTrajParams(void)
00077 {
00078 float total_angle;
00079 int dir=0;
00080
00081
00082 if(this->target_angle_>=0) dir=1;
00083 else dir=-1;
00084 this->acc_angle_=fabs((dir*this->desired_vr_-this->current_vr_)*(dir*this->desired_vr_-this->current_vr_)/(2*this->R_ACC_)+this->current_vr_*(dir*this->desired_vr_-this->current_vr_)/(this->R_ACC_));
00085 this->deacc_angle_=fabs(this->desired_vr_*this->desired_vr_/(2*this->R_ACC_));
00086 total_angle=this->acc_angle_+this->deacc_angle_;
00087 if(fabs(total_angle)>fabs(this->current_angle_))
00088 this->target_vr_=dir*sqrt(this->R_ACC_*fabs(this->current_angle_)+this->current_vr_*this->current_vr_/2);
00089 else
00090 this->target_vr_=dir*this->desired_vr_;
00091 ROS_INFO("Target rotational speed: %f, Acceleration angle: %f, Deceleration angle: %f",this->target_vr_,this->acc_angle_,this->deacc_angle_);
00092 }
00093
00094 void NoCollisionAlgorithm::config_update(const Config& new_cfg, uint32_t level)
00095 {
00096 this->lock();
00097
00098 MIN_SAFE_DISTANCE_ = new_cfg.min_safety_dist;
00099 MIN_SAFE_ANGLE_ = new_cfg.min_safety_angle*M_PI/180.0;
00100 LASER_SAFE_DIST_ = new_cfg.laser_safe_dist;
00101 VT_MAX_ = new_cfg.vT_max;
00102 VR_MAX_ = new_cfg.vR_max;
00103 R_ACC_ = new_cfg.r_acc;
00104 T_ACC_ = new_cfg.t_acc;
00105 OA_CONE_ANGLE_ = new_cfg.oa_cone_aperture*M_PI/180.0;
00106 MAX_ANGLE_TO_STOP_ = new_cfg.max_angle2stop*M_PI/180.0;
00107
00108 this->config_=new_cfg;
00109 this->unlock();
00110 }
00111
00112
00113 void NoCollisionAlgorithm::setGoal(const geometry_msgs::Pose & local_goal)
00114 {
00115 this->lock();
00116 ROS_WARN("NoCollisionAlgorithm::setGoal");
00117
00118
00119 fromCartesian2Polar(local_goal.position,this->target_dist_,this->target_angle_);
00120
00121 this->target_dist_-=LASER_SAFE_DIST_+MIN_SAFE_DISTANCE_;
00122 if(this->target_dist_<0) this->target_dist_=0;
00123 this->current_dist_=this->target_dist_;
00124 this->current_angle_=this->target_angle_;
00125 this->target_vt_=this->desired_vt_;
00126 this->target_vr_=this->desired_vr_;
00127
00128 this->heading=local_goal.orientation.z-this->target_angle_;
00129 ROS_INFO("NoCollisionAlgorithm::Distance: %f Angle: %f",this->target_dist_,this->target_angle_);
00130 this->updateTranslationTrajParams();
00131 this->updateRotationTrajParams();
00132
00133 this->current_time_ = ros::Time::now();
00134 this->unlock();
00135 }
00136
00137 bool NoCollisionAlgorithm::isGoalReached()
00138 {
00139 if(this->vt_state_>=traj_deacc && this->vr_state_>=traj_deacc)
00140 return true;
00141 else
00142 return false;
00143 }
00144
00145 void NoCollisionAlgorithm::setTranslationalSpeed(const double vt)
00146 {
00147 double speed;
00148
00149 this->lock();
00150 if(vt>this->VT_MAX_)
00151 speed=this->VT_MAX_;
00152 else
00153 speed=vt;
00154
00155 this->desired_vt_=speed;
00156
00157 if(this->vt_state_!=traj_deacc)
00158 {
00159 this->updateTranslationTrajParams();
00160 this->updateRotationTrajParams();
00161 }
00162 this->unlock();
00163 }
00164
00165 void NoCollisionAlgorithm::setRotationalSpeed(const double vr)
00166 {
00167 double speed;
00168
00169 this->lock();
00170 if(vr>this->VR_MAX_)
00171 speed=this->VR_MAX_;
00172 else
00173 speed=vr;
00174
00175 this->desired_vr_=speed;
00176
00177 if(this->vr_state_!=traj_deacc)
00178 {
00179 this->updateTranslationTrajParams();
00180 this->updateRotationTrajParams();
00181 }
00182 this->unlock();
00183 }
00184
00185 void NoCollisionAlgorithm::getDistance2Goal(geometry_msgs::Pose ¤t_goal)
00186 {
00187 fromPolar2Cartesian(fabs(this->target_dist_-this->current_dist_),this->target_angle_-this->current_angle_,current_goal.position);
00188 std::cout << fabs(this->target_dist_-this->current_dist_) << "," << this->target_angle_-this->current_angle_ << std::endl;
00189 }
00190
00191 bool NoCollisionAlgorithm::movePlatform(const sensor_msgs::LaserScan & laser,const geometry_msgs::Pose & local_goal, geometry_msgs::Twist &twist)
00192 {
00193 ros::Time prev_time = current_time_;
00194 current_time_ = ros::Time::now();
00195 double dist_error,angle_error;
00196 double dt = current_time_.toSec() - prev_time.toSec();
00197
00198 this->lock();
00199 ROS_WARN("NoCollisionAlgorithm::movePlatform::MOVE!");
00200
00201 fromCartesian2Polar(local_goal.position,this->current_dist_,this->current_angle_);
00202 this->current_dist_-=LASER_SAFE_DIST_+MIN_SAFE_DISTANCE_;
00203 if(this->current_dist_<0)
00204 this->current_dist_=0;
00205 ROS_WARN("NoCollisionAlgorithm::Current dist: %f Current angle: %f",this->current_dist_,this->current_angle_);
00206
00207 angle_error=fabs(this->current_angle_);
00208 if(angle_error>=this->ANGLE_TOL_)
00209 {
00210 if(this->vr_state_==traj_idle)
00211 {
00212 this->target_vr_=this->desired_vr_;
00213 this->target_angle_=this->current_angle_;
00214 this->updateRotationTrajParams();
00215 }
00216 if(this->current_vr_!=this->target_vr_)
00217 {
00218 if(this->current_vr_<this->target_vr_)
00219 {
00220 this->current_vr_+=this->R_ACC_*dt;
00221 if(this->current_vr_>this->target_vr_)
00222 this->current_vr_=this->target_vr_;
00223 }
00224 else
00225 {
00226 this->current_vr_-=this->R_ACC_*dt;
00227 if(this->current_vr_<this->target_vr_)
00228 this->current_vr_=this->target_vr_;
00229 }
00230 this->vr_state_=traj_acc;
00231 }
00232 else
00233 {
00234 if(angle_error>=this->deacc_angle_)
00235 {
00236
00237 this->vr_state_=traj_speed;
00238 }
00239 else
00240 {
00241 if(this->current_vr_>0)
00242 {
00243 this->current_vr_-=this->R_ACC_*dt;
00244 if(this->current_vr_<=0)
00245 this->current_vr_=0;
00246 this->target_vr_=this->current_vr_;
00247 }
00248 else
00249 {
00250 this->current_vr_+=this->R_ACC_*dt;
00251 if(this->current_vr_>=0)
00252 this->current_vr_=0;
00253 this->target_vr_=this->current_vr_;
00254 }
00255 this->vr_state_=traj_deacc;
00256 }
00257 }
00258 }
00259 else
00260 {
00261 this->current_vr_=0;
00262 this->vr_state_=traj_idle;
00263 }
00264
00265 if(angle_error<(MAX_ANGLE_TO_STOP_))
00266 {
00267
00268 if(isGoalTraversable(laser,local_goal.position))
00269 {
00270 dist_error=fabs(this->current_dist_);
00271 if(dist_error>=this->DIST_TOL_)
00272 {
00273 if(this->vt_state_==traj_idle)
00274 {
00275 this->target_vt_=this->desired_vt_;
00276 this->target_dist_=this->current_dist_;
00277 this->updateTranslationTrajParams();
00278 }
00279 if(this->current_vt_!=this->target_vt_)
00280 {
00281 if(this->current_vt_<this->target_vt_)
00282 {
00283 this->current_vt_+=this->T_ACC_*dt;
00284 if(this->current_vt_>this->target_vt_)
00285 this->current_vt_=this->target_vt_;
00286 }
00287 else
00288 {
00289 this->current_vt_-=this->T_ACC_*dt;
00290 if(this->current_vt_<this->target_vt_)
00291 this->current_vt_=this->target_vt_;
00292 }
00293 this->vt_state_=traj_acc;
00294 }
00295 else
00296 {
00297 if(dist_error>=this->deacc_dist_)
00298 {
00299
00300 this->vt_state_=traj_speed;
00301 }
00302 else
00303 {
00304 if(this->current_vt_>0)
00305 {
00306 this->current_vt_-=this->T_ACC_*dt;
00307 if(this->current_vt_<=0)
00308 this->current_vt_=0;
00309 this->target_vt_=this->current_vt_;
00310 }
00311 else
00312 {
00313 this->current_vt_+=this->T_ACC_*dt;
00314 if(this->current_vt_>=0)
00315 this->current_vt_=0;
00316 this->target_vt_=this->current_vt_;
00317 }
00318 this->vt_state_=traj_deacc;
00319 }
00320 }
00321 }
00322 else
00323 {
00324 this->current_vt_=0;
00325 this->vt_state_=traj_idle;
00326 }
00327 }
00328 else
00329 {
00330 ROS_WARN("NoCollisionAlgorithm::movePlatform::STOP!");
00331
00332 this->current_vt_=0;
00333 }
00334 }
00335 else
00336 {
00337 if(this->current_vt_==0)
00338 this->vt_state_=traj_idle;
00339 else
00340 {
00341 if(this->current_vt_>0)
00342 {
00343 this->current_vt_-=this->T_ACC_*dt;
00344 if(this->current_vt_<=0)
00345 this->current_vt_=0;
00346 this->target_vt_=this->current_vt_;
00347 }
00348 else
00349 {
00350 this->current_vt_+=this->T_ACC_*dt;
00351 if(this->current_vt_>=0)
00352 this->current_vt_=0;
00353 this->target_vt_=this->current_vt_;
00354 }
00355 this->vt_state_=traj_deacc;
00356 }
00357 }
00358 twist.linear.x=this->current_vt_;
00359 twist.angular.z=this->current_vr_;
00360 ROS_INFO("vT=%f\t\tvR=%f,state=%d", twist.linear.x, twist.angular.z,this->vr_state_);
00361 this->unlock();
00362 if(this->vt_state_==traj_idle && this->vr_state_==traj_idle)
00363 return true;
00364 else
00365 return false;
00366 }
00367
00368 bool NoCollisionAlgorithm::isGoalTraversable(const sensor_msgs::LaserScan & laser,
00369 const geometry_msgs::Point & goal)
00370 {
00371
00372 float module_goal, angle_goal;
00373 fromCartesian2Polar(goal, module_goal, angle_goal);
00374
00375
00376 const unsigned int central_index_range = round(laser.ranges.size()/2);
00377
00378
00379 const unsigned int goal_index_range = round(angle_goal/laser.angle_increment) + central_index_range;
00380
00381
00382 const double cone_aperture = OA_CONE_ANGLE_;
00383 const unsigned int half_index_cone = abs(round(cone_aperture/(laser.angle_increment*2)));
00384
00385
00386 for(unsigned int ii=std::max(goal_index_range-half_index_cone,(unsigned int)0);
00387 ii<std::min(goal_index_range+half_index_cone,(unsigned int)laser.ranges.size());
00388 ii++)
00389 {
00390
00391 if ( laser.ranges[ii] > MIN_LASER_RANGE_ && laser.ranges[ii] <= this->LASER_SAFE_DIST_ )
00392 {
00393 ROS_DEBUG("NoCollisionAlgorithm::isGoalTraversable::FALSE");
00394 return false;
00395 }
00396 }
00397
00398 ROS_DEBUG("NoCollisionAlgorithm::isGoalTraversable::TRUE");
00399 return true;
00400 }