Main Page | Namespace List | Class Hierarchy | Alphabetical List | Compound List | File List | Compound Members | File Members

Direction3.cc

Go to the documentation of this file.
00001 /*
00002 
00003     Spectrum based direction server
00004     Copyright (C) 2000-2002 Jussi Laako
00005 
00006     This program is free software; you can redistribute it and/or modify
00007     it under the terms of the GNU General Public License as published by
00008     the Free Software Foundation; either version 2 of the License, or
00009     (at your option) any later version.
00010 
00011     This program is distributed in the hope that it will be useful,
00012     but WITHOUT ANY WARRANTY; without even the implied warranty of
00013     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014     GNU General Public License for more details.
00015 
00016     You should have received a copy of the GNU General Public License
00017     along with this program; if not, write to the Free Software
00018     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00019 
00020 */
00021 
00022 
00023 #include <stdio.h>
00024 #include <signal.h>
00025 #include <unistd.h>
00026 #include <sys/time.h>
00027 
00028 #include <Alloc.hh>
00029 
00030 #include "Direction3.hh"
00031 
00032 
00033 static bool bDebug;
00034 static bool bDaemon;
00035 clDirection3 *Direction3;
00036 
00037 
00038 void SigHandler (int iSigNum)
00039 {
00040     switch (iSigNum)
00041     {
00042         case SIGSEGV:
00043             if (bDebug)
00044             {
00045                 printf("Oops, received SIGSEGV, crash...\n");
00046                 abort();
00047             }
00048             else exit(-1);
00049             break;
00050     }
00051 }
00052 
00053 
00054 int main (int argc, char *argv[])
00055 {
00056     int iRetVal;
00057 
00058     bDebug = false;
00059     bDaemon = false;
00060     signal(SIGPIPE, SIG_IGN);
00061     signal(SIGFPE, SIG_IGN);
00062     signal(SIGSEGV, SigHandler);
00063     if (argc >= 2)
00064     {
00065         if (strcmp(argv[1], "--debug") == 0)
00066         {
00067             bDebug = true;
00068         }
00069         if (strcmp(argv[1], "-D") == 0)
00070         {
00071             bDaemon = true;
00072         }
00073     }
00074     if (bDebug) printf("direction3: Started\n");
00075     Direction3 = new clDirection3(3, 4);
00076     iRetVal = Direction3->Main();
00077     delete Direction3;
00078     if (bDebug) printf("direction3: Exit = %i\n", iRetVal);
00079     return iRetVal;
00080 }
00081 
00082 
00083 bool clDirection3::GetCfg ()
00084 {
00085     Cfg.SetFileName(SD_CFGFILE);
00086     if (!Cfg.GetStr("LocalSocket", cpStreamSocket)) return false;
00087     Cfg.SetFileName(DIR3_CFGFILE);
00088     if (!Cfg.GetInt("ArrayType", &iArrayType)) return false;
00089     if (!Cfg.GetInt("SensorCount", &lSensorCount)) return false;
00090     if (!Cfg.GetFlt("SensorSpacing", &fSensorSpacing)) return false;
00091     if (!Cfg.GetInt("FilterSize", &lFilterSize))
00092         lFilterSize = DIR3_DEF_FILT_SIZE;
00093     /*if (!Cfg.GetInt("WindowSize", &lWindowSize))
00094         lWindowSize = DIR3_DEF_FFT_SIZE;*/
00095     if (!Cfg.GetInt("StartChannel", &lStartChannel))
00096         lStartChannel = 0l;
00097     if (!Cfg.GetInt("FilterType", &iFilterType))
00098         iFilterType = clRecDecimator::FILTER_TYPE_FFT;
00099     return true;
00100 }
00101 
00102 
00103 bool clDirection3::GetRq ()
00104 {
00105     char cpMsgBuf[GLOBAL_HEADER_LEN];
00106 
00107     if (!SOpRequest.ReadSelect(DIR3_REQ_TIMEOUT)) return false;
00108     if (SOpRequest.ReadN(cpMsgBuf, GLOBAL_HEADER_LEN) != GLOBAL_HEADER_LEN)
00109         return false;
00110     Msg.GetRequest(cpMsgBuf, &sReq);
00111     return true;
00112 }
00113 
00114 
00115 bool clDirection3::ConnectStream ()
00116 {
00117     int iSockH;
00118     stRawDataReq sDataReq;
00119 
00120     iSockH = SClient.Connect(cpStreamSocket);
00121     if (iSockH < 0) return false;
00122     SOpData.SetHandle(iSockH);
00123     if (!SOpData.ReadSelect(DIR3_RAW1ST_TIMEOUT)) return false;
00124     if (SOpData.ReadN(&sRawHdr, sizeof(sRawHdr)) < (int) sizeof(sRawHdr))
00125         return false;
00126     sDataReq.iChannel = -1;
00127     if (SOpData.WriteN(&sDataReq, sizeof(sDataReq)) < (int) sizeof(sDataReq))
00128         return false;
00129     return true;
00130 }
00131 
00132 
00133 bool clDirection3::InitDir ()
00134 {
00135     if (bDebug) printf("direction3: Initializing spectrum algorithm\n");
00136     switch (iArrayType)
00137     {
00138         case DIR3_ARRAY_TYPE_DIPOLE:
00139             if (bDebug) 
00140                 printf("direction3: Dipole array\n");
00141             SDDipole = new clSpectDirDipole2(fSensorSpacing, sReq.fSoundSpeed,
00142                 sRawHdr.dSampleRate, lFilterSize, iFilterType, 
00143                 sReq.lWindowSize, sReq.fIntegrationTime, bDebug);
00144             break;
00145         case DIR3_ARRAY_TYPE_TRIANGLE:
00146             if (bDebug)
00147                 printf("direction3: Triangular array not supported yet\n");
00148             break;
00149         case DIR3_ARRAY_TYPE_LINE:
00150             if (bDebug)
00151                 printf("direction3: Line array\n");
00152             SDLine = new clSpectDirLine2(lSensorCount, fSensorSpacing,
00153                 sReq.fSoundSpeed, sRawHdr.dSampleRate, lFilterSize, iFilterType,
00154                 sReq.lWindowSize, sReq.fIntegrationTime, bDebug);
00155             break;
00156         case DIR3_ARRAY_TYPE_PLANE:
00157             if (bDebug)
00158                 printf("direction3: Planar array not supported yet\n");
00159             break;
00160         case DIR3_ARRAY_TYPE_CYLINDER:
00161             if (bDebug)
00162                 printf("direction3: Cylindral array not supported yet\n");
00163             break;
00164         case DIR3_ARRAY_TYPE_SPHERE:
00165             if (bDebug)
00166                 printf("direction3: Spherical array not supported yet\n");
00167             break;
00168         default:
00169             if (bDebug)
00170                 printf("direction3: Unknown array type\n");
00171     }
00172     if (bDebug)
00173     {
00174         switch (iFilterType)
00175         {
00176             case clRecDecimator::FILTER_TYPE_FFT:
00177                 puts("direction3: Using FFT filter");
00178                 break;
00179             case clRecDecimator::FILTER_TYPE_FIR:
00180                 puts("direction3: Using FIR filter");
00181                 break;
00182             case clRecDecimator::FILTER_TYPE_IIR:
00183                 puts("direction3: Using IIR filter");
00184                 break;
00185         }
00186     }
00187     return true;
00188 }
00189 
00190 
00191 void clDirection3::ProcessLoop ()
00192 {
00193     int iInSize;
00194     int iResSize = 0;
00195     int iMsgSize;
00196     long lTotalSamples;
00197     char *cpMsgBuf;
00198     GDT *fpProcData;
00199     stSpectDir2RN sRemoveNoise;
00200     clAlloc ProcBuf;
00201     clAlloc MsgBuf;
00202 
00203     lTotalSamples = abs(lFilterSize) / 2 * sRawHdr.iChannels;
00204     iInSize = lTotalSamples * sizeof(GDT);
00205     switch (iArrayType)
00206     {
00207         case DIR3_ARRAY_TYPE_DIPOLE:
00208             iResSize = SDDipole->GetResultCount() * sizeof(GDT);
00209             break;
00210         case DIR3_ARRAY_TYPE_TRIANGLE:
00211             break;
00212         case DIR3_ARRAY_TYPE_LINE:
00213             iResSize = SDLine->GetResultCount() * sizeof(GDT);
00214             break;
00215         case DIR3_ARRAY_TYPE_PLANE:
00216         case DIR3_ARRAY_TYPE_CYLINDER:
00217         case DIR3_ARRAY_TYPE_SPHERE:
00218             break;
00219     }
00220     iMsgSize = GLOBAL_HEADER_LEN + iResSize * 2;
00221     sRemoveNoise.iType = sReq.iRemoveNoise;
00222     sRemoveNoise.fAlpha = sReq.fAlpha;
00223     sRemoveNoise.lMeanLength = sReq.lMeanLength;
00224     sRemoveNoise.lGapLength = sReq.lGapLength;
00225     fpProcData = (GDT *) ProcBuf.Size(lTotalSamples * sizeof(GDT));
00226     cpMsgBuf = (char *) MsgBuf.Size(iMsgSize);
00227     SOpData.SetRecvBufSize(iInSize * 3);
00228     SOpResult.SetSendBufSize(iMsgSize * 3);
00229     if (bDebug) printf("direction3: Buffer size %i/%i bytes\n", 
00230         iInSize * 3, iMsgSize * 3);
00231     if (bDebug) printf("direction3: Entering processing loop\n");
00232     while (bRun)
00233     {
00234         if (SOpData.ReadN(fpProcData, iInSize) != iInSize) return;
00235         gettimeofday(&sResHdr.sTimeStamp, NULL);
00236         sResHdr.fPeakLevel = DSP.PeakLevel(fpProcData, lTotalSamples);
00237         switch (iArrayType)
00238         {
00239             case DIR3_ARRAY_TYPE_DIPOLE:
00240                 SDDipole->PutData(fpProcData, lTotalSamples, lStartChannel,
00241                     sRawHdr.iChannels);
00242                 while (SDDipole->GetResults(NULL, NULL, sReq.fLowFreqLimit,
00243                     sReq.iScaling, &sRemoveNoise) && bRun)
00244                 {
00245                     sResHdr.lMinBin = SDDipole->GetMinBin();
00246                     sResHdr.lMaxBin = SDDipole->GetMaxBin();
00247                     sResHdr.fFreqResolution = SDDipole->GetFreqResolution();
00248                     sResHdr.lResultCount = SDDipole->GetResultCount();
00249                     sResHdr.fIntegrationTime = SDDipole->GetIntegrationTime();
00250                     Msg.SetResult(cpMsgBuf, &sResHdr, SDDipole->GetLevels(),
00251                         SDDipole->GetDirections());
00252                     if (SOpResult.WriteN(cpMsgBuf, iMsgSize) != iMsgSize) 
00253                         return;
00254                 }
00255                 break;
00256             case DIR3_ARRAY_TYPE_TRIANGLE:
00257                 break;
00258             case DIR3_ARRAY_TYPE_LINE:
00259                 SDLine->PutData(fpProcData, lTotalSamples, lStartChannel,
00260                     sRawHdr.iChannels);
00261                 while (SDLine->GetResults(NULL, NULL, sReq.fLowFreqLimit,
00262                     sReq.iScaling, &sRemoveNoise) && bRun)
00263                 {
00264                     sResHdr.lMinBin = SDLine->GetMinBin();
00265                     sResHdr.lMaxBin = SDLine->GetMaxBin();
00266                     sResHdr.fFreqResolution = SDLine->GetFreqResolution();
00267                     sResHdr.lResultCount = SDLine->GetResultCount();
00268                     sResHdr.fIntegrationTime = SDLine->GetIntegrationTime();
00269                     Msg.SetResult(cpMsgBuf, &sResHdr, SDLine->GetLevels(),
00270                         SDLine->GetDirections());
00271                     if (SOpResult.WriteN(cpMsgBuf, iMsgSize) != iMsgSize)
00272                         return;
00273                 }
00274                 break;
00275             case DIR3_ARRAY_TYPE_PLANE:
00276             case DIR3_ARRAY_TYPE_CYLINDER:
00277             case DIR3_ARRAY_TYPE_SPHERE:
00278                 break;
00279         }
00280     }
00281 }
00282 
00283 
00284 clDirection3::clDirection3 (int iInHandle, int iOutHandle)
00285 {
00286     bRun = true;
00287     SOpRequest.SetHandle(iInHandle);
00288     SOpResult.SetHandle(iOutHandle);
00289 }
00290 
00291 
00292 clDirection3::~clDirection3 ()
00293 {
00294 }
00295 
00296 
00297 int clDirection3::Main ()
00298 {
00299     if (!GetCfg())
00300     {
00301         if (bDebug) printf("direction3: Error reading configuration\n");
00302         return 1;
00303     }
00304     if (!GetRq())
00305     {
00306         if (bDebug) printf("direction3: Unable to receive request message\n");
00307         return 1;
00308     }
00309     if (!ConnectStream())
00310     {
00311         if (bDebug) printf("direction3: Unable to connect to streamdist\n");
00312         return 1;
00313     }
00314     if (!InitDir())
00315     {
00316         if (bDebug) 
00317             printf("direction3: Direction finding initialization failed\n");
00318         return 1;
00319     }
00320     ProcessLoop();
00321     return 0;
00322 }
00323 

Generated on Sun Oct 26 19:11:19 2003 for HASAS by doxygen 1.3.3