【问题标题】:How to convert byte array into various LREAL(double) values in TwinCAT3如何在 TwinCAT 3 中将字节数组转换为各种 L'OREAL(double) 值
【发布时间】:2021-08-18 06:40:17
【问题描述】:

我现在正试图将我原来的 python 套接字读取代码转换为 TwinCAT3 中的结构文本。 以下是将 read_data = socket.recv(1116) 数据解包成不同事物的原始 python 代码:

def ur_read(read_data):
    moment=[0,0,0,0,0,0]
    joint_p=[0,0,0,0,0,0]
    joint_v=[0,0,0,0,0,0]         
    tcp_p=[0,0,0,0,0,0]
    tcp_v=[0,0,0,0,0,0]
    tcp_force=[0,0,0,0,0,0]
    state=0
    time_new=0
    try:
        for i in range(len(read_data)):            
            if [read_data[i],read_data[i+1],read_data[i+2],read_data[i+3]] == [0,0,4,92]:
                time = struct.unpack('>d', read_data[i+4:i+12])
                moment[0], = struct.unpack('>d', read_data[i+204:i+212])
                moment[1], = struct.unpack('>d', read_data[i+212:i+220])
                moment[2], = struct.unpack('>d', read_data[i+220:i+228])
                moment[3], = struct.unpack('>d', read_data[i+228:i+236])
                moment[4], = struct.unpack('>d', read_data[i+236:i+244])
                moment[5], = struct.unpack('>d', read_data[i+244:i+252])
                joint_p[0], = struct.unpack('>d', read_data[i+252:i+260])
                joint_p[1], = struct.unpack('>d', read_data[i+260:i+268])
                joint_p[2], = struct.unpack('>d', read_data[i+268:i+276])
                joint_p[3], = struct.unpack('>d', read_data[i+276:i+284])
                joint_p[4], = struct.unpack('>d', read_data[i+284:i+292])
                joint_p[5], = struct.unpack('>d', read_data[i+292:i+300])
                joint_v[0], = struct.unpack('>d', read_data[i+300:i+308])
                joint_v[1], = struct.unpack('>d', read_data[i+308:i+316])
                joint_v[2], = struct.unpack('>d', read_data[i+316:i+324])
                joint_v[3], = struct.unpack('>d', read_data[i+324:i+332])
                joint_v[4], = struct.unpack('>d', read_data[i+332:i+340])
                joint_v[5], = struct.unpack('>d', read_data[i+340:i+348])
                tcp_p[0], = struct.unpack('>d', read_data[i+444:i+452])
                tcp_p[1], = struct.unpack('>d', read_data[i+452:i+460])
                tcp_p[2], = struct.unpack('>d', read_data[i+460:i+468])
                tcp_p[3], = struct.unpack('>d', read_data[i+468:i+476])
                tcp_p[4], = struct.unpack('>d', read_data[i+476:i+484])
                tcp_p[5], = struct.unpack('>d', read_data[i+484:i+492])
                tcp_v[0], = struct.unpack('>d', read_data[i+492:i+500])
                tcp_v[1], = struct.unpack('>d', read_data[i+500:i+508])
                tcp_v[2], = struct.unpack('>d', read_data[i+508:i+516])
                tcp_v[3], = struct.unpack('>d', read_data[i+516:i+524])
                tcp_v[4], = struct.unpack('>d', read_data[i+524:i+532])
                tcp_v[5], = struct.unpack('>d', read_data[i+532:i+540])
                tcp_force[0], = struct.unpack('>d', read_data[i+540:i+548])
                tcp_force[1], = struct.unpack('>d', read_data[i+548:i+556])
                tcp_force[2], = struct.unpack('>d', read_data[i+556:i+564])
                tcp_force[3], = struct.unpack('>d', read_data[i+564:i+572])
                tcp_force[4], = struct.unpack('>d', read_data[i+572:i+580])
                tcp_force[5], = struct.unpack('>d', read_data[i+580:i+588])
                state,= struct.unpack('>d', read_data[i+1052:i+1060])  
                time_new, = struct.unpack('>d', read_data[i+4:i+12])
                break
    except:
        print('exp')

根据python代码,我在TwinCAT3中写了一个socket连接和读取功能块。但是,我现在在进行数据编码时遇到了一些问题:

