Tcopen: الاتفاقيات

تم إنشاؤها على ٣٠ أكتوبر ٢٠٢٠  ·  31تعليقات  ·  مصدر: TcOpenGroup/TcOpen

وثيقة الاتفاقيات هنا

الرجاء المساهمة في المناقشة أدناه

  • دعونا نحافظ على المناقشات هنا للتتبع.
  • محادثات سريعة هنا:TcOpen Slack

  • [] اصطلاحات تسمية المتغيرات (VAR ، VAR_INPUT ، VAR_OUTPUT ، VAR_IN_OUT ، VAR_INST ، TEMP)

  • [] اصطلاح التسمية للأساليب
  • [] اصطلاح تسمية الخصائص
  • [] اصطلاح تسمية الكتل (FB ، FC ، PRG وما إلى ذلك)
discussion

التعليق الأكثر فائدة

سيكون لدي اقتراح حول المصفوفات. هناك مطلب رسمي لمترجم inxton وهو أن المصفوفات العابرة للأكوام التي تعتمد على الصفر فقط. والسبب هو منع الالتباس عند استخدامها في C #.

_array: صفيف [0..10] من BOOL ؛ // عبر أكوام
في حين
_array: صفيف [1..10] من BOOL ؛ // لا يتحول

أي تعليق على هذا؟

ال 31 كومينتر

@ mark-lazarides @ Roald87philippleidigjozefchmelar دعونا نحافظ على المناقشة حول الاتفاقيات هنا ... Slack للدردشة السريعة ؛ المناقشات هنا لتتبع النشاط

  • في رأيي يجب تحديد الخصائص على النحو التالي "IsEnabled". يجب أن يشير الاسم نفسه بالفعل إلى نوعه.

  • أنا أحب القيمة المرجعة للطريقة على أنها منطقية. أجد أن أنواع البيانات الأكثر تعقيدًا غير مناسبة ، لأنه يجب إنشاء مثيل لها بالخارج أو إعادتها بالرجوع إليها.

  • إن وراثة كل فئة أساسية من "fbComponent" ضرورية لاستخدام Inxton أو tc.prober؟

  • عندما يتعلق الأمر بتسمية الكتابة ، فأنا شخصياً متطرف قليلاً وأتجاهل البادئات بشكل عام. باستثناء الواجهات والمراجع والمؤشرات.
    على سبيل المثال

    اكتب التسمية


| نوع الكتلة | تدوين | بادئة | مثال |
| : ------------- | : --------- | : ------------ | : ------------------------------------------------- - |
| اسم FB / CLASS | باسكال كيس | لا | Cyclinder |
| اسم نوع ENUM | باسكال كيس | لا | MachineState.Start |
| اسم الواجهة | باسكال كيس | I | ICyclinder |
| اسم الوظيفة | باسكال كيس | لا | Add() |
| اسم الهيكل | باسكال كيس | لا | Data |
| اسم الاتحاد | باسكال كيس | لا | Control |

تضمين التغريدة

  • في رأيي يجب تحديد الخصائص على النحو التالي "IsEnabled". يجب أن يشير الاسم نفسه بالفعل إلى نوعه.

موافق تماما.

  • أنا أحب القيمة المرجعة للطريقة على أنها منطقية. أجد أن أنواع البيانات الأكثر تعقيدًا غير مناسبة ، لأنه يجب إنشاء مثيل لها بالخارج أو إعادتها بالرجوع إليها.

نستخدمها كما هو موصوف مع مكوناتنا. إنه مفيد عند التحكم في حالة التسلسل. في الغالبية العظمى من الحالات يكفي منطقي. قد يكون من الجيد أحيانًا الحصول على مزيد من المعلومات حول حالة الطريقة ... ولكن هذا قد يحتاج إلى مناقشة أوسع (ربما بناء جملة بطلاقة مثل شيء ما)

  • إن وراثة كل فئة أساسية من "fbComponent" ضرورية لاستخدام Inxton أو tc.prober؟

لا ، ليس هناك متطلبات محددة لذلك ولا Inxton ولا tc.prober. نحن نستخدمه بهذه الطريقة. ComponentBase فئة مجردة بها بعض العقود العامة (الطريقة اليدوية ، إلخ) ، ولكن يمكنها تنفيذ بعض الميزات المشتركة للمكونات. أنا لست من أشد المعجبين بالميراث (أفضل التكوين) ، لكن في هذه الحالة أود أن يكون لدي خيار مفتوح للمستقبل.

