You can not select more than 25 topics Topics must start with a chinese character,a letter or number, can include dashes ('-') and can be up to 35 characters long.

test_utils.py 12 kB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284
  1. import numpy as np
  2. import pyarrow as pa
  3. # Marker Message Example
  4. TEST_ARRAYS = [
  5. ("std_msgs", "UInt8", pa.array([{"data": np.uint8(2)}])),
  6. (
  7. "std_msgs",
  8. "String",
  9. pa.array([{"data": "hello"}]),
  10. ),
  11. (
  12. "std_msgs",
  13. "UInt8MultiArray",
  14. pa.array(
  15. [
  16. {
  17. "data": np.array([1, 2, 3, 4], np.uint8),
  18. "layout": {
  19. "dim": [
  20. {
  21. "label": "a",
  22. "size": np.uint32(10),
  23. "stride": np.uint32(20),
  24. }
  25. ],
  26. "data_offset": np.uint32(30),
  27. },
  28. }
  29. ]
  30. ),
  31. ),
  32. (
  33. "std_msgs",
  34. "Float32MultiArray",
  35. pa.array(
  36. [
  37. {
  38. "data": np.array([1, 2, 3, 4], np.float32),
  39. "layout": {
  40. "dim": [
  41. {
  42. "label": "a",
  43. "size": np.uint32(10),
  44. "stride": np.uint32(20),
  45. }
  46. ],
  47. "data_offset": np.uint32(30),
  48. },
  49. }
  50. ]
  51. ),
  52. ),
  53. (
  54. "visualization_msgs",
  55. "Marker",
  56. pa.array(
  57. [
  58. {
  59. "header": {
  60. "frame_id": "world", # Placeholder value (String type, no numpy equivalent)
  61. },
  62. "ns": "my_namespace", # Placeholder value (String type, no numpy equivalent)
  63. "id": np.int32(1), # Numpy type
  64. "type": np.int32(0), # Numpy type (ARROW)
  65. "action": np.int32(0), # Numpy type (ADD)
  66. "lifetime": {
  67. "sec": np.int32(1),
  68. "nanosec": np.uint32(2),
  69. }, # Numpy type
  70. "pose": {
  71. "position": {
  72. "x": np.float64(1.0), # Numpy type
  73. "y": np.float64(2.0), # Numpy type
  74. "z": np.float64(3.0), # Numpy type
  75. },
  76. "orientation": {
  77. "x": np.float64(0.0), # Numpy type
  78. "y": np.float64(0.0), # Numpy type
  79. "z": np.float64(0.0), # Numpy type
  80. "w": np.float64(1.0), # Numpy type
  81. },
  82. },
  83. "scale": {
  84. "x": np.float64(1.0), # Numpy type
  85. "y": np.float64(1.0), # Numpy type
  86. "z": np.float64(1.0), # Numpy type
  87. },
  88. "color": {
  89. "r": np.float32(1.0), # Numpy type
  90. "g": np.float32(0.0), # Numpy type
  91. "b": np.float32(0.0), # Numpy type
  92. "a": np.float32(1.0), # Numpy type (alpha)
  93. },
  94. "frame_locked": False, # Boolean type, no numpy equivalent
  95. "points": [ # Numpy array for points
  96. {
  97. "x": np.float64(1.0), # Numpy type
  98. "y": np.float64(1.0), # Numpy type
  99. "z": np.float64(1.0), # Numpy type
  100. }
  101. ],
  102. "colors": [
  103. {
  104. "r": np.float32(1.0), # Numpy type
  105. "g": np.float32(1.0), # Numpy type
  106. "b": np.float32(1.0), # Numpy type
  107. "a": np.float32(1.0), # Numpy type (alpha)
  108. } # Numpy array for colors
  109. ],
  110. "texture_resource": "",
  111. "uv_coordinates": [{}],
  112. "text": "",
  113. "mesh_resource": "",
  114. "mesh_use_embedded_materials": False, # Boolean type, no numpy equivalent
  115. }
  116. ]
  117. ),
  118. ),
  119. (
  120. "visualization_msgs",
  121. "MarkerArray",
  122. pa.array(
  123. [
  124. {
  125. "markers": [
  126. {
  127. "header": {
  128. "frame_id": "world", # Placeholder value (String type, no numpy equivalent)
  129. },
  130. "ns": "my_namespace", # Placeholder value (String type, no numpy equivalent)
  131. "id": np.int32(1), # Numpy type
  132. "type": np.int32(0), # Numpy type (ARROW)
  133. "action": np.int32(0), # Numpy type (ADD)
  134. "lifetime": {
  135. "sec": np.int32(1),
  136. "nanosec": np.uint32(2),
  137. }, # Numpy type
  138. "pose": {
  139. "position": {
  140. "x": np.float64(1.0), # Numpy type
  141. "y": np.float64(2.0), # Numpy type
  142. "z": np.float64(3.0), # Numpy type
  143. },
  144. "orientation": {
  145. "x": np.float64(0.0), # Numpy type
  146. "y": np.float64(0.0), # Numpy type
  147. "z": np.float64(0.0), # Numpy type
  148. "w": np.float64(1.0), # Numpy type
  149. },
  150. },
  151. "scale": {
  152. "x": np.float64(1.0), # Numpy type
  153. "y": np.float64(1.0), # Numpy type
  154. "z": np.float64(1.0), # Numpy type
  155. },
  156. "color": {
  157. "r": np.float32(1.0), # Numpy type
  158. "g": np.float32(0.0), # Numpy type
  159. "b": np.float32(0.0), # Numpy type
  160. "a": np.float32(1.0), # Numpy type (alpha)
  161. },
  162. "frame_locked": False, # Boolean type, no numpy equivalent
  163. "points": [ # Numpy array for points
  164. {
  165. "x": np.float64(1.0), # Numpy type
  166. "y": np.float64(1.0), # Numpy type
  167. "z": np.float64(1.0), # Numpy type
  168. }
  169. ],
  170. "colors": [
  171. {
  172. "r": np.float32(1.0), # Numpy type
  173. "g": np.float32(1.0), # Numpy type
  174. "b": np.float32(1.0), # Numpy type
  175. "a": np.float32(1.0), # Numpy type (alpha)
  176. } # Numpy array for colors
  177. ],
  178. "texture_resource": "",
  179. "uv_coordinates": [{}],
  180. "text": "",
  181. "mesh_resource": "",
  182. "mesh_use_embedded_materials": False, # Boolean type, no numpy equivalent
  183. }
  184. ]
  185. }
  186. ]
  187. ),
  188. ),
  189. (
  190. "visualization_msgs",
  191. "ImageMarker",
  192. pa.array(
  193. [
  194. {
  195. "header": {
  196. "stamp": {
  197. "sec": np.int32(123456), # 32-bit integer
  198. "nanosec": np.uint32(789), # 32-bit unsigned integer
  199. },
  200. "frame_id": "frame_example",
  201. },
  202. "ns": "namespace",
  203. "id": np.int32(1), # 32-bit integer
  204. "type": np.int32(0), # 32-bit integer, e.g., CIRCLE = 0
  205. "action": np.int32(0), # 32-bit integer, e.g., ADD = 0
  206. "position": {
  207. "x": np.float64(1.0), # 32-bit float
  208. "y": np.float64(2.0), # 32-bit float
  209. "z": np.float64(3.0), # 32-bit float
  210. },
  211. "scale": np.float32(1.0), # 32-bit float
  212. "outline_color": {
  213. "r": np.float32(255.0), # 32-bit float
  214. "g": np.float32(0.0), # 32-bit float
  215. "b": np.float32(0.0), # 32-bit float
  216. "a": np.float32(1.0), # 32-bit float
  217. },
  218. "filled": np.uint8(1), # 8-bit unsigned integer
  219. "fill_color": {
  220. "r": np.float32(0.0), # 32-bit float
  221. "g": np.float32(255.0), # 32-bit float
  222. "b": np.float32(0.0), # 32-bit float
  223. "a": np.float32(1.0), # 32-bit float
  224. },
  225. "lifetime": {
  226. "sec": np.int32(300), # 32-bit integer
  227. "nanosec": np.uint32(0), # 32-bit unsigned integer
  228. },
  229. "points": [
  230. {
  231. "x": np.float64(1.0), # 32-bit float
  232. "y": np.float64(2.0), # 32-bit float
  233. "z": np.float64(3.0), # 32-bit float
  234. },
  235. {
  236. "x": np.float64(4.0), # 32-bit float
  237. "y": np.float64(5.0), # 32-bit float
  238. "z": np.float64(6.0), # 32-bit float
  239. },
  240. ],
  241. "outline_colors": [
  242. {
  243. "r": np.float32(255.0), # 32-bit float
  244. "g": np.float32(0.0), # 32-bit float
  245. "b": np.float32(0.0), # 32-bit float
  246. "a": np.float32(1.0), # 32-bit float
  247. },
  248. {
  249. "r": np.float32(0.0), # 32-bit float
  250. "g": np.float32(255.0), # 32-bit float
  251. "b": np.float32(0.0), # 32-bit float
  252. "a": np.float32(1.0), # 32-bit float
  253. },
  254. ],
  255. }
  256. ]
  257. ),
  258. ),
  259. ]
  260. def is_subset(subset, superset):
  261. """
  262. Check if subset is a subset of superset, to avoid false negatives linked to default values.
  263. """
  264. if isinstance(subset, pa.Array):
  265. return is_subset(subset.to_pylist(), superset.to_pylist())
  266. match subset:
  267. case dict(_):
  268. return all(
  269. key in superset and is_subset(val, superset[key])
  270. for key, val in subset.items()
  271. )
  272. case list(_) | set(_):
  273. return all(
  274. any(is_subset(subitem, superitem) for superitem in superset)
  275. for subitem in subset
  276. )
  277. # assume that subset is a plain value if none of the above match
  278. case _:
  279. return subset == superset