Value Types

Overview

Robot Raconteur passes “Value Types” between clients and services by value. The values are “serialized” to a binary format that can be transmitted over a network. The values are then “deserialized” back into the original data type. The serialization and deserialization process is handled transparently by the Robot Raconteur library. Because Robot Raconteur supports multiple programming languages, the value types are defined using Robot Raconteur “Service Definitions,” which provide a common language-independent format for defining data types. The Value Types are carefully designed to support robotics and automation applications.

See also the Robot Raconteur Framework Service Definition Documentation

The following data types are supported by Robot Raconteur:

  • bool - A boolean value that can be either true or false. * Arrays and multidimensional arrays of booleans.

  • Numeric types including uint8, int8, uint16, int16, uint32, int32, uint64, int64, single, double, csingle, and cdouble. * Arrays and multidimensional arrays of numeric types.

  • string - A string of characters.

  • struct - A structure that contains a collection of fields.

  • pod - A “Plain Old Data” structure that contains a collection of fields that are stored in contiguous memory. * Arrays and multidimensional arrays of POD types.

  • namedarray - A structure that contains a collection of fields that are stored as a union between a structure and a numeric array in contiguous memory. * Arrays and multidimensional arrays of namedarray types.

  • Collection types including list, map{int32}, and map{string}. * Any of the above types can be used as the value type in a collection type.

The struct, pod, and namedarray types are defined using the Robot Raconteur “Service Definitions” format.

Object “members” are used to interact with services and pass data between clients and services. The examples on this page use property types to pass data between clients and services. The value types can all be used with all member types.

The example service definition experimental.value_types is used for the examples on this page. The service definition is shown below:

  1service experimental.value_types
  2
  3stdver 0.10
  4
  5# Example vector namedarray. Note that all fields must
  6# have the same underlying numeric type
  7namedarray MyVector3
  8    field double x
  9    field double y
 10    field double z
 11end
 12
 13namedarray MyQuaternion
 14    field double w
 15    field double x
 16    field double y
 17    field double z
 18end
 19
 20# Example pose namedarray using composition of other namedarrays.
 21# All underlying fields must have the same numeric type.
 22namedarray MyPose
 23    field MyQuaternion orientation
 24    field MyVector3 position
 25end
 26
 27# Pod example. Only numeric types, other pods, and namedarrays can
 28# be used in a pod. All arrays must have a fixed or maximum length.
 29# Multidimarrays must be fixed. Pods have a fixed maximum binary
 30# size to fit in contiguous memory. Pods do not
 31# have to have the same underlying numeric type for all the
 32# fields.
 33pod MyPod
 34    field double a
 35    field int32 b
 36    field uint8[4] c
 37    field uint8[4-] d
 38    field uint16[2,3] e
 39    field MyVector3 f
 40end
 41
 42# Structure examples.
 43struct MyStructure
 44    # struct fields can be any value type
 45    field double a
 46    field uint32[2] b
 47    field string c
 48    field string{list} d
 49end
 50
 51# This object contains examples of many value types. The names of the fields are
 52# arbitrary. See the standard service definitions for examples of more
 53# common naming conventions.
 54object ValueTypesExample
 55    # Examples of scalar numeric types
 56    property double a_double
 57    property int32 b_int
 58    property uint8 c_byte
 59    property cdouble d_cdouble
 60    property bool e_bool
 61    property int32 meaning_of_life [readonly]
 62
 63    # Examples of numeric arrays. Any numeric array type
 64    # can be used
 65    property double[] a_double_array
 66    property double[3] a_double_array_fixed
 67    property double[6-] a_double_array_maxlen
 68    property double[3,2] a_double_marray_fixed
 69    property double[*] a_double_marray
 70    property uint8[] c_byte_array
 71
 72    property string f_string
 73
 74    # Examples using namedarray
 75    property MyVector3 g_vector
 76    property MyVector3[] g_vector_array
 77    property MyQuaternion h_quaternion
 78    property MyPose i_pose
 79
 80    # Examples using pods
 81    property MyPod j_pod
 82    property MyPod[] j_pod_array
 83
 84    # Examples using structures
 85    property MyStructure k_struct
 86
 87    # Container examples
 88    # Containers can be int32 key maps, string key maps, or lists
 89    # All types can be stored in containers, but containers cannot
 90    # directly contain other containers. For example
 91    # string{list} is allowed, but string{list}{list} is not.
 92    property double{int32} l_double_map
 93    property double[]{string} l_double_array_map
 94    property string{list} m_string_list
 95    property string{int32} m_string_map_int32
 96    property string{string} m_string_map_string
 97    property MyVector3{int32} n_vector_map
 98    property MyStructure{list} o_struct_list
 99
