Wiselib
|
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