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

First commit and implementation of transmit_globalpath #469

Open
wants to merge 6 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
88 changes: 73 additions & 15 deletions src/network_systems/lib/sailbot_db/inc/sailbot_db.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,19 +7,22 @@
#include <mongocxx/instance.hpp>
#include <mongocxx/pool.hpp>

#include "global_path.pb.h"
#include "sensors.pb.h"
#include "waypoint.pb.h"

// >>>>IMPORTANT<<<<<
// BSON document formats from: https://ubcsailbot.atlassian.net/wiki/spaces/prjt22/pages/1907589126/Database+Schemas:

const std::string COLLECTION_AIS_SHIPS = "ais_ships";
const std::string COLLECTION_BATTERIES = "batteries";
const std::string COLLECTION_DATA_SENSORS = "data_sensors";
const std::string COLLECTION_GPS = "gps";
const std::string COLLECTION_WIND_SENSORS = "wind_sensors";
const std::string COLLECTION_LOCAL_PATH = "local_path";
const std::string MONGODB_CONN_STR = "mongodb://localhost:27017";
const std::string COLLECTION_AIS_SHIPS = "ais_ships";
const std::string COLLECTION_BATTERIES = "batteries";
const std::string COLLECTION_DATA_SENSORS = "data_sensors";
const std::string COLLECTION_GPS = "gps";
const std::string COLLECTION_WIND_SENSORS = "wind_sensors";
const std::string COLLECTION_LOCAL_PATH = "local_path";
const std::string COLLECTION_GLOBAL_PATH = "global_path";
const std::string COLLECTION_IRIDIUM_RESPONSE = "iridium_response";
const std::string MONGODB_CONN_STR = "mongodb://localhost:27017";

template <typename T>
using ProtoList = google::protobuf::RepeatedPtrField<T>;
Expand All @@ -46,14 +49,6 @@ class SailbotDB
* @brief overload stream operator
*/
friend std::ostream & operator<<(std::ostream & os, const RcvdMsgInfo & info);

/**
* @brief Get a properly formatted timestamp string
*
* @param tm standard C/C++ time structure
* @return tm converted to a timestamp string
*/
static std::string mkTimestamp(const std::tm & tm);
};

/**
Expand All @@ -79,6 +74,14 @@ class SailbotDB
*/
bool testConnection();

/**
* @brief Get a properly formatted timestamp string
*
* @param tm standard C/C++ time structure
* @return tm converted to a timestamp string
*/
static std::string mkTimestamp(const std::tm & tm);

/**
* @brief Write new sensor data to the database
*
Expand All @@ -90,6 +93,61 @@ class SailbotDB
*/
bool storeNewSensors(const Polaris::Sensors & sensors_pb, RcvdMsgInfo new_info);

/**
* @brief Write new sensor data to the database
*
* @param global_pb Protobuf GlobalPath object
* @param timestamp Timestamp for data
*
* @return true if successful
* @return false on failure
*/
bool storeNewGlobalPath(const Polaris::GlobalPath & global_pb, const std::string & timestamp);

/**
* @brief Write global path data to the database
*
* @param global_path_pb Protobuf list of global path objects
* @param timestamp transmission time <year - 2000>-<month>-<day> <hour>:<minute>:<second>
* @param client mongocxx::client instance for the current thread

* @return true if successful
* @return false on failure
*/
bool storeNewGlobalPath(
const Polaris::GlobalPath & global_path_pb, const std::string & timestamp, mongocxx::client & client);

/**
* @brief Write iridium response data to the database
*
* @param response OK or FAILED
* @param error MO message error code
* @param message message given by rockblock server
* @param timestamp transmission time <year - 2000>-<month>-<day> <hour>:<minute>:<second>

* @return true if successful
* @return false on failure
*/
bool storeIridiumResponse(
const std::string & response, const std::string & error, const std::string & message,
const std::string & timestamp);

