Merged branch jcorgan/wip into trunk.
authorjcorgan <jcorgan@221aa14e-8319-0410-a670-987f0aec2ac5>
Sun, 3 Sep 2006 23:46:01 +0000 (23:46 +0000)
committerjcorgan <jcorgan@221aa14e-8319-0410-a670-987f0aec2ac5>
Sun, 3 Sep 2006 23:46:01 +0000 (23:46 +0000)
git-svn-id: http://gnuradio.org/svn/gnuradio/trunk@3471 221aa14e-8319-0410-a670-987f0aec2ac5

21 files changed:
config/Makefile.am
config/grc_gr_rdf.m4 [new file with mode: 0644]
configure.ac
ezdop/src/host/ezdop/ezdop.cc
ezdop/src/host/ezdop/ezdop.h
ezdop/src/host/hunter/config/hunter_wx.m4
ezdop/src/host/hunter/configure.ac
ezdop/src/host/hunter/src/Makefile.am
ezdop/src/host/hunter/src/doppler.cc
ezdop/src/host/hunter/src/doppler.h
ezdop/src/host/hunter/src/hunter.cc
ezdop/src/host/hunter/src/search.cc
ezdop/src/host/hunter/src/serial.cc
ezdop/src/host/tests/dopper.cc
gr-ezdop/src/lib/ezdop_source_c.cc
gr-rdf/AUTHORS [new file with mode: 0644]
gr-rdf/Makefile.am [new file with mode: 0644]
gr-rdf/README [new file with mode: 0644]
gr-rdf/src/Makefile.am [new file with mode: 0644]
gr-rdf/src/lib/Makefile.am [new file with mode: 0644]
gr-rdf/src/python/Makefile.am [new file with mode: 0644]

index 571d311dbf4e96f77d888cf40d5fad5a88930025..38a6810c416794754a04e571c1c45e4c2e5e290a 100644 (file)
@@ -46,6 +46,7 @@ m4macros = \
        grc_gr_gsm_fr_vocoder.m4 \
        grc_gr_radar.m4 \
        grc_gr_radio_astronomy.m4 \
+       grc_gr_rdf.m4 \
        grc_gr_trellis.m4 \
        grc_gr_usrp.m4 \
        grc_gr_video_sdl.m4 \
diff --git a/config/grc_gr_rdf.m4 b/config/grc_gr_rdf.m4
new file mode 100644 (file)
index 0000000..aee71b8
--- /dev/null
@@ -0,0 +1,35 @@
+dnl Copyright 2001,2002,2003,2004,2005,2006 Free Software Foundation, Inc.
+dnl 
+dnl This file is part of GNU Radio
+dnl 
+dnl GNU Radio is free software; you can redistribute it and/or modify
+dnl it under the terms of the GNU General Public License as published by
+dnl the Free Software Foundation; either version 2, or (at your option)
+dnl any later version.
+dnl 
+dnl GNU Radio is distributed in the hope that it will be useful,
+dnl but WITHOUT ANY WARRANTY; without even the implied warranty of
+dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+dnl GNU General Public License for more details.
+dnl 
+dnl You should have received a copy of the GNU General Public License
+dnl along with GNU Radio; see the file COPYING.  If not, write to
+dnl the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+dnl Boston, MA 02111-1307, USA.
+
+AC_DEFUN([GRC_GR_RDF],[
+    GRC_ENABLE([gr-rdf])
+
+    AC_CONFIG_FILES([\
+       gr-rdf/Makefile \
+       gr-rdf/src/Makefile \
+       gr-rdf/src/lib/Makefile \
+       gr-rdf/src/python/Makefile \
+    ])
+
+    passed=yes
+    GRC_BUILD_CONDITIONAL([gr-rdf],[
+        dnl run_tests is created from run_tests.in.  Make it executable.
+        dnl AC_CONFIG_COMMANDS([run_tests_rdf], [chmod +x gr-rdf/src/python/run_tests])
+    ])
+])
index add98a53705a5ecd3703d8fec63deb507aca73a9..d35f74b8973280b06e5a19db64cd7fc131f532ab 100644 (file)
@@ -182,6 +182,7 @@ GRC_PMT
 GRC_MBLOCK                     dnl this must come after GRC_PMT
 GRC_EZDOP              
 GRC_GR_EZDOP                   dnl this must come after GRC_EZDOP
+GRC_GR_RDF
 
 # Each component is now either to be built, was skipped, or failed dependencies
 AC_SUBST([build_dirs], [$build_dirs])
index 43a70dacb5738384e42ab62483a62e60e3a31b9b..99997fedf920ab63cdaaf8e5aa161bf2d196e4aa 100644 (file)
@@ -22,6 +22,9 @@
 // Application specific includes
 #include "ezdop.h"
 
+// Boost includes
+#include <boost/scoped_array.hpp>
+
 // System includes (FIXME: autoconf these)
 #include <cassert>
 #include <cstdio>
@@ -219,26 +222,27 @@ int ezdop::read_raw(unsigned char *buffer, unsigned int length)
     return rd;
 }
 