في inxton ، إذا كنت ترغب في جمع كل المكونات في مجموعة ، يمكنك القيام بذلك عندما تكون هناك آلية لذلك something is copmonent .

هناك سبب آخر لذلك. نحن نعمل هذه اليوم على مصادر مفتوحة لمكتبتنا الأساسية ، والتي لها بعض المتطلبات فيما يتعلق. آمل أن أتمكن من الخروج بشيء الأسبوع المقبل. لإعطائك المزيد من التفاصيل.

  • عندما يتعلق الأمر بتسمية الكتابة ، فأنا شخصياً متطرف قليلاً وأتجاهل البادئات بشكل عام. باستثناء الواجهات والمراجع والمؤشرات.
    على سبيل المثال

اكتب التسمية

مثال على بادئة نوع التدوين
اسم FB / CLASS PascalCase رقم Cyclinder
اسم نوع ENUM PascalCase رقم MachineState.Start
اسم الواجهة PascalCase I ICyclinder
اسم الوظيفة PascalCase رقم Add()
اسم الهيكل PascalCase No Data
اسم الاتحاد باسكال كيس رقم Control

لست من محبي البادئات أيضًا. الجدول يشبه نظام البادئات الذي نستخدمه ... ولكن مرة أخرى إذا قررنا التخلص من هذا ، فسوف يجعلني سعيدًا.

في معظم الحالات لا أرى فائدة في استخدام البادئات. أوافق على اقتراح philippleidig .

أود أن أقول أن المؤشر والمرجع هما استثناء هنا.

لقد اقترحت اتفاقياتي في PR # 5

تسمية الأعضاء وتسمية النوع

لا أرى فائدة في استخدام البادئة. لا يساعدني بأي شكل من الأشكال.

متغيرات العضو

يجب إخفاء متغيرات أعضاء الفئة (FB) وتبدأ باسم صغير
~ باسكالVAR{سمة "إخفاء"}الزناد: BOOL ؛{سمة "إخفاء"}العداد: INT ؛{سمة "إخفاء"}الحالة التناظرية:END_VAR~

تضمين التغريدة

في معظم الحالات لا أرى فائدة في استخدام البادئات. أوافق على اقتراح philippleidig .

أود أن أقول أن المؤشر والمرجع هما استثناء هنا.
👍
لقد اقترحت اتفاقياتي في PR # 5

تسمية الأعضاء وتسمية النوع

لا أرى فائدة في استخدام البادئة. لا يساعدني بأي شكل من الأشكال.
👍👍

متغيرات العضو

يجب إخفاء متغيرات أعضاء الفئة (FB) وتبدأ باسم صغير

    VAR
        {attribute 'hide'}
        trigger : BOOL;
        {attribute 'hide'}
        counter : INT;
        {attribute 'hide'}
        analogStatus : AnalogStatus;
    END_VAR
  • لن تظهر المتغيرات المخفية فوق الإعلانات ، لذا إذا لم تكن هناك حاجة لها على HMI ، فيمكن إخفاؤها. ولكن إذا احتجنا إلى رؤيتها في HMI ، فلا ينبغي لنا استخدام سمة "إخفاء".
  • Tc3 غير حساس لحالة الأحرف ، لذا قد يتعارض trigger (اسم متغير) و Trigger (اسم الخاصية). سنحتاج إلى أن نبدأها بـ _ كما هو مقترح على ما أعتقد

أوافق تماما 👍

هناك أيضا السمة "conditionalshow". ولكن لا يمكن استخدام هذا إلا مع مكتبة مترجمة.
https://infosys.beckhoff.com/english.php؟content=../content/1033/tc3_plc_intro/8095402123.html & id = 7685156034373049758
بما أنني أفترض أننا سنوفر مكتبة مفتوحة ، فإن هذا سيكون له معنى محدود فقط.

_ كبادئة لمتغيرات الأعضاء أمر ضروري كما قال PTKu .

أحب عمومًا التمسك باتفاقيات التسمية واختيار اسم C #.

