News:

  • July 16, 2024, 03:58:46 PM

Login with username, password and session length

Author Topic: Feedback wanted: Instantiable programs concept  (Read 10596 times)

BobO

  • Host Moderator
  • Hero Member
  • *****
  • Posts: 6007
  • Yes Pinky, Do-more will control the world!
Feedback wanted: Instantiable programs concept
« on: June 22, 2021, 12:41:50 PM »
Feedback wanted...

While working on nested structs in UDTs, it occurred to me that we might now have the foundation laid for instance based program blocks.

This is the basic work flow:
1. Create a UDT definition that contains all of the instance data of the program.
2. Create an object block definition, which is just a program block where you reference the UDT and program struct instance through some abstract names like $Data and $Pgm, tbd.
3. Add one or more instances of the object. The facility creates the program and UDT and adds the object instance to the list.
4. Run the object instance with RUN just like any other program.

Only one copy of the code exists, run multiple times, using the program and data instances.

Most instructions would be supported in objects, but there is a pretty big caveat there. While we can reference a structure indirectly, we cannot (yet) reference an array indirectly. What this means is that anything that needed to do array referencing of arrays unique to an instance cannot (easily) do so. So the best rule of thumb is that if you can't describe it in a 256 byte UDT with nested structures, you really can't do it in an object. I'm sure there will be ways around that, but they may be more trouble than they are worth, or more advanced than most want to learn.

The function definitely has utility as described, but I guess what I'm asking is whether the limitation to a single (and maybe more than one, we'll see) UDT per instance is so limiting for your typical application that you don't think you'd ever use it. No wrong answers.

And FYI...I've done a proof of concept. It works, and even though we still have a couple of things to work out, we think it's completely viable.
"It has recently come to our attention that users spend 95% of their time using 5% of the available features. That might be relevant." -BobO

RBPLC

  • Hero Member
  • *****
  • Posts: 585
Re: Feedback wanted: Instantiable programs concept
« Reply #1 on: June 22, 2021, 02:00:11 PM »
Quote
2. Create an object block definition, which is just a program block where you reference the UDT and program struct instance through some abstract names like $Data and $Pgm, tbd.

Could you have multiple object block definitions to deal with the case where you needed multiple UDT's if you're limited to one UDT per object block definition?

BobO

  • Host Moderator
  • Hero Member
  • *****
  • Posts: 6007
  • Yes Pinky, Do-more will control the world!
Re: Feedback wanted: Instantiable programs concept
« Reply #2 on: June 22, 2021, 02:05:11 PM »
Quote
2. Create an object block definition, which is just a program block where you reference the UDT and program struct instance through some abstract names like $Data and $Pgm, tbd.

Could you have multiple object block definitions to deal with the case where you needed multiple UDT's if you're limited to one UDT per object block definition?

It would be easier to add more UDTs to the program definition, $Data1, $Data2, etc. Nothing to prevent it architecturally, just a question of what is needed.
"It has recently come to our attention that users spend 95% of their time using 5% of the available features. That might be relevant." -BobO

RBPLC

  • Hero Member
  • *****
  • Posts: 585
Re: Feedback wanted: Instantiable programs concept
« Reply #3 on: June 22, 2021, 02:32:00 PM »
I'm trying to understand exactly how this would work. After playing around in TIA Portal, is what you're proposing similar to a Multi-Instance Function Block? Would the UDT serve as local memory definitions? How would you troubleshoot an instance in regards to a data view or more importantly a window where you could see an instance running in ladder? I think this was brought up a few days ago on the ADC forum.

BobO

  • Host Moderator
  • Hero Member
  • *****
  • Posts: 6007
  • Yes Pinky, Do-more will control the world!
Re: Feedback wanted: Instantiable programs concept
« Reply #4 on: June 22, 2021, 02:49:42 PM »
I'm trying to understand exactly how this would work. After playing around in TIA Portal, is what you're proposing similar to a Multi-Instance Function Block? Would the UDT serve as local memory definitions? How would you troubleshoot an instance in regards to a data view or more importantly a window where you could see an instance running in ladder? I think this was brought up a few days ago on the ADC forum.

Yes, it is essentially what you are describing. A single physical code block, that runs multiple times using different data and program instances. It is fully a program block, with its own set of stages and current execution state, so I wouldn't call it a function block...each is a full program.

You would use this any time you are currently creating multiple copies of the same program and then editing all of the global memory references. I know many users do exactly this. The big question is whether a single UDT is enough data to solve the typical problem or not.

As for debugging, you really won't know the difference. In the project tree, there will be an Object section at the same level as Tasks, Programs, and Subroutines are now. Immediately underneath that, you would have Object definitions, which are just program blocks built with abstract references to the associated program and UDT structures, rather than hard references. Underneath each Object definition is a list of instances. If you double click the definition, we open the abstract definition for editing. If you double click an an instance, we open the specific instance, with the abstract references resolved to the actual structures, so it will look exactly like debugging a program block now.

