• ur机械臂30003端口socket通信踩坑(double类型数据怎么解析)


    坑的由来

    • 都知道在网络通信时要把网络字节序转化为主机字节序才行,但是c++里的标准库函数ntohl默认是转换32位字节序的数据,也就是说默认是转换float类型的数据;
    • 而ur机械臂30003端口发送的是double类型的数据,没法直接用ntohl进行转换。

    小贴士

    • float是4字节,32位;double是8字节,64位。
    • 在网络传输中,数据通常以字节为单位进行编码,这种编码方式被称为网络字节序,它主要用于确保数据在不同主机之间传输时不会受到主机不同字节序的影响。
    • 网络字节序采用大端模式,即高位字节在前,低位字节在后。
    • 而主机字节序则可能因主机的不同而有所差异,常见的有两种:大端模式和小端模式。小端模式的主机字节序低位字节在前,高位字节在后,与人的直观感受相符。

    解决办法

    需要自己编写一个函数做这个转换,以下是一种方式:

    double ntohd(double netDouble)
     {
      uint64_t netInt = be64toh(*((uint64_t*)&netDouble));
      return *((double*)&netInt);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5

    逐行解析一下:

    uint64_t netInt = be64toh(*((uint64_t*)&netDouble));
    
    • 1

    这句话做了:

    • &netDouble: 获取 netDouble 的内存地址。
    • (uint64_t*)&netDouble: 将该地址强制转换为 uint64_t 类型的指针。这是为了将双精度浮点数的内存表示视为一个64位的无符号整数。
    • *((uint64_t*)&netDouble): 通过解引用这个指针,我们得到了一个 uint64_t 类型的值,该值在内存中的表示与 netDouble 完全相同。
    • be64toh(...): 这是一个库函数,用于将64位的无符号整数从网络字节序(big-endian)转换为主机字节序。
    return *((double*)&netInt);
    
    • 1

    同理,这句话:

    • &netInt: 获取 netInt内存地址

    • (double*)&netInt: 将该地址强制转换为 double 类型的指针。这是为了将64位的无符号整数的内存表示视为一个双精度浮点数。

    • *((double*)&netInt): 通过解引用这个指针,我们得到了一个 double 类型的值,该值在内存中的表示与 netInt 完全相同。

    • 最后,这个值被返回。

    附录(ur机械臂30003端口机械臂法兰位姿数据解析)

    double x, y, z, rx, ry, rz;
    	char data[1140];
    	int recvLen = recv(socket_, data, 1140, 0);
        if (recvLen > 0) 
        {
            memcpy(&x,  data+444, sizeof(double));
            memcpy(&y,  data+452, sizeof(double));
    	    memcpy(&z,  data+460, sizeof(double));
    	    memcpy(&rx, data+468, sizeof(double));
    	    memcpy(&ry, data+476, sizeof(double));
    	    memcpy(&rz, data+484, sizeof(double));
            x = ntohd(x);
            y = ntohd(y);
            z = ntohd(z);
            rx = ntohd(rx);
            ry = ntohd(ry);
            rz = ntohd(rz);
           
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 上面的代码就是对ur机械臂30003端口机械臂法兰位姿的解析,如果将ntohd换成dtohl会解析出全是0的错误数据。
  • 相关阅读:
    DigiCert证书——银行官网的首选
    驱动开发之pinctrl 和 gpio 子系统
    Jenkins中强制停止停不下来的job
    Android 13.0 Launcher3 app图标长按去掉应用信息按钮
    微信管理系统
    java 利用geotools包对wkt格式数据进行操作
    仿函数的学习
    Vue----webStorage浏览器本地存储、localStorage、sessionStorage
    【 C++ 】智能指针
    【从0-1成为架构师】性能优化的手段
  • 原文地址:https://blog.csdn.net/m0_52785249/article/details/133679389