Welcome, Guest. Please login or register.
Did you miss your activation email?
May 23, 2012, 07:18:22 PM
Home Help Login Register
News: Any Problems or Experience with Industrial Robots ?
Register and place your Question / Answer to worldwide Robotexperts right here !

+  Robotforum | Support for Robotprogrammer and Users
|-+  Industrial Robot Help and Discussion Center
| |-+  KUKA Robot Forum (Moderators: Werner Hampel, Martin H, SkyeFire)
| | |-+  Finding declared Array length
0 Members and 1 Guest are viewing this topic. « previous next »
Pages: [1] Print
Author Topic: Finding declared Array length  (Read 1473 times)
ChuckUFarley
Newbie
*
Offline Offline

Gender: Male
Posts: 3



« on: June 21, 2009, 11:07:27 PM »

Are there any "built in" functions within KRL to return the declared length of an array? I have created a function to return the declared length of an array of data type FRAME but the sheer size of the "Case" structure is ridiculous. Am I reinventing the wheel here?

Thank you
Logged
SkyeFire
Global Moderator
*****
Offline Offline

Posts: 1784



« Reply #1 on: June 22, 2009, 07:35:25 PM »

Hm... not one that I know of offhand.  There's one for the length of string variables (STRDECLLEN), but it won't work on an array that wasn't type CHAR.  There's a function called GETVARSIZE ( SYS_VARS MESSAGENO:IN ) that I haven't used, but the variable types in the delcaration make me doubtful.

You could use VARSTATE.  Use a FOR loop to count up through the array elements until you get an #UNKNOWN response from the function instead of #DECLARED.  The drawback is, VARSTATE doesn't seem to work on non-global variables.

DECL INT X
DECL VAR_STATE Result
FOR X = 1 TO 100
  Result = VARSTATE ("Array_Name[X]")
  IF Result == #UNKNOWN THEN
    X=X-1
    RETURN X
  ENDIF
ENDFOR

At the end of this loop, X would represent the number to which the array had been declared.  This looks like it should work, but I haven't actually tried it.  If it works for you, let us know.

Addendum:  VARSTATE needs a string variable of the name of the variable you want to check, so this won't work as-is.  You'll need to use a string-construction function to get X properly into the "ARRAY_NAME[X]" string.
« Last Edit: June 22, 2009, 07:55:47 PM by SkyeFire » Logged
ChuckUFarley
Newbie
*
Offline Offline

Gender: Male
Posts: 3



« Reply #2 on: June 22, 2009, 10:27:30 PM »

Heres a short example, it only checks 5 elements but to check an array of maybe 1000 elements the case structure gets out of hand fast. Sure it works if you don't mind 10000 line functions. I am missing something on the string-construction function though. Assuming X is initialized to 1, I noticed that MY_VAR = (VARSTATE("tool_data[X]")) would always return #UNKNOWN but MY_VAR = (VARSTATE("tool_data[1]")) would return #INITIALISED. Would the string construction function help solve this problem? This is the root cause of my "case" problem - all 1000+ of them.

Thanx!



GLOBAL DEFFCT INT ARRAYLENGTH_FRM(_ARRAYNAME, STATE)
DECL FRAME _ARRAYNAME[]
DECL INT ARRAY_INDEX, NUM_DECLARED,NUM_INITIALIZED
DECL VAR_STATE STATE

$ADVANCE=0

ARRAY_INDEX=0
NUM_DECLARED=0
NUM_INITIALIZED=0

LOOP

ARRAY_INDEX=ARRAY_INDEX+1