100    # varvalue examples
101    property varvalue p_varvalue_double_array
102    property varvalue q_varvalue_string
103    property varvalue r_varvalue_struct
104    # varvalue{string} is a string keyed map of varvalues
105    # It is frequently used for "extended" fields
106    # to allow for forward compatibility
107    property varvalue{string} s_varvalue_map2
108
109    # Null examples
110    property MyStructure t_struct_null
111end

Numeric Types

Robot Raconteur supports numeric types including uint8, int8, uint16, int16, uint32, int32, uint64, int64, single, double, csingle, and cdouble. For the purpose of this section, bool is also considered a numeric type. Scalar numbers are converted to the built-in numeric types in the client programming language. Numeric types can also be stored in arrays and multidimensional arrays.

The following members from the experimental.value_types.ValueTypesExample object are used in the examples for numeric types:

    # Examples of scalar numeric types
    property double a_double
    property int32 b_int
    property uint8 c_byte
    property cdouble d_cdouble
    property bool e_bool
    property int32 meaning_of_life [readonly]

    # Examples of numeric arrays. Any numeric array type
    # can be used
    property double[] a_double_array
    property double[3] a_double_array_fixed
    property double[6-] a_double_array_maxlen
    property double[3,2] a_double_marray_fixed
    property double[*] a_double_marray
    property uint8[] c_byte_array

The examples below show how to use the numeric types in Python, MATLAB, LabView, C#, and C++.

 1# numeric_value_types.py - Example of using numeric value types
 2
 3from RobotRaconteur.Client import *
 4import numpy as np
 5
 6c = RRN.ConnectService('rr+tcp://localhost:53223?service=values_example')
 7
 8# Scalar numbers
 9# property double a_double
10a_double_read = c.a_double
11print(a_double_read)
12# assert is used for the rest of the example property read operations
13# to demonstrate the expected values.
14assert (c.a_double == 5.78)
15c.a_double = 49.3
16# property int32 b_int
17assert (c.b_int == 4557)
18c.b_int = 359
19# property uint8 c_byte
20assert (c.c_byte == 0x1A)
21c.c_byte = 31
22# property cdouble d_cdouble
23assert (c.d_cdouble == 23.7 + 1j * 5.3)
24c.d_cdouble = 1.2 + 3.4j
25# property bool e_bool
26assert (c.e_bool == True)
27c.e_bool = False
28# property int32 meaning_of_life [readonly]
29assert (c.meaning_of_life == 42)
30
31# Numeric Arrays
32# Note the use of `dtype` parameter when creating arrays. This must match the
33# type specified in the service definition.
34# property double[] a_double_array
35np.testing.assert_allclose(c.a_double_array, [0.016, 0.226])
36c.a_double_array = np.array([0.582, 0.288, 0.09, 0.213, 0.98], dtype=np.float64)
37# property double[3] a_double_array_fixed
38np.testing.assert_allclose(c.a_double_array_fixed, [0.13, 0.27, 0.15])
39c.a_double_array_fixed = np.array([0.21, 0.12, 0.39], dtype=np.float64)
40# property double[6-] a_double_array_maxlen
41np.testing.assert_allclose(c.a_double_array_maxlen, [0.7, 0.16, 0.16, 0.05, 0.61, 0.9])
42c.a_double_array_maxlen = np.array([0.035, 0.4], dtype=np.float64)
43# property double[3,2] a_double_marray_fixed
44np.testing.assert_allclose(c.a_double_marray_fixed, [[0.29, 0.66], [0.41, 0.6], [0.4, 0.2]])
45c.a_double_marray_fixed = np.array([[0.3, 0.6], [0.4, 0.6], [0.5, 0.2]], dtype=np.float64)
46# property double[*] a_double_marray
47np.testing.assert_allclose(c.a_double_marray, [[0.72, 0.4], [0.05, 0.07]])
48c.a_double_marray = np.array([[0.3], [0.01]], dtype=np.float64)
49# property uint8[] c_byte_array
50np.testing.assert_array_equal(c.c_byte_array, [0x1A, 0x2B])
51c.c_byte_array = np.array([0x3C, 0x4D, 0x5E, 0x6F, 0x70], dtype=np.uint8)

