0119

news/2026/1/19 20:13:39/文章来源:https://www.cnblogs.com/aultcarius/p/19503554

好的,明白了!根据你的确认,我来提供完整的实现代码。

完整修改方案

一、UdpSocketServer.h 修改

在文件中添加以下内容:

1. 添加委托声明(在现有委托声明区域,建议放在 FOnMissileGroupDataReceived 之后)

DECLARE_DYNAMIC_MULTICAST_DELEGATE_FiveParams(FOnLoiteringMunitionGroupDataReceived, const TArray<uint8>&, MunitionIds, const TArray<uint8>&, MunitionTypes, const TArray<uint8>&, MunitionStates, const TArray<FVector>&, MunitionPositions,const TArray<FRotator>&, MunitionRotations
);

2. 添加委托实例(在public区域,建议放在 OnMissileGroupDataReceived 之后)

UPROPERTY(BlueprintAssignable, Category = "UDP Loitering Munition Delegate")
FOnLoiteringMunitionGroupDataReceived OnLoiteringMunitionGroupDataReceived;

3. 添加解析函数声明(在 ParseMissileGroupData 之后)

void ParseLoiteringMunitionGroupData(const TArray<uint8>& Data, FString& OutStr);

二、UdpSocketServer.cpp 修改

1. 在 DataRecv 函数的 switch 语句中添加 case 5

找到 DataRecv 函数中的 switch 语句,在 case 4 之后添加:

case 5:
{FString DebugStr;ParseLoiteringMunitionGroupData(ReceivedData, DebugStr);str = DebugStr;success = true;break;
}

2. 实现 ParseLoiteringMunitionGroupData 函数

在文件末尾(建议放在 ParseMissileGroupData 函数之后)添加:

void UUdpSocketServer::ParseLoiteringMunitionGroupData(const TArray<uint8>& Data, FString& OutStr)
{int32 Offset = 1;uint8 MunitionCount = Data[Offset];Offset += 1;const int32 SingleMunitionDataSize = 51;  // 1(ID) + 1(Type) + 1(State) + 24(Position) + 24(Rotation)if ((Data.Num() - Offset) < (MunitionCount * SingleMunitionDataSize)){UE_LOG(LogTemp, Warning, TEXT("Insufficient data for loitering munition group. munition count: %d, hope length: %d, fact length: %d"),MunitionCount, Offset + MunitionCount * SingleMunitionDataSize, Data.Num());OutStr = TEXT("Error: Insufficient data for loitering munition group");return;}TArray<uint8> MunitionIds;TArray<uint8> MunitionTypes;TArray<uint8> MunitionStates;TArray<FVector> MunitionPositions;TArray<FRotator> MunitionRotations;FString GroupStr = TEXT("Loitering Munition Group: ");for (int32 i = 0; i < MunitionCount; ++i){uint8 MunitionId = Data[Offset];uint8 MunitionType = Data[Offset + 1];uint8 MunitionState = Data[Offset + 2];// 解析位置double X = 0, Y = 0, Z = 0;FMemory::Memcpy(&X, &Data[Offset + 3], sizeof(double));FMemory::Memcpy(&Y, &Data[Offset + 11], sizeof(double));FMemory::Memcpy(&Z, &Data[Offset + 19], sizeof(double));// 解析姿态double Yaw = 0, Pitch = 0, Roll = 0;FMemory::Memcpy(&Yaw, &Data[Offset + 27], sizeof(double));FMemory::Memcpy(&Pitch, &Data[Offset + 35], sizeof(double));FMemory::Memcpy(&Roll, &Data[Offset + 43], sizeof(double));FVector Position(static_cast<float>(X), static_cast<float>(Y), static_cast<float>(Z));FRotator Rotation(static_cast<float>(Pitch), static_cast<float>(Yaw), static_cast<float>(Roll));GroupStr += FString::Printf(TEXT("[ID: %d, Type: %d, State: %d, Pos: %s, Rot: %s] "),MunitionId, MunitionType, MunitionState, *Position.ToString(), *Rotation.ToString());Position = ConvertUEOffset(Position);if (MunitionId > 0)  // 0 为无效巡飞弹{MunitionIds.Add(MunitionId);MunitionTypes.Add(MunitionType);MunitionStates.Add(MunitionState);MunitionPositions.Add(Position);MunitionRotations.Add(Rotation);}Offset += SingleMunitionDataSize;}OutStr = GroupStr;if (bIsLogReceivedPackage)UE_LOG(LogTemp, Warning, TEXT("the data parse loitering munition group is: %s"), *OutStr);// 广播委托OnLoiteringMunitionGroupDataReceived.Broadcast(MunitionIds, MunitionTypes, MunitionStates, MunitionPositions, MunitionRotations);
}

