Update of /cvsroot/playerstage/code/player/server/drivers/laser
In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv28595/server/drivers/laser
Modified Files:
Makefile.am
Added Files:
RS4LeuzeLaserDriver.cc RS4Leuze_laser.cc RS4Leuze_laser.h
Log Message:
added rs4leuze driver
--- NEW FILE: RS4Leuze_laser.cc ---
/**
laser.cpp V 2.0 -> RS4Leuze_laser.cpp
Modified by Ernesto Homar Teniente Aviles
Date 20 APril 2007
*/
//include
#include "RS4Leuze_laser.h"
#include <string.h>
/**
Default constructor.
*/
//Claser::Claser(ClogMsg *lgMsg, bool *laser_ON, char dir_name[80]) //default
constructor.
Claser::Claser(int scan_points) //default constructor.
{
points_to_scan = scan_points;
}
/**
Destructor
*/
Claser::~Claser()
{
//close port
closeSerial();
}
void Claser::closeSerial()
{
close(serialFD);
}
void Claser::openSerial(bool *laser_ON, int Baud_rate, char * Port)
{
serialFD = open(Port, O_RDWR|O_NOCTTY);
if (serialFD<0)
{
cout << "Claser, Error opening serial port " << endl;
*laser_ON=0;
return;
}
// Configure Serial Port: termios settings: 57600(default), No Parity,
8 data bits, 1 stop Bit (8N1)
// values of masks in /usr/include/bits/termios.h
tcgetattr(serialFD,&ttyset);
ttyset.c_cflag = ( Baud_rate | CLOCAL | CREAD | CS8 );
ttyset.c_iflag = ( IGNBRK ); //Ignores break condition on input
ttyset.c_oflag = 0x0;
ttyset.c_lflag = 0x0;
// Set configuration immediately.
if (tcsetattr(serialFD, TCSANOW, &ttyset)<0)
{
cout << "Claser, Error opening serial port " << endl;
*laser_ON=0;
return;
}
else
FD_ZERO(&rfds); // Initialize the read set to zero
FD_SET(serialFD, &rfds); // Turn on the read set
// set timer
tv.tv_sec = 1;
tv.tv_usec = 0;
//Flush both pending input and untransmitted output.
tcflush(serialFD, TCIOFLUSH);
}
/**
Reads one byte from serialFD and updates checksum
*/
unsigned char Claser::readByte()
{
unsigned char localByte;
read (serialFD, &localByte, 1);
checksum = checksum ^ localByte;
return localByte;
}
/**
sync function synchronizes with the start of the laser data
*/
void Claser::sync()
{
int num_zeroes = 0;
// We must read three consecutive 0x00 for the end of the message
while (num_zeroes < 3)
{
read(serialFD, &byte, 1);
if(byte == 0x00) num_zeroes++;
else num_zeroes = 0;
}
// We are now, for a short time, at the beginning of the message.
}
/**
scanRead reads a whole message of a laser scan, loads it to scanData vector
and prints it to laserDataFile. If success returns 0 and returns 1 if failure.
*/
int Claser::scanRead()
{
unsigned int ii;
//******STEP 1: Reading message header
for (ii=0; ii<2; ii++)
{
byte = readByte();
//cout<<"Header: "<< byte << ";" <<endl;
if(byte != 0x00)
{
//cout << " Claser::scanRead(STEP 1), Error reading
Laser message header" << endl;
cout << "Error reading Laser message header" << endl;
return 1;
}
}
readByte(); //Reads but doesn't analyze command byte
option1=readByte(); //Reads Option1;
if (option1 & 0x03 > 1)
{
byte=readByte(); //Reads Option2
}
if (option1 & 0x03 > 2)
{;
byte=readByte(); //Reads Option3
}
// There's a bit that determines the existance of the password field
if ((option1 & 0x20) != 0x00)
{
for (ii=0; ii<8; ii++)
{
byte=readByte(); //Reads Password
}
}
//******STEP 2: Reading data header
scan_number = 0;
for (ii=0; ii<8; ii++)
{
if (ii%2 == 0)
{
scan_number = scan_number * 256 + readByte();
}
else
{
byte=readByte();
if (byte != 0xFE)
{
//cout << "Claser::scanRead(STEP 2), Error
reading Laser message header" << endl;
cout << "Error reading Laser message header" <<
endl;
return 1;
}
}
}
byte=readByte();//Resolution byte
output_start=readByte()*256;//ouput Start
output_start+=readByte();
output_stop=readByte()*256;//ouput Stop
output_stop+=readByte();
//******STEP 3: Reading laser scan /*data*/
//cout << "points_to_scan "<< points_to_scan << std::endl;
for (ii=0; ii<2*points_to_scan; ii++)
{
if (ii%2 == 0)
{
// 3.1: reading the first Byte of two from de scaned
point
scanedPoint = (readByte() * 256);
}
else
{
// 3.2: reading the second Byte of two from de scaned
point, and must mask the last bit
scanedPoint += readByte() & 0xFE;
// 3.3 joins the two Bytes froms the scaned point, and
they are converted from mm to meters
scanData.Reading[(ii-1)/2] =
(double)(scanedPoint/1000.0);
}
}
//******STEP 4: Reading Control Byte for checksum and ending message;
read(serialFD, &controlByte, 1);//just read without checksum
/*********************!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!*****/
return(0);
}
void Claser::runLaser()
{
//Claser *thisLaser = (Claser*)thisPnt;
//zeroTimeStamp=clock(); //Initializes time stamp
FD_ZERO(&rfds); // Initialize the read set to zero
FD_SET(serialFD, &rfds); // Turn on the read set
// set timer
tv.tv_sec = 1;
tv.tv_usec = 0;
if(select(serialFD+1, &rfds, NULL, NULL, &tv))
{
this->sync(); //Synchronizes
this->checksum=0x00; //Reset Checksum
this->scanRead(); //Read all scan Message
}
else
{
cout<<"Laser disconnected!!!!!!!!!!!!!!!!"<<endl;
}
}
--- NEW FILE: RS4Leuze_laser.h ---
/**
laser.h V 2.0 -> RS4Leuze_laser.cpp
Modified by Ernesto Homar Teniente Aviles
Date 08 May 2007
*/
#ifndef RS4Leuze_laser_h
#define RS4Leuze_laser_h
#include <termios.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <time.h>
#include <sys/time.h>
#include <stdlib.h>
#include <iostream>
#include <fstream>
using namespace std;
#define MAX_SCAN_POINTS 529
typedef struct RS4Leuze_laser_readings {
double Reading[MAX_SCAN_POINTS];
} RS4Leuze_laser_readings_t;
//classes
/**
Claser implements functions to read data from a laser scanner ROTOSCAN RS4-4
(Leuze corp.) connected to a serial port.
*/
class Claser
{
private:
char *portName; /**<Serial Port where laser is connected*/
int serialFD; /**<Serial port file descriptor*/
termios ttyset; /**<termios variable to configure serial port*/
fd_set rfds;
int selectResult; /**<Laser Message fields*/
unsigned char byte;
unsigned char checksum;
unsigned char option1;
long unsigned int scan_number;
unsigned int output_start;
unsigned int output_stop;
unsigned int scanedPoint;
unsigned char controlByte;
unsigned int points_to_scan;
struct timeval tv;/**<termios variable time interval*/
timeval timeStamp; /**<Time in microseconds resolution*/
ofstream laserDataFile; /**<Laser Scanner Data file*/
public:
//Claser(ClogMsg *lgMsg, bool *laser_ON, char dir_name[80]);
/**<Opens serial port*/
Claser(int scan_points); /**<Opens serial port*/
~Claser();
void closeLaser();/**<Closes serial Port and data file*/
unsigned char readByte(); /**<Reads one byte and updates
checksum message*/
void sync();
//void readScan(); /**<Sets to scanData array values of last
laser scanner*/
void writeConfig(); /**<Write configuration parameters to laser
scanner device*/
int scanRead(); /**<reads one scan and puts it in scanData
array*/
void runLaser(); /**<Return the scan reading from the laser*/
void closeSerial(); /**<Closes serial Port */
void openSerial(bool *laser_ON,int Baud_rate, char * Port);
/**<Opens serial Port and get the default paarameters or those given in the
.cfg file*/
RS4Leuze_laser_readings_t scanData;
};
#endif
--- NEW FILE: RS4LeuzeLaserDriver.cc ---
/*
* Player - One Hell of a Robot Server
* Copyright (C) 2000 Brian Gerkey et al.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
/////////////////////////////////////////////////////////////////////////////////////
// Desc: RS4-Leuze range finder laser driver
// Author: Ernesto Homar Teniente Avilés
// (C) Institut de Robótica Industrial
// Universidad Politécnica de Catalunya
// Date: May, 2007
// Version: 1.5.001
//
//
// Usage:
// (empty)
//
// Theory of operation:
// Based on the
//
// Known Bugs:
// (empty)
//
// Possible enhancements:
// (empty)
//
/////////////////////////////////////////////////////////////////////////////////////
/** @ingroup drivers */
/** @{ */
/** @defgroup driver_RS4Leuzelaser RS4LeuzeLaser
* @brief RS4-E leuze laser range-finder
The RS4-LeuzeLaser driver acquire date from the Leuze RS4 scanning laser
range-finder.
Communication with the laser is via RS232.
@par Compile-time dependencies
- none
@par Provides
- @ref interface_laser
@par Requires
- none
@par Configuration requests
- PLAYER_LASER_REQ_GET_GEOM
- PLAYER_LASER_REQ_GET_CONFIG
- PLAYER_LASER_REQ_SET_CONFIG
@par Configuration file options
- port (string)
- Default: "/dev/ttyS1"
- Port to which the laser is connected. If you are using a USB/232 converter,
this will be "dev/ttyUSBx".
- pose (float tuple m m rad)
- Default: [0.0 0.0 0.0]
- Pose (x,y,theta) of the laser, relative to its parent object (e.g.,
the robot to which the laser is attached).
- min_angle, max_angle (angle float)
- Default: [] (or [-5.04 185.04] in degrees)
- Minimum and maximum scan angles to return
- baud (integer)
- Default: 57600
- Baud rate to use when communicating with the laser over RS232. Valid
rates are: 4800, 9600,
19200, 38400, 57600, and 115200. It should be chosen accordingly with the
RS4 laser settings.
- scan_points (integer)
- Default: 132
- Others : 176, 264, 528
- invert_data(bool)
- Default: 1 (invert_data_on) Leuze data must be inverted in order to be used
in player
- 0 (invert_data_off) - Is the laser physically inverted (i.e.,
upside-down)? Is so, scan data
will not be reversed accordingly.
@par Example
@verbatim
driver
(
name "rs4leuzelaser"
plugin "RS4LeuzeLaserDriver.la"
provides ["laser:0"]
port "/dev/ttyS1"
scan_points "528"
#invert_data "0"
)
@endverbatim
@author Ernesto Homar Teniente Avilés
IRI-UPC
CONACYT-Schoolarship
*/
/** @} */
#include <unistd.h>
#include <string.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <sys/select.h>
#include <sys/time.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <stdlib.h>
#include <math.h>
#include <termios.h>
#include <vector>
#include <time.h>
#include <iostream>
#include <fstream>
#include "RS4Leuze_laser.h"
#include <libplayercore/playercore.h>
using namespace std;
//Header file. Player driver class for the RS4 Leuze Laser(1);
class RS4LeuzeLaserDriver : public Driver {
public:
// Constructor, teh constructor takes a CongifgFile parameter
//and an integer section parameter(2);
RS4LeuzeLaserDriver(ConfigFile* cf, int section);
// Destructor
~RS4LeuzeLaserDriver();
//The driver must implement the abstract Setup and Shutdown methods
(3);
// Implementations of virtual functions
int Setup();
int Shutdown();
//The drivers re-implements the ProcessMessage method to provide
support for
//handling request and commands(4)
// This method will be invoked on each incoming message
virtual int ProcessMessage(MessageQueue* resp_queue,
player_msghdr * hdr,
void * data);
private:
//The drivers re-implements Main, wich will be called when the dirver
thread
//is started(5)
// Main function for device thread.
virtual void Main();
RS4Leuze_laser_readings_t Readings;
Claser *myLaser;
bool laser_ON;
player_laser_data_t Data;
player_laser_geom_t Geom;
player_laser_config_t Conf;
//bool UseSerial;
int BaudRate;
char * Port;
bool invert;
int ScanPoints;
struct timeval tv;/**<termios variable time interval*/
timeval timeStamp; /**<Time in microseconds resolution*/
};
////////////////////////////////////////////////////////////////////////////////
// Constructor. Retrieve options from the configuration file and do any
// pre-Setup() setup.
RS4LeuzeLaserDriver::RS4LeuzeLaserDriver(ConfigFile* cf, int section)
: Driver(cf, section, false, PLAYER_MSGQUEUE_DEFAULT_MAXLEN, PLAYER_LASER_CODE)
{
//init vars
memset(&Data, 0, sizeof(Data));
memset(&Geom, 0, sizeof(Geom));
memset(&Conf, 0, sizeof(Conf));
Geom.size.sw = (0.050);
Geom.size.sl = (0.050);
// read options from config file
Geom.pose.px = (cf->ReadTupleLength(section,"pose",0,0));
Geom.pose.py = (cf->ReadTupleLength(section,"pose",1,0));
Geom.pose.pyaw = (cf->ReadTupleAngle(section,"pose",2,0));
//set up config structure
Conf.min_angle = cf->ReadAngle(section,"min_angle",DTOR(-5.04));
Conf.max_angle = cf->ReadAngle(section,"max_angle",DTOR(185.04));
//Conf.resolution = depends on the laser resolution
Conf.max_range = 50;
Conf.range_res = 0.01;
Conf.intensity = 0;
// serial configuration
cout << "myLaser RS4 Leuze:"<< endl;
int b = cf->ReadInt(section, "baud", 57600);
switch(b)
{
case 115200:
BaudRate = B115200;
break;
case 57600:
BaudRate = B57600;
break;
case 38400:
BaudRate = B38400;
break;
case 19200:
BaudRate = B19200;
break;
case 9600:
BaudRate = B9600;
break;
case 4800:
BaudRate = B4800;
break;
default:
PLAYER_WARN1("ignoring invalid baud rate %d", b);
BaudRate = B57600;
b = 57600;
break;
}
cout << "baud rate : " << b << endl;
Port = strdup(cf->ReadString(section, "port", "/dev/ttyS1"));
cout << "port :" << Port << endl;
// Scan points configuration
int sc = cf->ReadInt(section, "scan_points", 132);
switch(sc)
{
case 132:
ScanPoints = 133;
Conf.resolution = DTOR(4*0.36);
break;
case 176:
ScanPoints = 177;
Conf.resolution = DTOR(3*0.36);
break;
case 264:
ScanPoints = 265;
Conf.resolution = DTOR(2*0.36);
break;
case 528:
ScanPoints = 529;
Conf.resolution = DTOR(0.36);
break;
default:
PLAYER_WARN1("ignoring invalid scan points %d", sc);
ScanPoints = 133;
Conf.resolution = DTOR(4*0.36);
break;
}
cout << "scan points : " << ScanPoints << endl;
//invert data from teh leuze. Check if the leuze is
upside-down.Normally dat must be inverted
//int sc = cf->ReadInt(section, "scan_points", 132);
invert = cf -> ReadInt(section, "invert_data", 1);
laser_ON = 1;
myLaser=new Claser(ScanPoints);
;
return;
}
RS4LeuzeLaserDriver::~RS4LeuzeLaserDriver()
{
//Reading are erased
delete myLaser;
//delete Readings;
}
////////////////////////////////////////////////////////////////////////////////
// Set up the device. Return 0 if things go well, and -1 otherwise.
int RS4LeuzeLaserDriver::Setup() {
//config data
// Si el el puerto no fue abierto, entonces mandar error. if(*mylaser.
//if(Laser.Open(Port,UseSerial,BaudRate) < 0)
//{
// this->SetError(1);
// return -1;
//}
cout << "S4LeuzeLaserDriver::Setup" << endl;
// Start the device thread; spawns a new thread and executes
// ExampleDriver::Main(), which contains the main loop for the driver.
StartThread();
return(0);
}
////////////////////////////////////////////////////////////////////////////////
// Shutdown the device
int RS4LeuzeLaserDriver::Shutdown() {
// Stop and join the driver thread
StopThread();
myLaser->closeSerial();
return(0);
}
int RS4LeuzeLaserDriver::ProcessMessage(MessageQueue* resp_queue,
player_msghdr * hdr,
void * data)
{
if(Message::MatchMessage(hdr, PLAYER_MSGTYPE_REQ,
PLAYER_LASER_REQ_GET_GEOM,
this->device_addr))
{
Publish(device_addr,resp_queue,
PLAYER_MSGTYPE_RESP_ACK,hdr->subtype,&Geom,sizeof(Geom),NULL);
}
else if(Message::MatchMessage(hdr, PLAYER_MSGTYPE_REQ,
PLAYER_LASER_REQ_GET_CONFIG,
this->device_addr))
{
Publish(device_addr,resp_queue,
PLAYER_MSGTYPE_RESP_ACK,hdr->subtype,&Conf,sizeof(Conf),NULL);
}
else
{
return -1;
}
return 0;
}
////////////////////////////////////////////////////////////////////////////////
// Main function for device thread
void RS4LeuzeLaserDriver::Main()
{
cout << "RS4LeuzeLaserDriver::Main" << endl;
bool laser_ON=1;
//int i;
cout<<"Laser Ok"<<endl;
// The main loop; interact with the device here
for(int veces = 0;;veces++) {
// test if we are supposed to cancel
pthread_testcancel();
// Process any pending messages
ProcessMessages();
// update device data
myLaser->openSerial(&laser_ON, BaudRate, Port);
myLaser->runLaser();
Data.min_angle = Conf.min_angle;
Data.max_angle = Conf.max_angle;
Data.max_range = Conf.max_range;
Data.resolution = Conf.resolution;
Data.ranges_count = ScanPoints;
//cout << endl << "Data RS4leuze Player : ";
int top_ii = Data.ranges_count;
float tmp;
cout << "Data: ";
for (unsigned int i = 0; i < Data.ranges_count; ++i)
{
tmp = myLaser->scanData.Reading[i];
if (invert)
{
//Inverting the data, Laser upside
Data.ranges[top_ii] = tmp;
--top_ii;
}
else
{
//Laser upside-down
Data.ranges[i] = tmp;
}
cout << Data.ranges[i] << " ";
}
cout << endl;
Publish(device_addr, NULL, PLAYER_MSGTYPE_DATA,
PLAYER_LASER_DATA_SCAN,
&Data, sizeof(player_laser_data_t), NULL);
//cout << endl << "Data RS4leuze passed ";
myLaser->closeSerial();
getchar();
//cout << endl << "end laser **************" <<endl;
}
}
////////////////////////////////////////////////////////////////////////////////
// Things for building shared object, and functions for registering and creating
// new instances of the driver
////////////////////////////////////////////////////////////////////////////////
//Factory creation function. This functions is given as an argument when
// the driver is added to the driver table
Driver* RS4LeuzeLaserDriver_Init(ConfigFile* cf, int section) {
// Create and return a new instance of this driver
return((Driver*)(new RS4LeuzeLaserDriver(cf, section)));
}
//Registers the driver in the driver table. Called from the
// player_driver_init function that the loader looks for
int RS4LeuzeLaserDriver_Register(DriverTable* table) {
table->AddDriver("rs4leuze", RS4LeuzeLaserDriver_Init);
return 0;
}
Index: Makefile.am
===================================================================
RCS file: /cvsroot/playerstage/code/player/server/drivers/laser/Makefile.am,v
retrieving revision 1.19
retrieving revision 1.20
diff -C2 -d -r1.19 -r1.20
*** Makefile.am 31 Jul 2007 08:33:45 -0000 1.19
--- Makefile.am 22 Aug 2007 00:19:56 -0000 1.20
***************
*** 41,44 ****
--- 41,48 ----
endif
+ if INCLUDE_RS4LEUZE
+ noinst_LTLIBRARIES += librs4leuze.la
+ endif
+
EXTRA_DIST = lasercspace-1.jpg lasercspace-2.jpg
***************
*** 55,56 ****
--- 59,61 ----
liblasercutter_la_SOURCES = lasercutter.cc lasertransform.h lasertransform.cc
liburglaser_la_SOURCES = urg_laser.cc urg_laser.h urglaserdriver.cc
+ librs4leuze_la_SOURCES = RS4LeuzeLaserDriver.cc RS4Leuze_laser.cc
RS4Leuze_laser.h
-------------------------------------------------------------------------
This SF.net email is sponsored by: Splunk Inc.
Still grepping through log files to find problems? Stop.
Now Search log events and configuration files using AJAX and a browser.
Download your FREE copy of Splunk now >> http://get.splunk.com/
_______________________________________________
Playerstage-commit mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/playerstage-commit