内存优化
This commit is contained in:
@@ -84,6 +84,7 @@ struct Constraint {
|
||||
double base_station_height_meters = 0.0;
|
||||
bool radio_range_filter = false;
|
||||
double radio_range_factor = 1.2;
|
||||
bool report_routine_details = true;
|
||||
mutable bool fail_clear_pos = false; // 如果启用那么解码位置失败,将会清空状态
|
||||
};
|
||||
template <typename That>
|
||||
|
||||
+45
-43
@@ -15,7 +15,8 @@ using namespace Psc;
|
||||
std::lock_guard mtx_##Field(info.Field.mtx.mtx); \
|
||||
init_that(info, #Field, info.Field, mode_s_msg); \
|
||||
auto& t = info.Field.value.value(); \
|
||||
msg_json.append_list(t.toJson().children);
|
||||
if (collect_json) \
|
||||
msg_json.append_list(t.toJson().children);
|
||||
#define checkLength(len) \
|
||||
if (msg_hex.size() != len) { \
|
||||
parse_call_back(Parse_Call_Back_Type::Length_Error, nullptr, to_string(df), {}, nullptr, mode_s_msg); \
|
||||
@@ -84,7 +85,7 @@ 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,
|
||||
bool parse_absb_17(SSR::Data_Source_Interface* src, SSR::P_S mode_s_msg, JSON& msg_json, bool collect_json,
|
||||
std::optional<Position_3D> base_station_pos, const SSR::ADS_B_T::Constraint& air_constraint,
|
||||
const SSR::ADS_B_T::Constraint& surface_constraint) {
|
||||
std::shared_ptr<Aircraft_Info> a = src->get_aircraft(mode_s_msg->icao);
|
||||
@@ -111,13 +112,16 @@ bool parse_absb_17(SSR::Data_Source_Interface* src, SSR::P_S mode_s_msg, JSON& m
|
||||
Position_Info p(tp.value(), info.altitude_meter().value_or(0));
|
||||
list.push(p);
|
||||
info.mlat = false;
|
||||
parse_pos_call_back(&info, mode_s_msg, true);
|
||||
msg_json.append_list(t.toJson().children);
|
||||
if (parse_pos_call_back)
|
||||
parse_pos_call_back(&info, mode_s_msg, true);
|
||||
if (collect_json)
|
||||
msg_json.append_list(t.toJson().children);
|
||||
}
|
||||
else if (constraint.fail_clear_pos) {
|
||||
list.reset();
|
||||
}
|
||||
msg_json.append(Psc::JSON("地表位置消息", get_current_time_as_string()));
|
||||
if (collect_json)
|
||||
msg_json.append(Psc::JSON("地表位置消息", get_current_time_as_string()));
|
||||
}
|
||||
else if ((tc >= 9 && tc <= 18) || (tc >= 20 && tc <= 22)) {
|
||||
Parse_no_json(t, BDS05_airborne_position) info.refresh_pos(true);
|
||||
@@ -137,13 +141,16 @@ bool parse_absb_17(SSR::Data_Source_Interface* src, SSR::P_S mode_s_msg, JSON& m
|
||||
Position_Info p(tp.value(), alt);
|
||||
list.push(p);
|
||||
info.mlat = false;
|
||||
parse_pos_call_back(&info, mode_s_msg, false);
|
||||
msg_json.append_list(t.toJson().children);
|
||||
if (parse_pos_call_back)
|
||||
parse_pos_call_back(&info, mode_s_msg, false);
|
||||
if (collect_json)
|
||||
msg_json.append_list(t.toJson().children);
|
||||
}
|
||||
else if (constraint.fail_clear_pos) {
|
||||
list.reset();
|
||||
}
|
||||
msg_json.append(Psc::JSON("空中位置消息", get_current_time_as_string()));
|
||||
if (collect_json)
|
||||
msg_json.append(Psc::JSON("空中位置消息", get_current_time_as_string()));
|
||||
}
|
||||
else if (tc == 19) {
|
||||
// 速度
|
||||
@@ -207,7 +214,8 @@ bool parse_absb_17(SSR::Data_Source_Interface* src, SSR::P_S mode_s_msg, JSON& m
|
||||
}
|
||||
return true;
|
||||
}
|
||||
bool parse_Message_commb(SSR::Data_Source_Interface* src, std::string_view BDS, SSR::P_S mode_s_msg, JSON& msg_json) {
|
||||
bool parse_Message_commb(SSR::Data_Source_Interface* src, std::string_view BDS, SSR::P_S mode_s_msg, JSON& msg_json,
|
||||
bool collect_json) {
|
||||
std::string& msg = mode_s_msg->msg_bin;
|
||||
Downlink_Format& df = mode_s_msg->df;
|
||||
bool new_create;
|
||||
@@ -233,7 +241,8 @@ bool parse_Message_commb(SSR::Data_Source_Interface* src, std::string_view BDS,
|
||||
}
|
||||
else if (BDS == "30") {
|
||||
Parse(t, BDS30) ACAS_SubType st = t.parse_sum(msg);
|
||||
msg_json.append({"ACAS_SubType st", to_string(st)});
|
||||
if (collect_json)
|
||||
msg_json.append({"ACAS_SubType st", to_string(st)});
|
||||
switch (st) {
|
||||
case ACAS_SubType::NO_RA:
|
||||
break;
|
||||
@@ -246,7 +255,8 @@ bool parse_Message_commb(SSR::Data_Source_Interface* src, std::string_view BDS,
|
||||
}
|
||||
}
|
||||
Threat_Type_Indicator ti = t.get_threat_Type_Indicator();
|
||||
msg_json.append({"Threat_Type_Indicator", to_string(ti)});
|
||||
if (collect_json)
|
||||
msg_json.append({"Threat_Type_Indicator", to_string(ti)});
|
||||
switch (ti) {
|
||||
case Threat_Type_Indicator::No_Identity_Data:
|
||||
break;
|
||||
@@ -283,6 +293,7 @@ bool parse_mode_s_bin(Data_Source_Interface* src, P_S mode_s_msg, std::optional<
|
||||
auto& df = mode_s_msg->df;
|
||||
auto& icao = mode_s_msg->icao;
|
||||
JSON msg_json = JSON::object();
|
||||
const bool collect_json = static_cast<bool>(parse_ok_json);
|
||||
bool ok = true;
|
||||
if (df == Downlink_Format::Extended_Squitter_17) {
|
||||
checkLength(28) if (!with_PI::check_crc(msg, icao)) {
|
||||
@@ -291,7 +302,8 @@ bool parse_mode_s_bin(Data_Source_Interface* src, P_S mode_s_msg, std::optional<
|
||||
mode_s_msg);
|
||||
return false;
|
||||
}
|
||||
ok = parse_absb_17(src, mode_s_msg, msg_json, base_station_pos, air_constraint, surface_constraint);
|
||||
ok = parse_absb_17(src, mode_s_msg, msg_json, collect_json, base_station_pos, air_constraint,
|
||||
surface_constraint);
|
||||
}
|
||||
else if (df == Downlink_Format::Comm_B_Altitude_Reply_20 || df == Downlink_Format::Comm_B_Identity_Reply_21) {
|
||||
checkLength(28) if (!src->get_aircraft(icao)) {
|
||||
@@ -301,7 +313,8 @@ bool parse_mode_s_bin(Data_Source_Interface* src, P_S mode_s_msg, std::optional<
|
||||
}
|
||||
std::vector<std::string> bds_list = infer2(msg, true);
|
||||
if (bds_list.empty()) {
|
||||
msg_json.append({"bds", "bds_empty"});
|
||||
if (collect_json)
|
||||
msg_json.append({"bds", "bds_empty"});
|
||||
std::string bds_list_str;
|
||||
for (auto& bds : bds_list) {
|
||||
bds_list_str += "_" + bds;
|
||||
@@ -322,12 +335,13 @@ bool parse_mode_s_bin(Data_Source_Interface* src, P_S mode_s_msg, std::optional<
|
||||
}
|
||||
std::string BDS = bds_list[0];
|
||||
if (!with_AP::check_crc(msg, icao, BDS)) {
|
||||
msg_json.append({"crc", "invalid crc"});
|
||||
if (collect_json)
|
||||
msg_json.append({"crc", "invalid crc"});
|
||||
if (parse_call_back)
|
||||
parse_call_back(Parse_Call_Back_Type::CRC_Error, nullptr, "commb_crc", {}, nullptr, mode_s_msg);
|
||||
return false;
|
||||
}
|
||||
ok = parse_Message_commb(src, BDS, mode_s_msg, msg_json);
|
||||
ok = parse_Message_commb(src, BDS, mode_s_msg, msg_json, collect_json);
|
||||
}
|
||||
else if (df == Downlink_Format::Surveillance_Altitude_Reply_4 ||
|
||||
df == Downlink_Format::Surveillance_Identity_Reply_5) {
|
||||
@@ -421,35 +435,16 @@ bool parse_mode_s_bin(Data_Source_Interface* src, P_S mode_s_msg, std::optional<
|
||||
if (a) {
|
||||
++a->times;
|
||||
}
|
||||
parse_ok_json(a.get(), mode_s_msg, msg_json);
|
||||
if (parse_ok_json)
|
||||
parse_ok_json(a.get(), mode_s_msg, std::move(msg_json));
|
||||
return ok;
|
||||
}
|
||||
bool Monitor_Mode_ACS_Message_Num = false;
|
||||
struct Frequency_State {
|
||||
std::atomic_int64_t cur_num{};
|
||||
};
|
||||
Msg::Msg(const std::shared_ptr<Data_Source_Interface>& source, std::string_view packet) :
|
||||
source(source), packet(packet) {
|
||||
type = static_cast<T>(packet[1]);
|
||||
static Frequency_Limit_Multi_T<Frequency_State> fl;
|
||||
auto t = source->get_key() + "_" + Psc::to_string(type);
|
||||
auto state = fl.get_state(t);
|
||||
if (state->cur_num > 100) {
|
||||
if (fl.test_ex(t)) {
|
||||
std::cerr << t << " 构造 Msg msg_num " << ++state->cur_num << std::endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
Msg::~Msg() {
|
||||
auto t = source->get_key() + "_" + Psc::to_string(type);
|
||||
static Frequency_Limit_Multi_T<Frequency_State> fl;
|
||||
auto state = fl.get_state(t);
|
||||
if (state->cur_num > 100) {
|
||||
if (fl.test_ex(t)) {
|
||||
std::cerr << t << " 析构 Msg msg_num " << --state->cur_num << std::endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
Msg::~Msg() = default;
|
||||
struct Live_Report {
|
||||
explicit Live_Report(std::string_view name) : name(name) {
|
||||
}
|
||||
@@ -489,12 +484,19 @@ Live_Report plane("plane");
|
||||
// 1 + 1 + 6 + 1 + 2/7/14
|
||||
// 1a + type time_stamp signal_level data
|
||||
Mode_Msg::Mode_Msg(const std::shared_ptr<Data_Source_Interface>& source, std::string_view packet) :
|
||||
Msg(source, packet) {
|
||||
mlat_timestamp = MLAT_timestamp(packet.substr(2, 6));
|
||||
Msg(source, packet), mlat_timestamp(packet.substr(2, 6)) {
|
||||
signal_level = packet[8];
|
||||
std::string memory(packet.substr(9));
|
||||
msg_hex = mem2hex(memory);
|
||||
msg_bin = hex2bin(msg_hex);
|
||||
const auto memory = packet.substr(9);
|
||||
constexpr char hex[] = "0123456789ABCDEF";
|
||||
msg_hex.resize(memory.size() * 2);
|
||||
msg_bin.resize(memory.size() * 8);
|
||||
for (std::size_t index = 0; index < memory.size(); ++index) {
|
||||
const auto byte = static_cast<unsigned char>(memory[index]);
|
||||
msg_hex[index * 2] = hex[byte >> 4];
|
||||
msg_hex[index * 2 + 1] = hex[byte & 0x0f];
|
||||
for (std::size_t bit = 0; bit < 8; ++bit)
|
||||
msg_bin[index * 8 + bit] = byte & (0x80 >> bit) ? '1' : '0';
|
||||
}
|
||||
if (mlat_timestamp.daysec == 0 && mlat_timestamp.nanosec == 0) {
|
||||
std::time_t tp = std::time(nullptr);
|
||||
mlat_timestamp.daysec = tp % (3600 * 24);
|
||||
@@ -537,7 +539,7 @@ Mode_S_Msg::Mode_S_Msg(const std::shared_ptr<Data_Source_Interface>& source, std
|
||||
Psc::fail_fast();
|
||||
}
|
||||
}
|
||||
df = decode_df(hex2bin(msg_hex.substr(0, 2)));
|
||||
df = decode_df(msg_bin);
|
||||
icao = SSR::decode_icao(msg_bin);
|
||||
if (Monitor_Mode_ACS_Message_Num) {
|
||||
s_mode.add();
|
||||
|
||||
@@ -228,9 +228,6 @@ std::optional<Position> airborne_position(std::string_view msg0, std::string_vie
|
||||
auto poses = CPR::global_decode(YZ0, YZ1, XZ0, XZ1, 17, 360.0);
|
||||
if (!poses.has_value()) return std::nullopt;
|
||||
auto [pos0, pos1] = poses.value();
|
||||
std::string info = pos0.to_string() + " @@@@ " + pos1.to_string();
|
||||
// std::cout << info << std::endl;
|
||||
mode_s_logger->debug("CPR_global_decode", {}, info);
|
||||
return (t0 > t1) ? pos0 : pos1;
|
||||
}
|
||||
std::optional<Position> airborne_position_with_ref(std::string_view msg_bin, double lat_ref, double lon_ref, Time t, Time t_ref) {
|
||||
|
||||
@@ -227,13 +227,13 @@ struct POS_List {
|
||||
POS_List() = default;
|
||||
void reset() {
|
||||
std::lock_guard g(mtx.mtx);
|
||||
buf.clear();
|
||||
seq = 0;
|
||||
head = 0;
|
||||
count = 0;
|
||||
}
|
||||
void init(size_t _max_size) {
|
||||
this->max_size = _max_size;
|
||||
buf.resize(_max_size);
|
||||
}
|
||||
size_t size() {
|
||||
std::lock_guard g(mtx.mtx);
|
||||
@@ -257,10 +257,19 @@ struct POS_List {
|
||||
std::optional<std::pair<Position_Info, Position_Info>> last_two();
|
||||
void push(Position_Info new_position) {
|
||||
std::lock_guard g(mtx.mtx);
|
||||
if (count < max_size) {
|
||||
if (buf.size() == buf.capacity()) {
|
||||
auto capacity = std::max<std::size_t>(1, buf.capacity() * 2);
|
||||
buf.reserve(std::min(max_size, capacity));
|
||||
}
|
||||
buf.push_back(std::move(new_position));
|
||||
++count;
|
||||
head = count % max_size;
|
||||
++seq;
|
||||
return;
|
||||
}
|
||||
buf[head] = std::move(new_position);
|
||||
head = (head + 1) % max_size;
|
||||
if (count < max_size)
|
||||
++count;
|
||||
++seq;
|
||||
}
|
||||
Psc::JSON get_last_array_json(std::uint64_t last_seq);
|
||||
|
||||
@@ -23,12 +23,12 @@ MLAT_timestamp::MLAT_timestamp() {
|
||||
}
|
||||
MLAT_timestamp::MLAT_timestamp(std::string_view memory_6) : memory(memory_6) {
|
||||
assert(memory_6.size() == 6);
|
||||
auto msg_bin = hex2bin(mem2hex(memory));
|
||||
daysec = std::bitset<18>(msg_bin.substr(0, 18)).to_ulong();
|
||||
nanosec = std::bitset<30>(msg_bin.substr(18, 30)).to_ulong();
|
||||
std::uint64_t value = 0;
|
||||
for (const unsigned char byte : memory_6)
|
||||
value = value << 8 | byte;
|
||||
daysec = static_cast<std::uint32_t>(value >> 30);
|
||||
nanosec = static_cast<std::uint32_t>(value & ((std::uint64_t{1} << 30) - 1));
|
||||
parse_hhmmss();
|
||||
PSC_ASSERT(memory_6 == bin2mem(to_bin_string()),
|
||||
"MLAT_timestamp,内存转换错误!");
|
||||
}
|
||||
MLAT_timestamp::MLAT_timestamp(std::uint32_t daysec, std::uint32_t nanosec) : daysec(daysec), nanosec(nanosec) {
|
||||
parse_hhmmss();
|
||||
|
||||
+16
-8
@@ -74,13 +74,21 @@ template <typename That>
|
||||
bool in_radio_range(const ADS_B_T::Constraint& constraint, CPR_MSG<That>& cpr, const CPR::Position& position) {
|
||||
return in_radio_range(constraint, position, target_height_meters(cpr));
|
||||
}
|
||||
template <typename That>
|
||||
void report_routine_cpr_event(const ADS_B_T::Constraint& constraint, CPR_MSG<That>& cpr, CPR_Type type,
|
||||
CPR_Ret_Type result, P_S msg) {
|
||||
if (constraint.report_routine_details)
|
||||
constraint.cb(type, result, cpr.current_state(msg), msg);
|
||||
else
|
||||
constraint.cb(type, result, {}, msg);
|
||||
}
|
||||
// cpr回调
|
||||
template <typename That>
|
||||
RET<Pos_Ret> CPR_MSG<That>::local_parse_message(CPR::Position old_pos, P_S msg, double time_s, Constraint constraint) {
|
||||
Psc::JSON info = Psc::JSON::object();
|
||||
auto type = SSR::CPR_Type::Local_pos_parse;
|
||||
info.append({"type", Psc::to_string(type)});
|
||||
constraint.cb(type, SSR::CPR_Ret_Type::Base, current_state(msg), msg);
|
||||
report_routine_cpr_event(constraint, *this, type, SSR::CPR_Ret_Type::Base, msg);
|
||||
auto diff_time = std::abs(time_s - last_parse_pos_time);
|
||||
if (!constraint.use_system_time) {
|
||||
if (constraint.time_space_filter && diff_time > constraint.max_time_s) {
|
||||
@@ -135,7 +143,7 @@ RET<Pos_Ret> CPR_MSG<That>::local_parse_message(CPR::Position old_pos, P_S msg,
|
||||
"本地解码 超出基站理论探测范围" + current_state(msg), msg);
|
||||
return std::nullopt;
|
||||
}
|
||||
constraint.cb(type, SSR::CPR_Ret_Type::Parse_OK, current_state(msg), msg);
|
||||
report_routine_cpr_event(constraint, *this, type, SSR::CPR_Ret_Type::Parse_OK, msg);
|
||||
return Pos_Ret(new_pos.value(), info);
|
||||
}
|
||||
template <typename That>
|
||||
@@ -144,7 +152,7 @@ RET<Pos_Ret> CPR_MSG<That>::global_parse_message(P_S msg, double time_s, P_S oth
|
||||
Psc::JSON info = Psc::JSON::object();
|
||||
auto type = SSR::CPR_Type::Global_pos_parse;
|
||||
info.append({"type", Psc::to_string(type)});
|
||||
constraint.cb(type, SSR::CPR_Ret_Type::Base, current_state(msg), msg);
|
||||
report_routine_cpr_event(constraint, *this, type, SSR::CPR_Ret_Type::Base, msg);
|
||||
auto diff_time = std::abs(time_s - other_time_s);
|
||||
if (!constraint.use_system_time) {
|
||||
if (constraint.time_space_filter && diff_time > constraint.max_time_s) {
|
||||
@@ -201,7 +209,7 @@ RET<Pos_Ret> CPR_MSG<That>::global_parse_message(P_S msg, double time_s, P_S oth
|
||||
"全局解码 超出基站理论探测范围" + current_state(msg), msg);
|
||||
return std::nullopt;
|
||||
}
|
||||
constraint.cb(type, SSR::CPR_Ret_Type::Parse_OK, current_state(msg), msg);
|
||||
report_routine_cpr_event(constraint, *this, type, SSR::CPR_Ret_Type::Parse_OK, msg);
|
||||
return Pos_Ret(new_pos.value(), info);
|
||||
}
|
||||
template <typename Duration = std::chrono::microseconds>
|
||||
@@ -216,8 +224,8 @@ RET<Pos_Ret> CPR_MSG<That>::parse_message(P_S msg, Constraint constraint) {
|
||||
Info* that = f == CPR::Frame::Even ? &even_msg : &odd_msg;
|
||||
Info* other = f == CPR::Frame::Even ? &odd_msg : &even_msg;
|
||||
if (!last_parse_pos.has_value()) {
|
||||
constraint.cb(SSR::CPR_Type::Local_pos_parse, SSR::CPR_Ret_Type::Lack_Old_Pos, "缺旧位置" + current_state(msg),
|
||||
msg);
|
||||
report_routine_cpr_event(constraint, *this, SSR::CPR_Type::Local_pos_parse,
|
||||
SSR::CPR_Ret_Type::Lack_Old_Pos, msg);
|
||||
// 不返回下面接着走
|
||||
}
|
||||
else {
|
||||
@@ -233,8 +241,8 @@ RET<Pos_Ret> CPR_MSG<That>::parse_message(P_S msg, Constraint constraint) {
|
||||
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);
|
||||
report_routine_cpr_event(constraint, *this, SSR::CPR_Type::Global_pos_parse,
|
||||
SSR::CPR_Ret_Type::Lack_Other_Msg, msg);
|
||||
return std::nullopt;
|
||||
}
|
||||
RET<Pos_Ret> ret = global_parse_message(msg, time_s, other->msg, other->time, constraint);
|
||||
|
||||
Reference in New Issue
Block a user