أنا أحب القيمة المرجعة للطريقة على أنها منطقية. أجد أن أنواع البيانات الأكثر تعقيدًا غير مناسبة ، لأنه يجب إنشاء مثيل لها بالخارج أو إعادتها بالرجوع إليها.

philippleidig ماذا تقصد بقيم الإرجاع؟ في هذه الحالة يتم استخدامها للتحقق من الأخطاء؟ عادة ما تعتمد قيمة الإرجاع على الطريقة. CalculcateArea سيعيد REAL `LREAL`.

موافق تماما على تسمية المتغير المقترحة!

أنا أحب القيمة المرجعة للطريقة على أنها منطقية. أجد أن أنواع البيانات الأكثر تعقيدًا غير مناسبة ، لأنه يجب إنشاء مثيل لها بالخارج أو إعادتها بالرجوع إليها.

philippleidig ماذا تقصد بقيم الإرجاع؟ في هذه الحالة يتم استخدامها للتحقق من الأخطاء؟ عادة ما تعتمد قيمة الإرجاع على الطريقة. CalculcateArea سيعود REAL``LREAL .

@ Roald87 ستتمثل الفكرة في أن طريقة المكون الذي ينفذ إجراءً ما سيعود "صحيح" عند اكتمال الإجراء (MoveToHome () عند الوصول إلى مستشعر المنزل / الموضع). هذا لا يمنع أنواع العودة الأخرى عند الضرورة.

موافق تماما على تسمية المتغير المقترحة!

سيكون لدي اقتراح حول المصفوفات. هناك مطلب رسمي لمترجم inxton وهو أن المصفوفات العابرة للأكوام التي تعتمد على الصفر فقط. والسبب هو منع الالتباس عند استخدامها في C #.

_array: صفيف [0..10] من BOOL ؛ // عبر أكوام
في حين
_array: صفيف [1..10] من BOOL ؛ // لا يتحول

أي تعليق على هذا؟

نفس الشيء بالنسبة إلى TwinCAT HMI (TE2000)

نفس الشيء بالنسبة إلى TwinCAT HMI (TE2000)

سيكون من الملائم جدًا أن تكون المصفوفات متزامنة مع HMI بالفعل!

تضمين التغريدة @ Roald87 هل أي واحد منكم اتفاقيات العلاقات العامة حول المصفوفات ثم الثابتة والمتنقلة ... أنا فقط أحب رؤية المزيد من المساهمين في الريبو :).

سيكون لدي اقتراح حول المصفوفات. هناك مطلب رسمي لمترجم inxton وهو أن المصفوفات العابرة للأكوام التي تعتمد على الصفر فقط. والسبب هو منع الالتباس عند استخدامها في C #.

_array: صفيف [0..10] من BOOL ؛ // عبر أكوام
في حين
_array: صفيف [1..10] من BOOL ؛ // لا يتحول

أي تعليق على هذا؟

نظرًا للطريقة التي تعمل بها حلقات النص المهيكلة ، فإنني أفضل الاحتفاظ بمصفوفات PLC بأبعاد 1..X. نتيجة لذلك ، يسهل قراءة الكود في كل مكان في PLC. أعتقد أننا يجب أن نكتب رمزًا جذابًا ويمكن صيانته على PLC دائمًا. إذا احتجنا إلى الحشوات لجعلها تعمل بشكل أفضل على أجزاء التعليمات البرمجية الخاصة بطرف ثالث ، فيمكننا إدارة ذلك بشكل منفصل.

// Declaration
NUMBER_OF_DRIVES : INT := 10;
drives  : ARRAY[1..NUMBER_OF_DRIVES] OF I_Drive;

// now in the code
FOR i := 1 to NUMBER_OF_DRIVES DO
   drives[i].SomethingCool();
END_FOR

// Compared to

// Declaration
drives : ARRAY[0..(NUMBER_OF_DRIVES -1) ] OF I_Drive;
// Code
FOR i := 0 to (NUMBER_OF_DRIVES -1) DO
   drives[i].SomethingCool();
END_FOR

أنا أحب القيمة المرجعة للطريقة على أنها منطقية. أجد أن أنواع البيانات الأكثر تعقيدًا غير مناسبة ، لأنه يجب إنشاء مثيل لها بالخارج أو إعادتها بالرجوع إليها.

