Jump to content

Handling HAL with Children Through Packages


Recommended Posts

Posted

Lets say I have a basic hardware abstraction layer for environmental chambers.

Chamber.png.f134731106f38ca54cd11d6dc5570438.png

Here I have the parent Chamber class, a Simulate Class which overrides the required members, a CSZ, and an Envirotronics which are two makers of chamber hardware.  For this example lets say I want to distribute this as 3 different VIPM packages.  I have my Hooovahh Chamber.vip, which contains the Parent, and Simulate classes, and I have two others the Hooovahh Chamber >> CSZ.vip, and Hooovahh Chamber >> Envirotronics.vip.

On the palette I have the main functions all look similar to this.

ChamberPalette.png.2d372dd76f6e644e8906c804fa24c19b.png

My main question is about how people handle the Finding and Opening functions?  I want these drivers on the palette to be easy to use for my developers.  At the moment when you install the main Chamber package it installs the Parent VIs you see, and the Simulate class constant on the Class Constants subpalette.  Each child specific package then installs a new class constant in the subpalette.  Then when a developer wants to use the Find Chambers, they must wire to it an array of classes to use.  Here is an example:

Capture5.JPG.61dca6ab62f223b39d7a008c6a03dbe8.JPG

Here we have a Find VI that is static dispatch on the parent, with overrides insides for each of the Chamber types.  It returns an array of found Chambers which is a cluster.  In the cluster is the class for the chamber found, which is used in the Overrides for Open and Close.  This works and is fine.  But I like the idea of hiding away the class constants, and having more self contained Find VIs for each hardware type.  In most cases we know the hardware we want to talk to and it isn't an array of classes on an array of COM ports, but instead the one hardware class we intend to use on the system.  What I think I would prefer is some thing more like this:

Capture6.JPG.c6552b831053a397fd109222d2c434de.JPG

Here the developer gets a dedicated Find VI for each class which is a static dispatch for each child class.  They all return the same array of cluster (which would be a data type from the parent) and then that array of found chambers is used in the Parent Open which has overrides for each class inside.  In this design I would have the Find for each class installed on the palette under some kind of Find Hardware subpalette.  In this case I imagine there would need to be some kind method of keeping each Find from only using one COM port at a time.  Either through VIG or Semaphore of some kind.  Admittedly this is simplified in the previous example since the Parent would be doing the finding, and would know to only pass a unique COM port to one child at a time.

ChamberPalette3.png.e7e62c242512400ca28f6c8b8d1b5e60.png

In all of these cases I imagine we have full control over the Parent, and all Children.  If anyone develops a new child class, we would roll it into the reuse library as another package which would go through the verification process.  Do developers prefer one design over the other? What pros and cons haven't I thought about?  Thanks.

Posted (edited)

I use a polymorphic VI. It basically just wraps the class constant for this purpose.The user can then have a single VI that they can choose the implementation method from a menu and that ripples down through the class functions. It means you only need 1 VI in the palette for the Open/New/Whatever and, once placed, the the user can change implementations without creating or deleting anything.

image.png.43992047b091c091c7fff3742ddabbbd.png

When there is a single type wired it looks much better because LabVIEW will show the class instance (see below) rather than the generic instance see (above).

image.png.b9154d983852e8274aad60b004db95d0.png

The drawback is quick-drop (apparently) because you cannot choose a specific instance, only the polymorphic, but I ignore people that complain about that :D

Edited by ShaunR
Posted
35 minutes ago, ShaunR said:

I use a polymorphic VI. It basically just wraps the class constant for this purpose.The user can then have a single VI that they can choose the implementation method from a menu and that ripples down through the class functions. It means you only need 1 VI in the palette for the Open/New/Whatever and, once placed, the the user can change implementations without creating or deleting anything.

The problem I have with that is you need a polymorphic VI that has all of the instances inside it.  That creates a dependency that all children are available and installed.  In my situation you may only install the Chamber package, and CSZ package.  Then the developer only has the parent, and that one child (well 2 there is the simulate).  So now where would that polymorphic VI live?  In the parent package?  Then that creates a circular dependency.  I did explore creating an XNode that would look at your current system and drop a VI that had whatever children were available for that target, but that got a bit messy.

The reason for having separate packages, is because some child classes, only work on some targets.  I may have one chamber that uses a Windows DLL to talk to it over USB.  This DLL wouldn't run on Linux RT, and I need to not bring along that child class as dependencies, because that will break the deploy or build, even when that child isn't being directly called.

Posted

If you have a specific structure for your chambers (ie everybody is under the "Hooovahh Chamber" directory), you could do a simple lookup and use the Get LV Class Default Value to dynamically load the classes. I do something similar with my HAL already, except I dictate what class to load based on a JSON file.

  • Like 1
Posted (edited)
11 minutes ago, crossrulz said:

If you have a specific structure for your chambers (ie everybody is under the "Hooovahh Chamber" directory), you could do a simple lookup and use the Get LV Class Default Value to dynamically load the classes. I do something similar with my HAL already, except I dictate what class to load based on a JSON file.

That's not the real problem (but the same solution as I was about to suggest). The main issue is the LabVIEW static linking. Traditionally we have gotten around it with conditional disable structures or calling CLFN's with a path.

hooovahh has created a class that isn't platform independent, only device independent and is attempting to solve platform dependencies with deployment.

I'll have to sleep on it.

Edited by ShaunR
Posted
5 hours ago, crossrulz said:

If you have a specific structure for your chambers (ie everybody is under the "Hooovahh Chamber" directory), you could do a simple lookup and use the Get LV Class Default Value to dynamically load the classes. I do something similar with my HAL already, except I dictate what class to load based on a JSON file.

How do you deal with built applications?  Your solution sounds fine on Windows, and in a development environment.  But if I make an RT or Windows application, it won't know to bring along the child classes into the build if they are called dynamically.  Unless I add them as an always include I guess.  I think there isn't any way around having to have either a class constant of the children somewhere (like into the Find Parent VI) or to have each child class have it's own Find which is part of it's own class and brought into the builds.  I suggested the XNode option just because it could read those files on your Windows disk, then plop down the constants into the generated code.  That has complications like only bringing along the classes on your disk, at that time, unless on load the XNode reloads and regenerates code which is a different kind of mess I wouldn't want to deal with.  But then again it could be a cool right click feature for reload, or check boxes on what libraries are installed, and which ones to load.  And while that is all cool sounding, the very large majority of the time a developer just wants to plop down a single VI, that finds the hardware for that specific hardware type.  And then not have to do anything extra to make builds work.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

By using this site, you agree to our Terms of Use.