Robot Structural Analysis Forum
Welcome to Autodesk’s Robot Structural Analysis Forums. Share your knowledge, ask questions, and explore popular Robot Structural Analysis topics.
cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

VB for Excel API not Extracting Peak Member Forces from Robot

7 REPLIES 7
SOLVED
Reply
Message 1 of 8
RoboExploiter
2111 Views, 7 Replies

VB for Excel API not Extracting Peak Member Forces from Robot

Hope someone can help me.

 

I'm using VB to  extract peak member forces from Robot for a given set of load cases.  Unfortunately in the case where a given bar position has 2 member forces, Robot will pass the lower of the 2 values to Excel.  The result is that my code and spreadsheet and therefore my structural design is not capturing the peak moment.

 

I don't think this is a problem with my code, its working at every other position of the structure.  I have a work around in mind, but forcing a peak moment extraction would be first prize.

 

Private Sub GetBarForces()
    Dim rbForceServer As RobotBarForceServer
    Dim rbCase_Col As RobotCaseCollection
    Dim lBarNum As Long
    Dim lCaseNum As Long
    Dim rbForceData As RobotBarForceData
    Dim ResultFx As Double, ResultFz As Double, ResultMy As Double
    Dim rbCase As IRobotCase
    Dim rbCase_Sel As RobotSelection
    Dim i, j As Integer
    Dim iNumPositions As Integer
    Dim iMinFx, iMaxFx As Single
    Dim iMinFz, iMaxFz As Single
    Dim iMinMy, iMaxMy As Single
    Dim iBarPosition, iBarLength As Single
    Dim rRange As Range
    
    'set collection of load cases
    Set rbCase_Sel = Robot.Project.Structure.Selections.Create(I_OT_CASE)
    rbCase_Sel.AddText (sCaseNums)
    Set rbCase_Col = Robot.Project.Structure.Cases.GetMany(rbCase_Sel)
    
    'set Robot forceserver
    Set rbForceServer = Robot.Project.Structure.Results.Bars.Forces
    
    With Worksheets("Case 2&3- " & vWallResults(1, iWallNum))
        .Unprotect
        iBarLength = vWallResults(3, iWallNum) - vWallResults(4, iWallNum)
        Set rRange = .Range("A:A")
        iNumPositions = Application.WorksheetFunction.Count(rRange)
        
        For i = 1 To iNumPositions
            
            'update status window
            With frmStatusWindow
                .txtStatusWindow = .txtStatusWindow.Text _
                    & ". "
            End With
                
            'set position on bar for force extraction
            iBarPosition = (vWallResults(3, iWallNum) - .Cells(6 + i, 1)) / iBarLength

            For j = 1 To rbCase_Col.Count
                'get jth load case
                Set rbCase = rbCase_Col.Get(j)
                lCaseNum = rbCase.Number
                
                'set bar number for force extraction
                lBarNum = vWallResults(2, iWallNum)
                
                'extract forces/moments
                Set rbForceData = rbForceServer.Value(lBarNum, lCaseNum, iBarPosition)
                ResultFx = rbForceData.FX
                ResultFz = rbForceData.FZ
                ResultMy = rbForceData.MY
                
                'initialise envelope variables
                If j = 1 Then
                    iMinFx = ResultFx
                    iMaxFx = ResultFx
                    iMinFz = ResultFz
                    iMaxFz = ResultFz
                    iMinMy = ResultMy
                    iMaxMy = ResultMy
                End If
                
                'compare forces/moments to determine envelope
                If ResultFx < iMinFx Then
                    iMinFx = ResultFx
                End If
                If ResultFx > iMaxFx Then
                    iMaxFx = ResultFx
                End If
                
                If ResultFz < iMinFz Then
                    iMinFz = ResultFz
                End If
                If ResultFz > iMaxFz Then
                    iMaxFz = ResultFz
                End If
                
                If ResultMy < iMinMy Then
                    iMinMy = ResultMy
                End If
                If ResultMy > iMaxMy Then
                    iMaxMy = ResultMy
                End If
                
                Set rbForceData = Nothing
            Next j
            
            'record force/moment envelope to spreadsheet
            With rCase
                .Cells(6 + i, 1) = iMinFx / 1000
                .Cells(6 + i, 2) = iMaxFx / 1000
                .Cells(6 + i, 3) = iMinFz / 1000
                .Cells(6 + i, 4) = iMaxFz / 1000
                .Cells(6 + i, 5) = iMinMy / 1000
                .Cells(6 + i, 6) = iMaxMy / 1000
            End With
        Next i

 Thanks in Advance for your help.

7 REPLIES 7
Message 2 of 8

My assumption is that you have this bar divided into number of calculation elements (intermediate nodes along the bar).
There are several possibilities:
1. Change model to avoid bar division (e.g. split bar into two smaller at node 100)
2. Read value from dx from both sides of this point
3. Use extreme server to find min and max value
Dim r As New RobotOM.RobotApplication
Dim ep As RobotOM.RobotExtremeParams
Dim selCas As RobotOM.RobotSelection
Dim selBar As RobotOM.RobotSelection

selBar = r.Project.Structure.Selections.Create(RobotOM.IRobotObjectType.I_OT_BAR)
selCas = r.Project.Structure.Selections.Create(RobotOM.IRobotObjectType.I_OT_CASE)

selBar.FromText("1")
selCas.FromText("1")

ep = r.CmpntFactory.Create(RobotOM.IRobotComponentType.I_CT_EXTREME_PARAMS)

ep.ValueType = RobotOM.IRobotExtremeValueType.I_EVT_FORCE_BAR_MY
ep.Selection.Set(RobotOM.IRobotObjectType.I_OT_CASE, selCas)
ep.Selection.Set(RobotOM.IRobotObjectType.I_OT_BAR, selBar)
ep.BarDivision = 11

Dim ev As RobotOM.RobotExtremeValue

ev = r.Project.Structure.Results.Extremes.MaxValue(ep)
MsgBox(ev.Value)
ev = r.Project.Structure.Results.Extremes.MinValue(ep)
MsgBox(ev.Value)

 

Most likely the 4th solution below will be the best:
4. Use the query mechanism able to working on elements (since RSA 2012). Example:
Dim RobApp As New RobotOM.RobotApplication

Dim Res As RobotOM.IRobotResultQueryReturnType
Dim RobResQueryParams As RobotOM.RobotResultQueryParams
Dim RobResRowSet As New RobotOM.RobotResultRowSet

Dim SelBar As RobotOM.RobotSelection
Dim SelCas As RobotOM.RobotSelection

SelBar = RobApp.Project.Structure.Selections.Create(RobotOM.IRobotObjectType.I_OT_BAR)
SelCas = RobApp.Project.Structure.Selections.Create(RobotOM.IRobotObjectType.I_OT_CASE)
SelBar.AddText("1")
SelCas.AddText("1")

RobResQueryParams = RobApp.CmpntFactory.Create(RobotOM.IRobotComponentType.I_CT_RESULT_QUERY_PARAMS)
RobResQueryParams.Selection.Set(RobotOM.IRobotObjectType.I_OT_BAR, SelBar)
RobResQueryParams.Selection.Set(RobotOM.IRobotObjectType.I_OT_CASE, SelCas)
RobResQueryParams.SetParam(RobotOM.IRobotResultParamType.I_RPT_BAR_ELEMENT_DIV_COUNT, 11)

RobResQueryParams.ResultIds.SetSize(6)

RobResQueryParams.ResultIds.Set(1, RobotOM.IRobotExtremeValueType.I_EVT_FORCE_BAR_FX)
RobResQueryParams.ResultIds.Set(2, RobotOM.IRobotExtremeValueType.I_EVT_FORCE_BAR_FY)
RobResQueryParams.ResultIds.Set(3, RobotOM.IRobotExtremeValueType.I_EVT_FORCE_BAR_FZ)
RobResQueryParams.ResultIds.Set(4, RobotOM.IRobotExtremeValueType.I_EVT_FORCE_BAR_MX)
RobResQueryParams.ResultIds.Set(5, RobotOM.IRobotExtremeValueType.I_EVT_FORCE_BAR_MY)
RobResQueryParams.ResultIds.Set(6, RobotOM.IRobotExtremeValueType.I_EVT_FORCE_BAR_MZ)

Res = RobApp.Project.Structure.Results.Query(RobResQueryParams, RobResRowSet)

Dim q As New Object
Dim v As Double

Dim max As Double
Dim min As Double
max = 0
min = 0

Do
Res = RobApp.Project.Structure.Results.Query(RobResQueryParams, RobResRowSet)
Dim ok As Boolean
ok = RobResRowSet.MoveFirst()
While ok
v = RobResRowSet.CurrentRow.GetValue(RobResRowSet.ResultIds.Get(5))
If (min > v) Then min = v
If (max < v) Then max = v
ok = RobResRowSet.MoveNext()
End While
Loop While Res = RobotOM.IRobotResultQueryReturnType.I_RQRT_MORE_AVAILABLE

MsgBox("min = " & min & " max = " & max)

If you find your post answered press the Accept as Solution button please. This will help other users to find solutions much faster. Thank you.



Artur Kosakowski
Message 3 of 8

Hi Artur,

 

1) Not possible.  The bar is continuous, but there are nodes along the length where i've placed spring supports.

2) This is my potential workaround, I was hoping for another quicker/neater solution.

3) On what version of RSA is this available?  I have RSA Pro 2010.

4)  Thanks, however I don't have RSA 2012.

 

Thanks.

Message 4 of 8

Hi,

 

API for methods 3 and 4 should be available in ARSA 2010.



Rafal Gaweda
Message 5 of 8

Hi Gents,

 

Thanks for your help so far.  I think i'm almost there.  I've tried to adapt your piece of code to work properly, but I'm having some difficulty.

 

When I'm running this query mechanism  I am given this error at the 

ResultFx= RobResRowSet.CurrentRow.GetValue(RobResRowSet.ResultIds.Get(1)) :  "Run Time Error '-2147467259 (80004005)':  Method 'GetValue of object 'IRobotResultRow' failed".

 

I think the error occurs because I haven't defined RobResRowSet properly.  Can you help me?

 

Sub Extreme_Bar_Forces()
    

''Using the query mechanism
Dim Res As RobotOM.IRobotResultQueryReturnType
Dim RobResQueryParams As RobotResultQueryParams
Dim RobResRowSet As New RobotResultRowSet
Dim SelBar As RobotSelection
Dim SelCase As RobotSelection