/**
* @brief Write iridum response data to the database
*
* @param response OK or FAILED
* @param error MO message error code
* @param message message given by rockblock server
* @param timestamp transmission time <year - 2000>-<month>-<day> <hour>:<minute>:<second>
* @param client mongocxx::client instance for the current thread
*
* @return true if successful
* @return false on failure
*/
bool storeIridiumResponse(
const std::string & response, const std::string & error, const std::string & message,
const std::string & timestamp, mongocxx::client & client);

protected:
const std::string db_name_; // Name of the database
std::unique_ptr<mongocxx::pool> pool_; // pool of clients for thread safety
Expand Down
58 changes: 58 additions & 0 deletions src/network_systems/lib/sailbot_db/inc/util_db.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@ class UtilDB : public SailbotDB
*/
Polaris::Sensors genRandSensors();

Polaris::GlobalPath genGlobalPath();

/**
* @return timestamp for the current time
*/
Expand All @@ -48,6 +50,14 @@ class UtilDB : public SailbotDB
*/
std::pair<Polaris::Sensors, SailbotDB::RcvdMsgInfo> genRandData(const std::tm & tm);

/**
* @brief Generate random global path data
*
* @param tm Timestamp returned by getTimestamp() (with any modifications made to it)
* @return std::pair<Polaris::GlobalPath, std::string>
*/
std::pair<Polaris::GlobalPath, std::string> genGlobalData(const std::tm & tm);

/**
* @brief Query the database and check that the sensor and message are correct
*
Expand All @@ -57,6 +67,27 @@ class UtilDB : public SailbotDB
bool verifyDBWrite(
std::span<Polaris::Sensors> expected_sensors, std::span<SailbotDB::RcvdMsgInfo> expected_msg_info);

/**
* @brief Query the database and check that the global path and timestamp are correct
*
* @param expected_globalpath
* @param expected_timestamp
*/
bool verifyDBWrite_GlobalPath(
std::span<Polaris::GlobalPath> expected_globalpath, std::span<std::string> expected_timestamp);

/**
* @brief Query the database and check that the Iridium response, error code, message, and timestamp are correct
*
* @param expected_response
* @param expected_error
* @param expected_message
* @param expected_timestamp
*/
bool verifyDBWrite_IridiumResponse(
std::span<std::string> expected_response, std::span<std::string> expected_error,
std::span<std::string> expected_message, std::span<std::string> expected_timestamp);

/**
* @brief Dump and check all sensors and timestamps from the database
*
Expand All @@ -67,6 +98,26 @@ class UtilDB : public SailbotDB
std::pair<std::vector<Polaris::Sensors>, std::vector<std::string>> dumpSensors(
utils::FailTracker & tracker, size_t expected_num_docs = 1);

/**
* @brief Dump and check all global paths and timestamps from the database
*
* @param tracker FailureTracker that gets if any unexpected results are dumped
* @param expected_num_docs Expected number of documents. tracker is updated if there's a mismatch
* @return std::pair{Vector of dumped Global Paths, Vector of dumped timestamps}
*/
std::pair<std::vector<Polaris::GlobalPath>, std::vector<std::string>> dumpGlobalpath(
utils::FailTracker & tracker, size_t expected_num_docs = 1);

/**
* @brief Dump and check all Iridium responses and timestamps from the database
*
* @param tracker FailureTracker that gets if any unexpected results are dumped
* @param expected_num_docs Expected number of documents. tracker is updated if there's a mismatch
* @return std::tuple{Vector of dumped responses, Vector of dumped error codes, Vector of dumped messages, Vector of dumped timestamps}
*/
std::tuple<std::vector<std::string>, std::vector<std::string>, std::vector<std::string>, std::vector<std::string>>
dumpIridiumResponse(utils::FailTracker & tracker, size_t expected_num_docs = 1);

private:
std::shared_ptr<std::mt19937> rng_; // random number generator

