This repository has been archived on 2020-04-08. You can view files and clone it, but cannot push or open issues or pull requests.
Files
FtmPrologic/code/misc.h
2020-01-28 11:33:17 +01:00

181 lines
4.8 KiB
C++

#pragma once
#include <array>
#include <vector>
#include <Indoor/math/stats/Statistics.h>
#include <Indoor/data/Timestamp.h>
#include <Indoor/sensors/offline/FileReader.h>
#include <Indoor/sensors/radio/model/LogDistanceModel.h>
#include "Settings.h"
static std::string timeForFilename(const std::time_t& time)
{
std::stringstream ss;
ss << std::put_time(std::localtime(&time), "%F_%T"); // ISO 8601 without timezone information.
auto s = ss.str();
std::replace(s.begin(), s.end(), ':', '-');
return s;
}
static std::string currentTimeForFilename()
{
auto time = std::time(nullptr);
return timeForFilename(time);
}
static std::filesystem::path appendCurrentTimeToFilename(const std::filesystem::path& fileName)
{
return fileName.stem().string() + "_" + currentTimeForFilename() + fileName.extension().string();
}
template<typename T>
inline std::filesystem::path appendFileSuffixToPath(const std::filesystem::path& path, T value)
{
std::string filename = path.stem().string() + "_" + std::to_string(value) + path.extension().string();
return path.parent_path() / filename;
}
static bool forceDirectories(const std::filesystem::path& path)
{
if (!std::filesystem::exists(path)) {
return std::filesystem::create_directories(path);
}
return true;
}
template<typename T, int Size>
std::vector<T> asVector(const std::array<T, Size>& src)
{
std::vector<T> result;
result.assign(src.begin(), src.end());
return result;
}
struct WifiMeas {
Timestamp ts;
std::array<float, 4> ftmDists;
std::array<float, 4> rssiDists;
WifiMeas()
: ts(Timestamp::fromMS(0)), ftmDists{ NAN, NAN, NAN, NAN }, rssiDists{ NAN, NAN, NAN, NAN }
{ }
int numSucessMeas() const {
int count = 0;
if (!std::isnan(ftmDists[0])) count++;
if (!std::isnan(ftmDists[1])) count++;
if (!std::isnan(ftmDists[2])) count++;
if (!std::isnan(ftmDists[3])) count++;
return count;
}
};
template<typename T>
struct CombinedStats {
Stats::Statistics<T> ftm;
Stats::Statistics<T> rssi;
};
template<typename T>
void printErrorStats(std::ostream& stream, const CombinedStats<T>& errorStats)
{
stream << "Walk error:" << "\n";
stream << "[m] " << std::setw(10) << "mean" << std::setw(10) << "stdDev" << std::setw(10) << "median" << std::setw(10) << "count" << "\n";
stream << "FTM " << std::setw(10) << errorStats.ftm.getAvg() << std::setw(10) << errorStats.ftm.getStdDev() << std::setw(10) << errorStats.ftm.getMedian() << std::setw(10) << errorStats.ftm.getCount() << "\n";
stream << "RSSI " << std::setw(10) << errorStats.rssi.getAvg() << std::setw(10) << errorStats.rssi.getStdDev() << std::setw(10) << errorStats.rssi.getMedian() << std::setw(10) << errorStats.rssi.getCount() << "\n";
stream << std::endl;
}
template<typename T>
void printErrorStats(const CombinedStats<T>& errorStats)
{
return printErrorStats(std::cout, errorStats);
}
static std::vector<WifiMeas> filterOfflineData(const Offline::FileReader& fr)
{
std::vector<WifiMeas> result;
WifiMeas currentItem;
// parse each sensor-value within the offline data
for (const Offline::Entry& e : fr.getEntries())
{
if (e.type != Offline::Sensor::WIFI_FTM) {
continue;
}
// TIME
const Timestamp ts = Timestamp::fromMS(e.ts);
// init last ts
if (currentItem.ts.isZero())
{
currentItem.ts = ts;
}
// new time step?
if ((ts - currentItem.ts) > Timestamp::fromMS(10))
{
result.push_back(currentItem);
currentItem = {};
}
currentItem.ts = ts;
// DISTANCE
auto ftm = fr.getWifiFtm()[e.idx].data;
const MACAddress& mac = ftm.getAP().getMAC();
float ftm_offset = Settings::CurrentPath.NUCs.at(mac).ftm_offset;
float ftmDist = ftm.getFtmDist() + ftm_offset; // in m; plus static offset
float rssi_pathloss = Settings::CurrentPath.NUCs.at(mac).rssi_pathloss;
float rssiDist = LogDistanceModel::rssiToDistance(-40, rssi_pathloss, ftm.getRSSI());
int nucIndex = Settings::nucIndex(mac);
currentItem.ftmDists[nucIndex] = ftmDist;
currentItem.rssiDists[nucIndex] = rssiDist;
}
return result;
}
struct CmdArguments
{
std::string executableFilename;
std::vector<std::string> arguments;
CmdArguments()
{
}
CmdArguments(int argc, char** argv)
{
if (argc > 0)
{
executableFilename = std::string(argv[0]);
for (size_t i = 1; i < argc; i++)
{
arguments.push_back(std::string(argv[i]));
}
}
}
bool hasFlag(const std::string& arg) const
{
return std::find(arguments.begin(), arguments.end(), arg) != arguments.end();
}
};