Use a linear interpolator for the reported RSSI values.

This commit is contained in:
Jonathan Naylor 2016-12-21 19:58:46 +00:00
parent 59080e1bd7
commit aac48cb58f
20 changed files with 198 additions and 58 deletions

View File

@ -91,8 +91,7 @@ m_modemDMRTXLevel(50U),
m_modemYSFTXLevel(50U),
m_modemP25TXLevel(50U),
m_modemOscOffset(0),
m_modemRSSIMultiplier(0),
m_modemRSSIOffset(0),
m_modemRSSIMappingFile(),
m_modemDebug(false),
m_umpEnabled(false),
m_umpPort(),
@ -327,10 +326,8 @@ bool CConf::read()
m_modemP25TXLevel = (unsigned int)::atoi(value);
else if (::strcmp(key, "OscOffset") == 0)
m_modemOscOffset = ::atoi(value);
else if (::strcmp(key, "RSSIMultiplier") == 0)
m_modemRSSIMultiplier = ::atoi(value);
else if (::strcmp(key, "RSSIOffset") == 0)
m_modemRSSIOffset = ::atoi(value);
else if (::strcmp(key, "RSSIMappingFile") == 0)
m_modemRSSIMappingFile = value;
else if (::strcmp(key, "Debug") == 0)
m_modemDebug = ::atoi(value) == 1;
} else if (section == SECTION_UMP) {
@ -724,14 +721,9 @@ int CConf::getModemOscOffset() const
return m_modemOscOffset;
}
int CConf::getModemRSSIMultiplier () const
std::string CConf::getModemRSSIMappingFile () const
{
return m_modemRSSIMultiplier;
}
int CConf::getModemRSSIOffset() const
{
return m_modemRSSIOffset;
return m_modemRSSIMappingFile;
}
bool CConf::getModemDebug() const

6
Conf.h
View File

@ -78,8 +78,7 @@ public:
unsigned int getModemYSFTXLevel() const;
unsigned int getModemP25TXLevel() const;
int getModemOscOffset() const;
int getModemRSSIMultiplier() const;
int getModemRSSIOffset() const;
std::string getModemRSSIMappingFile() const;
bool getModemDebug() const;
// The UMP section
@ -227,8 +226,7 @@ private:
unsigned int m_modemYSFTXLevel;
unsigned int m_modemP25TXLevel;
int m_modemOscOffset;
int m_modemRSSIMultiplier;
int m_modemRSSIOffset;
std::string m_modemRSSIMappingFile;
bool m_modemDebug;
bool m_umpEnabled;

View File

@ -21,7 +21,7 @@
#include <cassert>
#include <algorithm>
CDMRControl::CDMRControl(unsigned int id, unsigned int colorCode, unsigned int callHang, bool selfOnly, const std::vector<unsigned int>& prefixes, const std::vector<unsigned int>& blacklist, const std::vector<unsigned int>& whitelist, unsigned int timeout, CModem* modem, CDMRNetwork* network, CDisplay* display, bool duplex, CDMRLookup* lookup, int rssiMultiplier, int rssiOffset, unsigned int jitter) :
CDMRControl::CDMRControl(unsigned int id, unsigned int colorCode, unsigned int callHang, bool selfOnly, const std::vector<unsigned int>& prefixes, const std::vector<unsigned int>& blacklist, const std::vector<unsigned int>& whitelist, unsigned int timeout, CModem* modem, CDMRNetwork* network, CDisplay* display, bool duplex, CDMRLookup* lookup, CRSSIInterpolator* rssi, unsigned int jitter) :
m_id(id),
m_colorCode(colorCode),
m_modem(modem),
@ -34,11 +34,12 @@ m_lookup(lookup)
assert(modem != NULL);
assert(display != NULL);
assert(lookup != NULL);
assert(rssi != NULL);
// Load black and white lists to DMRAccessControl
CDMRAccessControl::init(blacklist, whitelist, selfOnly, prefixes, id);
CDMRSlot::init(colorCode, callHang, modem, network, display, duplex, m_lookup, rssiMultiplier, rssiOffset, jitter);
CDMRSlot::init(colorCode, callHang, modem, network, display, duplex, m_lookup, rssi, jitter);
}
CDMRControl::~CDMRControl()