三、Python 测试脚本

创建一个测试脚本来验证功能:

import socket
import struct
import timedef send_loitering_munition_group(sock, target_ip, target_port, munitions_data):"""发送巡飞弹组数据munitions_data: list of dict, 每个dict包含 id, type, state, position(x,y,z), rotation(yaw,pitch,roll)"""message_type = 5munition_count = len(munitions_data)# 构建数据包packet = struct.pack('BB', message_type, munition_count)for munition in munitions_data:# 基本信息: ID, Type, Statepacket += struct.pack('BBB', munition['id'], munition['type'], munition['state'])# 位置: X, Y, Z (double)packet += struct.pack('ddd', munition['position'][0],munition['position'][1],munition['position'][2])# 姿态: Yaw, Pitch, Roll (double)packet += struct.pack('ddd',munition['rotation'][0],  # Yawmunition['rotation'][1],  # Pitchmunition['rotation'][2])  # Rollsock.sendto(packet, (target_ip, target_port))print(f"发送巡飞弹组数据: {munition_count} 个巡飞弹")print(f"数据包大小: {len(packet)} 字节")# 测试代码
if __name__ == "__main__":# 配置TARGET_IP = "127.0.0.1"  # 修改为你的目标IPTARGET_PORT = 8888        # 修改为你的目标端口# 创建UDP socketsock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)# 测试数据:3个巡飞弹test_munitions = [{'id': 1,'type': 1,'state': 0,'position': [100.0, 200.0, 50.0],'rotation': [45.0, 10.0, 5.0]  # Yaw, Pitch, Roll},{'id': 2,'type': 2,'state': 1,'position': [150.0, 250.0, 60.0],'rotation': [90.0, 15.0, -5.0]},{'id': 3,'type': 1,'state': 0,'position': [200.0, 300.0, 70.0],'rotation': [135.0, 20.0, 0.0]}]try:while True:send_loitering_munition_group(sock, TARGET_IP, TARGET_PORT, test_munitions)# 更新位置和姿态(模拟移动)for munition in test_munitions:munition['position'][0] += 1.0munition['position'][1] += 0.5munition['rotation'][0] = (munition['rotation'][0] + 1) % 360time.sleep(0.1)  # 100ms发送一次except KeyboardInterrupt:print("\n停止发送")finally:sock.close()

四、修改总结

修改的文件:

  1. UdpSocketServer.h - 添加委托和函数声明
  2. UdpSocketServer.cpp - 添加解析逻辑

关键点:

  • ✅ 复用 NumMissilesPerPacket 配置
  • ✅ 使用消息类型 5
  • ✅ 数据包格式:1(消息类型) + 1(数量) + N×51(每个巡飞弹数据)
  • ✅ 仅实现 Group 版本
  • ✅ 包含位置和姿态数据
  • ✅ 支持坐标转换 ConvertUEOffset

数据包结构:

[消息类型:1字节] [数量:1字节] [巡飞弹1数据:51字节] [巡飞弹2数据:51字节] ...每个巡飞弹数据(51字节):
- ID: 1字节
- Type: 1字节  
- State: 1字节
- Position X: 8字节(double)
- Position Y: 8字节(double)
- Position Z: 8字节(double)
- Yaw: 8字节(double)
- Pitch: 8字节(double)
- Roll: 8字节(double)

这样修改后,你就可以在蓝图中订阅 OnLoiteringMunitionGroupDataReceived 委托来接收和处理巡飞弹数据了!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/1184857.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

基于vue和python的酒店客房预订管理系统

目录系统概述技术架构核心功能创新与优势应用价值开发技术路线相关技术介绍核心代码参考示例结论源码lw获取/同行可拿货,招校园代理 &#xff1a;文章底部获取博主联系方式&#xff01;系统概述 该系统基于Vue.js前端框架和Python后端技术&#xff0c;构建了一个高效、用户友好…