String Type

Robot Raconteur uses the built-in string types in the client programming language. Note that strings cannot be stored in arrays since internally strings are already stored as arrays of characters.

The following members from the experimental.value_types.ValueTypesExample object are used in the examples for numeric types:

    property string f_string

The examples below show how to use strings in Python, MATLAB, LabView, C#, and C++.

 1# string_value_type.py - Example of using string value types
 2
 3from RobotRaconteur.Client import *
 4import numpy as np
 5
 6c = RRN.ConnectService('rr+tcp://localhost:53223?service=values_example')
 7
 8# Strings
 9# property string f_string
10f_string_read = c.f_string
11print(f_string_read)
12# assert is used for the rest of the example property read operations
13# to demonstrate the expected values.
14assert (c.f_string == "An example string read from the service")
15c.f_string = "An example string written to the service"

Structure Types

Structures are a collection of fields that can contain any value type, including itself. Structures are defined using the Robot Raconteur “Service Definitions” format. Structures are nullable. The following examples demonstrate using the experimental.value_types.MyStructure structure type:

# Structure examples.
struct MyStructure
    # struct fields can be any value type
    field double a
    field uint32[2] b
    field string c
    field string{list} d
end

The following members from the experimental.value_types.ValueTypesExample object are used in the examples for structure types:

    property MyStructure k_struct

The examples below show how to use structures in Python, MATLAB, LabView, C#, and C++.

 1# struct_value_type.py - Simple example of using struct value types
 2
 3from RobotRaconteur.Client import *
 4import numpy as np
 5
 6c = RRN.ConnectService('rr+tcp://localhost:53223?service=values_example')
 7
 8# Example using MyStructure type. Also see example
 9# using MyStructure for a more complex example.
10
11# Retrieve the structure type. obj is only used
12# for clients. It is omitted for services.
13my_structure_type = RRN.GetStructureType("experimental.value_types.MyStructure", obj=c)
14
15# Create and populate a MyStructure
16s = my_structure_type()
17# field double a
18s.a = 5
19# field uint32[2] b
20s.b = np.array([10, 20], dtype=np.uint32)
21# field string c
22s.c = "String from structure client"
23# field string{list} d
24s.d = [
25    "string a",
26    "string b"
27]
28
29# Set the property using the structure
30# property MyStructure k_struct
31c.k_struct = s
32
33# Retrieve the structure from the service
34u = c.k_struct
35
36# Structures can be None
37assert u is not None
38
39# field double a
40assert (u.a == 52)
41# field uint32[2] b
42np.testing.assert_array_equal(u.b, np.array([110, 120], dtype=np.uint32))
43# field string c
44assert (u.c == "String from structure service")
45# field string{list} d
46assert (len(u.d) == 3)
47assert (u.d[0] == "string c")
48assert (u.d[1] == "string d")
49assert (u.d[2] == "string e")

Pod Types

Pods are a collections of fields that have a fixed memory layout. Pods have a restricted set of allowed field types including numbers, arrays, namedarrays, and other pods. See the Robot Raconteur Framework Service Definition Documentation for more information about the allowed contents of pods. Unlike structures, pods store all their data within the pod itself in contiguous memory, and do not contain pointers to other data. They are guaranteed to have a maximum binary size. The following examples demonstrate using the experimental.value_types.MyPod pod type:

