Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 1 addition & 2 deletions ros2controlcli/package.xml
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,7 @@
<depend>controller_manager</depend>
<depend>controller_manager_msgs</depend>
<exec_depend>rosidl_runtime_py</exec_depend>
<exec_depend>python-graphviz-pip</exec_depend>
<exec_depend>graphviz</exec_depend>
<exec_depend>python3-pygraphviz</exec_depend>

<test_depend>ament_copyright</test_depend>
<test_depend>ament_flake8</test_depend>
Expand Down
30 changes: 16 additions & 14 deletions ros2controlcli/ros2controlcli/verb/view_controller_chains.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@

from ros2controlcli.api import add_controller_mgr_parsers

import graphviz
import pygraphviz as pgz


def make_controller_node(s, controller_name, state_interfaces, command_interfaces, input_controllers,
Expand Down Expand Up @@ -58,7 +58,7 @@ def make_controller_node(s, controller_name, state_interfaces, command_interface
deliminator = ''
outputs_str += '<{}> {} {} '.format("controller_start_" + output_controller, output_controller, deliminator)

s.node(controller_name, f'{controller_name}|{{{{{inputs_str}}}|{{{outputs_str}}}}}')
s.add_node(controller_name, label=f'{controller_name}|{{{{{inputs_str}}}|{{{outputs_str}}}}}')


def make_command_node(s, command_interfaces):
Expand All @@ -70,7 +70,7 @@ def make_command_node(s, command_interfaces):
deliminator = ''
outputs_str += '<{}> {} {} '.format("command_end_" + command_interface, command_interface, deliminator)

s.node("command_interfaces", '{}|{{{{{}}}}}'.format("command_interfaces", outputs_str))
s.add_node("command_interfaces", label='{}|{{{{{}}}}}'.format("command_interfaces", outputs_str))


def make_state_node(s, state_interfaces):
Expand All @@ -82,12 +82,14 @@ def make_state_node(s, state_interfaces):
deliminator = ''
inputs_str += '<{}> {} {} '.format("state_start_" + state_interface, state_interface, deliminator)

s.node("state_interfaces", '{}|{{{{{}}}}}'.format("state_interfaces", inputs_str))
s.add_node("state_interfaces", label='{}|{{{{{}}}}}'.format("state_interfaces", inputs_str))


def show_graph(input_chain_connections, output_chain_connections, command_connections, state_connections,
command_interfaces, state_interfaces, visualize):
s = graphviz.Digraph('g', filename='/tmp/controller_diagram.gv', node_attr={'shape': 'record', 'style': 'rounded'})
s = pgz.AGraph(name='g', strict=False, directed=True, rankdir='LR')
s.node_attr["shape"] = "record"
s.node_attr["style"] = "rounded"
port_map = dict()
# get all controller names
controller_names = set()
Expand All @@ -107,19 +109,19 @@ def show_graph(input_chain_connections, output_chain_connections, command_connec

for controller_name in controller_names:
for connection in output_chain_connections[controller_name]:
s.edge('{}:{}'.format(controller_name, "controller_start_" + connection),
'{}:{}'.format(port_map['controller_end_' + connection], 'controller_end_' + connection))
s.add_edge('{}:{}'.format(controller_name, "controller_start_" + connection),
'{}:{}'.format(port_map['controller_end_' + connection], 'controller_end_' + connection))
for state_connection in state_connections[controller_name]:
s.edge('{}:{}'.format("state_interfaces", "state_start_" + state_connection),
'{}:{}'.format(controller_name, 'state_end_' + state_connection))
s.add_edge('{}:{}'.format("state_interfaces", "state_start_" + state_connection),
'{}:{}'.format(controller_name, 'state_end_' + state_connection))
for command_connection in command_connections[controller_name]:
s.edge('{}:{}'.format(controller_name, "command_start_" + command_connection),
'{}:{}'.format("command_interfaces", 'command_end_' + command_connection))
s.add_edge('{}:{}'.format(controller_name, "command_start_" + command_connection),
'{}:{}'.format("command_interfaces", 'command_end_' + command_connection))

s.attr(ranksep='2')
s.attr(rankdir="LR")
s.graph_attr.update(ranksep='2')
s.layout(prog='dot')
if visualize:
s.view()
s.draw('/tmp/controller_diagram.gv.pdf', format='pdf')


def parse_response(list_controllers_response, list_hardware_response, visualize=True):
Expand Down