أعتقد أن الأساليب يجب أن تعيد كل ما هو معقول لهذه الطريقة. يجب أن يساعدك اسم الطريقة على فهم ذلك.

بمعنى آخر

IF NOT piece.PassesValidation() THEN
 LogError('Piece does not pass validation');
END_IF

// OR

IF sequence.Finished THEN
  axis.Disable(); // No return type necessary.
  state := WaitForAxisDisabled;
END_IF

@ Roald87 ستتمثل الفكرة في أن طريقة المكون الذي ينفذ إجراءً ما سيعود "صحيح" عند اكتمال الإجراء (MoveToHome () عند الوصول إلى مستشعر المنزل / الموضع). هذا لا يمنع أنواع العودة الأخرى عند الضرورة.

لا أحب حقًا نهج استدعاء طريقة عامة بشكل متكرر ، حيث تقوم هذه الطريقة بتنفيذ الوظيفة بشكل متكرر حتى تعود بشكل صحيح. هناك حالة واحدة أعتقد أنها قابلة للتطبيق (إذا كانت هناك طريقة من نوع "التنفيذ" على واجهة ، ولكن هناك أيضًا طرق أفضل لعمل ذلك أيضًا ، على ما أعتقد).

المشاكل معها

  • يمكنك / تقوم بإنشاء مسارات تنفيذ على فئة يمكن استدعاؤها بشكل متزامن. بمعنى آخر
atEnd :=  axis.GoToEnd();
atBeginning := axis.GoToBeginning();
  • يجب أن تدير الفصول حالتها داخليًا. يمكن استخدام الأساليب لإجراء طلبات وتعديلات لهذه الحالة ، ويمكن استخدام الخصائص للوصول إلى الحالة أو تعيين حالة بسيطة أيضًا.
  • كيف تسمي الطريقة بحيث تتضح كيف ولماذا يتم استخدامها بهذه الطريقة؟ axis.GoToEndTrueWhenComplete ()؟
  • ماذا لو تغيرت الحالة الأساسية للفصل بطريقة تغير طريقة تشغيل هذا الاستدعاء؟
  • يمكن أن تكون ظروف السباق أكثر سهولة. إذا استدعينا .Enable () مرارًا وتكرارًا ، ولكننا حصلنا على خطأ في فحص واحد ، فإن .Enable () قد يُمكّن على أي حال باستخدام نهج "استمر في الاتصال حتى ينتهي". يجب أن يكون هذا بدلاً من ذلك .RequestEnable: BOOL ، والذي يشير إلى ما إذا كانت الشروط الأساسية عند نقطة الطلب صحيحة (السماح لكود الاستدعاء بالتراجع بأمان في تلك النقطة). إذا كان من الممكن تقديم الطلب ، فيمكن لرمز الاستدعاء بعد ذلك مراقبة .IsEnabled و .InError لإكماله.

philippleidig غير مألوف مع TwinCAT HMI. كيف يتم التعامل مع المصفوفات غير المستندة إلى 0 هناك؟

@ مارك لازاريدس

أعتقد أن الأساليب يجب أن تعيد كل ما هو معقول لهذه الطريقة. يجب أن يساعدك اسم الطريقة على فهم ذلك.
👍

التزامن وظروف العرق كلها مخاوف معقولة. IMHO يجب معالجة هذه المشاكل قدر الإمكان على مستوى المكونات ، ولكن الأهم من ذلك على مستوى التنسيق عند استهلاك المكونات. يجب استدعاء طرق المكون من داخل العناصر الأولية الشبيهة بوحدة التحكم في الحالة التي تم تنفيذها بشكل صحيح (سواء كانت CASE أو IF أو ELSIF أو مُسلسِل / محدد / مكرر أكثر تعقيدًا) والتي من شأنها منع الاستدعاءات المتزامنة للطرق المتعارضة لنفس مثيل المكون .

يجب منع شيء من هذا القبيل في رمز المستهلك الخاص بالمكون
~atEnd: = axis.GoToEnd () ،atBeginning: = axis.GoToBeginning () ،~

يسمح executing methods العائد true عند الانتهاء من الاستخدام التعريفي النظيف.

ما يدور في ذهني هو شيء مثل هذا:

~~~
VAR
_ الدولة: INT ؛

END_VAR