# Pod example. Only numeric types, other pods, and namedarrays can
# be used in a pod. All arrays must have a fixed or maximum length.
# Multidimarrays must be fixed. Pods have a fixed maximum binary
# size to fit in contiguous memory. Pods do not
# have to have the same underlying numeric type for all the
# fields.
pod MyPod
    field double a
    field int32 b
    field uint8[4] c
    field uint8[4-] d
    field uint16[2,3] e
    field MyVector3 f
end

The following members from the experimental.value_types.ValueTypesExample object are used in the examples for pod types:

    # Examples using pods
    property MyPod j_pod
    property MyPod[] j_pod_array

The examples below show how to use pods in Python, MATLAB, LabView, C#, and C++.

 1# pod_value_types.py - Example of using pod value types
 2
 3from RobotRaconteur.Client import *
 4import numpy as np
 5
 6c = RRN.ConnectService('rr+tcp://localhost:53223?service=values_example')
 7
 8# Example using Pod numpy dtypes. Pods are represented as NumPy dtypes with fields
 9# obj is only used for clients. It is omitted for services.
10my_pod_dtype = RRN.GetPodDType("experimental.value_types.MyPod", obj=c)
11
12# property MyPod j_pod
13a = np.zeros((1,), dtype=my_pod_dtype)
14a[0]["a"] = 0.928
15a[0]["b"] = 8374
16a[0]["c"] = [8, 9, 10, 11]
17# Max length fields are stored with a length field and
18# data field.
19a[0]["d"]["len"] = 1
20a[0]["d"]["array"][0] = 17
21a[0]["e"] = [[1, 2, 3], [4, 5, 6]]
22a[0]["f"]["x"] = 10.1
23a[0]["f"]["y"] = 10.2
24a[0]["f"]["z"] = 10.3
25c.j_pod = a
26
27b = c.j_pod
28assert (b[0]["a"] == 0.791)
29assert (b[0]["b"] == 1077)
30np.testing.assert_array_equal(b[0]["c"], [61, 52, 33, 24])
31assert (b[0]["d"]["len"] == 2)
32np.testing.assert_array_equal(b[0]["d"]["array"][0:2], [1, 2])
33np.testing.assert_array_equal(b[0]["e"], [[7, 8, 9], [10, 11, 12]])
34assert (b[0]["f"]["x"] == 20.1)
35assert (b[0]["f"]["y"] == 20.2)
36assert (b[0]["f"]["z"] == 20.3)
37
38# Now an array of Pods
39# property MyPod[] j_pod_array
40d = np.zeros((2,), dtype=my_pod_dtype)
41d[0]["a"] = 0.928
42d[0]["b"] = 8374
43d[0]["c"] = [8, 9, 10, 11]
44d[0]["d"]["len"] = 1
45d[0]["d"]["array"][0] = 17
46d[0]["e"] = [[1, 2, 3], [4, 5, 6]]
47d[0]["f"]["x"] = 10.1
48d[0]["f"]["y"] = 10.2
49d[0]["f"]["z"] = 10.3
50d[1]["a"] = 0.67
51d[1]["b"] = 123
52d[1]["c"] = [1, 2, 3, 4]
53d[1]["d"]["len"] = 2
54d[1]["d"]["array"][0:2] = [5, 6]
55d[1]["e"] = [[13, 14, 15], [16, 17, 18]]
56d[1]["f"]["x"] = 30.1
57d[1]["f"]["y"] = 30.2
58d[1]["f"]["z"] = 30.3
59c.j_pod_array = d
60
61e = c.j_pod_array
62assert (e[0]["a"] == 0.791)
63assert (e[0]["b"] == 1077)
64np.testing.assert_array_equal(e[0]["c"], [61, 52, 33, 24])
65assert (e[0]["d"]["len"] == 2)
66np.testing.assert_array_equal(e[0]["d"]["array"][0:2], [1, 2])
67np.testing.assert_array_equal(e[0]["e"], [[7, 8, 9], [10, 11, 12]])
68assert (e[0]["f"]["x"] == 20.1)
69assert (e[0]["f"]["y"] == 20.2)
70assert (e[0]["f"]["z"] == 20.3)
71assert (e[1]["a"] == 0.03)
72assert (e[1]["b"] == 693)
73np.testing.assert_array_equal(e[1]["c"], [5, 6, 7, 8])
74assert (e[1]["d"]["len"] == 1)
75np.testing.assert_array_equal(e[1]["d"]["array"][0:1], [3])
76np.testing.assert_array_equal(e[1]["e"], [[19, 20, 21], [22, 23, 24]])
77assert (e[1]["f"]["x"] == 40.1)
78assert (e[1]["f"]["y"] == 40.2)
79assert (e[1]["f"]["z"] == 40.3)

