Jump to content

ibbuntu

Members
  • Posts

    21
  • Joined

  • Last visited

Everything posted by ibbuntu

  1. QUOTE (ibbuntu @ Mar 27 2008, 07:02 PM) I went back to using Shared Variables and LabView has stopped crashing. My code now works. Thanks to all who replied.
  2. QUOTE (ibbuntu @ Mar 27 2008, 10:33 AM) Ok it appears I had some messages clashing. I have now re-written the code to use the dstp protocol. The code now crashes LabView, but when I run the debugger to find out where it crashes, LabView doesn't crash. What could be causing this? I would provide more information, but I don't know where to start. (Getting very frustrated now). Tom
  3. Thanks for all your replies. I have been busy at work on my code, as I only have 2 weeks left before the experiment starts (I started writing the code in October, so it's not last minute, it's just taken me a long time to get to grips with writing such a large program in LabView using many varied techniques). As I didn't have time to understand and implement your code Eugen, I decided to modify my code. I now have implemented code to prevent message loss. When I send a message, I check to see if a "received" message has been written to the variable, and if it hasn't then I send the message again (after a 100ms delay). Now I don't lose any messages and the code works the way it should, apart from the fact that it runs slowly. The loop which sends the messages has to run many times before a message is sent by the client and a "received" message is received from the server. This is variable, sometimes it will happen first time, and sometimes it can take up to 100 times to successfully send the message. I can't cope with such long delays in my code. Any ideas? Thanks, Tom
  4. QUOTE (Eugen Graf @ Mar 20 2008, 11:41 PM) Thanks for that, this does look like exactly what I am trying to do. I will have a look and see whether I can incorporate this into my code. I guess I am suffering from this problem with my implementation (from the wikipedia page): QUOTE As a first example, many pub/sub systems will try to deliver messages for a little while, but then give up. If an application actually needs a stronger guarantee (such as: messages will always be delivered or, if delivery cannot be confirmed, the publisher will be informed), the pub/sub system probably won't have a way to provide that property. In my application I do require the guarantee that all messages will always be delivered, as my system requires the messages to undergo transitions in state. Such as going from a state of waiting for path information to a state of capturing data and saving to the provided path. Tom
  5. Hi, Firstly sorry for the length of this, I have tried to be as succinct as possible. I would appreciate any suggestions anyone might have. I have been writing code for a while now to use for collecting data in an upcoming experiment. At the core of the code I am using shared variables to pass messages between the different computers on the network. The messages are small, they are a cluster of 4 strings: From, To, Type, Message. The Type field is the type of message being sent e.g. Register, Status, Enable and the Message field contains any extra information. To pass the messages I have a loop which reads the shared variable and checks to see if it has changed since the last time we read it (using the timestamp), it checks to see whether it is relevant (i.e. whether the To: field corresponds to itself) and as a further check which I added later it checks to see if the message is blank. If it sees a new message it adds it to a queue and writes a blank message to the shared variable. This is the server side, on the client side a message is sent by first checking to see if the message stored in the shared variable is blank, and then writes a message to the shared variable. This system works well when there is only one object sending and receiving messages from the server, and if it is running on the same computer. However the object is on a different computer, or there are many objects communicating messages are somehow lost and the system grinds to a halt. This can occur if a client is waiting for some information from the server (say a path for it to save its data to), and the message that the server sent was not received, the code will simply sit in an infinite loop waiting for the data. I originally coded this using plain shared variables, with one for messages coming into the server and one for messages going out of the server. This worked ok, up until I had about 3 things communicating with the server. I decided therefore I would try using one shared variable per object instead, so that I couldn't have the case that two objects were trying to write to the shared variable at the same time. For reasons I won't go into this meant I had to change from using shared variable reads and writes to using the datasocket vis to read and write data. Upon doing this the number of lost messages has increased and the program performs even worse than it did before. If you got this far, thanks for reading this. I'm really at a loss for what to do, so any suggestions are welcome. Thanks, Tom
  6. Just a random thought: Wouldn't it be nice if when you right-clicked on a class' wire there was a menu option to insert a method vi of that class?
  7. It turns out it was a known bug. The fix was: "The first time you load the private data control in 8.5, open the front panel and resize any control in the private data cluster before saving. This puts a change on the VI so the class knows to update the save image." I'm now (finally) enjoying the new features in 8.5 and using a lot more accessor methods, which I tried to avoid like the plague as it was such a hassle before. Whether this is a good thing or not I don't know (see http://www.javaworld.com/javaworld/jw-09-2...5-toolbox.html) Tom
  8. Hi, I am using shared variables to pass messages across a network. Every time I open my project my vis are broken due to this error: "LabVIEW could not generate code for the shared variable. You must open the VI in the project that contains the library where the shared variable resides." The only way I have found to fix this error is to double click on all the shared variables on my block diagram, after which the error goes away. What's going on, and how do I stop this from happening? Thanks, Tom
  9. Hi, I upgraded to LabView 8.5 on Friday. Had a quick play with it, opened my project from 8.2.1 had a look at some of the new oop features. Then closed it and saved it. Now when I come back to open it again this week Labview crashes on opening it saying: "Fatal Internal Error : "LinkObj.cpp" line 714". I also can't open the project in LabView 8.2.1 now as it says that the file version is later than the current labview version. So I tried creating a new project in 8.5 and filling it with all my old classes, however this doesn't work as on adding the old classes LabView either crashes or the class is locked and it is apparently not loaded. Here's the error log created when trying to open the project in 8.5: #### #Date: 22 Jan 2008 12:07:31 #OSName: Windows NT #OSVers: 5.1 #AppName: LabVIEW #Version: 8.5 #AppKind: FDS #AppModDate: 07/24/2007 20:07 GMT c:\builds\penguin\labview\branches\Jupiter\dev\source\linker\LinkObj.cpp(714) : DAbort: Attempting to remove [LinkIdentity "Astra-Gemini network controller (server).lvclass" [ My Computer] already on the close lists that close operation DID NOT APPROVE. T $Id: //labview/branches/Jupiter/dev/source/linker/LinkObj.cpp#80 $ 0x00BC3287 - LabVIEW <unknown> + 0 0x00DAC519 - LabVIEW <unknown> + 0 0x00DAD2D7 - LabVIEW <unknown> + 0 0x00DDF141 - LabVIEW <unknown> + 0 0x00DE10D6 - LabVIEW <unknown> + 0 0x00DE13DD - LabVIEW <unknown> + 0 0x00DE5B58 - LabVIEW <unknown> + 0 0x00DE5B88 - LabVIEW <unknown> + 0 0x00DE5B88 - LabVIEW <unknown> + 0 0x00DE5B88 - LabVIEW <unknown> + 0 0x00DE5C05 - LabVIEW <unknown> + 0 0x00DF8C26 - LabVIEW <unknown> + 0 0x00DFB749 - LabVIEW <unknown> + 0 0x00DFC240 - LabVIEW <unknown> + 0 0x00EE0DB5 - LabVIEW <unknown> + 0 0x00EE117F - LabVIEW <unknown> + 0 0x00EE4A55 - LabVIEW <unknown> + 0 0x005DC9CF - LabVIEW <unknown> + 0 0x005DCAC3 - LabVIEW <unknown> + 0 0x005E048F - LabVIEW <unknown> + 0 0x005E176B - LabVIEW <unknown> + 0 0x0049C139 - LabVIEW <unknown> + 0 0x0049A981 - LabVIEW <unknown> + 0 0x0049C1EC - LabVIEW <unknown> + 0 0x00405678 - LabVIEW <unknown> + 0 0x0040599B - LabVIEW <unknown> + 0 0x0045CFF6 - LabVIEW <unknown> + 0 0x00505D85 - LabVIEW <unknown> + 0 0x00505FAB - LabVIEW <unknown> + 0 0x00505FF0 - LabVIEW <unknown> + 0 0x0149415F - LabVIEW <unknown> + 0 0x7C816FD7 - kernel32 <unknown> + 0 0x00000000 - LabVIEW <unknown> + 0 What are my options? Thanks, Tom
  10. QUOTE(Aristos Queue @ Jan 19 2008, 03:11 AM) Well thanks very much for your replies, and keep up the good work! We just got Labview 8.5 on our servers yesterday, so I'm looking forward to using the new features. Tom
  11. QUOTE(Aristos Queue @ Jan 17 2008, 06:58 PM) Yes I do modify the value of Network Controller. That's the whole point of the design, the Message Handler objects are responsible for containing the code to handle the message, however it may be necessary to alter the Network Controller's state depending on the message. For example I have a "Register" message, which will create a "Register Message handler" in my "load message object" factory vi. Then we call Register Message handler's "handle" vi which calls the Network Controller's "add instrument" vi, and the instrument that sent the register message is added to the Network Controller's list of registered instruments. Why is it not possible to track the path of the object through the subvi, using some special terminal similar to the dynamic dispatch terminal? Tom
  12. QUOTE(Aristos Queue @ Jan 17 2008, 04:57 PM) Don't worry, I intially solved the problem by removing all dynamic inputs, but then later realised exactly what you just pointed out, so I went back to the front panel and made the input dynamic again. However the wires on the block diagram didn't seem to change back to ones with a grey border. So I went back and started again, here is a picture of the original problem: and this time I simply removed the dynamic terminal output and left input as it was. This now meant that the connecter panes in its parent VIs were different, so I changed those to only have a dynamic input, and changed my output object to give: it appears that unless both the input and output terminals are dynamic dispatch the wire does not have a grey border. Tom
  13. QUOTE(Aristos Queue @ Jan 16 2008, 10:12 PM) Here is a picture of my block diagram: I have now removed the dynamic inputs. The problem occurred at handle.vi when I passed in the network controller. I assume this solution will work, but it looks ugly to me and I was worried that perhaps there is a problem with my design. Tom
  14. Hi all, I've run across a problem when trying to implement the Specification design pattern. My problem is this, I have a class called "Network Controller" which I am using to handle messages being passed over the network (I use the LabView shared variable to pass messages as clusters of strings). Now I decided that I would like to encapsulate the code for handling the messages in a seperate class "Message Handler" which has a method "handle message". This vi could then be overridden by children of "Message Handler" to deal with specific types of message. The problem arose when I tried to implement this. I decided that "Network Controller" should have a list of subscribers, and they would subscribe themselves by sending a "subscribe" message. The network controller then takes this message and uses a Factory to create the corresponding child class of "Message Handler" in this case "Subcribe Message Handler" which can then run its "handle" vi to add the subscriber to the list. However I cannot pass the "Network Controller" object to the handle vi without the vi breaking. I get an error message saying "One or more of the inputs to this tunnel or shift register does not originate at the dynamic input front panel terminal". Now I could just use a get function to take all the data from the "Network Controller" and pass it to the vi that way, but that's not really what I want to do. I want to pass the "Network Controller" to the Message Handler's "handle" vi so I can use its methods. The idea behind this design was so that I could simply add functionality to the "Network Controller" class if I decided in the future to pass different messages across the network, by simply adding another child class of "Message Handler", which the Factory would create given the name of the message. I didn't want to do this by using children of "Network Controller" as that didn't seem to make sense to me. A "Subscribe Message Handler" class is not a type of "Network Controller", but it should be able to provide functionality to the Network Controller. Any thoughts? Thanks, Tom
  15. QUOTE(jdunham @ Nov 29 2007, 08:16 PM) Ok, I've had a go at creating a "view data" method and using a sub panel to add it to my main front panel and I've found that it doesn't work because a sub-panel requires a reference to a re-entrant VI and Dynamic VIs cannot be re-entrant. Is there another way to achieve this? [EDIT Ignore this, I was referencing my VI wrongly. I've now got it to work! ] Tom ps. I suspect we have moved on from the original topic of the post. I am new to these forums, how should I go about changing to a new topic whilst still keeping the thread?
  16. Thanks, I think I understand now more what I should be doing and am busy re-implementing things. I tried to view data earlier using a sub-panel and a dynamic dispatch VI, but I seem to remember there being problems, due to the VI having to have some re-entrance property that I don't remember at the moment. I am definitely going to want to do this, as popping up a window is not really ideal. I would want to view data from many diagnostics at once, and would like to arrange them nicely. I will have a go once I've got that far in my code and see what happens. Tom
  17. Hi Jason, Thank you for your reply, it was most helpful. I have a few comments ... QUOTE(jdunham @ Nov 28 2007, 10:08 PM) I agree that "diagnostic" isn't a good name, I called it that simply because in our experiments we refer to our cameras and diodes and such-like as diagnostics, but I agree "instrument" is a better name. QUOTE(jdunham @ Nov 28 2007, 10:08 PM) No, you store the data in the child classes, which are different, and you don't need any variants. The whole point of this type of design is to get away from using variants. Objects let you use strong typing and still decide at runtime which routines to run. I agree, when I first came up with it I meant it to be an abstract class, but clearly forgot about that in the implementation. I have one problem, which is to do with a "get data" or "set data" function. Now, as each instrument can set its own data internally as in the "capture data" method I mentioned earlier, there isn't a problem. However with the "get data", which would be a method to return the data, there would be a problem as each seperate instrument would output a different data type, which isn't allowed. So they couldn't override a "get data" method from the abstract "diagnostic" class and consequently I couldn't have a dynamically dispatched "get data" method to send my data to a "Storage" class. Now whether I would/should want to do this is another question. I suspect I still have some fundamental misunderstanding on this front. QUOTE(jdunham @ Nov 28 2007, 10:08 PM) You have to define the interface somewhere. Usually I would imagine you do this in the derived class. If you have a camera, it's going to give you an image, and it's reasonable for the camera object to understand the handful of image file formats you want to support. If you need metadata which is specific to your experiment, you probably don't want your camera object to know about it, but that is probably a separate object anyway (the experimental data) which hopefully does not need to know what kind of instrument generated the data, otherwise your loop is going to get really messy no matter how you slice it. This common data could be in your parent class, or else it could just be in a different class entirely and passed into the saving routines as a separate input. I imagine that due to the problem I described above I will have to go along the route of each "diagnostic" saving its own data, using metadata given to it by the "Storage" class. QUOTE(jdunham @ Nov 28 2007, 10:08 PM) I would think that each diagnostic shouldn't know about the common experiment data. You could make each of them call a method of the parent and cast their data to the parent before writing it in the header of the file. Another way is more of a database-type approach where each stored object is listed in a master file listing the common data, along with a file name which points to a child-specific file which could be images or text files or whatever. I hope that helps, Jason Finally, I'm not sure I understand what you mean by "cast their data to the parent before writing it". Again thank you very much for you reply, Tom
  18. I have a class: "diagnostic" to represent a diagnostic in an experiment, such as a camera or oscilloscope, derived from this base class are more specific classes such as "camera", which overrides the basic methods of "diagnostic" such as "initialise" and "capture data". In the private data of "diagnostic" there is a field "data". The problem is that different diagnostics have different types of data, say an image or a 1-D array of floats. Which diagnostics are used depends on the experiment and what's happening in the experiment. So what I want to do is simply have an array of objects of a type which inherits from "diagnostic" and use dynamic dispatching to call all the relevant "capture data" methods. However, because the data is of different types I can't store the data in the parent class easily. At the moment I am converting the data to variant type and storing it in the "diagnostic" class' private data. So my first question is whether this is the right approach for solving this particular problem? Not only do I want to capture the data, I also want to store it. Now, each diagnostic should know nothing about how its data is to be stored, as different experiments will want to store data differently but might want to use the same diagnostics as another experiment. So I have another "Storage" object which can be inherited from for a particular experiment. So somehow I need to get the data from the diagnostic object to the storage object and have the storage object save it. Again I would like to do this in a loop where each diagnostic passes its data to a "save data" method of the storage object. Here I hit a problem, different types of data need to be saved in different ways, say to a .bmp file, or a csv file, but I want to only call one VI so I can do it in a loop. I have thought of some solutions to this, but I can't decide which is the best way to go, if any. I thought of having a lot of different storage objects to deal with the different types of data, but then I need some way of identifying what type of data is being wired in and dynamically dispatching on that (don't really know how that would work). That idea also conflicts with the idea of what a storage object is, as it is supposed to be specific to the experiment, with information such as the root directory and run number, this data would then have to be common to all the derived storage classes. Another way to go would be to have each diagnostic be responsible for saving its own data, but then this loses the flexibility of being able to save the data differently for different experiments. Also the diagnostic shouldn't have to know about storage specific information, such as the filename and save location of the data, this should be passed to it from the storage object. I haven't really come up with a satisfactory solution to this problem. I have had a look at the LVOOP Design Patterns, and I don't think they deal with my specific problem, although I could be wrong. Can anyone put forward ideas to help me solve this problem? Thanks, Tom
  19. Thanks for your feedback, I will have a look at the links you gave and see where it takes me.
  20. My current solution is to have a graph in a tab on the front panel for all diagnostics and turn the visibility of each page on and off at runtime, depending on which diagnostics are being used. So far I have done this without going through a "viewer" object. Perhaps I don't need one. I'm a bit of a novice when it comes to object oriented design, so any comments are welcome.
  21. Hello, I am currently writing some control code to run an upcoming experiment. Our previous control code was built up over many years and has become so unweildly that there's no-one left who understands how it works. So the idea is for me to completely rewrite the code from scratch, but in a way that can be easily modified in the future. I recently installed LV 8.2.1 and saw that it had OOP built in, so I decided this would be the best way forward. I've started messing about dummying up the code. The functionality of the code is very simple, it simply takes in an input signal, which denotes that our laser is going to fire, and then grabs all the data from diagnostics such as cameras and oscilloscopes. It then needs to store the information sensibly, and also allow a user to view data from certain diagnostics. So, I have several objects: a controller, a generic diagnostic (from which all other diagnostics like camera and oscilloscope inherit), a viewer, a storage controller and possibly a network control object as each diagnostic will be connected to its own computer. That's the background. My question at the moment refers to the viewer object. As this code is supposed to be general for any experiment of this kind, it is not known beforehand what diagnostics are going to be used, and different diagnostics will produce different types of data. The viewer is supposed to be able to take data from any diagnostic, which is currently in the form of a variant data type with an attribute denoting its type (other suggestions welcome), and display it appropriately on the front panel. Finally my question: What's the best way to acheive this? Is there some way of say having a dynamic tab system on the front panel, with a tab for each diagnostic, which when you click on the tab you get an X-Y Graph or a Intensity Graph depending on what diagnostic you are looking at? Sorry for the long post, I thought it might be beneficial to put a full description of what I'm trying to do. If anyone has any suggestions for better ways for me to go about this I would be very glad to hear them.
×
×
  • Create New...

Important Information

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