示例#1
0
void
hokuyo::Laser::queryVersionInformation()
{
  if (!portOpen())
    HOKUYO_EXCEPT(hokuyo::Exception, "Port not open.");

  if (sendCmd("VV",1000) != 0)
    HOKUYO_EXCEPT(hokuyo::Exception, "Error requesting version information");
  
  char buf[100];
  vendor_name_ = laserReadlineAfter(buf, 100, "VEND:");
  vendor_name_ = vendor_name_.substr(0,vendor_name_.length() - 3);
  
  product_name_ = laserReadlineAfter(buf, 100, "PROD:");
  product_name_ = product_name_.substr(0,product_name_.length() - 3);
  
  firmware_version_ = laserReadlineAfter(buf, 100, "FIRM:");
  firmware_version_ = firmware_version_.substr(0,firmware_version_.length() - 3);

  protocol_version_ = laserReadlineAfter(buf, 100, "PROT:");
  protocol_version_ = protocol_version_.substr(0,protocol_version_.length() - 3);
  
  // This crazy naming scheme is for backward compatibility. Initially
  // the serial number always started with an H. Then it got changed to a
  // zero. For a while the driver was removing the leading zero in the
  // serial number. This is fine as long as it is indeed a zero in front.
  // The current behavior is backward compatible but will accomodate full
  // length serial numbers.
  serial_number_ = laserReadlineAfter(buf, 100, "SERI:");
  serial_number_ = serial_number_.substr(0,serial_number_.length() - 3);
  if (serial_number_[0] == '0')
    serial_number_[0] = 'H';
  else if (serial_number_[0] != 'H')
    serial_number_ = 'H' + serial_number_;
}
示例#2
0
int
hokuyo::Laser::requestScans(bool intensity, double min_ang, double max_ang, int cluster, int skip, int count, int timeout)
{
  if (!portOpen())
    HOKUYO_EXCEPT(hokuyo::Exception, "Port not open.");

  int status;

  if (cluster == 0)
    cluster = 1;
  
  int min_i = (int)(afrt_ + min_ang*ares_/(2.0*M_PI));
  int max_i = (int)(afrt_ + max_ang*ares_/(2.0*M_PI));
  
  char cmdbuf[MAX_CMD_LEN];
  
  char intensity_char = 'D';
  if (intensity)
    intensity_char = 'E';
  
  sprintf(cmdbuf,"M%c%.4d%.4d%.2d%.1d%.2d", intensity_char, min_i, max_i, cluster, skip, count);
  
  status = sendCmd(cmdbuf, timeout);
  
  return status;
}
示例#3
0
long long
hokuyo::Laser::calcLatency(bool intensity, double min_ang, double max_ang, int clustering, int skip, int num, int timeout)
{
    offset_ = 0;
    if (!portOpen())
        HOKUYO_EXCEPT(hokuyo::Exception, "Port not open.");

    if (num <= 0)
        num = 10;

    int ckreps = 1;
    int scanreps = 1;
    long long int start = getHokuyoClockOffset(ckreps, timeout);
    long long int pre = 0;
    std::vector<long long int> samples(num);
    for (int i = 0; i < num; i++)
    {
        long long int scan = getHokuyoScanStampToSystemStampOffset(intensity, min_ang, max_ang, clustering, skip, scanreps, timeout) - start;
        long long int post = getHokuyoClockOffset(ckreps, timeout) - start;
        samples[i] = scan - (post+pre)/2;
        //printf("%lli %lli %lli %lli %lli\n", samples[i], post, pre, scan, pre - post);
        //fflush(stdout);
        pre = post;
    }

    offset_ = median(samples);
    //printf("%lli\n", median(samples));
    return offset_;
}
示例#4
0
void
hokuyo::Laser::querySensorConfig()
{
  if (!portOpen())
    HOKUYO_EXCEPT(hokuyo::Exception, "Port not open.");

  if (sendCmd("PP",1000) != 0)
    HOKUYO_EXCEPT(hokuyo::Exception, "Error requesting configuration information");

  char buf[100];
  char* ind;
    
  ind = laserReadlineAfter(buf,100,"DMIN:",-1);
  sscanf(ind, "%d", &dmin_);
    
  ind = laserReadlineAfter(buf,100,"DMAX:",-1);
  sscanf(ind, "%d", &dmax_);
    
  ind = laserReadlineAfter(buf,100,"ARES:",-1);
  sscanf(ind, "%d", &ares_);
    
  ind = laserReadlineAfter(buf,100,"AMIN:",-1);
  sscanf(ind, "%d", &amin_);
    
  ind = laserReadlineAfter(buf,100,"AMAX:",-1);
  sscanf(ind, "%d", &amax_);
    
  ind = laserReadlineAfter(buf,100,"AFRT:",-1);
  sscanf(ind, "%d", &afrt_);
    
  ind = laserReadlineAfter(buf,100,"SCAN:",-1);
  sscanf(ind, "%d", &rate_);
    
  return;
}
示例#5
0
int
hokuyo::Laser::sendCmd(const char* cmd, int timeout)
{
if (!portOpen())
    HOKUYO_EXCEPT(hokuyo::Exception, "Port not open.");

  char buf[100]; 
  //printf("sendreq: %s\n", cmd);
  laserWrite(cmd);
  laserWrite("\n");;
  laserReadlineAfter(buf, 100, cmd, timeout);
  laserReadline(buf,100,timeout);
  //printf("chksum: %s",buf);
  if (!checkSum(buf,4))
  {
    //printf("chksum error\n");
    HOKUYO_EXCEPT(hokuyo::CorruptedDataException, "Checksum failed on status code.");
  }
  buf[2] = 0;
  //printf("sendreq_end: %s\n", cmd);

  if (buf[0] - '0' >= 0 && buf[0] - '0' <= 9 && buf[1] - '0' >= 0 && buf[1] - '0' <= 9)
    return (buf[0] - '0')*10 + (buf[1] - '0');
  else
    HOKUYO_EXCEPT(hokuyo::Exception, "Hokuyo error code returned. Cmd: %s --  Error: %s", cmd, buf);
}
示例#6
0
void
hokuyo::Laser::close ()
{
  int retval = 0;

  if (portOpen()) {
    //Try to be a good citizen and completely shut down the laser before we shutdown communication
    try
    {
      reset();
    }
    catch (hokuyo::Exception& e) {
      //Exceptions here can be safely ignored since we are closing the port anyways
    }
#if HOKUYO_INTERFACE_ETHERNET
    tcpclient_close(&tcpclient);
#else
    retval = ::close(laser_fd_); // Automatically releases the lock.
#endif

  }

  laser_fd_ = -1;

  if (retval != 0)
    HOKUYO_EXCEPT(hokuyo::Exception, "Failed to close port properly -- error = %d: %s\n", errno, strerror(errno));
}
示例#7
0
bool
hokuyo::Laser::isIntensitySupported()
{
  hokuyo::LaserScan  scan;
  
  if (!portOpen())
    HOKUYO_EXCEPT(hokuyo::Exception, "Port not open.");

  // Try an intensity command.
  try
  {
    requestScans(1, 0, 0, 0, 0, 1);
    serviceScan(scan, 1000);
    return true;
  }
  catch (hokuyo::Exception &e)
  {} 
  
  // Try an intensity command.
  try
  {
    requestScans(0, 0, 0, 0, 0, 1);
    serviceScan(scan, 1000);
    return false;
  }
  catch (hokuyo::Exception &e)
  {
    HOKUYO_EXCEPT(hokuyo::Exception, "Exception whil trying to determine if intensity scans are supported.")
  } 
}
示例#8
0
std::string 
hokuyo::Laser::getID()
{
  if (!portOpen())
    HOKUYO_EXCEPT(hokuyo::Exception, "Port not open.");

  return serial_number_;
}
示例#9
0
std::string 
hokuyo::Laser::getFirmwareVersion()
{
  if (!portOpen())
    HOKUYO_EXCEPT(hokuyo::Exception, "Port not open.");

  return firmware_version_;
}
示例#10
0
std::string 
hokuyo::Laser::getProtocolVersion()
{
  if (!portOpen())
    HOKUYO_EXCEPT(hokuyo::Exception, "Port not open.");

  return protocol_version_;
}
示例#11
0
std::string 
hokuyo::Laser::getVendorName()
{
  if (!portOpen())
    HOKUYO_EXCEPT(hokuyo::Exception, "Port not open.");

  return vendor_name_;
}
示例#12
0
std::string 
hokuyo::Laser::getProductName()
{
  if (!portOpen())
    HOKUYO_EXCEPT(hokuyo::Exception, "Port not open.");

  return product_name_;
}
bool SerialPortControl::openPort (void)
{
    this->portInit();
    bool result = 0;
    result = serialPort->open(open_mode);
    if (result)
        emit portOpen();
    return(result);
}
示例#14
0
void
hokuyo::Laser::open(const char * tcphost, const int tcpport)
{
  if (portOpen())
    close();

  // Make IO non blocking. This way there are no race conditions that
  // cause blocking when a badly behaving process does a read at the same
  // time as us. Will need to switch to blocking for writes or errors
  // occur just after a replug event.

  laser_fd_ = tcpclient_open(&tcpclient,tcphost, tcpport);//::open(port_name, O_RDWR | O_NONBLOCK | O_NOCTTY);
  //laser_fd_ = tcpclient_open(&tcpclient,"127.0.0.1", 10001);//::open(port_name, O_RDWR | O_NONBLOCK | O_NOCTTY);

  read_buf_start = read_buf_end = 0;


  if (laser_fd_ < 0)
  {
    HOKUYO_EXCEPT(hokuyo::Exception, "Failed to open tcp_client: %s:%d. %s (errno = %d)", tcphost,tcpport, strerror(errno), errno);
  }

  laser_fd_ = tcpclient.sock_desc;

  try
  {
    // Some models (04LX) need to be told to go into SCIP2 mode...
    laserFlush();
    // Just in case a previous failure mode has left our Hokuyo
    // spewing data, we send reset the laser to be safe.
    try {
      reset();
    }
    catch (hokuyo::Exception &e)
    {
      // This might be a device that needs to be explicitely placed in
      // SCIP2 mode.
      // Note: Not tested: a device that is currently scanning in SCIP1.1
      // mode might not manage to switch to SCIP2.0.
      setToSCIP2(); // If this fails then it wasn't a device that could be switched to SCIP2.
      reset(); // If this one fails, it really is an error.
    }

    querySensorConfig();

    queryVersionInformation(); // In preparation for calls to get various parts of the version info.
  }
  catch (hokuyo::Exception& e)
  {
    // These exceptions mean something failed on open and we should close
    if (laser_fd_ != -1)
      tcpclient_close(&tcpclient);
    laser_fd_ = -1;
    throw e;
  }

}
示例#15
0
int cereal::CerealPort::available()
{
    if (!portOpen()) {
        return 0;
    }
    int count = 0;
    if (-1 == ioctl (fd_, TIOCINQ, &count)) {
        CEREAL_EXCEPT(cereal::Exception, "Available error -- error = %d: %s\n",  errno, strerror(errno));
    } else {
        return static_cast<size_t> (count);
    }
}
示例#16
0
void
hokuyo::Laser::setToSCIP2()
{
	if (!portOpen())
	    HOKUYO_EXCEPT(hokuyo::Exception, "Port not open.");
	const char * cmd = "SCIP2.0";
	char buf[100];
	laserWrite(cmd);
  	laserWrite("\n");

	laserReadline(buf, 100, 1000);
	ROS_DEBUG("Laser comm protocol changed to %s \n", buf);
	//printf ("Laser comm protocol changed to %s \n", buf);
}
示例#17
0
int
hokuyo::Laser::pollScan(hokuyo::LaserScan& scan, double min_ang, double max_ang, int cluster, int timeout)
{
  if (!portOpen())
    HOKUYO_EXCEPT(hokuyo::Exception, "Port not open.");

  int status;

  // Always clear ranges/intensities so we can return easily in case of erro
  scan.ranges.clear();
  scan.intensities.clear();

  // clustering of 0 and 1 are actually the same
  if (cluster == 0)
    cluster = 1;
  
  int min_i = (int)(afrt_ + min_ang*ares_/(2.0*M_PI));
  int max_i = (int)(afrt_ + max_ang*ares_/(2.0*M_PI));
  
  char cmdbuf[MAX_CMD_LEN];
  
  sprintf(cmdbuf,"GD%.4d%.4d%.2d", min_i, max_i, cluster);
  
  status = sendCmd(cmdbuf, timeout);
  
  scan.system_time_stamp = timeHelper() + offset_;
  
  if (status != 0)
    return status;
  
  // Populate configuration
  scan.config.min_angle  =  (min_i - afrt_) * (2.0*M_PI)/(ares_);
  scan.config.max_angle  =  (max_i - afrt_) * (2.0*M_PI)/(ares_);
  scan.config.ang_increment =  cluster*(2.0*M_PI)/(ares_);
  scan.config.time_increment = (60.0)/(double)(rate_ * ares_);
  scan.config.scan_time = 0.0;
  scan.config.min_range  =  dmin_ / 1000.0;
  scan.config.max_range  =  dmax_ / 1000.0;
  
  readData(scan, false, timeout);
  
  long long inc = (long long)(min_i * scan.config.time_increment * 1000000000);
  
  scan.system_time_stamp += inc;
  scan.self_time_stamp += inc;
  
  return 0;
}
示例#18
0
std::string
hokuyo::Laser::getStatus()
{
  if (!portOpen())
    HOKUYO_EXCEPT(hokuyo::Exception, "Port not open.");

  if (sendCmd("II",1000) != 0)
    HOKUYO_EXCEPT(hokuyo::Exception, "Error requesting device information information");
  
  char buf[100];
  char* stat = laserReadlineAfter(buf, 100, "STAT:");

  std::string statstr(stat);
  statstr = statstr.substr(0,statstr.length() - 3);

  return statstr;
}
示例#19
0
void hokuyo::Laser::reset ()
{
	if (!portOpen())
	    HOKUYO_EXCEPT(hokuyo::Exception, "Port not open.");
        laserFlush();
        try
        {
          sendCmd("TM2", 1000);
        }
        catch (hokuyo::Exception &e)
        {} // Ignore. If the laser was scanning TM2 would fail
        try
        {
          sendCmd("RS", 1000);
        }
        catch (hokuyo::Exception &e)
        {} // Ignore. If the command coincided with a scan we might get garbage.
        laserFlush();
        sendCmd("RS", 1000); // This one should just work.
}
示例#20
0
SerialPort::~SerialPort()
{
  if (portOpen())
    close();
}
示例#21
0
long long
hokuyo::Laser::calcLatency(bool intensity, double min_ang, double max_ang, int clustering, int skip, int num, int timeout)
{
  ROS_DEBUG("Entering calcLatency.");

  if (!portOpen())
    HOKUYO_EXCEPT(hokuyo::Exception, "Port not open.");

  static const std::string buggy_version = "1.16.02(19/Jan./2010)";
  if (firmware_version_ == buggy_version)
  {
    ROS_INFO("Hokuyo firmware version %s detected. Using hard-coded time offset of -23 ms.", 
        buggy_version.c_str());
    offset_ = -23000000;
  }
  else
  {
    offset_ = 0;

    uint64_t comp_time = 0;
    uint64_t laser_time = 0;
    long long diff_time = 0;
    long long drift_time = 0;
    long long tmp_offset1 = 0;
    long long tmp_offset2 = 0;

    int count = 0;

    sendCmd("TM0",timeout);
    count = 100;

    for (int i = 0; i < count;i++)
    {
      usleep(1000);
      sendCmd("TM1",timeout);
      comp_time = timeHelper();
      try 
      {
        laser_time = readTime();

        diff_time = comp_time - laser_time;

        tmp_offset1 += diff_time / count;
      } catch (hokuyo::RepeatedTimeException &e)
      {
        // We expect to get Repeated Time's when hammering on the time server
        continue;
      }
    }

    uint64_t start_time = timeHelper();
    usleep(5000000);
    sendCmd("TM1;a",timeout);
    sendCmd("TM1;b",timeout);
    comp_time = timeHelper();
    drift_time = comp_time - start_time;
    laser_time = readTime() + tmp_offset1;
    diff_time = comp_time - laser_time;
    double drift_rate = double(diff_time) / double(drift_time);

    sendCmd("TM2",timeout);

    if (requestScans(intensity, min_ang, max_ang, clustering, skip, num, timeout) != 0)
      HOKUYO_EXCEPT(hokuyo::Exception, "Error requesting scans during latency calculation");

    hokuyo::LaserScan scan;

    count = 200;
    for (int i = 0; i < count;i++)
    {
      try
      {
        serviceScan(scan, 1000);
      } catch (hokuyo::CorruptedDataException &e) {
        continue;
      }

      comp_time = scan.system_time_stamp;
      drift_time = comp_time - start_time;
      laser_time = scan.self_time_stamp + tmp_offset1 + (long long)(drift_time*drift_rate);
      diff_time = laser_time - comp_time;

      tmp_offset2 += diff_time / count;
    }

    offset_ = tmp_offset2;

    stopScanning();
  }

  ROS_DEBUG("Leaving calcLatency.");

  return offset_;
}
示例#22
0
void
hokuyo::Laser::open(const char * port_name)
{
  if (portOpen())
    close();
  
  laser_port_ = fopen(port_name, "r+");
  if (laser_port_ == NULL)
  {
    const char *extra_msg = "";
    switch (errno)
    {
      case EACCES:
        extra_msg = "You probably don't have premission to open the port for reading and writing.";
        break;
      case ENOENT:
        extra_msg = "The requested port does not exist. Is the hokuyo connected? Was the port name misspelled?";
        break;
    }

    HOKUYO_EXCEPT(hokuyo::Exception, "Failed to open port: %s. %s (errno = %d). %s", port_name, strerror(errno), errno, extra_msg);
  }
  try
  {
    laser_fd_ = fileno (laser_port_);
    if (laser_fd_ == -1)
      HOKUYO_EXCEPT(hokuyo::Exception, "Failed to get file descriptor --  error = %d: %s", errno, strerror(errno));

    // Make IO non blocking. This way there are no race conditions that
    // cause blocking when a badly behaving process does a read at the same
    // time as us. Will need to switch to blocking for writes or errors
    // occur just after a replug event.
    // No error checking. This really shouldn't fail, and even if it does,
    // we aren't so badly off.
    fcntl(laser_fd_, F_SETFL, fcntl(laser_fd_,F_GETFL,0) | O_NONBLOCK);

    struct flock fl;
    fl.l_type   = F_WRLCK;
    fl.l_whence = SEEK_SET;
    fl.l_start = 0;
    fl.l_len   = 0;
    fl.l_pid   = getpid();

    if (fcntl(laser_fd_, F_SETLK, &fl) != 0)
      HOKUYO_EXCEPT(hokuyo::Exception, "Device %s is already locked. Try 'lsof | grep %s' to find other processes that currently have the port open.", port_name, port_name);

    // Settings for USB?
    struct termios newtio;
    memset (&newtio, 0, sizeof (newtio));
    newtio.c_cflag = CS8 | CLOCAL | CREAD;
    newtio.c_iflag = IGNPAR;
    newtio.c_oflag = 0;
    newtio.c_lflag = ICANON;
    
    // activate new settings
    tcflush (laser_fd_, TCIFLUSH);
    if (tcsetattr (laser_fd_, TCSANOW, &newtio) < 0)
      HOKUYO_EXCEPT(hokuyo::Exception, "Unable to set serial port attributes. The port you specified (%s) may not be a serial port.", port_name); /// @todo tcsetattr returns true if at least one attribute was set. Hence, we might not have set everything on success.
    usleep (200000);

    // Some models (04LX) need to be told to go into SCIP2 mode...
    laserFlush();
    // Just in case a previous failure mode has left our Hokuyo
    // spewing data, we send reset the laser to be safe.
    try {
      reset();
    }
    catch (hokuyo::Exception &e)
    { 
      // This might be a device that needs to be explicitely placed in
      // SCIP2 mode. 
      // Note: Not tested: a device that is currently scanning in SCIP1.1
      // mode might not manage to switch to SCIP2.0.
      
      setToSCIP2(); // If this fails then it wasn't a device that could be switched to SCIP2.
      reset(); // If this one fails, it really is an error.
    }

    querySensorConfig();

    queryVersionInformation(); // In preparation for calls to get various parts of the version info.
  }
  catch (hokuyo::Exception& e)
  {
    // These exceptions mean something failed on open and we should close
    if (laser_port_ != NULL)
      fclose(laser_port_);
    laser_port_ = NULL;
    laser_fd_ = -1;
    throw e;
  }
}
示例#23
0
int
hokuyo::Laser::serviceScan(hokuyo::LaserScan& scan, int timeout)
{
  if (!portOpen())
    HOKUYO_EXCEPT(hokuyo::Exception, "Port not open.");

  // Always clear ranges/intensities so we can return easily in case of erro
  scan.ranges.clear();
  scan.intensities.clear();

  char buf[100];

  bool intensity = false;
  int min_i;
  int max_i;
  int cluster;
  int skip;
  int left;

  char* ind;

  int status = -1;

  //printf("in serviceReques!\n");
  do {
    //printf("in serviceReques1!\n");
    ind = laserReadlineAfter(buf, 100, "M",timeout);
    //printf("in serviceReques2!\n");
    scan.system_time_stamp = timeHelper() + offset_;

    //
    //printf("buf: %s\n",buf);
    //
    //printf("in serviceReques3!\n");
    if (ind[0] == 'D')
      intensity = false;
    else if (ind[0] == 'E')
      intensity = true;
    else
    {
      //printf("in serviceReques4!\n");
      continue;
    }
    ind++;

    sscanf(ind, "%4d%4d%2d%1d%2d", &min_i, &max_i, &cluster, &skip, &left);  

    //99b
    //02]I8
    //0^k0ij0Hm0>W1851:C1DN08018m1E11:^1Ao0GV0c?0Kg13j0E@0YF0h81C\1A_0X

    laserReadline(buf,100,timeout);

    buf[4] = 0;

    if (!checkSum(buf, 4))
      HOKUYO_EXCEPT(hokuyo::CorruptedDataException, "Checksum failed on status code: %s", buf);

    sscanf(buf, "%2d", &status);

    if (status != 99)
      return status;
    
  } while(status != 99);
    
  //printf("in serviceReques5!\n");

  scan.config.min_angle  =  (min_i - afrt_) * (2.0*M_PI)/(ares_);
  scan.config.max_angle  =  (max_i - afrt_) * (2.0*M_PI)/(ares_);
  scan.config.ang_increment =  cluster*(2.0*M_PI)/(ares_);
  scan.config.time_increment = (60.0)/(double)(rate_ * ares_);
  scan.config.scan_time = (60.0 * (skip + 1))/((double)(rate_));
  scan.config.min_range  =  dmin_ / 1000.0;
  scan.config.max_range  =  dmax_ / 1000.0;

  readData(scan, intensity, timeout);

  long long inc = (long long)(min_i * scan.config.time_increment * 1000000000);

  scan.system_time_stamp += inc;
  scan.self_time_stamp += inc;

//  printf("Scan took %lli.\n", -scan.system_time_stamp + timeHelper() + offset_);

  return 0;
}
示例#24
0
cereal::cereal_port::~cereal_port()
{
	if(portOpen()) close();
}
示例#25
0
hokuyo::Laser::~Laser ()
{
  if (portOpen())
    close();
}
示例#26
0
cereal::CerealPort::~CerealPort()
{
	if(portOpen()) close();
}
示例#27
0
void cereal::CerealPort::open(const char * port_name, int baud_rate)
{
	if(portOpen()) close();
  
	// Make IO non blocking. This way there are no race conditions that
	// cause blocking when a badly behaving process does a read at the same
	// time as us. Will need to switch to blocking for writes or errors
	// occur just after a replug event.
	fd_ = ::open(port_name, O_RDWR | O_NONBLOCK | O_NOCTTY);

	if(fd_ == -1)
	{
		const char *extra_msg = "";
		switch(errno)
		{
			case EACCES:
			extra_msg = "You probably don't have premission to open the port for reading and writing.";
			break;

			case ENOENT:
			extra_msg = "The requested port does not exist. Is the hokuyo connected? Was the port name misspelled?";
			break;
		}
		CEREAL_EXCEPT(cereal::Exception, "Failed to open port: %s. %s (errno = %d). %s", port_name, strerror(errno), errno, extra_msg);
	}
	
	try
	{	
		struct flock fl;
		fl.l_type = F_WRLCK;
		fl.l_whence = SEEK_SET;
		fl.l_start = 0;
		fl.l_len = 0;
		fl.l_pid = getpid();

		if(fcntl(fd_, F_SETLK, &fl) != 0)
			CEREAL_EXCEPT(cereal::Exception, "Device %s is already locked. Try 'lsof | grep %s' to find other processes that currently have the port open.", port_name, port_name);

		// Settings for USB?
		struct termios newtio;
		tcgetattr(fd_, &newtio);
		memset (&newtio.c_cc, 0, sizeof (newtio.c_cc));
		newtio.c_cflag = CS8 | CLOCAL | CREAD;
		newtio.c_iflag = IGNPAR;
		newtio.c_oflag = 0;
		newtio.c_lflag = 0;
		cfsetspeed(&newtio, baud_rate);
		baud_ = baud_rate;

		// Activate new settings
		tcflush(fd_, TCIFLUSH);
		if(tcsetattr(fd_, TCSANOW, &newtio) < 0)
			CEREAL_EXCEPT(cereal::Exception, "Unable to set serial port attributes. The port you specified (%s) may not be a serial port.", port_name); /// @todo tcsetattr returns true if at least one attribute was set. Hence, we might not have set everything on success.
		usleep (200000);
	}
	catch(cereal::Exception& e)
	{
		// These exceptions mean something failed on open and we should close
		if(fd_ != -1) ::close(fd_);
		fd_ = -1;
		throw e;
	}
}
示例#28
0
int
hokuyo::Laser::serviceScan(hokuyo::LaserScan& scan, int timeout)
{
  if (!portOpen())
    HOKUYO_EXCEPT(hokuyo::Exception, "Port not open.");

  // Always clear ranges/intensities so we can return easily in case of erro
  scan.ranges.clear();
  scan.intensities.clear();

  char buf[100];

  bool intensity = false;
  int min_i;
  int max_i;
  int cluster;
  int skip;
  int left;

  char* ind;

  int status = -1;

  do {
    ind = laserReadlineAfter(buf, 100, "M",timeout);
    scan.system_time_stamp = timeHelper() + offset_;

    if (ind[0] == 'D')
      intensity = false;
    else if (ind[0] == 'E')
      intensity = true;
    else
      continue;

    ind++;

    sscanf(ind, "%4d%4d%2d%1d%2d", &min_i, &max_i, &cluster, &skip, &left);  
    laserReadline(buf,100,timeout);

    buf[4] = 0;

    if (!checkSum(buf, 4))
      HOKUYO_EXCEPT(hokuyo::CorruptedDataException, "Checksum failed on status code: %s", buf);

    sscanf(buf, "%2d", &status);

    if (status != 99)
      return status;
    
  } while(status != 99);

  scan.config.min_angle  =  (min_i - afrt_) * (2.0*M_PI)/(ares_);
  scan.config.max_angle  =  (max_i - afrt_) * (2.0*M_PI)/(ares_);
  scan.config.ang_increment =  cluster*(2.0*M_PI)/(ares_);
  scan.config.time_increment = (60.0)/(double)(rate_ * ares_);
  scan.config.scan_time = (60.0 * (skip + 1))/((double)(rate_));
  scan.config.min_range  =  dmin_ / 1000.0;
  scan.config.max_range  =  dmax_ / 1000.0;

  readData(scan, intensity, timeout);

  long long inc = (long long)(min_i * scan.config.time_increment * 1000000000);

  scan.system_time_stamp += inc;
  scan.self_time_stamp += inc;

  return 0;
}