View File

@ -19,6 +19,7 @@
#if !defined(DMRControl_H)
#define DMRControl_H
#include "RSSIInterpolator.h"
#include "DMRNetwork.h"
#include "DMRLookup.h"
#include "Display.h"
@ -30,7 +31,7 @@
class CDMRControl {
public:
CDMRControl(unsigned int id, unsigned int colorCode, unsigned int callHang, bool selfOnly, const std::vector<unsigned int>& prefixes, const std::vector<unsigned int>& blacklist, const std::vector<unsigned int>& whitelist, unsigned int timeout, CModem* modem, CDMRNetwork* network, CDisplay* display, bool duplex, CDMRLookup* lookup, int rssiMultiplier, int rssiOffset, unsigned int jitter);
CDMRControl(unsigned int id, unsigned int colorCode, unsigned int callHang, bool selfOnly, const std::vector<unsigned int>& prefixes, const std::vector<unsigned int>& blacklist, const std::vector<unsigned int>& whitelist, unsigned int timeout, CModem* modem, CDMRNetwork* network, CDisplay* display, bool duplex, CDMRLookup* lookup, CRSSIInterpolator* rssi, unsigned int jitter);
~CDMRControl();
bool processWakeup(const unsigned char* data);

View File

@ -37,8 +37,7 @@ bool CDMRSlot::m_duplex = true;
CDMRLookup* CDMRSlot::m_lookup = NULL;
unsigned int CDMRSlot::m_hangCount = 3U * 17U;
int CDMRSlot::m_rssiMultiplier = 0;
int CDMRSlot::m_rssiOffset = 0;
CRSSIInterpolator* CDMRSlot::m_rssiMapper = NULL;
unsigned int CDMRSlot::m_jitterTime = 300U;
unsigned int CDMRSlot::m_jitterSlots = 5U;
@ -120,11 +119,11 @@ void CDMRSlot::writeModem(unsigned char *data, unsigned int len)
}
// Have we got RSSI bytes on the end?
if (len == (DMR_FRAME_LENGTH_BYTES + 4U) && m_rssiMultiplier != 0) {
if (len == (DMR_FRAME_LENGTH_BYTES + 4U)) {
uint16_t raw = 0U;
raw |= (data[35U] << 8) & 0xFF00U;
raw |= (data[36U] << 0) & 0x00FFU;
int rssi = (raw - m_rssiOffset) / m_rssiMultiplier;
int rssi = m_rssiMapper->interpolate(raw);
m_rssi = (rssi >= 0) ? rssi : -rssi;
LogDebug("DMR Slot %u, raw RSSI: %u, reported RSSI: -%u dBm", m_slotNo, raw, m_rssi);
}
@ -1388,11 +1387,12 @@ void CDMRSlot::writeQueueNet(const unsigned char *data)
m_queue.addData(data, len);
}
void CDMRSlot::init(unsigned int colorCode, unsigned int callHang, CModem* modem, CDMRNetwork* network, CDisplay* display, bool duplex, CDMRLookup* lookup, int rssiMultiplier, int rssiOffset, unsigned int jitter)
void CDMRSlot::init(unsigned int colorCode, unsigned int callHang, CModem* modem, CDMRNetwork* network, CDisplay* display, bool duplex, CDMRLookup* lookup, CRSSIInterpolator* rssiMapper, unsigned int jitter)
{
assert(modem != NULL);
assert(display != NULL);
assert(lookup != NULL);
assert(rssiMapper != NULL);
m_colorCode = colorCode;
m_modem = modem;
@ -1402,8 +1402,7 @@ void CDMRSlot::init(unsigned int colorCode, unsigned int callHang, CModem* modem
m_lookup = lookup;
m_hangCount = callHang * 17U;
m_rssiMultiplier = rssiMultiplier;
m_rssiOffset = rssiOffset;
m_rssiMapper = rssiMapper;
m_jitterTime = jitter;
m_jitterSlots = jitter / DMR_SLOT_TIME;

View File

@ -19,6 +19,7 @@
#if !defined(DMRSlot_H)
#define DMRSlot_H
#include "RSSIInterpolator.h"
#include "DMREmbeddedLC.h"
#include "DMRDataHeader.h"
#include "DMRNetwork.h"
@ -50,7 +51,7 @@ public:
void clock();
static void init(unsigned int colorCode, unsigned int callHang, CModem* modem, CDMRNetwork* network, CDisplay* display, bool duplex, CDMRLookup* lookup, int rssiMultiplier, int rssiOffset, unsigned int jitter);
static void init(unsigned int colorCode, unsigned int callHang, CModem* modem, CDMRNetwork* network, CDisplay* display, bool duplex, CDMRLookup* lookup, CRSSIInterpolator* rssiMapper, unsigned int jitter);
private:
unsigned int m_slotNo;
@ -95,8 +96,7 @@ private:
static CDMRLookup* m_lookup;
static unsigned int m_hangCount;
static int m_rssiMultiplier;
static int m_rssiOffset;
static CRSSIInterpolator* m_rssiMapper;
static unsigned int m_jitterTime;
static unsigned int m_jitterSlots;

View File

@ -50,8 +50,7 @@ TXLevel=50
# YSFTXLevel=50
# P25TXLevel=50
OscOffset=0
RSSIMultiplier=1
RSSIOffset=10
RSSIMappingFile=RSSI.dat
Debug=0
[UMP]

View File

@ -17,6 +17,7 @@
*/
#include "MMDVMHost.h"
#include "RSSIInterpolator.h"
#include "SerialController.h"
#include "ModemSerialPort.h"
#include "Version.h"
@ -331,17 +332,16 @@ int CMMDVMHost::run()
CDMRControl* dmr = NULL;
if (m_dmrEnabled) {
unsigned int id = m_conf.getDMRId();
unsigned int colorCode = m_conf.getDMRColorCode();
bool selfOnly = m_conf.getDMRSelfOnly();
unsigned int id = m_conf.getDMRId();
unsigned int colorCode = m_conf.getDMRColorCode();
bool selfOnly = m_conf.getDMRSelfOnly();
std::vector<unsigned int> prefixes = m_conf.getDMRPrefixes();
std::vector<unsigned int> blackList = m_conf.getDMRBlackList();
std::vector<unsigned int> whiteList = m_conf.getDMRWhiteList();
unsigned int callHang = m_conf.getDMRCallHang();
unsigned int txHang = m_conf.getDMRTXHang();
int rssiMultiplier = m_conf.getModemRSSIMultiplier();
int rssiOffset = m_conf.getModemRSSIOffset();
unsigned int jitter = m_conf.getDMRNetworkJitter();
unsigned int callHang = m_conf.getDMRCallHang();
unsigned int txHang = m_conf.getDMRTXHang();
std::string rssiMappingFile = m_conf.getModemRSSIMappingFile();
unsigned int jitter = m_conf.getDMRNetworkJitter();
if (txHang > m_rfModeHang)
txHang = m_rfModeHang;
@ -365,12 +365,13 @@ int CMMDVMHost::run()
LogInfo(" Call Hang: %us", callHang);
LogInfo(" TX Hang: %us", txHang);
if (rssiMultiplier != 0) {
LogInfo(" RSSI Multiplier: %d", rssiMultiplier);
LogInfo(" RSSI Offset: %d", rssiOffset);
CRSSIInterpolator* rssi = new CRSSIInterpolator;
if (!rssiMappingFile.empty()) {
LogInfo(" RSSI Mapping File: %s", rssiMappingFile.c_str());
rssi->load(rssiMappingFile);
}
dmr = new CDMRControl(id, colorCode, callHang, selfOnly, prefixes, blackList, whiteList, m_timeout, m_modem, m_dmrNetwork, m_display, m_duplex, m_lookup, rssiMultiplier, rssiOffset, jitter);
dmr = new CDMRControl(id, colorCode, callHang, selfOnly, prefixes, blackList, whiteList, m_timeout, m_modem, m_dmrNetwork, m_display, m_duplex, m_lookup, rssi, jitter);
m_dmrTXTimer.setTimeout(txHang);
}

View File

@ -197,6 +197,7 @@
<ClInclude Include="RingBuffer.h" />
<ClInclude Include="RS129.h" />
<ClInclude Include="RS241213.h" />
<ClInclude Include="RSSIInterpolator.h" />
<ClInclude Include="SerialController.h" />
<ClInclude Include="SerialPort.h" />
<ClInclude Include="SHA256.h" />
@ -263,6 +264,7 @@
<ClCompile Include="QR1676.cpp" />
<ClCompile Include="RS129.cpp" />
<ClCompile Include="RS241213.cpp" />
<ClCompile Include="RSSIInterpolator.cpp" />
<ClCompile Include="SerialController.cpp" />
<ClCompile Include="SerialPort.cpp" />
<ClCompile Include="SHA256.cpp" />

View File

@ -218,6 +218,9 @@
<ClInclude Include="UMP.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="RSSIInterpolator.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="BPTC19696.cpp">
@ -406,5 +409,8 @@
<ClCompile Include="UMP.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="RSSIInterpolator.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
</Project>

View File

@ -10,8 +10,8 @@ OBJECTS = \
AMBEFEC.o BCH.o BPTC19696.o Conf.o CRC.o Display.o DMRControl.o DMRCSBK.o DMRData.o DMRDataHeader.o DMREMB.o DMREmbeddedLC.o DMRFullLC.o DMRLookup.o DMRLC.o \
DMRNetwork.o DMRShortLC.o DMRSlot.o DMRSlotType.o DMRAccessControl.o DMRTrellis.o DStarControl.o DStarHeader.o DStarNetwork.o DStarSlowData.o Golay2087.o \
Golay24128.o Hamming.o LCDproc.o Log.o MMDVMHost.o Modem.o ModemSerialPort.o Mutex.o Nextion.o NullDisplay.o P25Audio.o P25Control.o P25Data.o P25LowSpeedData.o \
P25Network.o P25NID.o P25Utils.o QR1676.o RS129.o RS241213.o SerialController.o SerialPort.o SHA256.o StopWatch.o Sync.o TFTSerial.o Thread.o Timer.o UDPSocket.o \
UMP.o Utils.o YSFControl.o YSFConvolution.o YSFFICH.o YSFNetwork.o YSFPayload.o
P25Network.o P25NID.o P25Utils.o QR1676.o RS129.o RS241213.o RSSIInterpolator.o SerialController.o SerialPort.o SHA256.o StopWatch.o Sync.o TFTSerial.o Thread.o \
Timer.o UDPSocket.o UMP.o Utils.o YSFControl.o YSFConvolution.o YSFFICH.o YSFNetwork.o YSFPayload.o
all: MMDVMHost

View File

@ -10,8 +10,8 @@ OBJECTS = \
AMBEFEC.o BCH.o BPTC19696.o Conf.o CRC.o Display.o DMRControl.o DMRCSBK.o DMRData.o DMRDataHeader.o DMREMB.o DMREmbeddedLC.o DMRFullLC.o DMRLookup.o DMRLC.o \
DMRNetwork.o DMRShortLC.o DMRSlot.o DMRSlotType.o DMRAccessControl.o DMRTrellis.o DStarControl.o DStarHeader.o DStarNetwork.o DStarSlowData.o Golay2087.o \
Golay24128.o Hamming.o LCDproc.o Log.o MMDVMHost.o Modem.o ModemSerialPort.o Mutex.o Nextion.o NullDisplay.o P25Audio.o P25Control.o P25Data.o P25LowSpeedData.o \
P25Network.o P25NID.o P25Utils.o QR1676.o RS129.o RS241213.o SerialController.o SerialPort.o SHA256.o StopWatch.o Sync.o TFTSerial.o Thread.o Timer.o UDPSocket.o \
UMP.o Utils.o YSFControl.o YSFConvolution.o YSFFICH.o YSFNetwork.o YSFPayload.o
P25Network.o P25NID.o P25Utils.o QR1676.o RS129.o RS241213.o RSSIInterpolator.o SerialController.o SerialPort.o SHA256.o StopWatch.o Sync.o TFTSerial.o Thread.o \
Timer.o UDPSocket.o UMP.o Utils.o YSFControl.o YSFConvolution.o YSFFICH.o YSFNetwork.o YSFPayload.o
all: MMDVMHost

View File

@ -10,8 +10,8 @@ OBJECTS = \
AMBEFEC.o BCH.o BPTC19696.o Conf.o CRC.o Display.o DMRControl.o DMRCSBK.o DMRData.o DMRDataHeader.o DMREMB.o DMREmbeddedLC.o DMRFullLC.o DMRLookup.o DMRLC.o \
DMRNetwork.o DMRShortLC.o DMRSlot.o DMRSlotType.o DMRAccessControl.o DMRTrellis.o DStarControl.o DStarHeader.o DStarNetwork.o DStarSlowData.o Golay2087.o \
Golay24128.o Hamming.o HD44780.o LCDproc.o Log.o MMDVMHost.o Modem.o ModemSerialPort.o Mutex.o Nextion.o NullDisplay.o P25Audio.o P25Control.o P25Data.o \
P25LowSpeedData.o P25Network.o P25NID.o P25Utils.o QR1676.o RS129.o RS241213.o SerialController.o SerialPort.o SHA256.o StopWatch.o Sync.o TFTSerial.o Thread.o \
Timer.o UDPSocket.o UMP.o Utils.o YSFControl.o YSFConvolution.o YSFFICH.o YSFNetwork.o YSFPayload.o
P25LowSpeedData.o P25Network.o P25NID.o P25Utils.o QR1676.o RS129.o RS241213.o RSSIInterpolator.o SerialController.o SerialPort.o SHA256.o StopWatch.o Sync.o \
TFTSerial.o Thread.o Timer.o UDPSocket.o UMP.o Utils.o YSFControl.o YSFConvolution.o YSFFICH.o YSFNetwork.o YSFPayload.o
all: MMDVMHost

View File

@ -10,8 +10,8 @@ OBJECTS = \
AMBEFEC.o BCH.o BPTC19696.o Conf.o CRC.o Display.o DMRControl.o DMRCSBK.o DMRData.o DMRDataHeader.o DMREMB.o DMREmbeddedLC.o DMRFullLC.o DMRLookup.o DMRLC.o \
DMRNetwork.o DMRShortLC.o DMRSlot.o DMRSlotType.o DMRAccessControl.o DMRTrellis.o DStarControl.o DStarHeader.o DStarNetwork.o DStarSlowData.o Golay2087.o \
Golay24128.o Hamming.o HD44780.o LCDproc.o Log.o MMDVMHost.o Modem.o ModemSerialPort.o Mutex.o Nextion.o NullDisplay.o P25Audio.o P25Control.o P25Data.o P25LowSpeedData.o \
P25Network.o P25NID.o P25Utils.o QR1676.o RS129.o RS241213.o SerialController.o SerialPort.o SHA256.o StopWatch.o Sync.o TFTSerial.o Thread.o Timer.o UDPSocket.o \
UMP.o Utils.o YSFControl.o YSFConvolution.o YSFFICH.o YSFNetwork.o YSFPayload.o
P25Network.o P25NID.o P25Utils.o QR1676.o RS129.o RS241213.o RSSIInterpolator.o SerialController.o SerialPort.o SHA256.o StopWatch.o Sync.o TFTSerial.o Thread.o \
Timer.o UDPSocket.o UMP.o Utils.o YSFControl.o YSFConvolution.o YSFFICH.o YSFNetwork.o YSFPayload.o
all: MMDVMHost

View File

@ -10,8 +10,8 @@ OBJECTS = \
AMBEFEC.o BCH.o BPTC19696.o Conf.o CRC.o Display.o DMRControl.o DMRCSBK.o DMRData.o DMRDataHeader.o DMREMB.o DMREmbeddedLC.o DMRFullLC.o DMRLookup.o DMRLC.o \
DMRNetwork.o DMRShortLC.o DMRSlot.o DMRSlotType.o DMRAccessControl.o DMRTrellis.o DStarControl.o DStarHeader.o DStarNetwork.o DStarSlowData.o Golay2087.o \
Golay24128.o Hamming.o OLED.o LCDproc.o Log.o MMDVMHost.o Modem.o ModemSerialPort.o Mutex.o Nextion.o NullDisplay.o P25Audio.o P25Control.o P25Data.o P25LowSpeedData.o \
P25Network.o P25NID.o P25Utils.o QR1676.o RS129.o RS241213.o SerialController.o SerialPort.o SHA256.o StopWatch.o Sync.o TFTSerial.o Thread.o Timer.o UDPSocket.o \
UMP.o Utils.o YSFControl.o YSFConvolution.o YSFFICH.o YSFNetwork.o YSFPayload.o
P25Network.o P25NID.o P25Utils.o QR1676.o RS129.o RS241213.o RSSIInterpolator.o SerialController.o SerialPort.o SHA256.o StopWatch.o Sync.o TFTSerial.o Thread.o \
Timer.o UDPSocket.o UMP.o Utils.o YSFControl.o YSFConvolution.o YSFFICH.o YSFNetwork.o YSFPayload.o
all: MMDVMHost

View File

@ -10,8 +10,8 @@ OBJECTS = \
AMBEFEC.o BCH.o BPTC19696.o Conf.o CRC.o Display.o DMRControl.o DMRCSBK.o DMRData.o DMRDataHeader.o DMREMB.o DMREmbeddedLC.o DMRFullLC.o DMRLookup.o DMRLC.o \
DMRNetwork.o DMRShortLC.o DMRSlot.o DMRSlotType.o DMRAccessControl.o DMRTrellis.o DStarControl.o DStarHeader.o DStarNetwork.o DStarSlowData.o Golay2087.o \
Golay24128.o Hamming.o HD44780.o LCDproc.o Log.o MMDVMHost.o Modem.o ModemSerialPort.o Mutex.o Nextion.o NullDisplay.o P25Audio.o P25Control.o P25Data.o P25LowSpeedData.o \
P25Network.o P25NID.o P25Utils.o QR1676.o RS129.o RS241213.o SerialController.o SerialPort.o SHA256.o StopWatch.o Sync.o TFTSerial.o Thread.o Timer.o UDPSocket.o \
UMP.o Utils.o YSFControl.o YSFConvolution.o YSFFICH.o YSFNetwork.o YSFPayload.o
P25Network.o P25NID.o P25Utils.o QR1676.o RS129.o RS241213.o RSSIInterpolator.o SerialController.o SerialPort.o SHA256.o StopWatch.o Sync.o TFTSerial.o Thread.o \
Timer.o UDPSocket.o UMP.o Utils.o YSFControl.o YSFConvolution.o YSFFICH.o YSFNetwork.o YSFPayload.o
all: MMDVMHost

View File

@ -10,8 +10,8 @@ OBJECTS = \
AMBEFEC.o BCH.o BPTC19696.o Conf.o CRC.o Display.o DMRControl.o DMRCSBK.o DMRData.o DMRDataHeader.o DMREMB.o DMREmbeddedLC.o DMRFullLC.o DMRLookup.o DMRLC.o \
DMRNetwork.o DMRShortLC.o DMRSlot.o DMRSlotType.o DMRAccessControl.o DMRTrellis.o DStarControl.o DStarHeader.o DStarNetwork.o DStarSlowData.o Golay2087.o \
Golay24128.o Hamming.o LCDproc.o Log.o MMDVMHost.o Modem.o ModemSerialPort.o Mutex.o Nextion.o NullDisplay.o P25Audio.o P25Control.o P25Data.o P25LowSpeedData.o \
P25Network.o P25NID.o P25Utils.o QR1676.o RS129.o RS241213.o SerialController.o SerialPort.o SHA256.o StopWatch.o Sync.o TFTSerial.o Thread.o Timer.o UDPSocket.o \
UMP.o Utils.o YSFControl.o YSFConvolution.o YSFFICH.o YSFNetwork.o YSFPayload.o
P25Network.o P25NID.o P25Utils.o QR1676.o RS129.o RS241213.o RSSIInterpolator.o SerialController.o SerialPort.o SHA256.o StopWatch.o Sync.o TFTSerial.o Thread.o \
Timer.o UDPSocket.o UMP.o Utils.o YSFControl.o YSFConvolution.o YSFFICH.o YSFNetwork.o YSFPayload.o
all: MMDVMHost

11
RSSI.dat Normal file
View File

@ -0,0 +1,11 @@
# This file maps the raw RSSI values to dBm values to send to the DMR network. A number of data
# points should be entered and the software will use those to work out the in-between values.
#
# The format of the file is:
# Raw RSSI Value dBm Value
#
# For example
# 1134 -90
# 1123 -100
# 1000 -109
#

91
RSSIInterpolator.cpp Normal file
View File

@ -0,0 +1,91 @@
/*
* Copyright (C) 2016 by Jonathan Naylor G4KLX
*
* 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., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include "RSSIInterpolator.h"
#include "Log.h"
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cctype>
CRSSIInterpolator::CRSSIInterpolator() :
m_map()
{
}
CRSSIInterpolator::~CRSSIInterpolator()
{
m_map.clear();
}
bool CRSSIInterpolator::load(const std::string& filename)
{
FILE* fp = ::fopen(filename.c_str(), "rt");
if (fp == NULL) {
LogWarning("Cannot open the RSSI data file - %s", filename.c_str());
return false;
}
char buffer[100U];
while (::fgets(buffer, 100, fp) != NULL) {
if (buffer[0U] == '#')
continue;
char* p1 = ::strtok(buffer, " \t\r\n");
char* p2 = ::strtok(NULL, " \t\r\n");
if (p1 != NULL && p2 != NULL) {
uint16_t raw = (unsigned int)::atoi(p1);
int rssi = ::atoi(p2);
m_map.insert(std::pair<uint16_t, int>(raw, rssi));
}
}
::fclose(fp);
LogInfo("Loaded %u RSSI data mapping points from %s", m_map.size(), filename.c_str());
return true;
}
int CRSSIInterpolator::interpolate(uint16_t val) const
{
if (m_map.empty())
return 0;
std::map<uint16_t, int>::const_iterator it = m_map.lower_bound(val);
if (it == m_map.end())
return m_map.rbegin()->second;
if (it == m_map.begin())
return it->second;
unsigned int x2 = it->first;
int y2 = it->second;
--it;
unsigned int x1 = it->first;
int y1 = it->second;
float p = float(val - x1) / float(x2 - x1);
return int((1.0F - p) * float(y1) + p * float(y2));
}

39
RSSIInterpolator.h Normal file
View File

@ -0,0 +1,39 @@
/*
* Copyright (C) 2016 by Jonathan Naylor G4KLX
*
* 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., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#if !defined(RSSIINTERPOLATOR_H)
#define RSSIINTERPOLATOR_H
#include <cstdint>
#include <string>
#include <map>
class CRSSIInterpolator {
public:
CRSSIInterpolator();
~CRSSIInterpolator();
bool load(const std::string& filename);
int interpolate(uint16_t raw) const;
private:
std::map<uint16_t, int> m_map;
};
#endif