Jump to content

AlexA

Members
  • Posts

    225
  • Joined

  • Last visited

  • Days Won

    2

Everything posted by AlexA

  1. I was doing some light reading and I noticed that Labview apparently stores Boolean data as bytes, where 8 zeros indicates false and anything else is true. Does anyone have any insight into the logic behind this decision? This is not an important question just a curiosity. It seems like an awful waste of space for embedded applications like FPGAs.
  2. Hey Daklu and James, Very interesting discussion, lots of insightful stuff. Thanks Daklu for your reply, yes in answer to your question, it was extremely helpful! The following is tangentially related to the discussion at hand, just musings on my part with any insight very welcome: I've spent a few hours trying to figure out how best to build a database of different queue types, and have come up with the idea of using a Class (Object Queue Class) whose private data is a Queue Reference to a queue of LV Objs. This Class has methods "Init Queue" and "Get Queue Ref" at the moment, Init queue takes an Object as input, where the object is whatever Data Class I want to make the queue. Get Queue Ref gives me the reference, then I can enqueue an element of type Data Class and dequeue, cast to more specific then read. This works for my test case, I was musing on whether it makes more sense to create an individual Object Queue class for each data type, haven't tested it but I imagine it would allow me to see mis-wirings at edit time rather than at run time which the current case does. Anyway, the whole point of the exercise is that encapsulating the queue references allows me to store them in an array and I guess search it for a specific reference by trying to cast to the reference and handling errors, though there may be an even better way to do this taking advantage of inheritance. More play to come.
  3. Hi Guys, I currently have an issue where I'm feeding a relativeley large data set into the FPGA FFT (524288 points) which are computed as 512 1024 sample length transforms (rows of image data). Despite receiving the correct number of valid inputs (I've checked), the FPGA only returns 522240 points (it's two rows short), can anyone illuminate why this is happening? The code snippet is shown below.
  4. AlexA

    FPGA FFT

    From the album: Code Pics

  5. Hi Daklu, I imagine you're busy but I was wondering if you could weigh in on the following question (from an earlier post). What would you do if you wanted to be able to close and reopen your slave loop without locking your code up? What I'm getting at here is, what is the OOP equivalent to launching a sub-vi using a Run VI method with "Wait Until Done" set false? Or, as an even more abstract question, how does one implement a plug-in type code structure where the functionality is determined at run-time? Also, if you're slave process should be continuous except when handling messages, do you utilise a timeout method, or do you separate the behaviours within the slave by adding another layer via a separate message handler? Thanks for your insight!
  6. So, due to my inexperience with LVOOP, I'll just say what I've done so far in trying to recreate what you guys are saying, and you can tell me if I'm on the right track. I've created a library for my singleton which contains a parent class called "Abstract Queue". The data of this class contains a generic queue reference (the default happens to be string). This class has child classes, I32 Queue, DBL Queue, etc. The library also has a VI called "Get Singleton Data Base.VI" set to private scope. This VI obtains a queue of type "Array of Abstract Queue" (it has to be an array to store as a database right?). The parent class has a method "Add Queue" which takes an "Abstract Queue" and "Array of Abstract Queue" as input and uses the build array prim to add the former to the latter. I anticipate over-riding this method for each child class. Am I thinking of this right, or have I got turned around somewhere? Each child classes "Add Queue" method takes "I32 Queue" and "Array of Abstract Queue" (or equivalent) as input. There will be a VI in the library which is called Add Queue or something similar, which will take call the Add Queue method (which is over-ridden for each child). Things I'm worried about but haven't had a chance to test yet. 1) Does the typecasting dot which appears on the "build array" prim mean that the information contained in the child queue objects will be lost when it's built into the array of type "Abstract Class"?
  7. Hmmm, Ok, worth playing with. I think I'm about 80% of the way to what we're talking about with the AE (FGV) approach. If I turn it into a singleton as mentioned above (I'm pondering whether it can be done without LVOOP) it should work.
  8. Yep thanks James, the handshaking has been on my list of things to do, the 3.5 hour compile times for the code have been putting me off!
  9. Hi Mikael, That idea was something I was playing around with in a blank project. How would you handle the fact that only one VI should be able to "subscribe" to a queue at any given time. You can't just base it on the singleton lock out idea as there are other operations which might need to take place (such as adding a new queue ref to the "data base").
  10. Hey guys, I'm faced with the challenge of having a plug-in type architecture where one of the primary plugins is responsible for listening to an FPGA DMA FIFO and placing the data extracted into a set of queues which can be obtained and then destroyed by any number of consumer VI's (in sequence, not simultaneously). The way I've been doing this is to maintain a "database" of queue references encapsulated inside clusters, the database is maintainted inside an AE. So the input to the AE is of type "Data Queue Handle" which is a single element cluster of type "variant". The data queues created are loaded into these clusters and then added to an array inside the AE. To obtain a data queue, a consumer will search through the array for the variant type which matches the queue type it needs (the one that doesn't return an error when the cluster is passed into the "variant to data" block). This is functional, but makes me feel icky for some reason. I would like to just pass the raw references into some sort of database, which can then be chosen by a simple Equal? comparison. I can't figure a way to do this inside an AE though, as you can't build an array of different data types and you couldn't have a single input to accept all possible Data Queues. Maintaining clusters of clusters of clusters is impractical and even more icky. So, to summarise the question. How would you construct a routing house type function for queue references, which can be searched by any function which knows the right command? I guess I could manually maintain a Typedef of the different data queue types as they're added to the project, then simply talk through that type def. Hmmmm
  11. Hi again guys, I've had my FPGA code running for a while now, but I'm hesitant to trust it, because I don't really understand the concept of handshaking and throughput. Say I have the following block of code: My question is, if the multiply takes 1 cycle/sample to compute (and this goes for all blocks that say they take 1 cycle/sample), does it return its result on the exact same cycle that it receives a valid point (I.e. when divides "ready for input" goes true and a deviated bin element is dequeued from the FIFO). OR Does it take another cycle and thus, I should always load the result of multiply (and any other high throughput maths) into a shift register to be absorbed by divide on the following loop iteration? Thanks for your help. Alex
  12. AlexA

    HandshakingQuery

    From the album: Code Pics

  13. Interesting way of looking at it Ned, thanks for the insight.
  14. Hi Guys, Tinkering with my FPGA code today, I ran into a question which I'd never really contemplated before. Say I have an unsigned FXP number with word length = 1 and integer word length = 2. Labview tells me that this gives a maximum of 2 with a delta of 2, so the number can either be 0 or 2. This makes no intuitive sense to me, the way I understood it, the word length is the total number of bits used to capture the number, the integer word length is the number of bits dedicated to capturing the integer portion, in other words, it kind of defines the "magnitude" of the number that can be captured, the remaining bits are used to give the "precision" to which the number is captured. So how is it even possible for the "integer word length" to be greater than the "word length"? Insight much appreciated. Cheers, Alex
  15. Hi Daklu, Grrr, I know what you mean, I just lost a post . Anyway, I was saying that I've figured out that new slave loops should be children of your parent class with different execution loops (blindingly obvious in retrospect). I've struck something strange though. The children don't seem to actually inherit the parents data type (the messenger queues). The same messenger queue types need to be placed into the child data.ctl file manually or else the childs execution loop, which I've copied from your parent and exchagned the object type from parent to child, is broken. From my own experimentation and understanding, children should always inherit all the data fields of their parents, even if they're not visible on the child data.ctl front panel, correct me if I'm wrong. Here are some pictures showing what I mean. With inheritance checked in the class properties but the data not manually moved onto the child data.ctl file: With inheritance checked and the data moved in manually: Your thoughts? Cheers, Alex
  16. As per Daklu's request in this thread, copy and pasting discussion on the slave loop idea.
  17. Hey Daklu, Yeah it is probably possible. Right now I'm sipping my morning coffee and going over your Slave Loops concept. I feel that it's probably very similar to what I'm trying to do with my code but implemented in an OOP sense. Hopefully I can draw some parallels and a light will click. I'm particularly interested in the idea of launching and shutting down a slave process as needed. I've gone through a really torturous route of wrapping each process inside a message handler framework, with an FGV pertinent to each process which is solely responsible for passing the stop message from the message handler to its process. The "process-nested-inside-message-handler" is in turn launced by a master message handler which handles input from the user to determine what tests should take place. I just had a blinding realisation as I wrote this that I could have handled this much simpler with a 0 time out queue in each process that listened for a stop message and if timed out did whatever the process was trying to do. One of the key assumptions that led me down my torturous path was that I must have a default case that handles messages which don't correspond to real messages. *Realisation* In fact, I could just use the timeout line on the queue to nest another case structure and still handle the default (incorrect message) case, gah, so much time wasted. From looking at your slave loops template posted in this thread, am I right in assuming that if you wanted a different slave behaviour (a new plug in if you will), that you would merely make a new execute method in the SlaveLoop class? Or would you instantiate a whole new child class of SlaveLoop.lvclass with its own execute method? Following on from my confession of my own wrangling efforts, how would you formulate one of your slave loops that needed to be a continuous process but also accept stop commands, would you use the timeout method I thought of above, or something else? What would you do if you wanted to be able to close and reopen your slave loop without locking your code up? What I'm getting at here is, what is the OOP equivalent to launching a sub-vi using a property node with "Wait Until Done" set false? Thank you for the opportunity to pick your brains! Your posts are always amazingly informative, even if it does take me months for things to finally click into place...
  18. Mr. Manners I'd just like to reanimate this thread to second your commitment to learning how to LVOOP. I've just spent the last week adjusting and readjusting plugin type VIs over and over, having to manually implement the same changes across each VI every time I uncovered a new bug in my implementations. Ugghh, now if only I could wrap my head around how to think about the launch methods for classes and equate that with running Sub-VIs programmatically, I think I'll be able to crack something important! I need to set aside some time to sit down and try and DO, not just scratch my head over what's possible and not possible. If only I had more time!
  19. Hahahaha, Thanks Daklu. I do appreciate the work that's gone into LapDog, and it does seem like a really elegant and light messaging system. Unfortunately re-engineering my code (again) is being swiftly pushed down the priority list in favour of moving onto other more pressing projects. Hopefully I can come back to it at some point, and I'll definitely consider using it as the back bone of my future projects.
  20. Hmmm, I've read over the thread associated with LapDog's release on the Lava forums, and after playing with setting up and sending messages around using LapDog, I can understand the appeal of "strict" security implicit in using message classes to send data around, but it seems that it's a safer OOP duplication of variant type messaging? Please bear in mind that the above is in the context of my very poor understanding of OOP, as such there may be some inate power of OOP that I've missed when playing around (more than likely).
  21. Ok, it seems it's working now. I honestly have no idea what it was doing yesterday but I assume some sort of corruption on download or something like that. Anyway, I'll have a play around and see what I can make of it.
  22. Hey Daklu, Thanks for the insight. I've had a look at Actor Framework but concurred with someone who described it as not being suitable to drop into an already established project without massive re-engineering. I wanted to have a look at LapDog but when I downloaded it. It doesn't seem to run correctly. Double clicking or running the .vip package will cause the VIPM package handler window to open but almost instantly close again. I was trying to install it for LV 2011 if that makes any difference. Once again, thanks for your insight on re-entrancy! Alex
  23. Sorry about the second post, I had to refresh page so can't edit my OP. I've managed to narrow down whats causing the lock. When the "Dequeue Message.VI" is placed on a block diagram in two separate while loops and asked to operate on two different queues in your typical asynchronous fashion, it will lock. So I guess I've answered my own question (it seems the only way is to make it re-entrant), but now I'm left wondering why this should be the case? Also, is the answer (while avoiding re-entrancy) to make the message handler sub-vis into methods on a message class? I don't know why I'm scared of re-entrancy, I just feel like maybe it will introduce some bugs that I can't predict (due to my lack of knowledge). On a related question. If I take the approach of making the message handling code OO, would the resulting memory footprint be similar to multi-clone re-entrant execution? Or somehow similar to single memory instance re-entrant execution? (Which I'll admit I haven't yet tested).
  24. I recently went through my code wrapping all my dequeue prims inside Sub-VI's which I've called Dequeue Message.VI. It's a simple wrapper that handles some basic errors such as queue reference loss and prettys up the unbundle by name code a little bit. I noticed that messages enqueued weren't getting through to the dequeue. So I poked around a bit and discovered that the reference inside the Dequeue Message.VI was different to that outside. My best guess was that somehow because I was using multiple instances of this Sub-VI concurrently, when debugging, I was looking at a different instance of the Sub-VI. Even so, they shouldn't be "losing" their message, my best guess was somehow the multiple instances were causing the Sub-VI to lock. Which sounds like bs even to myself as I was under the impression that every time you dropped a Sub-VI into code, the compiler effectively inlined another copy of that code. In other words, from all my understanding, it should be possible to drop my Dequeue Message.VI into any number of loops and each dropped copy be independant of the other. Anyway, just to see what happened, I changed the execution of "Dequeue Message.VI" to allow re-entrant execution and allocate different memory for each clone. Lo and behold, it worked. Can anyone explain why this is so to me? Also, if I've done something crippling obvious that means I don't have to allow re-entrant execution, please let me know. Edit: I've pulled the code apart and created a scratch pad type test where I just passed a message from one loop to the other. It behaves as expected, even with the dequeue hidden inside a sub VI. I'm completely stumped why, in my main set of code it's hanging at the dequeue...
×
×
  • Create New...

Important Information

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