Expand Down Expand Up @@ -111,4 +162,11 @@ class UtilDB : public SailbotDB
* @param path_data Path data to modify
*/
void genRandPathData(Polaris::Sensors::Path & path_data);

/**
* @brief generate random global path data
*
* @param global_path_data Global path data to modify
*/
void genGlobalPathData(Polaris::GlobalPath & global_path_data);
};
47 changes: 46 additions & 1 deletion src/network_systems/lib/sailbot_db/src/sailbot_db.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,12 @@
#include <mongocxx/instance.hpp>
#include <sstream>

#include "global_path.pb.h"
#include "sensors.pb.h"
#include "waypoint.pb.h"

namespace bstream = bsoncxx::builder::stream;
using Polaris::GlobalPath;
using Polaris::Sensors;

mongocxx::instance SailbotDB::inst_{}; // staticallly initialize instance
Expand All @@ -33,7 +35,7 @@ std::ostream & operator<<(std::ostream & os, const SailbotDB::RcvdMsgInfo & info
return os;
}

std::string SailbotDB::RcvdMsgInfo::mkTimestamp(const std::tm & tm)
std::string SailbotDB::mkTimestamp(const std::tm & tm)
{
// This is impossible to read. It's reading each field of tm and 0 padding it to 2 digits with either "-" or ":"
// in between each number
Expand Down Expand Up @@ -82,6 +84,19 @@ bool SailbotDB::storeNewSensors(const Sensors & sensors_pb, RcvdMsgInfo new_info

// END PUBLIC

bool SailbotDB::storeNewGlobalPath(const GlobalPath & global_pb, const std::string & timestamp)
{
mongocxx::pool::entry entry = pool_->acquire();
return storeNewGlobalPath(global_pb, timestamp, *entry);
}

bool SailbotDB::storeIridiumResponse(
const std::string & response, const std::string & error, const std::string & message, const std::string & timestamp)
{
mongocxx::pool::entry entry = pool_->acquire();
return storeIridiumResponse(response, error, message, timestamp, *entry);
}

// PRIVATE

bool SailbotDB::storeGps(const Sensors::Gps & gps_pb, const std::string & timestamp, mongocxx::client & client)
Expand Down Expand Up @@ -175,4 +190,34 @@ bool SailbotDB::storePathSensors(
return static_cast<bool>(local_path_coll.insert_one(local_path_doc.view()));
}

bool SailbotDB::storeNewGlobalPath(
const Polaris::GlobalPath & global_path_pb, const std::string & timestamp, mongocxx::client & client)
{
mongocxx::database db = client[db_name_];
mongocxx::collection global_path_coll = db[COLLECTION_GLOBAL_PATH];
bstream::document doc_builder{};
auto global_path_doc_arr = doc_builder << "waypoints" << bstream::open_array;
ProtoList<Polaris::Waypoint> waypoints = global_path_pb.waypoints();
for (const Polaris::Waypoint & waypoint : waypoints) {
global_path_doc_arr = global_path_doc_arr << bstream::open_document << "latitude" << waypoint.latitude()
<< "longitude" << waypoint.longitude() << bstream::close_document;
}
DocVal global_path_doc = global_path_doc_arr << bstream::close_array << "timestamp" << timestamp
<< bstream::finalize;
return static_cast<bool>(global_path_coll.insert_one(global_path_doc.view()));
}

bool SailbotDB::storeIridiumResponse(
const std::string & response, const std::string & error, const std::string & message, const std::string & timestamp,
mongocxx::client & client)
{
mongocxx::database db = client[db_name_];
mongocxx::collection iridium_response_coll = db[COLLECTION_IRIDIUM_RESPONSE];

DocVal iridium_response_doc = bstream::document{} << "response" << response << "error" << error << "timestamp"
<< timestamp << "message" << message << bstream::finalize;

return static_cast<bool>(iridium_response_coll.insert_one(iridium_response_doc.view()));
}

// END PRIVATE
Loading
Loading