Jump to content

Daklu

Members
  • Posts

    1,824
  • Joined

  • Last visited

  • Days Won

    83

Everything posted by Daklu

  1. What happens if you close the project, open an empty one, add the library with the class to be edited, and make the changes? Does the editing performance improve? Are your libraries interlinked to the extent that loading the library ends up loading the entire project?
  2. If you have to use functional globals because your messaging system can't handle data, I'd look at changing your messaging system. That's a pretty stiff restriction to put on your designs. This is actually correct... you *want* loops to be able to send messages to each other. The queues don't require different names either. (I believe it is preferable to not use named queues at all.) It's good to worry about race conditions, but having separate sets of enqueue/dequeue vis doesn't affect race conditions one way or the other. Put a timeout terminal on your dequeue vi and you can use a single enqueue/dequeue set instead of having multiple sets. Ahh... I missed that. In that case, you won't end up with an unresponsive UI, but you will end up with situations where the UI loop is blocked waiting for a FP event and messages are getting backed up on the queue. If you're going to have multiple receiving mechanisms in a single loop they both must have timeouts. No, not in any amount you would notice. We've all been there. It'll take time and you'll get lots of bumps and bruises along the way, but if you spend enough time you'll learn the ins and outs. I would suggest learning multi-loop programming before diving into LVOOP. LapDog itself is LVOOP, but the principles of multi-loop programming are not restricted to object oriented techniques. If you open up the MessageQueue.Dequeue method and look at the block diagram you see it has some similarity to your dequeue vi. All the other MessageQueue methods are simple wrappers around NI's queue functions. If you want to start learning how to build robust multi-loop designs, here are three rules of thumb to get you started: 1. Restrict each loop to a single mechanism for receiving information from external sources. (Other loops or the user interface.) 2. Don't have a loop send messages to itself. Use sub vis instead. In fact, I don't even wire the loop's queue into the message handling case structure. 3. Find and remove any requirement a loop has for receiving specific sequences of messages. With a queue the receiving loop has no way of knowing what the next message will be, and neither do you. It could be anything. Your loops should be able to correctly handle any messages at any time, without becoming unpredictable. Keep that in mind when you're writing code. Yes, that means you should forget about macros--they cause race conditions. (Except under very specific circumstances.)
  3. Umm... what kind of comments/criticism are you looking for? 'Cause I could (and on sometimes do, much to the annoyance of fellow forummers) go on for days talking about the problems of QSM designs. If the template fits your needs, go ahead and give it a test drive on this project. Chances are you'll discover things you want to change for the next project. Make the changes, rinse, and repeat. Aside from the inherent QSM problems, there were a couple things that jumped out at me. -First, why do you have separate sets of enqueue and dequeue vis for each queue? Other than the icons (which I think are interesting) they are exactly the same. -Second, why are you using a functional global for data storage instead of passing data on the queues? -Third, I know there is a long history of calling each case a "state," but the terminology is incorrect. I've seen hints that people inside NI are beginning to change how they refer to them. What you have is not a pair of state machines, they are message handling loops. You'll be better off in the long run if you change how you think about them. -Fourth, you have two event processors in the top loop: the dequeue processes incoming messages and the event structure processes user inputs. Doing that in a multithreaded application is asking for trouble. And since you don't have any timeouts enabled for either the dequeue or the event structure, you'll run into that trouble sooner rather than later. -Finally, the template may be quite sufficient for smallish applications, but expect to run into race conditions and other problems if it grows much--especially if you attempt to add additional loops. Part of the reason the JKI SM works is because it is only a single loop. The strategies simply don't transfer well (imo) to a multithreaded application.
  4. "Can you think of anything that would be good to include in this?" Well if you don't mind me addressing the question you asked 3+ years ago, I don't have a need for anything like Requirements Gateway, but I have often wished for a tool I could use to review all the developer notes I've dropped on block diagrams. I'll typically use braces around a keyword, like {ToDo}, {Refactor}, {Magic Number}, or {Fugly Hack}, then fill in the rest of the note with an explanation. The problem is I never remember what keywords I used and hitting Ctl-G until I find the note I'm looking for is a pain. I realize it's not quite within the scope of what you're doing... Would you object to me poking around and possibly forking your code?
  5. His concept of API seems to be a little different than mine. I think of an API as the public methods and data structures developers use to interact with an arbitrary component. It looks like he is using API as a synonym for web-based services intended to be used by developers. There is a lot of overlap, but much of his blog is focusing on the business aspect of web services rather than the technical side of creating a usable API.
  6. Great, new dance moves to try out next time I go clubbing. I wipe the floor with Patrick Dempsey. Legion of Extraordinary Dancers is an interesting series based on dance. Little dialog, lots of modern dance styles.
  7. First, since you asked for a recommendation for a good RC helicopter, I assume you are not that familiar with them. I *strongly* suggest finding an RC shop and spending a good amount of time talking to the people there about your project. I assume this is for a senior project? What is your major and area of focus? A CS major studying AI will have different goals than an EE studying control systems. What's your budget for the project? I'd be surprised if any of the cheap 2-channel toy helicopters will have the performance you'll want. They have little available power for lifting the weight of the camera and are not very manuverable. The camera will also change the helicopter's center of gravity, which may drastically alter its flight characteristics. My guess is at minimum you'll want a 3 channel aircraft, and maybe even a 4 channel one. Of course, more channels increases the cost and complexity of your project. (Don't forget to budget for spare parts. You will break things.) You're proposing controlling the aircraft through a software interface. That alone could present all kinds of unexpected problems for you to solve, and the approach you take will lead to drastically different solutions. How do you expect the software's control commands to get to the helicopter? Are you planning on building your own transmitter or are you going to hack the RC controller? Modern RC controllers for helicopters contain much more functionality than a simple joystick. Are you prepared to write software to replace all that hardware? In order for the software to have an autonavigation mode, it needs to know a lot of information about the helicopter's current state: position, altitude, attitude, heading, and velocity come to mind. How do you plan on obtaining all that information? GPS is out. You could put a transponder on the helicopter and use three receivers connected to the pc to triangulate the position, but that has a set of engineering challenges all on its own. (More weight and cg chages on the helicopter, requires precise transponder placement, how to handle signal delays, etc.) In theory that will give you position and altitude. Unless the transponder pings very quickly (>10 Hz?) your sample rate will be too slow to calculate velocity. And it doesn't give you any attitude or heading information. Human pilots are a critical part of the control feedback system. They're not easy to replace. You can try using dead reckoning by calculating the control inputs that *should* get you to where you want to be. Unfortunately, dead reckoning rarely works well for mobile robot control. Minor errors compound over time and you end up nowhere near where you should be. My honest opinion is you're biting off a much bigger challenge than you are aware of. As a rough metaphore, if your original plan to stream video from a helicopter is a doghouse your advisors think is too simple, what you're proposing now is a 14 story office building with underground parking. I wish you the best of luck if you go forward with your idea, but be prepared to spend a huge amount of time on it. With all due respect, it's unrealistic to expect us to do your research for you, no matter how nicely you ask. It's your vision, your project, and your grade. If you want to be sucessful you need to put in the effort. We'll help you when you have more specific questions or technical problems, but we're not going to do your work for you. If you really need someplace to start, try this vi. (Requires Windows to run.) HelicopterProjectHelper.vi
  8. I, like many others, pay my bills by writing LV code for customers. Frequently people/companies want to keep knowledge in-house to preserve a competitive advantage. I believe that by sharing information and techniques we can increase the problem space for which Labview is a viable solution, thereby creating more business opportunities for everyone. (I don't have any data to back up my belief... it's just something I want to be true. It allows me to keep posting on Lava.) Another aspect to consider is the advertising benefit. How many people would have heard of JKI if not for the excellent free software they have provided to the community? There are other companies on the Tools Network that have released free libraries as well. How much is it worth to have potentially every licensed Labview developer using your product and learning your company's name? Marketing departments drool over that kind of exposure, and you can have it for the cost of the time it takes to prepare the code for public consumption. To be fair, I don't release *everything* I create that might be useful to others. It can be a difficult decision and I wouldn't fault you or your company if you didn't release it. Nevertheless, I'll hope the partners do allow it.
  9. I had always assumed the IMAQ library used cpu resources for all of its computations. Recently an NI sales rep told me some vis do in fact offload stuff to the GPU. Does anyone know which IMAQ vis use the GPU instead of the CPU? Seems like it would be useful information to know when running into vision bottlenecks.
  10. There's an ongoing "Idea Exchange" thread floating around on Lava users typically use to promote their ideas. Nothing wrong with putting it here, but it might get more visibility there. It might be technically possible, but I think the side effects of doing that are much worse than the current behavior. Have you ever edited a cluster only to discover later that some of the bundle/unbundle nodes have unexpectedly changed to an apparently random field? One reason that happens is because the vis with the bundle/unbundle nodes are not loaded into memory when the cluster definition is changed. When the vi is loaded after the edit, LV tries to map the old cluster fields to the new cluster fields. For certain combinations of edits LV can't tell what it should do and has to guess. Loading all class members into memory when any single class element is loaded ensures that all bundle/unbundle nodes will be in memory in case the class data cluster is changed. If you take that behavior away users will be exposed to the same potential problems that exist with clusters. In theory I suppose it would be possible to postpone loading the entire class until the class ctl editor is opened, but there may be other reasons why that is unfeasible.
  11. Nope, I get it. You're passing in a collection instead of an array of app-specific objects. I think *you* misunderstood what I was saying. "...and instead of passing an array of objects into the Listbox class..." refers to what he was originally planning on doing. "...pass a Map..." summarizes what you suggested.
  12. I think I understand what you want the Listbox class to do, but what's not clear is how you expect to use it. Do you plan on wiring a listbox reference into the class and handling all the events internally, or are you going to register the listbox with the event structure on the UI block diagram and call Listbox class methods in the appropriate event case? In general I agree with James and Shaun. You could probably rig up a class to do all the back end work for you, but associating classes with UI elements isn't as tidy as we would like. Yep, that's life when using a strongly typed language that doesn't support generics. You can do as Shaun suggested, and instead of passing an array of objects into the Listbox class pass a Map (or Dictionary, or TListItem...) object. Another option is rather than passing the data collection into the Listbox object, have it spit out an array of strings when the user changes it and pass the array of strings to the collection object.
  13. Whether you charge for it or not is up to you. I'm biased, as I may occasionally have uses for something like that and would like to see it open sourced. There are some things to consider: -If somebody pays for it they will expect professional level support. And I can almost guarantee you will get support requests for things that are outside your responsibility. Just last week I had a customer send me a pc because the windows tcp stack had been corrupted. It had nothing to do with my software or Labview, but they expected me, not their IT dept, to fix the problem. (Which I did.) -Open sourcing it will probably expose it to more people, providing you with more feedback for improvements. -You might attract developers who want to contribute to the project. -Good open source tools strengthen he community as a whole. -It would put pressure on Rolf to continue improving LuaView. I appreciate the desire to be compensated for your time, and it's not a bad thing. However, there are lots of people in the Labview community who give tremendous amounts of time with no expectations of monetary gain. Ask Jon Green or Jim Kring how much time they spent on OpenG. Ask Omar how long it took him to do VI Tester. Ask Christian or Ben (or any other champion) how much time they spend on the forums helping people out. I spent a year on the Interface Framework before releasing it to the CR. I'm not trying to pressure you into releasing it open source, just pointing out that there is an established history of friendly sharing in the LV community. Personally I think the community would get a lot of benefit from an easy-to-use, open source scripting tool.
  14. Nope, I made it up in 2009 in an attempt to clarify discussions (though I don't always follow the convention myself.) It's not a widespread convention (total number of followers = 1) so maybe I'm just adding to the confusion. All the literature I've ever read relies on context to know if they are talking about interfaces in general or interfaces as a construct or type. It works fine once you understand the difference, but for those who don't know the difference it can be very confusing. LV's lack of Interfaces compounds the confusion as there's no foundation for users to build up their understanding. Sometimes I'll use "api" instead of "interface" if I think there's potential for confusion.
  15. My personal opinion of the IF... It's functional and may have practical applications in rare situations, but it's too clunky to be general useful. Implementing an Interface takes too much code and isn't very easy for a typical LV developer to follow. (There's another conversation about Interfaces here.)
  16. [This comment led me to believe there might still be some misunderstanding about Interfaces. In typical fashion, what started as a brief response grew because I don't know when to shut up.] You can't make an Interface a descendant of any (non-Interface) class, period. I think some languages allow an Interface to inherit from another Interface, but since Interfaces contain no data and no implementation there's not much point in doing it as far as I can tell. The Interface Framework really isn't the best way to learn about and understand Interfaces. It blurs the line between Interface types and class types too much. Also, the IF uses the concept of "concrete Interfaces" that are instantiated at runtime. I do this to emulate the ability to typecast a class into one of its Interfaces. Languages with native support for Interfaces don't allow an Interface to be instantiated. i.e. Concrete Interfaces are an oxymoron. In many languages (java and vb come to mind) classes do not "inherit" from Interfaces; rather they use the keyword implements to indicate to the compiler that the class supports the Interface. interface ISleepable { void sleep() } class Baby { implements ISleepable private bool isSleeping void sleep() { this.isSleeping = True } } [/CODE] In C# the syntax for implementing an Interface is the same as the syntax for inheriting from superclass. Classes are still restricted to a single parent class, though they can implement as many Interfaces as necessary. [CODE] // Class inherits from the Person class class BabyA : Person { } // Class implements the ISleepable Interface class BabyB : ISleepable { } // Class inherits from the Person class and implements the ISleepable and IGrowable Interfaces class BabyC : Person, ISleepable, IGrowable { } [/CODE] As near as I can tell the idea of classes "inheriting" from Interfaces is a relatively recent convention. I prefer the "implements" terminology. It's less confusing to me.
  17. At this point I don't have any plans to revisit it. I released the IF nearly 3 years ago after a year of off-and-on development, and almost immediately discovered I didn't need it. Even with the IF implementating Interfaces and Interfaceable is fairly cumbersome and rigid. I've found adapters to be a simpler and more flexible solution in nearly all cases where I wanted to use an Interface. I still hope LV will someday support Interfaces (or Traits) natively and hide all that complexity from us developers. However, seeing as how the idea has only garnered 26 votes after 3 years on the Idea Exchange, and after having Interfaces lose a straw poll to stability and some other feature at the last architectural summit, I'm starting to wonder if we'll ever get them--or any other meaningful extension to LVOOP for that matter. It's unfortunate too. Although I love developing in LV I'm beginning to see the day when I'll "outgrow" (for lack of a better term) it on the distant horizon. I hope it didn't come across as overly critical of your efforts. I sat on the response for a couple hours trying to decide whether to post it as is or rewrite it to soften it up. Eventually I decided I didn't have the time or energy to rewrite it. Laziness triumphs again!
  18. I hadn't heard of Udacity or Coursera before reading this thread today, so naturally I spent the last 6 hours browsing through the content. Both offer short interactive quizzes during the lecture, and I ran across this one in the Udacity Cryptography course.
  19. I do the same kind of type switching between the working object and the Interface object in the Interface Framework. It's the only way to get it to work with by-value classes. That said, there are some important differences between what you are doing and how the Interface Framework is implemented. I am reluctant to call your example an Interface implementation. In your (and candidus') example each Interface class has its own data fields. Interfaces as a programming construct don't have their own data fields. The Interface just provides an alternate means of accessing the working object. Calls through the Interface operate on the working object, not on the Interface itself. What you have is more like a schizophrenic object--lots of separate identities rolled up into a single unit. I'm not saying there's no value in it, just that it doesn't strike me as Interface-ish. (I am curious if you have a use case in mind. If your intent is simply to aggregate a bunch of functionally distinct classes into a unified whole, we have ways to do that that are much simpler to understand and use. Namely, composition and delegation.) It is certainly possible to change the example code to remove the Interface objects' private data and have their methods delegate to the working object. That would be more Interface-ish, but it still doesn't quite fit the bill imo. One of the properties of Interfaces is the class designer controls what Interfaces the class supports. In the example code the class user controls what Interfaces are bundled with the working object. As a potential user of the framework, the mental picture I have is a bunch of objects thrown together in a bag where I can only pull out a single object at any given instant, instead of a single object with different views. That could probably be "fixed" by limiting access to the SetAggregates base class method. That would bring it even closer to an Interface as commonly understood. (Or at least how I understand them.) But it also highlights another potential issue. There is only a single IBase class that all Interfaces and Interfaceable objects inherit from. Interfaces are not the same as classes. (Though some languages may implement them as classes under the hood.) Interfaces are a different construct with their own restrictions and limitations. Since Labview doesn't natively support Interface constructs, we use classes to implement them. However, I think it is beneficial to continue considering Interfaces a distinct concept from classes. Maintaining separate class hierarchies for Interfaces and Interfaceables helps keep code understandable. If you made all three changes then I'd be willing to call it an Interface. Of course, if you did all that you'd also have essentially the Interface Framework, so take my opinion as worth about as much as the paper it's written on. Ultimately any Interface implementation is going to be influenced by what properties of Interfaces the developer thinks are important. When I created the IF I was primarily interested in being able to create groups of objects with related functionality outside of the class hierarchy and operate on them using a single set of VIs, so that's what I implemented. Since then I've talked to others who are more interested in an Interface's must implement nature, as a way to make sure a class implements all the methods defined by the Interface. (As near as I can tell the must implement property is a side effect of the desire to create functional groups, but I'm not going to claim they are wrong for wanting that.) --------- As an aside, there are a couple things about the original example project I thought were odd. 1. The existence of both an IBase class and an IBaseDefaultImpl class. I'm not sure the methods defined by the IBase class provide enough functionality to actually implement a functional Interface or Interfaceable object. In other words, any class implementing IBase is going to have to expose other methods to be usable, so there's really no point in having an abstract IBase class. I'd combine them into a single class. 2. I don't see the point of the parent/child objects in the example. It seems irrelevant to what the code is trying to demonstrate and only adds complexity where none is needed.
  20. I'm glad you posted that Jon. ~6 weeks ago I ran into a situation with LapDog.Messaging where I wished I had given it class input terminals and I immediately thought of that thread. I've done that before, but ultimately abandoned it for a couple reasons: 1. I prefer to have all code related to object initialization (or default values) contained in a single place. 2. It's nice to be able to see the values when I probe the class wire. The one place I can think of where it might make technical sense to return a constant in the method is if the constant is very large and you're concerned about memory copies. Yep. I'll have to think about this for a bit. It's 3am and my brain is protesting the lack of sleep. (Couldn't you just dynamically call the class' Creator?)
  21. Generally speaking, yes, you have it correct. However, many of us have adopted a functionally similiar but slightly different implementation pattern. Instead of creating an overridable Init method for each class, I suggest creating a custom, non-overridable, Create method for each class. Where you would previously drop the class constant on the block diagram and wire it to the Init method when you need an instance of the class, now you'll just drop the Create method. The Create method gives you a place to properly initialize the class' internal data fields. Here's an example of a very simple Create method from one of my projects. In this case the object create method has one input parameter, a TTB File object, and initializes an internal data field before passing the fully configured object out to be used by the calling code. Notes: * To avoid name conflicts with child classes, I always append the class name to my create methods. (i.e. "Create Motorbike" or "Create Car.") * When starting out I suggest not having an input terminal for the class being created. It has uses in more complex scenarios, but you can do quite a lot without them and it's easier to understand when you're starting out.
  22. Reading through old threads I missed... The demo code included in the framework uses a by-ref object, but the framework works just as well with by-value objects. It's entirely up to the class developer to implement their Interfaceable classes using by-ref or by-value techniques.
  23. I was reading through some old posts and saw my name... so of course I had to reply. I don't understand why you think this. If I want to use the Fluke DVM class in another app it is completely portable. If I want to replace the Fluke DVM in this app with a Radio Shack model, it's as simple as creating a Radio Shack Adapter child class that inherits from the DVM Interface class and having the RS Adapter delegate all calls to the Radio Shack DVM class. What kind of reuse is hard to do? Disapprove? Not at all. Disagree? You bet, at least until you convince me otherwise. Can you explain your reasoning? (I assume you're contrasting the adapter with direct inheritance?)
  24. Fair enough. That's very similar to how I learned it too... start by learning the "academically correct" way to implement it, then once I understand that I can selectively implement only those aspects that are important for a given project.
×
×
  • Create New...

Important Information

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