حالة _ حالة
0:
إذا (axis.MoveAbsolute (Position: 100.0)) ثم
_ الولاية: = 1 ؛
إنهاء إذا؛
1:
إذا (axis.MoveRelative (Position: 100.0)) ثم
_ الولاية: = 2 ؛
إنهاء إذا؛
2:
إذا كان (محور التحرك المطلق (الموضع: 300.0)) إذن
_ الولاية: = 3 ؛
إنهاء إذا؛
3:
_ الولاية: = 0 ؛
END_CASE
~~~

يمكن اختزال هذا إلى

~~~
VAR
_ الدولة: INT ؛

END_VAR

حالة _ حالة
0:
انتظار (axis.MoveAbsolute (Position: 100.0)، 1) ؛
1:
انتظار (axis.MoveRelative (Position: 100.0)، 2) ؛
2:
انتظار (axis.MoveAbsolute (Position: 300.0)، 3) ؛
3:
انتظار (صحيح ، 0) ؛

END_CASE

====================================

طريقة انتظار
VAR_INPUT
تم: BOOL
الدولة التالية: INT ؛
END_VAR
إذا (تم) ثم
_state: = nextState ؛

إنهاء إذا؛

~~~
تحرير: أفترض أن المكون يُستخدم في مهمة plc واحدة

يضع قيودًا على استهلاك الكود. يجب ألا تكون مكوناتنا عرضة للأخطاء إذا استخدمها المستهلك بترتيب غير صحيح. يجب أن يستجيبوا جيدًا لجميع التفاعلات. لن يعملوا بشكل ضروري (على سبيل المثال ، لن يعمل الاتصال res := axis.MoveTo(Position:=100); قبل axis.Enable() ) ، ولكن يجب إعطاء الشفرة المستهلكة معلومات كافية في جميع النقاط لفهم مكان المشكلة.

ما زالت لا تقرأ جيدًا بالنسبة لي أيضًا. لا يمكنك قراءة المحور. تحريك المطلق (syx) وفهمه يحتاج إلى أن يتم استدعاؤه دوريًا. ستفهم فقط أنك إذا علمت أن أسلوبنا الاصطلاحي يتطلب ذلك منك ، وفي تلك المرحلة أعتقد أننا فشلنا في إنشاء شيء قابل للاستخدام للغاية.

أود أن أقول أيضًا ، بغض النظر عما إذا كان يمكن استبعاد الأخطاء ، فإنها لا تزال أكثر احتمالًا. باستخدام نهج استدعاء الطريقة الدورية ، يمكنك إنشاء طريقة تتحقق مما إذا كانت حالة الكائن جاهزة للاتصال ، ثم استدعاء الطريقة الدورية ، ثم مراقبة الحالة الأخرى للكائن للتأكد من عدم حدوث أي شيء في غضون ذلك. أو تقوم بإجراء الطلب ، والذي يخبرك ما إذا كان ناجحًا أم لا ، ثم مراقبة الحالة للإنجاز. يمكنك تسجيل رد اتصال لذلك كجزء من الطلب إذا كنت تريد ، وهو نهج OO لائق لهذا ويقلل من المزيد من المكالمات / الاستجواب دوريًا.

@ مارك- lazarides الصحيح! أنا execute methods (دعنا نسميهم بهذه الطريقة) يجب ألا يطبق المنطق الدوري. لقد افترضت أن ما كنا نناقشه سابقًا هو أننا نضمن أن ما يجب تنفيذه بطريقة دورية سيتم وضعه إما في جسم FB أو بطريقة Cyclic ؛ يجب أن يتم استدعاؤه في مكان مناسب في برنامج المستهلك.

نعم. فلماذا نسمي الطريقة دوريًا؟ ما زلت أعتقد أن الحجج الأصلية قائمة. يجب أن تقوم الطريقة بعمل واحد. ابدأ شيئًا ما (وبالتالي أبلغ عن نجاح ذلك) أو احصل على شيء (وأعده).

نعم. فلماذا نسمي الطريقة دوريًا؟ ما زلت أعتقد أن الحجج الأصلية قائمة. يجب أن تقوم الطريقة بعمل واحد. ابدأ شيئًا ما (وبالتالي أبلغ عن نجاح ذلك) أو احصل على شيء (وأعده).

