-
Notifications
You must be signed in to change notification settings - Fork 20
Plotting Tool
The MADARA and GAMS middleware provide many tools for data introspection like karl and stk_inspect, which allow command-line text-based printouts of knowledge within a knowledge base. However, many types of data are harder to understand in only episodic text printouts. To help developers with visuals of how data and knowledge change over time in a robotic system or a group of robotic systems, we have also created a python-based visualization system.
The plotter requires that MADARA and GAMS be installed with at least python support (e.g., base_build.sh gams madara python). Once python support is compiled into MADARA and GAMS, this plotter then becomes available with either real-time plotting of knowledge over the network or offline plotting of knowledge that has been saved to disk in the serialized temporal knowledge (STK) format.
- Live Plotting Tool
- Yaml config file
- Shaping Plots into Useful Graphs
- Example Config File
- Running the Plotting Tool
The plotting tool is configured from a yaml file. Yaml is an open specification that is meant to be human-readable and extensible.
The plotter works off a data source, which can be an offline or online knowledge base. An offline knowledge base is a serialized temporal knowledge (STK) file that has been saved by tools like karl or by simply saving checkpoints to a file. An online knowledge base is a MADARA knowledge base that is currently being modified by logics or external data sources.
Each option for plotting requires the specification of a schemas directory if custom data types are used.
To plot from a saved knowledge base, the yaml file needs to be configured with the location of the stk file with stk_file.
The following example shows a yaml seciton for an offline STK file.
data_source:
stk_file: '/path/to/mystk.stk'
schemas: '/path/to/schemas/folder'
To plot an active knowledge base, the yaml file needs to be configured with a transport entry that includes keys like transport_type. transport_type: specifies MADARA transport type and can be ZMQ, UDP, MULTICAST or BROADCAST. hosts: specifies KB hosts with ports, queue_length: indicates the transport queue length in bytes, read_threads: is the number of read threads to launch for the transport, read_thread_hertz: is the maximum read thread poll frequency, and kb_name: is the kb host name for knowledge base (this is the unique identifier for the kb, which shouldn't conflict with anything else).
The following shows an example configuration in YAML.
data_source:
transport:
transport_type: ZMQ
hosts: ['tcp://127.0.0.1:52502', 'tcp://127.0.0.1:52500']
queue_length: 100000000
read_threads: 1
read_thread_hertz: 1000
kb_name: nothing
schemas: '/path/to/schemas/folder'
The plotter supports most common MADARA types in one, two, and three dimensional plots. However, it also supports complex type aggregatation from multiple variables.
There are 3 useful types of knowledge variables and key aggregations you can specify.
-
The most powerful is the aggregation of variables into a new reference frame. If you want a composite graph to be plotted, you can specify it under the
frame_typeskey. Specify name of the key, e.g.p1_base_link:and under itreference_frame:as an array, e.g.['p1_odom', 'p1_base_link']. See the example below for how this can be used. -
If you want an 'Any' type to be plotted, use the
any_typeskey. Any types are typically capnp types. The plotter is powerful enough to look into a capnp type to retrieve subkeys of custom types. -
Native MADARA types on an x or y axis. These can be specified in a direct manner with an entry for the name of the graph and then how the types map to
-
plot_<number>to specify certain subplots for the given key. For each axes you need to specify also the index and the name, e.g.0: 'x'and1: 'y'or0: 'x'-1: 'time'(-1 index means plotting the key against time), here first plots x against y. -
points_per_plotdefines the number of points to keep in the plot, and is defined as a number -
3Ddefines if the key needs to plotted as 3d or as 2d. If the value has more than 1 subvalues they all will be plotted against time. If3Dis set toTruethen the key will be attemped to plot in 3D graph. -
If the type is a map (it is appearing for capnp types defined in any_types), subplots can be specified with subkeys, e.g.
position.x: 'x'andposition.y: 'y'. In this case full path to the exact subkey in the map can be passed using., e.g.position.xsubkey forpose_in_mapkey points topose_in_map[position][x]in the map. If any of the values in the map is an array, it can be accessed by putting the index, e.g.'key1.key2.[3].key3', where [3] shows that key2 is an array where we take index 3. -
You can also leave the content empty and it will be plotted. If you don't mentioned the plot axes, all the keys are being plotted against time.
-
You can have several values to be plotted in one graph by specifying the range of indexes for similar KRs, and all the indexes in the range will be plotted. E.g.
agent.0-2.location:
plot_1:
0: 'x'
1: 'y'
points_per_plot: 100
this will plot 0 and 1 indexed values of array for agent.0.location, agent.1.location and agent.2.location
# config.yaml
data_source:
stk_file: '/media/sedrak/OS/SET/projects/test.stk'
schemas: '/media/sedrak/OS/SET/projects/capnp_schemas'
knowledge_record_subkeys:
# will plot 'sensors.imu.index' key against toi, as it is
sensors.imu.index:
# frames
frame_types:
# Default: Use if reference frame is geo and would like to plot full
# pose (position and orientation)
'p1_base_link':
# First entry should be upstream reference frame
'p1_base_link':
reference_frame: ['geo', 'p1_base_link']
points_per_plot: 200
#'p1_base_footprint':
# points_per_plot: 50
#3D: True
# Use if you would like to map specific position/orientation indices
# to x, y, or z axes. Value on lhs of colon indicates index of pose array
# and rhs indicates label for axis. Plot_1, etc. indicate subplots in figure
'p1_base_link':
reference_frame: ['p1_odom', 'p1_base_link']
plot_1:
0: 'x'
1: 'y'
plot_2:
-1: 'time'
0: 'x'
plot_3:
-1: 'time'
1: 'y'
plot_4:
2: 'z'
-1: 'time'
points_per_plot: 25
'p1_base_footprint':
3D: True
#Any data types
any_types:
'state_estimation.pose_graph.pose_in_map.1':
plot_1:
pose.position.x: 'x'
pose.position.y: 'y'
plot_2:
pose.position.x: 'x'
pose.position.z: 'z'
'state_estimation.pose_graph.pose_in_map.2':
3D: True
plot_1:
pose.position
After configuring the yaml file, you can run the plotting tool by calling: python $GAMS_ROOT/port/python/tools/plotting_sample.py <path_to_config.yaml>