Jump to content

Matt_AM

Members
  • Posts

    10
  • Joined

  • Last visited

LabVIEW Information

  • Version
    LabVIEW 2015
  • Since
    2011

Recent Profile Visitors

The recent visitors block is disabled and is not being shown to other users.

Matt_AM's Achievements

Newbie

Newbie (1/14)

  • Collaborator Rare
  • First Post Rare
  • Conversation Starter Rare
  • Week One Done Rare
  • One Month Later Rare

Recent Badges

0

Reputation

  1. Darren, Thanks for clearing that up! As I was thinking through everything I got onto the mindset that "singleton" isn't "sub module" specific but project specific. Meaning that if I had a singleton PS sub module nested in my "Power and IG" module, then only 1 PS class could exist throughout the entire project and not per cloneable Power and IG module (which having 1 copy of the PS submodule per Power and IG module is the desired result). Matt
  2. Darren, That is what I was thinking too. I wasn't sure if the DQMH used singleton to mean in the entire project, or specific to a module. IIRC, singleton in general means 1 copy of this object exists ever. However, I wasn't sure of "PS Class" being a "sub module" would affect the singleton to mean 1 copy exists for this main module. I assumed not but wanted to verify. Matt
  3. Hey Fancy Folk, Back at it with a question regarding DQMH and how to properly set up code. Long story short, I am creating a "power and IG" module for some motors. This module will contain a module for a "PS class" that I've already created (class, not module) and I'm trying to figure out if I should make the "PS class" module a singleton or cloneable. The high level view is that the code would have a controller which requests to the "Power and IG" module which would request to the "PS class" module. The "PS class" module would then broadcast to the "Power and IG" module which would broadcast back to the controller. This way everything gets passed down/up 1 level at a time. The "Power and IG" module will be cloneable because there can be multiple copies of this module for one test stand. However, I only want each "Power and IG" module to have 1 instance of the "PS class" module. I was originally thinking of making the "Power and IG module" cloneable but the "PS class" module singleton. The issue I see with this is that I am going to be creating multiple singleton "PS class" modules for when I have multiple "Power and IG" modules and I think that is going to cause the code to fail. Therefore, I am thinking about making both the "Power and IG" and "PS class" cloneable to be safe. Thanks, Matt
  4. drjdpowell, I don't think I understand what you are saying. All I can think of is rebroadcasting the data vs broadcasting the user event to. To give some details, A is the "post office" handling user events between B and C. B has a helper loop reading XNET as an XY and C is the test's state machine. Since C is expecting the XNET type of XY, B would broadcast it's XY to A, then A would rebroadcast that XY to C. In this case A is just forwarding the user event from B to C without actually doing any work on it. joerghampel, I thought the EHL was the "top loop" that listens to user events or button presses via the event loop. The EHL would then send a message via queue to the "lower loop" of the MHL which would then be the primary place where you "do the work" of the module. Regrading the helper loop reccomendation, it sounds like the helper loop would be triggered by the user events of a different module...? The way that I have been imagining the helper loop, it would set some timeout/flag to start and stop the module via the EHL getting a request to start broadcasting which sends a message to the MHL to set the flag to initialize the helper loops. Likewise when the code needs to stop, the EHL sends a message to MHL which sends the flag to the helper loop. This feels a bit cumbersome, but thats how I am currently visualizing the process.
  5. Hey fancy folk, I've been looking into the DQMH architecture a bit and I'm thinking about designing a test around it. Basic test background, I am have a motor driving another motor and I'll be reading and writing over CAN for both motors and reading an analog in. I have laid out the basic module diagram as far as who is requesting what and who needs to broadcast their data. I'm currently running into 2 issues that I'm someone can provide some insight on. First Issues - constant broadcast helper loop I will be have 3 read loops broadcasting their data to an "XY Module" (the data will get formatted in the XY style and stored in a circular buffer) which the XY module will broadcast the circular buffer to the "Main Module". My issue is how do I do the constant read properly? I have 2 basic ideas. First is to create a helper loop that is started from the MHL and that helper loop continually broadcasts the message. Second is to use the MHL timeout to do my read (set the timeout from -1 to say 100ms once the module is started). IIRC, best practice is to have the helper loop do your repetitive actions, but by having my helper loop broadcast, I feel like I'm taking away from the main design that the MHL is supposed to broadcast. I am currently leaning towards the second option since I'm not too worried if my read is a bit of. For example, say another action got sent to the MHL (request sent to EHL which sends action to MHL) and the action takes 10 ms, the timing should be: read, wait X of 100 ms for MHL to receive action, do action in 10 ms, timeout 100 ms, read. This would result in a 110+X ms between the reads. I'm not worries about the 10+X ms between reads since my "test cycle" is on the side of 6 seconds. I'm just trying to make sure I understand the drawback of method 2. Second Issue - prevent circular messaging I was reading about the best practices and they were saying that modules shouldn't have circular referencing. In my project, I was going to have a set up of module A requests module B who broadcasts back to A and requests module C who broadcasts back to A. I could go into more of the specifics if you want, but this is the basic idea. Instead what I'm thining about is s Module A requests Module B, Module B broadcasts back to Module A, Module A sees the broadcast and sends the request to Module C. In this scenario, Module A seems more like a "post office" for the messages/user events being sent back and forth. I think its a bit cumbersome, but I also like how all the module controls stems from the "post office" since the submodules will only get their requests from the main module. Any additional insight would be much appreciated, Matt
  6. Agreed completely. I understand that DD is basically allowing the child to redefine a method via overwrite or extend it via overwrite w/ calling the parent's method. Because of this, as you said, all the connector panes for the DD VI must be the exact same. So, if I want to be able to read multiple types of data from a class, DD won't work for a genera "read", hence my question. You are correct, this is basically what I am thinking. I think having a separate read type class that implements how the data is read, or its strategy, is how I can get around multiple read types. From there I was thinking about sending the data via queue to a different "display class". This way, the read type class can have a DD VI called read, where it calls the child class read function (XNET signal/frame/XY) and send it to the display via queue. The queue control will most likely be a variant and enum, variant being the data read from read type and enum being the read type it came from (I've seen that I'm not supposed to send classes via queues so this is my work around to properly cast my variant to the correct data). When I was talking about events/queues, I mean more like a queue to send my data (not read) or an event struct with a 0ms timeout to monitor if a stop condition occurred. I understand I don't want to induce additional delays in my read to avoid timeouts.
  7. This is where my hiccup is, I am using the factory template for my power supply class since I know what my outputs and inputs are. I can use the DD to set/read my voltage, current, or output state since I know they will be double, double, and boolean respectively. I was thinking about using the factory pattern for an XNET Read class, but there are 3 basic methods to read from XNET - signal, frame, and XY. Theoretically, i could force all of these into an XY format. I am trying to figure out how I can use something like a dynamic dispatch to read anything from XNET without having to create 3 specific XNET read subclasses to an XNET read class. And then taking that further, what about a generic read class where I could read DAQmx data as well as XNET data? My current thought is so have a "Read" and "Read Type" class used to build my XNET read. Read would be an abstract class containing queues and events so my Read Type Class knows where to send the data. Read Type would be another class that would implement how I want to read this specific type of class. For example, Read Tye could be XNET signal/frame/XY or DAQmx Analog/digital/counter since the read type class is my strategy of how I want to read my data.
  8. @MikaelH Thanks for the links good sir, I appreciate it! @ThomasGutzler What do you mean by "Returning different data types from classes of the same instrument type is something you don't want."? I'm assuming you mean something like use the parent "Power Supply" object for my connector panes and define the child (such as TDK Lambda) during the initialization section of my test. This way the if I wanted to change the PS from TDK Lambda to say Sorenson, all I'd have to do is change the test's initialization section since all my connector panes are using the Power Supply parent class in their connector pane. If this is the case, I am doing that already, I may just be bad with my vocabulary. @drjdpowell Fair point, learning to walk makes running a lot easier. I guess what I am currently trying to do is define my end goal and figure out the different steps along the way. Then start working on the individual steps to build up to my end goal. Like for a generic motor (in my case) I'll need a power supply class and CAN communication class as my main two classes along with some other private methods/data (ignition task and methods, motor info, stuff like that). As far as the CAN coms, I am actually running into a bit of an issue trying to figure out how exactly I want to lay it out. I'm using XNET and I'm trying to figure out how I should handle having things like single point signal/frame as well as queued signal/frame. If I go down the splitting out all of those into their own child class, then I'm going to have 4 child classes for my basic XNET write class. OR I could try and go into a strategy pattern where the XNET class has some other class information that contains how the data is supposed to be written (something like the CookingStrategyPattern from here.) Thanks all for responding, I appreciate the help!
  9. Hey all, I want to start my first big design in LV with OOP by laying out and designing a motor class. I was wondering if there are any tools that I should look into to help me with the process. I've built a power supply class which is basically an abstract factory where all the children create the concrete classes. I am still trying to understand a lot of the different architectures/design patterns from the LV forums but am getting a better understanding each time I go through them again. My biggest issue I can see is having child classes return different data types without it getting overly complicated (any suggestions on designs on this front are more than welcome). Digressing back to the original question, As of right now I am looking into GOOP, but its occasionally crashing LV 2015. It seems like theres some good stuff with GOOP, but the lack of documentation is a bit rough to slog through. I was wondering if you fine folks could recommend any tools for me to look into as well. I'm sorry this is a generic request, but I don't know what I don't know. Matt
  10. Hey fancy folk, Problem/TL;DR: I've been having a problem getting all of my timing to sync up for a 4 station tower I'm running. I am using a part of my code to store a start and stop timestamp to analyze data coming from XNET via XY read to determine if a motor is assisting or not. When I first start a station, things are aligned, then after time, they drift (makes sense with clocks based on different crystals). I tried to set the master timebase to the same clock via PXI trig (for some reason my card wouldn't let me connect a clock to PXI star and I know PXI trig lines can cause double clocking) and doing a soft reset every 24 hours (resets my CAN cards). After a few days of a station running, the timestamp and XNET read XY no longer align and the timestamp can be up to 10 seconds "earlier" than my XNET read. If it would help, I can attach a cycle from my log to show what I mean by things not lining up. I have a work around that I'll talk about below, but I'd prefer to get to the bottom of why I can't sync my tasks, code, and CAN cards. Background/hardware setup: We have a four station tower where each station commands a motor in position mode which is connected to a motor in a torque assist mode against a brake. We are doing lifetime testing of the torque assist motor. The tower has a PXI 1010 chassis in it with 4 PXI 8512/2 cards (CAN coms), a PXI 6713 (brake set), a PXI 6602 (IG set), a PXI 6052E (coms for SCXI chassis in PXI1010), and 2 SCXI 1121 (allows for 8 torque sensor readings, 2 per station). There is 1 PXI 8512/2 per station - each motor gets its own port because all 8 motors have the same Arbitration ID, but that's a different conversation. I am using LabVIEW 2015 on a PC which communicates to the PXI 1010 in this tower. We were using 8.6 and I "upgrade to our latest and greatest" a few months back when I updated the code. Software attempt at sync: After the first few days of running the code and realizing things weren't staying sync'd, I started to try and give everything a common clock. Issue ran into how do I properly sync the PXI 8512/ to an SCXI 1121? My thought is that if I set the master timebase the same to both, then the PXI 8512/2 and SCXI 1121 should be able to divide down the master time base to the proper sampling rate and since they are using the same Master timebase, everything will be good. So in my test init section, I use "DAQmx signal connect" to connect the PXI 6713's 20Mhz timebase to PXI Trig 7 and set the analog in task from the SCXI 1121's to use the master timebase as PXI Trig 7. Likewise in the station init, I am using the Trig 7 as the Master timebase for the PXI 8512/2. I am performing an XNET read XY for my sessions and a waveform read (later converted to XY data) for the SCXI 1121's analog in task. I am displaying all of this data on an XY graph. Problem in my code: I created 1 station and made it a preallocated clone reentrant VI. In the station main, I have an XNET Read XY session loop, a log loop, a state machine, and a time monitoring loop. The XNET Read XY loop reads all motor feedback data (command current of the position motor) and shoves it to an XY array notifier (used in the station's state machine as well as the top level's display loop). The station's state machine is the part that sends out the command to the XNET write which commands the position motor to move in a desired movement profile while also setting the torque assist motor to its proper mode. When I go to write these values, I am acquiring the timestamp of the state machine and storing that into a notifier. Once the desired movement profile is complete, I am storing the timestamp again. The state machine then checks the XNET Read XY array notifier and grabs the data between the start and end timestamp. It then analyzes the position motor's commanded current to determine if the desired movement was assissted or not. Note: I was originally using the analog torque in from the 1121, but noticed that the shift between the station's timestamp and my XY torque in (converted from waveform) data shifted faster than the XNET read XY of the commanded current. Ideally, I'd like to move back to my torque sensor. Failure point: The main failure point of my code is when I compare the state machine's start and end timestamp to the XY data from my XNET read XY timestamps. The state machine's timestamp can get 5-10 seconds "faster" than the XNET read timestamp. I use quotes because I am monitoring my state machine and the FP XY graph and when the state machine tells the position motor to start moving, my XY graph updates as well and doesn't lag 5-10 sec beind. I believe that the reason for the time difference is due to the clock skew of the code and the PXI 8512/2. I've tried looking in multiple locations for where LV actually gets it's timestamp via "Get Time/Date In Seconds" VI but can't confirm anything. My general assumption is that it queries the PC's clock to get that information. Work around: I have 2 bits in my XNET write frame for the position motor. I can use those 2 bits as flags for when the code tells the position motor to start moving and when movement finished and set the "Echo TX" setting for XNET to T. This would allow me to read when messages were being sent out from my card so I can determine when the start and end time were sent to the position motor. I'd repurposed the get timestamp notifier to store data in my XNET read XY loop instead of my state machine. Where I am at: Any tips or insight into synchronization between everything would be greatly appropriated. I've been reading NI documentation about how things should be handled behind the scenes but couldn't figure out how to get my PXI 8512/2 and SCXI 1121 clocks sync'd without using the DAQmx connect terminals. I think that the only way I can actually get things synced properly is by somehow getting the clock from my PC to my SCXI but I have no idea how to do that. I am thinking about going down my work around because that is the path of least resistance at this point, but I am genuinely curious how I properly sync all my stuff. I feel like something like this will plague any sort of long term life cycle testing. I'd much rather spend time to design right now than suffer from a half baked attempt when I have to fix the code later. If you'd like me to add snippets of code or delve into more details, I can. Thanks for reading, Matt
×
×
  • Create New...

Important Information

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