-
Posts
1,986 -
Joined
-
Last visited
-
Days Won
183
Content Type
Profiles
Forums
Downloads
Gallery
Posts posted by drjdpowell
-
-
Indeed, "Set Rate formula" was for an example, I'm going to “Show Device Configuration UIâ€.
All Devices can implement “Show Device Configuration UIâ€, so you do not have any problem.
In fact I need. My problems with clustering all children are that I don't know how to retrieve programmatically a cluster i-th element, save to replace it with an element of a different type (unless they are all variants), and that growing the cluster may be problematic; and with arrays of different device types, that each future device type would require a new array. Better to plan ahead.
Your mixing two incompatible statements: you’re code is generic enough to switch types, but specific enough that it must use one specific type. If you organize your code in levels, generic and specific**, then each level will be a lot cleaner.
**Note that you can have intermediate levels, such as a generic “power supplyâ€. Code can know that it is using power supplies (rather than generic devices) but not depend on the type of supply used.
-
But if I group heterogeneous devices in an array, the array becomes of the ancestor class, and I lose the access to peculiar properties.
I think your conceptual problem is here. Your high-level, handles-array-of-generic-devices, code shouldn’t want to know anything about specific device properties. One of the biggest advantages of OOP is the ability to have generic code that doesn’t need to be complicated by a 1001 specific details. Anything specific needs to be pushed down a level to the specific child classes. The high-level code may have dynamically dispatched methods such as “Get Device configuration as Stringâ€, “Set Device configuration as Stringâ€, “Get Human-readable Device Statusâ€, “Show Device Configuration UIâ€, and so on. It should never have anything as specific as “Set Rate Formulaâ€.
Now if you do need to write specific code that “knows†what the devices specifically are, then use a cluster, not an array (note that you can use a cluster of arrays of specific types if you have a variable number of each device type).
-
The distinction between an actor and a service is somewhat lost on me.
Ignore it; it's not relevant to your OP.
-
Oooh. You are so close. Won't be long now until you're talking about services instead of actors
My actors are already services. They’re private, rather than public, services, so access to them needs to be explicitly passed. Rather like an unnamed Queue is different from a named Queue.
It makes me want a “Tastes Like†message that tongue can send out to “registered recipientsâ€. Other actors can route the message through the tree to the destination without knowing anything about the contents (like the post office).
If I were to adopt the AF, such a “Notification†and “Routing†system using “Data Messages†would be the first thing I would do. Mouth would register for (and re-notify) Tongue’s Data Message. Brain would register Chew to receive Mouth’s re-notified Data Message (originally from Tongue), contained in a “Command Envelope†that tells Chew what to do with the info (Command Envelopes illustrated here).
-
I wondered if anyone, who has used this package in real-world applications, would kindly review it on the Tools Network.
-
A previous related conversation:"Decoupling message based systems that communicate across a network"
Added later: I'm a strong proponent of message decoupling, even with the string-labelled messages I use instead of the Command pattern. I never want a component to explicitly contain text commands for anything that isn't a subcomponent of it. Instead, and command text is injected as part of the "reply address" attached as part of the initial message received from higher-level code. This has the great advantage of making it easier to follow code, since I don't need to place any actual commands in the low-level actors, and just need to study the high-level actors to understand the app. The low-level actors are also more simple and reusable.
-
Not for User Events i.e. the ones which you fire by calling Generate Event with some data
User Events aren’t front panel events, and should never lock any front panels.
-
Am I correct?
No. There’s a “Lock Panel until handler completes†shortcut menu item on the Register for Events node.
-
Even if the child creates the DVR, the reference's lifetime is tied to the top level VI that created it. You're going to still have to use an Async Call VI method (which will at some point call the create DVR method), so that's what will control the lifetime of the reference.
If one uses a named single-element queue, instead of a DVR, then one can get the lifetime of the queue to exceed that of its initial creator. This is because one can create multiple references to it; the queue continues to exist till all references to it are released.
-
If one needs a persistent reference, not tied to the lifetime of one VI hierarchy, then one can either:
1) Async Call a VI to create and own the reference as brink is doing.
or 2) Use a Named Single-Element Queue with multiple references instead of a DVR to hold the session data.
-- James
BTW: If I were designing a persistent session framework I would probably combine both, in order to get around their individual weaknesses:
(1) can't handle VIs that forget to call the Close Session method, in violation of LabVIEW's standard "refs don't outlive their creator" rule.
(2) can't execute cleanup code, as the data in the SEQ is just dropped.
-
There is a related thread on the Actor Framework board (reply #15 and after) where I think the DVR goes invalid.
-
Thanks, I didn't know about the synchronous display stuff. The producer is actually doing other processing tasks with the frames, and needs to spend as less time as possible on the display, which is secondary compared to the overall acquisition rate, so I need display-related stuff to be wait-free in the producer.
I suspect simply writing to an IMAQ image indicator inside the producer (and get rid of the consumer entirely) will be less overhead than your complex structure.
-
You’ll need to mark your Image Indicator as “Synchronous Display†if you want it to display before the Producer overwrites the buffer. Indicators are asynchronous by default and update at something like 60Hz, slower than your 400 frames/second.
BTW, I can’t see how this code would interface with some other process doing the main application work on all 400 frames. What do you do with the full 400 frames?
-
1
-
-
Unfortunately I can't use any async framegrabber option, because I'm doing processing on sequence of images, which disables the possibility of a "get latest frame". I really need to implement triple-buffering by myself, or I'll have to slow down the producer with copying image to the display at each iteration.
I don’t have enough of a feel for your application to give specific advice, but are you sure it wouldn’t be simpler to attend to the main processing of your 400 images per second in a simple clean way, then just make a copy for display 20-30 times per second for the separate display part, rather than invent a complex locking system to avoid those 20-30 copies? You might be able to do the display with a single IMAQ reference, making it very simple.
-
That is odd that dynamic events can't be limited like non-dynamic, to make them lossy.
I wish they would extend this to User Events. Last-only User Events could be very useful.
-
But in my case a slower consumer can drop frames (maybe I should have pointed that before), as it's just for display. So if producer is faster it must not be slowed down waiting for consumer to process every frame. Does my problem make more sense now?
Again, check that your frame grabber isn’t already buffering, with a “Get latest frame†method. That is what I would expect it to do. And this would greatly simplify your program as you’ll only need one loop.
However, you can get “lossy behavior†by getting the Consumer to flush the queue and only process the last element, passing any other IMAQ refs returned back to the C—>P queue. You might need more than 3 refs if your Consumer is very slow.
-
In triple buffering the producer never waits, that's its strength.
Uh, it aint magic. If you can consume 90 frames a second then you can’t produce 100 frames a second. In that case, a single buffer would lead to something like 45 frames/sec, as the Consumer waits about half the time for the producer. With two buffers the frame rate would still be less than 90/sec, as jitter in the Producer sometimes causes the Consumer to wait. With three buffers the jitter doesn’t matter, and one gets 90 frames/sec. But you don’t get 100.
BTW, you should check to see if your Matrox frame grabber isn’t already buffering frames asynchronously, rendering additional buffering pointless.
-
Why don’t you just use two queues and three IMAQ refs? Producer takes a ref from one queue, fills it, and puts on the other queue. Consumer takes from that queue, reads it, and puts it back on the first queue. Simple. Why do you need some complex locking system?
-
Traditional LabVIEW queues don't fit here because we have large buffers that we don't want to copy.
Are you sure of that? I wouldn’t expect a queue to make a copy of a pointer-based data structure like an array or object. Unlike Notifiers, which must make a copy on reading.
-
Version 1.3 contains the following significant changes/additions:
1) new pallet location under “Data Communicationâ€.
2) a new “DEV Actor Template†which is my attempt to combine two past templates I have used into a singular one with the advantages of both. Find the templates under “<LabVIEW>\examples\drjdpowell\Messenging\Actor Templatesâ€. This design owes a debt to the excellent JKI “state machine†template.
3) I have had a project where I have dealt with an array of actors (and analysis chain), and this has let me exercise and extend the “FutureToken†part of the library. A Future Token is a single-use address that can be used to represent and organize messages that have not yet been sent. This is mostly used to deal with the indeterminate response order when gathering information multiple actors at once (for example, when requesting configuration information from many actors for saving to a single file).
This allows the gathering of multiple response messages into a single “Message Bundle†that can be acted on as a single step. The Bundle can be easily converted into an array or cluster of the required type. (Originally described in this conversation.) This is a form of the Scatter-Gather messaging pattern.
This helper actor deals with the fact that replies to a series of requests can come back out-of-order, leaving the last reply not consistent with the last request. I developed this in an app where mouse-move events over icons representing running actors triggered a request-reply to the relevant actor to get a description for display to the User. Fast mouse moves could exceed the response time of some busy actors, resulting in an inconsistent description. This is a form of the Resequencer pattern.
-
By now, I've created my implementation with little difficulty...
Could you explain more? Your initial description gave the impression of being very complex, a lot more complex that the Extensible Session Framework.
-
If the User is comparing “runs†then how about an overlay feature. Display all plots twice (with the second plot having the same colour but being dashed to distinguish it) and provide a single deltaT time shift to the second plot. This delta can be based on something that defines the start of a “run†or can be User adjustable.
-
I believe Quick Drop uses the VI Title, rather than Name, so we can easily change the titles without causing any other issues.
String values are escaped; however I realized recently that the name strings in JSON Objects aren’t escaped. That’s on my list of changes to make when I have the time.
—James
PS> since we are listing issues that need to be addressed, the parsing fails on empty subObjects, such a {subObj:{},â€OtherItemâ€:1}
-
As a word of warning, any system of waiting on multiple different channels of information in one loop is very tricky to get right. Not impossible, but one is well advised to attempt to get away with one channel instead, or alternately with additional receiving loops, one per channel.
array of heterogeneous classes
in Object-Oriented Programming
Posted
You can still push the details into the subClass. Your generic code only needs a "Show Configuration UI in subpanel" method and a "Poll Configuration UI" method. You'll be able to write vastly simpler code in the subClass itself (no Variants, no Open VI ref, no Property nodes).