linux 编译
This commit is contained in:
+577
-549
File diff suppressed because it is too large
Load Diff
@@ -7,260 +7,317 @@
|
||||
#include <functional>
|
||||
#include <variant>
|
||||
#define STRINGIFY(x) #x
|
||||
|
||||
// 硬件接收来的 二进制消息族
|
||||
namespace SSR {
|
||||
class Data_Source_Interface;
|
||||
static std::atomic_int64_t msg_num = 0;
|
||||
extern bool Monitor_Mode_ACS_Message_Num;
|
||||
class Msg {
|
||||
public:
|
||||
enum T : unsigned char {
|
||||
AC = 0x31, // 49
|
||||
S7 = 0x32, // 50
|
||||
S14 = 0x33, // 51
|
||||
Radarcape_status = 0x34, // 52
|
||||
HULC_Status = 0x48, // 72
|
||||
UNKNOWN = 0xFF
|
||||
};
|
||||
enum Len {
|
||||
AC_len = 9 + 2,
|
||||
S7_len = 9 + 7,
|
||||
S14_len = 9 + 14,
|
||||
Radarcape_status_len = 2 + 3,
|
||||
HULC_len = 28,
|
||||
};
|
||||
std::shared_ptr<Data_Source_Interface> source{};
|
||||
T type = UNKNOWN;
|
||||
std::string packet; // 收到的原始消息
|
||||
explicit Msg(const std::shared_ptr<Data_Source_Interface>& source,
|
||||
std::string_view packet) : source(source), packet(packet) {
|
||||
type = static_cast<T>(packet[1]);
|
||||
// std::cerr << "Msg msg_num "<< ++msg_num << std::endl;
|
||||
}
|
||||
virtual Psc::JSON to_Json() {
|
||||
Psc::JSON ret = Psc::JSON::object();
|
||||
ret.append({"type", Psc::to_string((T)(type))});
|
||||
return ret;
|
||||
}
|
||||
virtual ~Msg() = default;
|
||||
virtual std::string to_string() {
|
||||
return VAR_STR_2(type, packet);
|
||||
}
|
||||
};
|
||||
struct Play_Back_Time_Point {
|
||||
std::uint64_t day_num{};
|
||||
std::uint64_t day_sec{}; // 0..86399
|
||||
struct HMS {
|
||||
std::uint32_t hour;
|
||||
std::uint32_t minute;
|
||||
std::uint32_t second;
|
||||
std::string to_string() const {
|
||||
std::ostringstream oss;
|
||||
oss << std::setw(2) << std::setfill('0') << hour << ':' << std::setw(2)
|
||||
<< std::setfill('0') << minute << ':' << std::setw(2)
|
||||
<< std::setfill('0') << second;
|
||||
return oss.str();
|
||||
}
|
||||
};
|
||||
HMS hms() noexcept {
|
||||
HMS hms{};
|
||||
hms.hour = static_cast<std::uint32_t>(day_sec / 3600);
|
||||
day_sec %= 3600;
|
||||
hms.minute = static_cast<std::uint32_t>(day_sec / 60);
|
||||
hms.second = static_cast<std::uint32_t>(day_sec % 60);
|
||||
return hms;
|
||||
}
|
||||
std::string to_string() {
|
||||
return "Play_Back_Time_Point[" + Psc::to_string(day_num) + "," +
|
||||
hms().to_string() + "]";
|
||||
}
|
||||
static constexpr std::uint64_t SECS_PER_DAY = 86400ULL;
|
||||
// 归一化:保证 day_sec < 86400
|
||||
void normalize() noexcept {
|
||||
if (day_sec >= SECS_PER_DAY) {
|
||||
day_num += day_sec / SECS_PER_DAY;
|
||||
day_sec %= SECS_PER_DAY;
|
||||
}
|
||||
}
|
||||
bool operator<(const Play_Back_Time_Point& other) const noexcept {
|
||||
if (other == *this) return false;
|
||||
if (day_num != other.day_num) return day_num < other.day_num;
|
||||
return day_sec < other.day_sec;
|
||||
}
|
||||
bool operator==(const Play_Back_Time_Point& other) const noexcept {
|
||||
return day_num == other.day_num && day_sec == other.day_sec;
|
||||
}
|
||||
bool operator>(const Play_Back_Time_Point& other) const noexcept {
|
||||
if (other == *this) return false;
|
||||
return other < *this;
|
||||
}
|
||||
std::uint64_t abs_sec() const noexcept {
|
||||
return day_num * SECS_PER_DAY + day_sec;
|
||||
}
|
||||
void add_sec(std::uint64_t sec) noexcept {
|
||||
day_sec += sec;
|
||||
normalize();
|
||||
}
|
||||
};
|
||||
class Mode_Msg : public Msg {
|
||||
public:
|
||||
std::uint64_t day_num = 0; // 自己维护的字段
|
||||
MLAT_timestamp mlat_timestamp;
|
||||
std::string msg_hex;
|
||||
std::string msg_bin;
|
||||
char signal_level{};
|
||||
explicit Mode_Msg(const std::shared_ptr<Data_Source_Interface>& source,
|
||||
std::string_view packet);
|
||||
Psc::JSON to_Json() override {
|
||||
Psc::JSON ret = Msg::to_Json();
|
||||
Ret_J(msg_hex)
|
||||
Ret_J(signal_level)
|
||||
ret.append({"mlat_timestamp", mlat_timestamp.to_string()});
|
||||
Ret_J(day_num)
|
||||
return ret;
|
||||
}
|
||||
~Mode_Msg() override;
|
||||
Play_Back_Time_Point time() {
|
||||
return {day_num, mlat_timestamp.daysec};
|
||||
}
|
||||
std::string to_string() override {
|
||||
auto& time = mlat_timestamp;
|
||||
return VAR_STR_3(signal_level, time, msg_hex);
|
||||
}
|
||||
};
|
||||
class Mode_AC_Msg : public Mode_Msg {
|
||||
public:
|
||||
explicit Mode_AC_Msg(const std::shared_ptr<Data_Source_Interface>& source,
|
||||
std::string_view packet);
|
||||
~Mode_AC_Msg() override;
|
||||
};
|
||||
// 1 + 1 + 6 + 1 + 2/7/14
|
||||
// 1a + type time_stamp signal_level data
|
||||
// 用于数据发送
|
||||
class Mode_S_Msg : public Mode_Msg {
|
||||
public:
|
||||
Downlink_Format df = Downlink_Format::Unknown;
|
||||
std::string icao;
|
||||
Psc::JSON to_Json() override {
|
||||
Psc::JSON ret = Mode_Msg::to_Json();
|
||||
ret.append({"df", Psc::to_string(df)});
|
||||
ret.append({"icao", icao});
|
||||
return ret;
|
||||
}
|
||||
// 1a 31 19 b2dd1c7af671 3220
|
||||
explicit Mode_S_Msg(const std::shared_ptr<Data_Source_Interface>& source,
|
||||
std::string_view packet);
|
||||
~Mode_S_Msg() override;
|
||||
std::string to_string() override {
|
||||
auto& time = mlat_timestamp;
|
||||
return VAR_STR_5(df, icao, signal_level, time, msg_hex);
|
||||
}
|
||||
};
|
||||
class NoneCopyLock {
|
||||
public:
|
||||
std::mutex mtx; // 互斥量,不能被复制
|
||||
NoneCopyLock() = default;
|
||||
NoneCopyLock(const NoneCopyLock& other) = delete;
|
||||
NoneCopyLock& operator=(const NoneCopyLock& other) {
|
||||
return *this;
|
||||
}
|
||||
};
|
||||
struct Position_3D : CPR::Position {
|
||||
CPR::D alt;
|
||||
Position_3D(CPR::D lat, CPR::D lon, CPR::D alt) : CPR::Position(lat, lon), alt(alt) {}
|
||||
};
|
||||
// 这个返回值的意义在于 解码失败后 返回值能反应出是 位置解码失败
|
||||
// 还是奇偶报文解码位置失败
|
||||
class Pos_Ret {
|
||||
public:
|
||||
CPR::Position pos;
|
||||
std::shared_ptr<Mode_S_Msg> that;
|
||||
using Extra = std::variant<std::shared_ptr<Mode_S_Msg>, CPR::Position>;
|
||||
Extra extra;
|
||||
Pos_Ret(CPR::Position p, std::shared_ptr<Mode_S_Msg> t,
|
||||
std::shared_ptr<Mode_S_Msg> o) : pos(p), that(std::move(t)), extra(std::move(o)) {}
|
||||
Pos_Ret(CPR::Position p, std::shared_ptr<Mode_S_Msg> t, CPR::Position old) : pos(p), that(std::move(t)), extra(old) {}
|
||||
};
|
||||
// 展示出最详细的信息
|
||||
struct Position_Info : Position_3D {
|
||||
std::int64_t sys_day_ns{};
|
||||
std::uint64_t utc{};
|
||||
std::uint64_t odd_even_diff_ns{};
|
||||
Position_Info() : Position_3D(0.0, 0.0, 0.0) {}
|
||||
Pos_Ret::Extra extra;
|
||||
std::shared_ptr<Mode_S_Msg> that;
|
||||
Position_Info(const Pos_Ret& r, CPR::D alt) : Position_3D(r.pos.lat, r.pos.lon, alt), that(r.that), extra(r.extra) {
|
||||
using namespace std::chrono;
|
||||
utc = static_cast<std::uint64_t>(
|
||||
duration_cast<seconds>(system_clock::now().time_since_epoch()).count());
|
||||
}
|
||||
Psc::JSON to_json() {
|
||||
Psc::JSON ret = Psc::JSON::object();
|
||||
Ret_J(lat)
|
||||
Ret_J(lon)
|
||||
Ret_J(alt)
|
||||
Ret_J(utc)
|
||||
Ret_J(that->mlat_timestamp)
|
||||
Ret_J(that->msg_hex)
|
||||
Ret_J(that->signal_level)
|
||||
if (auto p = std::get_if<
|
||||
std::shared_ptr<Mode_S_Msg>>(
|
||||
&extra)) {
|
||||
std::shared_ptr<Mode_S_Msg> other = *p;
|
||||
Ret_J(other->mlat_timestamp)
|
||||
Ret_J(other->msg_hex)
|
||||
Ret_J(other->signal_level)
|
||||
class Data_Source_Interface;
|
||||
|
||||
extern bool Monitor_Mode_ACS_Message_Num;
|
||||
|
||||
class Msg {
|
||||
public:
|
||||
enum T : unsigned char {
|
||||
AC = 0x31, // 49
|
||||
S7 = 0x32, // 50
|
||||
S14 = 0x33, // 51
|
||||
Radarcape_status = 0x34, // 52
|
||||
HULC_Status = 0x48, // 72
|
||||
UNKNOWN = 0xFF
|
||||
};
|
||||
|
||||
enum Len {
|
||||
AC_len = 9 + 2,
|
||||
S7_len = 9 + 7,
|
||||
S14_len = 9 + 14,
|
||||
Radarcape_status_len = 2 + 3,
|
||||
HULC_len = 28,
|
||||
};
|
||||
|
||||
std::shared_ptr<Data_Source_Interface> source{};
|
||||
T type = UNKNOWN;
|
||||
std::string packet; // 收到的原始消息
|
||||
explicit Msg(const std::shared_ptr<Data_Source_Interface> &source, std::string_view packet);
|
||||
|
||||
virtual Psc::JSON to_Json() {
|
||||
Psc::JSON ret = Psc::JSON::object();
|
||||
ret.append({"type", Psc::to_string((T) (type))});
|
||||
return ret;
|
||||
}
|
||||
if (auto p = std::get_if<CPR::Position>(&extra)) {
|
||||
CPR::Position old = *p;
|
||||
Ret_J(old)
|
||||
|
||||
virtual ~Msg();
|
||||
|
||||
virtual std::string to_string() {
|
||||
return VAR_STR_2(type, packet);
|
||||
}
|
||||
};
|
||||
|
||||
struct Play_Back_Time_Point {
|
||||
std::uint64_t day_num{};
|
||||
std::uint64_t day_sec{}; // 0..86399
|
||||
struct HMS {
|
||||
std::uint32_t hour;
|
||||
std::uint32_t minute;
|
||||
std::uint32_t second;
|
||||
|
||||
std::string to_string() const {
|
||||
std::ostringstream oss;
|
||||
oss << std::setw(2) << std::setfill('0') << hour << ':' << std::setw(2)
|
||||
<< std::setfill('0') << minute << ':' << std::setw(2)
|
||||
<< std::setfill('0') << second;
|
||||
return oss.str();
|
||||
}
|
||||
};
|
||||
|
||||
HMS hms() noexcept {
|
||||
HMS hms{};
|
||||
hms.hour = static_cast<std::uint32_t>(day_sec / 3600);
|
||||
day_sec %= 3600;
|
||||
hms.minute = static_cast<std::uint32_t>(day_sec / 60);
|
||||
hms.second = static_cast<std::uint32_t>(day_sec % 60);
|
||||
return hms;
|
||||
}
|
||||
|
||||
std::string to_string() {
|
||||
return "Play_Back_Time_Point[" + Psc::to_string(day_num) + "," +
|
||||
hms().to_string() + "]";
|
||||
}
|
||||
|
||||
static constexpr std::uint64_t SECS_PER_DAY = 86400ULL;
|
||||
// 归一化:保证 day_sec < 86400
|
||||
void normalize() noexcept {
|
||||
if (day_sec >= SECS_PER_DAY) {
|
||||
day_num += day_sec / SECS_PER_DAY;
|
||||
day_sec %= SECS_PER_DAY;
|
||||
}
|
||||
}
|
||||
|
||||
bool operator<(const Play_Back_Time_Point &other) const noexcept {
|
||||
if (other == *this) return false;
|
||||
if (day_num != other.day_num) return day_num < other.day_num;
|
||||
return day_sec < other.day_sec;
|
||||
}
|
||||
|
||||
bool operator==(const Play_Back_Time_Point &other) const noexcept {
|
||||
return day_num == other.day_num && day_sec == other.day_sec;
|
||||
}
|
||||
|
||||
bool operator>(const Play_Back_Time_Point &other) const noexcept {
|
||||
if (other == *this) return false;
|
||||
return other < *this;
|
||||
}
|
||||
|
||||
std::uint64_t abs_sec() const noexcept {
|
||||
return day_num * SECS_PER_DAY + day_sec;
|
||||
}
|
||||
|
||||
void add_sec(std::uint64_t sec) noexcept {
|
||||
day_sec += sec;
|
||||
normalize();
|
||||
}
|
||||
};
|
||||
|
||||
class Mode_Msg : public Msg {
|
||||
public:
|
||||
std::uint64_t day_num = 0; // 自己维护的字段
|
||||
MLAT_timestamp mlat_timestamp;
|
||||
std::string msg_hex;
|
||||
std::string msg_bin;
|
||||
char signal_level{};
|
||||
|
||||
explicit Mode_Msg(const std::shared_ptr<Data_Source_Interface> &source,
|
||||
std::string_view packet);
|
||||
|
||||
Psc::JSON to_Json() override {
|
||||
Psc::JSON ret = Msg::to_Json();
|
||||
Ret_J(msg_hex)
|
||||
Ret_J(signal_level)
|
||||
ret.append({"mlat_timestamp", mlat_timestamp.to_string()});
|
||||
Ret_J(day_num)
|
||||
return ret;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
};
|
||||
struct POS_List {
|
||||
NoneCopyLock mtx;
|
||||
size_t max_size;
|
||||
POS_List() {}
|
||||
void reset() {
|
||||
std::lock_guard g(mtx.mtx);
|
||||
seq = 0;
|
||||
head = 0;
|
||||
count = 0;
|
||||
}
|
||||
void init(size_t _max_size) {
|
||||
this->max_size = _max_size;
|
||||
buf.resize(_max_size);
|
||||
}
|
||||
size_t size() {
|
||||
std::lock_guard g(mtx.mtx);
|
||||
return count;
|
||||
}
|
||||
bool empty() {
|
||||
std::lock_guard g(mtx.mtx);
|
||||
return count == 0;
|
||||
}
|
||||
std::optional<Position_Info> last() {
|
||||
std::lock_guard g(mtx.mtx);
|
||||
if (count == 0) return std::nullopt;
|
||||
std::size_t idx = (head + max_size - 1) % max_size;
|
||||
return buf[idx];
|
||||
}
|
||||
void push(Position_Info new_position) {
|
||||
std::lock_guard g(mtx.mtx);
|
||||
buf[head] = std::move(new_position);
|
||||
head = (head + 1) % max_size;
|
||||
if (count < max_size) ++count;
|
||||
++seq;
|
||||
}
|
||||
Psc::JSON get_last_array_json(std::uint64_t last_seq);
|
||||
std::string to_string();
|
||||
protected:
|
||||
std::uint64_t seq = 0;
|
||||
std::uint64_t head = 0;
|
||||
std::uint64_t count = 0;
|
||||
std::vector<Position_Info> buf;
|
||||
};
|
||||
} // namespace SSR
|
||||
|
||||
~Mode_Msg() override;
|
||||
|
||||
Play_Back_Time_Point time() {
|
||||
return {day_num, mlat_timestamp.daysec};
|
||||
}
|
||||
|
||||
std::string to_string() override {
|
||||
auto &time = mlat_timestamp;
|
||||
return VAR_STR_3(signal_level, time, msg_hex);
|
||||
}
|
||||
};
|
||||
|
||||
class Mode_AC_Msg : public Mode_Msg {
|
||||
public:
|
||||
explicit Mode_AC_Msg(const std::shared_ptr<Data_Source_Interface> &source,
|
||||
std::string_view packet);
|
||||
|
||||
~Mode_AC_Msg() override;
|
||||
};
|
||||
|
||||
// 1 + 1 + 6 + 1 + 2/7/14
|
||||
// 1a + type time_stamp signal_level data
|
||||
// 用于数据发送
|
||||
class Mode_S_Msg : public Mode_Msg {
|
||||
public:
|
||||
Downlink_Format df = Downlink_Format::Unknown;
|
||||
std::string icao;
|
||||
|
||||
Psc::JSON to_Json() override {
|
||||
Psc::JSON ret = Mode_Msg::to_Json();
|
||||
ret.append({"df", Psc::to_string(df)});
|
||||
ret.append({"icao", icao});
|
||||
return ret;
|
||||
}
|
||||
|
||||
// 1a 31 19 b2dd1c7af671 3220
|
||||
explicit Mode_S_Msg(const std::shared_ptr<Data_Source_Interface> &source,
|
||||
std::string_view packet);
|
||||
|
||||
~Mode_S_Msg() override;
|
||||
|
||||
std::string to_string() override {
|
||||
auto &time = mlat_timestamp;
|
||||
return VAR_STR_5(df, icao, signal_level, time, msg_hex);
|
||||
}
|
||||
};
|
||||
|
||||
class NoneCopyLock {
|
||||
public:
|
||||
std::mutex mtx; // 互斥量,不能被复制
|
||||
NoneCopyLock() = default;
|
||||
|
||||
NoneCopyLock(const NoneCopyLock &other) = delete;
|
||||
|
||||
NoneCopyLock &operator=(const NoneCopyLock &other) {
|
||||
return *this;
|
||||
}
|
||||
};
|
||||
|
||||
struct Position_3D : CPR::Position {
|
||||
CPR::D alt;
|
||||
|
||||
Position_3D(CPR::D lat, CPR::D lon, CPR::D alt) : CPR::Position(lat, lon), alt(alt) {
|
||||
}
|
||||
};
|
||||
|
||||
// 这个返回值的意义在于 解码失败后 返回值能反应出是 位置解码失败
|
||||
// 还是奇偶报文解码位置失败
|
||||
class Pos_Ret {
|
||||
public:
|
||||
CPR::Position pos;
|
||||
std::shared_ptr<Mode_S_Msg> that;
|
||||
using Extra = std::variant<std::shared_ptr<Mode_S_Msg>, CPR::Position>;
|
||||
Extra extra;
|
||||
|
||||
Pos_Ret(CPR::Position p, std::shared_ptr<Mode_S_Msg> t,
|
||||
std::shared_ptr<Mode_S_Msg> o) : pos(p), that(std::move(t)), extra(std::move(o)) {
|
||||
}
|
||||
|
||||
Pos_Ret(CPR::Position p, std::shared_ptr<Mode_S_Msg> t, CPR::Position old) : pos(p), that(std::move(t)),
|
||||
extra(old) {
|
||||
}
|
||||
};
|
||||
|
||||
// 展示出最详细的信息
|
||||
struct Position_Info : Position_3D {
|
||||
std::int64_t sys_day_ns{};
|
||||
std::uint64_t utc{};
|
||||
std::uint64_t odd_even_diff_ns{};
|
||||
|
||||
Position_Info() : Position_3D(0.0, 0.0, 0.0) {
|
||||
}
|
||||
|
||||
Pos_Ret::Extra extra;
|
||||
std::shared_ptr<Mode_S_Msg> that;
|
||||
|
||||
Position_Info(const Pos_Ret &r, CPR::D alt) : Position_3D(r.pos.lat, r.pos.lon, alt), that(r.that),
|
||||
extra(r.extra) {
|
||||
using namespace std::chrono;
|
||||
utc = static_cast<std::uint64_t>(
|
||||
duration_cast<seconds>(system_clock::now().time_since_epoch()).count());
|
||||
}
|
||||
|
||||
Psc::JSON to_json() {
|
||||
Psc::JSON ret = Psc::JSON::object();
|
||||
Ret_J(lat)
|
||||
Ret_J(lon)
|
||||
Ret_J(alt)
|
||||
Ret_J(utc)
|
||||
Ret_J(that->mlat_timestamp)
|
||||
Ret_J(that->msg_hex)
|
||||
Ret_J(that->signal_level)
|
||||
if (auto p = std::get_if<
|
||||
std::shared_ptr<Mode_S_Msg> >(
|
||||
&extra)) {
|
||||
std::shared_ptr<Mode_S_Msg> other = *p;
|
||||
Ret_J(other->mlat_timestamp)
|
||||
Ret_J(other->msg_hex)
|
||||
Ret_J(other->signal_level)
|
||||
return ret;
|
||||
}
|
||||
if (auto p = std::get_if<CPR::Position>(&extra)) {
|
||||
CPR::Position old = *p;
|
||||
Ret_J(old)
|
||||
return ret;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
};
|
||||
|
||||
struct POS_List {
|
||||
NoneCopyLock mtx;
|
||||
size_t max_size;
|
||||
|
||||
POS_List() {
|
||||
}
|
||||
|
||||
void reset() {
|
||||
std::lock_guard g(mtx.mtx);
|
||||
seq = 0;
|
||||
head = 0;
|
||||
count = 0;
|
||||
}
|
||||
|
||||
void init(size_t _max_size) {
|
||||
this->max_size = _max_size;
|
||||
buf.resize(_max_size);
|
||||
}
|
||||
|
||||
size_t size() {
|
||||
std::lock_guard g(mtx.mtx);
|
||||
return count;
|
||||
}
|
||||
|
||||
bool empty() {
|
||||
std::lock_guard g(mtx.mtx);
|
||||
return count == 0;
|
||||
}
|
||||
|
||||
std::optional<Position_Info> last() {
|
||||
std::lock_guard g(mtx.mtx);
|
||||
if (count == 0) return std::nullopt;
|
||||
std::size_t idx = (head + max_size - 1) % max_size;
|
||||
return buf[idx];
|
||||
}
|
||||
|
||||
void push(Position_Info new_position) {
|
||||
std::lock_guard g(mtx.mtx);
|
||||
buf[head] = std::move(new_position);
|
||||
head = (head + 1) % max_size;
|
||||
if (count < max_size) ++count;
|
||||
++seq;
|
||||
}
|
||||
|
||||
Psc::JSON get_last_array_json(std::uint64_t last_seq);
|
||||
|
||||
std::string to_string();
|
||||
|
||||
protected:
|
||||
std::uint64_t seq = 0;
|
||||
std::uint64_t head = 0;
|
||||
std::uint64_t count = 0;
|
||||
std::vector<Position_Info> buf;
|
||||
};
|
||||
} // namespace SSR
|
||||
|
||||
+2540
-2527
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user