b21_driver.cc
Go to the documentation of this file.
00001 /*
00002  *  B21 Driver - By David Lu!! 2/2010
00003  *  Modified from Player code
00004  *
00005  *  Player - One Hell of a Robot Server
00006  *  Copyright (C) 2000
00007  *     Brian Gerkey, Kasper Stoy, Richard Vaughan, & Andrew Howard
00008  *
00009  *
00010  *  This program is free software; you can redistribute it and/or modify
00011  *  it under the terms of the GNU General Public License as published by
00012  *  the Free Software Foundation; either version 2 of the License, or
00013  *  (at your option) any later version.
00014  *
00015  *  This program is distributed in the hope that it will be useful,
00016  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00017  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00018  *  GNU General Public License for more details.
00019  *
00020  *  You should have received a copy of the GNU General Public License
00021  *  along with this program; if not, write to the Free Software
00022  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00023  *
00024  */
00025 
00026 #include <rflex/b21_driver.h>
00027 #include <rflex/b21_config.h>
00028 #include <math.h>
00029 
00030 B21::B21() {
00031     found_distance = false;
00032     bumps = new int*[2];
00033 
00034     for (int index=0;index<2;index++) {
00035         bumps[index] = new int[BUMPERS_PER[index]];
00036         for (int i=0;i<BUMPERS_PER[index];i++) {
00037             bumps[index][i] =0;
00038         }
00039     }
00040 
00041 }
00042 
00043 B21::~B21() {
00044     delete bumps[0];
00045     delete bumps[1];
00046     delete bumps;
00047 }
00048 
00049 float B21::getDistance() {
00050     if (!found_distance && isOdomReady()) {
00051         first_distance = distance;
00052         found_distance = true;
00053     }
00054 
00055     return (distance-first_distance) / (float) ODO_DISTANCE_CONVERSION;
00056 }
00057 
00058 float B21::getBearing() {
00059     return (bearing-HOME_BEARING) / (float) ODO_ANGLE_CONVERSION;
00060 }
00061 
00062 float B21::getTranslationalVelocity() const {
00063     return transVelocity / (float) ODO_DISTANCE_CONVERSION;
00064 }
00065 
00066 float B21::getRotationalVelocity() const {
00067     return rotVelocity / (float) ODO_ANGLE_CONVERSION;
00068 }
00069 
00070 float B21::getVoltage() const {
00071     if (voltage==0.0)
00072         return 0.0;
00073     else
00074         return voltage/100.0 + POWER_OFFSET;
00075 }
00076 
00077 bool B21::isPluggedIn() const {
00078     float v = getVoltage();
00079     if (v>PLUGGED_THRESHOLD)
00080         return true;
00081     else
00082         return false;
00083 }
00084 
00085 int B21::getNumBodySonars() const {
00086     return SONARS_PER_RING[BODY_INDEX];
00087 }
00088 
00089 int B21::getNumBaseSonars() const {
00090     return SONARS_PER_RING[BASE_INDEX];
00091 }
00092 
00093 void B21::getBodySonarReadings(float* readings) const {
00094     getSonarReadings(BODY_INDEX, readings);
00095 }
00096 
00097 void B21::getBaseSonarReadings(float* readings) const {
00098     getSonarReadings(BASE_INDEX, readings);
00099 }
00100 
00101 void B21::getBodySonarPoints(sensor_msgs::PointCloud* cloud) const {
00102     getSonarPoints(BODY_INDEX, cloud);
00103 }
00104 void B21::getBaseSonarPoints(sensor_msgs::PointCloud* cloud) const {
00105     getSonarPoints(BASE_INDEX, cloud);
00106 }
00107 
00108 int B21::getBodyBumps(sensor_msgs::PointCloud* cloud) const {
00109     return getBumps(BODY_INDEX, cloud);
00110 }
00111 
00112 int B21::getBaseBumps(sensor_msgs::PointCloud* cloud) const {
00113     return getBumps(BASE_INDEX, cloud);
00114 }
00115 
00116 void B21::setSonarPower(bool on) {
00117     unsigned long echo, ping, set, val;
00118     if (on) {
00119         echo = SONAR_ECHO_DELAY;
00120         ping = SONAR_PING_DELAY;
00121         set = SONAR_SET_DELAY;
00122         val = 2;
00123     } else {
00124         echo = ping = set = val = 0;
00125     }
00126     configureSonar(echo, ping, set, val);
00127 }
00128 
00129 
00130 void B21::setMovement( float tvel, float rvel,
00131                        float acceleration ) {
00132     setVelocity(tvel * ODO_DISTANCE_CONVERSION,
00133                 rvel * ODO_ANGLE_CONVERSION,
00134                 acceleration * ODO_DISTANCE_CONVERSION);
00135 }
00136 
00137 
00138 void B21::getSonarReadings(const int ringi, float* adjusted_ranges) const {
00139     int i = 0;
00140     for (int x = SONAR_RING_BANK_BOUND[ringi];x<SONAR_RING_BANK_BOUND[ringi+1];x++) {
00141         for (int y=0;y<SONARS_PER_BANK[x];y++) {
00142             int range = sonar_ranges[x*SONAR_MAX_PER_BANK+y];
00143             if (range > SONAR_MAX_RANGE)
00144                 range = SONAR_MAX_RANGE;
00145             float fRange = range / (float) RANGE_CONVERSION;
00146             adjusted_ranges[i] = fRange;
00147             i++;
00148         }
00149     }
00150 }
00151 
00152 void B21::getSonarPoints(const int ringi, sensor_msgs::PointCloud* cloud) const {
00153     int numSonar = SONARS_PER_RING[ringi];
00154     float* readings = new float[numSonar];
00155     getSonarReadings(ringi, readings);
00156     cloud->points.resize(numSonar);
00157     int c = 0;
00158     for (int i = 0; i < numSonar; ++i) {
00159         if (readings[i] < SONAR_MAX_RANGE/ (float) RANGE_CONVERSION) {
00160             double angle =  SONAR_RING_START_ANGLE[ringi] + SONAR_RING_ANGLE_INC[ringi]*i;
00161             angle *= M_PI / 180.0;
00162 
00163             double d = SONAR_RING_DIAMETER[ringi] + readings[i];
00164             cloud->points[c].x = cos(angle)*d;
00165             cloud->points[c].y = sin(angle)*d;
00166             cloud->points[c].z = SONAR_RING_HEIGHT[ringi];
00167             c++;
00168         }
00169     }
00170 }
00171 
00172 int B21::getBumps(const int index, sensor_msgs::PointCloud* cloud) const {
00173     int c = 0;
00174     double wedge = 2 * M_PI / BUMPERS_PER[index];
00175     double d = SONAR_RING_DIAMETER[index]*1.1;
00176     int total = 0;
00177     for (int i=0;i<BUMPERS_PER[index];i++) {
00178         int value = bumps[index][i];
00179         for (int j=0;j<4;j++) {
00180             int mask = 1 << j;
00181             if ((value & mask) > 0) {
00182                 total++;
00183             }
00184         }
00185     }
00186 
00187     cloud->points.resize(total);
00188     if (total==0)
00189         return 0;
00190     for (int i=0;i<BUMPERS_PER[index];i++) {
00191         int value = bumps[index][i];
00192         double angle = wedge * (2.5 - i);
00193         for (int j=0;j<4;j++) {
00194             int mask = 1 << j;
00195             if ((value & mask) > 0) {
00196                 double aoff = BUMPER_ANGLE_OFFSET[j]*wedge/3;
00197                 cloud->points[c].x = cos(angle-aoff)*d;
00198                 cloud->points[c].y = sin(angle-aoff)*d;
00199                 cloud->points[c].z = BUMPER_HEIGHT_OFFSET[index][j];
00200                 c++;
00201             }
00202         }
00203     }
00204     return total;
00205 
00206 }
00207 
00208 void B21::processDioEvent(unsigned char address, unsigned short data) {
00209 
00210     if (address == HEADING_HOME_ADDRESS) {
00211         home_bearing = bearing;
00212         //printf("B21 Home %f \n", home_bearing / (float) ODO_ANGLE_CONVERSION);
00213     }// check if the dio packet came from a bumper packet
00214     else if ((address >= BUMPER_ADDRESS) && (address < (BUMPER_ADDRESS+BUMPER_COUNT))) {
00215         int index =0, rot = address - BUMPER_ADDRESS;
00216         if (rot > BUMPERS_PER[index]) {
00217             rot -= BUMPERS_PER[index];
00218             index++;
00219         }
00220         bumps[index][rot] = data;
00221     } else {
00222         //printf("B21 DIO: address 0x%02x (%d) value 0x%02x (%d)\n", address, address, data, data);
00223     }
00224 }
00225 
00226 


rflex
Author(s): David V. Lu!!, Mikhail Medvedev
autogenerated on Fri Aug 28 2015 12:58:58