OpenTracker

An Open Architecture for Reconfigurable Tracking based on XML | Contact

GPSDriver.cxx

Go to the documentation of this file.
00001 /* ========================================================================
00002  * Copyright (c) 2006,
00003  * Institute for Computer Graphics and Vision
00004  * Graz University of Technology
00005  * All rights reserved.
00006  *
00007  * Redistribution and use in source and binary forms, with or without
00008  * modification, are permitted provided that the following conditions are
00009  * met:
00010  *
00011  * Redistributions of source code must retain the above copyright notice,
00012  * this list of conditions and the following disclaimer.
00013  *
00014  * Redistributions in binary form must reproduce the above copyright
00015  * notice, this list of conditions and the following disclaimer in the
00016  * documentation and/or other materials provided with the distribution.
00017  *
00018  * Neither the name of the Graz University of Technology nor the names of
00019  * its contributors may be used to endorse or promote products derived from
00020  * this software without specific prior written permission.
00021  *
00022  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
00023  * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
00024  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
00025  * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
00026  * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
00027  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
00028  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
00029  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
00030  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
00031  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
00032  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00033  * ========================================================================
00034  * PROJECT: OpenTracker
00035  * ======================================================================== */
00043 /* ======================================================================= */
00044 
00045 
00046 // required for WinCE to make sure time_t is 32-bits !!!
00047 // crappy WinCE SDK defines 32-bit version AND 64-bit version,
00048 // while ACE expects the 32-bits version...
00049 #include <stdlib.h>
00050 
00051 // this will remove the warning 4786
00052 #include "../tool/disable4786.h"
00053 #include <cstdlib>
00054 
00055 #include "../OpenTracker.h"
00056 #include "../tool/FixWinCE.h"
00057 #include <ace/Reactor.h>
00058 #include <iostream>
00059 #include <algorithm>
00060 #include <memory>
00061 
00062 #include "GPSDriver.h"
00063 #include "GPS_Handler.h"
00064 #include "DGPSIP_Handler.h"
00065 #include "DGPSMirror_Handler.h"
00066 
00067 #include <ace/Log_Msg.h>
00068 #include "../tool/OT_ACE_Log.h"
00069 
00070 
00071 #ifndef OT_NO_GPS_SUPPORT
00072 
00073 
00074 namespace ot {
00075 
00076     GPSDriver::GPSDriver(ACE_Reactor * reactor_) :
00077         reactor( reactor_ ),
00078         receiver( NULL ),
00079         server( NULL ),
00080         acceptor( NULL ),
00081         rtcmdev( NULL ),
00082         fix( false )
00083     {
00084     if( NULL == reactor )
00085             reactor = ACE_Reactor::instance();
00086     }
00087 
00088     GPSDriver::~GPSDriver()
00089     {
00090     if( receiver != NULL )
00091             close();
00092     listeners.clear();
00093         std::vector<DGPSMirror_Handler *>::reverse_iterator it = clients.rbegin();
00094         while( it != clients.rend())
00095         {
00096             (*it)->destroy();
00097             it++;
00098         }
00099         clients.clear();
00100     }
00101 
00102     int GPSDriver::open( const std::string & device, int baud, const std::string & serveraddr, int port, int dgpsmirror, const std::string & rtcmdev )
00103     {
00104         if( getDebug())
00105             ACE_DEBUG((LM_INFO, ACE_TEXT("ot:GPSDriver open\n")));
00106 
00107     int result;
00108     // open the serial port the the GPS receiver
00109     receiver = new GPS_Handler( this );
00110     GPS_Connector gpsconnect( reactor );
00111     result = gpsconnect.connect( receiver, ACE_DEV_Addr(ACE_TEXT_CHAR_TO_TCHAR(device.c_str())));
00112     if( result == 0)
00113     {
00114             // set the appropriate parameters
00115             ACE_TTY_IO::Serial_Params params;       
00116             result = receiver->peer().control( ACE_TTY_IO::GETPARAMS, &params);
00117             params.baudrate = baud;
00118             params.databits = 8;
00119             params.stopbits = 1;
00120             params.parityenb = 0;
00121             params.ctsenb = 0;
00122             params.rcvenb = 1;
00123             params.rtsenb = 1;
00124             params.dsrenb = 0;
00125             result = receiver->peer().control(ACE_TTY_IO::SETPARAMS, &params );
00126             if( result != 0 )
00127             {
00128                 receiver = NULL;
00129                 //std::cerr << "GPSDriver could not open serial port " << device << " !\n";
00130                 ACE_DEBUG((LM_ERROR, ACE_TEXT("ot:GPSDriver could not open serial port %s\n"), device.c_str()));
00131             }
00132     }
00133         if( getDebug())
00134             ACE_DEBUG((LM_INFO, ACE_TEXT("ot:GPSDriver opened serial port %s\n"), device.c_str()));
00135     
00136     // open the tcp connection to the server, if required
00137     if( result == 0 && serveraddr.compare("") != 0 )
00138     {
00139             server = new DGPSIP_Handler( this );
00140             DGPSIP_Connector ipconnect( reactor );
00141             if( ipconnect.connect( server, ACE_INET_Addr( port, serveraddr.c_str() )) != 0 )
00142             {
00143                 server = NULL;
00144                 LOG_ACE_ERROR("ot:GPSDriver could not open connection to DGPS server %s port %d\n", serveraddr.c_str(), port);
00145             }
00146             if( getDebug())
00147             {
00148                 LOG_ACE_INFO("ot:GPSDriver opened connection to %s\n", serveraddr.c_str());
00149             }
00150     }
00151 
00152         // open a mirror if we have a DGPS handler
00153         if( server != NULL && dgpsmirror != -1)
00154         {
00155             acceptor = new DGPSMirror_Acceptor( this );
00156             if( acceptor->open( ACE_INET_Addr( dgpsmirror) , reactor ) != 0 )
00157             {
00158                 delete acceptor;
00159                 acceptor = NULL;
00160                 ACE_DEBUG((LM_ERROR, ACE_TEXT("ot:GPSDriver could not open DGPS mirror server on port %d\n"), dgpsmirror));
00161             }
00162             if( getDebug())
00163                 ACE_DEBUG((LM_INFO, ACE_TEXT("ot:GPSDriver opened mirror listener.\n")));
00164         }
00165 
00166         // open a dedicated serial port for RTCM output, if we have one
00167         // it assumes the same baud rate as the serial port
00168         if( rtcmdev.compare("") != 0)
00169         {
00170             this->rtcmdev = new ACE_TTY_IO;
00171             ACE_DEV_Connector connector( *this->rtcmdev, ACE_DEV_Addr(ACE_TEXT_CHAR_TO_TCHAR(rtcmdev.c_str())));
00172             // set the appropriate parameters
00173             ACE_TTY_IO::Serial_Params params;       
00174             result = this->rtcmdev->control( ACE_TTY_IO::GETPARAMS, &params);
00175             params.baudrate = baud;
00176             params.databits = 8;
00177             params.stopbits = 1;
00178             params.parityenb = 0;
00179             params.ctsenb = 0;
00180             params.rcvenb = 1;
00181             params.rtsenb = 1;
00182             params.dsrenb = 0;
00183             result = this->rtcmdev->control(ACE_TTY_IO::SETPARAMS, &params );           
00184             if( result != 0 )
00185             {
00186                 delete this->rtcmdev;
00187                 this->rtcmdev = NULL;
00188                 LOG_ACE_ERROR("ot:GPSDriver could not open serial port %s.\n", rtcmdev.c_str());
00189             }
00190             if( getDebug())
00191             {
00192                 LOG_ACE_INFO("ot:GPSDriver opened serial port %s\n", rtcmdev.c_str());
00193             }
00194         }    
00195     return result;
00196     }
00197 
00198     void GPSDriver::close()
00199     {
00200     if( server != NULL )
00201     {
00202             server->destroy();
00203             server = NULL;
00204     }
00205     if( receiver != NULL )
00206     {
00207             receiver->destroy();
00208             receiver = NULL;
00209     }
00210         if( acceptor != NULL )
00211         {
00212             delete acceptor;
00213             acceptor = NULL;
00214         }
00215         if( rtcmdev != NULL )
00216         {
00217             delete rtcmdev;
00218             rtcmdev = NULL;
00219         }    
00220     }
00221 
00222     void GPSDriver::addListener( GPSListener * listener, void * userData )
00223     {
00224     listeners[listener] = userData;
00225     }
00226 
00227     void GPSDriver::removeListener( GPSListener * listener, void * userData )
00228     {
00229     std::map<GPSListener *, void *>::iterator it = listeners.find( listener );
00230     if( it != listeners.end())
00231             listeners.erase( listener );
00232     }
00233 
00234     void GPSDriver::addClient( DGPSMirror_Handler * client )
00235     {
00236         if( std::find( clients.begin(), clients.end(), client) == clients.end())
00237             clients.push_back( client );
00238     }
00239 
00240     void GPSDriver::removeClient( DGPSMirror_Handler * client )
00241     {
00242         std::vector<DGPSMirror_Handler *>::iterator it = std::find( clients.begin(), clients.end(), client);
00243         if( it != clients.end())
00244             clients.erase( it );
00245     }
00246 
00247     void GPSDriver::new_line( const char * line )
00248     {
00249     std::auto_ptr<GPResult> result((GPResult *)GPSParser::parse(line));
00250         // for some messages we use some data on the side 
00251         if( result->type == GPResult::GPGGA )
00252         {
00253             fix = (((GPGGA *)result.get())->fix > 0);
00254             hdop = ((GPGGA *)result.get())->hdop;
00255             numsat = ((GPGGA *)result.get())->numsats;
00256         }
00257         std::map<GPSListener *, void *>::iterator it;
00258         for( it = listeners.begin(); it != listeners.end(); it++ )
00259             (*it).first->newData( result.get(), line, (*it).second );
00260     }
00261 
00262     void GPSDriver::send_rtcm( const char * buffer, const int len )
00263     {
00264         if( NULL != this->rtcmdev )
00265         {
00266             ACE_DEBUG((LM_DEBUG, "GPSDriver::send_rtcm send to device\n"));
00267             rtcmdev->send_n( buffer, len );
00268         }
00269     else if( NULL != receiver )
00270         {
00271             ACE_DEBUG((LM_DEBUG, "GPSDriver::send_rtcm send to receiver\n"));
00272             receiver->peer().send_n( buffer, len );
00273         }
00274         std::vector<DGPSMirror_Handler *>::iterator it;
00275         for( it = clients.begin(); it != clients.end(); it ++ )
00276         {
00277             ACE_DEBUG((LM_DEBUG, "GPSDriver::send_rtcm send to peer\n"));
00278             if( (*it)->peer().send_n( buffer, len ) < 0 )
00279             {
00280                 (*it)->destroy();
00281                 it--;
00282             }
00283         }
00284     }
00285 
00286     void GPSDriver::setDebug( bool debug )
00287     {
00288     debugOn = debug;
00289     }
00290 
00291 } // namespace ot
00292 
00293 
00294 #else
00295 #pragma message(">>> OT_NO_GPS_SUPPORT")
00296 #endif // OT_NO_GPS_SUPPORT
00297 
00298 /* 
00299  * ------------------------------------------------------------
00300  *   End of GPSDriver.cxx
00301  * ------------------------------------------------------------
00302  *   Automatic Emacs configuration follows.
00303  *   Local Variables:
00304  *   mode:c++
00305  *   c-basic-offset: 4
00306  *   eval: (c-set-offset 'substatement-open 0)
00307  *   eval: (c-set-offset 'case-label '+)
00308  *   eval: (c-set-offset 'statement 'c-lineup-runin-statements)
00309  *   eval: (setq indent-tabs-mode nil)
00310  *   End:
00311  * ------------------------------------------------------------ 
00312  */

copyright (c) 2006 Graz University of Technology