NamedArray Types

Namedarrays represent a union type between a structure and a numeric array. A vector is an example of a type that can be represented either as a structure with three fields, or as a numeric array with three elements. Namedarrays are very efficient compared to the other data types since they can be transmitted or manipulated as a plain array. All fields in the namedarray must have the same numeric type. Other namedarrays and arrays may also be used as fields, but they must have the same underlying numeric type and a fixed size. The following examples demonstrate using the experimental.value_types.MyVector3, experimental.value_types.MyQuaternion, and experimental.value_types.MyPose namedarray types:

# Example vector namedarray. Note that all fields must
# have the same underlying numeric type
namedarray MyVector3
    field double x
    field double y
    field double z
end

namedarray MyQuaternion
    field double w
    field double x
    field double y
    field double z
end

# Example pose namedarray using composition of other namedarrays.
# All underlying fields must have the same numeric type.
namedarray MyPose
    field MyQuaternion orientation
    field MyVector3 position
end

The following members from the experimental.value_types.ValueTypesExample object are used in the examples for namedarray types:

    # Examples using namedarray
    property MyVector3 g_vector
    property MyVector3[] g_vector_array
    property MyQuaternion h_quaternion
    property MyPose i_pose

The examples below show how to use namedarrays in Python, MATLAB, LabView, C#, and C++.

  1# namedarray_value_types.py - Example of using namedarray value types
  2
  3from RobotRaconteur.Client import *
  4import numpy as np
  5
  6c = RRN.ConnectService('rr+tcp://localhost:53223?service=values_example')
  7
  8# Retrieve NamedArray numpy dtypes. NamedArrays are represented as NumPy dtypes with fields
  9# obj is only used for clients. It is omitted for services.
 10my_vector3_dtype = RRN.GetNamedArrayDType("experimental.value_types.MyVector3", obj=c)
 11my_quaternion_dtype = RRN.GetNamedArrayDType("experimental.value_types.MyQuaternion", obj=c)
 12my_pose_dtype = RRN.GetNamedArrayDType("experimental.value_types.MyPose", obj=c)
 13
 14# NumPy structures are used to represent NamedArrays.
 15# These structures can also be converted to and from plain arrays of the
 16# underlying numeric type using RRN.NamedArrayToArray() and RRN.ArrayToNamedArray().
 17# Scalar NamedArrays are represented as arrays with a single element.
 18
 19# property MyVector3 g_vector
 20a = np.zeros((1,), dtype=my_vector3_dtype)
 21a[0]["x"] = 1.0
 22a[0]["y"] = 2.0
 23a[0]["z"] = 3.0
 24c.g_vector = a
 25
 26b = c.g_vector
 27assert (b[0]["x"] == 4.0)
 28assert (b[0]["y"] == 5.0)
 29assert (b[0]["z"] == 6.0)
 30
 31# Use plain arrays and convert to and from NamedArrays
 32d = np.array([1.0, 2.0, 3.0], dtype=np.float64)
 33c.g_vector = RRN.ArrayToNamedArray(d, named_array_dt=my_vector3_dtype)
 34e = RRN.NamedArrayToArray(c.g_vector)
 35np.testing.assert_array_equal(e, [[4.0, 5.0, 6.0]])
 36
 37# Now an array of NamedArrays
 38# property MyVector3[] g_vector_array
 39f = np.zeros((2,), dtype=my_vector3_dtype)
 40f[0]["x"] = 1.0
 41f[0]["y"] = 2.0
 42f[0]["z"] = 3.0
 43f[1]["x"] = 4.0
 44f[1]["y"] = 5.0
 45f[1]["z"] = 6.0
 46c.g_vector_array = f
 47
 48g = c.g_vector_array
 49assert (g[0]["x"] == 7.0)
 50assert (g[0]["y"] == 8.0)
 51assert (g[0]["z"] == 9.0)
 52assert (g[1]["x"] == 10.0)
 53assert (g[1]["y"] == 11.0)
 54assert (g[1]["z"] == 12.0)
 55
 56# Use plain arrays and convert to and from NamedArrays
 57h = np.array([[1.0, 2.0, 3.0], [4.0, 5.0, 6.0]], dtype=np.float64)
 58c.g_vector_array = RRN.ArrayToNamedArray(h, named_array_dt=my_vector3_dtype)
 59i = RRN.NamedArrayToArray(c.g_vector_array)
 60np.testing.assert_array_equal(i, [[7.0, 8.0, 9.0], [10.0, 11.0, 12.0]])
 61
 62# property MyQuaternion h_quaternion
 63j = np.zeros((1,), dtype=my_quaternion_dtype)
 64j[0]["w"] = 1.0
 65j[0]["x"] = 0.0
 66j[0]["y"] = 0.0
 67j[0]["z"] = 0.0
 68c.h_quaternion = j
 69
 70k = c.h_quaternion
 71assert (k[0]["w"] == 0.707)
 72assert (k[0]["x"] == 0.0)
 73assert (k[0]["y"] == 0.707)
 74assert (k[0]["z"] == 0.0)
 75
 76# MyPose is a composite NamedArray with fields of other NamedArrays
 77# property MyPose l_pose
 78l = np.zeros((1,), dtype=my_pose_dtype)
 79l[0]["orientation"]["w"] = 1.0
 80l[0]["orientation"]["x"] = 0.0
 81l[0]["orientation"]["y"] = 0.0
 82l[0]["orientation"]["z"] = 0.0
 83l[0]["position"]["x"] = 1.0
 84l[0]["position"]["y"] = 2.0
 85l[0]["position"]["z"] = 3.0
 86c.i_pose = l
 87
 88m = c.i_pose
 89assert (m[0]["orientation"]["w"] == 0.707)
 90assert (m[0]["orientation"]["x"] == 0.0)
 91assert (m[0]["orientation"]["y"] == 0.707)
 92assert (m[0]["orientation"]["z"] == 0.0)
 93assert (m[0]["position"]["x"] == 4.0)
 94assert (m[0]["position"]["y"] == 5.0)
 95assert (m[0]["position"]["z"] == 6.0)
 96
 97# Use plain arrays and convert to and from NamedArrays
 98n = np.array([1.0, 0.0, 0.0, 0.0, 1.0, 2.0, 3.0,], dtype=np.float64)
 99c.i_pose = RRN.ArrayToNamedArray(n, named_array_dt=my_pose_dtype)
