cmake库改造前
This commit is contained in:
@@ -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"
|
||||
|
||||
@@ -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
@@ -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
@@ -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
@@ -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
|
||||
|
||||
@@ -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,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
@@ -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
@@ -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
@@ -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,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
@@ -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,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
@@ -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})
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user