The key difference is that any reference to memory not contained with the Object's program or data structure is global, and every instance is reading/writing the same location. That can be perfectly fine...but...that can also be a big issue. We won't prevent it, but we will warn you about it.
"It has recently come to our attention that users spend 95% of their time using 5% of the available features. That might be relevant." -BobO

BobO

  • Host Moderator
  • Hero Member
  • *****
  • Posts: 6007
  • Yes Pinky, Do-more will control the world!
Re: Feedback wanted: Instantiable programs concept
« Reply #5 on: June 22, 2021, 03:18:21 PM »
And when I say "abstract reference" it would be like this:

STR $Data.BitInMyStruct
TMR $Data.TmrInMyStruct, 5000

This is what you see in the object definition.

When we display for status, we would resolve the abstract reference to the actual reference for the instance you are viewing. If when you created the instance you called the data UDT, MyUdt1, $Data would be replaced with MyUdt1, so the instance displayed would be:

STR MyUdt1.BitInStruct
TMR MyUdt1.TmrInMyStruct, 5000

Any other instances of the same object would of course resolve to the associated structures. Should feel exactly like what you do now.
« Last Edit: June 22, 2021, 03:20:14 PM by BobO »
"It has recently come to our attention that users spend 95% of their time using 5% of the available features. That might be relevant." -BobO

franji1

  • Bit Weenie
  • Host Moderator
  • Hero Member
  • *****
  • Posts: 3676
    • Host Engineering
Re: Feedback wanted: Instantiable programs concept
« Reply #6 on: June 22, 2021, 03:32:28 PM »
You would define one UDT per "class" (using C++ terminology), then create instances of the "class", which would include the Program structure (.$pgm member) and instance data  (UDT) structure (.$data member).

Say this is a packing machine, there would be 1 code-block to run 10 packing maches, say the code-block is called PackingMachine.  Say each one uses a couple Timers, FillTimer and SealTimer.  For simplicity, let's say you have 10 machines, MachineA thru MachineJ.

You would write ONE code block using PackingMachine.  Say it was a Stage program, so you would write your code ONCE:

SG PackingMachine.$pgm.S0
...
SG PackingMachine.$pgm.S1
...
SG PackingMachine.$pgm.S2
...

inside Stage S2, say you use the FillTimer

PackingMachine.$pgm.S2

SG PackingMachine.$pgm.S2
TMR PackingMachine.$data.FillTimer

STR PackingMachine.$data.FillTimer.Done
JMP PackingMachine.$pgm.S3

