Lists and Structs
Struct
A set of variables can be aggregated into structs, and thus transferred and stored as a single variable.
Structs can be obtained through multiple means:
-
Using the struct function
-
Doing an RPC call that returns a struct
-
Receiving ROS2 message (available on Polyscope X only)
The struct function takes one or more named arguments, and each argument name becomes a member in the struct. All values must be initialized by value, and the type of the value cannot be changed subsequently.
Using a struct
Create a struct:
myStruct = struct(identifier1 = 1, identifier2 = 2, myMember = "Hello structs", listMember = [1,2,3])
Reassign a member:
myStruct.myMember = "Goodbye structs"
Use a member:
myVar = myStruct.myMember
Use a nested list:
myListElement = myStruct.listMember[0]
Use the second member by index (identifier2):
myVar = myStruct[1]
A nested struct, stored by value:
myStruct = struct(myStructMember = struct(myMember = "Hi nested struct") )
Conversion of a struct to a list, if all the struct members are of same type and if the list has the same type. Value of myList will be [1.1, 2.2, 3.3, 4.4].
myStruct = struct(m1 = 1.1, m2 = 2.2, m3 = 3.3, m4 = 4.4) myList = [0.0, 0.0, 0.0, 0.0] myList = myStruct
Structs can be passed to and returned from function. In this example we create a new struct extended with a boolean member.
struct_1 = struct(m1 = 1.1, m2="a string", m3=[1,2,3]) def ExtendStructWithBoolMember(struct_arg): struct_local = struct(m1 = 0.0, m2 = "n/a", m3 = make_list(0, 0, 10), extra_member = False) struct_local.m1 = struct_arg.m1 struct_local.m2 = struct_arg.m2 struct_local.m3 = struct_arg.m3 struct_local.extra_member = True return struct_local end new_extended_struct = ExtendStructWithBoolMember(struct_1)
List
A list is a set of variables with the same type aggregated into a single object.
A list object in URScript has two attributes: length and capacity. The length indicates how many elements the list currently holding. The capacity tells how many elements the list can hold maximum.
Once declared, the capacity of the list cannot be changed.
Fixed length lists can be created with square bracket operator:
aa = [11, 22, 33, 44, 55, 66, 77]
Both length and capacity of this list is equal to 7.
Variable length lists can be created:
bb = make_list(length = 7, initial_value = 11, capacity = 20)
Length of this list is 7, but capacity is 20. List can be extended and contracted between 0, and 20 numeric elements.
Lists can hold any type that URScript supports. This includes complex values created with struct() keyword:
aa = [1, 2, 3.5, 4, 5.5] bb = make_list(10, struct(p1 = 1, p2 = "text"), 10) cc = ["a", "b", "c", "d"] dd = [struct(m1 = 10, m2 = "hello", m3 = make_list(length = 25, initial_value = 0, capacity = 100)) , struct(m1 = 20, m2 = "hi", m3 = make_list(length = 50, initial_value = 0, capacity = 100))]
List can be assigned only to existing list of greater or equal capacity to the length of source list:
aa = [1, 2, 3, 4, 5, 6] # aa.length() == 6, aa.capacity() == 6 bb = make_list(5, 0, 100) # bb.length() == 5, bb.capacity() == 100 aa = bb # aa capacity will remain 6 aa length will be 5 aa = [1, 2, 3, 4, 5, 6] bb = aa # bb capacity will remain 100 bb length will be 6
List can hold structs (aka complex data types). All structs in the list have to be exactly of the same type:
aa = make_list(10, struct(p1 = 1, p2 = "text"), 10) a = aa[4].p1 # a = 1 b = aa[4].p2 # b = "text" aa[3].p1 = 22.5 aa[4] = struct(p1 = 99, p2 = "different text")
Limitations of lists
Lists can be passed to, and returned from functions only as copy by value.
List elements can't change type.
If list is returned from a function or list method, then the target list have to be earlier initialized with enough capacity.
List of lists is not supported as this is how matrices are implemented in URScript.