FUNCTION_BLOCK DataEncoding
VAR_INPUT
    DataReceived: ARRAY[0..1115] OF BYTE;
END_VAR
VAR_OUTPUT
    moment: ARRAY[0..5] OF LREAL := [6(0.0)]; // LREAL stands for Double
    joint_pos: ARRAY[0..5] OF LREAL := [6(0.0)];
    joint_vel: ARRAY[0..5] OF LREAL := [6(0.0)];
    tcp_pos: ARRAY[0..5] OF LREAL := [6(0.0)];
    tcp_vel: ARRAY[0..5] OF LREAL := [6(0.0)];
    tcp_force: ARRAY[0..5] OF LREAL := [6(0.0)];
END_VAR
VAR
    i: INT;
    BYTEARR_to_STRING: BYTEARR_TO_MAXSTRING;
END_VAR

在正文部分:

FOR i := 0 TO 1116 BY 1 DO
    IF DataReceived[i] = 0 AND DataReceived[i+1] = 0 AND DataReceived[i+2] = 4 AND 
    DataReceived[i+3] = 92
        moment[0] := TO_LREAL(BYTEARR_to_STRING(in:= DataReceived[(i+204)..(i+212)]));
    END_IF
END_FOR

我遇到的问题是不知道怎么写字节数组和LREAL之间的转换。此外, DataReceived[(i+204)..(i+212)] 的数组索引似乎有一些错误。谁能教我如何在 ARRAY[0..1115] 中索引特定部分,如(204 到 212)?还有字节数组和LREAL的转换。

谢谢!

【问题讨论】:

  • 也许您已经可以在 python 代码中进行字节到 lreal 的转换。似乎 Python 代码已经特定于 momentjoint_p 变量。关于数组切片,即DataReceived[(i+204)..(i+212)],这在 TwinCAT 中是不可能的。您必须使用 for 循环来获取特定值。
  • 我不懂python。它如何将字节转换为数字?它是双数的字节表示吗?或者它如何在python中转换?还是要将字节表示的数字写入 lreal?
  • @UweHafner 感谢您的回复。 python unpack 函数会将字节转换为双精度,因为声明是“>d”。我以为你意识到 TwinCAT 问题不会是你的问题,所以我没有解释它。对此感到抱歉。主要问题可能是我不熟悉结构文本编码。
  • @Roald 哇,谢谢你告诉我在结构文本中不允许像那样索引数组。这可能是一个非常好的切入点。
  • 正如@Roald 所说,您必须编写代码才能自己访问数组,并获取单个字节并将它们传输到您的 LREAL。这就是为什么我要问什么字节的二进制表示正在转换为双精度值?因为您正在将 9 个字节 (204..212) 转换为仅包含 8 个字节的 lreal。

标签: python type-conversion twincat st


【解决方案1】:

您可以将字节复制到 LREAL。
ADR()是获取变量内存地址的函数:

FOR i := 0 TO 1116 BY 1 DO
    IF DataReceived[i] = 0 AND DataReceived[i+1] = 0 AND DataReceived[i+2] = 4 AND DataReceived[i+3] = 92 THEN
        memcpy(ADR(moment[0]), ADR(DataReceived[(i+204)]), 212-204);
    END_IF
END_FOR

【讨论】:

  • 根据您提供的答案,我有一些问题希望您能帮助我解决。根据简单的代码示例,我很好奇 LREAL 和 BYTE 数组之间的类型转换。那么memcpy函数会将字节复制到想要的地址,地址的数据类型会自动设置?
  • 这就是这段代码的问题。它需要一个内存部分并将内容复制到另一个内存部分。因为目标内存部分被定义为 PLC 的 LREAL 部分,所以它将内存内容解释为 LREAL。在我的回答中,我假设您接收信息的字节顺序与复制到目标的字节顺序相同。 Memcpy 对类型一无所知。它只复制位和字节。
  • memcpy 代码将工作,只要您的输入数据是实际的 64 位浮点值,拆分为 8 个字节,同时保持 IEEE754 格式。您原始帖子中的代码似乎将字节解释为单独的 ASCII 字符 (BYTEARR_TO_MAXSTRING),这是完全不同的。
猜你喜欢
  • 1970-01-01
  • 2018-12-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-12-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多