Jump to content

Mark Balla

Moderators
  • Posts

    607
  • Joined

  • Last visited

  • Days Won

    41

Posts posted by Mark Balla

  1. I guess this locking business is one point that caused me to think that the data would be leaving the class. Inside the class is a small protected environment that I would expect to be single-threaded. Outside the class no assumptions about how or when the data is accessed can be made. Why bother with the locks if the environment where the data is used is well defined and protected?

    For a decent size class there will be many public function using the same data cluster. The locking insures that only one public vi at a time may change the data. This is more apparent when using classes or even functional globals in multiple while loops.

    The locks will prevent the following situation.

    PulblicOne.vi reads data cluster (A)

    PublicTwo.vi reads data cluster (A)

    PublicOne.vi unbundles STR data, changes it and bundles it and writes back the data cluster (A & STR).

    PublicTwo.vi unbundles NUM data, changes it and bundles it and writes back the data cluster (A & NUM) not (A & STR & NUM).

    PublicOne's change is lost because PublicTwo did not read the STR changes.

    Its the changing of one data item and assuming that none of the other item in the cluster have changed that causes the problem.

    The locking of the data cluster would have forced PublicTwo to wait until PublicOne had completed its change.

    Tracking down a lost data problem is very difficult.

    Timming is a major factor and when you try to find the problem you change the timming.

    Here is an example showing why locks are important.

    the counts of each loop should follow the itteration number

    Download File:post-584-1142554592.llb

    To do the same thing with out locks you have to keep all of data change functionality inside a single Functional global to insure no other

    vi has access to the data while it is being changed.

    There are probably other ways but the dqGOOP locking method to me is the eaisest way to keep the data safe.

    "Gee, that works great! Now we need to run this camera too" followed by "oh, by the way, we need to control this illumination source" and so forth.

    It sound like you too have fallen victim to the dreaded "SCOPE CREEP" :ninja:>>>>>>>>>> :o

  2. I guess I was thinking of it as a protected data store or as a data library that allowed reading or updating (check-out, modify, check-in). It would only be global to the motion control module.

    Do you use your classes for something different?

    I think of them as dynamic objects. What they do is as important as what data they hold. Checking in and out (which implies some external object takes control of the data) is not allowed. However Requesting changes and viewing data is permitted through public functions only.

    Inside a change public function the object is locked.

    The data is tested, changed and written in to the cluster

    and them unlocked.

    The data never leaves the class.

    So, if for example I need a GUI to update some aspect of the static data like maximum-allowed axis acceleration, then that GUI needs to be one of the functions built into the class rather than checking data out, allowing the user to modify it and then checking it back into the class?

    How about this instead.

    The GUI would like to increase the maximum acceleration. It calls the public function "Change Acceleration.vi" and the function makes sure it is capable and then changes the acceleration value. It then returns the values that was actually set.

    Sticking with the motion control example, why can't an upper level module (beyond these static & dynamic axis data classes) include a GUI which provides the user the necessary information and means to move an axis and in doing so the upper-level module would access the static class data to determine the bounds of movement and it would access the dynamic class data to determine the current axis state? IMHO, it wouldn't be reasonable to try and shove the GUI and the running of the motion controller down into either the static or the dynamic classes because they are both needed to get the job done (so which one do you pick if you are intent on shoving the GUI down into one?)

    If you think of a class as a group of functions that manipulate data and not a global variable that needs help, then

    I think there isn't a valid reason to separate static data from dynamic data.

    How often a data object changes doesn't make the functionality less dependant on its values.

    Since we are using motion as an example here is how I would frame the solution.

    I would create an Axis class

    Its data cluster contain thing like acceleration, velocity, position, tuning constants, motor com reference, rotary encoder count/rev, gearbox ratio......

    The private vis manage things like communication, syntax, conversion of counts to degrees, maybe even plug-ins for different controllers.......

    The public vis are the interface to the class. their inputs use real world units like Degrees and seconds.

    All the public function are tested to make sure they work as expected. Even unexpected data is used to insure the class is robust and can adapt to bad inputs.

    When I'm finished I have a stand alone class that can be used by any program that wants to use an axis. A program that uses the class doesn't need to know how to communicate with the motion controller or how to convert degrees/sec to counts/sec. It only has to know where it wants to go and how fast it wants to get there.

    If I find I need more functionality I create a new public function and it is automatically usable by all axes.

    If multiple axes are needed then I would create a multi axis class to do the coordination. This class would have an array of axis class references inside the data cluster.

    Now the GUI is much simpler to write because it only has to be concerned with the user and the multi axis public functions.

    If the axis class is written well I could even change the motor controller brand without affecting the GUI.

    Robustness, flexibility and modularity that

  3. Thanks for the reply!

    If I create a subclass of axis to the instrument class (which is the only class I was previously envisioning) then it seems like I'd be adding a lot of extra GOOP overhead to the access of the axis data. I would be replacing simple INDEX ARRAY and REPLACE ARRAY ELEMENT functions (which would otherwise be buried in the public methods of an instrument-only class) with more complex GOOP public & private methods to do exactly the same thing. Is this really good thing? Why would it make sense?

    If we assume it is a good thing and I do decide to use both an axis and instrument class then from a purely-LabVIEW perspective I would still use a cluster of items to characterize an axis and an array of those clusters to characterize the system of axes. From a GOOP perspective then the cluster of items for an axis would become the class for a generic axis. Then would I use an array of those clusters for the instrument class or should I instead use an array of references to the axis class?

    But is it considered acceptable to just read/update the entire class (typedef'd cluster) rather than individual attributes? If my class (cluster) has 10 attributes (items) in it, then why bother with 10 connector pane connections when I can just use one for the cluster? Am I supposed to be keeping the cluster hidden/private?

    It sounds like you are thinking of a class as more of a global variable.

    In a class data is manipulated only by its public and private functions.

    If you hold to the strict class rules, programs out side of the class can only access the class through public functions. Only public or private functions may access or change the data cluster.

    Any function that manipulates the data cluster should be a part of the private or public class functions.

    This allows you to encapsulate the class and makes for easier debugging.

    So every time you want to add more functionality to the class you would create another public vi to do so.

    Yes it does create more overhead but I think you will gain flexibility and robustness.

    like this nonModifying.vit:

    post-2800-1142257535.png?width=400

    I have a similar template in my goop structure. It is used when I need to combine two or more public vis together. An example would be a standard motion profile that calls a public single move vi several different times with pauses in between.

    1. I'm impressed by the graphics used in the refnums. It never did occur to me to customize the controls with pictures.
    I think they add a definite cool factor to the Goop vis :thumbup:
    Although sometimes the graphic creation takes more time than it should.

    1. You are the first person I've found (besides me) who is using Galil motion controllers with LabVIEW.
      I've always found that to be a bit odd because IMHO they are very nice controllers to use.

    I'm very fond of Galil.

    They have great Products

    Excellent Support

    And like NI the people at the top are very technical minded.

  4. I'm having lots of problems when I try to transfer information between these classes.

    The problem I'm having is that in my user interface I'm not sure how to call the createpath class and transfer these values to it so it can perform its function.

    Thanks a lot in advance!

    My solution to this challenge is to create a Master class that contains all of the other classes.

    Here is the Data Cluster of a Class that I am currently working with. It represents a Test Bay.

    post-584-1142142636.png?width=400

    All of the class objects for this class are created in the Master create vi.

    post-584-1142143074.png?width=400

    When 2 or more separate classes need to work together their referenced are easily accessible inside a public function.

    post-584-1142144067.png?width=400

    Hope this helps.

  5. I have a VI that is executing a case structure and within it are twe events in the same structure where event 2 requires event 1 as an input. I have put event 1 right above event 2 but the program is picking event 2 before event one and hence confusing the process. Is there a way I can condition the VI that event 1 has to be perfomed first before event 2 in the same case? Thanks

    Posting your code or some example of what you are trying to do would make it easier to help you.

  6. Another useful tool when building a user interface was given to me by njkirchner.

    The propose is to put a Front Panel in it correct position at run time.

    The steps to use it are as follows

    Position the Parent VI in the desired runtime position.

    Place the FP size and position vi on the block diagram.

    post-584-1140327646.png?width=400

    Next open the FP size and position vi and click on the Set Values button.

    post-584-1140327802.png?width=400

    Now run the Parent vi and stop it.

    The position values with be filled in and the Set Value button will be set to false.

    Create constants on each of the position inputs.

    post-584-1140328069.png?width=400

    Set the Move Window input true if desired

    post-584-1140328299.png?width=400

    Finally if you move the front panel of the Parent to a new location it will always come back to the same spot at runtime.

    post-584-1140327992.png?width=400

    Download File:post-584-1140328475.llb

  7. As i said in the other forum, im new to LabVIEW and having to teach myself and was wondering if anyone had any problems for me to try our any methods or fun stuff to do. I hope someone can help me out. Thanks.

    Try programming a radio button control that works like the one in the NI controls pallet.

    The key is to be able to add as many buttons as you want to the cluster without changing your code.

    This exercise should covers shift registers, array, clusters and bool logic.

  8. I noticed a couple of drawbacks with the DQ3 syle of GOOP. One was that there is no way to find all of your active objects. You have to remember them somewhere else and get them. The current templates could be updated with a LV2 style global to remember all of the names and corresponding queues. They could then be created, retrieved, and removed from this repository.

    My solution to your issue would be to create a Master DQ3class that manages the other minor classes. The Master class would have an array of

    minor class references in its data cluster.

    Essentially DQ3 is a type of global variable just like LV2. You could just as easily create another DQ3 class or a Single item que to do what your requesting.

    The other thing I noticed was that the -1 timeout would timeout right away during the DQ3Class_getDataToModify.vi. I think this was just overlooked?

    Yes I believe this was an oversight.

    Here is the current template I use if you are interested.

    Download File:post-584-1137095989.zip

    Support Files are Now included. Thanks Michael,

    Ok lets try again

    Download File:post-584-1137308121.zip

    And here is the template with everything included

    Download File:post-584-1137308268.zip

  9. Hi,

    M/M/1 is a single server simulation model in which we have poisson arrivals and exponential service time and there is only one server. This model is simmilar to a bank teller in which people queue up for their turn for getting served. This way we can evaluate the performance of a simple single server queuing system.

    Faisal Iradat

    If you select File\New.. and in the tree view select (Vi from Template\Design Patterns\Producer/Consumer Design Pattern). This is the standard user consumer configuration.

    Referring to your example.

    The upper loop would be the people waiting in line sending requests.

    and the lower loop would be the bank teller.

    I've attached my template that I use. Its a bit more advanced than the Labview example.

    Download File:post-584-1130172767.llb

  10. Burt, right? Actually, he had a surprisingly good performance in Boogie nights. I liked that movie.

    And lets not forget Smokey and the Bandit. Man can that guy drive a Trans Am or what.

    As for attractiveness, Jodie attracted a Lunatic while Burt got Loni.:worship:

    post-584-1129092754.jpg?width=400

  11. Since were talking about multiple monitor.

    Does any on know of a way to add a second graphics card to a laptop?

    I'm am soon to receive a new laptop from IT but I will have to give-up my dual monitor desktop.

    I'm looking for a way to get the best of both worlds, portability and bigger desktop.

    I saw that APPIAN use to make a PCMCIA graphics card but it is no longer available.

  12. Going forward, if you think it would save the consternation for you and everyone else I could password protect the block diagram of anything I thought might be of value to others and use the time honored excuse others have used that the "code was just too messy to let others see."

    Would that be better?

    WMassey

    I would greatly discourage you from taking this course of action in the future. No one learns anything from locked diagrams.

    However I would also encourage you to enthusiastically defend and explain you coding style and techniques. I

  13. I need to know if they clicked the 'show details' button for a particular cluster. This is like a value change event on a particular control in the cluster. The problem is, there are a bunch of these clusters, so I don't want to create specific event cases for every 'show details' button in every cluster. I would rather have one generic version that uses the 'passed-in' cluster reference to determine which cluster to look at.

    I guess basically what I want is a 'which control in which cluster triggered the mouse down event' event. Does that make any sense?

    Thanks for any help or suggestions on this.

    -John

    Here is what I came up with. It will only work if all the clusters in the event case are the same.

    post-584-1127782924.png?width=400

    Download File:post-584-1127782943.vi

  14. I can probably help but I need more information

    I've an input array A[255]

    such that A[0] to A[3] is considered as a block

    Therfore totally 64 blocks (from Block 0 to Block 63)

    How does this equate to 255 is it a 4x64 2D array or a 1x255 1D array

    I'm confused as to what exactly a block is. Is it an element in the array or a group of elements.

    I'll get a command with Start block and number of blocks to read.

    Start Block= 0 to 63

    Numblocks=1 to n n depends on the Start block

    i.e if Start Block=0 then the NumBlocks=1 to 64

    if Start block=1 then NumBlocks=1 to 63 ...

    so 2=1 to 62

    and 63=1

    n(NumBlocks)=1 to 64-(Start block)?

    i need to frame an output array for all the combination.

    what do you mean by frame? 1D array 2D array

    to make it simple i want to use loop.But i cudn't make it up.

    Pls do the needful

    Thanks and Regards

    Supriya

    It would help if you could post the code you are working on. If I can see what you are using for input and outputs it is much easier.

    Also remember to save it as a development distribution llb before posting.

  15. Thanks! :thumbup:

    I really liked the idea of moving the table modifications to the lower loop.

    You nailed me on the error trapping. I often build quick examples without the error trapping. Later I end up modifying the example for use in an application. I loose as much time editing these programs as would be lost error trapping the examples. Thanks for the prompting here. :oops:

    The file IO was the only one that concerned me. When I see file IO I think errors.

    At NI week once, I thought it was taught that without the shift registers the program would need to generate a new copy of the data with each iteration. Also in some earlier versions I had some applications that appeared to loose the value inside a loop after executing several times. These may be figments of my imagination. I checked the buffer allocation and it doesn
×
×
  • Create New...

Important Information

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