Test channel with quotient produces graphical error


Recommended Posts

Hello,

I've got some problems when I'm plotting a test channel containing the quotient between two other test channels. It seems that my Quotient channel somehow contains old data so plotting the quotients looks like some type of random signal appearing, after a while it stabilizes and behaves like it should (probably when the program has run long enough for all the data points in its history to be filled up with new numbers).

I'm adding numbers to the test channels in an event for a real channel looking like:

A.AddValue(-Horizontal_force+loadCellBTare)

B.AddValue(Vertical_force-LoadCellATare)

Quotient.AddValue(A/B)

Plotting A and B or even A/B is totally fine, plotting "Quotient" is a graphical mess to start off with. Logging Quotient to a file gives me correct numbers so it appears it is some type of graphical issue (and I'm using something like ( A > 0.2) * Quotient for the plot so it is not related to a mathematical problem).

I was thinking about including Quotient.ClearHistory in my auto-start sequence but it didn't help. Any ideas would be very much appreciated!

Thanks,

Marcus

Link to comment
Share on other sites

Most likely you have an alignment error due to the timestamps on the data you are adding. Two solutions:

1) fix the timestamps by using the insertTime() function:

Quotient.addValue(insertTime(A/B, systime(), 0))

2) disable alignment: go to the bottom axis properties for your graph and set the Align Threshold to 0.

Link to comment
Share on other sites

  • 2 weeks later...

Hmm, I tried your suggestions but neither seems to do the trick.

If I use the Quotient.addValue(insertTime(A, systime(), 0)) under the events tab for one of my real channels it will just fill up my Quotient channel with time numbers and eliminate what I'm really interested in logging to a file which is the A/B values, maybe I'm missing something in your suggestion?

If I put in a 0 in the align threshold the graph goes blank so in a way that sorts one problem :) but doesn't take care of the real issue.

Like I wrote earlier, If I lower the History number for the Channels (say from 2000 to 200) the problem still appears but goes away quicker.

Regards

Marcus

Link to comment
Share on other sites

Got your file. I'm not sure what the "mess" you are referring to, as I don't know what the proper graph should look like. One thing I will say is that you are doing the addValue()'s wrong. You are not subsetting. You are doing Quotient.addValue(A/B), but you forgot to mention that A and B are channels with history, so what you end up getting is the entire history of A divided by the entire history of B (which is also an array) shoved into quotient. What you want is: Quotient.addValue(A[0] / B[0])

Second, it should be noted that you have the code for doing this math in one of your input channels. You can't reliably predict which channel event will trigger first, so its possible that the data for A is actually one step out of sync with the data for B. To avoid this, it's typically best to use a sequence, and is in fact, part of the reason for the channel.readGroup() function. Simply assign your two 0.01 timing input channels to the group "Input" or something, then create a sequence like this:


while (1)
try
channel.readGroup("Input")
// do your math here:
// quotient.addvalue(a[0] / b[0]) for example
catch()
? strLastError
endcatch
delay(0.01)
endwhile

[/CODE]

You might consider using wait(0.01) if you really want the data at exactly 0.01 second intervals. Ignore the warnings, but be sure your code follows the pattern above with the delay / wait OUTSIDE the try/catch block.

Link to comment
Share on other sites

  • 2 weeks later...

Thank you for your suggestions and sorry for my late response, been away for a few days.

The only sequence that I've tried so far that is seemingly stable is this (plotting the two test channels as A/B, not plotting the Quotient):

while (1)
try
channel.ReadGroup("Input")
delta_T.AddValue(((gettime(vertical_force)-starttime)>0)*(gettime(vertical_force)-starttime))
Horizontal_force_tared.AddValue(-Horizontal_force+loadCellBTare)
Vertical_force_tared.AddValue(Vertical_force-LoadCellATare)
Quotient.AddValue((Horizontal_force_tared/Vertical_force_tared)+mu_ball_slide)
catch()
? strLastError
endcatch
delay(0.01)
endwhile[/CODE]

(The Input group is my two 0.01 channels as you recommended)

As you can see I do not use the subsetting for my Quotient which somehow causes alot of duplicates in my results file. Also, still, if I choose to plot the Quotient even with the code above I still get a graph that for the first few seconds behaves really strange and then stabilizes. When I say strange I'm not talking about the instantaneous value in the graph but the portion of the graph that leaves the graph window with time (in this case strange = Quotient value jumping between different numbers on the y-axis).

Link to comment
Share on other sites

You've got to subset in your calculation, otherwise you are doing math on arrays and then sticking arrays into quotient. Those arrays are going to have different time stamps on each element, thus causing the data in the Quotient channel to have time stamps that are not in order. This will completely throw the graph, which expects the data to be in order in time, and cause unpredictable results. It likely stabilizes because the arrays in your math get big enough that they cover the entire time range of the graph.

Link to comment
Share on other sites

Hmm, I've e-mailed you two results files (not allowed to upload them here), in both cases I put in this code in the sequence:



while ( 1 )
try
channel . ReadGroup ( "Input" )
delta_T . AddValue ((( gettime ( vertical_force )- starttime )> 0 )*( gettime ( vertical_force )- starttime ))
Horizontal_force_tared . AddValue (- Horizontal_force + loadCellBTare )
Vertical_force_tared . AddValue ( Vertical_force - LoadCellATare )
Quotient . AddValue (( Horizontal_force_tared[0] / Vertical_force_tared[0] )+ mu_ball_slide )
catch ()
? strLastError
endcatch
delay ( 0.01 )
endwhile[/CODE]

