From 9409a4aa1feafdb69c04fa9362bee56ccc2c11ee Mon Sep 17 00:00:00 2001 From: Marco Micera Date: Sun, 22 Dec 2019 01:58:25 +0100 Subject: [PATCH] Using bursts average RSSI value (#71) --- core/server/src/receiver.cpp | 52 +++++++++++++++++++++------ core/server/src/receiver.h | 68 +++++++++++++++++++++++++++++++++--- 2 files changed, 105 insertions(+), 15 deletions(-) diff --git a/core/server/src/receiver.cpp b/core/server/src/receiver.cpp index 2ba5a96..8c82bab 100644 --- a/core/server/src/receiver.cpp +++ b/core/server/src/receiver.cpp @@ -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 avg_t; // RSSI average value and number of contributions + std::unordered_map 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(currentBurst, + std::pair(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()` @@ -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) { @@ -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)) { @@ -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() { diff --git a/core/server/src/receiver.h b/core/server/src/receiver.h index 76534cd..9036374 100644 --- a/core/server/src/receiver.h +++ b/core/server/src/receiver.h @@ -30,6 +30,9 @@ 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 @@ -37,6 +40,51 @@ typedef std::unordered_map< 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. */ @@ -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. @@ -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(); /** @@ -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()) + ">"; }