⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 laservisualbarcode.cc

📁 机器人仿真软件
💻 CC
📖 第 1 页 / 共 2 页
字号:
  mrr = 0.0;  mbb = 0.0;      // Look for a candidate patch in scan.  for (i = 0; i < data->ranges_count; i++)  {    r = (double) (data->ranges[i]);    b = (double) (data->min_angle + i * data->resolution);    h = (int) (data->intensity[i]);    // If there is a reflection...    if (h > 0)    {      mn += 1;      mr += r;      mb += b;      mrr += r * r;      mbb += b * b;    }    // If there is no reflection and we have a patch...    else if (mn > 0)    {      // Compute the moments of the patch.      mr /= mn;      mb /= mn;      mrr = mrr / mn - mr * mr;      mbb = mbb / mn - mb * mb;      // Test moments to see if they are valid.      valid = 1;      valid &= (mn >= 1.0);      dr = this->barwidth / 2;      db = atan2(this->barwidth / 2, mr);      valid &= (mrr < (dr * dr));      valid &= (mbb < (db * db));            if (valid)      {        // Do a best fit to determine the pose of the reflector.        this->FitLaserFiducial(data, i - (int) mn, i - 1, pose);        // Match this fiducial against the ones we are already tracking.        this->MatchLaserFiducial(time, pose);      }            mn = 0.0;      mr = 0.0;      mb = 0.0;      mrr = 0.0;      mbb = 0.0;    }  }  return;}////////////////////////////////////////////////////////////////////////////////// Find the line of best fit for the given segment of the laser scan.// Fills in the pose and pose of the reflector relative to the laser.void LaserVisualBarcode::FitLaserFiducial(player_laser_data_t *data,                                          int first, int last, double pose[3]){  int i;  double r, b;  double mn, mr, mb;  mn = 0.0;  mr = 1e6;  mb = 0.0;  for (i = first; i <= last; i++)  {    r = (double) (data->ranges[i]) / 1000;    b = (double) (data->min_angle + i * data->resolution) / 100.0 * M_PI / 180;    if (r < mr)      mr = r;    mn += 1.0;    mb += b;  }  mr += this->barwidth / 2;  mb /= mn;  pose[0] = mr * cos(mb);  pose[1] = mr * sin(mb);  pose[2] = mb;  return;}////////////////////////////////////////////////////////////////////////////////// Match a new laser fiducial against the ones we are already// tracking.  The pose is relative to the laser.void LaserVisualBarcode::MatchLaserFiducial(double time, double pose[3]){  int i;  double dx, dy, dr;  double mindr;  fiducial_t *fiducial;  fiducial_t *minfiducial;    // Observations must be at least this close to the existing  // fiducial.  mindr = this->max_dist;  minfiducial = NULL;  // Find the existing fiducial which is closest to the new  // observation.  for (i = 0; i < this->fiducial_count; i++)  {    fiducial = this->fiducials + i;    dx = pose[0] - fiducial->pose[0];    dy = pose[1] - fiducial->pose[1];    dr = sqrt(dx * dx + dy * dy);    if (dr < mindr)    {      mindr = dr;      minfiducial = fiducial;    }  }  // If we didnt find a matching fiducial, add a new one.  if (minfiducial == NULL)  {    if (this->fiducial_count < ARRAYSIZE(this->fiducials))    {      minfiducial = this->fiducials + this->fiducial_count++;      minfiducial->id = -1;      minfiducial->pose[0] = pose[0];      minfiducial->pose[1] = pose[1];      minfiducial->pose[2] = pose[2];      minfiducial->laser_time = time;      minfiducial->ptz_select_time = -1;      minfiducial->ptz_lockon_time = -1;      minfiducial->id_time = -1;    }  }  // Otherwise, update the existing fiducial.  else  {    minfiducial->pose[0] = pose[0];    minfiducial->pose[1] = pose[1];    minfiducial->pose[2] = pose[2];    minfiducial->laser_time = time;  }    return;}////////////////////////////////////////////////////////////////////////////////// Retire fiducials we havent seen for a while.void LaserVisualBarcode::RetireLaserFiducials(double time, player_laser_data_t *data){  int i;  fiducial_t *fiducial;    // Remove any old fiducials.  for (i = 0; i < this->fiducial_count; i++)  {    fiducial = this->fiducials + i;    if (time - fiducial->laser_time > this->retire_time)    {      if (this->ptz_fiducial == fiducial)        this->ptz_fiducial = NULL;      memmove(fiducial, fiducial + 1, (this->fiducial_count - i - 1) * sizeof(fiducial_t));      this->fiducial_count--;      i--;    }  }  return;}////////////////////////////////////////////////////////////////////////////////// Update the PTZ to point at one of the laser reflectors.int LaserVisualBarcode::UpdatePtz(player_ptz_data_t * data, double timestamp){  this->ptz_time = timestamp;    // Pick a fiducial to look at.  this->SelectPtzTarget(timestamp, data);  // Point the fiducial  this->ServoPtz(timestamp, data);  return 1;}////////////////////////////////////////////////////////////////////////////////// Select a target fiducial for the PTZ to inspect.// This algorithm picks the one that we havent looked at for a long time.void LaserVisualBarcode::SelectPtzTarget(double time, player_ptz_data_t *data){  int i;  double t, maxt;  fiducial_t *fiducial;  // Consider the currently selected target for a while to  // give the blobfinder time to identify it.  if (this->ptz_fiducial != NULL)  {    if (time - this->ptz_fiducial->ptz_select_time < this->max_ptz_attention)      return;  }  // Find one we havent looked at for while.  this->ptz_fiducial = NULL;  maxt = -1;    for (i = 0; i < this->fiducial_count; i++)  {    fiducial = this->fiducials + i;    t = time - fiducial->ptz_select_time;    if (t > maxt)    {      maxt = t;      this->ptz_fiducial = fiducial;    }  }  if (this->ptz_fiducial)  {    this->ptz_fiducial->ptz_select_time = time;    this->ptz_fiducial->ptz_lockon_time = -1;  }    return;}////////////////////////////////////////////////////////////////////////////////// Servo the PTZ to a target fiducial.void LaserVisualBarcode::ServoPtz(double time, player_ptz_data_t *data){  double dx, dy, r, pan, tilt, zoom;  fiducial_t *fiducial;  player_ptz_cmd_t cmd;  double maxtilt;  double deadpan, deadzoom;  // Max tilt value.  maxtilt = 5 * M_PI / 180;  // Deadband values.  deadpan = 2;  deadzoom = 2;    fiducial = this->ptz_fiducial;  if (fiducial == NULL)  {    r = 0;    pan = 0;    tilt = 0;    zoom = M_PI;  }  else  {    // Compute range and bearing of fiducial relative to camera.    // TODO: account for camera geometry.    dx = fiducial->pose[0];    dy = fiducial->pose[1];    r = sqrt(dx * dx + dy * dy);    pan = atan2(dy, dx);    zoom = 8 * atan2(this->barwidth / 2, r);    // See if we have locked on yet.    if (fiducial->ptz_lockon_time < 0)      if (fabs(pan * 180 / M_PI - data->pan) < deadpan &&          fabs(zoom * 180 / M_PI - data->zoom) < deadzoom)        fiducial->ptz_lockon_time = time;    // If we havent locked on yet...    if (fiducial->ptz_lockon_time < 0)      tilt = 0;    else      tilt = maxtilt * sin((time - fiducial->ptz_lockon_time) /                           this->max_ptz_attention * 2 * M_PI);  }    // Compose the command packet to send to the PTZ device.  cmd.pan = pan;  cmd.tilt = tilt;  cmd.zoom = zoom;    this->ptz->PutMsg(InQueue, PLAYER_MSGTYPE_CMD, PLAYER_PTZ_CMD_STATE, &cmd, sizeof(cmd), NULL);  // Compute the dimensions of the image at the range of the target fiducial.  this->zoomwidth = 2 * r * tan(data->zoom/2);  this->zoomheight = 3.0 / 4.0 * this->zoomwidth;  return;}////////////////////////////////////////////////////////////////////////////////// Process any new blobfinder data.int LaserVisualBarcode::UpdateBlobfinder(player_blobfinder_data_t * data, double timestamp){  int id;  // Extract valid blobs.  this->FindBlobs(timestamp, data);  // Search for fiducials.  id = this->FindVisualFiducials(timestamp, data, 0, NULL);  // Assign id to fiducial we are currently looking at.  if (id >= 0 && this->ptz_fiducial)  {    if (this->ptz_fiducial->ptz_lockon_time >= 0)    {      this->ptz_fiducial->id = id;      this->ptz_fiducial->id_time = timestamp;    }  }    return 1;}////////////////////////////////////////////////////////////////////////////////// Find blobs with valid properties.void LaserVisualBarcode::FindBlobs(double time, player_blobfinder_data_t *data){  unsigned int i;  blob_t *nblob;  player_blobfinder_blob_t *blob;  unsigned int width, height;  unsigned int minx, maxx, miny, maxy;  unsigned int minwidth, maxwidth, minheight, maxheight;  int minarea, maxarea;  double tol;  // Allowable tolerance (fractional error).  tol = 0.5;  // Compute expect width and height at the current range and zoom.  width = (int) (this->barwidth / this->zoomwidth * data->width);  height = (int) (this->barheight / this->zoomheight * data->height);        // Set limits  minx = (int) ((1 - tol) * data->width / 2);  maxx = (int) ((1 + tol) * data->width / 2);  miny = 0;  maxy = data->height;  minwidth = (int) ((1 - tol) * width);  maxwidth = (int) ((1 + tol) * width);  minheight = (int) ((1 - tol) * height);  maxheight = (int) ((1 + tol) * height);  minarea = 50;  maxarea = maxwidth * maxheight;  /*    printf("zoom %.3f %.3f\n", this->zoomwidth, this->zoomheight);    printf("image %d %d\n", data->width, data->height);    printf("w, h %d %d\n", width, height);  */    this->blob_count = 0;  for (i = 0; i < data->blobs_count; i++)  {    blob = data->blobs + i;    // Test the blob properties.    if (blob->x < minx || blob->x > maxx)      continue;    if (blob->y < miny || blob->y > maxy)      continue;    if ((blob->right - blob->left) < minwidth || (blob->right - blob->left) > maxwidth)      continue;    if ((blob->bottom - blob->top) < minheight || (blob->bottom - blob->top) > maxheight)      continue;    if ((int) blob->area < minarea || (int) blob->area > maxarea)      continue;    /*      printf("%d %d : %d %d : %d\n", blob->x, blob->y,      blob->right - blob->left, blob->bottom - blob->top, blob->area);    */    // Add to valid blob list.    if (this->blob_count < ARRAYSIZE(this->blobs))    {      nblob = this->blobs + this->blob_count++;      nblob->ch = blob->id;      nblob->x = blob->x;      nblob->y = blob->y;    }  }    return;}////////////////////////////////////////////////////////////////////////////////// Do a recursive depth-first search of the blob list for fiducals.int LaserVisualBarcode::FindVisualFiducials(double time, player_blobfinder_data_t *data,                                            int depth, blob_t *prevblob){  int i, id;  blob_t *blob;  double dx, dy;  double tol;  double width, height;  // Allowable tolerance (fractional error).  tol = 0.5;  // Compute expected width and height at the current range and zoom.  width = (int) (this->barwidth / this->zoomwidth * data->width);  height = (int) (this->barheight / this->zoomheight * data->height);  for (i = 0; i < this->blob_count; i++)  {    blob = this->blobs + i;    if (depth > 0)    {      dx = blob->x - prevblob->x;      dy = blob->y - prevblob->y;      if (fabs(dx) > (1 - tol) * width)        continue;      if (dy < (1 - tol) * height)        continue;      if (dy > (1 + tol) * height)        continue;    }    if (depth == this->barcount - 1)    {      id = blob->ch;      return id;    }        id = this->FindVisualFiducials(time, data, depth + 1, blob);    if (id >= 0)    {      id = 10 * id + blob->ch;      return id;    }  }  return -1;}////////////////////////////////////////////////////////////////////////////////// Update the device data (the data going back to the client).void LaserVisualBarcode::UpdateData(){  int i;  double r, b, o;  double timestamp;  fiducial_t *fiducial;  player_fiducial_data_t data;  data.fiducials_count = 0;  for (i = 0; i < this->fiducial_count; i++)  {    fiducial = this->fiducials + i;    // Only report fiducials that where seen in the most recent laser    // scan.    if (fiducial->laser_time != this->laser_time)      continue;        r = sqrt(fiducial->pose[0] * fiducial->pose[0] +             fiducial->pose[1] * fiducial->pose[1]);    b = atan2(fiducial->pose[1], fiducial->pose[0]);    o = fiducial->pose[2];    data.fiducials[data.fiducials_count].id = fiducial->id;    data.fiducials[data.fiducials_count].pose.px = r * cos(b);    data.fiducials[data.fiducials_count].pose.py = r * sin(b);    data.fiducials[data.fiducials_count].pose.pyaw = o;    data.fiducials_count++;  }    // Compute the data timestamp (from laser).  timestamp = this->laser_time;    // Copy data to server.  Publish(device_addr, NULL, PLAYER_MSGTYPE_DATA, PLAYER_FIDUCIAL_DATA_SCAN, (void*) &data, sizeof(data), &timestamp);}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -