Revision: 8410 http://playerstage.svn.sourceforge.net/playerstage/?rev=8410&view=rev Author: thjc Date: 2009-11-15 13:17:03 +0000 (Sun, 15 Nov 2009)
Log Message: ----------- didnt actually add the new files from the blobtracker patch Added Paths: ----------- code/player/trunk/server/drivers/dio/blobtracker/ code/player/trunk/server/drivers/dio/blobtracker/CMakeLists.txt code/player/trunk/server/drivers/dio/blobtracker/blobtracker.cc Added: code/player/trunk/server/drivers/dio/blobtracker/CMakeLists.txt =================================================================== --- code/player/trunk/server/drivers/dio/blobtracker/CMakeLists.txt (rev 0) +++ code/player/trunk/server/drivers/dio/blobtracker/CMakeLists.txt 2009-11-15 13:17:03 UTC (rev 8410) @@ -0,0 +1,2 @@ +PLAYERDRIVER_OPTION (blobtracker build_blobtracker ON) +PLAYERDRIVER_ADD_DRIVER (blobtracker build_blobtracker SOURCES blobtracker.cc) Added: code/player/trunk/server/drivers/dio/blobtracker/blobtracker.cc =================================================================== --- code/player/trunk/server/drivers/dio/blobtracker/blobtracker.cc (rev 0) +++ code/player/trunk/server/drivers/dio/blobtracker/blobtracker.cc 2009-11-15 13:17:03 UTC (rev 8410) @@ -0,0 +1,406 @@ +/* + * 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 + * + */ + +/* + * + * Blob tracker that sends ptz commands in order to make camera follow certain blobs. + */ + +/** @ingroup drivers */ +/** @{ */ +/** @defgroup driver_Blobtracker Blobtracker + * @brief Blob tracker that sends ptz commands in order to make camera follow certain blobs. + +...@par Compile-time dependencies + +- None + +...@par Provides + +- @ref interface_dio - lowest bit of dio bits is set to 1 whenever any of desired blobs is found + +...@par Requires + +- @ref interface_blobfinder +- @ref interface_ptz + +...@par Configuration requests + +- None + +...@par Configuration file options + +- r (integer) + - Default: 0 + - r value of desired blobs RGB +- g (integer) + - Default: 0 + - g value of desired blobs RGB +- b (integer) + - Default: 0 + - b value of desired blobs RGB +- idle_area (double) + - Default: 0.4 + - Valid value range 0.0 to 1.0 + - Middle part of the image where blob moves are not followed + - Border cases: 0.0 - no part of the image is idle, 1.0 - whole image +- step (degrees) + - Default: 1.0 + - How many degrees to move during one iteration + - The default value (1.0) is good for Stage, + however it's too small for Logitech Sphere AF camera +- pan_speed (degrees) + - Default: 10.0 + - Angular pan speed +- tilt_speed (degrees) + - Default: 10.0 + - Agular tilt speed +- zoom (degrees) + - Default: not set + - Field of view (typically it is not required to set this value) + - Negative value means 'not set' - field of view will not be changed + +...@par Example + +Look for a green sheet: + +...@verbatim +driver +( + name "camerauvc" + provides ["camera:0"] + port "/dev/video1" + size [640 480] +) +driver +( + name "sphereptz" + provides ["ptz:0"] + port "/dev/video1" + autoreset 0 +) +driver +( + name "cmvision" + provides ["blobfinder:0"] + requires ["camera:0"] + colorfile "colors.txt" +) +driver +( + name "blobtracker" + provides ["dio:0"] + requires ["6665:blobfinder:0" "6665:ptz:0"] + r 0 + g 255 + b 0 + step 5.0 + alwayson 1 +) +...@endverbatim + +colors.txt file I used for this was: + +...@verbatim +[Colors] +(255, 0, 0) 0.000000 10 Red +( 0,255, 0) 0.000000 10 Greeen +( 0, 0,255) 0.000000 10 Blue + +[Thresholds] +( 25:164, 80:120,150:240) +( 20:220, 50:120, 40:115) +( 15:190,145:255, 40:120) +...@endverbatim + +...@author Paul Osmialowski + +*/ +/** @} */ + +#include <libplayercore/playercore.h> + +#include <stddef.h> +#include <string.h> +#include <math.h> + +#define EPS 0.0000001 + +#ifndef M_PI +#define M_PI 3.14159265358979323846 +#endif + +#ifndef DTOR +#define DTOR(d) ((d) * (M_PI) / 180.0) +#endif + +class Blobtracker : public Driver +{ +public: + Blobtracker(ConfigFile * cf, int section); + virtual ~Blobtracker(); + virtual int Setup(); + virtual int Shutdown(); + virtual int ProcessMessage(QueuePointer & resp_queue, player_msghdr * hdr, void * data); +private: + player_devaddr_t r_blobfinder_addr; + player_devaddr_t r_ptz_addr; + player_devaddr_t p_dio_addr; + Device * r_blobfinder_dev; + Device * r_ptz_dev; + player_ptz_data_t ptz_data; + unsigned char r; + unsigned char g; + unsigned char b; + double idle_area; + double step; + double pan_speed; + double tilt_speed; + double zoom; + bool valid_ptz_data; +}; + +Blobtracker::Blobtracker(ConfigFile * cf, int section) : Driver(cf, section, true, PLAYER_MSGQUEUE_DEFAULT_MAXLEN) +{ + memset(&(this->r_blobfinder_addr), 0, sizeof(player_devaddr_t)); + memset(&(this->r_ptz_addr), 0, sizeof(player_devaddr_t)); + memset(&(this->p_dio_addr), 0, sizeof(player_devaddr_t)); + this->r_blobfinder_dev = NULL; + this->r_ptz_dev = NULL; + memset(&(this->ptz_data), 0, sizeof(ptz_data)); + this->ptz_data.pan = 0.0; + this->ptz_data.tilt = 0.0; + this->r = 0; + this->g = 0; + this->b = 0; + this->idle_area = 0.0; + this->step = 0.0; + this->pan_speed = 0.0; + this->tilt_speed = 0.0; + this->valid_ptz_data = false; + if (cf->ReadDeviceAddr(&(this->p_dio_addr), section, "provides", + PLAYER_DIO_CODE, -1, NULL)) + { + PLAYER_ERROR("cannot provide dio device"); + this->SetError(-1); + return; + } + if (this->AddInterface(this->p_dio_addr)) + { + this->SetError(-1); + return; + } + if (cf->ReadDeviceAddr(&(this->r_blobfinder_addr), section, "requires", + PLAYER_BLOBFINDER_CODE, -1, NULL)) + { + PLAYER_ERROR("cannot require blobfinder device"); + this->SetError(-1); + return; + } + if (cf->ReadDeviceAddr(&(this->r_ptz_addr), section, "requires", + PLAYER_PTZ_CODE, -1, NULL)) + { + PLAYER_ERROR("cannot require ptz device"); + this->SetError(-1); + return; + } + this->r = static_cast<unsigned char>(cf->ReadInt(section, "r", 0)); + this->g = static_cast<unsigned char>(cf->ReadInt(section, "g", 0)); + this->b = static_cast<unsigned char>(cf->ReadInt(section, "b", 0)); + this->idle_area = cf->ReadFloat(section, "idle_area", 0.4); + if ((this->idle_area < 0.0) || (this->idle_area > 1.0)) + { + PLAYER_ERROR("invalid idle_area value"); + this->SetError(-1); + return; + } + this->step = cf->ReadAngle(section, "step", DTOR(1.0)); + if ((this->step) < EPS) + { + PLAYER_ERROR("invalid step value"); + this->SetError(-1); + return; + } + this->pan_speed = cf->ReadAngle(section, "pan_speed", DTOR(10.0)); + if ((this->pan_speed) < EPS) + { + PLAYER_ERROR("invalid pan_speed value"); + this->SetError(-1); + return; + } + this->tilt_speed = cf->ReadAngle(section, "tilt_speed", DTOR(10.0)); + if ((this->tilt_speed) < EPS) + { + PLAYER_ERROR("invalid tilt_speed value"); + this->SetError(-1); + return; + } + this->zoom = cf->ReadAngle(section, "zoom", -1.0); +} + +Blobtracker::~Blobtracker() { } + +int Blobtracker::Setup() +{ + memset(&(this->ptz_data), 0, sizeof(ptz_data)); + this->valid_ptz_data = false; + this->r_blobfinder_dev = deviceTable->GetDevice(this->r_blobfinder_addr); + if (!(this->r_blobfinder_dev)) return -1; + if (this->r_blobfinder_dev->Subscribe(this->InQueue)) + { + this->r_blobfinder_dev = NULL; + return -1; + } + this->r_ptz_dev = deviceTable->GetDevice(this->r_ptz_addr); + if (!(this->r_ptz_dev)) + { + this->r_blobfinder_dev->Unsubscribe(this->InQueue); + this->r_blobfinder_dev = NULL; + return -1; + } + if (this->r_ptz_dev->Subscribe(this->InQueue)) + { + this->r_blobfinder_dev->Unsubscribe(this->InQueue); + this->r_blobfinder_dev = NULL; + this->r_ptz_dev = NULL; + return -1; + } + return 0; +} + +int Blobtracker::Shutdown() +{ + if (this->r_blobfinder_dev) this->r_blobfinder_dev->Unsubscribe(this->InQueue); + this->r_blobfinder_dev = NULL; + if (this->r_ptz_dev) this->r_ptz_dev->Unsubscribe(this->InQueue); + this->r_ptz_dev = NULL; + return 0; +} + +int Blobtracker::ProcessMessage(QueuePointer & resp_queue, player_msghdr * hdr, void * data) +{ + uint32_t idle_width, idle_height, u, v; + player_blobfinder_data_t * bdata; + player_dio_data_t ddata; + player_ptz_cmd_t cmd; + int i, idx; + double dPan, dTilt; + + if (!hdr) + { + PLAYER_ERROR("NULL header"); + return -1; + } + if (Message::MatchMessage(hdr, PLAYER_MSGTYPE_DATA, + PLAYER_BLOBFINDER_DATA_BLOBS, + this->r_blobfinder_addr)) + { + if (!data) + { + PLAYER_ERROR("NULL data"); + return -1; + } + bdata = reinterpret_cast<player_blobfinder_data_t *>(data); + idle_width = static_cast<uint32_t>(static_cast<double>(bdata->width) * (this->idle_area)); + idle_height = static_cast<uint32_t>(static_cast<double>(bdata->height) * (this->idle_area)); + if ((idle_width > 0) && (idle_height > 0) && ((bdata->blobs_count) > 0)) + { + idx = -1; + for (i = 0; i < static_cast<int>(bdata->blobs_count); i++) + { + if ((((bdata->blobs[i].color >> 16) & 0xff) == (this->r)) && (((bdata->blobs[i].color >> 8) & 0xff) == (this->g)) && ((bdata->blobs[i].color & 0xff) == (this->b))) + { + idx = i; + break; + } + } + memset(&ddata, 0, sizeof ddata); + ddata.count = 1; + dPan = 0.0; + dTilt = 0.0; + if (!(idx < 0)) + { + u = (bdata->width - idle_width) / 2; + v = u + idle_width; + if ((bdata->blobs[idx].x) < u) dPan = step; + if (((bdata->blobs[idx].x) >= u) && ((bdata->blobs[idx].x) <= v)) dPan = 0.0; + if ((bdata->blobs[idx].x) > v) dPan = -step; + u = (bdata->height - idle_height) / 2; + v = u + idle_height; + if ((bdata->blobs[idx].y) < u) dTilt = step; + if (((bdata->blobs[idx].y) >= u) && ((bdata->blobs[idx].y) <= v)) dTilt = 0.0; + if ((bdata->blobs[idx].y) > v) dTilt = -step; + ddata.bits = 1; + } else ddata.bits = 0; + this->Publish(this->p_dio_addr, + PLAYER_MSGTYPE_DATA, + PLAYER_DIO_DATA_VALUES, + reinterpret_cast<void *>(&ddata), + 0, NULL, true); // copy = true, do not dispose data placed on local stack! + if ((this->valid_ptz_data) && ((fabs(dPan) > EPS) || (fabs(dTilt) > EPS))) + { + this->valid_ptz_data = false; + memset(&cmd, 0, sizeof cmd); + cmd.pan = this->ptz_data.pan + dPan; + cmd.tilt = this->ptz_data.tilt + dTilt; + if (this->zoom < 0.0) cmd.zoom = this->ptz_data.zoom; + else cmd.zoom = this->zoom; + cmd.panspeed = this->pan_speed; + cmd.tiltspeed = this->tilt_speed; + this->r_ptz_dev->PutMsg(this->InQueue, PLAYER_MSGTYPE_CMD, PLAYER_PTZ_CMD_STATE, reinterpret_cast<void *>(&cmd), 0, NULL); + } + } + return 0; + } + if (Message::MatchMessage(hdr, PLAYER_MSGTYPE_DATA, + PLAYER_PTZ_DATA_STATE, + this->r_ptz_addr)) + { + if (!data) + { + PLAYER_ERROR("NULL data"); + return -1; + } + this->ptz_data = *(reinterpret_cast<player_ptz_data *>(data)); + this->valid_ptz_data = true; + return 0; + } + return -1; +} + +// A factory creation function, declared outside of the class so that it +// can be invoked without any object context (alternatively, you can +// declare it static in the class). In this function, we create and return +// (as a generic Driver*) a pointer to a new instance of this driver. +Driver * Blobtracker_Init(ConfigFile * cf, int section) +{ + // Create and return a new instance of this driver + return reinterpret_cast<Driver *>(new Blobtracker(cf, section)); +} + +// A driver registration function, again declared outside of the class so +// that it can be invoked without object context. In this function, we add +// the driver into the given driver table, indicating which interface the +// driver can support and how to create a driver instance. +void blobtracker_Register(DriverTable * table) +{ + table->AddDriver("blobtracker", Blobtracker_Init); +} This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. ------------------------------------------------------------------------------ Let Crystal Reports handle the reporting - Free Crystal Reports 2008 30-Day trial. Simplify your report design, integration and deployment - and focus on what you do best, core application coding. Discover what's new with Crystal Reports now. http://p.sf.net/sfu/bobj-july _______________________________________________ Playerstage-commit mailing list Playerstage-commit@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/playerstage-commit