Commit 4119e718 authored by 957dd's avatar 957dd

接收到相应的消息就在相应的发送相应的位置

parent 0f075104
This diff is collapsed.
...@@ -252,7 +252,7 @@ CMakeFiles/main.dir/src/main.cc.o: /home/orangepi/gps/master/src/main.cc \ ...@@ -252,7 +252,7 @@ CMakeFiles/main.dir/src/main.cc.o: /home/orangepi/gps/master/src/main.cc \
/usr/include/aarch64-linux-gnu/bits/termios-tcflow.h \ /usr/include/aarch64-linux-gnu/bits/termios-tcflow.h \
/usr/include/aarch64-linux-gnu/bits/termios-misc.h \ /usr/include/aarch64-linux-gnu/bits/termios-misc.h \
/usr/include/aarch64-linux-gnu/sys/ttydefaults.h \ /usr/include/aarch64-linux-gnu/sys/ttydefaults.h \
/home/orangepi/gps/master/include/tank_data.hpp \ /home/orangepi/gps/master/include/positioning_data.hpp \
/home/orangepi/gps/master/third_party/json/include/nlohmann/json.hpp \ /home/orangepi/gps/master/third_party/json/include/nlohmann/json.hpp \
/usr/include/c++/11/algorithm \ /usr/include/c++/11/algorithm \
/usr/include/c++/11/pstl/glue_algorithm_defs.h \ /usr/include/c++/11/pstl/glue_algorithm_defs.h \
......
No preview for this file type
This source diff could not be displayed because it is too large. You can view the blob instead.
// tank_data.hpp (正确的版本) #pragma once
#ifndef TANK_DATA_HPP
#define TANK_DATA_HPP
#include <string> #include <string>
#include <nlohmann/json.hpp> #include <nlohmann/json.hpp>
using json = nlohmann::json; using json = nlohmann::json;
struct TankWarMapData { struct positioningMapData {
int id; int id;//std::string
std::string type;
int resWidth; int resWidth;
int resHeight; int resHeight;
int resX; int resX;
...@@ -17,11 +14,10 @@ struct TankWarMapData { ...@@ -17,11 +14,10 @@ struct TankWarMapData {
int resZ; int resZ;
}; };
// 这个函数只负责 TankWarMapData 的转换,不应包含任何其他内容 // 这个函数只负责 positioningMapData 的转换,不应包含任何其他内容
void to_json(json& j, const TankWarMapData& data) { void to_json(json& j, const positioningMapData& data) {
j = json{ j = json{
{"id", data.id}, {"id", data.id},
{"type", data.type},
{"resWidth", data.resWidth}, {"resWidth", data.resWidth},
{"resHeight", data.resHeight}, {"resHeight", data.resHeight},
{"resX", data.resX}, {"resX", data.resX},
...@@ -30,4 +26,12 @@ void to_json(json& j, const TankWarMapData& data) { ...@@ -30,4 +26,12 @@ void to_json(json& j, const TankWarMapData& data) {
}; };
} }
#endif // TANK_DATA_HPP
\ No newline at end of file std::string transfor_json( positioningMapData &data) {
json j;
j["body"] = data;
j["head"] = {{"message_type", 1}};
std::string json_payload = j.dump();
return json_payload;
}
...@@ -56,6 +56,8 @@ private: ...@@ -56,6 +56,8 @@ private:
// 监听线程的主循环函数 // 监听线程的主循环函数
void listenerLoop(); void listenerLoop();
const std::vector<uint8_t> _stop_serial_modbus = {0x01, 0x10, 0x00, 0x3B, 0x00, 0x01, 0x02, 0x00, 0x00, 0xA2, 0xDB};//停止串口
// 内部状态 // 内部状态
std::string port_name_; std::string port_name_;
int fd_; // 文件描述符 int fd_; // 文件描述符
......
...@@ -5,9 +5,10 @@ ...@@ -5,9 +5,10 @@
#include <thread> #include <thread>
#include <chrono> #include <chrono>
#include <iomanip> #include <iomanip>
#include <string>
#include "device_tag_bind.hpp" #include "device_tag_bind.hpp"
#include "serial_port.hpp" #include "serial_port.hpp"
#include "tank_data.hpp" #include "positioning_data.hpp"
#include "mqtt_used.hpp" // 注意:这里应该是 MqttTopicsHandler.hpp #include "mqtt_used.hpp" // 注意:这里应该是 MqttTopicsHandler.hpp
#include "file_operations.hpp" #include "file_operations.hpp"
...@@ -20,8 +21,10 @@ const std::string PASSWORD = "admin"; ...@@ -20,8 +21,10 @@ const std::string PASSWORD = "admin";
// 主题定义 // 主题定义
const std::string g_base_topic_prefix = "ser2dev/"; // 用于接收动态订阅指令的主题 const std::string g_base_topic_prefix = "ser2dev/"; // 用于接收动态订阅指令的主题
const std::string publish_topic_prefix = "positioning/"; // 发布数据的主题前缀 const std::string publish_topic_prefix = "positioning/"; // 发布数据的主题前缀
std::string final_publish_topic;
std::string g_device_id; std::string g_device_id;
positioningMapData g_positioning_data_t;
// --- 全局变量 --- // --- 全局变量 ---
// 使用智能指针管理串口和MQTT客户端的生命周期 // 使用智能指针管理串口和MQTT客户端的生命周期
...@@ -63,7 +66,7 @@ void onSerialMessageReceived(const std::vector<uint8_t>& message) { ...@@ -63,7 +66,7 @@ void onSerialMessageReceived(const std::vector<uint8_t>& message) {
// 直接从 message vector 访问数据,无需拷贝 // 直接从 message vector 访问数据,无需拷贝
if (message[10] == 0x01) { if (message[10] == 0x01) {
int i = static_cast<int>(message[8]); int i = static_cast<int>(message[8]);
if (i >= 0 && i < x_local.size()) { if (i>0 && static_cast<size_t>(i) < x_local.size()) {
x_local[i] = (static_cast<uint16_t>(message[13]) << 8) | message[14]; x_local[i] = (static_cast<uint16_t>(message[13]) << 8) | message[14];
y_local[i] = (static_cast<uint16_t>(message[15]) << 8) | message[16]; y_local[i] = (static_cast<uint16_t>(message[15]) << 8) | message[16];
...@@ -102,7 +105,7 @@ std::shared_ptr<MqttTopicsHandler> mqtt_init_and_connect() { ...@@ -102,7 +105,7 @@ std::shared_ptr<MqttTopicsHandler> mqtt_init_and_connect() {
std::string g_base_topic = g_base_topic_prefix + g_device_id; std::string g_base_topic = g_base_topic_prefix + g_device_id;
// 构造发布主题,例如:positioning/CN040300000002 // 构造发布主题,例如:positioning/CN040300000002
std::string final_publish_topic = publish_topic_prefix + g_device_id; final_publish_topic = publish_topic_prefix + g_device_id;
handler->AddSubscription(g_base_topic, handler->AddSubscription(g_base_topic,
[weak_handler = std::weak_ptr<MqttTopicsHandler>(handler)](const std::string& topic, const nlohmann::json& json) { [weak_handler = std::weak_ptr<MqttTopicsHandler>(handler)](const std::string& topic, const nlohmann::json& json) {
...@@ -111,25 +114,49 @@ std::shared_ptr<MqttTopicsHandler> mqtt_init_and_connect() { ...@@ -111,25 +114,49 @@ std::shared_ptr<MqttTopicsHandler> mqtt_init_and_connect() {
if (json.value("/head/message_type"_json_pointer, 0) != 5000) return; if (json.value("/head/message_type"_json_pointer, 0) != 5000) return;
auto dev_id = json.at("body").at("dev_id").get<std::string>(); auto dev_id = json.at("body").at("dev_id").get<std::string>();
auto tag_id = json.at("body").at("id").get<std::string>();
auto data_topic = "app2dev/" + dev_id; auto data_topic = "app2dev/" + dev_id;
g_device_tag_t.set(dev_id, data_topic); g_device_tag_t.set(tag_id, data_topic);
// 转换为整数
int tag_id_num_int = std::stoi(tag_id); // 可能抛出 std::invalid_argument 或 std::out_of_range
positioningMapData bind_tag_send_data_t = {
.id = tag_id_num_int,
.resWidth = 500,
.resHeight = 500,
.resX = x_local[tag_id_num_int],
.resY = y_local[tag_id_num_int],
.resZ = 0
};
g_positioning_data_t=bind_tag_send_data_t;
g_mqtt_handler->publish(final_publish_topic, transfor_json(g_positioning_data_t));
if (auto shared_handler = weak_handler.lock()) { if (auto shared_handler = weak_handler.lock()) {
std::cout << "指令解析成功,准备动态订阅主题: " << data_topic << std::endl; std::cout << "指令解析成功,准备动态订阅主题: " << data_topic << std::endl;
// 调用 AddSubscription,它现在会将订阅任务 post 到工作线程,避免死锁 // 调用 AddSubscription,它现在会将订阅任务 post 到工作线程,避免死锁
shared_handler->AddSubscription(data_topic, shared_handler->AddSubscription(data_topic,
[](const std::string& sub_topic, const nlohmann::json& sub_json) { [](const std::string& sub_topic, const nlohmann::json& sub_json) {
std::cout<<"发送成功"<<std::endl;
if (sub_json.contains("head") && if (sub_json.contains("head") &&
sub_json["head"].is_object() && sub_json["head"].is_object() &&
sub_json["head"].contains("message_type") && sub_json["head"].contains("message_type") &&
sub_json["head"]["message_type"].is_number_integer() && sub_json["head"]["message_type"].is_number_integer() &&
sub_json["head"]["message_type"].get<int>() == 3){ sub_json["head"]["message_type"].get<int>() == 3){
std::cout<<"发送成功123"<<std::endl;
std::string device_local_label_id=g_device_tag_t.find(sub_topic); std::string device_local_label_id=g_device_tag_t.find(sub_topic);
int tag_id_num_int = std::stoi(device_local_label_id);
if(device_local_label_id!="empty"){ if(device_local_label_id!="empty"){
std::cout<<"发送成123功"<<std::endl; positioningMapData bind_tag_send_data_t = {
// 使用全局的 g_mqtt_handler 来发布 .id = tag_id_num_int,
.resWidth = 500,
.resHeight = 500,
.resX = x_local[tag_id_num_int],
.resY = y_local[tag_id_num_int],
.resZ = 0
};
g_positioning_data_t=bind_tag_send_data_t;
std::cout<<"发送成功"<<std::endl;
g_mqtt_handler->publish(final_publish_topic, transfor_json(g_positioning_data_t));
//使用全局的 g_mqtt_handler 来发布
//mqtt_handler->PublishJson(final_publish_topic, root_json); //mqtt_handler->PublishJson(final_publish_topic, root_json);
} }
} }
...@@ -147,6 +174,7 @@ std::shared_ptr<MqttTopicsHandler> mqtt_init_and_connect() { ...@@ -147,6 +174,7 @@ std::shared_ptr<MqttTopicsHandler> mqtt_init_and_connect() {
int main(int argc, char* argv[]) { int main(int argc, char* argv[]) {
// 注册信号处理 // 注册信号处理
//signal(SIGTERM, signalHandler);
signal(SIGINT, signalHandler); signal(SIGINT, signalHandler);
// 初始化 tag_id // 初始化 tag_id
...@@ -181,34 +209,10 @@ int main(int argc, char* argv[]) { ...@@ -181,34 +209,10 @@ int main(int argc, char* argv[]) {
// 发送开始连续读取的指令 // 发送开始连续读取的指令
g_serial_port->send(cmd_continuous); g_serial_port->send(cmd_continuous);
std::cout << "已发送连续读取指令到串口设备。" << std::endl; std::cout << "已发送连续读取指令到串口设备。" << std::endl;
while(1){
// --- 3. 主循环:从串口获取数据并通过 MQTT 发布 --- std::this_thread::sleep_for(std::chrono::milliseconds(300));
std::cout << "进入主循环,将通过 MQTT 发布数据..." << std::endl;
while (true) {
// 遍历所有标签,检查是否有新数据并发布
for (int current_id : tag_id) {
// 这里可以添加一个逻辑,比如只发布坐标有变化的数据
// 为简化,我们每次都发布
TankWarMapData tank_data = {
.id = current_id,
.type = "tank",
.resWidth = 500,
.resHeight = 500,
.resX = x_local[current_id],
.resY = y_local[current_id],
.resZ = 0,
};
nlohmann::json root_json;
root_json["body"] = tank_data;
root_json["head"] = {{"message_type", 1}};
}
// 每秒发布一次所有标签的数据
std::this_thread::sleep_for(std::chrono::seconds(1));
} }
return 0; // 正常情况下不会执行到这里 return 0; // 正常情况下不会执行到这里
} }
\ No newline at end of file
...@@ -17,6 +17,7 @@ SerialPort::SerialPort(const std::string& port_name) ...@@ -17,6 +17,7 @@ SerialPort::SerialPort(const std::string& port_name)
stop_listener_(false) {} stop_listener_(false) {}
SerialPort::~SerialPort() { SerialPort::~SerialPort() {
send(_stop_serial_modbus);
close(); close();
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment