08-13-2019 02:21 AM
Hello, everybody,
for years I've been reading here quietly in the board. But this time the search function did not produce any hits.
Situation:
For a punching process, I measured both the cutting force and the tool travel over 400 strokes at the synchronized time. (attached are the measurement files)
Task:
I want to merge both signal channels and define a special event for each individual stroke (e.g. maximum) and get both the x-value (tool path) and the y-value (cutting force) for the event.
Problem:
1. If I convert both signal channels from waveform to numeric channels and then try to create a composite waveform channel with x-channel as path and y-channel as force, I get an equidistant error.
2. How do I get the X-value of a defined event? When I search for the maxima, I only get the corresponding force displayed, but not the corresponding x-value.
I hope you guys can help me.
Best regards
Alex
08-14-2019 11:30 AM
Hey Alex,
I have attached the resulting file after I extracted all the cycles out of your test in the "results" group. This is a script I ran after cutting out a "Travel Event" in the VIEW tab and using the "find pattern" function in the ANALYSIS tab with the "Travel Event" and the "travel" channels to get the "PatternResultFind" marker channel:
'------------------------------------------------------------------------------- '-- VBS script file '-- Created on 08/14/2019 08:14:48 '-- Author: '-- Comment: '------------------------------------------------------------------------------- Option Explicit 'Forces the explicit declaration of all the variables in a script. ' VARIABLES SETUP DIM SAMPLE_RATE_HZ: SAMPLE_RATE_HZ = 50000 Dim DataGrp, travelChnl, forceChnl, timeChnl, resultGrp, patternResChnl, i, resultChnl Set DataGrp = Data.Root.ChannelGroups("Data Trimmed") Set travelChnl = DataGrp.Channels("travel") Set forceChnl = DataGrp.Channels("force") Set resultGrp = Data.Root.ChannelGroups.Add("Results") Set patternResChnl = Data.Root.ChannelGroups("Travel Event").Channels("PatternFindResult") ' CHOP OFF THE BEGINNING For i = 1 To patternResChnl.Size Step 1 ' Sweep entire pattern result channel If patternResChnl.Values(i) = 1 Then If i = 1 Then Exit For Else Call DataBlDel(patternResChnl, 1, i) Call DataBlDel(travelChnl, 1, i) Call DataBlDel(forceChnl, 1, i) End If Exit For End If Next ' CHOP OFF THE END For i = patternResChnl.Size To 1 Step -1 ' Sweep entire pattern result channel If patternResChnl.Values(i) = 0 Then Call DataBlDel(patternResChnl, patternResChnl.Size, 1) Call DataBlDel(travelChnl, travelChnl.Size, 1) Call DataBlDel(forceChnl, forceChnl.Size, 1) Else Exit For End If Next ' MAEK AS TRIMMED AND GET TRIMMED TIME CHANNEL If Not dataGrp.Properties.Exists("Trimmed") Then Call dataGrp.Properties.Add("Trimmed","Yes",DataTypeString) Call ChnGenTime("Data Trimmed/TimeGenerated","microsecond",6.3732331547E+10,6.3733517784E+10,20,"StartStepNo",travelChnl.Size) End If Set timeChnl = dataGrp.Channels("TimeGenerated") ' GET INDIVIDUAL CYCLES Dim start: start = 1 Dim count: count = 1 Dim cycleCount: cycleCount = 1 For i = 2 To patternResChnl.Size Step 1 If (patternResChnl.Values(i) = 0 Or i = patternResChnl.Size) And patternResChnl.Values(i - 1) = 1 Then Call resultGrp.Channels.Add("travel " & cycleCount, DataTypeChnFloat64).SetValuesBlock(travelChnl.GetValuesBlock(start, count)) Call resultGrp.Channels.Add("force " & cycleCount, DataTypeChnFloat64).SetValuesBlock(forceChnl.GetValuesBlock(start, count)) Call resultGrp.Channels.Add("time " & cycleCount, DataTypeChnDate).SetValuesBlock(timeChnl.GetValuesBlock(start, count)) cycleCount = cycleCount + 1 count = 0 ElseIf patternResChnl.Values(i) = 1 And patternResChnl.Values(i - 1) = 0 Then start = i count = 1 End If count = count + 1 Next
You can average those cycles or find all the peaks and times
08-14-2019 11:32 AM
Idk why the code is under "spoiler" but here is the rest of the data
08-15-2019 05:27 AM
Hi gsklyr,
thanks for your reply. Unfortunately I am looking for a slightly different functionality.
I have implemented the pattern search similar to you and created a new channel group with all found locations more specificaly single strokes.
My real goal was to get the force value and the travel value from a defined event of every single stroke, e.g. maximum.
Therefore, my plan was to generate a channel in which the force is plotted across the path. Afterwards I wanted to save the X-value (travel) and the Y-value (force) of the event (maximum) with the find Peak function.
However, such a combination of two channels as force over travel does not seem to work. Currently I'm trying the following.
1. defining a pattern (single stroke) in the force signal
2. storage of all individual strokes in a separate signal group
3. maximum of each single stroke with find Peak function. This gives me a Y-value (force) and an X-value (time).
With the X-value (time) I then search for the appropriate position in the travel signal and read out the path at that time.
I have already successfully implemented steps 1 to 2 in the script. At the moment I try to implement step 4 with the functions PNo and DataB1Copy. At the moment, however, the syntax still fails.
08-17-2019 04:43 PM
I recently worked on a similar project like this involving cyclic data. I ended up developing custom functions to do the peak search (optimization of the DIAdem functions), and one function that finds the row in the time channel for a particular time value. With that row, you can then lookup the value in another corresponding channel by row. See the function below, and the links below for other helpful functions. If you have any trouble, I can write a complete script for you.
http://www.savvydiademsolutions.com/analysis.php?topic=peak-search-algorithms
'Call LogFileDel()
'Dim oChnTime, dChnVal
'Set oChnTime = Data.Root.ChannelGroups(3).Channels(1)
'dChnVal = 13.0
'Call LogFileWrite("iRowForChnTimeVal() = " & iRowForChnTimeVal(oChnTime, dChnVal))
Function iRowForChnTimeVal(ByVal oChnTime, ByVal dChnVal)
'Returns the row for the closest value in oChnTime.
'Returns <= 0 if the row was not found.
'Expects oChnTime to be a numeric channel
'Version 20190702
iRowForChnTimeVal = 0
If oChnTime.DataType <> DataTypeChnFloat64 Then Exit Function
Dim sFormula, arrSymbols, arrValues, iRowFwd, iRowRev, iRow, bUIAutoRefreshSet
bUIAutoRefreshSet = UIAutoRefresh
'Call UIAutoRefreshSet(False)
sFormula = "ValEqualGT(Ch(""" & oChnTime.GetReference(eRefTypeIndexIndex) & """)," & Str(dChnVal) & ")"
iRow = ChnFind(sFormula,1)
If iRow <=0 AND ValEqualLT(oChnTime.Values(oChnTime.Size),dChnVal) Then
'The value for the last row in oChnTime is <= dChnVal.
If Fix(oChnTime.Values(oChnTime.Size)) <> Fix(dChnVal) Then Call LogFileWrite("WARNING: The value for the last row in " & oChnTime.GetReference(eRefTypeNameName) & " of " & Str(oChnTime.Values(oChnTime.Size)) & " <= dChnVal of " & Str(dChnVal) & " Fn iRowForChnTimeVal()")
sFormula = "ValEqualLT(Ch(""" & oChnTime.GetReference(eRefTypeIndexIndex) & """)," & Str(dChnVal) & ")"
iRow = ChnFindReverse(sFormula,oChnTime.Size)
If iRow <= 0 Then Call Err.Raise(65535,,"ERROR - ChnFind() failed in iRowForChnTimeVal() for " & sFormula)
ElseIf iRow <=0 Then
Call Err.Raise(65535,,"ERROR - ChnFind() failed in iRowForChnTimeVal() for " & sFormula)
End If
ReDim arrSymbols(1): ReDim arrValues(1)
sFormula = "ValEqualLT(A,B)"
arrSymbols(0) = "A"
arrSymbols(1) = "B"
Set arrValues(0) = oChnTime
arrValues(1) = dChnVal
iRowFwd = ChnFind(sFormula, 1, arrSymbols, arrValues)
iRowRev = ChnFindReverse(sFormula, oChnTime.Size, arrSymbols, arrValues)
If iRowFwd <= 0 OR iRowRev <= 0 Then
sFormula = "Ch(""" & oChnTime.GetReference(eRefTypeIndexIndex) & """)>=" & Str(dChnVal)
iRowForChnTimeVal = ChnFind(sFormula,1)
Else
If ValEqualLT(Abs(dChnVal-oChnTime.Values(iRow)),Abs(dChnVal-oChnTime.Values(iRowFwd))) AND ValEqualLT(Abs(dChnVal-oChnTime.Values(iRow)),Abs(dChnVal-oChnTime.Values(iRowRev))) Then
iRowForChnTimeVal = iRow
ElseIf ValEqualLT(Abs(dChnVal-oChnTime.Values(iRowFwd)),Abs(dChnVal-oChnTime.Values(iRow))) AND ValEqualLT(Abs(dChnVal-oChnTime.Values(iRowFwd)),Abs(dChnVal-oChnTime.Values(iRowRev))) Then
iRowForChnTimeVal = iRowFwd
ElseIf ValEqualLT(Abs(dChnVal-oChnTime.Values(iRowRev)),Abs(dChnVal-oChnTime.Values(iRow))) AND ValEqualLT(Abs(dChnVal-oChnTime.Values(iRowRev)),Abs(dChnVal-oChnTime.Values(iRowFwd))) Then
iRowForChnTimeVal = iRowRev
Else
Call LogFileWrite("Abs(dChnVal-oChnTime.Values(iRow)) = " & Abs(dChnVal-oChnTime.Values(iRow)) & vbTab & iRow)
Call LogFileWrite("Abs(dChnVal-oChnTime.Values(iRowFwd)) = " & Abs(dChnVal-oChnTime.Values(iRowFwd)) & vbTab & iRowFwd)
Call LogFileWrite("Abs(dChnVal-oChnTime.Values(iRowRev)) = " & Abs(dChnVal-oChnTime.Values(iRowRev)) & vbTab & iRowRev)
Call Err.Raise(65535,,"ERROR - iRowForChnTimeVal() unexpected conditions")
End If
End If
If IsArray(arrSymbols) Then Call Erase(arrSymbols)
If IsArray(arrValues) Then Call Erase(arrValues)
'Call UIAutoRefreshSet(bUIAutoRefreshSet)
End Function 'iRowForChnTimeVal()