Dim v As Double
Dim max As Double
Dim min As Double
Dim ok As Boolean
Dim iBarPosition, iNumpositions, iBarLength, i, j As Single
Dim rRange As Range
Dim ResultFx, ResultFz, ResultMy, iMinFx, iMaxFx, iMinFz, iMaxFz, iMinMy, iMaxMy As Double


    'set collection of load cases
    Set SelCase = Robot.Project.Structure.Selections.Create(I_OT_CASE)
    SelCase.FromText (sCaseNums)
    MsgBox sCaseNums
    Set SelBar = Robot.Project.Structure.Selections.Create(I_OT_BAR)
    
    Set RobResQueryParams = Robot.CmpntFactory.Create(I_CT_RESULT_QUERY_PARAMS)
   
   
    RobResQueryParams.Selection.Set I_OT_BAR, SelCase
    RobResQueryParams.Selection.Set I_OT_BAR, SelBar
    
    RobResQueryParams.ResultIds.SetSize 6
    
    RobResQueryParams.ResultIds.Set 1, IRobotExtremeValueType.I_EVT_FORCE_BAR_FX
    RobResQueryParams.ResultIds.Set 2, IRobotExtremeValueType.I_EVT_FORCE_BAR_FY
    RobResQueryParams.ResultIds.Set 3, IRobotExtremeValueType.I_EVT_FORCE_BAR_FZ
    RobResQueryParams.ResultIds.Set 4, IRobotExtremeValueType.I_EVT_FORCE_BAR_MX
    RobResQueryParams.ResultIds.Set 5, IRobotExtremeValueType.I_EVT_FORCE_BAR_MY
    RobResQueryParams.ResultIds.Set 6, IRobotExtremeValueType.I_EVT_FORCE_BAR_MZ
    
   'Set RobResRowSet = Robot.CmpntFactory.Create(??_??_??)
    

    With Worksheets("Forces " & vWallResults(1, iWallNum))
        .Unprotect
        iBarLength = vWallResults(3, iWallNum) - vWallResults(4, iWallNum)
        Set rRange = .Range("A:A")
        iNumpositions = Application.WorksheetFunction.Count(rRange)
        
        Res = Robot.Project.Structure.Results.Query(RobResQueryParams, RobResRowSet)
        
        ok = RobResRowSet.MoveNext()
        
        For i = 1 To iNumpositions
            
            'update status window
            With frmStatusWindow
                .txtStatusWindow = .txtStatusWindow.Text _
                    & ". "
            End With
                
            'set position on bar for force extraction
            'iBarPosition = (vWallResults(3, iWallNum) - .Cells(6 + i, 1)) / iBarLength
            RobResQueryParams.SetParam I_RPT_BAR_DIV_COUNT, iNumpositions
            
            For j = 1 To SelCase.Count
                'get jth load case
                'Set jCase = SelCase.Get(j)
                 
                'lCaseNum = SelCase.Number
                
                'set bar number for force extraction
                'lBarNum = vWallResults(2, iWallNum)
                
                'extract forces/moments
                'Set rbForceData = rbForceServer.Value(lBarNum, lCaseNum, iBarPosition)
                ResultFx = RobResRowSet.CurrentRow.GetValue(RobResRowSet.ResultIds.Get(1))
                ResultFz = RobResRowSet.CurrentRow.GetValue(RobResRowSet.ResultIds.Get(3))
                ResultMy = RobResRowSet.CurrentRow.GetValue(RobResRowSet.ResultIds.Get(5))
                
                'initialise envelope variables
                If j = 1 Then
                    iMinFx = ResultFx
                    iMaxFx = ResultFx
                    iMinFz = ResultFz
                    iMaxFz = ResultFz
                    iMinMy = ResultMy
                    iMaxMy = ResultMy
                End If
                
                'compare forces/moments to determine envelope
                If ResultFx < iMinFx Then
                    iMinFx = ResultFx
                End If
                If ResultFx > iMaxFx Then
                    iMaxFx = ResultFx
                End If
                
                If ResultFz < iMinFz Then
                    iMinFz = ResultFz
                End If
                If ResultFz > iMaxFz Then
                    iMaxFz = ResultFz
                End If
                
                If ResultMy < iMinMy Then
                    iMinMy = ResultMy
                End If
                If ResultMy > iMaxMy Then
                    iMaxMy = ResultMy
                End If
                
                
                ok = RobResRowSet.MoveNext()
            Next j
            
            'record force/moment envelope to spreadsheet
            With rCase
                .Cells(6 + i, 1) = iMinFx / 1000
                .Cells(6 + i, 2) = iMaxFx / 1000
                .Cells(6 + i, 3) = iMinFz / 1000
                .Cells(6 + i, 4) = iMaxFz / 1000
                .Cells(6 + i, 5) = iMinMy / 1000
                .Cells(6 + i, 6) = iMaxMy / 1000
            End With
        Next i
        '.protect
    End With
    'update status window
    With frmStatusWindow
        .txtStatusWindow = .txtStatusWindow.Text & _
            "." & vbNewLine
    End With
End Sub

 


 

Message 6 of 8

Some bug in your code:

- wrong selection : bars mixed with cases

    RobResQueryParams.Selection.Set I_OT_BAR, SelCase

- bar selection not set

SelBar.FromText()

- wrong querry

parameter  RobResQueryParams.SetParam I_RPT_BAR_DIV_COUNT, iNumpositions should be set before

querry: Res = Robot.Project.Structure.Results.Query(RobResQueryParams, RobResRowSet)

 

Correct your code and check.



Rafal Gaweda
Message 7 of 8

Thanks Rafal.

 

RoboExploiter has enlisted me to help out, and with your hints the query is working now.  Just need to confirm it's doing the right thing.

Message 8 of 8

Hi Guys, some feedback on your suggestions.  

 

The query mechanism suggested was also unable to capture the peak member force, given 2 member forces at the same position.  

 

I didn't try the extreme server method, as i couldn't risk losing more time to do anymore abortive work.

 

My final solution (albeit flawed) was to read the member forces 1mm above and 1mm below the position in question.

 

Thanks.

Can't find what you're looking for? Ask the community or share your knowledge.

Post to forums  

Autodesk Design & Make Report