From Friday, April 19th (11:00 PM CDT) through Saturday, April 20th (2:00 PM CDT), 2024, ni.com will undergo system upgrades that may result in temporary service interruption.

We appreciate your patience as we improve our online experience.

LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

Help on defining the right software architecture with LVOOP

Hello,

I belong to those developers who come from the OOP world (Java, C++ in my case), and need to understand how to do things in labview.

My current project is a control system which periodically reads, executes and writes. Execution mean interactions with other systems, possibly slow operations. The system offers the possibility to perform different commands.
The intention is to model all components using LVOOP classes.
Like in every other programming language, there are a lot of ways to get the same thing, and the reason I write this post is to expose my architecture to other more experienced labview engineer to get a feedback if I am doing right or completely wrong.

I would like to build the software this way:
- System.lvclass - this class contains the status of the system, confguration parameters, etc.
- Interface.lvclass - this class is responsible for getting data and commands from outside (OPC-UA will be used concretely) and to create instances of Command.lvclass with tasks to perform.
There will be a "producer" loop for constantly reading from the Interface and produce Commands.
- Command.lvclass - A command perform an operation following the current flow: 1) Validate against the current System status, 2) perform operation, 3) produce result and write them.
There is a queue where commands are pushed by the Interface. There is another loop that pulls Commands from the same queue, and executes them against the System status (Command.lvclass has an "execute" public vi).

This is the (very high level) overview description of the system. And now come the points where I am not sure how to do.
1) The System.lvclass must be ONE instance. Every Command validates against it, and can possibly modify it's status. Access to it must be synchronized and exclusive. I see a good candidate for the singleton pattern. Would you say this is the best way to go? I've seen there are different ways to realize a singleton in Labview, which one should I use?
2) The "Perform operation" phase of the Command.lvclass consists of potentially slow operations. For example, it could involve interactions with some hardware and the needs to wait for its completion. How can I manage this? I don't want the "Command" loop to be blocked too long by command executions. I would like the commands to be able to run in parallel. To solve this I was thinking to use a state machine for the execute method, giving the command a chance to change its internal state at every loop "tick". Is this a good practice in labview?

Thank you for your help! Any suggestion or correction is highly appreciated.

0 Kudos
Message 1 of 4
(2,811 Views)

Difficult to comment on just a verbal outline, but quite a few LabVIEW programmers favour more asynchronous architectures, with loops/modules/actors sending messages to each other, rather than one using synchronous blocking access.  This handles slow hardware operations very well, since each independant bit of hardware is handled by a separate loop.

0 Kudos
Message 2 of 4
(2,782 Views)

For the System class, you might be able to do it by referring to all of its settings as data value references.  If you only ever have access to the data value reference and not the actual data, then as soon as you enter the in-place structure to access it, you can't leave it without writing a new value back in and it automatically blocks all other access to the reference while it's open in that particular structure.  Not sure about this as I've never tried to implement it myself.

 

For the Command class, you could internally structure it to use asynchronous calling and collect VIs.  If you put a timeout on the "collect" node and trap error 123 (indicating that it timed out) you can iterate through any number of parallel commands that you have issued, and get the data from the completed ones whenever they finish.  See this link if you're unfamiliar with it.  I haven't tried implementing this myself either but it might be a way to get what you want.

0 Kudos
Message 3 of 4
(2,770 Views)

@enricobragante wrote:

2) The "Perform operation" phase of the Command.lvclass consists of potentially slow operations. For example, it could involve interactions with some hardware and the needs to wait for its completion. How can I manage this? I don't want the "Command" loop to be blocked too long by command executions. I would like the commands to be able to run in parallel. To solve this I was thinking to use a state machine for the execute method, giving the command a chance to change its internal state at every loop "tick". Is this a good practice in labview?


Just to address this issue:

I would recommend the recveiver of the measurement command to off-load the actual measurement to a parallel loop with it's own message queue (command receiver 2).  As part of the original command (the parent of the entire command hierarchy) I would incorporate a Notifier to which the sender is listening and the measurement routine can write to when it's finished.  This way the command receiver itself is free to deal with other requests as required.  It's like passing on a "Do this and when you're finished let this person know" delegation.  By implementing such a structure for any different kind of command you want running in parallel, you can let many processes run in parallel.

0 Kudos
Message 4 of 4
(2,740 Views)