Jump to content

Leaderboard

Popular Content

Showing content with the highest reputation on 07/26/2010 in all areas

  1. I posted some example code on NI Community that implements linked lists, tree, and graphs using LVOOP and DVRs. It can be found http://decibel.ni.com/content/docs/DOC-12668 . If anyone is attending Alliance Day I have a presentation on it called Applications of Advanced Data Structures in LabVIEW. As a bonus I use the base classes to make a Priority Queue, solve the travelling salesman problem (as much as it can be solved), and find the best path between point A and B. For fun there is also a sudoku solver. I left it community so as anyone can add onto it. If there is a particular problem someone wants to see solved, and it has common uses, give it a request and I might have time to make it before NIWeek. This might also be a start to LapDog.
    2 points
  2. I can't give an authoritative 'yes,' but that's my take on it. Each class provides a specific function. For example, I use collection classes fairly frequently. Its sole purpose is to manage a group of arbitrary objects at runtime. It has a few very basic methods: Add Item, Remove Item, Get Item, etc. I'll use a collection class as part of a set of classes (often grouped in an lvlib) to provide some higher level of functionality. I have an EventManagerLibrary I can drop into an observable software component that provides a relatively easy way for that component to manage and raise events from multiple observers. The other classes in the EventManagerLibrary use the collection class' methods and as a result are very tightly coupled to it. That's okay, because the EventManagerLibrary is used as a whole, not broken up into separate parts. (I don't want software outside the library depending on the collection class though, so it's a private member of the library.) For better or worse, I spend a lot of my design time figuring out and maintaining dependencies and between modules. Somewhere in my reading I saw that described as "managing the seams" and I think that's an good way to phrase it. Once I figure out what my dependency tree should look like from a high-level application view, then I can figure out how to implement it using (when appropriate) various design patterns. Paul gave some good examples of managing the seam between the Model and the View. In his XML app the Model directly updates the View's fp control. This couples them together to some extent. (Though I believe it's a relatively weak coupling since it's using a native LV type to cross the 'seam.') Lately I've been keeping the Model and View completely decoupled by having them both send and receive messages from the Controller, which acts as a mediator. Is one method right and the other wrong? Nope, it all depends on what you're trying to accomplish. Paul understands the consequences associated with each approach and made a decision based on the requirements. Where it gets dangerous is when decisions are made without understanding the consequences. Actually, the Entry and Exit actions are overridable BaseState methods and are part of the state machine. Each state has the ability to execute arbitrary actions when entering the state, while in the state, and when leaving the state. Moore state machines only allow entry actions. Mealy state machines don't allow any of those, instead opting to associate actions with a specific transition. Decomposing a problem into states using Entry, Input, and Exit actions for each state reduces the number of states required and makes the system as a whole easier to understand and modify. (That's my hypothesis anyway.) [Note: QSM's are most closely related to Moore state machines, except instead of executing an entry action and then waiting in that state for the next transition like a "real" state machine, in a QSM a state is continuously reentered until the next transition occurs.] Functionally I think our two approaches are identical. It is possible in your model for the Execute method to have equivalent Entry and Exit operations surrounding a loop that polls the shared variable. I created unique Entry and Exit methods in the BaseState to help guide the way the developer thinks about states in their application. Without understanding the idea of Entry, Input, and Exit actions a developer is more likely going to lapse into bad habits learned from the QSM. The BaseState class contains a private LVObject labelled NextState. When a state has enough information to determine what the next state should be, it puts an instance of that state in the NextState variable. This most correctly occurs in the InputActions method, but technically could happen in any of the three methods. StateTransition is a static dispatch BaseState method that simply gets the next state object from the private data, copies the existing BaseState data into the next state object, and puts the next state object on the shift register wire. I'll try to put together a simple example that I can post online. However, it is the weekend and the sun is out (rare enough in the Pacific Northwest) so no promises on when I'll get it up...
    1 point
  3. I've been thinking about this solution. I will make a couple observations: If the Entry and Exit actions are common to all cases then it makes sense to keep them out of the statemachine, as you have done in your example. We have solutions either way, depending on whether this behavior is state-specific. For some applications messaging is an advantage because we can separate the View from the Controller not only into separate loops but into separate applications. This means we can create alternative Views that will work with the Controller, and the Controller can work with another component as well. The Controller just knows that it receives messages defined on its interface, and it knows what to do with those data messages. It does not care about the source of the messages. This is very powerful when you need it. (The ability to bind controls to shared variables makes this pretty simple to implement with shared variables, but that's just one solution.) We use this capability especially since we often want to test a component stand-alone and then integrate it into the system. In the former case we need a local UI, but in the latter case the component usually receives data from another component in the system. Moreover, we use the local UI for local control for diagnostics and an "engineering mode." Of course, the needs of the application will indicate whether this is appropriate or not. OK, I'm also curious what your State Transition method does exactly....
    1 point
×
×
  • Create New...

Important Information

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