dock_drive_states.cpp
Go to the documentation of this file.
00001 /*
00002  * copyright (c) 2013, Yujin Robot.
00003  * all rights reserved.
00004  *
00005  * redistribution and use in source and binary forms, with or without
00006  * modification, are permitted provided that the following conditions are met:
00007  *
00008  *     * redistributions of source code must retain the above copyright
00009  *       notice, this list of conditions and the following disclaimer.
00010  *     * redistributions in binary form must reproduce the above copyright
00011  *       notice, this list of conditions and the following disclaimer in the
00012  *       documentation and/or other materials provided with the distribution.
00013  *     * neither the name of yujin robot nor the names of its
00014  *       contributors may be used to endorse or promote products derived from
00015  *       this software without specific prior written permission.
00016  *
00017  * this software is provided by the copyright holders and contributors "as is"
00018  * and any express or implied warranties, including, but not limited to, the
00019  * implied warranties of merchantability and fitness for a particular purpose
00020  * are disclaimed. in no event shall the copyright owner or contributors be
00021  * liable for any direct, indirect, incidental, special, exemplary, or
00022  * consequential damages (including, but not limited to, procurement of
00023  * substitute goods or services; loss of use, data, or profits; or business
00024  * interruption) however caused and on any theory of liability, whether in
00025  * contract, strict liability, or tort (including negligence or otherwise)
00026  * arising in any way out of the use of this software, even if advised of the
00027  * possibility of such damage.
00028  */
00034 /*****************************************************************************
00035 ** includes
00036 *****************************************************************************/
00037 
00038 #include "kobuki_dock_drive/dock_drive.hpp"
00039 
00040 /*****************************************************************************
00041 ** Namespaces
00042 *****************************************************************************/
00043 
00044 namespace kobuki {
00045   /*********************************************************
00046    * Shared variables among states
00047    * @ dock_detector : records + or - when middle IR sensor detects docking signal
00048    * @ rotated : records how much the robot has rotated in scan state
00049    * @ bump_remainder : from processBumpChargerEvent.
00050    *********************************************************/
00051 
00052 
00053   /*******************************************************
00054    * Idle
00055    *  @breif Entry of auto docking state machine
00056    *
00057    *  Shared variable
00058    *  @dock_detecotr - indicates where the dock is located. Positive means dock is on left side of robot
00059    *  @rotated       - indicates how much the robot has rotated while scan
00060    *******************************************************/
00061   void DockDrive::idle(RobotDockingState::State& nstate,double& nvx, double& nwz) {
00062     dock_detector = 0;
00063     rotated = 0.0;
00064     nstate = RobotDockingState::SCAN;
00065     nvx = 0;
00066     nwz = 0.66;
00067   }
00068 
00069   /********************************************************
00070    * Scan
00071    *  @breif While it rotates ccw, determines the dock location with only middle sensor.
00072    *         If its middle sensor detects center ir, the robot is aligned with docking station
00073    *
00074    *  Shared variable
00075    *  @dock_detecotr - indicates where the dock is located. Positive means dock is on left side of robot
00076    *  @rotated       - indicates how much the robot has rotated while scan
00077    ********************************************************/
00078   void DockDrive::scan(RobotDockingState::State& nstate,double& nvx, double& nwz, const std::vector<unsigned char>& signal_filt, const ecl::LegacyPose2D<double>& pose_update, std::string& debug_str) {
00079     unsigned char right = signal_filt[0];
00080     unsigned char mid   = signal_filt[1];
00081     unsigned char left  = signal_filt[2];
00082 
00083     RobotDockingState::State next_state;
00084     double next_vx;
00085     double next_wz;
00086 
00087     rotated += pose_update.heading() / (2.0 * M_PI);
00088     std::ostringstream oss;
00089     oss << "rotated: " << std::fixed << std::setprecision(2) << std::setw(4) << rotated;
00090     debug_str = oss.str();
00091 
00092 
00093 
00094     if((mid & DockStationIRState::FAR_CENTER) || (mid & DockStationIRState::NEAR_CENTER))
00095     {
00096       next_state = RobotDockingState::ALIGNED;
00097       next_vx = 0.05;
00098       next_wz = 0.0;
00099     }
00100     // robot is located left side of dock
00101     else if(mid & (DockStationIRState::FAR_LEFT + DockStationIRState::NEAR_LEFT))
00102     {
00103       dock_detector--;
00104       next_state = RobotDockingState::SCAN;
00105       next_vx = 0.0;
00106       next_wz = 0.66;
00107     }
00108     // robot is located right side of dock
00109     else if(mid & (DockStationIRState::FAR_RIGHT + DockStationIRState::NEAR_RIGHT))
00110     {
00111       dock_detector++;
00112       next_state = RobotDockingState::SCAN;
00113       next_vx = 0.0;
00114       next_wz = 0.66;
00115     }
00116     // robot is located in front of robot
00117     else if(mid) { // if mid sensor sees something, rotate slowly
00118       next_state = RobotDockingState::SCAN;
00119       next_vx = 0.0;
00120       next_wz = 0.10;
00121     }
00122     else if(std::abs(rotated) > 1.0)
00123     {
00124       next_state = RobotDockingState::FIND_STREAM;
00125       next_vx = 0;
00126       next_wz = 0;
00127     }
00128     else { // if mid sensor does not see anything, rotate fast
00129       next_state = RobotDockingState::SCAN;
00130       next_vx = 0.0;
00131       next_wz = 0.66;
00132     }
00133 
00134     nstate = next_state;
00135     nvx = next_vx;
00136     nwz = next_wz;
00137   }
00138 
00139   /********************************************************
00140    * Find stream
00141    *  @breif based on dock_detector variable, it determines the dock's location and rotates toward the center line of dock
00142    *
00143    *  Shared variable
00144    *  @dock_detector - to determine dock's location
00145    *
00146    ********************************************************/
00147   void DockDrive::find_stream(RobotDockingState::State& nstate,double& nvx, double& nwz, const std::vector<unsigned char>& signal_filt) {
00148     unsigned char right = signal_filt[0];
00149     unsigned char mid   = signal_filt[1];
00150     unsigned char left  = signal_filt[2];
00151     RobotDockingState::State next_state;
00152     double next_vx;
00153     double next_wz;
00154 
00155     if(dock_detector > 0) // robot is located in right side of dock
00156     {
00157       // turn right, CW until get right signal from left sensor
00158       if(left & (DockStationIRState::FAR_RIGHT + DockStationIRState::NEAR_RIGHT)) {
00159         next_state = RobotDockingState::GET_STREAM;
00160         next_vx = 0.5;
00161         next_wz = 0.0;
00162       }
00163       else {
00164         next_state = RobotDockingState::FIND_STREAM;
00165         next_vx = 0.0;
00166         next_wz = -0.33;
00167       }
00168     }
00169     else if(dock_detector < 0 ) // robot is located in left side of dock
00170     {
00171       // turn left, CCW until get left signal from right sensor
00172       if(right & (DockStationIRState::FAR_LEFT + DockStationIRState::NEAR_LEFT))
00173       {
00174         next_state = RobotDockingState::GET_STREAM;
00175         next_vx = 0.5;
00176         next_wz = 0.0;
00177       }
00178       else {
00179         next_state = RobotDockingState::FIND_STREAM;
00180         next_vx = 0.0;
00181         next_wz = 0.33;
00182       }
00183     }
00184 
00185     nstate = next_state;
00186     nvx = next_vx;
00187     nwz = next_wz;
00188   }
00189 
00190  /********************************************************
00191   * Get stream
00192   *   @brief In this state, robot is heading the center line of dock. When it passes the center, it rotates toward the dock
00193   *
00194   *   Shared Variable
00195   *   @ dock_detector - reset
00196   *   @ rotated       - reset
00197   ********************************************************/
00198   void DockDrive::get_stream(RobotDockingState::State& nstate,double& nvx, double& nwz, const std::vector<unsigned char>& signal_filt)
00199   {
00200     unsigned char right = signal_filt[0];
00201     unsigned char mid   = signal_filt[1];
00202     unsigned char left  = signal_filt[2];
00203     RobotDockingState::State next_state;
00204     double next_vx;
00205     double next_wz;
00206 
00207     if(dock_detector > 0) { // robot is located in right side of dock
00208       if (left & (DockStationIRState::FAR_LEFT + DockStationIRState::NEAR_LEFT)) {
00209         dock_detector = 0;
00210         rotated = 0;
00211         next_state = RobotDockingState::SCAN;
00212         next_vx = 0;
00213         next_wz = 0.1;
00214       }
00215       else {
00216         next_state = RobotDockingState::GET_STREAM;
00217         next_vx = 0.05;
00218         next_wz = 0.0;
00219       }
00220     }
00221     else if(dock_detector < 0) { // robot is located left side of dock
00222       if(right & (DockStationIRState::FAR_RIGHT + DockStationIRState::NEAR_RIGHT)) {
00223         dock_detector = 0;
00224         rotated = 0;
00225         next_state = RobotDockingState::SCAN;
00226         next_vx = 0;
00227         next_wz = 0.1;
00228       }
00229       else {
00230         next_state = RobotDockingState::GET_STREAM;
00231         next_vx = 0.05;
00232         next_wz = 0.0;
00233       }
00234     }
00235 
00236     nstate = next_state;
00237     nvx = next_vx;
00238     nwz = next_wz;
00239   }
00240 
00241 
00242  /********************************************************
00243   * Aligned
00244   *   @breif Robot sees center IR with middle sensor. It is heading dock. It approaches to the dock only using mid sensor
00245   *
00246   *   Shared Variable
00247   *   @ dock_detector - reset
00248   *   @ rotated       - reset
00249   ********************************************************/
00250   void DockDrive::aligned(RobotDockingState::State& nstate,double& nvx, double& nwz, const std::vector<unsigned char>& signal_filt, std::string& debug_str)
00251   {
00252     unsigned char right = signal_filt[0];
00253     unsigned char mid   = signal_filt[1];
00254     unsigned char left  = signal_filt[2];
00255     RobotDockingState::State next_state = nstate;
00256     double next_vx = nvx;
00257     double next_wz = nwz;
00258 
00259     if(mid)
00260     {
00261       if(((mid & DockStationIRState::NEAR) == DockStationIRState::NEAR_CENTER) || ((mid & DockStationIRState::NEAR) == DockStationIRState::NEAR))
00262       {
00263         debug_str = "AlignedNearCenter";
00264         next_state = RobotDockingState::ALIGNED_NEAR;
00265         next_vx = 0.05;
00266         next_wz = 0.0;
00267       }
00268       else if(mid & DockStationIRState::NEAR_LEFT) {
00269         debug_str = "AlignedNearLeft";
00270         next_state = RobotDockingState::ALIGNED_NEAR;
00271         next_vx = 0.05;
00272         next_wz = 0.1;
00273       }
00274       else if(mid & DockStationIRState::NEAR_RIGHT) {
00275         debug_str = "AlignedNearRight";
00276         next_state = RobotDockingState::ALIGNED_NEAR;
00277         next_vx = 0.05;
00278         next_wz = -0.1;
00279       }
00280       else if(((mid & DockStationIRState::FAR) == DockStationIRState::FAR_CENTER) || ((mid & DockStationIRState::FAR) == DockStationIRState::FAR)) {
00281         debug_str = "AlignedFarCenter";
00282         next_state = RobotDockingState::ALIGNED_FAR;
00283         next_vx = 0.1;
00284         next_wz = 0.0;
00285       }
00286       else if(mid & DockStationIRState::FAR_LEFT) {
00287         debug_str = "AlignedFarLeft";
00288         next_state = RobotDockingState::ALIGNED_FAR;
00289         next_vx = 0.1;
00290         next_wz = 0.3;
00291       }
00292       else if(mid & DockStationIRState::FAR_RIGHT) {
00293         debug_str = "AlignedFarRight";
00294         next_state = RobotDockingState::ALIGNED_FAR;
00295         next_vx = 0.1;
00296         next_wz = -0.3;
00297       }
00298       else {
00299         dock_detector = 0;
00300         rotated = 0.0;
00301         next_state = RobotDockingState::SCAN;
00302         next_vx = 0.0;
00303         next_wz = 0.66;
00304       }
00305     }
00306     else {
00307         next_state = RobotDockingState::SCAN;
00308         next_vx = 0.0;
00309         next_wz = 0.66;
00310     }
00311 
00312     nstate = next_state;
00313     nvx = next_vx;
00314     nwz = next_wz;
00315   }
00316 
00317 
00318  /********************************************************
00319   * Bumped
00320   *  @breif Robot has bumped somewhere. Go backward for 10 iteration
00321   *
00322   ********************************************************/
00323   void DockDrive::bumped(RobotDockingState::State& nstate,double& nvx, double& nwz, int& bump_count)
00324   {
00325     if(bump_count < 10)
00326     {
00327       nvx = -0.05;
00328       nwz = 0.0;
00329       bump_count++;
00330     }
00331     else {
00332       nstate = RobotDockingState::SCAN;
00333       nvx = 0.0;
00334       nwz = 0.0;
00335       bump_count = 0;
00336     }
00337 
00338   }
00339 }


kobuki_dock_drive
Author(s): Younghun Ju
autogenerated on Thu Jun 6 2019 20:24:33