Jump to content


  • Posts

  • Joined

  • Last visited

Everything posted by CharlesB

  1. In the need for displaying large images at a high performance, I want to use triple buffering in my program. This type of acquisition allows to acquire large data in buffers, and have it used without copying images back and forth between producer and consumer. This way consumer thread doesn't wait if a buffer is ready, and producer works at max speed because it never waits or copy. If the consumer makes the request when a buffer is ready, it is atomically turned into a "lock" state. If a buffer isn't ready, it waits for it, atomically lock it when it is ready. The following timing diagram shows how it goes with the 3 buffers. Traditional LabVIEW queues don't fit here because we have large buffers that we don't want to copy. I tried to implement it with notifiers, but there is always a risk of a race condition between the producer selecting where to fill next acquisition, and locking by the consumer. With condition variables, it is easy because when a wait ends, a mutex is locked. There is no such synchronization primitive in LabVIEW. How can I implement this? (cross-posted on the dark-side)
  2. It flattens / unflattens the variant, replacing its type by the one of the other variant (so it's like a raw type cast):
  3. Oh OK, so the problem is that the wire type of the variant needs to be of the object type. The fact that it works for objects that are not inside a cluster was misleading, though. In my case, where I don't have the wire type in the diagram (because it's generic code), but only a variant of it, "preserve run-time class" can't be used, so I had to copy give object variant the type of the source object, and it works correctly: Thanks a lot!
  4. I hope someone can shed some light on this problem that arose when working on object serialization with JSON API Take a cluster of two elements with an object inside it, make it a variant, and cast the wire of the inner object to LVObject. For this I use the OpenG's LVdata library, that allows to access the contents of cluster as an array of variant. Then, still with LVdata, put it back in the cluster. The variant should be compatible with the original data, but it isn't, you'll get an error 91 (incompatible variant) when converting back to data. If you don't cast, or if you convert to the object that came after the cast, the conversion is fine. You may ask what's the point of this code: from a deserialization, it allows to get data back from a JSON string that represents a cluster with objects inside. So it would be really great if I can make it work! Is it a bug or a "feature"? What can be done to correctly get my data back? Attached the piece of code that demonstrates the problem (LabVIEW 2011). Cluster variant and objects.zip
  5. CharlesB


  6. Thanks for clarifying; performance isn't an issue for me, as it'll be used for configuration files loading, which happens at software start, so even if I get 1 or 2s hit it's OK.
  7. You have to install it from VIPM (LV Tools Network), it's called "Class Retrieval". And it's indeed a NI package from Allen.
  8. It's in <vi.lib>/NI/Class Retrieval/. Basically it is built around a FGV that holds a lookup table between class names and paths, and when ran from LV2013 it delegates this to the native VIs (that are password protected, since built into LabVIEW). For pre-2013, if the class isn't found in the table, it asks uses LabVIEW's project introspection to find it, so your classes just have to live in the project. When ran from an executable, you have to preload your classes to fill the lookup table (there's a VI for that too).
  9. OK I found NI's "Class retrieval" library that does the job, in the NI Tools Network, but the minimum requirement is LV 2012, though I'd need it for 2011 It could have been a matter of saving the library to LV2011, but there are password protected VIs like "2013 Get LV Class Default Value By Name.vi". This VI is precisely aimed at using builtin 2013 functionality when run from LV2013. For now I've came up with removing this code that uses 2013's bultin VI, and always use the pre-2013 workaround. FWIW I need it for implementing class instance deserialization in the JSON API.
  10. I'm looking for the pre-LV2013 version of this VI, that works from a FQN, does anyone have it?
  11. I'm discovering this library, find it to be very mature, and the best replacement to the aging OpenG's variant config library, and more practical to use than AQ Character lineator, that requires to manually handle each field of your classes or clusters. I'd have a suggestion to handle numbers with units: currently it's not recognized as such, and outputs the raw binary representation. I think it should at least issue an error, or represent the unit in the JSON string. I tried to look at what can be done for the latest case, but ran into two problems: First, in order to serialize the unit you have to get a string representation of the unit (like "m.s^-1" for a speed number), which is quite difficult. You just get a cluster with base units and exponent, using vi.lib/Utility/VariantDataType/GetNumericInfo.vi. And also it's difficult, if not impossible, for the JSON representation to set the correct type back. A solution can be to not output the unit string with number, and convert it to raw number in unit base, using the "Strip Units" VI from OpenG Data library. This is what variant config library does, in the "SGL PQ".."EXT PQ" case of "Read key (variant).vi". The other point I'd like to share is that I have some classes that I would like to serialize. Can we imagine the following thing, à la AQ Character lineator: A class wants to be serializable, and thus defines methods "to data" and "from data", which take a variant as their respective input/output. Internally this variant would be a cluster representing private data. JSON API, when meeting a class instance, just needs to call the "to data" method VI and pass the resulting variant to "Variant to JSON", and serialize the real class name next to it. On deserialization, JSON creates an instance from the real class name, and call its "from data" method VI. This would require of course that these classes to inherit from a "serializable" class. What do y'all think about this?
  12. I could find my way in the vi.lib/addons VIs, source is cristal clear so it was easy to find what to disable
  13. Hi, I'd like to add my vote for drjdpowell request, seeing all that all terminal labels moved when it's not the adopted style for labels creates kind of a mess on my diagram... Also, I couldn't find source code, is it available? Cheers, Charles
  14. I Found the relevant discussion for the "assign parent's data to a child" problem, which allows me to keep my design simple. Strategy pattern is a bit overkill here, and although Daklu's solution (manual copy of parent's private data) in this thread has its drawbacks, it's the simplest solution to me.
  15. It's the pragmatic solution compared to a strategy pattern, but not satisfying from OO desing point of view. LabVIEW can be so frustrating some times... I really wish I could create this child object from a base class.
  16. I'm designing a generic motion system, where an motion axis is an class, with Move/getPosition/Home etc. I want to extend its behavior to handle backlash. It requires to extend the move method, so if I don't want to modify the original Axis class to keep it simple and generic, I make an HysteresisAxis class that overrides the Move method, in which correct move commands are issued to correct backlash. Fine. But how do I extend it dynamically? Meaning that given an existing Axis object, I want to enable hysteresis handling by creating an HysteresisAxis object from it? Without manual copy of the private data fields? My only answer is the decorator pattern: the HysteresisAxis actually holds the Axis in private data, and override home, getPosition, etc to invoke the Axis' method. The problem with it is that it requires to recreate all Axis methods as dumb methods that calls the decorated axis, which is a bit far from inheritance original idea... Is there any way to clone an object into its child class, or some other solution to my problem Thanks for your insights Charles
  17. My 2cts: the controls provided by the the "Missing" System Control Suite include system buttons with pictures.
  18. At some point of the day I thought about asking user to give an intermediate base class that inherits SM's base class, but that's impossible and nobody will bother. We reach the limit of LabVIEW OO model (why don't we have template or duck-typing ?). OK. I'm just not used to this paradigm (copy and paste) for giving librairies. Template updated? Download update and re-customize it.... True Attached. You mean something like interfaces ? Seriously, I think it's better to ship code with standard queue (thus no shiny error cluster message), if users have their framework they can use it instead. Also, IMHO the model you use in slave queue is a bit complex, maybe you can give people just an input queue to trigger state changes and they'll message what they want on output. In my case for example I already have Model VIs (in terms of MVC) that message the stuff out to View. I'm no guru enough to make a nice stuff, and by short of time I think I'm gonna use the SimpleSM.vi you posted, which perfectly fit my need for a simple and clean SM. I'm frustrated by the nice stuff you can get on C#, but LabVIEW just can't enable us to build such a quick and clean thing. Maybe a simple thing would be to provide the SM with a dictionary of state->trigger->next-state? Would be glad to help but sincerely out of time LDSM.zip
  19. Hi there, It's great to have a simplified version of the object-based SM. A few comments on the last version you posted: - I would definitely go for a vi.lib version. Having to duplicate the SM base code is counter-intuitive and will keep people from using it. This is also useful if you want to have several SM in the application, or even nested SMs. The work required to switch to such a version is not difficult: I already done it, for now I'm passing the initial state as an argument to Execute.vi, and modified "create base state" to take as argument the state type you want to create. - Binding the SM to a particular messaging framework is not great, also. Not that the lapdog one is bad, but people are surely using their own one, so we should let them choose. This way you have a SM framework doing only SM, and people add messaging with customizing the base state, or something like this (surely there's better way) - These 2 points allow to make a true VI package I'm still working on making a simple example without messaging and "library-based", if anyone is interested let me know
  20. Wow, thanks! I was working on a generic SM based on your code too, and just finished when I saw your answer Never mind, it got me diving in the code. However I think the attachment is still the old code
  21. I downloaded and looked at the code, it looks great! I have a few questions, though: Transitions seem to be handled in Entry and Exit actions. But what if I want an action to be executed only in a from one state to the other? (i.e. a transition action) I will use the SM from the GUI, which will trigger state changes. Can I use the SendMessage method for that? I ask this because it is currently a private method of the SM What needs to be done if I want a more generic SM class that will be inherited, in order to be reusable from one case to the other? Have you considered to make it an OpenG package? Charles
  22. Thanks, I had found it since. See some questions I asked on this thread.
  23. I realize that the thread had diverged on different errors, so just to precise that this is about error 1502 (cannot save VI in bad state)
  • Create New...

Important Information

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