mirror of
https://github.com/lumapu/ahoy.git
synced 2025-05-17 02:46:11 +02:00
parent
c71377011b
commit
df2e840751
6 changed files with 114 additions and 65 deletions
|
@ -1,5 +1,8 @@
|
||||||
# Development Changes
|
# Development Changes
|
||||||
|
|
||||||
|
## 0.8.18 - 2023-12-10
|
||||||
|
* copied even more from the original heuristic code #1259
|
||||||
|
|
||||||
## 0.8.17 - 2023-12-10
|
## 0.8.17 - 2023-12-10
|
||||||
* possible fix of NRF with opendtufusion (without ETH)
|
* possible fix of NRF with opendtufusion (without ETH)
|
||||||
* small fix in heuristics (if conditions made assignment not comparisson)
|
* small fix in heuristics (if conditions made assignment not comparisson)
|
||||||
|
|
|
@ -13,7 +13,7 @@
|
||||||
//-------------------------------------
|
//-------------------------------------
|
||||||
#define VERSION_MAJOR 0
|
#define VERSION_MAJOR 0
|
||||||
#define VERSION_MINOR 8
|
#define VERSION_MINOR 8
|
||||||
#define VERSION_PATCH 17
|
#define VERSION_PATCH 18
|
||||||
|
|
||||||
//-------------------------------------
|
//-------------------------------------
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
|
|
@ -65,6 +65,7 @@ class Communication : public CommQueue<> {
|
||||||
mHeu.getTxCh(q->iv);
|
mHeu.getTxCh(q->iv);
|
||||||
q->iv->mGotFragment = false;
|
q->iv->mGotFragment = false;
|
||||||
q->iv->mGotLastMsg = false;
|
q->iv->mGotLastMsg = false;
|
||||||
|
q->iv->curFrmCnt = 0;
|
||||||
mIsResend = false;
|
mIsResend = false;
|
||||||
if(NULL == q->iv->radio)
|
if(NULL == q->iv->radio)
|
||||||
cmdDone(true); // can't communicate while radio is not defined!
|
cmdDone(true); // can't communicate while radio is not defined!
|
||||||
|
@ -140,7 +141,7 @@ class Communication : public CommQueue<> {
|
||||||
mWaitTimeout = millis() + 1000;
|
mWaitTimeout = millis() + 1000;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
closeRequest(q->iv, false, false);
|
closeRequest(q, false, false);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -182,17 +183,18 @@ class Communication : public CommQueue<> {
|
||||||
q->iv->radioStatistics.frmCnt++;
|
q->iv->radioStatistics.frmCnt++;
|
||||||
|
|
||||||
if (p->packet[0] == (TX_REQ_INFO + ALL_FRAMES)) { // response from get information command
|
if (p->packet[0] == (TX_REQ_INFO + ALL_FRAMES)) { // response from get information command
|
||||||
parseFrame(p);
|
if(parseFrame(p))
|
||||||
|
q->iv->curFrmCnt++;
|
||||||
nextState = States::CHECK_PACKAGE;
|
nextState = States::CHECK_PACKAGE;
|
||||||
} else if (p->packet[0] == (TX_REQ_DEVCONTROL + ALL_FRAMES)) { // response from dev control command
|
} else if (p->packet[0] == (TX_REQ_DEVCONTROL + ALL_FRAMES)) { // response from dev control command
|
||||||
parseDevCtrl(p, q);
|
parseDevCtrl(p, q);
|
||||||
closeRequest(q->iv, true);
|
closeRequest(q, true, true);
|
||||||
} else if(IV_MI == q->iv->ivGen) {
|
} else if(IV_MI == q->iv->ivGen) {
|
||||||
parseMiFrame(p, q);
|
if(parseMiFrame(p, q))
|
||||||
|
q->iv->curFrmCnt++;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
q->iv->radioStatistics.rxFail++; // got no complete payload
|
q->iv->radioStatistics.rxFail++; // got no complete payload
|
||||||
DPRINTLN(DBG_WARN, F("Inverter serial does not match"));
|
|
||||||
mWaitTimeout = millis() + timeout;
|
mWaitTimeout = millis() + timeout;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -200,7 +202,7 @@ class Communication : public CommQueue<> {
|
||||||
yield();
|
yield();
|
||||||
}
|
}
|
||||||
if((0 == q->attempts) && (!q->iv->mGotFragment))
|
if((0 == q->attempts) && (!q->iv->mGotFragment))
|
||||||
closeRequest(q->iv, false);
|
closeRequest(q, false, true);
|
||||||
else {
|
else {
|
||||||
if(q->iv->ivGen != IV_MI)
|
if(q->iv->ivGen != IV_MI)
|
||||||
mState = nextState;
|
mState = nextState;
|
||||||
|
@ -212,9 +214,8 @@ class Communication : public CommQueue<> {
|
||||||
|| ((q->cmd == MI_REQ_CH2) && (q->iv->type == INV_TYPE_2CH))
|
|| ((q->cmd == MI_REQ_CH2) && (q->iv->type == INV_TYPE_2CH))
|
||||||
|| ((q->cmd == MI_REQ_CH1) && (q->iv->type == INV_TYPE_1CH))) {
|
|| ((q->cmd == MI_REQ_CH1) && (q->iv->type == INV_TYPE_1CH))) {
|
||||||
miComplete(q->iv);
|
miComplete(q->iv);
|
||||||
//closeRequest(q->iv, q->iv->miMultiParts > 5);
|
|
||||||
}
|
}
|
||||||
closeRequest(q->iv, true);
|
closeRequest(q, true, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -267,7 +268,7 @@ class Communication : public CommQueue<> {
|
||||||
if(NULL != mCbPayload)
|
if(NULL != mCbPayload)
|
||||||
(mCbPayload)(q->cmd, q->iv);
|
(mCbPayload)(q->cmd, q->iv);
|
||||||
|
|
||||||
closeRequest(q->iv);
|
closeRequest(q, true, true);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -278,8 +279,13 @@ class Communication : public CommQueue<> {
|
||||||
uint8_t tmp[4];
|
uint8_t tmp[4];
|
||||||
CP_U32_BigEndian(tmp, iv->radioId.u64 >> 8);
|
CP_U32_BigEndian(tmp, iv->radioId.u64 >> 8);
|
||||||
for(uint8_t i = 0; i < 4; i++) {
|
for(uint8_t i = 0; i < 4; i++) {
|
||||||
if(tmp[i] != buf[i])
|
if(tmp[i] != buf[i]) {
|
||||||
|
DPRINT(DBG_WARN, F("Inverter serial does not match, got: 0x"));
|
||||||
|
DHEX(buf[0]);DHEX(buf[1]);DHEX(buf[2]);DHEX(buf[3]);
|
||||||
|
DBGPRINT(F(", expected: 0x"));
|
||||||
|
DHEX(tmp[0]);DHEX(tmp[1]);DHEX(tmp[2]);DHEX(tmp[3]);
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -288,20 +294,20 @@ class Communication : public CommQueue<> {
|
||||||
return (ah::crc8(buf, len - 1) == buf[len-1]);
|
return (ah::crc8(buf, len - 1) == buf[len-1]);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void parseFrame(packet_t *p) {
|
inline bool parseFrame(packet_t *p) {
|
||||||
uint8_t *frameId = &p->packet[9];
|
uint8_t *frameId = &p->packet[9];
|
||||||
if(0x00 == *frameId) {
|
if(0x00 == *frameId) {
|
||||||
DPRINTLN(DBG_WARN, F("invalid frameId 0x00"));
|
DPRINTLN(DBG_WARN, F("invalid frameId 0x00"));
|
||||||
return; // skip current packet
|
return false; // skip current packet
|
||||||
}
|
}
|
||||||
if((*frameId & 0x7f) > MAX_PAYLOAD_ENTRIES) {
|
if((*frameId & 0x7f) > MAX_PAYLOAD_ENTRIES) {
|
||||||
DPRINTLN(DBG_WARN, F("local buffer to small for payload fragments"));
|
DPRINTLN(DBG_WARN, F("local buffer to small for payload fragments"));
|
||||||
return; // local storage is to small for id
|
return false; // local storage is to small for id
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!checkFrameCrc(p->packet, p->len)) {
|
if(!checkFrameCrc(p->packet, p->len)) {
|
||||||
DPRINTLN(DBG_WARN, F("frame CRC is wrong"));
|
DPRINTLN(DBG_WARN, F("frame CRC is wrong"));
|
||||||
return; // CRC8 is wrong, frame invalid
|
return false; // CRC8 is wrong, frame invalid
|
||||||
}
|
}
|
||||||
|
|
||||||
if((*frameId & ALL_FRAMES) == ALL_FRAMES)
|
if((*frameId & ALL_FRAMES) == ALL_FRAMES)
|
||||||
|
@ -311,9 +317,11 @@ class Communication : public CommQueue<> {
|
||||||
memcpy(f->buf, &p->packet[10], p->len-11);
|
memcpy(f->buf, &p->packet[10], p->len-11);
|
||||||
f->len = p->len - 11;
|
f->len = p->len - 11;
|
||||||
f->rssi = p->rssi;
|
f->rssi = p->rssi;
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void parseMiFrame(packet_t *p, const queue_s *q) {
|
inline bool parseMiFrame(packet_t *p, const queue_s *q) {
|
||||||
if ((p->packet[0] == MI_REQ_CH1 + ALL_FRAMES)
|
if ((p->packet[0] == MI_REQ_CH1 + ALL_FRAMES)
|
||||||
|| (p->packet[0] == MI_REQ_CH2 + ALL_FRAMES)
|
|| (p->packet[0] == MI_REQ_CH2 + ALL_FRAMES)
|
||||||
|| ((p->packet[0] >= (MI_REQ_4CH + ALL_FRAMES))
|
|| ((p->packet[0] >= (MI_REQ_4CH + ALL_FRAMES))
|
||||||
|
@ -330,6 +338,8 @@ class Communication : public CommQueue<> {
|
||||||
miStsConsolidate(q, ((p->packet[0] == 0x88) ? 1 : 2), rec, p->packet[10], p->packet[12], p->packet[9], p->packet[11]);
|
miStsConsolidate(q, ((p->packet[0] == 0x88) ? 1 : 2), rec, p->packet[10], p->packet[12], p->packet[9], p->packet[11]);
|
||||||
//mHeu.setGotFragment(q->iv); only do this when we are through the cycle?
|
//mHeu.setGotFragment(q->iv); only do this when we are through the cycle?
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void parseDevCtrl(packet_t *p, const queue_s *q) {
|
inline void parseDevCtrl(packet_t *p, const queue_s *q) {
|
||||||
|
@ -369,7 +379,7 @@ class Communication : public CommQueue<> {
|
||||||
DBGPRINTLN(F("-> Fail"));
|
DBGPRINTLN(F("-> Fail"));
|
||||||
/*q->iv->radioStatistics.rxFail++; // got fragments but not complete response
|
/*q->iv->radioStatistics.rxFail++; // got fragments but not complete response
|
||||||
cmdDone();*/
|
cmdDone();*/
|
||||||
closeRequest(q->iv, false, false);
|
closeRequest(q, false, false);
|
||||||
|
|
||||||
} else
|
} else
|
||||||
DBGPRINTLN(F("-> complete retransmit"));
|
DBGPRINTLN(F("-> complete retransmit"));
|
||||||
|
@ -417,7 +427,7 @@ class Communication : public CommQueue<> {
|
||||||
DBGPRINTLN(F(" bytes"));
|
DBGPRINTLN(F(" bytes"));
|
||||||
}
|
}
|
||||||
/*q->iv->radioStatistics.rxFail++;*/
|
/*q->iv->radioStatistics.rxFail++;*/
|
||||||
closeRequest(q->iv, false, false);
|
closeRequest(q, false, false);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -450,31 +460,29 @@ class Communication : public CommQueue<> {
|
||||||
mState = States::WAIT;
|
mState = States::WAIT;
|
||||||
} else {
|
} else {
|
||||||
add(q, true);
|
add(q, true);
|
||||||
closeRequest(q->iv, false);
|
closeRequest(q, false, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void closeRequest(Inverter<> *iv, bool succeeded = true, bool delCmd = true) {
|
void closeRequest(const queue_s *q, bool crcPass, bool delCmd) {
|
||||||
// ordering of lines is relevant for statistics
|
mHeu.evalTxChQuality(q->iv, crcPass, (4 - q->attempts), q->iv->curFrmCnt);
|
||||||
if(succeeded) {
|
if(crcPass)
|
||||||
mHeu.setGotAll(iv);
|
q->iv->radioStatistics.rxSuccess++;
|
||||||
iv->radioStatistics.rxSuccess++;
|
else if(q->iv->mGotFragment)
|
||||||
} else if(iv->mGotFragment) {
|
q->iv->radioStatistics.rxFail++; // got no complete payload
|
||||||
mHeu.setGotFragment(iv);
|
else {
|
||||||
iv->radioStatistics.rxFail++; // got no complete payload
|
q->iv->radioStatistics.rxFailNoAnser++; // got nothing
|
||||||
} else {
|
|
||||||
iv->radioStatistics.rxFailNoAnser++; // got nothing
|
|
||||||
mHeu.setGotNothing(iv);
|
|
||||||
mWaitTimeout = millis() + WAIT_GAP_TIMEOUT;
|
mWaitTimeout = millis() + WAIT_GAP_TIMEOUT;
|
||||||
}
|
}
|
||||||
|
|
||||||
cmdDone(delCmd);
|
cmdDone(delCmd);
|
||||||
iv->mGotFragment = false;
|
q->iv->mGotFragment = false;
|
||||||
iv->mGotLastMsg = false;
|
q->iv->mGotLastMsg = false;
|
||||||
iv->miMultiParts = 0;
|
q->iv->miMultiParts = 0;
|
||||||
mIsResend = false;
|
mIsResend = false;
|
||||||
mFirstTry = false; // for correct reset
|
mFirstTry = false; // for correct reset
|
||||||
mState = States::RESET;
|
mState = States::RESET;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void miHwDecode(packet_t *p, const queue_s *q) {
|
inline void miHwDecode(packet_t *p, const queue_s *q) {
|
||||||
|
@ -673,10 +681,10 @@ class Communication : public CommQueue<> {
|
||||||
}
|
}
|
||||||
|
|
||||||
if(q->iv->miMultiParts == 7) {
|
if(q->iv->miMultiParts == 7) {
|
||||||
mHeu.setGotAll(q->iv);
|
//mHeu.setGotAll(q->iv);
|
||||||
q->iv->radioStatistics.rxSuccess++;
|
q->iv->radioStatistics.rxSuccess++;
|
||||||
} else
|
} else
|
||||||
mHeu.setGotFragment(q->iv);
|
//mHeu.setGotFragment(q->iv);
|
||||||
/*iv->radioStatistics.rxFail++; // got no complete payload*/
|
/*iv->radioStatistics.rxFail++; // got no complete payload*/
|
||||||
//q->iv->radioStatistics.retransmits++;
|
//q->iv->radioStatistics.retransmits++;
|
||||||
q->iv->radio->sendCmdPacket(q->iv, cmd, 0x00, true);
|
q->iv->radio->sendCmdPacket(q->iv, cmd, 0x00, true);
|
||||||
|
|
|
@ -15,6 +15,11 @@
|
||||||
|
|
||||||
#define RF_TX_TEST_CHAN_1ST_USE 0xff
|
#define RF_TX_TEST_CHAN_1ST_USE 0xff
|
||||||
|
|
||||||
|
#define RF_TX_CHAN_QUALITY_GOOD 2
|
||||||
|
#define RF_TX_CHAN_QUALITY_OK 1
|
||||||
|
#define RF_TX_CHAN_QUALITY_LOW -1
|
||||||
|
#define RF_TX_CHAN_QUALITY_BAD -2
|
||||||
|
|
||||||
class Heuristic {
|
class Heuristic {
|
||||||
public:
|
public:
|
||||||
uint8_t getTxCh(Inverter<> *iv) {
|
uint8_t getTxCh(Inverter<> *iv) {
|
||||||
|
@ -25,7 +30,7 @@ class Heuristic {
|
||||||
|
|
||||||
// start with the next index: round robbin in case of same 'best' quality
|
// start with the next index: round robbin in case of same 'best' quality
|
||||||
uint8_t curId = (ih->txRfChId + 1) % RF_MAX_CHANNEL_ID;
|
uint8_t curId = (ih->txRfChId + 1) % RF_MAX_CHANNEL_ID;
|
||||||
uint8_t lastBestId = ih->txRfChId;
|
ih->lastBestTxChId = ih->txRfChId;
|
||||||
ih->txRfChId = curId;
|
ih->txRfChId = curId;
|
||||||
curId = (curId + 1) % RF_MAX_CHANNEL_ID;
|
curId = (curId + 1) % RF_MAX_CHANNEL_ID;
|
||||||
for(uint8_t i = 1; i < RF_MAX_CHANNEL_ID; i++) {
|
for(uint8_t i = 1; i < RF_MAX_CHANNEL_ID; i++) {
|
||||||
|
@ -37,14 +42,16 @@ class Heuristic {
|
||||||
if(ih->testPeriodSendCnt < 0xff)
|
if(ih->testPeriodSendCnt < 0xff)
|
||||||
ih->testPeriodSendCnt++;
|
ih->testPeriodSendCnt++;
|
||||||
|
|
||||||
if((ih->txRfChId == lastBestId) && (ih->testPeriodSendCnt >= RF_TEST_PERIOD_MAX_SEND_CNT)) {
|
if((ih->txRfChId == ih->lastBestTxChId) && (ih->testPeriodSendCnt >= RF_TEST_PERIOD_MAX_SEND_CNT)) {
|
||||||
if(ih->testPeriodFailCnt > RF_TEST_PERIOD_MAX_FAIL_CNT) {
|
if(ih->testPeriodFailCnt > RF_TEST_PERIOD_MAX_FAIL_CNT) {
|
||||||
// try round robbin another chan and see if it works even better
|
// try round robbin another chan and see if it works even better
|
||||||
ih->testChId = (ih->testChId + 1) % RF_MAX_CHANNEL_ID;
|
ih->testChId = (ih->testChId + 1) % RF_MAX_CHANNEL_ID;
|
||||||
if(ih->testChId == ih->txRfChId)
|
if(ih->testChId == ih->txRfChId)
|
||||||
ih->testChId = (ih->testChId + 1) % RF_MAX_CHANNEL_ID;
|
ih->testChId = (ih->testChId + 1) % RF_MAX_CHANNEL_ID;
|
||||||
|
|
||||||
// give it a fair chance but remember old status in case of immediate fail
|
// give it a fair chance but remember old status in case of immediate fail
|
||||||
|
ih->saveOldTestQuality = ih->txRfQuality[ih->testChId];
|
||||||
|
ih->txRfQuality[ih->testChId] = ih->txRfQuality[ih->txRfChId];
|
||||||
ih->txRfChId = ih->testChId;
|
ih->txRfChId = ih->testChId;
|
||||||
ih->testChId = RF_TX_TEST_CHAN_1ST_USE; // mark the chan as a test and as 1st use during new test period
|
ih->testChId = RF_TX_TEST_CHAN_1ST_USE; // mark the chan as a test and as 1st use during new test period
|
||||||
DPRINTLN(DBG_INFO, "Test CH " + String(id2Ch(ih->txRfChId)));
|
DPRINTLN(DBG_INFO, "Test CH " + String(id2Ch(ih->txRfChId)));
|
||||||
|
@ -53,7 +60,7 @@ class Heuristic {
|
||||||
// start new test period
|
// start new test period
|
||||||
ih->testPeriodSendCnt = 0;
|
ih->testPeriodSendCnt = 0;
|
||||||
ih->testPeriodFailCnt = 0;
|
ih->testPeriodFailCnt = 0;
|
||||||
} else if(ih->txRfChId != lastBestId) {
|
} else if(ih->txRfChId != ih->lastBestTxChId) {
|
||||||
// start new test period
|
// start new test period
|
||||||
ih->testPeriodSendCnt = 0;
|
ih->testPeriodSendCnt = 0;
|
||||||
ih->testPeriodFailCnt = 0;
|
ih->testPeriodFailCnt = 0;
|
||||||
|
@ -62,27 +69,52 @@ class Heuristic {
|
||||||
return id2Ch(ih->txRfChId);
|
return id2Ch(ih->txRfChId);
|
||||||
}
|
}
|
||||||
|
|
||||||
void setGotAll(Inverter<> *iv) {
|
void evalTxChQuality(Inverter<> *iv, bool crcPass, uint8_t retransmits, uint8_t rxFragments) {
|
||||||
updateQuality(iv, 2); // GOOD
|
|
||||||
}
|
|
||||||
|
|
||||||
void setGotFragment(Inverter<> *iv) {
|
|
||||||
updateQuality(iv, 1); // OK
|
|
||||||
}
|
|
||||||
|
|
||||||
void setGotNothing(Inverter<> *iv) {
|
|
||||||
HeuristicInv *ih = &iv->heuristics;
|
HeuristicInv *ih = &iv->heuristics;
|
||||||
|
|
||||||
if(RF_TX_TEST_CHAN_1ST_USE == ih->testChId) {
|
if(ih->lastRxFragments == rxFragments) {
|
||||||
// immediate fail
|
// nothing received: send probably lost
|
||||||
ih->testChId = ih->txRfChId; // reset to best
|
if(!retransmits || isNewTxCh(ih)) {
|
||||||
return;
|
if(RF_TX_TEST_CHAN_1ST_USE == ih->testChId) {
|
||||||
}
|
// switch back to original quality
|
||||||
|
ih->txRfQuality[ih->txRfChId] = ih->saveOldTestQuality;
|
||||||
|
|
||||||
if(ih->testPeriodFailCnt < 0xff)
|
updateQuality(ih, RF_TX_CHAN_QUALITY_BAD);
|
||||||
ih->testPeriodFailCnt++;
|
if(ih->testPeriodFailCnt < 0xff)
|
||||||
|
ih->testPeriodFailCnt++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if(!ih->lastRxFragments && crcPass) {
|
||||||
|
if(!retransmits || isNewTxCh(ih)) {
|
||||||
|
// every fragment received successfull immediately
|
||||||
|
updateQuality(ih, RF_TX_CHAN_QUALITY_GOOD);
|
||||||
|
} else {
|
||||||
|
// every fragment received successfully
|
||||||
|
updateQuality(ih, RF_TX_CHAN_QUALITY_OK);
|
||||||
|
}
|
||||||
|
} else if(crcPass) {
|
||||||
|
if(isNewTxCh(ih)) {
|
||||||
|
// last Fragment successfully received on new send channel
|
||||||
|
updateQuality(ih, RF_TX_CHAN_QUALITY_OK);
|
||||||
|
}
|
||||||
|
} else if(!retransmits || isNewTxCh(ih)) {
|
||||||
|
// no complete receive for this send channel
|
||||||
|
if((rxFragments - ih->lastRxFragments) > 2) {
|
||||||
|
// graceful evaluation for big inverters that have to send 4 answer packets
|
||||||
|
updateQuality(ih, RF_TX_CHAN_QUALITY_OK);
|
||||||
|
} else if((rxFragments - ih->lastRxFragments) < 2) {
|
||||||
|
if(RF_TX_TEST_CHAN_1ST_USE == ih->txRfChId) {
|
||||||
|
// switch back to original quality
|
||||||
|
ih->txRfQuality[ih->txRfChId] = ih->saveOldTestQuality;
|
||||||
|
}
|
||||||
|
updateQuality(ih, RF_TX_CHAN_QUALITY_LOW);
|
||||||
|
if(ih->testPeriodFailCnt < 0xff)
|
||||||
|
ih->testPeriodFailCnt++;
|
||||||
|
} // else: _QUALITY_NEUTRAL, keep any test channel
|
||||||
|
} // else: dont overestimate burst distortion
|
||||||
|
|
||||||
updateQuality(iv, -2); // BAD
|
ih->testChId = ih->txRfChId; // reset to best
|
||||||
|
ih->lastRxFragments = rxFragments;
|
||||||
}
|
}
|
||||||
|
|
||||||
void printStatus(Inverter<> *iv) {
|
void printStatus(Inverter<> *iv) {
|
||||||
|
@ -105,9 +137,11 @@ class Heuristic {
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void updateQuality(Inverter<> *iv, uint8_t quality) {
|
bool isNewTxCh(HeuristicInv *ih) {
|
||||||
HeuristicInv *ih = &iv->heuristics;
|
return ih->txRfChId != ih->lastBestTxChId;
|
||||||
|
}
|
||||||
|
|
||||||
|
void updateQuality(HeuristicInv *ih, uint8_t quality) {
|
||||||
ih->txRfQuality[ih->txRfChId] += quality;
|
ih->txRfQuality[ih->txRfChId] += quality;
|
||||||
if(ih->txRfQuality[ih->txRfChId] > RF_MAX_QUALITY)
|
if(ih->txRfQuality[ih->txRfChId] > RF_MAX_QUALITY)
|
||||||
ih->txRfQuality[ih->txRfChId] = RF_MAX_QUALITY;
|
ih->txRfQuality[ih->txRfChId] = RF_MAX_QUALITY;
|
||||||
|
|
|
@ -19,11 +19,14 @@ class HeuristicInv {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
int8_t txRfQuality[RF_MAX_CHANNEL_ID]; // heuristics tx quality (check 'Heuristics.h')
|
int8_t txRfQuality[RF_MAX_CHANNEL_ID]; // heuristics tx quality (check 'Heuristics.h')
|
||||||
uint8_t txRfChId = 0; // RF TX channel id
|
uint8_t txRfChId = 0; // RF TX channel id
|
||||||
|
uint8_t lastBestTxChId = 0;
|
||||||
|
|
||||||
uint8_t testPeriodSendCnt = 0;
|
uint8_t testPeriodSendCnt = 0;
|
||||||
uint8_t testPeriodFailCnt = 0;
|
uint8_t testPeriodFailCnt = 0;
|
||||||
uint8_t testChId = 0;
|
uint8_t testChId = 0;
|
||||||
|
int8_t saveOldTestQuality = -6;
|
||||||
|
uint8_t lastRxFragments = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /*__HEURISTIC_INV_H__*/
|
#endif /*__HEURISTIC_INV_H__*/
|
||||||
|
|
|
@ -129,6 +129,7 @@ class Inverter {
|
||||||
uint8_t miMultiParts; // helper info for MI multiframe msgs
|
uint8_t miMultiParts; // helper info for MI multiframe msgs
|
||||||
uint8_t outstandingFrames; // helper info to count difference between expected and received frames
|
uint8_t outstandingFrames; // helper info to count difference between expected and received frames
|
||||||
bool mGotFragment; // shows if inverter has sent at least one fragment
|
bool mGotFragment; // shows if inverter has sent at least one fragment
|
||||||
|
uint8_t curFrmCnt; // count received frames in current loop
|
||||||
bool mGotLastMsg; // shows if inverter has already finished transmission cycle
|
bool mGotLastMsg; // shows if inverter has already finished transmission cycle
|
||||||
Radio *radio; // pointer to associated radio class
|
Radio *radio; // pointer to associated radio class
|
||||||
statistics_t radioStatistics; // information about transmitted, failed, ... packets
|
statistics_t radioStatistics; // information about transmitted, failed, ... packets
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue