मैं अभी TwinCAT3 में अपने मूल पायथन सॉकेट रीडिंग कोड को स्ट्रक्चर टेक्स्ट में बदलने की कोशिश कर रहा हूं। निम्नलिखित मूल पायथन कोड है जो read_data = socket.recv(1116) डेटा को अलग-अलग चीजों में अनपैक करता है:

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')

पायथन कोड के अनुसार, मैंने एक सॉकेट कनेक्शन लिखा है और ट्विनकैट 3 में फ़ंक्शन ब्लॉक पढ़ा है। हालाँकि, मैं अभी डेटा एन्कोडिंग करने में कुछ समस्या का सामना कर रहा हूँ:

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 के बीच का रूपांतरण भी।

धन्यवाद!

1
Harry 18 अगस्त 2021, 09:40
हो सकता है कि आप पहले से ही पाइथन कोड में वास्तविक रूपांतरण के लिए बाइट कर सकें। ऐसा लगता है कि पायथन कोड पहले से ही moment और joint_p चर के साथ विशिष्ट है। ऐरे स्लाइसिंग यानी DataReceived[(i+204)..(i+212)] के संबंध में, यह ट्विनकैट में संभव नहीं है। विशिष्ट मान प्राप्त करने के लिए आपको लूप के लिए उपयोग करना होगा।
 – 
Roald
18 अगस्त 2021, 10:01
मैं अजगर को नहीं जानता। यह बाइट्स को किसी संख्या में कैसे स्थानांतरित करता है? क्या यह एक डबल नंबर का बाइट प्रतिनिधित्व है? या यह पायथन में कैसे परिवर्तित होता है? या क्या आप चाहते हैं कि बाइट एक वास्तविक में लिखी गई संख्या का प्रतिनिधित्व करे?
 – 
Uwe Hafner
18 अगस्त 2021, 12:36
आपके जवाब के लिए धन्यवाद। पायथन अनपैक फ़ंक्शन बाइट्स को डबल में स्थानांतरित कर देगा क्योंकि घोषणा ">d" है। मैंने सोचा था कि आपको ट्विनकैट समस्या का एहसास नहीं होगा इसलिए मैंने इसकी व्याख्या नहीं की। उसके लिए खेद है। मुख्य मुद्दा यह हो सकता है कि मैं संरचना पाठ कोडिंग से परिचित नहीं हूँ।
 – 
Aries
18 अगस्त 2021, 12:47
वाह, मुझे यह बताने के लिए धन्यवाद कि संरचना पाठ में इस तरह की सरणी को अनुक्रमित करने की अनुमति नहीं है। यह काटने के लिए वास्तव में एक अच्छा बिंदु हो सकता है।
 – 
Aries
18 अगस्त 2021, 12:49
जैसा कि @Roald ने कहा था कि आपको एकल बाइट्स लेते हुए सरणी तक पहुँचने के लिए कोड लिखना होगा और उन्हें अपने LREAL में स्थानांतरित करना होगा। यही कारण है कि मैं पूछ रहा था कि बाइट्स का द्विआधारी प्रतिनिधित्व क्या दोहरे मूल्यों में स्थानांतरित हो रहा था? क्योंकि आप 9 बाइट्स (204..212) को एक वास्तविक में परिवर्तित कर रहे हैं जिसमें केवल 8 बाइट्स हैं।
 – 
Uwe Hafner
18 अगस्त 2021, 13:12

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
3
kolyur 18 अगस्त 2021, 15:16
आपके द्वारा दिए गए उत्तर के अनुसार, मुझे कुछ प्रश्न मिले हैं आशा है कि आप मुझे हल करने में मदद कर सकते हैं। सरल कोड नमूने के अनुसार, मैं LREAL और BYTE सरणी के बीच प्रकार परिवर्तन के बारे में उत्सुक हूं। तो memcpy फ़ंक्शन बाइट को वांछित पते पर कॉपी कर देगा और पते का डेटा प्रकार स्वचालित रूप से सेट हो जाएगा?
 – 
Aries
18 अगस्त 2021, 16:03
1
इस कोड के साथ यही समस्या है। यह एक मेमोरी सेक्शन लेता है और सामग्री को दूसरे मेमोरी सेक्शन में कॉपी करता है। क्योंकि गंतव्य स्मृति खंड को पीएलसी के लिए एक वास्तविक खंड के रूप में परिभाषित किया गया है, यह स्मृति सामग्री को एलआरईएल के रूप में व्याख्या करता है। मेरे उत्तर में मैं यह मान रहा हूं कि जिस बाइट क्रम में आपको जानकारी प्राप्त होती है वह वही है जो लक्ष्य पर कॉपी की जाती है। Memcpy प्रकारों के बारे में कुछ नहीं जानता। यह केवल बिट्स और बाइट्स को कॉपी करता है।
 – 
Uwe Hafner
18 अगस्त 2021, 16:38
1
memcpy कोड तब तक काम करेगा जब तक आपका इनपुट डेटा IEEE754 प्रारूप को बनाए रखते हुए 8 बाइट्स में विभाजित वास्तविक 64-बिट फ्लोटिंग पॉइंट मान है। ऐसा लगता है कि आपकी मूल पोस्ट में कोड बाइट्स को अलग-अलग ASCII वर्णों (BYTEARR_TO_MAXSTRING) के रूप में व्याख्या कर रहा है जो काफी अलग है।
 – 
kolyur
18 अगस्त 2021, 16:58