But when the code EXECUTES for the 10 different INSTANCES in one PLC scan, it basically runs that code block 10 times, but instead of using PackingMachine, it uses 10 individual SPECIFIC INSTANCES (same code - not a copy of the code, but each execution instance at runtime just replaces PackingMachine with MachineA, then MachineB, then MachineC, ... MachineJ.

Each INSTANCE has its own program/data state, but just ONE code-block (ran 10 different times with 10 different object states).  So then MachineA can be in Stage S0, MachineB in Stage S1, MachineC in Stage S2 with MachineC.$data.FillTimer.Acc equal to 1234, MachineD in Stage S2 with MachineD.$data.FillTimer.Acc equal to 5678.

If you want to see the status of the logic for MachineA, open up THAT INSTANCE, turn status ON.  For MachineJ, open up THAT INSTANCE, turn status ON.  THAT code will be SIMILAR to the ORIGINAL code-block (PackingMachine), but will instead show instruction status of instance MachineJ as follows (say for Stage S2):

SG MachineJ.$pgm.S2
TMR MachineJ.$data.FillTimer

STR MachineJ.$data.FillTimer.Done
JMP MachineJ.$pgm.S3

If you had a big enough screen, you could tile the 10 code INSTANCED blocks, all with status ON.  The shape of the 10 Ladder Views would be IDENTICAL, but the INDIVIDUAL OBJECT INSTANCE PARAMETERs would be SWAPPED OUT.

You create/edit using the base PackingMachine code block, but you do status with the INSTANCE based code blocks (MachineA thru MachineJ).  You can't "edit" MachineJ's "copy", because MachineA thru MachineJ SHARE THE SAME BASE CODE (i.e. PackingMachine).

Since you would be limited to just 256 bytes in the $data portion of the "class", how many timers, counters, PID, nested UDTs will you need?  A Timer is 8 BYTEs.  A REAL is 4 BYTEs.  A PID is 96 BYTEs.  A string can be 8 BYTEs or 64 BYTEs or ???.  So you can burn through 256 BYTEs easily if you need a couple PIDs or a bunch of non-trivial strings.  Hence, do we need 2 (or 3) UDTs to hold all the necessary "member" variables (Timers, PID, Strings, Recipe UDT, other UDT, etc. etc.) .$data1 .$data2 .$data3 ? ? ?

RBPLC

  • Hero Member
  • *****
  • Posts: 585
Re: Feedback wanted: Instantiable programs concept
« Reply #7 on: June 22, 2021, 04:30:39 PM »
Let me first say that this ability would be extremely beneficial. I've got a project written for 8 similar machines and there was a whole lot of find/replace going on to get the multiple instances resolved, not to mention duplicate comments and error checking to make sure I haven't missed an instance update and the issue of incorrect logic that is duplicated 8 times and has to be corrected in eight places. Quickly adding up total number of bytes that would have gone into one UDT, I think I've got approximately 300 bytes of non-strings that are used for program control. I personally could have gotten by without adding strings to the UDT to keep the byte count as low as possible. I would very much like to see these changes as this would have completely changed how I programmed this particular machine (which is the largest I will work on). I kept trying to figure out how to use a subroutine to reduce copy/paste programming but couldn't because you can't perform multi-scan instructions in the subroutines and you can't effectively troubleshoot subroutines when you can't see specific individual instances easily for troubleshooting. If you guys can include this functionality combined with structures in UDT's and increased name lengths to keep it all organized, this will be one very powerful tool. After seeing this functionality in TIA Portal, I immediately wished it was available in DmD.

BobO

  • Host Moderator
  • Hero Member
  • *****
  • Posts: 6007
  • Yes Pinky, Do-more will control the world!
Re: Feedback wanted: Instantiable programs concept
« Reply #8 on: June 22, 2021, 04:45:18 PM »
Name lengths become a little less relevant when you have depth. A 16 character name ends up being a big problem specifically because y'all are cramming so much into a single flat namespace. When the name is 16.16.16 it's much easier to be expressive with us changing anything. We are currently rewriting some display code to be long name friendly however, so we still want to get there. It's just a big job. We're a small company and try to pick our battles.

At the controller level, there is nothing to prevent being more than one user struct per object, so 300 bytes should be no issue. Each struct is just another reference pushed onto the stack, and the object can reference n as a easily as 1. The only real concern is how we reference them from DmD for editing, find, xref, etc. As long as we can solve a few small-ish issues there, this is manageable. I already have a simple proof on concept running in the PLC and it wasn't very hard at all. The key is nested structures. That was huge.

Thanks for the feedback so far. Would love to hear from others!

"It has recently come to our attention that users spend 95% of their time using 5% of the available features. That might be relevant." -BobO

BobO

  • Host Moderator
  • Hero Member
  • *****
  • Posts: 6007
  • Yes Pinky, Do-more will control the world!
Re: Feedback wanted: Instantiable programs concept
« Reply #9 on: June 22, 2021, 04:49:21 PM »
...and let me add that basically any structure can be added to UDTs, and that means that UDTs can be added to UDTs, not just built-ins. That's why I'm saying 16.16.16 on the names. You control all of that.
"It has recently come to our attention that users spend 95% of their time using 5% of the available features. That might be relevant." -BobO

RBPLC

  • Hero Member
  • *****
  • Posts: 585
Re: Feedback wanted: Instantiable programs concept
« Reply #10 on: June 22, 2021, 05:07:28 PM »
1) Valid point concerning names and depth.
2) Does this development segue into user-defined functions and function blocks? What about local variables?
3) Do you guys do beta-test releases that could be used in Simulator? 

ATU

  • Internal Dev
  • Hero Member
  • ****
  • Posts: 2121
  • YKPAIHA
    • ATU, Inc.
Re: Feedback wanted: Instantiable programs concept
« Reply #11 on: June 22, 2021, 05:37:20 PM »
Can you reference a global array indirectly?

BobO

  • Host Moderator
  • Hero Member
  • *****
  • Posts: 6007
  • Yes Pinky, Do-more will control the world!
Re: Feedback wanted: Instantiable programs concept
« Reply #12 on: June 22, 2021, 06:52:07 PM »
Can you reference a global array indirectly?

No. That's the primary limitation.

You could manually allocate a range from a global array and pass the index range through members in the data struct, but some will consider that more advanced than they are willing to do.
"It has recently come to our attention that users spend 95% of their time using 5% of the available features. That might be relevant." -BobO

ATU

  • Internal Dev
  • Hero Member
  • ****
  • Posts: 2121
  • YKPAIHA
    • ATU, Inc.
Re: Feedback wanted: Instantiable programs concept
« Reply #13 on: June 22, 2021, 08:00:04 PM »
What about indexing in the Math box? I thought that was done differently anyway.

BobO

  • Host Moderator
  • Hero Member
  • *****
  • Posts: 6007
  • Yes Pinky, Do-more will control the world!
Re: Feedback wanted: Instantiable programs concept
« Reply #14 on: June 22, 2021, 08:29:39 PM »
What about indexing in the Math box? I thought that was done differently anyway.

Yes, that is the best way. The array itself cannot be abstracted though and must be global. You can solve that by manually assigning a global range to an instance through struct members, and then indexing in a MATH box. You could use a global V, but you would have to make sure the program never yielded. MATH is cleaner.
"It has recently come to our attention that users spend 95% of their time using 5% of the available features. That might be relevant." -BobO