SWITCH(ARRAY_INDEX)
;FOLD    CASE 1, 2, 3,....N
    CASE   1
        SWITCH (VARSTATE("_ARRAYNAME[1]"))         
          CASE #UNKNOWN        
                EXIT
            CASE #DECLARED
                NUM_DECLARED=NUM_DECLARED+1
            CASE #INITIALIZED
                NUM_INITIALIZED=NUM_INITIALIZED+1
         ENDSWITCH                                                                                          
    CASE   2                                                                                                   
          SWITCH (VARSTATE("_ARRAYNAME[2]"))                                                                                                            
            CASE #UNKNOWN        
                EXIT
            CASE #DECLARED
                NUM_DECLARED=NUM_DECLARED+1
            CASE #INITIALIZED
                NUM_INITIALIZED=NUM_INITIALIZED+1
         ENDSWITCH                                                                                           
    CASE   3                                                                                                   
          SWITCH (VARSTATE("_ARRAYNAME[3]"))                                                                                                            
            CASE #UNKNOWN        
                EXIT
            CASE #DECLARED
                NUM_DECLARED=NUM_DECLARED+1
            CASE #INITIALIZED
                NUM_INITIALIZED=NUM_INITIALIZED+1
         ENDSWITCH                                                                                           
    CASE   4                                                                                                   
          SWITCH (VARSTATE("_ARRAYNAME[4]"))                                                                                                            
            CASE #UNKNOWN        
                EXIT
            CASE #DECLARED
                NUM_DECLARED=NUM_DECLARED+1
            CASE #INITIALIZED
                NUM_INITIALIZED=NUM_INITIALIZED+1
         ENDSWITCH                                                                                           
    CASE   5                                                                                                   
          SWITCH (VARSTATE("_ARRAYNAME[5]"))                                                                                                            
            CASE #UNKNOWN        
                EXIT
            CASE #DECLARED
                NUM_DECLARED=NUM_DECLARED+1
            CASE #INITIALIZED
                NUM_INITIALIZED=NUM_INITIALIZED+1
         ENDSWITCH 
             DEFAULT
      EXIT
ENDSWITCH

ENDLOOP

$ADVANCE=3

SWITCH(STATE)
  CASE #INITIALIZED
    RETURN NUM_INITIALIZED
  CASE #DECLARED
    RETURN NUM_DECLARED
ENDSWITCH

ENDFCT
Logged
SkyeFire
Global Moderator
*****
Offline Offline

Posts: 1784



« Reply #3 on: June 25, 2009, 10:19:33 PM »

Well, I've been able to make the loop work using VARSTATE.  The weaknesses so far are:

1:  The function has to be hard-coded for the correct variable type of the array (INT, REAL, etc).

2:  To avoid #1, I need a way to convert the name of a variable into a string and send *that* to the size-measuring function.

Logged
ChuckUFarley
Newbie
*
Offline Offline

Gender: Male
Posts: 3



« Reply #4 on: June 29, 2009, 05:45:20 PM »

The string building example helped immensely! 100000+ lines reduced to less than 200. Example attached and includes functions for the usual data types. Any enumerated types or structures will have to be added as needed. Thanks!
Logged
mookie
Global Moderator
*****
Offline Offline

Gender: Male
Posts: 419



« Reply #5 on: April 08, 2010, 08:41:39 PM »

Let me throw my hat into the ring, this is working, allthough i still have a couple things to work out


Code:
GLOBAL DEFFCT INT Array_Length(Var[] : IN, _VarType : IN)
;FOLD --> Variables
CHAR Var[]
DECL Var_Type _VarType
DECL INT Size, i, Unknown
Size = 0
UnKnown = 0
;ENDFOLD
;FOLD --> Get Max Array Size for type Variable
;ENDFOLD

For I = 1 to _GetArraySize(_VarType)

 Switch (GetVarState(Var[],I))
  Case #Initialized, #Declared
    Size = Size + 1
  Case #UnKnown
    Unknown = Unknown + 1 
 ENDSWITCH
ENDFOR
halt
Return Size
ENDFCT
DEFFCT Var_State GetVarState(Var[] : IN, Index : IN)
;FOLD --> Variables
CHAR Var[]
DECL INT RESULT, INDEX, OFFSET
DECL STATE_T StateResult
CHAR ResultString[26]
DECL CHAR QUOTE[1]
DECL CHAR NUM[256]
QUOTE[1] = 'h22'
OFFSET = 0

;ENDFOLD
;FOLD --> Write the Index number to a string
;ENDFOLD
SWRITE (NUM[], STATERESULT, OFFSET, "%D", INDEX)