基于python+Vue的学生交流互助平台 学习兴趣小组任务打卡系统8y1o61qk

目录项目概述核心功能模块技术实现亮点应用场景与价值开发技术路线相关技术介绍核心代码参考示例结论源码lw获取/同行可拿货,招校园代理 &#xff1a;文章底部获取博主联系方式&#xff01;项目概述 PythonVue学生交流互助平台结合学习兴趣小组任务打卡系统&#xff08;8y1o61…

亚马逊买家号常见异常解析:为什么账号会逐步受限?

在亚马逊运营过程中&#xff0c;很多卖家都会遇到一种“说不清原因”的情况&#xff1a; 账号可以正常登录和浏览&#xff0c;但加购异常、下单失败&#xff0c;甚至广告点击后没有任何效果。表面上看账号仍然可用&#xff0c;实际上往往已经进入平台的观察或限制阶段。 这些问…

Doris数据过期策略:自动清理历史数据

Doris数据过期策略&#xff1a;自动清理历史数据关键词&#xff1a;Doris、数据过期策略、自动清理、历史数据、数据管理摘要&#xff1a;本文主要介绍了Doris的数据过期策略&#xff0c;也就是如何实现自动清理历史数据。我们会先了解相关背景知识&#xff0c;再解释核心概念&…

如何高效管理项目需求变更?实战技巧与方法解析

频繁的需求变更不仅是技术问题&#xff0c;更是对团队沟通、评估机制和执行节奏的全面考验。本文围绕需求变更管理的核心话题展开&#xff0c;从评估、分类、执行到团队协作逐步剖析&#xff0c;并结合实际工具实践建议&#xff0c;帮助项目经理、团队负责人、PMO构建高效变更管…

基于vue和python的医院预约挂号系统的设计与实现

目录医院预约挂号系统的设计与实现开发技术路线相关技术介绍核心代码参考示例结论源码lw获取/同行可拿货,招校园代理 &#xff1a;文章底部获取博主联系方式&#xff01;医院预约挂号系统的设计与实现 该系统基于Vue.js前端框架和Python后端技术&#xff0c;构建了一个高效、便…

python基于vue的积分制零食商城自选平台 (三端:管理端+用户PC端+用户小程序端)

目录项目概述核心功能模块技术实现亮点应用场景与价值开发技术路线相关技术介绍核心代码参考示例结论源码lw获取/同行可拿货,招校园代理 &#xff1a;文章底部获取博主联系方式&#xff01;项目概述 该项目为基于Python后端与Vue前端开发的积分制零食商城自选平台&#xff0c;…

【 每天学习一点算法 2026/01/19】位1的个数

每天学习一点算法 2026/01/19 题目&#xff1a;位1的个数 给定一个正整数 n&#xff0c;编写一个函数&#xff0c;获取一个正整数的二进制形式并返回其二进制表达式中 设置位 的个数&#xff08;也被称为汉明重量&#xff09;。 最容易想到的方法就是&#xff0c;遍历二进制字…

【机翼】三维机翼几何进行耦合静态气弹性分析Matlab仿真

✅作者简介&#xff1a;热爱科研的Matlab仿真开发者&#xff0c;擅长数据处理、建模仿真、程序设计、完整代码获取、论文复现及科研仿真。&#x1f34e; 往期回顾关注个人主页&#xff1a;Matlab科研工作室&#x1f447; 关注我领取海量matlab电子书和数学建模资料 &#x1f34…

创客匠人视角:创始人 IP 与智能体的协同范式革命,重新定义知识变现的价值边界

当千问 APP 实现 “一句话点外卖、订机票” 的落地场景&#xff0c;当春晚将 AI 作为全链路技术基础设施&#xff0c;一个明确的信号已然显现&#xff1a;AI 行业已从 “会聊天” 的交互时代&#xff0c;正式迈入 “能干活” 的协同时代。在知识变现领域&#xff0c;这场变革的…

python基于人脸识别的互联网课堂学生考勤系统

目录基于人脸识别的互联网课堂学生考勤系统摘要开发技术路线相关技术介绍核心代码参考示例结论源码lw获取/同行可拿货,招校园代理 &#xff1a;文章底部获取博主联系方式&#xff01;基于人脸识别的互联网课堂学生考勤系统摘要 随着在线教育的普及&#xff0c;传统考勤方式如手…

