Update of /cvsroot/playerstage/code/player/server/drivers/pointcloud3d
In directory
sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv549/server/drivers/pointcloud3d
Added Files:
Makefile.am laserptzcloud.cc
Log Message:
added laserptz pointcloud3d driver
--- NEW FILE: Makefile.am ---
noinst_LTLIBRARIES =
if INCLUDE_LASERPTZCLOUD
noinst_LTLIBRARIES += liblaserptzcloud.la
endif
AM_CPPFLAGS = -Wall -I$(top_srcdir)
liblaserptzcloud_la_SOURCES = laserptzcloud.cc
--- NEW FILE: laserptzcloud.cc ---
/*
* Player - One Hell of a Robot Server
* Copyright (C) 2006 - Radu Bogdan Rusu ([EMAIL PROTECTED])
*
* 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
*
*/
/** @ingroup drivers */
/** @{ */
/** @defgroup driver_laserptzcloud laserptzcloud
* @brief Build a 3D point cloud from laser and ptz data
The laserptztcloud driver reads laser scans from a laser device and PTZ poses
from a ptz device, linearly interpolates to estimate the actual pan/tilt pose
from which the scan was taken, then outputs messages containing the cartesian
3D coordinates (X,Y,Z in [m]) via a pointcloud3d interface. No additional
thread is started. Based on Brian's laserposerinterpolator.
@par Compile-time dependencies
- none
@par Provides
- @ref interface_pointcloud3d
@par Requires
- @ref interface_laser
- @ref interface_ptz
@par Configuration requests
- None (yet)
@par Configuration file options
@par Example
@verbatim
driver
(
name "laserptzcloud"
provides ["pointcloud3d:0"]
requires ["laser:0" "ptz:0"]
)
@endverbatim
@author Radu Bogdan Rusu
*/
/** @} */
#if HAVE_CONFIG_H
#include <config.h>
#endif
#include <math.h>
#include <float.h>
#include <stdlib.h>
#include <assert.h>
#include <libplayercore/playercore.h>
#include <libplayercore/error.h>
#define DEFAULT_MAXSCANS 100
#define DEFAULT_MAXPOINTS PLAYER_POINTCLOUD3D_MAX_POINTS
#define DEFAULT_MAXDISTANCE 10
// PTZ defaults for tilt
#define PTZ_PAN 0
#define PTZ_TILT 1
#define DEFAULT_PTZ_PAN_OR_TILT PTZ_TILT
// The laser device class.
class LaserPTZCloud : public Driver
{
public:
// Constructor
LaserPTZCloud (ConfigFile* cf, int section);
~LaserPTZCloud ();
int Setup();
int Shutdown();
// MessageHandler
int ProcessMessage (MessageQueue * resp_queue,
player_msghdr * hdr,
void * data);
private:
// device bookkeeping
player_devaddr_t laser_addr;
player_devaddr_t ptz_addr;
Device* laser_device;
Device* ptz_device;
// Laser scans
player_laser_data_t* scans;
// Laser timestamps
double* scantimes;
// Maximum number of laser scans to buffer
int maxnumscans;
// Total number of laser scans
int numscans;
// 3D points buffer
player_point_3d_t* points;
// Maximum number of poins in a graphics3d data packet
int maxpoints;
// Maximum distance that we should consider from the laser
float maxdistance;
// PTZ tilt parameters
float ptz_pan_or_tilt;
// Timeouts, delays
float delay;
// First PTZ pose
player_ptz_data_t lastpose;
double lastposetime;
};
////////////////////////////////////////////////////////////////////////////////
//Factory creation function. This functions is given as an argument when
// the driver is added to the driver table
Driver* LaserPTZCloud_Init (ConfigFile* cf, int section)
{
return ((Driver*)(new LaserPTZCloud (cf, section)));
}
////////////////////////////////////////////////////////////////////////////////
//Registers the driver in the driver table. Called from the
// player_driver_init function that the loader looks for
void LaserPTZCloud_Register (DriverTable* table)
{
table->AddDriver ("laserptzcloud", LaserPTZCloud_Init);
}
////////////////////////////////////////////////////////////////////////////////
// Constructor. Retrieve options from the configuration file and do any
// pre-Setup() setup.
LaserPTZCloud::LaserPTZCloud (ConfigFile* cf, int section)
: Driver(cf, section, false, PLAYER_MSGQUEUE_DEFAULT_MAXLEN,
PLAYER_POINTCLOUD3D_CODE)
{
// Must have an input laser
if (cf->ReadDeviceAddr (&this->laser_addr, section, "requires",
PLAYER_LASER_CODE, -1, NULL) != 0)
{
PLAYER_ERROR ("must have an input laser");
this->SetError (-1);
return;
}
this->laser_device = NULL;
// Must have an input ptz
if (cf->ReadDeviceAddr (&this->ptz_addr, section, "requires",
PLAYER_PTZ_CODE, -1, NULL) != 0)
{
PLAYER_ERROR ("must have an input ptz");
this->SetError (-1);
return;
}
this->ptz_device = NULL;
// ---[ PTZ parameters ]---
this->ptz_pan_or_tilt = cf->ReadFloat
(section, "ptz_pan_or_tilt", DEFAULT_PTZ_PAN_OR_TILT);
// Maximum number of laser scans to buffer
this->maxnumscans = cf->ReadInt (section, "max_scans", DEFAULT_MAXSCANS);
// Maximum allowed distance
this->maxdistance = cf->ReadFloat (section, "max_distance",
DEFAULT_MAXDISTANCE);
// Maximum number of points that can be sent at once
this->maxpoints = cf->ReadInt (section, "max_points", DEFAULT_MAXPOINTS);
if (this->maxpoints > DEFAULT_MAXPOINTS)
{
maxpoints = MIN (maxpoints, DEFAULT_MAXPOINTS);
PLAYER_WARN1 ("number of points cannot exceeded MAXPOINTS (%d)",
DEFAULT_MAXPOINTS);
}
// Allocate memory for the buffer
this->scans = (player_laser_data_t*)calloc
(this->maxnumscans, sizeof (player_laser_data_t));
assert (this->scans);
// Allocate memory for the laser timestamps
this->scantimes = (double*)calloc (this->maxnumscans, sizeof (double));
assert (this->scantimes);
// Allocate memory for the points buffer
this->points = (player_point_3d_t*)calloc
(this->maxnumscans, sizeof (player_point_3d_t));
return;
}
////////////////////////////////////////////////////////////////////////////////
// Destructor.
LaserPTZCloud::~LaserPTZCloud()
{
free (this->scans);
free (this->scantimes);
}
////////////////////////////////////////////////////////////////////////////////
// Set up the device. Return 0 if things go well, and -1 otherwise.
int LaserPTZCloud::Setup()
{
// Subscribe to the laser
if (!(this->laser_device = deviceTable->GetDevice (this->laser_addr)))
{
PLAYER_ERROR ("unable to locate suitable laser device");
return (-1);
}
if (this->laser_device->Subscribe (this->InQueue) != 0)
{
PLAYER_ERROR ("unable to subscribe to laser device");
return (-1);
}
// Subscribe to the ptz.
if (!(this->ptz_device = deviceTable->GetDevice (this->ptz_addr)))
{
PLAYER_ERROR ("unable to locate suitable ptz device");
return (-1);
}
if (this->ptz_device->Subscribe (this->InQueue) != 0)
{
PLAYER_ERROR ("unable to subscribe to ptz device");
return (-1);
}
this->numscans = 0;
this->lastposetime = -1;
return (0);
}
////////////////////////////////////////////////////////////////////////////////
// Shutdown the device
int LaserPTZCloud::Shutdown()
{
this->laser_device->Unsubscribe (this->InQueue);
this->ptz_device->Unsubscribe (this->InQueue);
return (0);
}
////////////////////////////////////////////////////////////////////////////////
// ProcessMessage
int LaserPTZCloud::ProcessMessage (MessageQueue * resp_queue,
player_msghdr * hdr,
void * data)
{
// Is it a laser scan?
if (Message::MatchMessage (hdr, PLAYER_MSGTYPE_DATA,
PLAYER_LASER_DATA_SCAN,
this->laser_addr))
{
// Buffer the scan
// is there room?
if (this->numscans >= this->maxnumscans)
{
PLAYER_WARN1 ("exceeded maximum number of scans to buffer (%d)",
this->maxnumscans);
return (0);
}
// store the scan and timestamp
this->scans[this->numscans] = *((player_laser_data_t*)data);
this->scantimes[this->numscans] = hdr->timestamp;
this->numscans++;
return (0);
}
// Is it a ptz pose?
else if (Message::MatchMessage (hdr, PLAYER_MSGTYPE_DATA,
PLAYER_PTZ_DATA_STATE, this->ptz_addr))
{
player_ptz_data_t newpose = *((player_ptz_data_t*)data);
// Is it the first pose?
if (this->lastposetime < 0)
{
// Just store it.
this->lastpose = newpose;
this->lastposetime = hdr->timestamp;
}
else
{
// Interpolate pose for all buffered scans and send them out
double t1 = hdr->timestamp - this->lastposetime;
if (newpose.tilt != lastpose.tilt)
for (int i = 0; i < this->numscans; i++)
{
double t0 = this->scantimes[i] - this->lastposetime;
float corrected_tilt = this->lastpose.tilt + t0 *
(newpose.tilt - this->lastpose.tilt) / t1;
// Convert the vertical angle to radians
//float angle_y = corrected_tilt * M_PI/180.0;
// No need to: already converted from PTZ
float angle_y = corrected_tilt;
// Calculate the horizontal angles and the cartesian
coordinates
float angle_x = this->scans[i].min_angle;
float resolution = this->scans[i].resolution;
int ranges_count = (int)(this->scans[i].ranges_count);
// The 3D point array
player_pointcloud3d_data_t cloud_data;
player_pointcloud3d_element_t all_elements[ranges_count];
int counter = 0;
for (int j = 0; j < ranges_count; j++)
{
float distance = this->scans[i].ranges[j];
if (distance < maxdistance)
{
float X = distance * cos (angle_x) * sin (angle_y);
float Y = distance * cos (angle_x) * cos (angle_y);
float Z = distance * sin (angle_x);
player_point_3d_t p3d;
p3d.px = X;
p3d.py = Y;
p3d.pz = Z;
all_elements[counter].point = p3d;
counter++;
}
angle_x += resolution;
}
cloud_data.points_count = counter;
for (int j=0; j < counter; j++)
cloud_data.points[j] = all_elements[j];
Publish (this->device_addr, NULL, PLAYER_MSGTYPE_DATA,
PLAYER_POINTCLOUD3D_DATA_STATE, &cloud_data,
sizeof (player_pointcloud3d_data_t), NULL);
}
this->numscans = 0;
this->lastpose = newpose;
this->lastposetime = hdr->timestamp;
}
return(0);
}
// Don't know how to handle this message.
return (-1);
}
-------------------------------------------------------------------------
Using Tomcat but need to do more? Need to support web services, security?
Get stuff done quickly with pre-integrated technology to make your job easier
Download IBM WebSphere Application Server v.1.0.1 based on Apache Geronimo
http://sel.as-us.falkag.net/sel?cmd=lnk&kid=120709&bid=263057&dat=121642
_______________________________________________
Playerstage-commit mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/playerstage-commit