لا اعتراضات مارك ، لسنا بحاجة إلى استدعاء طرق التنفيذ بشكل دوري ، ولكن لا ينبغي أن تكون مشكلة إذا فعلنا ذلك.

لا أفهم لماذا لا تستطيع الطريقة إرجاع نتيجة العملية.

أعتقد أننا يجب أن نتوصل إلى بعض المكونات الأكثر تعقيدًا وأن نضع نموذجًا أوليًا لهذه الأفكار (المكبس الهوائي ليس معقدًا بدرجة كافية لهذه المناقشة) أعتقد أنه يمكننا البدء بمحرك / محور.

متفق عليه يا بيتر.

بسبب اسم الخيط ، اعتقدت أننا نهدف إلى هذا باعتباره اصطلاحًا! أعتذر إذا لم أفهم.

لدى كريس كتلة محور أساسية في العلاقات العامة في الوقت الحالي - لقد علقت عليها ، لكنها تحتاج إلى مزيد من الأنظار عليها.

@ mark-lazarides لا حاجة إلى اعتذار مارك ، نحن هنا لمناقشة بحرية ، وسألقي نظرة على العلاقات العامة غدًا ...

philippleidig @ Roald87 @ dhullett08 مناقشة حول تصميم المكونات هنا أيضًا

بعض الاقتراحات العشوائية مأخوذة من وثائق PLCopen.

plcopen_coding_guidelines_version_1.0.pdf

الثوابت
يجب أن تكون في ALLCAPS بحيث يسهل التعرف عليها

طول الاسم المقبول
بحد أدنى 4 أحرف بحد أقصى 24 حرفًا؟

بعض الاقتراحات العشوائية مأخوذة من وثائق PLCopen.

plcopen_coding_guidelines_version_1.0.pdf

شكرا على الرابط

الثوابت
يجب أن تكون في ALLCAPS بحيث يسهل التعرف عليها

👍

طول الاسم المقبول
بحد أدنى 4 أحرف بحد أقصى 24 حرفًا؟

يجب ألا تكون الأسماء الأطول مشكلة حتى تعبر عن النية ، يجب أن يكفي 24 حرفًا ، لكنني لن أضع حدًا على الحد الأقصى. الشخصيات. الأسماء القصيرة جدًا مشبوهة حقًا حيث يجب أن تكون أكثر من 4 أحرف.

Seversonic اضافت ملاحظاتك للوثيقة ...

متابعة المناقشة. هنا رقم 11

أنا حقًا لا أحب اتفاقياتك ولكني أعتقد أن مشروعك مثير جدًا للاهتمام!
شخصيًا أفضل طريقة أكثر كلاسيكية
FB_ fb وظيفة بلوك
طريقة M_Add ()
P_Parameter Prop

مرحبا @ PeterZerlauth وشكرا. من الصعب بعض الشيء الاتفاق على الاتفاقيات لأننا في منتصف الطريق بين PLC وهندسة البرمجيات الكلاسيكية.

ها هو الاستطلاع منذ البداية المبكرة للمناقشات:

TcOpen.Survey.Result.pdf

بالإضافة إلى ذلك ، كان هناك نقاش هنا وفي قناة Slack ، قد يكون هناك أيضًا شيء ما في @ dhullett08 TcOpen repo.

كان هناك شعور عام (أو على الأقل أفسره بهذه الطريقة) بأننا يجب أن نتخلى عن البادئات إذا لم تقدم معلومات مفيدة أو يوفر IDE الحديث المعلومات التي نقلناها مع البادئات في الماضي.

أفهم أن هذا يتعلق بالتفضيلات الشخصية وليس هناك حقًا طريقة صحيحة أو خاطئة للقيام بذلك. فقط علينا أن نتفق على شيء ما.

عند الإغلاق هنا ، تستمر المناقشة هنا: https://github.com/TcOpenGroup/TcOpen/discussions/11

هل كانت هذه الصفحة مفيدة؟
0 / 5 - 0 التقييمات

القضايا ذات الصلة

runtimevic picture runtimevic  ·  12تعليقات

runtimevic picture runtimevic  ·  8تعليقات

DmitryEfimenko picture DmitryEfimenko  ·  3تعليقات

songjinxi picture songjinxi  ·  3تعليقات

JoergTiedemann picture JoergTiedemann  ·  3تعليقات