100o = RRN.NamedArrayToArray(c.i_pose)
101np.testing.assert_array_equal(o, [[0.707, 0.0, 0.707, 0.0, 4.0, 5.0, 6.0]])

Container Types

Robot Raconteur containers store a collection of values using lists and maps. The available container types are list, map{int32}, and map{string}. The container types can store any value type, except for other containers. Containers are nullable.

The following members from the experimental.value_types.ValueTypesExample object are used in the examples for container types:

    # Container examples
    # Containers can be int32 key maps, string key maps, or lists
    # All types can be stored in containers, but containers cannot
    # directly contain other containers. For example
    # string{list} is allowed, but string{list}{list} is not.
    property double{int32} l_double_map
    property double[]{string} l_double_array_map
    property string{list} m_string_list
    property string{int32} m_string_map_int32
    property string{string} m_string_map_string
    property MyVector3{int32} n_vector_map
    property MyStructure{list} o_struct_list

The examples below show how to use containers in Python, MATLAB, LabView, C#, and C++.

  1# container_value_types.py - Example of using container value types (maps and lists)
  2
  3from RobotRaconteur.Client import *
  4import numpy as np
  5
  6c = RRN.ConnectService('rr+tcp://localhost:53223?service=values_example')
  7
  8# property double{int32} l_double_map
  9# int32 keyed map of scalar doubles
 10c.l_double_map = {
 11    1: 1.1,
 12    2: 2.2,
 13    5: 3.3
 14}
 15
 16b = c.l_double_map
 17assert (len(b) == 2)
 18assert (b[1] == 5.1)
 19assert (b[5] == 6.2)
 20
 21# property double[]{string} l_double_array_map
 22# string keyed map of double arrays
 23c.l_double_array_map = {
 24    "key1": np.array([1.1, 1.2, 1.3], dtype=np.float64),
 25    "key2": np.array([2.1, 2.2, 2.3], dtype=np.float64)
 26}
 27
 28d = c.l_double_array_map
 29assert (len(d) == 2)
 30np.testing.assert_array_equal(d["key3"], [5.1, 5.2, 5.3])
 31np.testing.assert_array_equal(d["key4"], [6.1, 6.2, 6.3])
 32
 33# property string{list} m_string_list
 34# list of strings
 35c.m_string_list = ["string 1", "string 2", "string 3"]
 36
 37a = c.m_string_list
 38assert (len(a) == 2)
 39assert (a[0] == "string 4")
 40assert (a[1] == "string 5")
 41
 42
 43# property string{int32} m_string_map_int32
 44# int32 keyed map of strings
 45c.m_string_map_int32 = {
 46    12: "string 1",
 47    100: "string 2",
 48    17: "string 3"
 49}
 50
 51e = c.m_string_map_int32
 52assert (len(e) == 2)
 53assert (e[87] == "string 4")
 54assert (e[1] == "string 5")
 55
 56# property string{string} m_string_map_string
 57# string keyed map of strings
 58c.m_string_map_string = {
 59    "key1": "string 1",
 60    "key2": "string 2"
 61}
 62
 63f = c.m_string_map_string
 64assert (len(f) == 3)
 65assert (f["key3"] == "string 3")
 66assert (f["key4"] == "string 4")
 67assert (f["key5"] == "string 5")
 68
 69# property MyVector3{int32} n_vector_map
 70# int32 keyed map of MyVector3
 71my_vector3_dtype = RRN.GetNamedArrayDType("experimental.value_types.MyVector3", obj=c)
 72e = np.zeros((1,), dtype=my_vector3_dtype)
 73e[0]["x"] = 1.0
 74e[0]["y"] = 2.0
 75e[0]["z"] = 3.0
 76c.n_vector_map = {
 77    1: e
 78}
 79
 80g = c.n_vector_map
 81assert (len(g) == 1)
 82g1 = g[1]
 83assert (g1[0]["x"] == 4.0)
 84assert (g1[0]["y"] == 5.0)
 85assert (g1[0]["z"] == 6.0)
 86
 87# property MyStructure{list} o_struct_list
 88# list of MyStructure
 89my_structure_type = RRN.GetStructureType("experimental.value_types.MyStructure", obj=c)
 90h = my_structure_type()
 91h.a = 5
 92h.b = np.array([10, 20], dtype=np.uint32)
 93h.c = "String from structure client"
 94h.d = [
 95    "string a",
 96    "string b"
 97]
 98c.o_struct_list = [h]
 99
