更新cpr统计,以及解码时间间隔,速度检测跳过配置
This commit is contained in:
+13
-44
@@ -69,22 +69,18 @@ struct CPR_Data {
|
|||||||
}
|
}
|
||||||
} even_msg, odd_msg;
|
} even_msg, odd_msg;
|
||||||
time_t last_parse_pos_time = 0;
|
time_t last_parse_pos_time = 0;
|
||||||
std::function<std::optional<CPR::Position>(
|
std::function<std::optional<CPR::Position>(std::string_view, std::string_view, time_t, time_t)> global_parse = nullptr;
|
||||||
std::string_view, std::string_view, time_t, time_t)>
|
std::function<std::optional<CPR::Position>(std::string_view, double lat, double lon, time_t, time_t)> locale_parse = nullptr;
|
||||||
global_parse = nullptr;
|
|
||||||
std::function<std::optional<CPR::Position>(std::string_view, double lat, double lon, time_t, time_t)>
|
|
||||||
locale_parse = nullptr;
|
|
||||||
std::function<std::string(double, double, CPR::Frame)> encode = nullptr;
|
std::function<std::string(double, double, CPR::Frame)> encode = nullptr;
|
||||||
std::optional<CPR::Position> pos;
|
std::optional<CPR::Position> pos;
|
||||||
std::optional<CPR::Position> cache_ok_pos;
|
|
||||||
CPR::Frame cpr_format = CPR::Frame::Even;
|
CPR::Frame cpr_format = CPR::Frame::Even;
|
||||||
void set_pos(std::optional<CPR::Position> new_pos, time_t cur_time) {
|
};
|
||||||
pos = new_pos;
|
struct Constraint {
|
||||||
if (new_pos != std::nullopt) {
|
CPR::D max_speed_m_s;
|
||||||
cache_ok_pos = new_pos;
|
CPR::D max_time_s;
|
||||||
}
|
SSR::CPR_CB cb;
|
||||||
last_parse_pos_time = cur_time;
|
bool time_space_filter;
|
||||||
}
|
bool speed_filter;
|
||||||
};
|
};
|
||||||
template <typename That>
|
template <typename That>
|
||||||
struct CPR_MSG : CPR_Data {
|
struct CPR_MSG : CPR_Data {
|
||||||
@@ -92,16 +88,7 @@ struct CPR_MSG : CPR_Data {
|
|||||||
PROP_T_FUN(RET<double>, lon, std::nullopt)
|
PROP_T_FUN(RET<double>, lon, std::nullopt)
|
||||||
PROP_T_FUN(RET<double>, lat, std::nullopt)
|
PROP_T_FUN(RET<double>, lat, std::nullopt)
|
||||||
PROP_T_FUN(CPR::Frame, cpr_format, CPR::Frame::Even);
|
PROP_T_FUN(CPR::Frame, cpr_format, CPR::Frame::Even);
|
||||||
std::string current_state() {
|
std::string current_state(P_S msg);
|
||||||
std::ostringstream oss;
|
|
||||||
oss << "{" << std::endl;
|
|
||||||
oss << "\tpos:" << (pos.has_value() ? pos->to_string() : "null")
|
|
||||||
<< std::endl;
|
|
||||||
oss << "\todd_msg: " + odd_msg.to_string() << std::endl;
|
|
||||||
oss << "\teven_msg: " + even_msg.to_string() << std::endl;
|
|
||||||
oss << "}" << std::endl;
|
|
||||||
return oss.str();
|
|
||||||
}
|
|
||||||
Psc::JSON current_state_json() {
|
Psc::JSON current_state_json() {
|
||||||
Psc::JSON ret = Psc::JSON::object();
|
Psc::JSON ret = Psc::JSON::object();
|
||||||
ret.append({"pos", (pos.has_value() ? pos->to_string() : "null")});
|
ret.append({"pos", (pos.has_value() ? pos->to_string() : "null")});
|
||||||
@@ -109,27 +96,9 @@ struct CPR_MSG : CPR_Data {
|
|||||||
ret.append({"even_msg", even_msg.to_json()});
|
ret.append({"even_msg", even_msg.to_json()});
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
std::string get_cpr_log(std::string_view type, std::string_view icao,
|
RET<Pos_Ret> global_parse_message(P_S msg, double time_s, P_S other_msg, double other_time_s, Constraint constraint);
|
||||||
std::string_view msg_hex, CPR::Frame f,
|
RET<Pos_Ret> local_parse_message(CPR::Position old_pos, P_S msg, double time_s, Constraint constraint);
|
||||||
std::string_view before_state, std::string_view after_state) {
|
RET<Pos_Ret> parse_message(P_S msg, double time_s, Constraint constraint);
|
||||||
return std::format(
|
|
||||||
"\n"
|
|
||||||
"【开始】:===============[{0}][{1}]======================\n"
|
|
||||||
"当前收到的消息 msg: {2} frame:{3} \n"
|
|
||||||
"先前的状态:\n{4}现在的状态:\n{5}\n"
|
|
||||||
"【结束】:===============[{0}][{1}]======================\n",
|
|
||||||
type,
|
|
||||||
icao,
|
|
||||||
msg_hex,
|
|
||||||
Psc::to_string(f),
|
|
||||||
before_state,
|
|
||||||
current_state()
|
|
||||||
);
|
|
||||||
}
|
|
||||||
// 虽然消息已经存在当天的秒数
|
|
||||||
RET<Pos_Ret> parse_message(const std::shared_ptr<Mode_S_Msg>& msg,
|
|
||||||
double time_s, CPR::D max_speed_m_s,
|
|
||||||
CPR::D max_time_s, const SSR::CPR_CB& cb);
|
|
||||||
virtual void parse(std::string& msg_bin) {
|
virtual void parse(std::string& msg_bin) {
|
||||||
get_bin<53, 1, CPR::Frame>(msg_bin, cpr_format);
|
get_bin<53, 1, CPR::Frame>(msg_bin, cpr_format);
|
||||||
}
|
}
|
||||||
|
|||||||
+5
-20
@@ -100,16 +100,7 @@ bool check_new_prase_pos(ADS_B_T::CPR_Data& t, std::optional<CPR::Position>& tp,
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
constexpr double s_ns = 1000000000.0;
|
constexpr double s_ns = 1000000000.0;
|
||||||
// cpr回调
|
bool parse_absb_17(SSR::Data_Source_Interface* src, SSR::P_S mode_s_msg, JSON& msg_json, std::optional<CPR::Position> base_station_pos, SSR::ADS_B_T::Constraint air_constraint, SSR::ADS_B_T::Constraint surface_constraint) {
|
||||||
CPR_CB cpr_cb = [](CPR_Error_Type t, std::string_view log, P_S msg) {
|
|
||||||
if (mode_s_logger) mode_s_logger->debug("CPR/" + to_string(t), {}, log);
|
|
||||||
|
|
||||||
};
|
|
||||||
bool parse_absb_17(SSR::Data_Source_Interface* src, SSR::P_S mode_s_msg,
|
|
||||||
JSON& msg_json,
|
|
||||||
std::optional<CPR::Position> base_station_pos,
|
|
||||||
CPR::D max_speed_m_s, CPR::Time air_pos_time_out,
|
|
||||||
CPR::Time surface_pos_time_out) {
|
|
||||||
std::shared_ptr<Aircraft_Info> a = src->get_aircraft(mode_s_msg->icao);
|
std::shared_ptr<Aircraft_Info> a = src->get_aircraft(mode_s_msg->icao);
|
||||||
if (!a) {
|
if (!a) {
|
||||||
a = src->create_aircraft(mode_s_msg->icao);
|
a = src->create_aircraft(mode_s_msg->icao);
|
||||||
@@ -127,8 +118,7 @@ bool parse_absb_17(SSR::Data_Source_Interface* src, SSR::P_S mode_s_msg,
|
|||||||
Parse_no_json(t, BDS06_surface_position)
|
Parse_no_json(t, BDS06_surface_position)
|
||||||
info.refresh_pos(true);
|
info.refresh_pos(true);
|
||||||
t.base_station_pos = base_station_pos;
|
t.base_station_pos = base_station_pos;
|
||||||
auto tp = t.parse_message(mode_s_msg, mode_s_msg->time().abs_sec(),
|
auto tp = t.parse_message(mode_s_msg, mode_s_msg->time().abs_sec(), air_constraint);
|
||||||
max_speed_m_s, surface_pos_time_out, cpr_cb);
|
|
||||||
if (tp.has_value()) {
|
if (tp.has_value()) {
|
||||||
auto t2 = t.odd_msg;
|
auto t2 = t.odd_msg;
|
||||||
Position_Info p(tp.value(), info.altitude_meter().value_or(0));
|
Position_Info p(tp.value(), info.altitude_meter().value_or(0));
|
||||||
@@ -149,8 +139,7 @@ bool parse_absb_17(SSR::Data_Source_Interface* src, SSR::P_S mode_s_msg,
|
|||||||
Parse(t2, BDS05_airborne_Position_v2)
|
Parse(t2, BDS05_airborne_Position_v2)
|
||||||
}
|
}
|
||||||
using namespace std::chrono;
|
using namespace std::chrono;
|
||||||
auto tp = t.parse_message(mode_s_msg, mode_s_msg->time().abs_sec(), max_speed_m_s, air_pos_time_out,
|
auto tp = t.parse_message(mode_s_msg, mode_s_msg->time().abs_sec(), surface_constraint);
|
||||||
cpr_cb);
|
|
||||||
if (tp.has_value()) {
|
if (tp.has_value()) {
|
||||||
auto alt = t.get_alt_meter();
|
auto alt = t.get_alt_meter();
|
||||||
Position_Info p(tp.value(), alt);
|
Position_Info p(tp.value(), alt);
|
||||||
@@ -306,10 +295,7 @@ bool parse_Message_commb(SSR::Data_Source_Interface* src,
|
|||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
bool parse_mode_s_bin(Data_Source_Interface* src, P_S mode_s_msg,
|
bool parse_mode_s_bin(Data_Source_Interface* src, P_S mode_s_msg, std::optional<CPR::Position> base_station_pos, SSR::ADS_B_T::Constraint air_constraint, SSR::ADS_B_T::Constraint surface_constraint) {
|
||||||
std::optional<CPR::Position> base_station_pos,
|
|
||||||
CPR::D max_speed_m_s, CPR::Time air_pos_time_out,
|
|
||||||
CPR::Time surface_pos_time_out) {
|
|
||||||
auto& msg_hex = mode_s_msg->msg_hex;
|
auto& msg_hex = mode_s_msg->msg_hex;
|
||||||
auto& msg = mode_s_msg->msg_bin;
|
auto& msg = mode_s_msg->msg_bin;
|
||||||
auto& df = mode_s_msg->df;
|
auto& df = mode_s_msg->df;
|
||||||
@@ -324,8 +310,7 @@ bool parse_mode_s_bin(Data_Source_Interface* src, P_S mode_s_msg,
|
|||||||
"parse_absb_17 crc_error", {}, nullptr, mode_s_msg);
|
"parse_absb_17 crc_error", {}, nullptr, mode_s_msg);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
ok = parse_absb_17(src, mode_s_msg, msg_json, base_station_pos,
|
ok = parse_absb_17(src, mode_s_msg, msg_json, base_station_pos, air_constraint, surface_constraint);
|
||||||
max_speed_m_s, air_pos_time_out, surface_pos_time_out);
|
|
||||||
}
|
}
|
||||||
else if (df == Downlink_Format::Comm_B_Altitude_Reply_20 ||
|
else if (df == Downlink_Format::Comm_B_Altitude_Reply_20 ||
|
||||||
df == Downlink_Format::Comm_B_Identity_Reply_21) {
|
df == Downlink_Format::Comm_B_Identity_Reply_21) {
|
||||||
|
|||||||
@@ -7,13 +7,10 @@
|
|||||||
#include <functional>
|
#include <functional>
|
||||||
#include <variant>
|
#include <variant>
|
||||||
#define STRINGIFY(x) #x
|
#define STRINGIFY(x) #x
|
||||||
|
|
||||||
// 硬件接收来的 二进制消息族
|
// 硬件接收来的 二进制消息族
|
||||||
namespace SSR {
|
namespace SSR {
|
||||||
class Data_Source_Interface;
|
class Data_Source_Interface;
|
||||||
|
|
||||||
extern bool Monitor_Mode_ACS_Message_Num;
|
extern bool Monitor_Mode_ACS_Message_Num;
|
||||||
|
|
||||||
class Msg {
|
class Msg {
|
||||||
public:
|
public:
|
||||||
enum T : unsigned char {
|
enum T : unsigned char {
|
||||||
@@ -24,7 +21,6 @@ namespace SSR {
|
|||||||
HULC_Status = 0x48, // 72
|
HULC_Status = 0x48, // 72
|
||||||
UNKNOWN = 0xFF
|
UNKNOWN = 0xFF
|
||||||
};
|
};
|
||||||
|
|
||||||
enum Len {
|
enum Len {
|
||||||
AC_len = 9 + 2,
|
AC_len = 9 + 2,
|
||||||
S7_len = 9 + 7,
|
S7_len = 9 + 7,
|
||||||
@@ -32,90 +28,114 @@ namespace SSR {
|
|||||||
Radarcape_status_len = 2 + 3,
|
Radarcape_status_len = 2 + 3,
|
||||||
HULC_len = 28,
|
HULC_len = 28,
|
||||||
};
|
};
|
||||||
|
|
||||||
std::shared_ptr<Data_Source_Interface> source{};
|
std::shared_ptr<Data_Source_Interface> source{};
|
||||||
T type = UNKNOWN;
|
T type = UNKNOWN;
|
||||||
std::string packet; // 收到的原始消息
|
std::string packet; // 收到的原始消息
|
||||||
explicit Msg(const std::shared_ptr<Data_Source_Interface>& source, std::string_view packet);
|
explicit Msg(const std::shared_ptr<Data_Source_Interface>& source, std::string_view packet);
|
||||||
|
|
||||||
virtual Psc::JSON to_Json() {
|
virtual Psc::JSON to_Json() {
|
||||||
Psc::JSON ret = Psc::JSON::object();
|
Psc::JSON ret = Psc::JSON::object();
|
||||||
ret.append({"type", Psc::to_string((T)(type))});
|
ret.append({"type", Psc::to_string((T)(type))});
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual ~Msg();
|
virtual ~Msg();
|
||||||
|
|
||||||
virtual std::string to_string() {
|
virtual std::string to_string() {
|
||||||
return VAR_STR_2(type, packet);
|
return VAR_STR_2(type, packet);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Play_Back_Time_Point {
|
struct Play_Back_Time_Point {
|
||||||
|
static constexpr std::uint64_t SECS_PER_DAY = 86400ULL;
|
||||||
|
static constexpr std::uint64_t NANOSECS_PER_SEC = 1000000000ULL;
|
||||||
std::uint64_t day_num{};
|
std::uint64_t day_num{};
|
||||||
std::uint64_t day_sec{}; // 0..86399
|
std::uint64_t day_sec{};
|
||||||
|
std::uint64_t nanosec{};
|
||||||
struct HMS {
|
struct HMS {
|
||||||
std::uint32_t hour;
|
std::uint32_t hour{};
|
||||||
std::uint32_t minute;
|
std::uint32_t minute{};
|
||||||
std::uint32_t second;
|
std::uint32_t second{};
|
||||||
|
|
||||||
std::string to_string() const {
|
std::string to_string() const {
|
||||||
std::ostringstream oss;
|
std::ostringstream oss;
|
||||||
oss << std::setw(2) << std::setfill('0') << hour << ':' << std::setw(2)
|
oss << std::setfill('0')
|
||||||
<< std::setfill('0') << minute << ':' << std::setw(2)
|
<< std::setw(2) << hour << ':'
|
||||||
<< std::setfill('0') << second;
|
<< std::setw(2) << minute << ':'
|
||||||
|
<< std::setw(2) << second;
|
||||||
return oss.str();
|
return oss.str();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
HMS hms() const noexcept {
|
||||||
HMS hms() noexcept {
|
HMS result{};
|
||||||
HMS hms{};
|
result.hour = static_cast<std::uint32_t>(day_sec / 3600);
|
||||||
hms.hour = static_cast<std::uint32_t>(day_sec / 3600);
|
result.minute = static_cast<std::uint32_t>((day_sec % 3600) / 60);
|
||||||
day_sec %= 3600;
|
result.second = static_cast<std::uint32_t>(day_sec % 60);
|
||||||
hms.minute = static_cast<std::uint32_t>(day_sec / 60);
|
return result;
|
||||||
hms.second = static_cast<std::uint32_t>(day_sec % 60);
|
|
||||||
return hms;
|
|
||||||
}
|
}
|
||||||
|
std::string to_string() const {
|
||||||
std::string to_string() {
|
std::ostringstream oss;
|
||||||
return "Play_Back_Time_Point[" + Psc::to_string(day_num) + "," +
|
oss << "Play_Back_Time_Point[" << day_num << ',' << hms().to_string()
|
||||||
hms().to_string() + "]";
|
<< '.' << std::setfill('0') << std::setw(9) << nanosec << ']';
|
||||||
|
return oss.str();
|
||||||
}
|
}
|
||||||
|
|
||||||
static constexpr std::uint64_t SECS_PER_DAY = 86400ULL;
|
|
||||||
// 归一化:保证 day_sec < 86400
|
|
||||||
void normalize() noexcept {
|
void normalize() noexcept {
|
||||||
if (day_sec >= SECS_PER_DAY) {
|
std::uint64_t sec_carry = nanosec / NANOSECS_PER_SEC;
|
||||||
|
nanosec %= NANOSECS_PER_SEC;
|
||||||
day_num += day_sec / SECS_PER_DAY;
|
day_num += day_sec / SECS_PER_DAY;
|
||||||
day_sec %= SECS_PER_DAY;
|
day_sec %= SECS_PER_DAY;
|
||||||
|
day_num += sec_carry / SECS_PER_DAY;
|
||||||
|
sec_carry %= SECS_PER_DAY;
|
||||||
|
day_sec += sec_carry;
|
||||||
|
if (day_sec >= SECS_PER_DAY) {
|
||||||
|
++day_num;
|
||||||
|
day_sec -= SECS_PER_DAY;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool operator<(const Play_Back_Time_Point& other) const noexcept {
|
bool operator<(const Play_Back_Time_Point& other) const noexcept {
|
||||||
if (other == *this) return false;
|
if (day_num != other.day_num) {
|
||||||
if (day_num != other.day_num) return day_num < other.day_num;
|
return day_num < other.day_num;
|
||||||
|
}
|
||||||
|
if (day_sec != other.day_sec) {
|
||||||
return day_sec < other.day_sec;
|
return day_sec < other.day_sec;
|
||||||
}
|
}
|
||||||
|
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;
|
bool operator==(const Play_Back_Time_Point& other) const noexcept {
|
||||||
|
return day_num == other.day_num &&
|
||||||
|
day_sec == other.day_sec &&
|
||||||
|
nanosec == other.nanosec;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool operator>(const Play_Back_Time_Point& other) const noexcept {
|
bool operator>(const Play_Back_Time_Point& other) const noexcept {
|
||||||
if (other == *this) return false;
|
|
||||||
return other < *this;
|
return other < *this;
|
||||||
}
|
}
|
||||||
|
bool operator<=(const Play_Back_Time_Point& other) const noexcept {
|
||||||
std::uint64_t abs_sec() const noexcept {
|
return !(other < *this);
|
||||||
return day_num * SECS_PER_DAY + day_sec;
|
}
|
||||||
|
bool operator>=(const Play_Back_Time_Point& other) const noexcept {
|
||||||
|
return !(*this < other);
|
||||||
|
}
|
||||||
|
double abs_sec() const noexcept {
|
||||||
|
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 {
|
void add_sec(std::uint64_t sec) noexcept {
|
||||||
day_sec += sec;
|
day_num += sec / SECS_PER_DAY;
|
||||||
normalize();
|
day_sec += sec % SECS_PER_DAY;
|
||||||
|
if (day_sec >= SECS_PER_DAY) {
|
||||||
|
++day_num;
|
||||||
|
day_sec -= SECS_PER_DAY;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
void add_nanosec(std::uint64_t value) noexcept {
|
||||||
|
add_sec(value / NANOSECS_PER_SEC);
|
||||||
|
nanosec += value % NANOSECS_PER_SEC;
|
||||||
|
if (nanosec >= NANOSECS_PER_SEC) {
|
||||||
|
++day_sec;
|
||||||
|
nanosec -= NANOSECS_PER_SEC;
|
||||||
|
if (day_sec >= SECS_PER_DAY) {
|
||||||
|
++day_num;
|
||||||
|
day_sec -= SECS_PER_DAY;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
class Mode_Msg : public Msg {
|
class Mode_Msg : public Msg {
|
||||||
public:
|
public:
|
||||||
std::uint64_t day_num = 0; // 自己维护的字段
|
std::uint64_t day_num = 0; // 自己维护的字段
|
||||||
@@ -123,10 +143,8 @@ namespace SSR {
|
|||||||
std::string msg_hex;
|
std::string msg_hex;
|
||||||
std::string msg_bin;
|
std::string msg_bin;
|
||||||
char signal_level{};
|
char signal_level{};
|
||||||
|
|
||||||
explicit Mode_Msg(const std::shared_ptr<Data_Source_Interface>& source,
|
explicit Mode_Msg(const std::shared_ptr<Data_Source_Interface>& source,
|
||||||
std::string_view packet);
|
std::string_view packet);
|
||||||
|
|
||||||
Psc::JSON to_Json() override {
|
Psc::JSON to_Json() override {
|
||||||
Psc::JSON ret = Msg::to_Json();
|
Psc::JSON ret = Msg::to_Json();
|
||||||
Ret_J(msg_hex)
|
Ret_J(msg_hex)
|
||||||
@@ -135,27 +153,21 @@ namespace SSR {
|
|||||||
Ret_J(day_num)
|
Ret_J(day_num)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
~Mode_Msg() override;
|
~Mode_Msg() override;
|
||||||
|
|
||||||
Play_Back_Time_Point time() {
|
Play_Back_Time_Point time() {
|
||||||
return {day_num, mlat_timestamp.daysec};
|
return {day_num, mlat_timestamp.daysec, mlat_timestamp.nanosec};
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string to_string() override {
|
std::string to_string() override {
|
||||||
auto& time = mlat_timestamp;
|
auto& time = mlat_timestamp;
|
||||||
return VAR_STR_3(signal_level, time, msg_hex);
|
return VAR_STR_3(signal_level, time, msg_hex);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
class Mode_AC_Msg : public Mode_Msg {
|
class Mode_AC_Msg : public Mode_Msg {
|
||||||
public:
|
public:
|
||||||
explicit Mode_AC_Msg(const std::shared_ptr<Data_Source_Interface>& source,
|
explicit Mode_AC_Msg(const std::shared_ptr<Data_Source_Interface>& source,
|
||||||
std::string_view packet);
|
std::string_view packet);
|
||||||
|
|
||||||
~Mode_AC_Msg() override;
|
~Mode_AC_Msg() override;
|
||||||
};
|
};
|
||||||
|
|
||||||
// 1 + 1 + 6 + 1 + 2/7/14
|
// 1 + 1 + 6 + 1 + 2/7/14
|
||||||
// 1a + type time_stamp signal_level data
|
// 1a + type time_stamp signal_level data
|
||||||
// 用于数据发送
|
// 用于数据发送
|
||||||
@@ -163,45 +175,34 @@ namespace SSR {
|
|||||||
public:
|
public:
|
||||||
Downlink_Format df = Downlink_Format::Unknown;
|
Downlink_Format df = Downlink_Format::Unknown;
|
||||||
std::string icao;
|
std::string icao;
|
||||||
|
|
||||||
Psc::JSON to_Json() override {
|
Psc::JSON to_Json() override {
|
||||||
Psc::JSON ret = Mode_Msg::to_Json();
|
Psc::JSON ret = Mode_Msg::to_Json();
|
||||||
ret.append({"df", Psc::to_string(df)});
|
ret.append({"df", Psc::to_string(df)});
|
||||||
ret.append({"icao", icao});
|
ret.append({"icao", icao});
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 1a 31 19 b2dd1c7af671 3220
|
// 1a 31 19 b2dd1c7af671 3220
|
||||||
explicit Mode_S_Msg(const std::shared_ptr<Data_Source_Interface>& source,
|
explicit Mode_S_Msg(const std::shared_ptr<Data_Source_Interface>& source,
|
||||||
std::string_view packet);
|
std::string_view packet);
|
||||||
|
|
||||||
~Mode_S_Msg() override;
|
~Mode_S_Msg() override;
|
||||||
|
|
||||||
std::string to_string() override {
|
std::string to_string() override {
|
||||||
auto& time = mlat_timestamp;
|
auto& time = mlat_timestamp;
|
||||||
return VAR_STR_5(df, icao, signal_level, time, msg_hex);
|
return VAR_STR_5(df, icao, signal_level, time, msg_hex);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
class NoneCopyLock {
|
class NoneCopyLock {
|
||||||
public:
|
public:
|
||||||
std::mutex mtx; // 互斥量,不能被复制
|
std::mutex mtx; // 互斥量,不能被复制
|
||||||
NoneCopyLock() = default;
|
NoneCopyLock() = default;
|
||||||
|
|
||||||
NoneCopyLock(const NoneCopyLock& other) = delete;
|
NoneCopyLock(const NoneCopyLock& other) = delete;
|
||||||
|
|
||||||
NoneCopyLock& operator=(const NoneCopyLock& other) {
|
NoneCopyLock& operator=(const NoneCopyLock& other) {
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Position_3D : CPR::Position {
|
struct Position_3D : CPR::Position {
|
||||||
CPR::D alt;
|
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) {
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// 这个返回值的意义在于 解码失败后 返回值能反应出是 位置解码失败
|
// 这个返回值的意义在于 解码失败后 返回值能反应出是 位置解码失败
|
||||||
// 还是奇偶报文解码位置失败
|
// 还是奇偶报文解码位置失败
|
||||||
class Pos_Ret {
|
class Pos_Ret {
|
||||||
@@ -210,35 +211,25 @@ namespace SSR {
|
|||||||
std::shared_ptr<Mode_S_Msg> that;
|
std::shared_ptr<Mode_S_Msg> that;
|
||||||
using Extra = std::variant<std::shared_ptr<Mode_S_Msg>, CPR::Position>;
|
using Extra = std::variant<std::shared_ptr<Mode_S_Msg>, CPR::Position>;
|
||||||
Extra extra;
|
Extra extra;
|
||||||
|
|
||||||
Pos_Ret(CPR::Position p, std::shared_ptr<Mode_S_Msg> t,
|
Pos_Ret(CPR::Position p, std::shared_ptr<Mode_S_Msg> t,
|
||||||
std::shared_ptr<Mode_S_Msg> o) : pos(p), that(std::move(t)), extra(std::move(o)) {
|
std::shared_ptr<Mode_S_Msg> o) : pos(p), that(std::move(t)), extra(std::move(o)) {}
|
||||||
}
|
|
||||||
|
|
||||||
Pos_Ret(CPR::Position p, std::shared_ptr<Mode_S_Msg> t, CPR::Position old) : pos(p), that(std::move(t)),
|
Pos_Ret(CPR::Position p, std::shared_ptr<Mode_S_Msg> t, CPR::Position old) : pos(p), that(std::move(t)),
|
||||||
extra(old) {
|
extra(old) {}
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// 展示出最详细的信息
|
// 展示出最详细的信息
|
||||||
struct Position_Info : Position_3D {
|
struct Position_Info : Position_3D {
|
||||||
std::int64_t sys_day_ns{};
|
std::int64_t sys_day_ns{};
|
||||||
std::uint64_t utc{};
|
std::uint64_t utc{};
|
||||||
std::uint64_t odd_even_diff_ns{};
|
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) {
|
|
||||||
}
|
|
||||||
|
|
||||||
Pos_Ret::Extra extra;
|
Pos_Ret::Extra extra;
|
||||||
std::shared_ptr<Mode_S_Msg> that;
|
std::shared_ptr<Mode_S_Msg> that;
|
||||||
|
|
||||||
Position_Info(const Pos_Ret& r, CPR::D alt) : Position_3D(r.pos.lat, r.pos.lon, alt), that(r.that),
|
Position_Info(const Pos_Ret& r, CPR::D alt) : Position_3D(r.pos.lat, r.pos.lon, alt), that(r.that),
|
||||||
extra(r.extra) {
|
extra(r.extra) {
|
||||||
using namespace std::chrono;
|
using namespace std::chrono;
|
||||||
utc = static_cast<std::uint64_t>(
|
utc = static_cast<std::uint64_t>(
|
||||||
duration_cast<seconds>(system_clock::now().time_since_epoch()).count());
|
duration_cast<seconds>(system_clock::now().time_since_epoch()).count());
|
||||||
}
|
}
|
||||||
|
|
||||||
Psc::JSON to_json() {
|
Psc::JSON to_json() {
|
||||||
Psc::JSON ret = Psc::JSON::object();
|
Psc::JSON ret = Psc::JSON::object();
|
||||||
Ret_J(lat)
|
Ret_J(lat)
|
||||||
@@ -265,43 +256,34 @@ namespace SSR {
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
struct POS_List {
|
struct POS_List {
|
||||||
NoneCopyLock mtx;
|
NoneCopyLock mtx;
|
||||||
size_t max_size;
|
size_t max_size;
|
||||||
|
POS_List() {}
|
||||||
POS_List() {
|
|
||||||
}
|
|
||||||
|
|
||||||
void reset() {
|
void reset() {
|
||||||
std::lock_guard g(mtx.mtx);
|
std::lock_guard g(mtx.mtx);
|
||||||
seq = 0;
|
seq = 0;
|
||||||
head = 0;
|
head = 0;
|
||||||
count = 0;
|
count = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void init(size_t _max_size) {
|
void init(size_t _max_size) {
|
||||||
this->max_size = _max_size;
|
this->max_size = _max_size;
|
||||||
buf.resize(_max_size);
|
buf.resize(_max_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t size() {
|
size_t size() {
|
||||||
std::lock_guard g(mtx.mtx);
|
std::lock_guard g(mtx.mtx);
|
||||||
return count;
|
return count;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool empty() {
|
bool empty() {
|
||||||
std::lock_guard g(mtx.mtx);
|
std::lock_guard g(mtx.mtx);
|
||||||
return count == 0;
|
return count == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::optional<Position_Info> last() {
|
std::optional<Position_Info> last() {
|
||||||
std::lock_guard g(mtx.mtx);
|
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;
|
std::size_t idx = (head + max_size - 1) % max_size;
|
||||||
return buf[idx];
|
return buf[idx];
|
||||||
}
|
}
|
||||||
|
|
||||||
void push(Position_Info new_position) {
|
void push(Position_Info new_position) {
|
||||||
std::lock_guard g(mtx.mtx);
|
std::lock_guard g(mtx.mtx);
|
||||||
buf[head] = std::move(new_position);
|
buf[head] = std::move(new_position);
|
||||||
@@ -309,11 +291,8 @@ namespace SSR {
|
|||||||
if (count < max_size) ++count;
|
if (count < max_size) ++count;
|
||||||
++seq;
|
++seq;
|
||||||
}
|
}
|
||||||
|
|
||||||
Psc::JSON get_last_array_json(std::uint64_t last_seq);
|
Psc::JSON get_last_array_json(std::uint64_t last_seq);
|
||||||
|
|
||||||
std::string to_string();
|
std::string to_string();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
std::uint64_t seq = 0;
|
std::uint64_t seq = 0;
|
||||||
std::uint64_t head = 0;
|
std::uint64_t head = 0;
|
||||||
|
|||||||
+1
-1
@@ -42,7 +42,7 @@ public:
|
|||||||
virtual std::shared_ptr<Aircraft_Info> get_aircraft(std::string_view icao) = 0;
|
virtual std::shared_ptr<Aircraft_Info> get_aircraft(std::string_view icao) = 0;
|
||||||
virtual std::shared_ptr<Aircraft_Info> create_aircraft(std::string_view icao) = 0;
|
virtual std::shared_ptr<Aircraft_Info> create_aircraft(std::string_view icao) = 0;
|
||||||
};
|
};
|
||||||
bool parse_mode_s_bin(Data_Source_Interface* src, P_S mode_s_msg, std::optional<CPR::Position> base_station_pos, CPR::D max_speed_m_s, CPR::D air_pos_time_out, CPR::D surface_pos_time_out);
|
bool parse_mode_s_bin(Data_Source_Interface* src, P_S mode_s_msg, std::optional<CPR::Position> base_station_pos, SSR::ADS_B_T::Constraint air_constraint, SSR::ADS_B_T::Constraint surface_constraint);
|
||||||
}
|
}
|
||||||
#include "export.hpp"
|
#include "export.hpp"
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
+98
-120
@@ -19,137 +19,115 @@ void init_that(Aircraft_Info& info, std::string_view field_name, T& t,
|
|||||||
field_name, {}, &t, msg);
|
field_name, {}, &t, msg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
inline CPR_CB cpr_cb = [](CPR_Type t, CPR_Ret_Type err_type, std::string_view log, P_S msg) {
|
||||||
|
if (mode_s_logger) mode_s_logger->debug("CPR/" + Psc::to_string(t) + "/" + Psc::to_string(err_type), {}, log);
|
||||||
|
};
|
||||||
namespace ADS_B_T {
|
namespace ADS_B_T {
|
||||||
|
// cpr回调
|
||||||
template <typename That>
|
template <typename That>
|
||||||
RET<Pos_Ret> CPR_MSG<That>::parse_message(const std::shared_ptr<Mode_S_Msg>& msg, double time_s, CPR::D max_speed_m_s, CPR::D max_time_s, const SSR::CPR_CB& cb) {
|
RET<Pos_Ret> CPR_MSG<That>::local_parse_message(CPR::Position old_pos, P_S msg, double time_s, Constraint constraint) {
|
||||||
const std::string& msg_bin = msg->msg_bin;
|
constraint.cb(SSR::CPR_Type::Local_pos_parse, SSR::CPR_Ret_Type::Base, current_state(msg), msg);
|
||||||
std::string msg_hex = bin2hex(msg_bin);
|
auto diff_time = std::abs(time_s - last_parse_pos_time);
|
||||||
std::string icao = msg_hex.substr(2, 6);
|
if (constraint.time_space_filter && diff_time > constraint.max_time_s) {
|
||||||
Info *that, *other;
|
constraint.cb(SSR::CPR_Type::Local_pos_parse, SSR::CPR_Ret_Type::Time_Space_Too_Long, current_state(msg), msg);
|
||||||
auto f = get_cpr_format();
|
|
||||||
auto before_state = current_state();
|
|
||||||
if (f == CPR::Frame::Even) {
|
|
||||||
// std::cout << "even\n";
|
|
||||||
that = &even_msg;
|
|
||||||
other = &odd_msg;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
// std::cout << "odd\n";
|
|
||||||
that = &odd_msg;
|
|
||||||
other = &even_msg;
|
|
||||||
}
|
|
||||||
that->msg = msg;
|
|
||||||
that->time = time_s;
|
|
||||||
Log_Type log_type({}, {{"ICAO", icao}, {"Frame_type", Psc::to_string(f)}});
|
|
||||||
std::optional<CPR::Position>& old_pos = pos;
|
|
||||||
auto src = msg->source;
|
|
||||||
if (old_pos.has_value()) {
|
|
||||||
auto diff_time = std::abs(that->time - last_parse_pos_time);
|
|
||||||
if (diff_time < max_time_s) {
|
|
||||||
auto new_pos = locale_parse(that->msg->msg_bin, old_pos->lat, old_pos->lon, that->time, last_parse_pos_time);
|
|
||||||
bool locale_parse_ok = new_pos.has_value();
|
|
||||||
if (locale_parse_ok) {
|
|
||||||
auto distance_m = CPR::haversine(old_pos.value(), new_pos.value());
|
|
||||||
auto used_time_s = time_s - last_parse_pos_time;
|
|
||||||
auto max_distance = used_time_s * max_speed_m_s;
|
|
||||||
if (distance_m < max_distance) {
|
|
||||||
set_pos(new_pos, time_s);
|
|
||||||
cb(SSR::CPR_Error_Type::Normal,
|
|
||||||
get_cpr_log("本地位置解码", icao, msg_hex, f, before_state,
|
|
||||||
current_state()),
|
|
||||||
msg);
|
|
||||||
// 解码成功返回
|
|
||||||
if (!new_pos.has_value()) {
|
|
||||||
return std::nullopt;
|
return std::nullopt;
|
||||||
}
|
}
|
||||||
set_pos(new_pos, time_s);
|
auto new_pos = locale_parse(msg->msg_bin, old_pos.lat, old_pos.lon, time_s, last_parse_pos_time);
|
||||||
return Pos_Ret(new_pos.value(), that->msg, old_pos.value());
|
if (!new_pos.has_value()) {
|
||||||
|
constraint.cb(SSR::CPR_Type::Local_pos_parse, SSR::CPR_Ret_Type::Inter_Error, current_state(msg), msg);
|
||||||
|
return std::nullopt;
|
||||||
|
}
|
||||||
|
auto distance_m = CPR::haversine(old_pos, new_pos.value());
|
||||||
|
auto used_time_s = time_s - last_parse_pos_time;
|
||||||
|
auto max_distance = used_time_s * constraint.max_speed_m_s;
|
||||||
|
if (constraint.speed_filter && distance_m > max_distance) {
|
||||||
|
auto var = VAR_STR_6(distance_m, time_s, last_parse_pos_time, used_time_s, constraint.max_speed_m_s, max_distance);
|
||||||
|
constraint.cb(SSR::CPR_Type::Local_pos_parse, SSR::CPR_Ret_Type::Speed_Error, "本地解码 速度异常:" + var + current_state(msg), msg);
|
||||||
|
return std::nullopt;
|
||||||
|
}
|
||||||
|
constraint.cb(SSR::CPR_Type::Local_pos_parse, SSR::CPR_Ret_Type::Parse_OK, current_state(msg), msg);
|
||||||
|
return Pos_Ret(new_pos.value(), msg, old_pos);
|
||||||
|
}
|
||||||
|
template <typename That>
|
||||||
|
std::string CPR_MSG<That>::current_state(P_S msg) {
|
||||||
|
auto src = msg->source;
|
||||||
|
return std::format(
|
||||||
|
"{{\n"
|
||||||
|
" data_source:{}"
|
||||||
|
" cpr_format:{}"
|
||||||
|
" msg_hex:{}"
|
||||||
|
" pos:{}\n"
|
||||||
|
" odd_msg: {}\n"
|
||||||
|
" even_msg: {}\n"
|
||||||
|
" last_parse_pos_time: {}\n"
|
||||||
|
"}}\n",
|
||||||
|
src->get_key(),
|
||||||
|
msg->msg_hex, Psc::to_string(get_cpr_format()),
|
||||||
|
pos.has_value() ? pos->to_string() : "null",
|
||||||
|
odd_msg.to_string(),
|
||||||
|
even_msg.to_string(),
|
||||||
|
Psc::to_string(last_parse_pos_time)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
template <typename That>
|
||||||
|
RET<Pos_Ret> CPR_MSG<That>::global_parse_message(P_S msg, double time_s, P_S other_msg, double other_time_s, Constraint constraint) {
|
||||||
|
constraint.cb(SSR::CPR_Type::Global_pos_parse, SSR::CPR_Ret_Type::Base, current_state(msg), msg);
|
||||||
|
auto diff_time = std::abs(time_s - other_time_s);
|
||||||
|
if (constraint.time_space_filter && diff_time > constraint.max_time_s) {
|
||||||
|
constraint.cb(SSR::CPR_Type::Global_pos_parse, SSR::CPR_Ret_Type::Time_Space_Too_Long, current_state(msg), msg);
|
||||||
|
return std::nullopt;
|
||||||
|
}
|
||||||
|
RET<CPR::Position> new_pos = global_parse(msg->msg_bin, other_msg->msg_bin, time_s, other_time_s);
|
||||||
|
if (!new_pos.has_value()) {
|
||||||
|
constraint.cb(SSR::CPR_Type::Global_pos_parse, SSR::CPR_Ret_Type::Inter_Error, current_state(msg), msg);
|
||||||
|
return std::nullopt;
|
||||||
|
}
|
||||||
|
if (constraint.speed_filter && pos.has_value()) {
|
||||||
|
auto distance_m = CPR::haversine(pos.value(), new_pos.value());
|
||||||
|
auto used_time_s = time_s - other_time_s;
|
||||||
|
auto max_distance = used_time_s * constraint.max_speed_m_s;
|
||||||
|
if (distance_m > max_distance) {
|
||||||
|
auto var = VAR_STR_6(distance_m, time_s, last_parse_pos_time, used_time_s, constraint.max_speed_m_s, max_distance);
|
||||||
|
constraint.cb(SSR::CPR_Type::Global_pos_parse, SSR::CPR_Ret_Type::Speed_Error, "全局解码 速度异常:" + var + current_state(msg), msg);
|
||||||
|
return std::nullopt;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
constraint.cb(SSR::CPR_Type::Global_pos_parse, SSR::CPR_Ret_Type::Parse_OK, current_state(msg), msg);
|
||||||
|
return Pos_Ret(new_pos.value(), msg, other_msg);
|
||||||
|
}
|
||||||
|
template <typename That>
|
||||||
|
RET<Pos_Ret> CPR_MSG<That>::parse_message(P_S msg, double time_s, Constraint constraint) {
|
||||||
|
auto f = get_cpr_format();
|
||||||
|
Info* that = f == CPR::Frame::Even ? &even_msg : &odd_msg;
|
||||||
|
Info* other = f == CPR::Frame::Even ? &odd_msg : &even_msg;
|
||||||
|
if (!pos.has_value()) {
|
||||||
|
constraint.cb(SSR::CPR_Type::Local_pos_parse, SSR::CPR_Ret_Type::Lack_Old_Pos, "缺旧位置" + current_state(msg), msg);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// 尝试全局解码
|
RET<Pos_Ret> ret = local_parse_message(pos.value(), msg, time_s, constraint);
|
||||||
cb(SSR::CPR_Error_Type::Local_Speed_Error,
|
if (ret.has_value()) {
|
||||||
get_cpr_log("本地位置解码速度异常舍弃, 尝试全局解码", icao,
|
that->msg = msg;
|
||||||
msg_hex, f, before_state, current_state()) +
|
that->time = time_s;
|
||||||
" " +
|
pos = ret.value().pos;
|
||||||
VAR_STR_4(distance_m, max_distance, used_time_s,
|
|
||||||
max_speed_m_s),
|
|
||||||
msg);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
cb(SSR::CPR_Error_Type::Unknow_Error,
|
|
||||||
get_cpr_log("未知错误", icao, msg_hex, f, before_state,
|
|
||||||
current_state()),
|
|
||||||
msg);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
cb(SSR::CPR_Error_Type::Local_Time_Space_Too_Long,
|
|
||||||
get_cpr_log("本地位置解码时间异常, 尝试全局解码 超时:" + VAR_STR_2(diff_time, max_time_s), icao, msg_hex, f,
|
|
||||||
before_state, current_state()),
|
|
||||||
msg);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// 本地解码失败走到这里 尝试全局解码
|
|
||||||
if (other->msg) {
|
|
||||||
auto diff_time = std::abs(that->time - other->time);
|
|
||||||
if (diff_time < max_time_s) {
|
|
||||||
RET<CPR::Position> new_pos = global_parse(
|
|
||||||
that->msg->msg_bin, other->msg->msg_bin, that->time, other->time);
|
|
||||||
if (new_pos.has_value()) {
|
|
||||||
if (old_pos.has_value()) {
|
|
||||||
auto distance = CPR::haversine(old_pos.value(), new_pos.value());
|
|
||||||
auto used_time_s = time_s - other->time;
|
|
||||||
auto max_distance = used_time_s * max_speed_m_s;
|
|
||||||
if (distance < max_distance) {
|
|
||||||
cb(SSR::CPR_Error_Type::Normal,
|
|
||||||
get_cpr_log("全局位置解码", icao, msg_hex, f, before_state,
|
|
||||||
current_state()),
|
|
||||||
msg);
|
|
||||||
last_parse_pos_time = time_s;
|
last_parse_pos_time = time_s;
|
||||||
set_pos(new_pos, time_s);
|
return ret;
|
||||||
return Pos_Ret(new_pos.value(), that->msg, other->msg);
|
}
|
||||||
|
}
|
||||||
|
if (other->msg == nullptr) {
|
||||||
|
that->msg = msg;
|
||||||
|
that->time = time_s;
|
||||||
|
constraint.cb(SSR::CPR_Type::Global_pos_parse, SSR::CPR_Ret_Type::Lack_Other_Msg, "缺另一条消息" + current_state(msg), msg);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// 视为失败
|
RET<Pos_Ret> ret = global_parse_message(msg, time_s, other->msg, other->time, constraint);
|
||||||
cb(SSR::CPR_Error_Type::Global_Speed_Error,
|
if (ret.has_value()) {
|
||||||
get_cpr_log("全局位置解码速度异常,直接舍弃", icao, msg_hex, f,
|
that->msg = msg;
|
||||||
before_state, current_state()) +
|
that->time = time_s;
|
||||||
" " +
|
pos = ret.value().pos;
|
||||||
VAR_STR_4(distance, max_distance, used_time_s,
|
last_parse_pos_time = time_s;
|
||||||
max_speed_m_s),
|
return ret;
|
||||||
msg);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
|
||||||
// 第一次全局解码的位置,直接视为成功
|
|
||||||
set_pos(new_pos, time_s);
|
|
||||||
return Pos_Ret(new_pos.value(), that->msg, other->msg);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
cb(SSR::CPR_Error_Type::Unknow_Error,
|
|
||||||
get_cpr_log("未知错误", icao, msg_hex, f, before_state,
|
|
||||||
current_state()) +
|
|
||||||
" ",
|
|
||||||
msg);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
cb(SSR::CPR_Error_Type::Global_Time_Space_Too_Long,
|
|
||||||
get_cpr_log("本地位置解码时间异常, 尝试全局解码 超时:" + VAR_STR_2(diff_time, max_time_s), icao, msg_hex, f,
|
|
||||||
before_state, current_state()),
|
|
||||||
msg);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
// 消息不足 放弃解码
|
|
||||||
cb(SSR::CPR_Error_Type::Msg_Lack,
|
|
||||||
get_cpr_log(" 消息不足 放弃解码", icao, msg_hex, f, before_state,
|
|
||||||
current_state()),
|
|
||||||
msg);
|
|
||||||
}
|
|
||||||
// 两种解码尝试都失败 尝试这里
|
|
||||||
last_parse_pos_time = 0;
|
last_parse_pos_time = 0;
|
||||||
pos = std::nullopt;
|
pos = std::nullopt;
|
||||||
other->reset();
|
other->reset();
|
||||||
|
|||||||
+15
-10
@@ -13,16 +13,21 @@ enum class Parse_Call_Back_Type {
|
|||||||
ICAO_Error,
|
ICAO_Error,
|
||||||
Unknown_tc
|
Unknown_tc
|
||||||
};
|
};
|
||||||
enum class CPR_Error_Type {
|
enum class CPR_Type {
|
||||||
Normal,
|
Local_pos_parse,
|
||||||
Msg_Lack,
|
Global_pos_parse
|
||||||
Local_Speed_Error,
|
};
|
||||||
Global_Speed_Error,
|
enum class CPR_Ret_Type {
|
||||||
Local_Time_Space_Too_Long,
|
// 百分比情况
|
||||||
Global_Time_Space_Too_Long,
|
Speed_Error,
|
||||||
Unknow_Error,
|
Parse_OK,
|
||||||
|
Inter_Error,
|
||||||
|
Time_Space_Too_Long,
|
||||||
|
// 正常情况
|
||||||
|
Lack_Other_Msg, // 缺乏条件,不参与计数
|
||||||
|
Lack_Old_Pos, // 缺乏条件,不参与计数
|
||||||
|
Base // 总计数
|
||||||
};
|
};
|
||||||
using P_S = const std::shared_ptr<Mode_S_Msg>&;
|
using P_S = const std::shared_ptr<Mode_S_Msg>&;
|
||||||
using CPR_CB =
|
using CPR_CB = std::function<void(CPR_Type cet, CPR_Ret_Type err_type, std::string_view log, P_S msg)>;
|
||||||
std::function<void(CPR_Error_Type cet, std::string_view log, P_S msg)>;
|
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user