计算机毕业设计springboot基于Java的网上花店系统 计算机毕业设计springboot基于Java的网上花店系统 Java技术驱动的Spring Boot网上花店平台开发

计算机毕业设计springboot基于Java的网上花店系统0k4sm &#xff08;配套有源码 程序 mysql数据库 论文&#xff09; 本套源码可以在文本联xi,先看具体系统功能演示视频领取&#xff0c;可分享源码参考。 随着互联网的飞速发展&#xff0c;电子商务已经成为人们生活中不可或缺…

创客匠人深度解析:创始人 IP 打造的智能体基建逻辑,重构知识变现底层规则

2026 年春晚将 AI 纳入全链路技术基础设施的重磅决策&#xff0c;向所有行业释放了明确信号&#xff1a;智能时代的竞争核心&#xff0c;已从 “是否使用 AI 工具” 升级为 “是否建成 AI 基础设施”。在知识变现领域&#xff0c;创始人 IP 作为核心载体&#xff0c;正普遍面临…

【图像融合】基于小波变换红外和可见光图像融合(含评价指标)附Matlab代码

✅作者简介&#xff1a;热爱科研的Matlab仿真开发者&#xff0c;擅长数据处理、建模仿真、程序设计、完整代码获取、论文复现及科研仿真。&#x1f34e; 往期回顾关注个人主页&#xff1a;Matlab科研工作室&#x1f447; 关注我领取海量matlab电子书和数学建模资料 &#x1f34…

python基于大数据的自助餐厅菜品供应优化与分析预测系统 数据分析可视化大屏系统e8737qr2

目录项目背景核心功能技术栈应用成效开发技术路线相关技术介绍核心代码参考示例结论源码lw获取/同行可拿货,招校园代理 &#xff1a;文章底部获取博主联系方式&#xff01;项目背景 随着餐饮行业数字化转型加速&#xff0c;自助餐厅需通过大数据技术优化菜品供应、减少浪费并提…

三维动态避障路径规划:基于山羊优化算法(Goat Optimization Algorithm, GOA)融合动态窗口法DWA的无人机三维动态避障方法研究附MATLAB代码

✅作者简介&#xff1a;热爱科研的Matlab仿真开发者&#xff0c;擅长数据处理、建模仿真、程序设计、完整代码获取、论文复现及科研仿真。 &#x1f34e; 往期回顾关注个人主页&#xff1a;Matlab科研工作室 &#x1f447; 关注我领取海量matlab电子书和数学建模资料 &#…

创客匠人洞察:智能体重构 IP 变现逻辑,创始人 IP 如何实现从 “单次付费” 到 “终身价值”

当 AI 从 “会聊天” 进化到 “能干活”&#xff0c;知识变现行业正经历一场深刻的范式革命。过去&#xff0c;创始人 IP 变现的核心是 “卖内容”&#xff1b;如今&#xff0c;智能体让 IP 变现的核心升级为 “卖价值”—— 从一次性的课程售卖&#xff0c;转向持续的用户价值…

WebDataset使用指南:构建高效深度学习数据管道

在深度学习项目实践中,数据加载往往成为限制训练速度的关键瓶颈。当数据集规模达到数百万甚至数十亿样本时,传统的文件系统随机访问方式会导致I/O效率急剧下降,让昂贵的GPU资源处于闲置等待状态。WebDataset通过流式…

Transformer完全入门指南:从零开始理解

Transformer完全入门指南&#xff1a;从零开始理解Transformer完全入门指南&#xff1a;从零开始理解一、Transformer是什么&#xff1f;&#xff08;一句话解释&#xff09;二、为什么需要Transformer&#xff1f;1. RNN/LSTM的问题2. Transformer的解决方案三、Transformer的…

2026 年适合追剧吃的零食推荐、挑选技巧与选购指南(我常备的“追剧薯条”是浪味仙) - Top品牌推荐

结论 追剧零食的核心不是“多贵多好”,而是能长时间顺手吃、口感稳定、碎屑少、口味不容易腻。如果你偏爱“越看越上头”的膨化口感,我个人更常回购的是旺旺旗下的浪味仙(马铃薯膨化薯条/螺旋薯卷):它的DNA 双螺旋…