cmake库改造前

This commit is contained in:
2026-08-05 14:37:55 +08:00
parent 1637d642de
commit 03ebc1b25d
14 changed files with 595 additions and 657 deletions
-1
View File
@@ -1,7 +1,6 @@
#ifndef ADS_B_HPP
#define ADS_B_HPP
#include <format>
#include <json/config.h>
#include <string_view>
#include <utility>
#include "../ACAS/ACAS_9_56.hpp"
+1 -2
View File
@@ -3,7 +3,7 @@
#include <algorithm>
#include <cmath>
#include <string_view>
#include "Core/Statistics/Frequency_Limit.h"
#include "Psc_Cpp_Core/Statistics/Frequency_Limit.h"
#include "convert/SBS.h"
#include "export.h"
using namespace Psc;
@@ -84,7 +84,6 @@ void set_logger(BaseLogger* logger) {
delete mode_s_logger;
mode_s_logger = logger;
}
bool parse_absb_17(SSR::Data_Source_Interface* src, SSR::P_S mode_s_msg, JSON& msg_json,
std::optional<Position_3D> base_station_pos, const SSR::ADS_B_T::Constraint& air_constraint,
const SSR::ADS_B_T::Constraint& surface_constraint) {
+17 -23
View File
@@ -1,23 +1,22 @@
#pragma once
#include <functional>
#include <string_view>
#include "Core/system/export.h"
#include "ACAS/ACAS.h"
#include "ADS_B/ADS_B.h"
#include "Commb/Commb.h"
#include "Mode_S/Mode_S.h"
#include "Msg.h"
#include "Psc_Cpp_Core/system/export.h"
#include "convert/DataOutputFormats.h"
#include <functional>
namespace SSR {
#define GET_PRE(name) \
std::lock_guard<std::mutex> lock(name.mtx.mtx); \
if (!name.value.has_value()) \
{ \
return std::nullopt; \
} \
auto& w = name.value.value();
// #define EJ2(NAME) \
// if (NAME.value.has_value()) ret.append(Psc::Json(STRINGIFY(timestamp_##NAME), NAME.time)); \
std::lock_guard<std::mutex> lock(name.mtx.mtx); \
if (!name.value.has_value()) { \
return std::nullopt; \
} \
auto& w = name.value.value();
// #define EJ2(NAME) \
// if (NAME.value.has_value()) ret.append(Psc::Json(STRINGIFY(timestamp_##NAME), NAME.time)); \
// ret.append(NAME.value.has_value() ? Psc::Json(#NAME, NAME.value.value().toJson()) : Psc::Json(#NAME, nullptr));
template <typename T>
void d(Psc::JSON& ret, T& t, std::string_view name) {
@@ -86,8 +85,7 @@ public:
}
virtual Psc::JSON toJson() {
Psc::JSON ret = Psc::JSON::object();
Ret_J(icao)
ret.append({"每秒位置数", get_pest()});
Ret_J(icao) ret.append({"每秒位置数", get_pest()});
ret.append({"飞机位置轨迹点数", air_pos_track_list.size()});
ret.append({"地面位置轨迹点数", surface_pos_track_list.size()});
ret.append({"信号强度", signal_level});
@@ -171,8 +169,8 @@ public:
}
RET<bool> is_on_ground() {
GET_PRE(Reply_Base_builder)
if (w.get_flight_status() == Flight_Status::alert_on_ground || w.get_flight_status() ==
Flight_Status::no_alert_on_ground) {
if (w.get_flight_status() == Flight_Status::alert_on_ground ||
w.get_flight_status() == Flight_Status::no_alert_on_ground) {
return true;
}
return false;
@@ -185,7 +183,8 @@ public:
RET<double> vertical_rate() {
GET_PRE(BDS09_Base)
auto v = w.get_vertical_rate();
if (!v.has_value()) return std::nullopt;
if (!v.has_value())
return std::nullopt;
return v.value() * aero::fpm;
}
RET<CPR::Position> pos() {
@@ -194,7 +193,8 @@ public:
// if (it.get_lat().has_value() && it.get_lon().has_value()) {
// return CPR::Position{it.get_lat().value(), it.get_lon().value()};
// }
if (surface_pos_track_list.empty()) return std::nullopt;
if (surface_pos_track_list.empty())
return std::nullopt;
return surface_pos_track_list.last();
}
RET<double> select_heading() {
@@ -210,13 +210,9 @@ public:
return w.get_magnetic_heading();
}
RET<double> altitude_meter() {
GET_PRE(BDS05_airborne_position)
return w.get_alt_meter();
}
RET<Vortex_Type> vortex_type() {
GET_PRE(BDS08_id)
return w.get_vortex_type();
@@ -291,6 +287,4 @@ public:
this->timestamp = std::time(nullptr);
}
};
}
} // namespace SSR
+16 -25
View File
@@ -1,20 +1,21 @@
#pragma once
#include <string_view>
#include "Core/Base/JSON.h"
#include <cmath>
#include <cstdint>
#include <map>
#include <mutex>
#include <optional>
#include <string>
#include <string_view>
#include <tuple>
#include "Psc_Cpp_Core/Base/JSON.h"
namespace SSR {
namespace CPR {
using Time = long double;
using D = long double;
using I = std::int64_t;
struct Position {
Position(D lat, D lon) : lat(lat), lon(lon) {}
Position(D lat, D lon) : lat(lat), lon(lon) {
}
D lat;
D lon;
[[nodiscard]] std::string to_string() const;
@@ -70,9 +71,11 @@ inline std::optional<std::tuple<Position, Position>> surface_global_decode(I YZ0
auto [pos0, pos1] = poses.value();
return std::tuple(pos0, pos1);
}
inline std::optional<std::tuple<Position, Position>> surface_global_decode_ref(I YZ0, I YZ1, I XZ0, I XZ1, D lat_s, D lon_s) {
inline std::optional<std::tuple<Position, Position>> surface_global_decode_ref(I YZ0, I YZ1, I XZ0, I XZ1, D lat_s,
D lon_s) {
auto poses = surface_global_decode(YZ0, YZ1, XZ0, XZ1);
if (!poses.has_value()) return std::nullopt;
if (!poses.has_value())
return std::nullopt;
auto [pos0, pos1] = poses.value();
auto p0 = Position{bb(pos0.lat, lat_s), bb(pos0.lon, lon_s)};
auto p1 = Position{bb(pos1.lat, lat_s), bb(pos1.lon, lon_s)};
@@ -88,24 +91,14 @@ inline POS surface_locale_decode(D lat_s, D lon_s, I YZi, I XZi, I i) {
return Position{bb(lat, lat_s), bb(lon, lon_s)};
}
// time
std::string lat_lon_airborne_34(double latitude, double longitude,
CPR::Frame cpr_format);
std::optional<Position> airborne_position(std::string_view msg0,
std::string_view msg1, Time t0,
Time t1);
std::optional<Position> airborne_position_with_ref(std::string_view msg_bin,
double lat_ref,
double lon_ref, Time t,
std::string lat_lon_airborne_34(double latitude, double longitude, CPR::Frame cpr_format);
std::optional<Position> airborne_position(std::string_view msg0, std::string_view msg1, Time t0, Time t1);
std::optional<Position> airborne_position_with_ref(std::string_view msg_bin, double lat_ref, double lon_ref, Time t,
Time t_ref);
std::string lat_lon_surface_34(double latitude, double longitude,
CPR::Frame cpr_format);
std::optional<Position> surface_position(std::string_view msg0,
std::string_view msg1, Time t0,
Time t1,
std::string lat_lon_surface_34(double latitude, double longitude, CPR::Frame cpr_format);
std::optional<Position> surface_position(std::string_view msg0, std::string_view msg1, Time t0, Time t1,
const CPR::Position& base_station_pos);
std::optional<Position> surface_position_with_ref(std::string_view msg_bin,
double lat_ref,
double lon_ref, Time t,
std::optional<Position> surface_position_with_ref(std::string_view msg_bin, double lat_ref, double lon_ref, Time t,
Time t_ref);
// YZ, NZ, i
std::tuple<CPR::I, CPR::I, CPR::I> get(std::string_view msg_bin);
@@ -125,10 +118,8 @@ std::tuple<I, I> light_time_second_nano(const Position& p1, const Position& p2);
// (Longitude):表示经度,用来指示一个点在地球表面相对于本初子午线的角度。它的范围是从
// -180° 到 +180°。 H
// (Height):表示高度,通常指的是该点相对于海平面的高度,单位通常是米(m)。
void WGS84_LBH_to_XYZ(double longitude, double latitude, double height,
double& X, double& Y, double& Z);
void XYZ_to_WGS84_LBH(double X, double Y, double Z, double& longitude,
double& latitude, double& altitude);
void WGS84_LBH_to_XYZ(double longitude, double latitude, double height, double& X, double& Y, double& Z);
void XYZ_to_WGS84_LBH(double X, double Y, double Z, double& longitude, double& latitude, double& altitude);
} // namespace CPR
} // namespace SSR
#include <format>
+77 -89
View File
@@ -1,112 +1,100 @@
#pragma once
#include <string_view>
#include "../HPP.h"
#include "Core/Base/global_include.h"
#include "Psc_Cpp_Core/Base/global_include.h"
namespace SSR {
void check_icao(std::string_view icao);
namespace T {
template <typename That>
struct Reply_Base_Builder {
PROP_T(std::string, icao, std::string {}
);
PROP_T(Downlink_Format, df, Downlink_Format::Unknown)
PROP_T(Transponder_Capability, transponder_capability,
Transponder_Capability::Level_2_plus_airborne)
PROP_T(Flight_Status, flight_status, Flight_Status::not_assigned)
PROP_T(Downlink_Request, downlink_request, Downlink_Request::no_request)
PROP_T(IDS, ids, IDS::no_information)
PROP_Bit_T (
4
,
IIS
,
0
) // 询问器标识符代码
void parse(std::string& msg_bin) {
icao = decode_icao(msg_bin);
df = decode_df(msg_bin);
transponder_capability = decode_transponder_capability(msg_bin);
get_bin < 5, 3, Flight_Status > (msg_bin, flight_status);
get_bin < 8, 5, Downlink_Request > (msg_bin, downlink_request);
get_bin < 13, 4 > (msg_bin, IIS);
get_bin < 17, 2, IDS > (msg_bin, ids);
}
Psc::JSON toJson() {
Psc::JSON ret = Psc::JSON::object();
Ret_J(icao);
Ret_J(transponder_capability);
Ret_J(flight_status);
Ret_J(ids);
Ret_J(IIS);
return ret;
}
PROP_T(std::string, icao, std::string{});
PROP_T(Downlink_Format, df, Downlink_Format::Unknown)
PROP_T(Transponder_Capability, transponder_capability, Transponder_Capability::Level_2_plus_airborne)
PROP_T(Flight_Status, flight_status, Flight_Status::not_assigned)
PROP_T(Downlink_Request, downlink_request, Downlink_Request::no_request)
PROP_T(IDS, ids, IDS::no_information)
PROP_Bit_T(4, IIS,
0) // 询问器标识符代码
void parse(std::string& msg_bin) {
icao = decode_icao(msg_bin);
df = decode_df(msg_bin);
transponder_capability = decode_transponder_capability(msg_bin);
get_bin<5, 3, Flight_Status>(msg_bin, flight_status);
get_bin<8, 5, Downlink_Request>(msg_bin, downlink_request);
get_bin<13, 4>(msg_bin, IIS);
get_bin<17, 2, IDS>(msg_bin, ids);
}
Psc::JSON toJson() {
Psc::JSON ret = Psc::JSON::object();
Ret_J(icao);
Ret_J(transponder_capability);
Ret_J(flight_status);
Ret_J(ids);
Ret_J(IIS);
return ret;
}
protected:
// void set_crc(std::string& msg_bin, std::string& icao) {
// auto crc = std::bitset<24>(::crc(msg_bin, true)).to_string();
// auto crcHex = bin2hex(crc);
// std::string last24 = xorHex(crcHex, icao);
// msg_bin.replace(msg_bin.size() - 24, 24, xorBin(crc, hex2bin(icao)));
// }
void set(std::string& msg_bin) {
check_icao(icao);
PSC_ASSERT(msg_bin.size() == 56 || msg_bin.size() == 112,
" Reply_Base_Builder error size == " +
std::to_string(msg_bin.size()));
SSR::set_transponder_capability(msg_bin, transponder_capability);
set_bin < 5, 3 > (msg_bin, static_cast<int>(flight_status));
set_bin < 8, 5 > (msg_bin, static_cast<int>(downlink_request));
set_bin < 13, 4 > (msg_bin, IIS);
set_bin < 17, 2 > (msg_bin, static_cast<int>(ids));
}
// void set_crc(std::string& msg_bin, std::string& icao) {
// auto crc = std::bitset<24>(::crc(msg_bin, true)).to_string();
// auto crcHex = bin2hex(crc);
// std::string last24 = xorHex(crcHex, icao);
// msg_bin.replace(msg_bin.size() - 24, 24, xorBin(crc, hex2bin(icao)));
// }
void set(std::string& msg_bin) {
check_icao(icao);
PSC_ASSERT(msg_bin.size() == 56 || msg_bin.size() == 112,
" Reply_Base_Builder error size == " + std::to_string(msg_bin.size()));
SSR::set_transponder_capability(msg_bin, transponder_capability);
set_bin<5, 3>(msg_bin, static_cast<int>(flight_status));
set_bin<8, 5>(msg_bin, static_cast<int>(downlink_request));
set_bin<13, 4>(msg_bin, IIS);
set_bin<17, 2>(msg_bin, static_cast<int>(ids));
}
};
T_Parser(Reply_Base_Builder)
template <typename That>
T_Parser(Reply_Base_Builder) template <typename That>
struct Alt {
PROP_T(int, altitude, 0)
void parse(std::string& msg_bin) {
altitude = altcode(msg_bin);
}
Psc::JSON toJson() {
Psc::JSON ret = Psc::JSON::object();
Ret_J(altitude);
return ret;
}
PROP_T(int, altitude, 0)
void parse(std::string& msg_bin) {
altitude = altcode(msg_bin);
}
Psc::JSON toJson() {
Psc::JSON ret = Psc::JSON::object();
Ret_J(altitude);
return ret;
}
protected:
void set(std::string& msg_bin) {
set_bin < 19, 13 > (msg_bin, encode_altitude13_feet(altitude));
}
void set(std::string& msg_bin) {
set_bin<19, 13>(msg_bin, encode_altitude13_feet(altitude));
}
};
T_Parser(Alt)
template <typename That>
T_Parser(Alt) template <typename That>
struct Id {
// ATC Mode A 所使用的代码
PROP_T(std::string, ATC_Squawk, "0000")
void parse(std::string& msg_bin) {
ATC_Squawk = idcode(msg_bin);
}
Psc::JSON toJson() {
Psc::JSON ret = Psc::JSON::object();
Ret_J(ATC_Squawk);
return ret;
}
// ATC Mode A 所使用的代码
PROP_T(std::string, ATC_Squawk, "0000")
void parse(std::string& msg_bin) {
ATC_Squawk = idcode(msg_bin);
}
Psc::JSON toJson() {
Psc::JSON ret = Psc::JSON::object();
Ret_J(ATC_Squawk);
return ret;
}
protected:
void set(std::string& msg_bin) {
set_bin < 19, 13 > (msg_bin, encode_squawk13(ATC_Squawk));
}
void set(std::string& msg_bin) {
set_bin<19, 13>(msg_bin, encode_squawk13(ATC_Squawk));
}
};
T_Parser(Id)
template <typename That>
T_Parser(Id) template <typename That>
struct Surveillance_Altitude_Reply : Alt<That>, BDS_ {
void set(std::string& msg_bin) {
set_df(msg_bin, Downlink_Format::Surveillance_Altitude_Reply_4);
}
void set(std::string& msg_bin) {
set_df(msg_bin, Downlink_Format::Surveillance_Altitude_Reply_4);
}
};
template <typename That>
struct Surveillance_Identity_Reply : Id<That>, BDS_ {
void set(std::string& msg_bin) {
set_df(msg_bin, Downlink_Format::Surveillance_Identity_Reply_5);
}
void set(std::string& msg_bin) {
set_df(msg_bin, Downlink_Format::Surveillance_Identity_Reply_5);
}
};
} // namespace T
} // namespace SSR
+28 -39
View File
@@ -1,12 +1,12 @@
#pragma once
#include <string_view>
#include "CPR/CPR.h"
#include "Core/Base/global_include.h"
#include "convert/DataOutputFormats.h"
#include "enum.h"
#include <functional>
#include <string_view>
#include <utility>
#include <variant>
#include "CPR/CPR.h"
#include "Psc_Cpp_Core/Base/global_include.h"
#include "convert/DataOutputFormats.h"
#include "enum.h"
#define STRINGIFY(x) #x
// 硬件接收来的 二进制消息族
namespace SSR {
@@ -55,10 +55,8 @@ struct Play_Back_Time_Point {
std::uint32_t second{};
[[nodiscard]] std::string to_string() const {
std::ostringstream oss;
oss << std::setfill('0')
<< std::setw(2) << hour << ':'
<< std::setw(2) << minute << ':'
<< std::setw(2) << second;
oss << std::setfill('0') << std::setw(2) << hour << ':' << std::setw(2) << minute << ':' << std::setw(2)
<< second;
return oss.str();
}
};
@@ -71,8 +69,8 @@ struct Play_Back_Time_Point {
}
[[nodiscard]] std::string to_string() const {
std::ostringstream oss;
oss << "Play_Back_Time_Point[" << day_num << ',' << hms().to_string()
<< '.' << std::setfill('0') << std::setw(9) << nanosec << ']';
oss << "Play_Back_Time_Point[" << day_num << ',' << hms().to_string() << '.' << std::setfill('0')
<< std::setw(9) << nanosec << ']';
return oss.str();
}
void normalize() noexcept {
@@ -98,9 +96,7 @@ struct Play_Back_Time_Point {
return nanosec < other.nanosec;
}
bool operator==(const Play_Back_Time_Point& other) const noexcept {
return day_num == other.day_num &&
day_sec == other.day_sec &&
nanosec == other.nanosec;
return day_num == other.day_num && day_sec == other.day_sec && nanosec == other.nanosec;
}
bool operator>(const Play_Back_Time_Point& other) const noexcept {
return other < *this;
@@ -112,8 +108,7 @@ struct Play_Back_Time_Point {
return !(*this < other);
}
[[nodiscard]] double abs_sec() const noexcept {
return static_cast<double>(day_num) * static_cast<double>(SECS_PER_DAY) +
static_cast<double>(day_sec) +
return static_cast<double>(day_num) * static_cast<double>(SECS_PER_DAY) + static_cast<double>(day_sec) +
static_cast<double>(nanosec) / static_cast<double>(NANOSECS_PER_SEC);
}
void add_sec(std::uint64_t sec) noexcept {
@@ -144,15 +139,11 @@ public:
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);
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;
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() {
@@ -165,8 +156,7 @@ public:
};
class Mode_AC_Msg : public Mode_Msg {
public:
explicit Mode_AC_Msg(const std::shared_ptr<Data_Source_Interface>& source,
std::string_view packet);
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
@@ -183,8 +173,7 @@ public:
return ret;
}
// 1a 31 19 b2dd1c7af671 3220
explicit Mode_S_Msg(const std::shared_ptr<Data_Source_Interface>& source,
std::string_view packet);
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;
@@ -202,7 +191,8 @@ public:
};
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) {}
Position_3D(CPR::D lat, CPR::D lon, CPR::D alt) : CPR::Position(lat, lon), alt(alt) {
}
};
// 这个返回值的意义在于 解码失败后 返回值能反应出是 位置解码失败
// 还是奇偶报文解码位置失败 轨迹点上会显示的信息
@@ -210,27 +200,24 @@ class Pos_Ret {
public:
CPR::Position pos;
Psc::JSON info;
Pos_Ret(CPR::Position p, Psc::JSON info) : pos(p), info(std::move(info)) {}
Pos_Ret(CPR::Position p, Psc::JSON info) : pos(p), info(std::move(info)) {
}
};
// 展示出最详细的信息
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) {}
Position_Info() : Position_3D(0.0, 0.0, 0.0) {
}
Psc::JSON info;
Position_Info(const Pos_Ret& r, CPR::D alt) : Position_3D(r.pos.lat, r.pos.lon, alt), info(r.info) {
using namespace std::chrono;
utc = static_cast<std::uint64_t>(
duration_cast<seconds>(system_clock::now().time_since_epoch()).count());
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.append_list(info.children);
Ret_J(lat) Ret_J(lon) Ret_J(alt) Ret_J(utc) ret.append_list(info.children);
return ret;
}
};
@@ -262,7 +249,8 @@ struct POS_List {
}
std::optional<Position_Info> last() {
std::lock_guard g(mtx.mtx);
if (count == 0) return std::nullopt;
if (count == 0)
return std::nullopt;
std::size_t idx = (head + max_size - 1) % max_size;
return buf[idx];
}
@@ -271,7 +259,8 @@ struct POS_List {
std::lock_guard g(mtx.mtx);
buf[head] = std::move(new_position);
head = (head + 1) % max_size;
if (count < max_size) ++count;
if (count < max_size)
++count;
++seq;
}
Psc::JSON get_last_array_json(std::uint64_t last_seq);
+1 -1
View File
@@ -1,5 +1,5 @@
#include "DataOutputFormats.h"
#include "Core/Base/global_include.h"
#include "Psc_Cpp_Core/Base/global_include.h"
#include <cassert>
#include <chrono>
#include <string_view>
+36 -40
View File
@@ -1,47 +1,43 @@
#pragma once
#include <string_view>
#include "Core/Base/JSON.h"
#include "SSR/global.h"
#include <cstring>
#include <string_view>
#include "Psc_Cpp_Core/Base/JSON.h"
#include "SSR/global.h"
namespace SSR {
// 1纳秒是 10 -9次方秒
struct MLAT_timestamp {
explicit MLAT_timestamp();
explicit MLAT_timestamp(std::string_view memory_6);
MLAT_timestamp(std::uint32_t daysec, std::uint32_t nanosec);
std::uint32_t daysec{}; // 当天的秒数 高18位
std::uint32_t nanosec{}; // 当天的纳秒数 低30位
std::string to_bin_string() const;
std::string to_memory() const;
unsigned long hh{};
unsigned long mm{};
unsigned long ss{};
std::string memory{};
bool operator<(const MLAT_timestamp& other) const {
// 比较 daysec(高18位)
if (daysec != other.daysec) {
return daysec < other.daysec;
}
// 如果 daysec 相等,比较 nanosec(低30位)
return nanosec < other.nanosec;
}
[[nodiscard]] Psc::JSON toJson() const {
Psc::JSON ret = Psc::JSON::object();
ret.append({"", daysec});
ret.append({"纳秒", nanosec});
ret.append({
"时间", std::to_string(hh) + ":" + std::to_string(mm) + ":" +
std::to_string(ss)
});
return ret;
}
[[nodiscard]] std::string to_string() const {
return "{" + std::to_string(daysec) + "," + std::to_string(nanosec) + "}_" +
"[" + std::to_string(hh) + "时:" + std::to_string(mm) +
"分:" + std::to_string(ss) +
""
"]";
}
void parse_hhmmss();
explicit MLAT_timestamp();
explicit MLAT_timestamp(std::string_view memory_6);
MLAT_timestamp(std::uint32_t daysec, std::uint32_t nanosec);
std::uint32_t daysec{}; // 当天的秒数 高18位
std::uint32_t nanosec{}; // 当天的纳秒数 低30位
std::string to_bin_string() const;
std::string to_memory() const;
unsigned long hh{};
unsigned long mm{};
unsigned long ss{};
std::string memory{};
bool operator<(const MLAT_timestamp& other) const {
// 比较 daysec(高18位)
if (daysec != other.daysec) {
return daysec < other.daysec;
}
// 如果 daysec 相等,比较 nanosec(低30位)
return nanosec < other.nanosec;
}
[[nodiscard]] Psc::JSON toJson() const {
Psc::JSON ret = Psc::JSON::object();
ret.append({"", daysec});
ret.append({"纳秒", nanosec});
ret.append({"时间", std::to_string(hh) + ":" + std::to_string(mm) + ":" + std::to_string(ss)});
return ret;
}
[[nodiscard]] std::string to_string() const {
return "{" + std::to_string(daysec) + "," + std::to_string(nanosec) + "}_" + "[" + std::to_string(hh) +
"时:" + std::to_string(mm) + "分:" + std::to_string(ss) +
""
"]";
}
void parse_hhmmss();
};
}
+1 -1
View File
@@ -9,7 +9,7 @@
#include "py_Mode_S/Common.h"
#include "export_type.h"
#include <string_view>
#include "Core/Statistics/Statistics.h"
#include "Psc_Cpp_Core/Statistics/Statistics.h"
namespace SSR {
void set_logger(BaseLogger* logger);
using Parse_Call_Back = std::function<void(
+346 -358
View File
@@ -1,5 +1,4 @@
#pragma once
#include <string_view>
#include <algorithm>
#include <array>
#include <bitset>
@@ -14,290 +13,283 @@
#include <sstream>
#include <stdexcept>
#include <string>
#include <string_view>
#include <unordered_map>
#include <utility>
#include <vector>
#include "Core/Base/global_include.h"
#include "Core/spdlog/export.h"
#include "Psc_Cpp_Core/Base/global_include.h"
#include "Psc_Cpp_Core/spdlog/export.h"
namespace SSR {
extern BaseLogger *mode_s_logger;
extern BaseLogger* mode_s_logger;
std::string crc_hex(std::string_view msg_bin, bool encode);
int crc(std::string_view msg_bin, bool encode = false);
std::string decode_icao(std::string_view msg_bin);
template <typename T>
void handle_range_error(std::string_view log_pos, std::string_view field_name, T value, double min, double max) {
std::string range =
"[" + std::to_string(min) + "," + std::to_string(max) + "]";
std::string error_info = "ERROR:" + std::string(field_name) + ":" + std::to_string(value) +
"超出范围:" + range + "\n";
Log_Type type({}, {{"POS", std::string(log_pos)}});
mode_s_logger->error("out of range", type, error_info);
// #ifdef WIN32
// Psc::fail_fast("一个只是在windows上崩溃的本质是穿的错误数据
// 或解析的错误数据");
// #endif
// throw std::runtime_error(error_info);
std::string range = "[" + std::to_string(min) + "," + std::to_string(max) + "]";
std::string error_info =
"ERROR:" + std::string(field_name) + ":" + std::to_string(value) + "超出范围:" + range + "\n";
Log_Type type({}, {{"POS", std::string(log_pos)}});
mode_s_logger->error("out of range", type, error_info);
// #ifdef WIN32
// Psc::fail_fast("一个只是在windows上崩溃的本质是穿的错误数据
// 或解析的错误数据");
// #endif
// throw std::runtime_error(error_info);
}
template <typename T>
void handle_range_error(std::string_view log_pos,
std::string_view field_name, std::optional<T> value,
double min, double max) {
handle_range_error(log_pos, field_name, value.value(), min, max);
void handle_range_error(std::string_view log_pos, std::string_view field_name, std::optional<T> value, double min,
double max) {
handle_range_error(log_pos, field_name, value.value(), min, max);
}
#define PROP(TYPE, FIELD, DEFAULT) \
private: \
TYPE FIELD = DEFAULT; \
\
public: \
Builder &set_##FIELD(TYPE value) { \
this->FIELD = std::move(value); \
return *this; \
} \
TYPE get_##FIELD() { return this->FIELD; }
#define PROP_Bit(bits, FIELD, DEFAULT) \
private: \
int FIELD = DEFAULT; \
\
public: \
Builder &set_##FIELD(int value) { \
int MIN = 0; \
int MAX = (1 << bits); \
if (value < MIN || value >= MAX) { \
handle_range_error(LOG_POS, #FIELD, value, MIN, MAX); \
} \
this->FIELD = value; \
return *this; \
} \
int get_##FIELD() { \
int &value = this->FIELD; \
int MIN = 0; \
int MAX = (1 << bits); \
if (value < MIN || value >= MAX) { \
handle_range_error(LOG_POS, #FIELD, value, MIN, MAX); \
} \
return value; \
}
#define PROP_T_FUN(TYPE, FIELD, DEFAULT) \
public: \
That &set_##FIELD(TYPE value) { \
static_cast<That *>(this)->FIELD = std::move(value); \
return *static_cast<That *>(this); \
} \
TYPE get_##FIELD() { \
TYPE &value = static_cast<That *>(this)->FIELD; \
return value; \
}
#define PROP_T(TYPE, FIELD, DEFAULT) \
protected: \
TYPE FIELD = DEFAULT; \
\
public: \
That &set_##FIELD(TYPE value) { \
static_cast<That *>(this)->FIELD = std::move(value); \
return *static_cast<That *>(this); \
} \
TYPE get_##FIELD() { \
TYPE &value = static_cast<That *>(this)->FIELD; \
return value; \
}
#define PROP_Range(TYPE, MIN, MAX, FIELD, DEFAULT) \
private: \
TYPE FIELD = DEFAULT; \
\
public: \
Builder &set_##FIELD(const TYPE &value) { \
if (value < MIN || value > MAX) { \
handle_range_error(LOG_POS, #FIELD, value, MIN, MAX); \
} \
this->FIELD = value; \
return *this; \
} \
TYPE get_##FIELD() { \
TYPE &value = this->FIELD; \
if (value < MIN || value > MAX) { \
handle_range_error(LOG_POS #FIELD, value, MIN, MAX); \
} \
return value; \
}
#define PROP(TYPE, FIELD, DEFAULT) \
private: \
TYPE FIELD = DEFAULT; \
public: \
Builder& set_##FIELD(TYPE value) { \
this->FIELD = std::move(value); \
return *this; \
} \
TYPE get_##FIELD() { \
return this->FIELD; \
}
#define PROP_Bit(bits, FIELD, DEFAULT) \
private: \
int FIELD = DEFAULT; \
public: \
Builder& set_##FIELD(int value) { \
int MIN = 0; \
int MAX = (1 << bits); \
if (value < MIN || value >= MAX) { \
handle_range_error(LOG_POS, #FIELD, value, MIN, MAX); \
} \
this->FIELD = value; \
return *this; \
} \
int get_##FIELD() { \
int& value = this->FIELD; \
int MIN = 0; \
int MAX = (1 << bits); \
if (value < MIN || value >= MAX) { \
handle_range_error(LOG_POS, #FIELD, value, MIN, MAX); \
} \
return value; \
}
#define PROP_T_FUN(TYPE, FIELD, DEFAULT) \
public: \
That& set_##FIELD(TYPE value) { \
static_cast<That*>(this)->FIELD = std::move(value); \
return *static_cast<That*>(this); \
} \
TYPE get_##FIELD() { \
TYPE& value = static_cast<That*>(this)->FIELD; \
return value; \
}
#define PROP_T(TYPE, FIELD, DEFAULT) \
protected: \
TYPE FIELD = DEFAULT; \
public: \
That& set_##FIELD(TYPE value) { \
static_cast<That*>(this)->FIELD = std::move(value); \
return *static_cast<That*>(this); \
} \
TYPE get_##FIELD() { \
TYPE& value = static_cast<That*>(this)->FIELD; \
return value; \
}
#define PROP_Range(TYPE, MIN, MAX, FIELD, DEFAULT) \
private: \
TYPE FIELD = DEFAULT; \
public: \
Builder& set_##FIELD(const TYPE& value) { \
if (value < MIN || value > MAX) { \
handle_range_error(LOG_POS, #FIELD, value, MIN, MAX); \
} \
this->FIELD = value; \
return *this; \
} \
TYPE get_##FIELD() { \
TYPE& value = this->FIELD; \
if (value < MIN || value > MAX) { \
handle_range_error(LOG_POS #FIELD, value, MIN, MAX); \
} \
return value; \
}
// [0, 2^n-1] 区间
#define PROP_Bit_T_Base(Type, bits, FIELD, DEFAULT) \
protected: \
Type FIELD = DEFAULT; \
\
public: \
That &set_##FIELD(Type value) { \
int MIN = 0; \
int MAX = (1 << bits); \
if (value < MIN || value >= MAX) { \
handle_range_error(LOG_POS, #FIELD, value, MIN, MAX); \
} \
static_cast<That *>(this)->FIELD = value; \
return *static_cast<That *>(this); \
} \
Type get_##FIELD() { \
Type &value = static_cast<That *>(this)->FIELD; \
int MIN = 0; \
int MAX = (1 << bits); \
if (value < MIN || value >= MAX) { \
handle_range_error(LOG_POS, #FIELD, value, MIN, MAX); \
} \
return value; \
}
#define PROP_Bit_T(bits, FIELD, DEFAULT) \
PROP_Bit_T_Base(unsigned char, bits, FIELD, DEFAULT)
#define PROP_Bit_32T(bits, FIELD, DEFAULT) \
PROP_Bit_T_Base(unsigned int, bits, FIELD, DEFAULT)
#define PROP_Range_T(TYPE, MIN, MAX, FIELD, DEFAULT) \
private: \
TYPE FIELD = DEFAULT; \
\
public: \
That &set_##FIELD(const TYPE &value) { \
if (value < MIN - std::numeric_limits<double>::epsilon() || \
value > MAX + std::numeric_limits<double>::epsilon()) { \
handle_range_error(LOG_POS, #FIELD, value, MIN, MAX); \
} \
static_cast<That *>(this)->FIELD = value; \
return *static_cast<That *>(this); \
} \
TYPE get_##FIELD() { \
TYPE &value = static_cast<That *>(this)->FIELD; \
if (value < MIN - std::numeric_limits<double>::epsilon() || \
value > MAX + std::numeric_limits<double>::epsilon()) { \
handle_range_error(LOG_POS, #FIELD, value, MIN, MAX); \
} \
return value; \
}
#define BaseADD1(NAME, MSGBase, _T1) \
struct NAME : MSGBase { \
struct Builder; \
using T1 = _T1<Builder>; \
struct Builder : T1 { \
NAME build() { \
NAME ret; \
T1::set(ret.msg); \
this->set_crc(ret.msg, this->icao, this->bds()); \
return ret; \
} \
void parse(std::string &msg) { T1::parse(msg); } \
Psc::JSON toJson() { \
Psc::JSON ret = Psc::JSON::object(); \
ret.append_list(T1::toJson().children); \
return ret; \
} \
}; \
};
#define BaseADD2(NAME, MSGBase, _T1, _T2) \
struct NAME : MSGBase { \
struct Builder; \
using T1 = _T1<Builder>; \
using T2 = _T2<Builder>; \
struct Builder : T1, T2 { \
NAME build() { \
NAME ret; \
T1::set(ret.msg); \
T2::set(ret.msg); \
this->set_crc(ret.msg, this->icao, this->bds()); \
return ret; \
} \
void parse(std::string &msg) { \
T1::parse(msg); \
T2::parse(msg); \
} \
Psc::JSON toJson() { \
Psc::JSON ret = Psc::JSON::object(); \
ret.append_list(T1::toJson().children); \
ret.append_list(T2::toJson().children); \
return ret; \
} \
}; \
};
#define BaseADD3(NAME, MSGBase, _T1, _T2, _T3) \
struct NAME : MSGBase { \
struct Builder; \
using T1 = _T1<Builder>; \
using T2 = _T2<Builder>; \
using T3 = _T3<Builder>; \
struct Builder : T1, T2, T3 { \
NAME build() { \
NAME ret; \
T1::set(ret.msg); \
T2::set(ret.msg); \
T3::set(ret.msg); \
this->set_crc(ret.msg, this->icao, this->bds()); \
return ret; \
} \
void parse(std::string &msg) { \
T1::parse(msg); \
T2::parse(msg); \
T3::parse(msg); \
} \
Psc::JSON toJson() { \
Psc::JSON ret = Psc::JSON::object(); \
ret.append_list(T1::toJson().children); \
ret.append_list(T2::toJson().children); \
ret.append_list(T3::toJson().children); \
return ret; \
} \
}; \
};
#define BaseADD4(NAME, MSGBase, _T1, _T2, _T3, _T4) \
struct NAME : MSGBase { \
struct Builder; \
using T1 = _T1<Builder>; \
using T2 = _T2<Builder>; \
using T3 = _T3<Builder>; \
using T4 = _T4<Builder>; \
struct Builder : T1, T2, T3, T4 { \
NAME build() { \
NAME ret; \
T1::set(ret.msg); \
T2::set(ret.msg); \
T3::set(ret.msg); \
T4::set(ret.msg); \
this->set_crc(ret.msg, this->icao, this->bds()); \
return ret; \
} \
void parse(std::string &msg) { \
T1::parse(msg); \
T2::parse(msg); \
T3::parse(msg); \
T4::parse(msg); \
} \
Psc::JSON toJson() { \
Psc::JSON ret = Psc::JSON::object(); \
ret.append_list(T1::toJson().children); \
ret.append_list(T2::toJson().children); \
ret.append_list(T3::toJson().children); \
ret.append_list(T4::toJson().children); \
return ret; \
} \
}; \
};
#define PROP_Bit_T_Base(Type, bits, FIELD, DEFAULT) \
protected: \
Type FIELD = DEFAULT; \
public: \
That& set_##FIELD(Type value) { \
int MIN = 0; \
int MAX = (1 << bits); \
if (value < MIN || value >= MAX) { \
handle_range_error(LOG_POS, #FIELD, value, MIN, MAX); \
} \
static_cast<That*>(this)->FIELD = value; \
return *static_cast<That*>(this); \
} \
Type get_##FIELD() { \
Type& value = static_cast<That*>(this)->FIELD; \
int MIN = 0; \
int MAX = (1 << bits); \
if (value < MIN || value >= MAX) { \
handle_range_error(LOG_POS, #FIELD, value, MIN, MAX); \
} \
return value; \
}
#define PROP_Bit_T(bits, FIELD, DEFAULT) PROP_Bit_T_Base(unsigned char, bits, FIELD, DEFAULT)
#define PROP_Bit_32T(bits, FIELD, DEFAULT) PROP_Bit_T_Base(unsigned int, bits, FIELD, DEFAULT)
#define PROP_Range_T(TYPE, MIN, MAX, FIELD, DEFAULT) \
private: \
TYPE FIELD = DEFAULT; \
public: \
That& set_##FIELD(const TYPE& value) { \
if (value < MIN - std::numeric_limits<double>::epsilon() || \
value > MAX + std::numeric_limits<double>::epsilon()) { \
handle_range_error(LOG_POS, #FIELD, value, MIN, MAX); \
} \
static_cast<That*>(this)->FIELD = value; \
return *static_cast<That*>(this); \
} \
TYPE get_##FIELD() { \
TYPE& value = static_cast<That*>(this)->FIELD; \
if (value < MIN - std::numeric_limits<double>::epsilon() || \
value > MAX + std::numeric_limits<double>::epsilon()) { \
handle_range_error(LOG_POS, #FIELD, value, MIN, MAX); \
} \
return value; \
}
#define BaseADD1(NAME, MSGBase, _T1) \
struct NAME : MSGBase { \
struct Builder; \
using T1 = _T1<Builder>; \
struct Builder : T1 { \
NAME build() { \
NAME ret; \
T1::set(ret.msg); \
this->set_crc(ret.msg, this->icao, this->bds()); \
return ret; \
} \
void parse(std::string& msg) { \
T1::parse(msg); \
} \
Psc::JSON toJson() { \
Psc::JSON ret = Psc::JSON::object(); \
ret.append_list(T1::toJson().children); \
return ret; \
} \
}; \
};
#define BaseADD2(NAME, MSGBase, _T1, _T2) \
struct NAME : MSGBase { \
struct Builder; \
using T1 = _T1<Builder>; \
using T2 = _T2<Builder>; \
struct Builder : T1, T2 { \
NAME build() { \
NAME ret; \
T1::set(ret.msg); \
T2::set(ret.msg); \
this->set_crc(ret.msg, this->icao, this->bds()); \
return ret; \
} \
void parse(std::string& msg) { \
T1::parse(msg); \
T2::parse(msg); \
} \
Psc::JSON toJson() { \
Psc::JSON ret = Psc::JSON::object(); \
ret.append_list(T1::toJson().children); \
ret.append_list(T2::toJson().children); \
return ret; \
} \
}; \
};
#define BaseADD3(NAME, MSGBase, _T1, _T2, _T3) \
struct NAME : MSGBase { \
struct Builder; \
using T1 = _T1<Builder>; \
using T2 = _T2<Builder>; \
using T3 = _T3<Builder>; \
struct Builder : T1, T2, T3 { \
NAME build() { \
NAME ret; \
T1::set(ret.msg); \
T2::set(ret.msg); \
T3::set(ret.msg); \
this->set_crc(ret.msg, this->icao, this->bds()); \
return ret; \
} \
void parse(std::string& msg) { \
T1::parse(msg); \
T2::parse(msg); \
T3::parse(msg); \
} \
Psc::JSON toJson() { \
Psc::JSON ret = Psc::JSON::object(); \
ret.append_list(T1::toJson().children); \
ret.append_list(T2::toJson().children); \
ret.append_list(T3::toJson().children); \
return ret; \
} \
}; \
};
#define BaseADD4(NAME, MSGBase, _T1, _T2, _T3, _T4) \
struct NAME : MSGBase { \
struct Builder; \
using T1 = _T1<Builder>; \
using T2 = _T2<Builder>; \
using T3 = _T3<Builder>; \
using T4 = _T4<Builder>; \
struct Builder : T1, T2, T3, T4 { \
NAME build() { \
NAME ret; \
T1::set(ret.msg); \
T2::set(ret.msg); \
T3::set(ret.msg); \
T4::set(ret.msg); \
this->set_crc(ret.msg, this->icao, this->bds()); \
return ret; \
} \
void parse(std::string& msg) { \
T1::parse(msg); \
T2::parse(msg); \
T3::parse(msg); \
T4::parse(msg); \
} \
Psc::JSON toJson() { \
Psc::JSON ret = Psc::JSON::object(); \
ret.append_list(T1::toJson().children); \
ret.append_list(T2::toJson().children); \
ret.append_list(T3::toJson().children); \
ret.append_list(T4::toJson().children); \
return ret; \
} \
}; \
};
struct Base_56 {
std::string msg;
Base_56() {
msg.resize(56, '0');
}
std::string msg;
Base_56() {
msg.resize(56, '0');
}
};
struct Base_112 {
std::string msg;
Base_112() {
msg.resize(112, '0');
}
std::string msg;
Base_112() {
msg.resize(112, '0');
}
};
#define ADD_112_1(NAME, _T1) BaseADD1(NAME, Base_112, _T1)
#define ADD_112_2(NAME, _T1, _T2) BaseADD2(NAME, Base_112, _T1, _T2)
#define ADD_112_3(NAME, _T1, _T2, _T3) BaseADD3(NAME, Base_112, _T1, _T2, _T3)
#define ADD_112_4(NAME, _T1, _T2, _T3, _T4) \
BaseADD4(NAME, Base_112, _T1, _T2, _T3, _T4)
#define ADD_112_4(NAME, _T1, _T2, _T3, _T4) BaseADD4(NAME, Base_112, _T1, _T2, _T3, _T4)
#define ADD_56_1(NAME, _T1) BaseADD1(NAME, Base_56, _T1)
#define ADD_56_2(NAME, _T1, _T2) BaseADD2(NAME, Base_56, _T1, _T2)
#define ADD_56_3(NAME, _T1, _T2, _T3) BaseADD3(NAME, Base_56, _T1, _T2, _T3)
#define ADD_56_4(NAME, _T1, _T2, _T3, _T4) \
BaseADD4(NAME, Base_56, _T1, _T2, _T3, _T4)
#define T_Parser(Template_name) \
struct Parser_##Template_name : Template_name<Parser_##Template_name> {};
#define ADD_56_4(NAME, _T1, _T2, _T3, _T4) BaseADD4(NAME, Base_56, _T1, _T2, _T3, _T4)
#define T_Parser(Template_name) \
struct Parser_##Template_name : Template_name<Parser_##Template_name> {};
// 模式 S 使用三种类型的奇偶校验。
// 第一个只是 CRC 提醒,用于扩展 squitter 中的 ADS-B(参见第
// [章:adsb_parity])。 其他两种类型的奇偶校验是地址奇偶校验 (AP)
@@ -308,38 +300,36 @@ struct Base_112 {
// Surveillance replies DF=4,5 AP
// All call reply
struct with_PI {
virtual ~with_PI() = default;
void set_crc(std::string& msg, std::string icao, std::string bds) {
icao.resize(6, '0');
bds.resize(6, '0');
int size = static_cast<int>(msg.size());
auto crc_24 = std::bitset<24>(crc(msg, true)).to_string();
auto transponder_address = get_crc_transponder_address();
msg.replace(size - 24, 24, Psc::xorBin(crc_24, transponder_address));
}
// All call reply 是基于审讯的报文,PI是 询问器设备码 和 crc 异或而成的
// 所以,必须知道询问器标识符 才能校验是否有错误
// 每个设备应该只有一个询问器标识符
static bool check_crc(std::string& msg_bin, std::string icao_hex,
std::string bds = "") {
auto crc_24 = std::bitset<24>(crc(msg_bin, true)).to_string();
auto last_24 = msg_bin.substr(msg_bin.size() - 24);
return crc_24 == last_24;
}
static std::string parse_transponder_address(std::string& msg_bin,
std::string icao_hex) {
int size = static_cast<int>(msg_bin.size());
icao_hex.resize(6, '0');
auto crc_24 = std::bitset<24>(crc(msg_bin, true)).to_string();
auto PA = Psc::hex2bin(icao_hex);
auto last_24 = msg_bin.substr(size - 24);
return Psc::bin2hex(Psc::xorBin(crc_24, Psc::xorBin(PA, last_24)));
}
virtual ~with_PI() = default;
void set_crc(std::string& msg, std::string icao, std::string bds) {
icao.resize(6, '0');
bds.resize(6, '0');
int size = static_cast<int>(msg.size());
auto crc_24 = std::bitset<24>(crc(msg, true)).to_string();
auto transponder_address = get_crc_transponder_address();
msg.replace(size - 24, 24, Psc::xorBin(crc_24, transponder_address));
}
// All call reply 是基于审讯的报文,PI是 询问器设备码 和 crc 异或而成的
// 所以,必须知道询问器标识符 才能校验是否有错误
// 每个设备应该只有一个询问器标识符
static bool check_crc(std::string& msg_bin, std::string icao_hex, std::string bds = "") {
auto crc_24 = std::bitset<24>(crc(msg_bin, true)).to_string();
auto last_24 = msg_bin.substr(msg_bin.size() - 24);
return crc_24 == last_24;
}
static std::string parse_transponder_address(std::string& msg_bin, std::string icao_hex) {
int size = static_cast<int>(msg_bin.size());
icao_hex.resize(6, '0');
auto crc_24 = std::bitset<24>(crc(msg_bin, true)).to_string();
auto PA = Psc::hex2bin(icao_hex);
auto last_24 = msg_bin.substr(size - 24);
return Psc::bin2hex(Psc::xorBin(crc_24, Psc::xorBin(PA, last_24)));
}
protected:
virtual std::string get_crc_transponder_address() {
return Psc::hex2bin(std::string("000000"));
}
// ADS-B 是自发的,所以解不出询问器地址 询问器地址都是0
virtual std::string get_crc_transponder_address() {
return Psc::hex2bin(std::string("000000"));
}
// ADS-B 是自发的,所以解不出询问器地址 询问器地址都是0
};
using Psc::bin2;
using Psc::bin2hex;
@@ -350,29 +340,28 @@ using Psc::xorBin;
// icao = crc0 xor last
// crc === icao xor last === crc0
struct with_AP {
void set_crc(std::string& msg, std::string icao, std::string bds) {
icao.resize(6, '0');
bds.resize(6, '0');
auto crc_24 = std::bitset<24>(crc(msg, true)).to_string();
auto PA = xorBin(crc_24, std::bitset<24>(icao).to_string());
msg.replace(msg.size() - 24, 24, PA);
}
static bool check_crc(std::string& msg_bin, std::string icao_hex,
std::string bds = "") {
int size = static_cast<int>(msg_bin.size());
icao_hex.resize(6, '0');
bds.resize(6, '0');
auto icao_24 = hex2bin(icao_hex);
auto last_24 = msg_bin.substr(size - 24);
std::string crc_code = xorBin(last_24, icao_24);
std::string temp = msg_bin;
temp.replace(size - 24, 24, crc_code);
bool ret = crc(temp) == 0;
if (!ret) {
return false;
}
return ret;
}
void set_crc(std::string& msg, std::string icao, std::string bds) {
icao.resize(6, '0');
bds.resize(6, '0');
auto crc_24 = std::bitset<24>(crc(msg, true)).to_string();
auto PA = xorBin(crc_24, std::bitset<24>(icao).to_string());
msg.replace(msg.size() - 24, 24, PA);
}
static bool check_crc(std::string& msg_bin, std::string icao_hex, std::string bds = "") {
int size = static_cast<int>(msg_bin.size());
icao_hex.resize(6, '0');
bds.resize(6, '0');
auto icao_24 = hex2bin(icao_hex);
auto last_24 = msg_bin.substr(size - 24);
std::string crc_code = xorBin(last_24, icao_24);
std::string temp = msg_bin;
temp.replace(size - 24, 24, crc_code);
bool ret = crc(temp) == 0;
if (!ret) {
return false;
}
return ret;
}
};
// ICAO: DD33AA 1101 1101 0011 0011 1010 1010
//
@@ -384,37 +373,36 @@ struct with_AP {
// 不知道什么消息用这个校验
//
struct with_DP {
void set_crc(std::string& msg, std::string icao, std::string bds) {
icao.resize(6, '0');
bds.resize(6, '0');
auto crc_24 = std::bitset<24>(crc(msg, true)).to_string();
auto icao_24 = hex2bin(icao);
auto bds_24 = hex2bin(bds);
auto transponder_address = hex2bin(std::string("000000"));
auto last24 =
xorBin(xorBin(crc_24, icao_24), xorBin(bds_24, transponder_address));
msg.replace(msg.size() - 24, 24, last24);
}
static bool check_crc(std::string& msg_bin, std::string_view icao_hex,
std::string_view bds) {
return true;
}
static std::string transponder_address(std::string& msg, std::string icao,
std::string bds) {
int size = static_cast<int>(msg.size());
icao.resize(6, '0');
bds.resize(6, '0');
auto crc_24 = std::bitset<24>(crc(msg, true)).to_string();
auto last_24 = msg.substr(size - 24);
auto icao_bin = hex2bin(icao);
auto bds_bin = hex2bin(bds);
return bin2hex(xorBin(xorBin(last_24, crc_24), xorBin(icao_bin, bds_bin)));
}
void set_crc(std::string& msg, std::string icao, std::string bds) {
icao.resize(6, '0');
bds.resize(6, '0');
auto crc_24 = std::bitset<24>(crc(msg, true)).to_string();
auto icao_24 = hex2bin(icao);
auto bds_24 = hex2bin(bds);
auto transponder_address = hex2bin(std::string("000000"));
auto last24 = xorBin(xorBin(crc_24, icao_24), xorBin(bds_24, transponder_address));
msg.replace(msg.size() - 24, 24, last24);
}
static bool check_crc(std::string& msg_bin, std::string_view icao_hex, std::string_view bds) {
return true;
}
static std::string transponder_address(std::string& msg, std::string icao, std::string bds) {
int size = static_cast<int>(msg.size());
icao.resize(6, '0');
bds.resize(6, '0');
auto crc_24 = std::bitset<24>(crc(msg, true)).to_string();
auto last_24 = msg.substr(size - 24);
auto icao_bin = hex2bin(icao);
auto bds_bin = hex2bin(bds);
return bin2hex(xorBin(xorBin(last_24, crc_24), xorBin(icao_bin, bds_bin)));
}
};
#define D_BDS(number) \
struct BDS##number { \
static std::string bds() { return #number; } \
};
#define D_BDS(number) \
struct BDS##number { \
static std::string bds() { \
return #number; \
} \
};
D_BDS(_) // 凑数的
// ADS-B
D_BDS(05) // 机载位置
@@ -436,15 +424,15 @@ D_BDS(60) // 航向和速度报告
// Commb MS Meteorological services
D_BDS(44) // 气象例行空气报告
D_BDS(45) // 气象灾害报告
#define CE(cond, msg) \
if (cond) { \
static Log_Type log_type({}, {{"POS", LOG_POS}}); \
SSR::mode_s_logger->error("", log_type, msg); \
}
#define CE2(cond, msg) \
if (cond) { \
static Log_Type log_type({}, {{"POS", LOG_POS}}); \
SSR::mode_s_logger->error("", log_type, msg); \
return std::nullopt; \
}
}
#define CE(cond, msg) \
if (cond) { \
static Log_Type log_type({}, {{"POS", LOG_POS}}); \
SSR::mode_s_logger->error("", log_type, msg); \
}
#define CE2(cond, msg) \
if (cond) { \
static Log_Type log_type({}, {{"POS", LOG_POS}}); \
SSR::mode_s_logger->error("", log_type, msg); \
return std::nullopt; \
}
} // namespace SSR
+1 -1
View File
@@ -1,5 +1,5 @@
#include "Common.h"
#include "Core/Base/global_include.h"
#include "Psc_Cpp_Core/Base/global_include.h"
#include <string_view>
#undef max
#undef min
+59 -66
View File
@@ -1,66 +1,64 @@
#pragma once
#include <string_view>
#include "../CPR/CPR.h"
#include "Core/Base/global_include.h"
#include "Psc_Cpp_Core/Base/global_include.h"
#include "SSR/enum.h"
#ifndef M_PI
#define M_PI 3.14159265358979323846
#endif
#define Handle_Error(msg) \
std::cerr << msg; \
return std::nullopt;
#define Handle_Error2(cond, msg) \
if (cond) { \
std::cerr << msg; \
return std::nullopt; \
}
#define Handle_Error3(cond, msg) \
if (cond) { \
std::cerr << msg; \
}
#define Exec(var, expr) \
auto _opt_##var = type_code(msg); \
if (!_opt_##var.has_value()) \
return std::nullopt; \
auto var = _opt_##var.value();
#define Exec2(var, expr) \
auto _opt_##var = expr; \
auto var = _opt_##var.value();
#define Handle_Error(msg) \
std::cerr << msg; \
return std::nullopt;
#define Handle_Error2(cond, msg) \
if (cond) { \
std::cerr << msg; \
return std::nullopt; \
}
#define Handle_Error3(cond, msg) \
if (cond) { \
std::cerr << msg; \
}
#define Exec(var, expr) \
auto _opt_##var = type_code(msg); \
if (!_opt_##var.has_value()) \
return std::nullopt; \
auto var = _opt_##var.value();
#define Exec2(var, expr) \
auto _opt_##var = expr; \
auto var = _opt_##var.value();
// 定义一个宏 release模式输出core
// dump信息到控制台,到文件,这个文件名还要是自增的,这样不丢,
// 然后直接崩溃能看调用栈
// Debug模式下,然后抛出异常,异常在最顶层集中处理,没有异常才把该报文的信息汇总
namespace SSR {
struct Air_Speed {
double speed = -1; // kt
double angle = -1; // degree
int vertical_rate = -1; // ft/min
std::string
speed_type; // Speed type: 'GS' for ground speed, 'AS' for airspeed
std::string direction_source; // Optional: Direction source ('TRUE_NORTH' or
// 'MAGNETIC_NORTH')
std::string
vertical_rate_source; // Optional: Vertical rate source ('BARO' or 'GNSS')
Psc::JSON toJson() {
return Psc::JSON::object({
{"speed", speed},
{"angle", angle},
{"vertical_rate", vertical_rate},
{"speed_type", speed_type},
{"direction_source", direction_source},
{"vertical_rate_source", vertical_rate_source},
});
}
double speed = -1; // kt
double angle = -1; // degree
int vertical_rate = -1; // ft/min
std::string speed_type; // Speed type: 'GS' for ground speed, 'AS' for airspeed
std::string direction_source; // Optional: Direction source ('TRUE_NORTH' or
// 'MAGNETIC_NORTH')
std::string vertical_rate_source; // Optional: Vertical rate source ('BARO' or 'GNSS')
Psc::JSON toJson() {
return Psc::JSON::object({
{"speed", speed},
{"angle", angle},
{"vertical_rate", vertical_rate},
{"speed_type", speed_type},
{"direction_source", direction_source},
{"vertical_rate_source", vertical_rate_source},
});
}
};
struct Ground_Speed {
double speed = -1; // kt
double angle = -1; // degree
Psc::JSON toJson() {
return Psc::JSON::object({
{"speed", speed},
{"angle", angle},
});
}
double speed = -1; // kt
double angle = -1; // degree
Psc::JSON toJson() {
return Psc::JSON::object({
{"speed", speed},
{"angle", angle},
});
}
};
// common
Downlink_Format decode_df(std::string_view msg);
@@ -78,15 +76,14 @@ void set_df(std::string& msg, Downlink_Format df);
// return result;
// };
Transponder_Capability decode_transponder_capability(std::string_view msg);
void set_transponder_capability(std::string& msg,
Transponder_Capability transponder_capability);
void set_transponder_capability(std::string& msg, Transponder_Capability transponder_capability);
int crc(std::string_view msg_bin, bool encode);
std::string decode_icao(std::string_view msg_bin);
std::string set_icao(std::string& msg, std::string_view icaoHex);
bool is_icao_assigned(std::string_view icao);
int type_code(std::string_view msg);
void set_type_code(std::string& msg, int type_code);
int get_type_code(std::string & msg);
int get_type_code(std::string& msg);
std::string idcode(std::string_view msg);
void set_idcode(std::string& msg, std::string_view idcode);
std::string decode_squawk13(std::string_view binstr);
@@ -128,17 +125,16 @@ const double beta = -0.0065; // [K/m] ISA temp gradient below tropopause
const double r_earth = 6371000; // m, average earth radius
const double a0 = 340.293988; // m/s, sea level speed of sound ISA
struct Atmos {
double p;
double rho;
double T;
double p;
double rho;
double T;
};
Atmos atmos(double H);
double temperature(double H);
double pressure(double H);
double density(double H);
double vsound(double H);
double distance(double lat1, double lon1, double lat2, double lon2,
double H = 0);
double distance(double lat1, double lon1, double lat2, double lon2, double H = 0);
double bearing(double lat1, double lon1, double lat2, double lon2);
double tas2mach(double Vtas, double H);
double mach2tas(double Mach, double H);
@@ -156,8 +152,7 @@ double cas2mach(double Vcas, double H);
Airborne position
------------------------------------------
*/
double decode_altitude_12_meter(std::string_view msg_bin,
Altitude_type altitude_type);
double decode_altitude_12_meter(std::string_view msg_bin, Altitude_type altitude_type);
std::string encode_altitude_code_12(double height, Altitude_type altitude_type);
Vortex_Type parse_vortex_type(std::string_view msg);
// ------------------------------------------
@@ -190,8 +185,7 @@ double altitude_diff(std::string_view msg);
std::string vertical_rate_code_10(double vertical_rate);
double decode_vertical_rate_10(std::string_view vertical_rate);
std::string GNSS_barometric_altitudes_difference_8(double altitude_difference);
std::string encode_velocity_22(Ground_Speed_Type subType, double track_angle,
double ground_speed);
std::string encode_velocity_22(Ground_Speed_Type subType, double track_angle, double ground_speed);
std::string encode_magnetic_heading_11(double heading);
std::string encode_airspeed_10(Air_Speed_Code_Type subtype, double airspeed);
// ------------------------------------------
@@ -233,13 +227,13 @@ RET<int> alt40fms(std::string_view msg);
// ------------------------------------------
bool is44(std::string_view msg);
struct Wind {
int wind_speed;
double direction;
int wind_speed;
double direction;
};
RET<Wind> wind44(std::string_view msg);
struct Temperature {
double temperature;
double temperature_alternative;
double temperature;
double temperature_alternative;
};
Temperature temp44(std::string_view msg);
int p44(std::string_view msg);
@@ -319,8 +313,7 @@ Emergency_Type emergency_status(std::string_view msg);
// ------------------------------------------
// BDS
// ------------------------------------------
std::string is50or60(std::string_view msg, double spd_ref, double trk_ref,
double alt_ref);
std::string is50or60(std::string_view msg, double spd_ref, double trk_ref, double alt_ref);
std::string infer(std::string_view msg_bin, bool mrar = false);
std::vector<std::string> infer2(std::string_view msg, bool mrar = false);
// ADS-B
+1 -1
View File
@@ -1,5 +1,5 @@
#include "./Common.h"
#include "Core/Statistics/Frequency_Limit.h"
#include "Psc_Cpp_Core/Statistics/Frequency_Limit.h"
#include "SSR/CPR/CPR.h"
#include <string_view>
#undef max
+11 -10
View File
@@ -1,15 +1,16 @@
_create(interface SSR)
set(Core Core_Static)
_attach_include_dir("SSR" "${CMAKE_CURRENT_LIST_DIR}")
_attach_source_dir("SSR" "${CMAKE_CURRENT_LIST_DIR}/SSR")
_attach_source_dir("SSR" "${CMAKE_CURRENT_LIST_DIR}/test")
_depend(SSR ${Core})
#_create(dll readsb2)
#_attach_include_dir(readsb2 "${CMAKE_CURRENT_LIST_DIR}")
#_attach_source_dir(readsb2 "${CMAKE_CURRENT_LIST_DIR}/readsb2")
set(Core Psc_Core_Static)
set(SSR_srcs)
append_glob_source(SSR_srcs "${CMAKE_CURRENT_LIST_DIR}/SSR" "${CMAKE_CURRENT_LIST_DIR}/test")
add_library(SSR STATIC ${SSR_srcs})
target_include_directories(SSR PUBLIC "${CMAKE_CURRENT_LIST_DIR}")
target_link_libraries(SSR PUBLIC ${Core})