Wiselib
wiselib.testing/external_interface/pc/roomba_motion.h
Go to the documentation of this file.
00001 // vim: set noexpandtab ts=4 sw=4:
00002 
00003 #ifndef ROOMBA_MOTION_H
00004 #define ROOMBA_MOTION_H
00005 
00006 #include "external_interface/pc/pose.h"
00007 
00008 #include <iostream>
00009 
00010 namespace wiselib {
00011 
00012 template<typename Roomba_P, typename Math_P>
00013 class RoombaMotion {
00014    public:
00015       typedef Roomba_P Roomba;
00016       typedef Math_P Math;
00017       
00018       typedef typename Roomba::distance_t distance_t;
00019       typedef typename Roomba::angle_t angle_t;
00020       typedef Pose<angle_t, distance_t> pose_t;
00021       typedef typename Roomba::velocity_t velocity_t;
00022       typedef typename Roomba::angular_velocity_t angular_velocity_t;
00023       
00024       typedef RoombaMotion<Roomba_P, Math_P> self_t;
00025       
00026       enum { DEFAULT_VELOCITY = 50, MAX_VELOCITY = 100};
00027       enum { DEFAULT_ANGULAR_VELOCITY = 20, MAX_ANGULAR_VELOCITY = 100};
00028       enum State {
00029          STATE_STOPPED, STATE_MOVING
00030       };
00031       
00032       void init(Roomba& roomba);
00033       void init();
00034       void destruct();
00035       
00037       void move(velocity_t v = DEFAULT_VELOCITY) {
00038          roomba_->move(v);
00039       }
00040       
00042       void move_distance(distance_t d) {
00043          accum_distance_ = 0;
00044          move();
00045          while(accum_distance_ < d) ;
00046          stop();
00047       }
00048       
00050       void move_to_wall() {
00051          touched_wall_ = false;
00052          move();
00053          while(!touched_wall_) ;
00054          stop();
00055       }
00056       
00058       void turn(angular_velocity_t v = DEFAULT_ANGULAR_VELOCITY) {
00059          roomba_->turn(v);
00060       }
00061       
00063       void turn_about(angle_t a) {
00064          angle_t old = a;
00065          accum_angle_ = 0;
00066          
00067          if(a < 0) {
00068             turn(-DEFAULT_ANGULAR_VELOCITY);
00069             while(accum_angle_ > a) {
00070                if(accum_angle_ != old) {
00071                   old = accum_angle_;
00072                }
00073             }
00074          }
00075          else {
00076             turn();
00077             while(accum_angle_ < a) {
00078                if(accum_angle_ != old) {
00079                   old = accum_angle_;
00080                }
00081             }
00082          }
00083          
00084          std::cout << "stopping!\n";
00085          
00086          stop();
00087       }
00088       
00091       void turn_to(angle_t a) {
00092          flush_sensor_data();
00093          turn_about(a - pose_.angle);
00094       }
00095       
00097       State state();
00098       
00100       void stop() { roomba_->stop(); }
00101    
00103       distance_t distance() { return roomba_->distance(); }
00104 
00105       //void drive_arc(); // ?
00106       
00108       pose_t pose() { return pose_; }
00109       
00110    private:
00111       
00112       static angle_t make_positive(angle_t a) {
00113          while(a < 0) {
00114             a += 2.0 * Math::PI;
00115          }
00116          return a;
00117       }
00118       
00119       void flush_sensor_data() {
00120          flush_ = false;
00121          while(!flush_) ;
00122       }
00123       
00124       void on_new_sensor_data() {
00125          touched_wall_ |= roomba_->wall();
00126          accum_distance_ += roomba_->distance();
00127          accum_angle_ += roomba_->angle();
00128          pose_.angle += roomba_->angle();
00129          
00130          pose_.position.x = roomba_->distance() * Math::sin(Math::radians_to_degrees(roomba_->angle()));
00131          pose_.position.y = roomba_->distance() * Math::cos(Math::radians_to_degrees(roomba_->angle()));
00132          flush_ = true;
00133       }
00134       
00135       Roomba* roomba_;
00136       pose_t pose_;
00137       distance_t accum_distance_;
00138       angle_t accum_angle_;
00139       bool touched_wall_;
00140       bool flush_;
00141 };
00142 
00143 template<typename Roomba_P, typename Math_P>
00144 void RoombaMotion<Roomba_P, Math_P>::init(
00145       RoombaMotion<Roomba_P, Math_P>::Roomba& roomba
00146       ) {
00147    roomba_ = &roomba;
00148    init();
00149 }
00150 
00151 template<typename Roomba_P, typename Math_P>
00152 void RoombaMotion<Roomba_P, Math_P>::init() {
00153    roomba_->template reg_new_data_callback<self_t, &self_t::on_new_sensor_data>(this);
00154 }
00155 
00156 template<typename Roomba_P, typename Math_P>
00157 void RoombaMotion<Roomba_P, Math_P>::destruct() {
00158    roomba_->unreg_new_data_callback();
00159 }
00160 
00161 } // namespace wiselib
00162 
00163 #endif // ROOMBA_MOTION_H
00164 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines