Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Boards calibration #67

Open
wants to merge 21 commits into
base: master
Choose a base branch
from
Open
Changes from 1 commit
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
b6c7a82
Calibration: countdown timer (#58)
marcomicera Nov 24, 2019
6f7e8e4
Calibration: RSSI average (#58)
marcomicera Nov 25, 2019
d41cd46
Calibration: using custom 1-meter-distance RSSI values (#58)
marcomicera Nov 25, 2019
b904003
Calibration: JSON dedicated object + README instructions (#58)
marcomicera Nov 26, 2019
f154795
Calibration: average computation fix (#58)
marcomicera Nov 26, 2019
4d568ab
Calibration: placement duration parameter description fix (#58)
marcomicera Nov 26, 2019
07591df
Calibration: uniform "placement" terminology (#58)
marcomicera Nov 26, 2019
cc97777
Async calibration trial (#58)
marcomicera Nov 26, 2019
58303f3
Calibration should now work. It still has to be tested with
simonasaitta Nov 26, 2019
141376b
Now you should not have to wait anymore between one board calibration…
simonasaitta Nov 26, 2019
0a4484a
Missing check on bytes sent from board
simonasaitta Nov 27, 2019
21b0c70
Seems to have fixed issue with board send but needs further testing.
simonasaitta Nov 27, 2019
b043c24
Resolved some instances of board that would get it stuck. Now core di…
simonasaitta Nov 27, 2019
23c7c08
Synchronized batch sending between boards
simonasaitta Nov 27, 2019
d75e540
Uniform board TAG w/ MAC last two digits. Closes #62
marcomicera Nov 28, 2019
93d45b4
Removed verbose logging (calib. batches sent by other devices)
marcomicera Nov 28, 2019
3a6ea5c
Calibration: comments + static calibrated boards counter
marcomicera Nov 28, 2019
365ab18
Calibration: logging announced distances once per estimation
marcomicera Nov 28, 2019
9fd7c53
Some refactoring and comments
simonasaitta Nov 28, 2019
4fb7d8c
point is discarded if not in room
simonasaitta Nov 28, 2019
0854975
Merge branch 'master' into calibration
marcomicera Dec 3, 2019
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Some refactoring and comments
  • Loading branch information
simonasaitta committed Nov 28, 2019
commit 9fd7c53cd2744f556171338795a7052feaf8e1a7
25 changes: 25 additions & 0 deletions core/server/src/calibration.cpp
Original file line number Diff line number Diff line change
@@ -3,3 +3,28 @@
std::string calibration::board_to_calibrate;
long int calibration::starting_timestamp;
short calibration::board_counter = 0;
bool calibration::board_has_sent_calibration_batch;


void calibration::wait_placement(const std::string &board_mac) {

/* How many seconds are left for the user so s/he can place the board at 1 meter distance */
int board_placements_seconds_left = Settings::configuration.calibration_placement_duration_in_seconds.value();

std::cout << "Please place device " << Settings::configuration.calibration_device_mac_address.value()
<< " at 1 meter distance from board " << board_mac << " (" << (++calibration::board_counter) << "/"
<< Settings::get_num_boards() << ")." << std::endl;

/* `INITIALIZATION_BOARD_PLACEMENT_WAITING_TIME` seconds countdown starts now */
while (board_placements_seconds_left > 0) {
std::cout << "\r" << board_placements_seconds_left << " second"
<< (board_placements_seconds_left > 1 ? "s" : "") << " left... " << std::flush;
sleep(1);
--board_placements_seconds_left;
}
std::cout << "\rReady to calibrate board " << board_mac << ". Please do not move the device any further."
<< std::endl;
/* The timestamp corresponding to the instant the device has been placed is stored so that it can be used
* to discard messages before that instant*/
starting_timestamp = std::time(nullptr);
}
25 changes: 4 additions & 21 deletions core/server/src/calibration.h
Original file line number Diff line number Diff line change
@@ -25,32 +25,15 @@ class calibration {

static long int starting_timestamp;

static bool board_has_sent_calibration_batch;

/**
* Waits for the user to place the specified board at 1 meter distance from the server.
*
* @param board_mac MAC address of the board to be placed.
*/
static void wait_placement(const std::string &board_mac) {

/* How many seconds are left for the user so s/he can place the board at 1 meter distance */
int board_placements_seconds_left = Settings::configuration.calibration_placement_duration_in_seconds.value();

std::cout << "Please place device " << Settings::configuration.calibration_device_mac_address.value()
<< " at 1 meter distance from board " << board_mac << " (" << (++calibration::board_counter) << "/"
<< Settings::get_num_boards() << ")." << std::endl;

/* `INITIALIZATION_BOARD_PLACEMENT_WAITING_TIME` seconds countdown starts now */
while (board_placements_seconds_left > 0) {
std::cout << "\r" << board_placements_seconds_left << " second"
<< (board_placements_seconds_left > 1 ? "s" : "") << " left... " << std::flush;
sleep(1);
--board_placements_seconds_left;
}
std::cout << "\rReady to calibrate board " << board_mac << ". Please do not move the device any further."
<< std::endl;
starting_timestamp = std::time(nullptr);
}
};
static void wait_placement(const std::string &board_mac);

};

#endif //CORE_CALIBRATION_H
158 changes: 154 additions & 4 deletions core/server/src/connection.cpp
Original file line number Diff line number Diff line change
@@ -1,15 +1,12 @@
#include <boost/enable_shared_from_this.hpp>
#include <boost/bind.hpp>
#include "connection.h"
#include <string>
#include <google/protobuf/stubs/common.h>
#include <gen/message.pb.h>
#include "receiver.h"

using std::cout;
using std::cerr;
using std::endl;


connection::pointer connection::create(boost::asio::io_service &io_service) {
return connection::pointer(new connection(io_service));
}
@@ -24,3 +21,156 @@ connection::~connection() {
// TODO Is there something else to take care of?
socket_.close();
}

void connection::async_batch_read_for_statistics() {
async_read(&connection::statistics_packet_handler, "statistics");
}

void connection::async_batch_read_for_calibration() {
async_read(&connection::calibration_packet_handler, "calibration");
}

void connection::statistics_packet_handler(const followifier::Batch &batch) {
database database;
if (Settings::configuration.boards.find(batch.boardmac()) == Settings::configuration.boards.end()) {
// cerr << "Unknown source" << endl;
return;
}
receiver::addBatch(batch, database);
}

void connection::calibration_packet_handler(const followifier::Batch &batch) {

/* Data structures for reading purposes */
boost::system::error_code error; // connection may fail
double average_rssi = 0;
int number_of_messages_sent_by_calibration_device = 0;

/* Count the number of messages sent by the calibration device and also
* compute the average RSSI in the meantime
*/
for (const auto &message: batch.messages()) {

/* Filtering messages that are not being sent by the calibration device and
* whose timestamp greater than the calibration start time
*/
if (boost::iequals(message.metadata().devicemac(),
Settings::configuration.calibration_device_mac_address.value()) &&
message.metadata().timestamp() >= calibration::starting_timestamp) {

/* Counting the number of messages suitable for the average 1-meter-distance RSSI computation */
++number_of_messages_sent_by_calibration_device;

/* Summing up 1-meter-distance RSSI values */
average_rssi += message.metadata().rssi();
}
}

/* Computing the average 1-meter-distance RSSI value for this board */
average_rssi /= number_of_messages_sent_by_calibration_device;

/* If batch has been sent from the board that is being calibrated */
if (boost::iequals(batch.boardmac(), calibration::board_to_calibrate)) { // case-insensitive comparison

/* There needs to be at least `Settings::configuration.min_num_calibration_messages`
* messages in the batch in order to compute a meaningful RSSI average
*/
if (number_of_messages_sent_by_calibration_device < Settings::configuration.min_num_calibration_messages) {

/* Logging */
std::cout << "Device " << Settings::configuration.calibration_device_mac_address.value() << " has sent "
<< number_of_messages_sent_by_calibration_device << " calibration messages after timestamp "
<< calibration::starting_timestamp << ". At least "
<< Settings::configuration.min_num_calibration_messages.value()
<< (Settings::configuration.min_num_calibration_messages.value() == 1 ? " is" : " are")
<< " needed." << std::endl;
} else { // batch contained enough messages

/* Logging */
std::cout << "Device " << Settings::configuration.calibration_device_mac_address.value() << " has sent "
<< number_of_messages_sent_by_calibration_device << " calibration messages after timestamp "
<< calibration::starting_timestamp << "." << std::endl;

/* Store the average 1-meter-distance RSSI value */
statistics::insert_one_meter_rssi(calibration::board_to_calibrate, average_rssi);
std::cout << "Board " << calibration::board_to_calibrate << " detected an average RSSI of "
<< average_rssi << " from device "
<< Settings::configuration.calibration_device_mac_address.value() << "." << std::endl
<< std::endl;

calibration::board_has_sent_calibration_batch = true;
for (auto &board : Settings::configuration.boards) {

/* This board's MAC address */
calibration::board_to_calibrate = board.first;

if (!statistics::has_been_calibrated(calibration::board_to_calibrate)) {

/* Wait for the user to place this board */
if (calibration::board_has_sent_calibration_batch) {
calibration::wait_placement(calibration::board_to_calibrate);
calibration::board_has_sent_calibration_batch = false;
}
/* the first not calibrated board has been found */

return;
}
/* If the code arrives here it means that all the boards have been calibrated */
}
}
}
}

void connection::async_read(packet_handler_t packet_handler,
const std::string &operation_message) {

boost::asio::async_read_until(socket_, buf, delimiter,
boost::bind(&connection::async_packet_handler_wrapper, shared_from_this(),
boost::asio::placeholders::error,
boost::asio::placeholders::bytes_transferred,
packet_handler,
operation_message));
}

void connection::async_packet_handler_wrapper(const boost::system::error_code &error,
size_t transferred_bytes,
packet_handler_t packet_handler,
const std::string &operation) {

if (error) { // an error occurred
throw std::runtime_error("An error occurred during an asynchronous read in the " + operation +
" operation failed: (error code " + std::to_string(error.value()) + " " +
error.message() + ", number of transferred bytes: " +
std::to_string(transferred_bytes) + ")");
} else if (transferred_bytes == 0) { // no bytes have been transferred
throw std::runtime_error("An asynchronous read performed during the " + operation +
" operation returned no bytes at all: (error code " +
std::to_string(error.value()) + " " + error.message() +
", number of transferred bytes: " + std::to_string(transferred_bytes) + ")");
} else if (buf.size() < transferred_bytes) { // buf contains more data beyond the delimiter
throw std::runtime_error("Buffer-related error during the " + operation + "operation: buffer size is " +
std::to_string(buf.size()) + ", while " + std::to_string(transferred_bytes) +
" bytes have been transferred");
} else {

/* This wrapper reads a batch */
followifier::Batch batch;

/* Extract up to the first delimiter */
std::string data{
buffers_begin(buf.data()),
buffers_begin(buf.data()) + transferred_bytes - delimiter.size()
};

/* Consume through the first delimiter so that subsequent async_read_until will not reiterate over the same data. */
buf.consume(transferred_bytes);

/* Parsing the just-received batch */
if (!batch.ParseFromString(data)) {
throw std::runtime_error("Couldn't parse a batch of size " + std::to_string(data.length()) + ".");
}

/* Calling the actual packet handler */
(*this.*packet_handler)(batch);
}
}
Loading