Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
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
00213 }
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
00223 }
00224 }
00225
00226