Result = StrAdd(ResultString[],VAR[])
Result = StrAdd(ResultString[],"[")
Result = StrAdd(ResultString[],NUM[])
Result = StrAdd(ResultString[],"]")

Return VarState(ResultString[])

ENDFCT

GLOBAL DEFFCT Int _getArraySize(_VarType : IN)

;FOLD Variables
DECL Var_Type _VarType

INT Max_Struc_Array,Max_INT_Array,Max_REAL_Array,Max_Bool_Array
INT Max_Char_Array,Max_VarState_Array,Max_Frame_Array,MAX_E6POS_ARRAY,MAX_E3POS_ARRAY
INT MAX_E6AXIS_ARRAY,MAX_E3AXIS_ARRAY,MAX_AXIS_ARRAY ,MAX_POS_ARRAY       

Max_Struc_Array = 371       
Max_INT_Array = 7709       
Max_REAL_Array = 7709       
Max_Bool_Array = 26208     
Max_Char_Array = 26208     
Max_VarState_Array = 7942   
Max_Frame_Array = 1164     
MAX_E6POS_ARRAY = 544       
MAX_E3POS_ARRAY = 680       
MAX_POS_ARRAY = 906         
MAX_E6AXIS_ARRAY = 628     
MAX_E3AXIS_ARRAY = 820     
MAX_AXIS_ARRAY = 1164       

;ENDFOLD




Switch (_VarType)
 CASE #Typ_CHAR
    return MAX_char_ARRAY
 CASE #TYP_STRUC
   Return MAX_struc_ARRAY
 CASE #TYP_FRAME
   Return MAX_frame_ARRAY
 CASE #TYP_AXIS
   Return MAX_axis_ARRAY
 CASE #TYP_E3AXIS
   Return MAX_e3axis_ARRAY
 CASE #TYP_E6AXIS
   Return MAX_e6axis_ARRAY
 CASE #TYP_POS
   Return MAX_pos_ARRAY
 CASE #TYP_E3POS
   Return MAX_e3pos_ARRAY
 CASE #TYP_E6POS
   Return MAX_e6pos_ARRAY
 Case #TYP_BOOL
   Return MAX_bool_ARRAY
 Case #TYP_INT
   Return MAX_int_ARRAY
 CASE #TYP_REAL
   Return MAX_real_ARRAY
Default
  HALT
  ; Variable Types Not Allowed
  Loop
   Wait Sec .5
  ENDLOOP
EndSwitch
ENDFCT
Logged
SkyeFire
Global Moderator
*****
Offline Offline

Posts: 1784



« Reply #6 on: April 09, 2010, 05:53:13 PM »

I'll offer a small enhancement that might be useful:
Code:
GLOBAL INT Array_Length(Var[] : IN, _VarType : IN, _InitSize : OUT, _DeclSize : OUT)
  ;FOLD --> Variables
  CHAR Var[]
  DECL Var_Type _VarType
  DECL INT _InitSize,_DeclSize, i, Unknown
  _DeclSize = 0
  _InitSize = 0
  UnKnown = 0
  ;ENDFOLD
  ;FOLD --> Get Max Array Size for type Variable
  ;ENDFOLD
 
  For I = 1 to _GetArraySize(_VarType)
    Switch (GetVarState(Var[],I))
    Case #Initialized
      _InitSize = _InitSize + 1
    Case #Declared
      _DeclSize = DeclSize + 1
    Case #UnKnown
      Unknown = Unknown + 1 
    ENDSWITCH
  ENDFOR
END

It's not a function anymore, but it will send back both the Declared size and the Initialized size of the array, so this should work (I haven't tested it) to give you both how large the array was declared to be, and how many of the array's elements currently hold any values.
Logged
mookie
Global Moderator
*****
Offline Offline

Gender: Male
Posts: 419



« Reply #7 on: April 09, 2010, 05:54:44 PM »

did you get the email i sent you this morning?
Logged
Pages: [1] Print 
« previous next »
Jump to:  


Login with username, password and session length

Powered by MySQL Powered by PHP Powered by SMF 1.1.16 | SMF © 2011, Simple Machines Valid XHTML 1.0! Valid CSS!