-int ezdop::read_iq(complex<float> *buffer, unsigned int samples)
+typedef boost::scoped_array<unsigned char> unsigned_char_scoped_array;
+
+int ezdop::read_iq(complex<float> *buffer, unsigned int samples, float &volume)
 {
     assert(d_online);
     assert(d_device);
     assert(buffer);
 
     // 4 phases, d_rate samples per phase, 2 bytes per sample
-    int bufsize = 8*d_rate*samples;
-    unsigned char *raw = new unsigned char[bufsize];
+    int raw_size = 8*d_rate*samples;
+    unsigned_char_scoped_array raw(new unsigned char[raw_size]);
 
     // Read until required bytes are read. Will block until bytes arrive.
     int rd = 0;
-    while (rd < bufsize)
-        rd += read_raw(&raw[rd], bufsize-rd);
+    while (rd < raw_size)
+        rd += read_raw(&raw[rd], raw_size-rd);
 
     // Iterate through read bytes and invoke state machine
     int i = 0, j = 0;   // i index inputs, j indexes outputs
-    unsigned char ant;
 
-    while (i < bufsize) {
+    while (i < raw_size) {
         unsigned char ch = raw[i++];
         if (d_state == ST_LO) {
             d_val = ch;                     // Save lo byte
@@ -272,6 +276,7 @@ int ezdop::read_iq(complex<float> *buffer, unsigned int samples)
             d_in_phase -= d_val;
         else if (d_ant == 1)            // -Q
             d_quadrature -= d_val;
+
         d_val = 0;
     
         // Update expected antenna and sequence
@@ -292,6 +297,6 @@ int ezdop::read_iq(complex<float> *buffer, unsigned int samples)
         d_state = ST_LO;  // Switch states
     };
 
-    delete raw;
+    volume = 0.0;
     return j;
 }
index b4ce1a454b91b5d04e01df9c66618da252163fc2..c40178c0bc9cb8b6f46731da28922bf34fe6fd64 100644 (file)
@@ -57,7 +57,7 @@ public:
     int read_raw(unsigned char *buffer, unsigned int length);
 
     // Read synced, downconverted I and Q samples, one per rotation
-    int read_iq(complex<float> *buffer, unsigned int samples);
+    int read_iq(complex<float> *buffer, unsigned int samples, float &volume);
 
     // Status
     bool is_online() const { return d_online; }
index 5d6dd08e7567e21f0a2f11aa3cffe969f79403f2..ffee16a59f3447742af81735cea9a800e8804238 100644 (file)
@@ -4,8 +4,8 @@ AC_DEFUN([HUNTER_WX], [
                AC_MSG_ERROR(["wxWidgets is required, not found, stop."])
        fi
 
-       WX_FLAGS=`$WXCONFIG --cflags`
-       WX_LIBS=`$WXCONFIG --libs`
+       WX_FLAGS=`$WXCONFIG --debug --cflags`
+       WX_LIBS=`$WXCONFIG --debug --libs`
        AC_SUBST(WX_FLAGS)
        AC_SUBST(WX_LIBS)
 ])
index b6bd4cf7eef90c71a77def44f99c6021e6f3caa2..b0af6cba05e81d0ed84b6cd65aeb53a52a1cbcd5 100644 (file)
@@ -32,7 +32,7 @@ AC_CHECK_FUNCS([modf sqrt])
 
 # Application specific checks
 HUNTER_WX
-HUNTER_FTDI
+#HUNTER_FTDI
 
 AC_CONFIG_FILES([ \
     Makefile
index d1fe5eec237ff153704e61a907cba63040a7affd..392b79eff48c0276867e22ba7c296e6f8637c3b9 100644 (file)
@@ -33,10 +33,18 @@ hunter_SOURCES = \
                  spherical.cc \
                  tactical.cc
 
+# FIXME: put in config macro
+EZDOP_LIBS = -L/usr/local/lib -lezdop
+
 hunter_CXXFLAGS = $(WX_FLAGS)
 hunter_LDADD = \
-    $(FTDI_LIBS) \
-    $(WX_LIBS)
+    $(WX_LIBS) \
+    $(EZDOP_LIBS)
+
+BUILT_SOURCES = \
+    $(top_builddir)/src/resource.cc
     
-resource.cc: hunter.xrc
-       wxrc -c -o resource.cc hunter.xrc
+$(top_builddir)/src/resource.cc: hunter.xrc
+       wxrc -c -o $(top_builddir)/src/resource.cc $(top_srcdir)/src/hunter.xrc
+
+MOSTLYCLEANFILES = $(BUILT_SOURCES)
\ No newline at end of file
index 1e7b3cf49a00d09c602bb45ea037ce0684631f9c..99b5aa61649188cb2ad1c0d1ca104108881af4ca 100644 (file)
 #include <wx/log.h>
 #include <wx/frame.h>
 
+// Boost includes
+#include <boost/scoped_array.hpp>
+
 // System level includes
 #include <cmath>
 
+// TODO: read from ezdop.h
 #define SAMPLERATE      8000
-#define QUANTUM         0.2        // Sample period in seconds
 #define MAXSAMPLE       0x3FF      // 12 bit ADC
-
 #define DEFAULT_SELECTED_ROTATION_RATE 2     // 500 Hz until told otherwise
+
+#define QUANTUM         0.2        // Sample period in seconds
 #define DEFAULT_FILTER_LEVEL 20
 
 #define NORMALIZEPHASE(x) \
@@ -80,7 +84,7 @@ ExitCode DopplerBackground::Entry()
 
     m_running = true;
        while (!TestDestroy()) {
-           if (m_doppler->Sample((int)(QUANTUM*SAMPLERATE), in_phase, quadrature, volume)) {
+           if (m_doppler->Sample(in_phase, quadrature, volume)) {
            EZDopplerUpdate update(wxEVT_DOPPLER_UPDATE, in_phase, quadrature, volume);
                wxPostEvent(m_dest, update);
         }
@@ -93,209 +97,66 @@ EZDoppler::EZDoppler(wxWindow *gui)
     wxASSERT(gui);
 
     m_thread = NULL;
-    m_online = false;
-    m_selected_rate = DEFAULT_SELECTED_ROTATION_RATE;
     m_gui = gui;
-    m_in_phase = 0.0;
-    m_quadrature = 0.0;
-    m_alpha = 1.0/(DEFAULT_FILTER_LEVEL*200);
-    m_beta = 1.0-m_alpha;
-    m_phase = 0.0;
+
+    m_phase = complex<float>(0.0, 0.0);
+    m_output = complex<float>(0.0, 0.0);
+    m_alpha = complex<float>(0.0, 0.0);
+    m_beta = complex<float>(0.0, 0.0);
+
     m_offset = 0.0;
+    m_angle = 0.0;
         
     for(int i = 0; i < NUM_RATES; i++) 
         m_calibration[i] = 0.0;
     
-#if HAVE_LIBFTDI
-       m_device = new struct ftdi_context;
-       wxASSERT(m_device);
-       if (ftdi_init(m_device)) {
-           wxLogWarning(_T("ftdi_init: %s"), m_device->error_str);
-           return;
-    }
-#endif
-
+    m_ezdop = ezdop_sptr(new ezdop());
+    m_selected_rate = DEFAULT_SELECTED_ROTATION_RATE;
 }
 
 EZDoppler::~EZDoppler()
 {
-    if (m_online) {
+    if (m_ezdop->is_online()) {
         wxLogMessage(_T("EZDoppler::~EZDoppler(): doppler still online in destructor, finalizing"));
         Finalize();
     }
-#if HAVE_LIBFTDI
-    wxASSERT(m_device);
-       ftdi_deinit(m_device);
-       delete m_device;
-#endif
 }
 
 bool EZDoppler::Initialize()
 {
-    m_online = false;
-    
-#if HAVE_LIBFTDI
-       if (ftdi_usb_open(m_device, EZDOP_VENDORID, EZDOP_PRODUCTID)) {
-               wxLogDebug(_T("ftdi_usb_open: %s"), m_device->error_str);
-               return false;
-       }
-#elif HAVE_LIBFTD2XX
-    if ((m_status = FT_Open(0, &m_handle)) != FT_OK) {
-               wxLogError(_T("FT_Open failed: %i"), m_status);
-               return false;
-       }
-#endif
-
-    m_online = true;
-    if (m_online)
+    m_ezdop->init();
+    if (m_ezdop->is_online())
         Reset();
 
-    return m_online;
- }
+    return m_ezdop->is_online();
+}
 
 bool EZDoppler::Finalize()
 {
-    if (!m_online)
-        return true;
-
     if (m_thread && m_thread->IsRunning()) {
         wxLogDebug(_T("EZDoppler::Finalize: finalizing a running doppler"));
         Stop();
     }
-
-#if HAVE_LIBFTDI
-       if (ftdi_usb_close(m_device)) {
-           wxLogWarning(_T("ftdi_usb_close: %s"), m_device->error_str);
-           return false;
-       }
-#elif HAVE_LIBFTD2XX
-    if ((m_status = FT_Close(m_handle)) != FT_OK) {
-               wxLogWarning(_T("FT_Close failed: %i"), m_status);
-               return false;
-       }
-#endif
-
-    m_online = false;
-    return true;
 }
 
 bool EZDoppler::IsOnline()
 {
-    return m_online;
-}
-
-bool EZDoppler::send_byte(unsigned char data)
-{
-    wxASSERT(m_online);
-#if HAVE_LIBFTDI       
-    if (ftdi_write_data(m_device, &data, 1) != 1) {
-        wxLogWarning(_T("ftdi_write_data: %s"), m_device->error_str);
-        return false;
-    }
-#elif HAVE_LIBFTD2XX
-    DWORD written;
-    if ((m_status = FT_Write(m_handle, &data, 1, &written)) != FT_OK || written != 1) {
-        wxLogError(_T("FT_Write failed: %i"), m_status);
-               return false;
-       }
-#endif
-       return true;    
+    return m_ezdop->is_online();
 }
 
 bool EZDoppler::Reset()
 {
-    wxASSERT(m_online);
-
     if (m_thread && m_thread->IsRunning()) {
         wxLogDebug(_T("EZDoppler::Reset: resetting running doppler"));
         Stop();
     }
 
-
-    // Reset FTDI chipset
-#if HAVE_LIBFTDI
-       if (ftdi_usb_reset(m_device)) {
-           wxLogWarning(_T("ftdi_usb_reset: %s"), m_device->error_str);
-           return false;
-    }
-#elif HAVE_LIBFTD2XX
-       if ((m_status = FT_ResetDevice(m_handle) != FT_OK)) {
-               wxLogError(_T("FT_ResetDevice failed: %i"), m_status);
-               return false;
-       }
-#endif
-
-    // Set FTDI chipset baudrate for bitbang
-#if HAVE_LIBFTDI
-       if (ftdi_set_baudrate(m_device, EZDOP_BAUDRATE)) {
-           wxLogWarning(_T("ftdi_set_baudrate: %s"), m_device->error_str);
-           return false;
-    }
-#elif HAVE_LIBFTD2XX
-       if ((m_status = FT_SetBaudRate(m_handle, EZDOP_BAUDRATE)) != FT_OK) {
-               wxLogError(_T("FT_SetBaudRate failed: %i"), m_status);
-               return false;
-       }
-#endif
-
-    // Toggle DTR (-->AVR RESET)
-#if HAVE_LIBFTDI
-    // Enable bitbang
-       if (ftdi_enable_bitbang(m_device, EZDOP_BBDIR)) {
-           wxLogWarning(_T("ftdi_enable_bitbang: %s"), m_device->error_str);
-               return false;
-       }
-
-       // Lower DTR by writing 0 to bitbang output
-       if (!send_byte(0x00)) // HMMM: this actually lowers all outputs, of course
-           return false;
-#elif HAVE_LIBFTD2XX
-       // Set DTR line (goes low) to reset AVR and delay
-       if ((m_status = FT_SetDtr(m_handle)) != FT_OK) {
-               wxLogError(_T("FT_SetDtr failed: %i"), m_status);
-               return false;
-       }
-#endif
-
-    // 10 ms sleep with RESET low
-    wxMilliSleep(10); 
-
-#if HAVE_LIBFTDI
-       // Now raise DTR by writing 1 to bitbang output
-       if (!send_byte(0xFF))
-           return false;
-
-       if (ftdi_disable_bitbang(m_device)) {
-           wxLogWarning(_T("ftdi_disable_bitbang: %s"), m_device->error_str);
-               return false;
-       }
-       
-       // Minimum chunk size for reads to reduce latency
-       if (ftdi_read_data_set_chunksize(m_device, 256)) {
-           wxLogWarning(_T("ftdi_read_data_set_chunksize: %s"), m_device->error_str);
-               return false;
-       }
-#elif HAVE_LIBFTD2XX
-    if ((m_status = FT_ClrDtr(m_handle)) != FT_OK) {
-               wxLogError(_T("FT_ClrDtr failed: %i"), m_status);
-               return false;
-       }
-#endif
-
-    // 100 ms after RESET cleared to let things warm up
-    wxMilliSleep(100);
-
-    m_selected_rate = DEFAULT_SELECTED_ROTATION_RATE;
-
-    return true;
+    return m_ezdop->reset();
 }
 
 bool EZDoppler::Start()
 {
-    wxASSERT(m_online);
-    // TODO: flush stream data
-
-    if (!send_byte(EZDOP_CMD_ROTATE) || !send_byte(EZDOP_CMD_STREAM))
+    if (!(m_ezdop->rotate() && m_ezdop->stream()))
         return false;
         
     m_thread = new DopplerBackground(m_gui, this);
@@ -304,9 +165,6 @@ bool EZDoppler::Start()
 
 bool EZDoppler::Stop()
 {
-    wxASSERT(m_online);
-    // TODO: flush stream data
-
     if (m_thread && m_thread->IsRunning()) {
         m_thread->Delete();
         while (m_thread->IsRunning()) {
@@ -315,172 +173,85 @@ bool EZDoppler::Stop()
     }
     
     m_thread = NULL;
-    return (send_byte(EZDOP_CMD_STROFF) && send_byte(EZDOP_CMD_STOP));
+    return (m_ezdop->stop_streaming() && m_ezdop->stop_rotating());
 }
 
 bool EZDoppler::SelectRotationRate(int n)
 {
-    wxASSERT(m_online);
     wxASSERT(n >= 0 && n < 6);
-
-    unsigned char rate = rotation_rates[n];
-    if (send_byte(EZDOP_CMD_RATE) && send_byte(rate)) {
-        m_selected_rate = n;
-        m_in_phase = 0.0;
-        m_quadrature = 0.0;
-        return true;
-    }
-    
-    return false;
+    wxLogDebug(_T("EZDoppler::SelectRotationRate: %i %i"), n, (int)(2000/rotation_rates[n]));
+    m_selected_rate = n;
+    return m_ezdop->set_rate(2000/rotation_rates[n]);
 }
 
-int EZDoppler::GetSelectedRotationRate()
+int EZDoppler::GetRotationRate()
 {
     return m_selected_rate;
 }
 
-bool EZDoppler::Zero()
-{
-    return true;
-}
-
 bool EZDoppler::SetFilter(int n)
 {
-    wxASSERT(n > 0);
-    m_alpha = 1.0/(n*200); // Time constant is filter value divided by 5 (empirically determined)
-    m_beta = 1.0-m_alpha;
+    float beta = 30.0/(n*m_ezdop->rate()); // Empirically determined
+
+    m_alpha = complex<float>(1.0-beta, 0.0);
+    m_beta = complex<float>(beta, 0.0);
+
     return true;
 }
 
-bool EZDoppler::Sample(int nsamples, float &in_phase, float &quadrature, float &volume)
+typedef boost::scoped_array<complex<float> > complexf_scoped_array;
+
+// IQ is 2 complex floats, maximum rate is 2000, QUANTUM is period in seconds
+complex<float> buffer[(int)(2*QUANTUM*2000)];
+
+bool EZDoppler::Sample(float &in_phase, float &quadrature, float &volume)
 {
-    unsigned short *audio = new unsigned short[nsamples*2];
-    unsigned char *antenna = new unsigned char[nsamples];
-    
-    unsigned int rd;
-    unsigned int count = 0;
-    
-    // Read samples from USB port, 2 bytes per sample
-    while (count < nsamples*2) {
-        unsigned int amt = nsamples*2-count;
-        unsigned char *ptr = (unsigned char *)&audio[count/2]; // if count is odd, causes frame slip?
-        if ((count/2)*2 != count)
-            wxLogDebug(_T("EZDoppler::Sample: count is odd (%i)"), count);
-#if HAVE_LIBFTDI
-        rd = ftdi_read_data(m_device, ptr, amt);
-        if (rd < 0) {
-            wxLogWarning(_T("ftdi_read_data: %s"), m_device->error_str);
-            return false; // FIXME: memory leak for antenna and audio!
-        }
-        count += rd;
-#elif HAVE_LIBFTD2XX
-        DWORD num;
-        FT_STATUS status = FT_Read(m_handle, ptr, amt, &num);
-        if (status != FT_OK) {
-            wxLogWarning(_T("FT_Read: %i"), status);
-            return false; // FIXME: memory leak for antenna and audio!
-        }
-        count += num;
-#endif        
-    }    
-    
-    // Extract antenna array position from samples, flag unsynced if not a valid antenna value
-    bool sync = true;
-    for (int i = 0; i < nsamples; i++) {
-        unsigned char ant = (audio[i] & 0xF000) >> 12;
-        if (ant != 8 && ant != 4 && ant != 2 && ant != 1)
-            sync = false;
-        antenna[i] = ant;
-        audio[i] &= 0x03FF;
-    }
-            
-    // If not synced, throw away a byte in receive stream to resync
-    unsigned char dummy;
-    if (!sync) {
-        wxLogDebug(_T("EZDoppler::Sample: sync failure detected"));
-#if HAVE_LIBFTDI
-        ftdi_read_data(m_device, &dummy, 1);
-#elif HAVE_LIBFTD2XX
-        DWORD rd;
-        FT_Read(m_handle, &dummy, 1, &rd);
-#endif            
-        return false; // FIXME: memory leak for antenna and audio!
-    }
+    int nsamples = (int)(m_ezdop->rate()*QUANTUM);
 
-    // Calculate DC offset and max and min values
-    float sum = 0.0;
-    float mean = 0.0;
-    for (int i = 0; i < nsamples; i++)
-        sum += audio[i];
-    mean = sum/nsamples;
-
-    // Calculate doppler response
-    unsigned char ant;
-    float sample;
-    volume = 0.0;
-    for (int i = 0; i < nsamples; i++) {
-        ant = antenna[i];
-
-        // Subtract DC offset and scale to -1 to 1
-        sample = 2*(((float)audio[i])-mean)/MAXSAMPLE;
-
-        // Calculate peak volume
-        if (fabs(sample) > volume)
-            volume = fabs(sample);
-
-        // Integrate and lowpass filter sample into I/Q based on which antenna is selected
-        // Order here creates a clockwise rotating I/Q phasor
-        switch(ant) {
-            case 8:
-                m_in_phase = m_in_phase*m_beta + sample*m_alpha;
-                break;
-            case 4:
-                m_quadrature = m_quadrature*m_beta - sample*m_alpha;
-                break;
-            case 2:
-                m_in_phase = m_in_phase*m_beta - sample*m_alpha;
-                break;
-            case 1:
-                m_quadrature = m_quadrature*m_beta + sample*m_alpha;
-                break;
-            default:
-                wxLogError(_T("EZDoppler::Sample: Unknown antenna value %i"), ant);
-                break;
-        }
-    }
+    if (!m_ezdop->read_iq(buffer, nsamples, volume))
+        return false;
+
+    for (int i=0; i < nsamples; i++)
+        m_phase = m_alpha*m_phase + m_beta*buffer[i];
 
-    // m_phase is the actual instrument reading regardless of calibration
-    m_phase = atan2(m_quadrature, m_in_phase);
+    // m_angle is the actual instrument reading regardless of calibration
+    m_angle = atan2(m_phase.imag(), m_phase.real());
 
     // Calibration angle is sum of equalized offset and global offset
-    float cal = m_calibration[m_selected_rate] + m_offset;
+    float cal_angle = m_calibration[m_selected_rate] + m_offset;
 
     // Rotate I, Q by calibration angle
-    float i_cal = cos(cal);
-    float q_cal = sin(cal);
-    in_phase = m_in_phase*i_cal - m_quadrature*q_cal;
-    quadrature = m_quadrature*i_cal + m_in_phase*q_cal;
+    complex<float> cal = complex<float>(cos(cal_angle), sin(cal_angle));
+    m_output = m_phase*cal;
 
-    delete antenna;
-    delete audio;
+    in_phase = m_output.real()*nsamples/512.0;
+    quadrature = m_output.imag()*nsamples/512.0;
+    // adjust volume
+    
+//  wxLogDebug(_T("%f %f %f"), in_phase, quadrature, volume);
     return true;
 }
 
 bool EZDoppler::Calibrate(float phase)
 {
-    float offset = phase - m_phase;
+
+    float offset = phase - m_angle;
     NORMALIZEPHASE(offset);
     m_calibration[m_selected_rate] = offset;
+
     return true;
 }
 
 bool EZDoppler::SetCalibration(int rate, float offset)
 {
+
     wxASSERT(rate >= 0 && rate < 7);
     if (rate < 6)
         m_calibration[rate] = offset;
     else
         m_offset = offset;
+
+    return true;
 }
 
 float EZDoppler::GetCalibration(int rate)
@@ -490,11 +261,13 @@ float EZDoppler::GetCalibration(int rate)
         return m_calibration[rate];
     else
         return m_offset;        
+
+    return 0.0;
 }
 
 bool EZDoppler::SetOffset(float offset)
 {
-    m_offset = offset-m_phase-m_calibration[m_selected_rate];
+    m_offset = offset-m_angle-m_calibration[m_selected_rate];
     NORMALIZEPHASE(m_offset);
     NORMALIZEPHASE(m_offset);
     NORMALIZEPHASE(m_offset);
@@ -506,6 +279,7 @@ bool EZDoppler::Nudge(float amount)
     cal += amount;
     NORMALIZEPHASE(cal);
     m_calibration[m_selected_rate] = cal;
+
     return true;
 }
 
index 1471de6a493c1e8f9da19f0982a9a6bce658c78c..cf3d96da39ba24c1bee5eb1e05e2f53483c91a84 100644 (file)
     #include "config.h"
 #endif
 
-// USB access library
-#if HAVE_LIBFTDI
-    #include <ftdi.h>
-#elif HAVE_LIBFTD2XX
-    #if __WIN32__
-        #include <windows.h>
-    #endif
-    #include <FTD2XX.H>
-#endif
-
+// Application level includes
+#include <ezdop.h>
+#include <boost/shared_ptr.hpp>
 #include <wx/event.h>
 
-#define NUM_RATES   6
+// TODO: Read this from ezdop.h
+#define NUM_RATES   6   
 
 class EZDoppler;
 
@@ -76,6 +70,8 @@ typedef void(wxEvtHandler::*EZDopplerUpdateFunction)(EZDopplerUpdate&);
             (wxObject *)NULL \
         ),
 
+typedef boost::shared_ptr<ezdop> ezdop_sptr;
+
 class EZDoppler
 {
 public:
@@ -88,12 +84,11 @@ public:
     bool IsOnline();
     bool Start();
     bool Stop();
-    bool Zero();
     bool SetFilter(int n);
     bool SelectRotationRate(int n);
-    int  GetSelectedRotationRate();
+    int  GetRotationRate();
     bool Reset();
-    bool Sample(int nsamples, float &in_phase, float &quadrature, float &volume);
+    bool Sample(float &in_phase, float &quadrature, float &volume);
     bool Calibrate(float phase);
     bool SetCalibration(int rate, float offset);
     float GetCalibration(int rate);
@@ -102,28 +97,18 @@ public:
     bool NudgeAll(float amount);
             
 private:
-    // USB interaction
-#if HAVE_LIBFTDI
-    struct ftdi_context *m_device;          // libftdi device instance data
-#elif HAVE_LIBFTD2XX
-    FT_HANDLE m_handle;                     // FTD2XX device instance data
-    FT_STATUS m_status;                     // FTD2XX device function call results
-#endif
-    bool send_byte(unsigned char data);
-
-    // Doppler control
-    bool m_online;
-    int  m_selected_rate;
+    ezdop_sptr m_ezdop;
+    int m_selected_rate;
     wxWindow *m_gui;
     DopplerBackground *m_thread;
 
-    // DSP state
-    float m_in_phase;           // Filtered I value
-    float m_quadrature;         // Filtered Q value
-    float m_alpha;              // Exponential lowpass constant
-    float m_beta;               // Exponential lowpass constant = 1-alpha
-    float m_phase;              // Actual phase of doppler before calibration
-    float m_offset;             // Global calibration angle
+    complex<float> m_phase;         // Actual phase of doppler before calibration
+    complex<float> m_output;        // Calibrated output phase
+    complex<float> m_alpha;         // Exponential average constant
+    complex<float> m_beta;          // Exponential average constant
+    
+    float m_angle;                  // Actual angle of doppler before calibration
+    float m_offset;                 // Global calibration angle
     float m_calibration[NUM_RATES]; // Individual rotation rate offset
 };    
 
index 39b8325c88c2a719946e9c6e313cc334c63fe3da..0aabfe29edbfb4df86358611a0cee93cd6f139a9 100644 (file)
@@ -513,19 +513,6 @@ void HunterFrame::OnDopplerUpdate(EZDopplerUpdate &event)
     m_sample.Phase(atan2(event.m_quadrature, event.m_in_phase));
 
     UpdateDopplerStatus(true);
-
-    if (m_log && m_gps_started && m_capture &&
-        m_sample.Speed() >= 5.0 && m_sample.Valid()) {
-        m_log->Add(m_sample);
-        if (m_one_shot == true) {
-            StopCapture();
-            CalcSolution();
-            if (m_search.HasSolution()) {
-                UpdateSearchStatus(true);
-                UpdateSearchDirection(true);
-            }
-        }
-    }
 }
 
 void HunterFrame::UpdateDopplerStatus(bool display)
@@ -606,7 +593,7 @@ void HunterFrame::DoCalibrationStep(int which)
     static int delay;
     
     if (which == 0) {       // Set up doppler 
-        delay = XRCCTRL(*this, "doppler_filter_slider", wxSlider)->GetValue()/3; // Empirically determined
+        delay = XRCCTRL(*this, "doppler_filter_slider", wxSlider)->GetValue(); // Empirically determined
         if (delay == 0)
             delay = 1;
     }
@@ -699,12 +686,20 @@ void HunterFrame::OnGPSUpdate(GPSUpdate &update)
     UpdateGPSValidity(update.m_gprmc->m_valid);                 // Colors red for invalid, black for valid
     UpdateGPSStatus(true);                                      // gps lat, lon, heading, speed
     UpdateKnownDirection();                                     // actual bearing and range
-
     CalcKnownStatistics();
-    if (m_capture)
+
+    if (m_log && m_capture && m_doppler_started &&
+        m_sample.Speed() >= 5.0 && m_sample.Valid()) {
+        m_log->Add(m_sample);
         CalcSolution();
-    if (m_search.HasSolution())
+        if (m_one_shot == true)
+            StopCapture();
+    }
+
+    if (m_search.HasSolution()) {
+        UpdateSearchStatus(true);
         UpdateSearchDirection(true);
+    }
         
     delete update.m_gprmc;
 }
@@ -747,7 +742,7 @@ void HunterFrame::UpdateSearchStatus(bool display)
     str.Printf(_T("%i"), m_log->Count());
     XRCCTRL(*this, "search_count_text", wxStaticText)->SetLabel(str);
 
-    str.Printf(_T("%s"), m_search.Busy() ? "BUSY" : "");
+    str.Printf(_T("%s"), m_search.Busy() ? _T("BUSY") : _T(""));
     XRCCTRL(*this, "search_status_text", wxStaticText)->SetLabel(str);
 
     str.Printf(_T("%i"), m_search.Mode());
index 9992cb8964f25b7e9fabea7254d222f035cbc470..d15a406b65acc0cd43a97e34265a147f16d81528 100644 (file)
@@ -197,10 +197,12 @@ float TransmitterSearch::calc_trial_error(const vector<Sample>&samples,
         sample.CalcError(trial, angle, ierror, qerror);
 
         // Wrapped cauchy distribution
-        float p = m_scale;
-        float likelihood = (1-p*p)/(1+p*p-2*p*cos(angle*M_PI/180.0));
+        //float p = m_scale;
+        //float likelihood = (1-p*p)/(1+p*p-2*p*cos(angle*M_PI/180.0));
+       //trial_error += -log(likelihood)*sample.Strength();
 
-        trial_error += -log(likelihood)*sample.Strength();
+       // Adjusted exponential distribution
+       trial_error += sqrt(1+angle*angle)*sample.Strength();
         wsum += sample.Strength();
     }    
 
index 5ace5aac13070c19cb10fbbb5940663f92d0c92b..67325d3b4d70c317afc82b87405ebceb8f9bf96e 100644 (file)
@@ -19,6 +19,7 @@
 #include "serial.h"
 
 #include <wx/log.h>
+#include <errno.h>
 
 #ifdef __WIN32__
 // I hate Windows.
@@ -122,9 +123,10 @@ bool SerialPort::Open(int speed)
 
     m_opened = true;
 #else
-    m_fd = open((char *)m_port.c_str(), O_RDWR|O_NONBLOCK);
+    // Fixed at first USB port until string bug fixed
+    m_fd = open("/dev/ttyUSB0", O_RDWR|O_NONBLOCK);
     if (m_fd < 0) {
-        wxLogError(_T("SerialPort::Open: open() returned %i"), m_fd);
+        wxLogError(_T("SerialPort::Open: open(): %i"), errno);
         return false;
     }
 
index a7e79c53d43ead703bcc640779547c0adda9be34..74faba26855b9b579606a15ce6271d1412ee6579 100644 (file)
@@ -57,9 +57,11 @@ int main(int argc, char *argv)
     else
        printf("failed.\n");
 
+    float volume;
+
     for (int i = 0; i < chunks; i++) {
         printf("Asking EZDOP for %i samples...", samples);
-        int rd = dop->read_iq(buffer, samples);
+        int rd = dop->read_iq(buffer, samples, volume);
        printf("got %i --- ", rd);
        if (rd != samples)
            printf("*****\n");
index 38cb5dd072e42d8cfd6395107f637ec73f75aa83..793a20fcfa502bef5f4c39abfd6c4b47f6ee5a6c 100644 (file)
@@ -108,6 +108,8 @@ int ezdop_source_c::work(int noutput_items,
        gr_vector_void_star &output_items)
 {
     assert(d_ezdop);
+    float volume = 0.0; // Dummy for now
+
     gr_complex *out = (gr_complex *)output_items[0];
-    return d_ezdop->read_iq(out, noutput_items);
+    return d_ezdop->read_iq(out, noutput_items, volume);
 }
diff --git a/gr-rdf/AUTHORS b/gr-rdf/AUTHORS
new file mode 100644 (file)
index 0000000..cdb61c9
--- /dev/null
@@ -0,0 +1 @@
+Johnathan Corgan <jcorgan@aeinet.com>
diff --git a/gr-rdf/Makefile.am b/gr-rdf/Makefile.am
new file mode 100644 (file)
index 0000000..12d751e
--- /dev/null
@@ -0,0 +1,24 @@
+#
+# Copyright 2006 Free Software Foundation, Inc.
+# 
+# This file is part of GNU Radio
+# 
+# GNU Radio 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, or (at your option)
+# any later version.
+# 
+# GNU Radio 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 GNU Radio; see the file COPYING.  If not, write to
+# the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+# Boston, MA 02111-1307, USA.
+# 
+
+include $(top_srcdir)/Makefile.common
+
+SUBDIRS = src
diff --git a/gr-rdf/README b/gr-rdf/README
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/gr-rdf/src/Makefile.am b/gr-rdf/src/Makefile.am
new file mode 100644 (file)
index 0000000..a46727e
--- /dev/null
@@ -0,0 +1,24 @@
+#
+# Copyright 2006 Free Software Foundation, Inc.
+# 
+# This file is part of GNU Radio
+# 
+# GNU Radio 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, or (at your option)
+# any later version.
+# 
+# GNU Radio 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 GNU Radio; see the file COPYING.  If not, write to
+# the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+# Boston, MA 02111-1307, USA.
+# 
+
+include $(top_srcdir)/Makefile.common
+
+SUBDIRS = lib python
diff --git a/gr-rdf/src/lib/Makefile.am b/gr-rdf/src/lib/Makefile.am
new file mode 100644 (file)
index 0000000..2c65488
--- /dev/null
@@ -0,0 +1,24 @@
+#
+# Copyright 2006 Free Software Foundation, Inc.
+# 
+# This file is part of GNU Radio
+# 
+# GNU Radio 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, or (at your option)
+# any later version.
+# 
+# GNU Radio 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 GNU Radio; see the file COPYING.  If not, write to
+# the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+# Boston, MA 02111-1307, USA.
+# 
+
+include $(top_srcdir)/Makefile.common
+
+SUBDIRS = 
diff --git a/gr-rdf/src/python/Makefile.am b/gr-rdf/src/python/Makefile.am
new file mode 100644 (file)
index 0000000..2c65488
--- /dev/null
@@ -0,0 +1,24 @@
+#
+# Copyright 2006 Free Software Foundation, Inc.
+# 
+# This file is part of GNU Radio
+# 
+# GNU Radio 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, or (at your option)
+# any later version.
+# 
+# GNU Radio 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 GNU Radio; see the file COPYING.  If not, write to
+# the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+# Boston, MA 02111-1307, USA.
+# 
+
+include $(top_srcdir)/Makefile.common
+
+SUBDIRS =