📄 laserbarcode.cc
字号:
*resp_len=sizeof(player_fiducial_geom_t); return ret; }*/ return -1;}////////////////////////////////////////////////////////////////////////////////// Get the laser data/*int LaserBarcode::ReadLaser(){ size_t size; // Get the laser data. size = this->laser_driver->GetData(this->laser_id, (uint8_t*)&this->laser_data, sizeof(this->laser_data), &this->laser_timestamp); assert(size <= sizeof(this->laser_data)); // Do some byte swapping this->laser_data.resolution = ntohs(this->laser_data.resolution); this->laser_data.range_res = ntohs(this->laser_data.range_res); this->laser_data.min_angle = ntohs(this->laser_data.min_angle); this->laser_data.max_angle = ntohs(this->laser_data.max_angle); this->laser_data.range_count = ntohs(this->laser_data.range_count); for (int i = 0; i < this->laser_data.range_count; i++) this->laser_data.ranges[i] = ntohs(this->laser_data.ranges[i]); return 0;}*/////////////////////////////////////////////////////////////////////////////////// Analyze the laser data and return beacon datavoid LaserBarcode::FindBeacons(const player_laser_data_t *laser_data, player_fiducial_data_t *data){ data->fiducials_count = 0; int ai = -1; int bi = -1; double ax, ay; double bx, by; // Expected width of beacon // double min_width = (this->bit_count - 1) * this->bit_width; double max_width = (this->bit_count + 1) * this->bit_width; ax = ay = 0; bx = by = 0; // Find the beacons in this scan for (unsigned int i = 0; i < laser_data->ranges_count; i++) { double range = (laser_data->ranges[i]); double bearing = (laser_data->min_angle + i * laser_data->resolution); int intensity = (laser_data->intensity[i]); double px = range * cos(bearing); double py = range * sin(bearing); if (intensity > 0) { if (ai < 0) { ai = i; ax = px; ay = py; } bi = i; bx = px; by = py; } if (ai < 0) continue; double width = sqrt((px - ax) * (px - ax) + (py - ay) * (py - ay)); if (width < max_width) continue; width = sqrt((bx - ax) * (bx - ax) + (by - ay) * (by - ay)); if (width < min_width) continue; if (width > max_width) { ai = -1; continue; } // Assign an id to the beacon double orient = atan2(by - ay, bx - ax); int id = IdentBeacon(ai, bi, ax, ay, orient, laser_data); // Reset counters so we can find new beacons // ai = -1; bi = -1; // Ignore invalid ids // if (id < 0) continue; // Check for array overflow. if (data->fiducials_count >= ARRAYSIZE(data->fiducials)) continue; double ox = (bx + ax) / 2; double oy = (by + ay) / 2; range = sqrt(ox * ox + oy * oy); bearing = atan2(oy, ox); // Create an entry for this beacon. // Note that we return the surface normal for the beacon orientation. data->fiducials[data->fiducials_count].id = (id > 0 ? id : -1); data->fiducials[data->fiducials_count].pose.px = range * cos(bearing); data->fiducials[data->fiducials_count].pose.py = range * sin(bearing); data->fiducials[data->fiducials_count].pose.pyaw = NORMALIZE(orient + M_PI/2); data->fiducials_count++; }}////////////////////////////////////////////////////////////////////////////////// Analyze the candidate beacon and return its id.// Will return -1 if this is not a beacon.// Will return 0 if this is a beacon, but it cannot be identified.// Will return beacon id otherwise.int LaserBarcode::IdentBeacon(int a, int b, double ox, double oy, double oth, const player_laser_data_t *laser_data){ // Compute pose of laser relative to beacon double lx = -ox * cos(-oth) + oy * sin(-oth); double ly = -ox * sin(-oth) - oy * cos(-oth); double la = -oth; // Initialise our probability distribution. // We determine the probability that each bit is set using Bayes law. double prob[8][2]; for (int bit = 0; bit < ARRAYSIZE(prob); bit++) prob[bit][0] = prob[bit][1] = 0; // Scan through the readings that make up the candidate. for (int i = a; i <= b; i++) { double range = laser_data->ranges[i]; double bearing = laser_data->min_angle + i * laser_data->resolution; int intensity = (int) (laser_data->intensity[i]); double res = laser_data->resolution; // Compute point relative to beacon double py = ly + range * sin(la + bearing); // Discard candidate points are not close to x-axis (ie candidate // is not flat). if (fabs(py) > this->max_depth) return -1; // Compute intercept with beacon //double cx = lx + ly * tan(la + bearing + M_PI/2); double ax = lx + ly * tan(la + bearing - res/2 + M_PI/2); double bx = lx + ly * tan(la + bearing + res/2 + M_PI/2); // Update our probability distribution // Use Bayes law for (int bit = 0; bit < this->bit_count; bit++) { // Use a rectangular distribution double a = (bit + 0.0) * this->bit_width; double b = (bit + 1.0) * this->bit_width; double p = 0; if (ax < a && bx > b) p = 1; else if (ax > a && bx < b) p = 1; else if (ax > b || bx < a) p = 0; else if (ax < a && bx < b) p = 1 - (a - ax) / (bx - ax); else if (ax > a && bx > b) p = 1 - (bx - b) / (bx - ax); else assert(0); //printf("prob : %f %f %f %f %f\n", ax, bx, a, b, p); if (intensity == 0) { assert(bit >= 0 && bit < ARRAYSIZE(prob)); prob[bit][0] += p; prob[bit][1] += 0; } else { assert(bit >= 0 && bit < ARRAYSIZE(prob)); prob[bit][0] += 0; prob[bit][1] += p; } } } // Now assign the id int id = 0; for (int bit = 0; bit < this->bit_count; bit++) { double pn = prob[bit][0] + prob[bit][1]; double p0 = prob[bit][0] / pn; double p1 = prob[bit][1] / pn; if (pn < this->accept_thresh) id = -1; else if (p0 > this->zero_thresh) id |= (0 << bit); else if (p1 > this->one_thresh) id |= (1 << bit); else id = -1; //printf("%d %f %f : %f %f %f\n", bit, prob[bit][0], prob[bit][1], p0, p1, pn); } //printf("\n"); if (id < 0) id = 0; return id;}////////////////////////////////////////////////////////////////////////////////// Write fidicual data void LaserBarcode::WriteFiducial(){ // Write the data with the laser timestamp this->Publish(device_addr, NULL, PLAYER_MSGTYPE_DATA, PLAYER_FIDUCIAL_DATA_SCAN, &this->data, sizeof(this->data)); return;}////////////////////////////////////////////////////////////////////////////////// Process configuration requests/*int LaserBarcode::HandleConfig() { int subtype; size_t len; void *client; char req[PLAYER_MAX_REQREP_SIZE]; while ((len = this->GetConfig(&client, req, sizeof(req),NULL)) > 0) { subtype = ((uint8_t*) req)[0]; switch (subtype) { case PLAYER_FIDUCIAL_GET_GEOM: { HandleGetGeom(client, req, len); break; } default: { if (PutReply(client, PLAYER_MSGTYPE_RESP_NACK,NULL) != 0) PLAYER_ERROR("PutReply() failed"); break; } } } return(0);}////////////////////////////////////////////////////////////////////////////////// Handle geometry requests.void LaserBarcode::HandleGetGeom(void *client, void *request, size_t len){ unsigned short reptype; struct timeval ts; int replen; player_laser_geom_t lgeom; player_fiducial_geom_t fgeom; // Get the geometry from the laser replen = this->laser_driver->Request(this->laser_id, this, request, len, NULL, &reptype, &lgeom, sizeof(lgeom), &ts); if (replen <= 0 || replen != sizeof(lgeom)) { PLAYER_ERROR("unable to get geometry from laser device"); if (PutReply(client, PLAYER_MSGTYPE_RESP_NACK,NULL) != 0) PLAYER_ERROR("PutReply() failed"); } fgeom.pose[0] = lgeom.pose[0]; fgeom.pose[1] = lgeom.pose[1]; fgeom.pose[2] = lgeom.pose[2]; fgeom.size[0] = lgeom.size[0]; fgeom.size[1] = lgeom.size[1]; fgeom.fiducial_size[0] = ntohs((int) (0.05 * 1000)); fgeom.fiducial_size[1] = ntohs((int) (this->bit_count * this->bit_width * 1000)); if (PutReply(client, PLAYER_MSGTYPE_RESP_ACK, &fgeom, sizeof(fgeom), &ts) != 0) PLAYER_ERROR("PutReply() failed"); return;}*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -