From af8cbb35aaf646eb7aa0cb9ad49f98184f09879e Mon Sep 17 00:00:00 2001 From: baocm Date: Thu, 29 Jan 2026 11:41:47 +0800 Subject: [PATCH] =?UTF-8?q?1.=20=E4=BC=98=E5=8C=96=E7=A7=B0=E9=87=8D?= =?UTF-8?q?=E9=80=BB=E8=BE=91=E5=A4=84=E7=90=86=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- core/Publisher.cxx | 117 +++++++++++++++++++++++++++++++++++---------- led/Subscriber.cxx | 46 ++++++++++++++++++ led/Subscriber.hpp | 3 ++ led/main.cxx | 83 ++++++++++++++++++++++++++++---- led/msg.hpp | 1 + 5 files changed, 217 insertions(+), 33 deletions(-) diff --git a/core/Publisher.cxx b/core/Publisher.cxx index 8d6d1aa..a51979f 100644 --- a/core/Publisher.cxx +++ b/core/Publisher.cxx @@ -333,12 +333,23 @@ bool PublisherApp::print_receipt(const std::map& msg) return true; } +#define WEIGH_IDLE 0 +#define WEIGH_LIC 1 +#define WEIGH_STABLE1 2 +#define WEIGH_STABLE2 3 +#define WEIGH_SEND 4 +#define WEIGH_PRINT 5 +#define WEIGH_ERROR 6 +#define WEIGH_LEAVE 7 + void PublisherApp::run() { - uint8_t send_sum = 0; - uint8_t is_print = 0; - std::string license_no = ""; + std::string license_no; float stable_weight = 0; + float stable_weight1 = 0; + float stable_weight2 = 0; + int weigh_state = WEIGH_IDLE; + int weigh_timeout = 0; while (!is_stopped()) { @@ -354,9 +365,10 @@ void PublisherApp::run() DEBUG("车牌: " << info.License()); DEBUG("类型: " << info.NewTag()); - if (license_no == "") + if (license_no.empty() == true) { license_no = info.License(); + weigh_state = WEIGH_LIC; } } else if (!DdsMsgData::ScaleInfo_queue_.empty()) @@ -371,26 +383,25 @@ void PublisherApp::run() DEBUG("实时重量: " << info.Value()); DEBUG("稳定重量: " << info.StableValue()); - if (info.WeightOK() == 1) + if (info.WeightOK() == true) { stable_weight = info.StableValue(); } else { stable_weight = 0; - send_sum = 0; } if (info.HasVehicle() == 0) { - license_no = ""; - if (is_print == 1) + license_no.clear(); + if (weigh_state == WEIGH_LEAVE) { std::this_thread::sleep_for(std::chrono::seconds(5)); std::map ctrl; ctrl["FrontBar"] = "down"; bar_ctrl(ctrl); - is_print = 0; + weigh_state = WEIGH_IDLE; } } } @@ -466,12 +477,12 @@ void PublisherApp::run() print_msg["TicketType"] = info.TicketType(); print_receipt(print_msg); - - is_print = 1; - std::map ctrl; - ctrl["FrontBar"] = "up"; - bar_ctrl(ctrl); + std::this_thread::sleep_for(std::chrono::seconds(1)); } + weigh_state = WEIGH_LEAVE; + std::map ctrl; + ctrl["FrontBar"] = "up"; + bar_ctrl(ctrl); } else if (!DdsMsgData::WeightInfoError_queue_.empty()) { @@ -479,8 +490,7 @@ void PublisherApp::run() DdsMsgData::WeightInfoError_queue_.pop(); dds_lock.unlock(); - std::this_thread::sleep_for(std::chrono::seconds(3)); - send_sum = 0; + weigh_state = WEIGH_ERROR; } else { @@ -489,17 +499,74 @@ void PublisherApp::run() } // logic - if (send_sum == 0) + switch (weigh_state) { - if ((stable_weight != 0) && (license_no != "")) - { + case WEIGH_IDLE: + break; + case WEIGH_LIC: + if ((stable_weight != 0) && (license_no.empty() != true)) + { + DEBUG("stable_weight1 " << stable_weight); + DEBUG("license_no " << license_no); + stable_weight1 = stable_weight; + weigh_state = WEIGH_STABLE1; + weigh_timeout = 0; + } + break; + case WEIGH_STABLE1: + if (stable_weight == 0) + { + DEBUG("weigh1 clear"); + weigh_state = WEIGH_STABLE2; + } + if (weigh_timeout++ > 600) + { + DEBUG("weigh1 clear timeout"); + weigh_timeout = 0; + stable_weight2 = stable_weight; + weigh_state = WEIGH_SEND; + } + break; + case WEIGH_STABLE2: + if ((stable_weight != 0) && (license_no.empty() != true)) + { + DEBUG("license_no " << license_no); + DEBUG("stable_weight2 " << stable_weight); + stable_weight2 = stable_weight; + if (stable_weight2 < stable_weight1) + { + weigh_state = WEIGH_SEND; + } + else + { + DEBUG("stable_weight2 error"); + stable_weight1 = stable_weight; + weigh_state = WEIGH_STABLE1; + weigh_timeout = 0; + } + } + break; + case WEIGH_SEND: DEBUG("send summary"); - WeighingSystem::SummaryUpdate info; - info.License() = license_no; - info.StableValue() = stable_weight; - summary_writer_->write(&info); - send_sum = 1; - } + { + WeighingSystem::SummaryUpdate info; + info.License() = license_no; + info.StableValue() = stable_weight2; + summary_writer_->write(&info); + } + weigh_state = WEIGH_PRINT; + break; + case WEIGH_PRINT: + break; + case WEIGH_ERROR: + std::this_thread::sleep_for(std::chrono::seconds(3)); + weigh_state = WEIGH_STABLE2; + break; + case WEIGH_LEAVE: + break; + default: + weigh_state = WEIGH_IDLE; + break; } // Wait for period or stop event diff --git a/led/Subscriber.cxx b/led/Subscriber.cxx index a0e1e35..39a341a 100644 --- a/led/Subscriber.cxx +++ b/led/Subscriber.cxx @@ -53,6 +53,9 @@ SubscriberApp::SubscriberApp( , weightinfoerror_topic_(nullptr) , weightinfoerror_reader_(nullptr) , weightinfoerror_type_(new WeighingSystem::WeightInfoErrorPubSubType()) + , license_topic_(nullptr) + , license_reader_(nullptr) + , license_type_(new WeighingSystem::LicenseSnapUpdatePubSubType()) , samples_received_(0) , stop_(false) { @@ -72,6 +75,7 @@ SubscriberApp::SubscriberApp( scaleinfo_type_.register_type(participant_); weightinfook_type_.register_type(participant_); weightinfoerror_type_.register_type(participant_); + license_type_.register_type(participant_); // Create the subscriber SubscriberQos sub_qos = SUBSCRIBER_QOS_DEFAULT; @@ -162,6 +166,33 @@ SubscriberApp::SubscriberApp( { throw std::runtime_error("WeighingSystem::WeightInfoError DataReader initialization failed"); } + + // Create the topic + topic_qos = TOPIC_QOS_DEFAULT; + participant_->get_default_topic_qos(topic_qos); + license_topic_ = participant_->create_topic("LicenseSnapUpdate", license_type_.get_type_name(), topic_qos); + if (license_topic_ == nullptr) + { + throw std::runtime_error("WeighingSystem::LicenseSnapUpdate Topic initialization failed"); + } + + // Create the reader + reader_qos = DATAREADER_QOS_DEFAULT; + subscriber_->get_default_datareader_qos(reader_qos); + reader_qos.reliability().kind = ReliabilityQosPolicyKind::RELIABLE_RELIABILITY_QOS; + reader_qos.reliability().max_blocking_time = Duration_t(1, 0); + reader_qos.durability().kind = DurabilityQosPolicyKind::VOLATILE_DURABILITY_QOS; + reader_qos.history().kind = HistoryQosPolicyKind::KEEP_LAST_HISTORY_QOS; + reader_qos.history().depth = 1; + reader_qos.resource_limits().max_samples = 200; + reader_qos.resource_limits().max_instances = 1; + reader_qos.resource_limits().max_samples_per_instance = 100; + reader_qos.data_sharing().off(); + license_reader_ = subscriber_->create_datareader(license_topic_, reader_qos, this, StatusMask::all()); + if (license_reader_ == nullptr) + { + throw std::runtime_error("WeighingSystem::LicenseSnapUpdate DataReader initialization failed"); + } } SubscriberApp::~SubscriberApp() @@ -246,6 +277,21 @@ void SubscriberApp::on_data_available( } } } + else if (topic_name == "LicenseSnapUpdate") + { + WeighingSystem::LicenseSnapUpdate sample_; + while ((!is_stopped()) && (RETCODE_OK == reader->take_next_sample(&sample_, &info))) + { + if ((info.instance_state == ALIVE_INSTANCE_STATE) && info.valid_data) + { + { + std::unique_lock lock(DdsMsgData::queue_cv_mtx_); + DdsMsgData::LicenseSnapUpdate_queue_.push(std::move(sample_)); + lock.unlock(); + } + } + } + } } void SubscriberApp::run() diff --git a/led/Subscriber.hpp b/led/Subscriber.hpp index 623d157..248e4a0 100644 --- a/led/Subscriber.hpp +++ b/led/Subscriber.hpp @@ -72,6 +72,9 @@ private: eprosima::fastdds::dds::Topic* weightinfoerror_topic_; eprosima::fastdds::dds::DataReader* weightinfoerror_reader_; eprosima::fastdds::dds::TypeSupport weightinfoerror_type_; + eprosima::fastdds::dds::Topic* license_topic_; + eprosima::fastdds::dds::DataReader* license_reader_; + eprosima::fastdds::dds::TypeSupport license_type_; uint16_t samples_received_; std::atomic stop_; mutable std::mutex terminate_cv_mtx_; diff --git a/led/main.cxx b/led/main.cxx index 487fb4f..afe94a6 100644 --- a/led/main.cxx +++ b/led/main.cxx @@ -32,6 +32,7 @@ #include "Subscriber.hpp" #include "msg.hpp" #include "DEBUG.hpp" +#include "utils.hpp" #include "YQNetCom.h" using eprosima::fastdds::dds::Log; @@ -146,9 +147,7 @@ void send_text(std::string ip_addr, int port, std::string text) std::vector ip(ip_addr.begin(), ip_addr.end()); ip.push_back('\0'); - std::string encoded_str = base64_encode(text); - std::vector wcstring(encoded_str.begin(), encoded_str.end()); - wcstring.push_back('\0'); + std::string wcstring = base64_encode(text); int b = check_time(ip.data(), port, user_name, user_pwd); DEBUG("check_time==" << b); @@ -177,7 +176,7 @@ void send_text(std::string ip_addr, int port, std::string text) delete_playlist(play_list); } -void send_default(std::string ip_addr, int port) +void send_file(std::string ip_addr, int port, std::string wcstring) { char *user_name = "guest", *user_pwd = "guest"; int dynamic_type = 1; @@ -197,8 +196,6 @@ void send_default(std::string ip_addr, int port) std::vector ip(ip_addr.begin(), ip_addr.end()); ip.push_back('\0'); - std::string wcstring = "led.txt"; - int b = check_time(ip.data(), port, user_name, user_pwd); DEBUG("check_time==" << b); unsigned long play_list = create_playlist(128, 128, 8280); @@ -226,9 +223,38 @@ void send_default(std::string ip_addr, int port) delete_playlist(play_list); } +std::string readfile(std::string name) +{ + auto exeDir = getExeDir(); + auto configPath = exeDir / name; + + // 检查文件是否存在 + if (!std::filesystem::exists(configPath)) + { + std::cerr << "文件不存在: " << configPath << std::endl; + return ""; + } + + std::ifstream file(configPath); + if (!file.is_open()) + { + std::cerr << "无法打开文件: " << configPath << std::endl; + return ""; + } + + // 方法1:使用 stringstream 读取整个文件 + std::stringstream buffer; + buffer << file.rdbuf(); // 读取所有内容 + std::string config = buffer.str(); + + file.close(); + return config; +} + std::queue DdsMsgData::ScaleInfo_queue_; std::queue DdsMsgData::WeightInfoOk_queue_; std::queue DdsMsgData::WeightInfoError_queue_; +std::queue DdsMsgData::LicenseSnapUpdate_queue_; std::mutex DdsMsgData::queue_cv_mtx_; std::atomic running(true); @@ -240,8 +266,11 @@ int main(int argc, char** argv) int domain_id = 0; int port = 80; + int type = 0; std::string addr = "192.168.1.100"; uint8_t clear_led = 1; + uint8_t weight_stable = 0; + std::string license = ""; for (int i = 1; i < argc; i++) { @@ -257,6 +286,10 @@ int main(int argc, char** argv) { port = atoi(argv[++i]); } + else if (strcmp(argv[i], "--type") == 0 && i + 1 < argc) + { + type = atoi(argv[++i]); + } else if (strcmp(argv[i], "--version") == 0) { std::cout << "Vesrion: " << PROGRAM_VERSION << "\n"; @@ -269,6 +302,7 @@ int main(int argc, char** argv) << " --domain Set domain ID\n" << " --addr Set led addr (e.g., 192.168.1.1)\n" << " --port Set port name (e.g., 80)\n" + << " --type Set port name (0: in car, 1: not in car)\n" << " --version Show software Version\n" << " --help Show this help message\n"; return EXIT_SUCCESS; @@ -281,6 +315,7 @@ int main(int argc, char** argv) << " --domain Set domain ID\n" << " --addr Set led addr (e.g., 192.168.1.1)\n" << " --port Set port name (e.g., 80)\n" + << " --type Set port name (0: in car, 1: not in car)\n" << " --version Show software Version\n" << " --help Show this help message\n"; return EXIT_FAILURE; @@ -298,7 +333,8 @@ int main(int argc, char** argv) return oss.str(); }; - send_default(addr, port); + std::string default_text = readfile("led.txt"); + send_text(addr, port, default_text); while(running.load()) { @@ -333,10 +369,29 @@ int main(int argc, char** argv) { if (clear_led == 0) { - send_default(addr, port); + send_text(addr, port, default_text); clear_led = 1; + license.clear(); } } + + if (info.WeightOK() == true) + { + weight_stable = 1; + } + else + { + weight_stable = 0; + } + } + else if (!DdsMsgData::LicenseSnapUpdate_queue_.empty()) + { + WeighingSystem::LicenseSnapUpdate info = std::move(DdsMsgData::LicenseSnapUpdate_queue_.front()); + DdsMsgData::LicenseSnapUpdate_queue_.pop(); + lock.unlock(); + + license = info.License(); + weight_stable = 0; } else { @@ -344,6 +399,18 @@ int main(int argc, char** argv) } } + if (type == 1) + { + if ((weight_stable == 1) && (!license.empty())) + { + std::string text = license + std::string(",司机请下车等候,切勿停留在车上!"); + send_text(addr, port, text); + clear_led = 0; + weight_stable = 0; + license.clear(); + } + } + std::this_thread::sleep_for(std::chrono::milliseconds(100)); } diff --git a/led/msg.hpp b/led/msg.hpp index ad24173..7a2fd30 100644 --- a/led/msg.hpp +++ b/led/msg.hpp @@ -10,6 +10,7 @@ public: static std::queue ScaleInfo_queue_; static std::queue WeightInfoOk_queue_; static std::queue WeightInfoError_queue_; + static std::queue LicenseSnapUpdate_queue_; static std::mutex queue_cv_mtx_; };