Skip to content

Commit

Permalink
Using bursts average RSSI value (#71)
Browse files Browse the repository at this point in the history
  • Loading branch information
marcomicera committed Dec 22, 2019
1 parent 177eb20 commit 9409a4a
Show file tree
Hide file tree
Showing 2 changed files with 105 additions and 15 deletions.
52 changes: 41 additions & 11 deletions core/server/src/receiver.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -38,25 +38,41 @@ void receiver::addBatch(const followifier::Batch &newBatch, database &database)

/* Insert it into the set of boards that have sent a message during the last round */
lastRoundBoardMacs.insert(newBatch.boardmac());
#endif

/* Printing received messages */
if (newBatch.messages_size() > 0) { // if there is at least one message in it
int messageCounter = 1;
for (const auto &newMessage : newBatch.messages()) { // print all messages
cout << messageCounter++ << ")\t" << logMessage(newMessage) << endl;
}
}
cout << endl << endl;

#ifndef ROUNDLESS_MODE
/* True when all boards have sent the same frame, hence it's time for a new round */
bool aFrameHasBeenSentByAllBoards = false;
#endif

/* Average RSSI value for each bursts: Probe Request frames belonging to the same burst are considered
* to be received subsequently.
* Every average RSSI value is paired to the number of contributions needed to compute the average.
*/
typedef std::pair<double, unsigned int> avg_t; // RSSI average value and number of contributions
std::unordered_map<burst, avg_t, burst::burst_hasher> burstAverages;

/* For printing purposes */
unsigned short messageCounter = 1;

/* For each message in the batch */
for (const followifier::ESP32Message &newMessage: newBatch.messages()) {

/* Burst to which this message belongs to */
burst currentBurst = burst(newMessage);

/* Retrieving corresponding burst */
if (burstAverages.find(currentBurst) == burstAverages.end()) {

/* New burst */
burstAverages.insert(std::pair<burst, avg_t>(currentBurst,
std::pair<double, unsigned int>(newMessage.metadata().rssi(),
1)));
} else {

/* Updating average of the existing burst */
burstAverages[currentBurst].first += (newMessage.metadata().rssi() - burstAverages[currentBurst].first) /
(burstAverages[currentBurst].second++);
}

/* If this frame has been sent already */
if (messagesBuffer.find(newMessage.frame_hash()) !=
messagesBuffer.end()) { // lower complexity than `equal_range()`
Expand Down Expand Up @@ -88,6 +104,12 @@ void receiver::addBatch(const followifier::Batch &newBatch, database &database)
messagesAge.insert(std::make_pair(newMessage.frame_hash(), 0));
}

/* Metadata alteration: inserting the burst average RSSI value */
messagesBuffer.find(newMessage.frame_hash())->second[newBatch.boardmac()].set_rssi(
burstAverages[currentBurst].first);

/* Print message to screen */
cout << messageCounter++ << ")\t" << logMessage(newMessage, burstAverages[currentBurst].first) << endl;

/* If this message has been sent by all other boards */
if (messagesBuffer.find(newMessage.frame_hash())->second.size() == NUMBER_BOARDS) {
Expand Down Expand Up @@ -123,6 +145,12 @@ void receiver::addBatch(const followifier::Batch &newBatch, database &database)
}
}

// Printing bursts average values
// for (auto &burstAverage: burstAverages) {
// cout << "Burst " << std::string(burstAverage.first) << " has an average RSSI value of "
// << burstAverage.second.first << "." << endl;
// }

#ifndef ROUNDLESS_MODE
/* Number of boards seen during this round assertion */
if (aFrameHasBeenSentByAllBoards && (lastRoundBoardMacs.size() != NUMBER_BOARDS)) {
Expand All @@ -143,6 +171,8 @@ void receiver::addBatch(const followifier::Batch &newBatch, database &database)

/* Delete old and unused messages */
cleanMessagesBuffer();

cout << endl << endl;
}

void receiver::cleanMessagesBuffer() {
Expand Down
68 changes: 64 additions & 4 deletions core/server/src/receiver.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,13 +30,61 @@ using boost::uuids::detail::md5;
*/
#define MESSAGES_CLEANING_AGE_THRESHOLD 20

/*
* Maps frame hashes to their senders with their corresponding metadata.
*/
typedef std::unordered_map<
std::string, // frame hash
std::unordered_map< // sender
std::string, // board's MAC address
followifier::ESP32Metadata
>> messages_map;

/**
* Probe Request burst type: device MAC address and timestamp.
*/
struct burst {

/**
* MAC address of the device which has sent the Probe Request burst.
*/
std::string deviceMac;

/**
* At what time the burst has been sent.
*/
::google::protobuf::int64 timestamp;

public:

explicit burst(std::string deviceMac, ::google::protobuf::int64 timestamp) : deviceMac(std::move(deviceMac)),
timestamp(timestamp) {}

explicit burst(const followifier::ESP32Message &message) : deviceMac(message.metadata().devicemac()),
timestamp(message.metadata().timestamp()) {}

bool operator==(const burst &other) const {
return deviceMac == other.deviceMac && timestamp == other.timestamp;
}

bool operator!=(const burst &other) const {
return !(other == *this);
}

struct burst_hasher {
std::size_t operator()(const burst &b) const {
std::size_t result = 0;
boost::hash_combine(result, b.deviceMac);
boost::hash_combine(result, b.timestamp);
return result;
}
};

explicit operator std::string() const {
return deviceMac.substr(deviceMac.length() - 3) + "@" + std::to_string(timestamp);
}
};

/**
* Receives and filters batches from all boards.
*/
Expand All @@ -52,7 +100,7 @@ class receiver {
/**
* Messages buffer mapping frame hashes to boards' metadata.
*/
static messages_map messagesBuffer;
static messages_map messagesBuffer; // TODO Make it a map of frame hashes (string) to number of senders (unsigned short)

/**
* Stores the age of every frame hash.
Expand All @@ -76,9 +124,9 @@ class receiver {
*/
static void addBatch(const followifier::Batch &newBatch, database &database);

/**
* Deletes old and unused messages from the messages buffer.
*/
/**
* Deletes old and unused messages from the messages buffer.
*/
static void cleanMessagesBuffer();

/**
Expand All @@ -88,8 +136,20 @@ class receiver {
* @return a string representation of the message.
*/
static std::string logMessage(const followifier::ESP32Message &message) {
return logMessage(message, 1);
}

/**
* Logs a Proto message following its own format, indicating the burst average RSSI approximation.
*
* @param message message to be printed.
* @param burstAvgRssi burst average RSSI value. +1 if not being used.
* @return a string representation of the message.
*/
static std::string logMessage(const followifier::ESP32Message &message, double burstAvgRssi) {
return "< Hash: " + prettyHash(message.frame_hash()) +
", RSSI: " + std::to_string(message.metadata().rssi()) +
((burstAvgRssi != 1) ? (" -> " + std::to_string(burstAvgRssi) + " (burst approx.)") : "") +
", Src MAC: " + message.metadata().devicemac() +
", Timestamp: " + std::to_string(message.metadata().timestamp()) + ">";
}
Expand Down

0 comments on commit 9409a4a

Please sign in to comment.