summaryrefslogtreecommitdiff
path: root/ezdop/src/host
diff options
context:
space:
mode:
Diffstat (limited to 'ezdop/src/host')
-rw-r--r--ezdop/src/host/ezdop/ezdop.cc21
-rw-r--r--ezdop/src/host/ezdop/ezdop.h2
-rw-r--r--ezdop/src/host/hunter/config/hunter_wx.m44
-rw-r--r--ezdop/src/host/hunter/configure.ac2
-rw-r--r--ezdop/src/host/hunter/src/Makefile.am16
-rw-r--r--ezdop/src/host/hunter/src/doppler.cc358
-rw-r--r--ezdop/src/host/hunter/src/doppler.h51
-rw-r--r--ezdop/src/host/hunter/src/hunter.cc31
-rw-r--r--ezdop/src/host/hunter/src/search.cc8
-rw-r--r--ezdop/src/host/hunter/src/serial.cc6
-rw-r--r--ezdop/src/host/tests/dopper.cc4
11 files changed, 138 insertions, 365 deletions
diff --git a/ezdop/src/host/ezdop/ezdop.cc b/ezdop/src/host/ezdop/ezdop.cc
index 43a70dacb..99997fedf 100644
--- a/ezdop/src/host/ezdop/ezdop.cc
+++ b/ezdop/src/host/ezdop/ezdop.cc
@@ -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;
}
diff --git a/ezdop/src/host/ezdop/ezdop.h b/ezdop/src/host/ezdop/ezdop.h
index b4ce1a454..c40178c0b 100644
--- a/ezdop/src/host/ezdop/ezdop.h
+++ b/ezdop/src/host/ezdop/ezdop.h
@@ -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; }
diff --git a/ezdop/src/host/hunter/config/hunter_wx.m4 b/ezdop/src/host/hunter/config/hunter_wx.m4
index 5d6dd08e7..ffee16a59 100644
--- a/ezdop/src/host/hunter/config/hunter_wx.m4
+++ b/ezdop/src/host/hunter/config/hunter_wx.m4
@@ -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)
])
diff --git a/ezdop/src/host/hunter/configure.ac b/ezdop/src/host/hunter/configure.ac
index b6bd4cf7e..b0af6cba0 100644
--- a/ezdop/src/host/hunter/configure.ac
+++ b/ezdop/src/host/hunter/configure.ac
@@ -32,7 +32,7 @@ AC_CHECK_FUNCS([modf sqrt])
# Application specific checks
HUNTER_WX
-HUNTER_FTDI
+#HUNTER_FTDI
AC_CONFIG_FILES([ \
Makefile
diff --git a/ezdop/src/host/hunter/src/Makefile.am b/ezdop/src/host/hunter/src/Makefile.am
index d1fe5eec2..392b79eff 100644
--- a/ezdop/src/host/hunter/src/Makefile.am
+++ b/ezdop/src/host/hunter/src/Makefile.am
@@ -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
diff --git a/ezdop/src/host/hunter/src/doppler.cc b/ezdop/src/host/hunter/src/doppler.cc
index 1e7b3cf49..99b5aa616 100644
--- a/ezdop/src/host/hunter/src/doppler.cc
+++ b/ezdop/src/host/hunter/src/doppler.cc
@@ -25,14 +25,18 @@
#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;
}
diff --git a/ezdop/src/host/hunter/src/doppler.h b/ezdop/src/host/hunter/src/doppler.h
index 1471de6a4..cf3d96da3 100644
--- a/ezdop/src/host/hunter/src/doppler.h
+++ b/ezdop/src/host/hunter/src/doppler.h
@@ -24,19 +24,13 @@
#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
};
diff --git a/ezdop/src/host/hunter/src/hunter.cc b/ezdop/src/host/hunter/src/hunter.cc
index 39b8325c8..0aabfe29e 100644
--- a/ezdop/src/host/hunter/src/hunter.cc
+++ b/ezdop/src/host/hunter/src/hunter.cc
@@ -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());
diff --git a/ezdop/src/host/hunter/src/search.cc b/ezdop/src/host/hunter/src/search.cc
index 9992cb896..d15a406b6 100644
--- a/ezdop/src/host/hunter/src/search.cc
+++ b/ezdop/src/host/hunter/src/search.cc
@@ -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();
}
diff --git a/ezdop/src/host/hunter/src/serial.cc b/ezdop/src/host/hunter/src/serial.cc
index 5ace5aac1..67325d3b4 100644
--- a/ezdop/src/host/hunter/src/serial.cc
+++ b/ezdop/src/host/hunter/src/serial.cc
@@ -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;
}
diff --git a/ezdop/src/host/tests/dopper.cc b/ezdop/src/host/tests/dopper.cc
index a7e79c53d..74faba268 100644
--- a/ezdop/src/host/tests/dopper.cc
+++ b/ezdop/src/host/tests/dopper.cc
@@ -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");