2021-01-11 06:57:32 +08:00
|
|
|
#pragma once
|
2020-01-18 03:01:02 +08:00
|
|
|
|
2021-03-23 10:51:44 +08:00
|
|
|
#include <fcntl.h>
|
2021-05-09 13:15:17 +08:00
|
|
|
#include <unistd.h>
|
2021-05-12 17:15:54 +08:00
|
|
|
#include <dirent.h>
|
2021-03-23 10:51:44 +08:00
|
|
|
|
2021-05-09 13:15:17 +08:00
|
|
|
#include <algorithm>
|
2021-01-11 06:57:32 +08:00
|
|
|
#include <atomic>
|
2021-05-09 13:15:17 +08:00
|
|
|
#include <cassert>
|
|
|
|
#include <chrono>
|
|
|
|
#include <csignal>
|
|
|
|
#include <cstdio>
|
|
|
|
#include <cstring>
|
2021-01-11 06:57:32 +08:00
|
|
|
#include <fstream>
|
2021-05-09 13:15:17 +08:00
|
|
|
#include <memory>
|
|
|
|
#include <string>
|
2021-01-11 06:57:32 +08:00
|
|
|
#include <thread>
|
2021-05-12 17:15:54 +08:00
|
|
|
#include <map>
|
2020-01-18 03:01:02 +08:00
|
|
|
|
2021-01-11 06:57:32 +08:00
|
|
|
#ifndef sighandler_t
|
|
|
|
typedef void (*sighandler_t)(int sig);
|
2020-01-18 03:01:02 +08:00
|
|
|
#endif
|
|
|
|
|
|
|
|
void set_thread_name(const char* name);
|
|
|
|
|
|
|
|
int set_realtime_priority(int level);
|
2020-06-06 05:09:41 +08:00
|
|
|
int set_core_affinity(int core);
|
2020-01-18 03:01:02 +08:00
|
|
|
|
2021-01-11 06:57:32 +08:00
|
|
|
namespace util {
|
|
|
|
|
2021-03-23 10:51:44 +08:00
|
|
|
// ***** math helpers *****
|
|
|
|
|
|
|
|
// map x from [a1, a2] to [b1, b2]
|
|
|
|
template<typename T>
|
|
|
|
T map_val(T x, T a1, T a2, T b1, T b2) {
|
|
|
|
x = std::clamp(x, a1, a2);
|
|
|
|
T ra = a2 - a1;
|
|
|
|
T rb = b2 - b1;
|
|
|
|
return (x - a1)*rb / ra + b1;
|
|
|
|
}
|
|
|
|
|
|
|
|
// ***** string helpers *****
|
|
|
|
|
2021-01-24 05:47:09 +08:00
|
|
|
inline bool starts_with(const std::string &s, const std::string &prefix) {
|
2021-01-11 06:57:32 +08:00
|
|
|
return s.compare(0, prefix.size(), prefix) == 0;
|
2020-01-18 03:01:02 +08:00
|
|
|
}
|
|
|
|
|
2021-01-27 19:10:03 +08:00
|
|
|
template <typename... Args>
|
|
|
|
inline std::string string_format(const std::string& format, Args... args) {
|
|
|
|
size_t size = snprintf(nullptr, 0, format.c_str(), args...) + 1;
|
|
|
|
std::unique_ptr<char[]> buf(new char[size]);
|
|
|
|
snprintf(buf.get(), size, format.c_str(), args...);
|
|
|
|
return std::string(buf.get(), buf.get() + size - 1);
|
2021-01-11 06:57:32 +08:00
|
|
|
}
|
|
|
|
|
2021-04-14 02:43:43 +08:00
|
|
|
std::string read_file(const std::string &fn);
|
|
|
|
|
2021-05-12 17:15:54 +08:00
|
|
|
int read_files_in_dir(std::string path, std::map<std::string, std::string> *contents);
|
|
|
|
|
2021-04-14 02:43:43 +08:00
|
|
|
int write_file(const char* path, const void* data, size_t size, int flags = O_WRONLY, mode_t mode = 0777);
|
2021-01-11 06:57:32 +08:00
|
|
|
|
|
|
|
inline std::string tohex(const uint8_t* buf, size_t buf_size) {
|
|
|
|
std::unique_ptr<char[]> hexbuf(new char[buf_size*2+1]);
|
|
|
|
for (size_t i=0; i < buf_size; i++) {
|
|
|
|
sprintf(&hexbuf[i*2], "%02x", buf[i]);
|
|
|
|
}
|
|
|
|
hexbuf[buf_size*2] = 0;
|
|
|
|
return std::string(hexbuf.get(), hexbuf.get() + buf_size*2);
|
|
|
|
}
|
|
|
|
|
|
|
|
inline std::string base_name(std::string const & path) {
|
|
|
|
size_t pos = path.find_last_of("/");
|
|
|
|
if (pos == std::string::npos) return path;
|
|
|
|
return path.substr(pos + 1);
|
|
|
|
}
|
|
|
|
|
|
|
|
inline std::string dir_name(std::string const & path) {
|
|
|
|
size_t pos = path.find_last_of("/");
|
|
|
|
if (pos == std::string::npos) return "";
|
|
|
|
return path.substr(0, pos);
|
|
|
|
}
|
|
|
|
|
2021-01-24 05:47:09 +08:00
|
|
|
inline std::string readlink(const std::string &path) {
|
2021-01-11 06:57:32 +08:00
|
|
|
char buff[4096];
|
|
|
|
ssize_t len = ::readlink(path.c_str(), buff, sizeof(buff)-1);
|
|
|
|
if (len != -1) {
|
|
|
|
buff[len] = '\0';
|
|
|
|
return std::string(buff);
|
|
|
|
}
|
|
|
|
return "";
|
|
|
|
}
|
|
|
|
|
|
|
|
inline std::string getenv_default(const char* env_var, const char * suffix, const char* default_val) {
|
|
|
|
const char* env_val = getenv(env_var);
|
|
|
|
if (env_val != NULL){
|
|
|
|
return std::string(env_val) + std::string(suffix);
|
|
|
|
} else {
|
|
|
|
return std::string(default_val);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
inline void sleep_for(const int milliseconds) {
|
|
|
|
std::this_thread::sleep_for(std::chrono::milliseconds(milliseconds));
|
|
|
|
}
|
2021-01-20 04:16:12 +08:00
|
|
|
|
|
|
|
inline bool file_exists(const std::string& fn) {
|
|
|
|
std::ifstream f(fn);
|
|
|
|
return f.good();
|
|
|
|
}
|
|
|
|
|
2021-01-11 06:57:32 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
class ExitHandler {
|
|
|
|
public:
|
|
|
|
ExitHandler() {
|
|
|
|
std::signal(SIGINT, (sighandler_t)set_do_exit);
|
|
|
|
std::signal(SIGTERM, (sighandler_t)set_do_exit);
|
2021-02-19 00:46:46 +08:00
|
|
|
|
|
|
|
#ifndef __APPLE__
|
|
|
|
std::signal(SIGPWR, (sighandler_t)set_do_exit);
|
|
|
|
#endif
|
2021-01-11 06:57:32 +08:00
|
|
|
};
|
2021-02-19 00:46:46 +08:00
|
|
|
inline static std::atomic<bool> power_failure = false;
|
2021-01-11 06:57:32 +08:00
|
|
|
inline operator bool() { return do_exit; }
|
|
|
|
inline ExitHandler& operator=(bool v) {
|
|
|
|
do_exit = v;
|
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
private:
|
2021-02-19 00:46:46 +08:00
|
|
|
static void set_do_exit(int sig) {
|
|
|
|
#ifndef __APPLE__
|
|
|
|
power_failure = (sig == SIGPWR);
|
|
|
|
#endif
|
|
|
|
do_exit = true;
|
|
|
|
}
|
2021-01-11 06:57:32 +08:00
|
|
|
inline static std::atomic<bool> do_exit = false;
|
|
|
|
};
|
|
|
|
|
|
|
|
struct unique_fd {
|
|
|
|
unique_fd(int fd = -1) : fd_(fd) {}
|
|
|
|
unique_fd& operator=(unique_fd&& uf) {
|
|
|
|
fd_ = uf.fd_;
|
|
|
|
uf.fd_ = -1;
|
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
~unique_fd() {
|
|
|
|
if (fd_ != -1) close(fd_);
|
|
|
|
}
|
|
|
|
operator int() const { return fd_; }
|
|
|
|
int fd_;
|
|
|
|
};
|
2021-03-30 18:09:06 +08:00
|
|
|
|
|
|
|
class FirstOrderFilter {
|
|
|
|
public:
|
|
|
|
FirstOrderFilter(float x0, float ts, float dt) {
|
|
|
|
k_ = (dt / ts) / (1.0 + dt / ts);
|
|
|
|
x_ = x0;
|
|
|
|
}
|
|
|
|
inline float update(float x) {
|
|
|
|
x_ = (1. - k_) * x_ + k_ * x;
|
|
|
|
return x_;
|
|
|
|
}
|
|
|
|
inline void reset(float x) { x_ = x; }
|
|
|
|
|
|
|
|
private:
|
|
|
|
float x_, k_;
|
|
|
|
};
|