100i = c.o_struct_list
101assert (len(i) == 1)
102i0 = i[0]
103assert (i0.a == 52)
104np.testing.assert_array_equal(i[0].b, np.array([110, 120], dtype=np.uint32))
105assert (i0.c == "String from structure service")
106assert (len(i[0].d) == 3)
107assert (i0.d[0] == "string c")
108assert (i0.d[1] == "string d")
109assert (i0.d[2] == "string e")

varvalue Type

Varvalue is a special type that can store any value type, and is a form of variant. See the language documentation for more details on how the variant is implemented in each language. The varvalue type is nullable.

The following members from the experimental.value_types.ValueTypesExample object are used in the examples for varvalue types:

    # varvalue examples
    property varvalue p_varvalue_double_array
    property varvalue q_varvalue_string
    property varvalue r_varvalue_struct
    # varvalue{string} is a string keyed map of varvalues
    # It is frequently used for "extended" fields
    # to allow for forward compatibility
    property varvalue{string} s_varvalue_map2

The examples below show how to use varvalue in Python, MATLAB, LabView, C#, and C++.

 1# varvalue_value_types.py - Example of using varvalue wildcard type
 2
 3from RobotRaconteur.Client import *
 4import numpy as np
 5
 6c = RRN.ConnectService('rr+tcp://localhost:53223?service=values_example')
 7
 8# Any valid Robot Raconteur data type can be stored in a varvalue
 9# In Python, the RR.VarValue() Python structure is used to store
10# the value and type of the data. The type is stored as a string.
11# This is necessary because Python does not carry enough type
12# information
13
14# property varvalue p_varvalue_double_array
15# Example of storing a double array in a varvalue
16a = np.array([1.1, 2.2, 3.3], dtype=np.float64)
17c.p_varvalue_double_array = RR.VarValue(a, "double[]")
18b = c.p_varvalue_double_array
19np.testing.assert_array_equal(b.data, [1.4, 2.5, 3.6])
20assert b.datatype == "double[]"
21
22# property varvalue q_varvalue_string
23# Example of storing a string in a varvalue
24c.q_varvalue_string = RR.VarValue("varvalue string from client", "string")
25d = c.q_varvalue_string
26assert d.data == "varvalue string from service"
27assert d.datatype == "string"
28
29# property varvalue r_varvalue_struct
30# Example of storing a structure in a varvalue
31my_structure_type = RRN.GetStructureType("experimental.value_types.MyStructure", obj=c)
32s = my_structure_type()
33s.a = 5
34s.b = np.array([10, 20], dtype=np.uint32)
35s.c = "String from structure client"
36s.d = [
37    "string a",
38    "string b"
39]
40
41c.r_varvalue_struct = RR.VarValue(s, "experimental.value_types.MyStructure")
42
43t = c.r_varvalue_struct
44t_data = t.data
45
46assert t_data.a == 52
47np.testing.assert_array_equal(t_data.b, np.array([110, 120], dtype=np.uint32))
48assert t_data.c == "String from structure service"
49assert len(t_data.d) == 3
50assert t_data.d[0] == "string c"
51assert t_data.d[1] == "string d"
52assert t_data.d[2] == "string e"
53
54# property varvalue{string} s_varvalue_map2
55# Example of storing a map of strings in a varvalue
56# varvalue{string} is used extensively in structures
57# to allow for additional fields to be added to the
58# structure without changing the structure definition
59c.s_varvalue_map2 = {
60    "key1": RR.VarValue(np.array([2, 3]), "int32[]"),
61    "key2": RR.VarValue("string 2", "string")
62}
63
64u = c.s_varvalue_map2
65assert len(u) == 2
66np.testing.assert_array_equal(u["key3"].data, [4, 5])
67assert u["key3"].datatype == "int32[]"
68assert u["key4"].data == "string 4"
69assert u["key4"].datatype == "string"

Nullable Types

Structures, containers, and varvalues are nullable, meaning they can be set to null. All other value types are not nullable.

The following members from the experimental.value_types.ValueTypesExample object are used in the examples for nullable types:

    property MyStructure t_struct_null

The examples below show how to use nullable types in Python, MATLAB, LabView, C#, and C++.

 1# null_value_types.py - Example of types that can be null
 2
 3from RobotRaconteur.Client import *
 4import numpy as np
 5
 6c = RRN.ConnectService('rr+tcp://localhost:53223?service=values_example')
 7
 8# Null values
 9# Null values are "None" in Python
10# struct, containers, and varvalue are nullable.
11# Numbers, arrays, strings, pods, and namedarrays are not nullable.
12
13# property MyStructure t_struct_null
14c.t_struct_null = None
15assert c.t_struct_null is None