This commit is contained in:
2026-07-27 15:17:13 +08:00
parent 8370ff9e79
commit c99b16d000
15 changed files with 1169 additions and 428 deletions
@@ -1,15 +1,21 @@
#include "BaseStation.h"
namespace SSR {
struct HULC_Status_Message;
}
std::optional<SSR::CPR::Position> BaseStation::get_pos() {
double BaseStation::theoretical_detection_range_meters(double base_height_meters,
double target_height_meters) {
return static_cast<double>(SSR::CPR::radio_line_of_sight_range_meters(base_height_meters, target_height_meters));
}
std::optional<SSR::Position_3D> BaseStation::get_pos() {
std::lock_guard g(mtx);
if (!hulc.GPS_has_valid_fix()) {
return std::nullopt;
}
return SSR::CPR::Position{hulc.get_latitude(), hulc.get_longitude()};
return SSR::Position_3D{hulc.get_latitude(), hulc.get_longitude(), static_cast<SSR::CPR::D>(hulc.Alt)};
}
double BaseStation::get_height() {
std::lock_guard g(mtx);
return hulc.Alt;
}
bool BaseStation::has_valid_position() {
std::lock_guard g(mtx);
@@ -33,9 +39,6 @@ Psc::JSON BaseStation::to_Json() {
ret.append({"状态标志", hulc.Flags});
ret.append({"内部使用", hulc.I_U_});
ret.append({"时间", Psc::utc_2_local_time(hulc.xTime)});
ret.append({"latitude", hulc.get_latitude()});
ret.append({"longitude", hulc.get_longitude()});
ret.append({"height", hulc.Alt});
ret.append({"卫星数量", hulc.Sat});
ret.append({"HDOP", hulc.get_HDOP()});
ret.append({"GPS设备检测到", hulc.GPS_device_detected()});
+10 -14
View File
@@ -1,21 +1,17 @@
#pragma once
#include "global.h"
class BaseStation {
public:
std::string to_string();
Psc::JSON to_Json();
std::optional<SSR::CPR::Position> get_pos();
bool has_valid_position();
void set_msg(const SSR::HULC_Status_Message& msg);
std::function<void (const SSR::HULC_Status_Message&)> handle_when_updated = nullptr;
std::string to_string();
Psc::JSON to_Json();
std::optional<SSR::Position_3D> get_pos();
double get_height();
bool has_valid_position();
void set_msg(const SSR::HULC_Status_Message& msg);
static double theoretical_detection_range_meters(double base_height_meters, double target_height_meters);
std::function<void(const SSR::HULC_Status_Message&)> handle_when_updated = nullptr;
protected:
std::mutex mtx;
SSR::HULC_Status_Message hulc{};
std::mutex mtx;
SSR::HULC_Status_Message hulc{};
};
class Global;
@@ -513,6 +513,7 @@ void Data_Source_Config::server(Global* g) {
ds->from_json(&params);
g->save();
g->mode_acs.source_feed_relation_config.set_need_refresh();
res->setBody(warp(ds->to_json()).to_json_string());
});
svr.Post(api + svr.insert + name, [g, this](HTTP_Param) {
CHECK_JSON_PARAM
+58 -8
View File
@@ -50,23 +50,73 @@ protected:
std::mutex mtx;
std::vector<bool> test_v;
};
class Data_Source_Map_Display_Data {
public:
Psc::Copyable_Atomic<bool> base_station_show = true;
Psc::Copyable_Atomic<bool> aircraft_show = true;
Psc::Copyable_Atomic<bool> constant_screen_size = true;
std::string color = "#1677ff";
std::string track_point_color = "#ffff00";
std::string base_station_color = "#1677ff";
std::uint32_t aircraft_pixel_size = 50;
std::uint32_t base_station_pixel_size = 100;
double aircraft_scale = 1.0;
double base_station_scale = 1.0;
Psc::Copyable_Atomic<bool> show_icao = true;
Psc::Copyable_Atomic<bool> show_call_sign = false;
Psc::Copyable_Atomic<bool> show_fly_status = false;
PSC_USE_JSON
};
class Data_Source_Map_Display_Config {
public:
Data_Source_Map_Display_Data map2d;
Data_Source_Map_Display_Data map3d;
[[nodiscard]] Psc::JSON to_base_json() const {
auto ret = Psc::JSON::object();
ret.append({"map2d", map2d.to_base_json()});
ret.append({"map3d", map3d.to_base_json()});
return ret;
}
void from_base_json(const Psc::JSON* that_json) {
if (that_json == nullptr || that_json->valueType != Psc::Object) {
throw Psc::json_assign_error(std::make_error_code(std::errc::invalid_argument), "map_display");
}
map2d.from_base_json(that_json->get("map2d"));
map3d.from_base_json(that_json->get("map3d"));
}
};
class Data_Source_Data {
public:
Psc::Copyable_Atomic<bool> base_station_show{};
Psc::Copyable_Atomic<bool> base_station_has_valid_position{};
Psc::Copyable_Atomic<bool> aircraft_show{};
std::string color = "#1677ff";
int aircraft_pixel_size{};
Data_Source_Map_Display_Config map_display;
double lat{};
double lon{};
double alt{};
Psc::Copyable_Atomic<bool> ignore_msg_time = false; // 忽略消息时间戳 如果启用 解码位置将不在判断消息自带时间戳
Psc::Copyable_Atomic<bool> update_form_gps{};
Psc::Copyable_Atomic<bool> show_icao = true;
Psc::Copyable_Atomic<bool> show_call_sign = false;
Psc::Copyable_Atomic<bool> show_fly_status = false;
Psc::Copyable_Atomic<bool> keep_mode = true;
PSC_USE_JSON
[[nodiscard]] Psc::JSON to_base_json() const {
auto ret = Psc::JSON::object();
Ret_J(base_station_has_valid_position)
ret.append({"map_display", map_display.to_base_json()});
Ret_J(lat)
Ret_J(lon)
Ret_J(alt)
Ret_J(ignore_msg_time)
Ret_J(update_form_gps)
Ret_J(keep_mode)
return ret;
}
void from_base_json(const Psc::JSON* that_json) {
Get_J(base_station_has_valid_position)
map_display.from_base_json(that_json->get("map_display"));
Get_J(lat)
Get_J(lon)
Get_J(alt)
Get_J(ignore_msg_time)
Get_J(update_form_gps)
Get_J(keep_mode)
}
};
class Data_Source : public std::enable_shared_from_this<Data_Source>,
public Data_Source_Handler, public Data_Source_Data {
@@ -1,7 +1,7 @@
#include "Data_Source_Handler.h"
#include <string_view>
#include "Data_Source.h"
#include "Local_Server/server/Global.h"
#include <string_view>
#include "Local_Server/server/io_coro.h"
using namespace Psc;
std::shared_ptr<Data_Source> ds(Data_Source_Handler* dsh) {
@@ -13,18 +13,16 @@ std::shared_ptr<SSR::Msg> Data_Source_Handler::create_msg(std::string_view packe
std::cout << "first:" << mem2hex(std::string(packet)) << std::endl;
return nullptr;
}
std::string error_len = source->key + " " + LOG_POS_SIMPLE +
std::string(" ") + "mode_s_error_length";
if (packet.size() < 2) return nullptr;
std::string error_len = source->key + " " + LOG_POS_SIMPLE + std::string(" ") + "mode_s_error_length";
if (packet.size() < 2)
return nullptr;
auto mt = packet[1];
if (mt == SSR::Msg::AC) {
if (packet.size() != SSR::Msg::AC_len) {
auto packet_hex = mem2hex(std::string(packet));
SSR::mode_s_logger->c_debug(
error_len, {},
std::to_string(mt) + " size:" + std::to_string(packet.size()) +
" hex:" + packet_hex +
" should:" + std::to_string(SSR::Msg::AC_len));
SSR::mode_s_logger->c_debug(error_len, {},
std::to_string(mt) + " size:" + std::to_string(packet.size()) +
" hex:" + packet_hex + " should:" + std::to_string(SSR::Msg::AC_len));
mode_ac_statistic.add_length_error();
return nullptr;
}
@@ -34,13 +32,10 @@ std::shared_ptr<SSR::Msg> Data_Source_Handler::create_msg(std::string_view packe
if (mt == SSR::Msg::S7) {
if (packet.size() != SSR::Mode_S_Msg::S7_len) {
auto packet_hex = mem2hex(std::string(packet));
SSR::mode_s_logger->c_debug(
error_len, {},
std::to_string(mt) + " size:" + std::to_string(packet.size()) +
" hex:" + packet_hex +
" should:" + std::to_string(SSR::Msg::S7_len));
mode_s_statistic.add_length_error(
"[length error] Msg::S7 handle_mode_s_source");
SSR::mode_s_logger->c_debug(error_len, {},
std::to_string(mt) + " size:" + std::to_string(packet.size()) +
" hex:" + packet_hex + " should:" + std::to_string(SSR::Msg::S7_len));
mode_s_statistic.add_length_error("[length error] Msg::S7 handle_mode_s_source");
return nullptr;
}
return std::make_shared<SSR::Mode_S_Msg>(source, packet);
@@ -48,13 +43,10 @@ std::shared_ptr<SSR::Msg> Data_Source_Handler::create_msg(std::string_view packe
if (mt == SSR::Msg::S14) {
if (packet.size() != SSR::Msg::S14_len) {
auto packet_hex = mem2hex(std::string(packet));
SSR::mode_s_logger->c_debug(
error_len, {},
std::to_string(mt) + " size:" + std::to_string(packet.size()) +
" hex:" + packet_hex +
" should:" + std::to_string(SSR::Msg::S14_len));
mode_s_statistic.add_length_error(
"[length error] Msg::S14 handle_mode_s_source");
SSR::mode_s_logger->c_debug(error_len, {},
std::to_string(mt) + " size:" + std::to_string(packet.size()) +
" hex:" + packet_hex + " should:" + std::to_string(SSR::Msg::S14_len));
mode_s_statistic.add_length_error("[length error] Msg::S14 handle_mode_s_source");
return nullptr;
}
return std::make_shared<SSR::Mode_S_Msg>(source, packet);
@@ -63,13 +55,10 @@ std::shared_ptr<SSR::Msg> Data_Source_Handler::create_msg(std::string_view packe
return nullptr; // 不知道如何解析跳过
if (packet.size() != SSR::Msg::Radarcape_status_len) {
auto packet_hex = mem2hex(std::string(packet));
SSR::mode_s_logger->c_debug(
error_len, {},
std::to_string(mt) + " size:" + std::to_string(packet.size()) +
" hex:" + packet_hex +
" should:" + std::to_string(SSR::Msg::Radarcape_status_len));
mode_s_statistic.add_length_error(
"[length error] Msg::Radarcape_status_len handle_mode_s_source");
SSR::mode_s_logger->c_debug(error_len, {},
std::to_string(mt) + " size:" + std::to_string(packet.size()) + " hex:" +
packet_hex + " should:" + std::to_string(SSR::Msg::Radarcape_status_len));
mode_s_statistic.add_length_error("[length error] Msg::Radarcape_status_len handle_mode_s_source");
return nullptr;
}
return std::make_shared<SSR::Msg>(source, packet);
@@ -79,10 +68,9 @@ std::shared_ptr<SSR::Msg> Data_Source_Handler::create_msg(std::string_view packe
auto packet_hex = mem2hex(std::string(packet));
// 找不到协议 size:23 hex:1A34195F0000001500B502FF06F423CE50000090000000
// should:5
SSR::mode_s_logger->c_debug(
error_len, {},
Psc::to_string(source->type) + " HULC size:" +
std::to_string(packet.size()) + " hex:" + packet_hex);
SSR::mode_s_logger->c_debug(error_len, {},
Psc::to_string(source->type) + " HULC size:" + std::to_string(packet.size()) +
" hex:" + packet_hex);
return nullptr;
}
return std::make_shared<SSR::Msg>(source, packet);
@@ -101,8 +89,8 @@ size_t Data_Source_Handler::process_mode_acs_data(std::string_view origin_data)
}
origin_data_transform_mode_data(mode_data);
if (data_source_debug) {
std::cout << " after origin_data_transform_mode_data " << VAR_STR_2(name, mode_data.size()) <<
key << std::endl;
std::cout << " after origin_data_transform_mode_data " << VAR_STR_2(name, mode_data.size()) << key
<< std::endl;
}
static Value_Growth_Multi_T mt;
auto t = key;
@@ -124,17 +112,16 @@ size_t Data_Source_Handler::process_mode_acs_data(std::string_view origin_data)
static bool mode_s_console = Global::instance()->console_config.mode_s_console;
static bool record_playback = Global::instance()->console_config.record_playback;
if (record_playback) {
pure_log(get_exe_dir() + "/playback/" + source->key + "_playback.dat",
mem2hex(mode_data, true, " ") + "\n");
pure_log(get_exe_dir() + "/playback/" + source->key + "_playback.dat", mem2hex(mode_data, true, " ") + "\n");
}
if (mode_s_console) {
std::cout << source->key + " read:[mode_s_serial]:" << mem2hex(mode_data)
<< std::endl;
std::cout << source->key + " read:[mode_s_serial]:" << mem2hex(mode_data) << std::endl;
}
auto handle_packet = [this, source, &ret](std::string& packet) {
ret++;
auto msg = create_msg(packet);
if (!msg) return;
if (!msg)
return;
source->push_to_feed(msg);
auto mt = msg->type;
bool mode_s = mt == SSR::Msg::S7 || mt == SSR::Msg::S14;
@@ -144,8 +131,7 @@ size_t Data_Source_Handler::process_mode_acs_data(std::string_view origin_data)
else if (mt == SSR::Msg::Radarcape_status) {
auto radarcape_msg = SSR::create_Radarcape_STATUS_Message(packet);
std::cout << radarcape_msg.toJson().to_json_string() << std::endl;
SSR::mode_s_logger->debug("Radarcape_status/radarcape", {},
radarcape_msg.toJson().to_json_string());
SSR::mode_s_logger->debug("Radarcape_status/radarcape", {}, radarcape_msg.toJson().to_json_string());
}
else if (mode_s) {
// 拓展点
@@ -160,9 +146,7 @@ size_t Data_Source_Handler::process_mode_acs_data(std::string_view origin_data)
else {
auto co = Coro::instance();
auto executor = co->process_data->get_executor();
asio::post(executor, [handle_packet, packet = std::move(packet)]() mutable {
handle_packet(packet);
});
asio::post(executor, [handle_packet, packet = std::move(packet)]() mutable { handle_packet(packet); });
}
};
SSR::Binary_Format_handle_buffer(source->buffer, mode_data, f);
@@ -170,8 +154,8 @@ size_t Data_Source_Handler::process_mode_acs_data(std::string_view origin_data)
}
void Data_Source_Handler::handle_mode_s(std::shared_ptr<SSR::Mode_S_Msg> mode_s_msg) {
auto source = ds(this);
std::string t = mode_s_msg->mlat_timestamp.to_memory() +
mode_s_msg->signal_level + Psc::hex2mem(mode_s_msg->msg_hex);
std::string t =
mode_s_msg->mlat_timestamp.to_memory() + mode_s_msg->signal_level + Psc::hex2mem(mode_s_msg->msg_hex);
auto p = mode_s_msg->packet.substr(2);
if (t != p) {
std::cout << mem2hex(t, true, " ") << std::endl;
@@ -183,12 +167,26 @@ void Data_Source_Handler::handle_mode_s(std::shared_ptr<SSR::Mode_S_Msg> mode_s_
bool time_space_filter = cfg.time_space_filter.load();
bool speed_filter = cfg.speed_filter.load();
bool use_system_time = source->ignore_msg_time.load();
SSR::ADS_B_T::Constraint air_constraint{cfg.max_speed_m_s, cfg.air_pos_timeout, SSR::cpr_cb, time_space_filter, speed_filter, use_system_time};
SSR::ADS_B_T::Constraint surface_constraint{cfg.max_speed_m_s, cfg.surface_pos_timeout, SSR::cpr_cb, time_space_filter, speed_filter, use_system_time};
SSR::parse_mode_s_bin(source.get(), mode_s_msg,
source->base_station.get_pos(), air_constraint,
surface_constraint);
auto base_station_pos = source->base_station.get_pos();
if (!base_station_pos && source->base_station_has_valid_position.load()) {
base_station_pos = SSR::Position_3D{source->lat, source->lon, source->alt};
}
auto range_filter = cfg.aircraft_change_list_adsb_range_filter.load();
auto range_factor = cfg.aircraft_change_list_adsb_range_factor.load();
SSR::ADS_B_T::Constraint air_constraint{cfg.max_speed_m_s, cfg.air_pos_timeout, SSR::cpr_cb, time_space_filter,
speed_filter, use_system_time, base_station_pos, source->alt,
range_filter, range_factor};
SSR::ADS_B_T::Constraint surface_constraint{cfg.max_speed_m_s,
cfg.surface_pos_timeout,
SSR::cpr_cb,
time_space_filter,
speed_filter,
use_system_time,
base_station_pos,
source->alt,
range_filter,
range_factor};
SSR::parse_mode_s_bin(source.get(), mode_s_msg, base_station_pos, air_constraint, surface_constraint);
auto base = source->get_aircraft(mode_s_msg->icao);
if (base) {
auto derived = std::dynamic_pointer_cast<Aircraft>(base);
@@ -199,8 +197,7 @@ void Data_Source_Handler::handle_mode_s(std::shared_ptr<SSR::Mode_S_Msg> mode_s_
mh.push(mode_s_msg);
auto tt = mh.get_all();
if (!tt.empty()) {
pure_log("@/logs/mlat.log",
"receive[" + std::to_string(tt.size()) + "]:\n");
pure_log("@/logs/mlat.log", "receive[" + std::to_string(tt.size()) + "]:\n");
for (Mlat_MSG& t : tt) {
std::ostringstream oss;
oss << std::fixed << std::setprecision(10);
@@ -223,12 +220,9 @@ void Data_Source_Handler::handle_mode_s(std::shared_ptr<SSR::Mode_S_Msg> mode_s_
auto pos = o_pos.value();
source->alt = o_alt.value();
double x, y, z;
SSR::CPR::WGS84_LBH_to_XYZ(pos.lon, pos.lat, source->alt, x, y,
z);
oss << "\tpos[" << pos.lon << "," << pos.lat << ","
<< source->alt << "]" << std::endl;
oss << "\tXYZ[" << x << "," << y << "," << z << "]"
<< std::endl;
SSR::CPR::WGS84_LBH_to_XYZ(pos.lon, pos.lat, source->alt, x, y, z);
oss << "\tpos[" << pos.lon << "," << pos.lat << "," << source->alt << "]" << std::endl;
oss << "\tXYZ[" << x << "," << y << "," << z << "]" << std::endl;
}
}
}
@@ -262,23 +256,22 @@ void Data_Source_Handler::handle_HULC(std::string_view packet) {
auto msg = mem2hex(std::string(packet));
if (len != packet.size() - 4) {
SSR::mode_s_logger->debug("HULC/error_length", {},
"需要: " + std::to_string(len) +
" 当前: " + std::to_string(packet.size()) +
"需要: " + std::to_string(len) + " 当前: " + std::to_string(packet.size()) +
" hex: " + mem2hex(std::string(packet)));
return;
}
if (id == 1) {
// 状态消息
auto status_msg = SSR::create_HULC_Status_Message(packet);
bool gps_ok = status_msg.GPS_device_detected() && status_msg.GPS_valid() &&
status_msg.GPS_has_valid_fix();
if (gps_ok) {}
bool gps_ok = status_msg.GPS_device_detected() && status_msg.GPS_valid() && status_msg.GPS_has_valid_fix();
if (gps_ok) {
}
auto g = Global::instance();
base_station.set_msg(status_msg);
Log_Type type({}, {{"msg", std::string(msg)}});
SSR::mode_s_logger->debug("HULC/status", type,
status_msg.toJson().to_json_string());
if (gps_ok) {}
SSR::mode_s_logger->debug("HULC/status", type, status_msg.toJson().to_json_string());
if (gps_ok) {
}
}
else if (id == 24) {
SSR::mode_s_logger->debug("HULC/reply", {}, msg);
@@ -290,9 +283,9 @@ void Data_Source_Handler::handle_HULC(std::string_view packet) {
void Data_Source_Handler::refresh_data_feed_key_list() {
// std::cout << key << " refresh_data_feed_key_list" << std::endl;
std::vector<std::string> tmp;
for (auto& relation :
Global::instance()->mode_acs.source_feed_relation_config.map.list()) {
if (!relation->enable) continue;
for (auto& relation : Global::instance()->mode_acs.source_feed_relation_config.map.list()) {
if (!relation->enable)
continue;
if (relation->type == "One_to_One_Relation") {
auto t = dynamic_cast<One_to_One_Relation*>(relation.get());
// std::cout << VAR_STR_2(t->source_key, this->key) << "
@@ -302,19 +295,16 @@ void Data_Source_Handler::refresh_data_feed_key_list() {
}
}
else if (relation->type == "First_Source_To_All_Feed_Relation") {
auto t =
dynamic_cast<First_Source_To_All_Feed_Relation*>(relation.get());
auto t = dynamic_cast<First_Source_To_All_Feed_Relation*>(relation.get());
std::shared_ptr<Data_Source> first = nullptr;
for (const auto& ds :
Global::instance()->mode_acs.data_source_config.map.list()) {
for (const auto& ds : Global::instance()->mode_acs.data_source_config.map.list()) {
if (ds->enable) {
first = ds;
break;
}
}
if (first->key == key) {
for (const auto& df :
Global::instance()->mode_acs.data_feed_config.map.list()) {
for (const auto& df : Global::instance()->mode_acs.data_feed_config.map.list()) {
if (df->enable) {
tmp.push_back(df->key);
}
@@ -337,10 +327,9 @@ void Data_Source_Handler::refresh_data_feed_key_list() {
// 1. 删除 tmp 中没有的 cached_data_feed_key_list 元素
auto it = cached_data_feed_key_list.begin();
while (it != cached_data_feed_key_list.end()) {
if (std::find_if(tmp_info.begin(), tmp_info.end(),
[&](const Cached_Source_Info& info) {
return info.key == it->key;
}) == tmp_info.end()) {
if (std::find_if(tmp_info.begin(), tmp_info.end(), [&](const Cached_Source_Info& info) {
return info.key == it->key;
}) == tmp_info.end()) {
// 如果当前元素在 tmp 中找不到,删除它
it = cached_data_feed_key_list.erase(it);
}
@@ -350,11 +339,9 @@ void Data_Source_Handler::refresh_data_feed_key_list() {
}
// 2. 创建 tmp 中有但 cached_data_feed_key_list 没有的元素
for (const auto& tmp_item : tmp_info) {
auto found = std::find_if(cached_data_feed_key_list.begin(),
cached_data_feed_key_list.end(),
[&](const Cached_Source_Info& cached_item) {
return cached_item.key == tmp_item.key;
});
auto found = std::find_if(
cached_data_feed_key_list.begin(), cached_data_feed_key_list.end(),
[&](const Cached_Source_Info& cached_item) { return cached_item.key == tmp_item.key; });
if (found == cached_data_feed_key_list.end()) {
// 如果 tmp_item 不在 cached_data_feed_key_list 中,添加它
cached_data_feed_key_list.push_back(tmp_item);
@@ -364,8 +351,7 @@ void Data_Source_Handler::refresh_data_feed_key_list() {
}
}
}
std::optional<std::string> convert_to_send_format(Data_Source_Handler* ds,
const std::shared_ptr<Data_Feed>& feed,
std::optional<std::string> convert_to_send_format(Data_Source_Handler* ds, const std::shared_ptr<Data_Feed>& feed,
const std::shared_ptr<SSR::Msg>& msg) {
auto& type = msg->type;
auto fs = dynamic_cast<File_Data_Source*>(msg->source.get());
@@ -382,22 +368,22 @@ std::optional<std::string> convert_to_send_format(Data_Source_Handler* ds,
// 计算出是否输出消息
std::optional<std::string> send_msg = std::nullopt;
if (type == SSR::Msg::HULC_Status) {
if (!use_status) return std::nullopt;
if (!use_status)
return std::nullopt;
auto data = static_cast<SSR::Msg*>(msg.get());
if (output_format == Output_Data_Format::BIN ||
output_format == Output_Data_Format::BIN_ID) {
if (output_format == Output_Data_Format::BIN || output_format == Output_Data_Format::BIN_ID) {
send_msg = SSR::packet_to_escape_format(data->packet);
}
}
else if (type == SSR::Msg::Radarcape_status) {
auto data = static_cast<SSR::Msg*>(msg.get());
if (output_format == Output_Data_Format::BIN ||
output_format == Output_Data_Format::BIN_ID) {
if (output_format == Output_Data_Format::BIN || output_format == Output_Data_Format::BIN_ID) {
send_msg = SSR::packet_to_escape_format(data->packet);
}
}
else if (type == SSR::Msg::AC) {
if (!use_mode_ac) return std::nullopt;
if (!use_mode_ac)
return std::nullopt;
auto data = static_cast<SSR::Mode_AC_Msg*>(msg.get());
std::string& msg_hex = data->msg_hex;
char signal_level = data->signal_level;
@@ -448,10 +434,12 @@ std::optional<std::string> convert_to_send_format(Data_Source_Handler* ds,
sbs_out_put = true;
}
}
if (!sbs_out_put) return std::nullopt;
if (!sbs_out_put)
return std::nullopt;
send_msg = "";
SSR::SBS_MSG msg_base;
if (!aircraft) return std::nullopt;
if (!aircraft)
return std::nullopt;
msg_base.set(aircraft.get());
for (int msg_t = 1; msg_t <= 8; ++msg_t) {
send_msg->append(msg_base.to_msg(msg_t) + "\n");
@@ -463,11 +451,11 @@ std::optional<std::string> convert_to_send_format(Data_Source_Handler* ds,
send_msg->append(msg_base.to_STA() + "\n");
return send_msg;
}
bool DF_11_17_18 =
df == SSR::Downlink_Format::All_Call_Reply_11 ||
bool DF_11_17_18 = df == SSR::Downlink_Format::All_Call_Reply_11 ||
df == SSR::Downlink_Format::Extended_Squitter_17 ||
df == SSR::Downlink_Format::Extended_Squitter_Non_Transponder_18;
if (mode_s_output_type == Mode_S_Output_Type::DF_11_17_18 && !DF_11_17_18) return std::nullopt;
if (mode_s_output_type == Mode_S_Output_Type::DF_11_17_18 && !DF_11_17_18)
return std::nullopt;
if (mode_s_output_type == Mode_S_Output_Type::NO_POS_Mode_S) {
if (aircraft && aircraft->pos().has_value()) {
return std::nullopt;
@@ -493,8 +481,7 @@ std::optional<std::string> convert_to_send_format(Data_Source_Handler* ds,
send_msg = create_MLAT_AVR_format(msg_hex, &mlat_timestamp);
}
else {
std::cerr << "Unknown output format " << VAR_STR_1(output_format)
<< std::endl;
std::cerr << "Unknown output format " << VAR_STR_1(output_format) << std::endl;
return std::nullopt;
}
}
@@ -516,9 +503,9 @@ void Data_Source_Handler::push_to_feed(const std::shared_ptr<SSR::Msg>& msg) {
break;
}
std::shared_ptr<Data_Feed>& feed = opt_feed.value();
if (!feed->enable) continue;
if (msg->type == SSR::Mode_Msg::T::S7 ||
msg->type == SSR::Mode_Msg::T::S14) {
if (!feed->enable)
continue;
if (msg->type == SSR::Mode_Msg::T::S7 || msg->type == SSR::Mode_Msg::T::S14) {
// static Frequency_Limit fl;
// if (!fl.test()) {
// std::ostringstream oss;
+88 -6
View File
@@ -1,12 +1,56 @@
#include "Database.h"
#include "Data_Source.h"
#include "../server/Global.h"
#include "../server/Performance_Monitor.h"
#include <algorithm>
#include <chrono>
#include <cmath>
#include <functional>
#include <map>
#include <string_view>
namespace {
double to_radians(double degrees) {
return degrees * 3.14159265358979323846 / 180.0;
}
double to_degrees(double radians) {
return radians * 180.0 / 3.14159265358979323846;
}
bool aircraft_in_base_station_radio_range(const std::optional<SSR::Position_3D> &base_position,
const SSR::Position_Info &position,
double factor) {
if (!base_position) {
return true;
}
return SSR::CPR::in_radio_line_of_sight_range(*base_position, base_position->alt, position, position.alt, factor);
}
double track_heading_from_points(const SSR::Position_Info &first,
const SSR::Position_Info &second) {
auto lat1 = to_radians(first.lat);
auto lat2 = to_radians(second.lat);
auto dlon = to_radians(second.lon - first.lon);
auto y = std::sin(dlon) * std::cos(lat2);
auto x = std::cos(lat1) * std::sin(lat2) -
std::sin(lat1) * std::cos(lat2) * std::cos(dlon);
auto angle = to_degrees(std::atan2(y, x));
return angle < 0 ? angle + 360.0 : angle;
}
double track_pitch_from_points(const SSR::Position_Info &first,
const SSR::Position_Info &second) {
auto distance = SSR::CPR::haversine(first, second);
return std::atan2(second.alt - first.alt, distance) * 180.0 /
3.14159265358979323846;
}
Psc::JSON track_orientation_json_from_points(const SSR::Position_Info &first,
const SSR::Position_Info &second) {
auto ret = Psc::JSON::object();
ret.append({"heading", track_heading_from_points(first, second)});
ret.append({"pitch", track_pitch_from_points(first, second)});
ret.append({"roll", 0.0});
return ret;
}
}
Aircraft::Aircraft(std::string_view icao) : Aircraft_Info(icao) {
auto size = Global::instance()->mode_acs.max_track_point_size.load();
air_pos_track_list.init(size);
@@ -77,14 +121,34 @@ Psc::JSON DataBase::get_aircraftlist(int limit_msg_num) {
JSON DataBase::get_all_aircraft_json() {
JSON json = JSON::array();
auto g = Global::instance();
auto min_position_points =
g->mode_acs.aircraft_change_list_min_position_points.load();
auto range_filter = g->mode_acs.aircraft_change_list_adsb_range_filter.load();
auto range_factor = g->mode_acs.aircraft_change_list_adsb_range_factor.load();
auto source = g->source(get_key());
auto base_position = base_station.get_pos();
if (source) {
if (!base_position && source->base_station_has_valid_position.load()) {
base_position = SSR::Position_3D{source->lat, source->lon, source->alt};
}
}
size_t num = 0;
for (auto &it : aircraft_map.values()) {
auto vto = Flight_VTO::to_VTO(it.get());
bool have_pos = !it.get()->air_pos_track_list.empty();
if (have_pos) {
json.children.push_back(vto.to_json());
num++;
if (it->air_pos_track_list.size() < min_position_points) {
continue;
}
auto last_position = it->air_pos_track_list.last();
if (!last_position) {
continue;
}
if (range_filter &&
!aircraft_in_base_station_radio_range(base_position, *last_position,
range_factor)) {
continue;
}
auto vto = Flight_VTO::to_VTO(it.get());
json.children.push_back(vto.to_json());
num++;
}
have_pos_aircraft_num = num;
return json;
@@ -187,6 +251,16 @@ void database_server(Global *g) {
auto ret = JSON::object();
if (db) {
ret = db->base_station.to_Json();
auto target_height =
g->mode_acs.adsb_theoretical_target_altitude_meters.load();
auto range = BaseStation::theoretical_detection_range_meters(db->alt,
target_height);
ret.append({"latitude", db->lat});
ret.append({"longitude", db->lon});
ret.append({"height", db->alt});
ret.append({"adsb_theoretical_target_altitude_meters", target_height});
ret.append({"adsb_theoretical_detection_range_meters", range});
ret.append({"理论探测范围", range});
}
res->setBody(warp(ret).to_json_string());
});
@@ -198,7 +272,7 @@ void database_server(Global *g) {
JSON ret;
if (aircraft != nullptr) {
auto vto = Flight_VTO::to_VTO(aircraft.get());
ret = vto.to_json();
ret = vto.to_base_info_json();
}
res->setBody(ret.to_json_string());
});
@@ -222,6 +296,14 @@ void database_server(Global *g) {
JSON ret;
if (aircraft != nullptr) {
ret = aircraft->air_pos_track_list.get_last_array_json(last_size);
auto last_two = aircraft->air_pos_track_list.last_two();
if (last_two.has_value()) {
ret.children.insert(
ret.children.begin(),
JSON("track_orientation",
track_orientation_json_from_points(last_two->first,
last_two->second)));
}
ret.children.insert(ret.children.begin(), JSON("ds", data_source_key));
ret.children.insert(ret.children.begin(), JSON("icao", icao));
}