前言:#
最近在写使用UE4联动“六轴平台”的控制程序,这里就用到了机器硬件交互和计算机网络相关的知识。拿到硬件厂商的网络协议后,就要根据协议编写相关代码,下面记录一下开发过程。
网络字节序:
首先要明白和机器通讯中所传输的数据一般为字节流,即网络字节序,顾名思义就是字节的顺序。一般系统都会采用 UDP协议,UDP的好处就是机器只管接收就行。
进行 UDP广播:
在开始前,你需要了解如何使用UE4进行 UDP广播数据,你可以参考这篇文章“使用UE4原生模块进行简单UDP广播和数据接收”。
float转字节序:
直接上代码:这个函数可以将float类型的数据转为unsigned char类型的数组。
/*
- Describe:将float类型数据转换为unsigned char数组(即网络字节序)
- Paramfvalue待转换数据
- Paramarr传入的字节序
- ParamIndex从数组的第几位开始转换,默认为0
**/
1
2
3
4
|
void AUDPSend::ftoc(float fvalue, int Index, unsigned char* arr)
{
unsigned char* pf;
unsigned char* px;
|
unsigned char i; //计数器
pf = (unsigned char*)&fvalue; /unsigned char型指针取得浮点数的首地址/
px = arr; /字符数组arr准备存储浮点数的四个字节,px指针指向字节数组arr/
for (i = Index; i < Index + 4; i++)
{
*(px + i) = *(pf + (i - Index)); /使用unsigned char型指针从低地址一个字节一个字节取出/
}
示例:
1、假设一个六维平台采用的是 UDP协议,且接收的数据结构如下:
USTRUCT(BlueprintType)
1
2
3
4
5
6
7
8
9
10
11
12
13
|
struct FDataToVice
{
GENERATED_USTRUCT_BODY()
UPROPERTY(EditDefaultsOnly, BlueprintReadWrite, Category = "DataToVice")
int sMark = 55;
UPROPERTY(EditDefaultsOnly, BlueprintReadWrite, Category = "DataToVice")
int sComd = 0;
int sRepa[2] = { 0 };
float sAtti[6];
float sVelo[6] = { 0 };
float sAcce[3] = { 0 };
};
|
2、进行 UDP广播之前,应该先构造需要广播的数据。意思就是将结构体中的数据转为字节流。
创建一个“unsigned char”类型数组:
unsigned char ViceData[64] = {0};
用于构造数据的函数如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
|
void AUDPSend::MakeViceData(FTransform Transform_, FDataToVice DataToVice_)
{
DataToVice_.sAtti[0] = Transform_.Rotator().Pitch;
DataToVice_.sAtti[1] = Transform_.Rotator().Yaw;
DataToVice_.sAtti[2] = Transform_.Rotator().Roll;
DataToVice_.sAtti[3] = Transform_.GetTranslation().X;
DataToVice_.sAtti[4] = Transform_.GetTranslation().Y;
DataToVice_.sAtti[5] = Transform_.GetTranslation().Z;
ViceData[0] = DataToVice_.sMark;
ViceData[1] = DataToVice_.sComd;
ViceData[2] = DataToVice_.sRepa[0];
ViceData[3] = DataToVice_.sRepa[1];
//float Vector_X = Transform_.GetTranslation().X;
//ftoc(Vector_X, 4, ViceData);
ftocLoop(DataToVice_.sAtti, 4, 6, ViceData);
ftocLoop(DataToVice_.sVelo, 28, 6, ViceData);
ftocLoop(DataToVice_.sAcce, 52, 3, ViceData);
}
void AUDPSend::ftocLoop(float Value[],int BeginIndex, int length, unsigned char* arr)
{
for (int i = 0; i < length; i++)
{
ftoc(Value[i], BeginIndex, ViceData);
BeginIndex += 4;
}
}
|
开始UDP广播数据:(建议先阅读文章“使用UE4原生模块进行简单UDP广播和数据接收”)
在蓝图中先调用“构造数据的函数MakeViceData”,再调用函数“SendUDPMessages”就可以开始广播数据了
1
2
3
4
5
6
7
8
9
|
bool AUDPSend::SendUDPMessages(FString ToSend)
{
if (!SenderSocket)
{
//ScreenMsg("No sender socket");
return false;
}
int32 BytesSent = 0;
|
SenderSocket->SendTo(ViceData, 64, BytesSent, *RemoteAddr);//发送给远端地址
if (BytesSent <= 0)
{
1
2
3
4
5
6
7
8
|
const FString Str = "Socket is valid but the receiver received 0 bytes, make sure it is listening properly!";
UE_LOG(LogTemp, Error, TEXT("%s"), *Str);
ScreenMsg(Str);
return false;
}
return true;
}
|
使用网络抓包工具查看网络中的字节数据:#
可以使用网络抓包工具对网络中的数据进行查看,网上这种工具很多,我这里使用的是“NetAssist”,(安装包放在了文章结尾处的百度云链接中,见资源01)。
下载好直接运行即可,UDP开始广播后,输入对应的 IP和端口,开始监听就可以看到数据了。如图1-1所示:
图1-1
参考链接:#
https://blog.csdn.net/u013457167/article/details/78323298
资源链接:#
链接:https://pan.baidu.com/s/1RB_fYao2CCyNeKao5L3p8Q
提取码:Mcao