[color=#000000]In the results_A I did not include the Quotient in the logging set and in results_B I included Quotient in the logging set. As you can see, adding the Quotient to the logging causes duplicate rows and strange results. Also, by subsetting the Quotient or if I try to subset any of the forces causes the graph windows to be emptied and I kinda feel lost using this approach. I'm probably not fully understanding what I should do based on the info you've given me but so far what seems to be working the best is still to use:[/color]

[color=#000000]delta_T[color=#666600].[/color][color=#660066]AddValue[/color][color=#666600]((([/color][color=#000000]gettime[/color][color=#666600]([/color][color=#000000]vertical_force[/color][color=#666600])-[/color][color=#000000]starttime[/color][color=#666600])>[/color][color=#006666][/color][color=#666600])*([/color][color=#000000]gettime[/color][color=#666600]([/color][color=#000000]vertical_force[/color][color=#666600])-[/color][color=#000000]starttime[/color][color=#666600]))[/color]

[color=#660066]Horizontal_force_tared[/color][color=#666600].[/color][color=#660066]AddValue[/color][color=#666600](-[/color][color=#660066]Horizontal_force[/color][color=#666600]+[/color][color=#000000]loadCellBTare[/color][color=#666600])[/color]

[color=#660066]Vertical_force_tared[/color][color=#666600].[/color][color=#660066]AddValue[/color][color=#666600]([/color][color=#660066]Vertical_force[/color][color=#666600]-[/color][color=#660066]LoadCellATare[/color][color=#666600])[/color][/color]

[color=#000000]in the event for one of my channels, leaving the quotient to a post processing operation in excel or matlab. [/color]

Link to comment
Share on other sites

First, just because it works "best" doesn't mean it is right, nor that it will stay working.

You need to use [0] in your tared expressions too, as well as your deltaT. Just remember, if you don't use [0], you are doing math on the entire history and sticking the result, which is an array, into the channel with AddValue().

If you still have problems with alignment (which causes missed data in logging sets), consider using insertTime() to give all 4 channels the same time stamp. Something like (I'm assuming your tares, mu_ball_slide and starttime are scalar variables, not arrays / channels:

private theTime = vertical_force.time[0]

delta_T . AddValue (insertTime((( gettime ( vertical_force[0] )- starttime )> 0 )*( gettime ( vertical_force[0] )- starttime ),theTime, 0))

Horizontal_force_tared . AddValue (insertTime(-Horizontal_force[0] + loadCellBTare, theTime , 0))

Vertical_force_tared . AddValue (insertTime( Vertical_force[0] - LoadCellATare, theTime, 0) )

Quotient . AddValue (insertTime(( Horizontal_force_tared[0] / Vertical_force_tared[0] )+ mu_ball_slide, theTime, 0) )

I may not have proper matching parens above... insertTime() takes three parameters, so the pattern for you is: channel.addValue(insertTime(data, theTime, 0))

Link to comment
Share on other sites

Ok! Now there's progress! Now that my auto-start prio 5 sequence looks like your suggested:

while (1)

try

channel.ReadGroup("Input")

private theTime=vertical_force.Time[0]

delta_T.AddValue(insertTime((((gettime(vertical_force[0])-starttime)>0)*(gettime(vertical_force[0])-starttime)),theTime,0))

Horizontal_force_tared.AddValue(insertTime((-Horizontal_force+loadCellBTare),theTime,0))

Vertical_force_tared.AddValue(insertTime((Vertical_force-LoadCellATare),theTime,0))

Quotient.AddValue(insertTime(((Horizontal_force_tared[0]/Vertical_force_tared[0])+mu_ball_slide),theTime,0))

catch()

? strLastError

endcatch

delay(0.01)

endwhile

the results file looks ok which is really good! Now two additional question arises:

1. Having "Time" in the x-expression in my graphs no longer works, it just freezes the graphs. If I leave the x-expression field blank I can see the instantaneous Vertical/Horizontal_force_tared values in the graphs but I like to have them so that you visually can follow the values as they leave the graph window using a time window of say 10 seconds. I tried a couple of different expressions like gettime(vertical_force_tared) but didn't do the trick. Any suggestions?

2. Using delay or wait in the sequence above both results in a time step (in delta_T) of around 0.015 seconds, shouldn't wait result in a 0.01 second time step and if not how do you relate the actual time step to the timing of 0.01 in the Input channels? A nice feature to have is to allow a user to control the sampling frequency / timing up to 100Hz but if the actual time step output is not directly related to what you put in under timing that is more or less fruitless...

Many thanks,

Marcus

Link to comment
Share on other sites

Wait() will give you a more consistent timing, but its important to understand that Windows is NOT a real time operating system, and as such does not reliably do anything faster than maybe 20ms (0.20). The reason you get 0.015 out of wait(0.01) is because Windows isn't giving DAQFactory the processor back and is busy doing other things, or because its actually taking 0.015 seconds to read all the channels and process the data. If you are using a LabJack, this is to be expected since it takes like 4ms to do anything, and you are doing more than one thing.

BTW: if its not the LabJack holding you up, you can tweak DAQFactory to get reliable timing below 20ms. First, it helps to be on a multi-core PC. Second, eliminate as many other apps as possible. Third, try running DAQFactory in Acquire mode. Finally there is a tweak that trades processor power for precision in timing loops. Its in the registry under HKCU/Software/DAQFactory/DAQFactory/Settings/MaxSpinTime. This is the max time (in milliseconds) that DAQFactory will attempt to hold the processor while waiting for a specific interval. If the amount of time it needs to wait is longer than this number, it will release the processor, otherwise it will sit and spin until the interval elapses. Increasing this will improve precision. Don't increase it a lot or you'll chew up lots of CPU power spinning. Even changing from the default of 2 to 3 can have a big effect.

Link to comment
Share on other sites

Archived

This topic is now archived and is closed to further replies.