diff --git a/Tools/msg/generate_msg_docs.py b/Tools/msg/generate_msg_docs.py index 193c56431f..f8bc70bc10 100755 --- a/Tools/msg/generate_msg_docs.py +++ b/Tools/msg/generate_msg_docs.py @@ -2,6 +2,7 @@ """ Generate docs from .msg files +Also generates docs/en/middleware/dds_topics.md from dds_topics.yaml """ import os @@ -9,6 +10,97 @@ import argparse import sys +import yaml + +def generate_dds_yaml_doc(allMessageFiles, output_file = 'dds_topics.md'): + """ + Generates human readable version of dds_topics.yaml. + Default output is to docs/en/middleware/dds_topics.md + """ + + dds_file_path = os.path.join(os.path.dirname(os.path.realpath(__file__)),"../../src/modules/uxrce_dds_client/dds_topics.yaml") + output_file_path = os.path.join(os.path.dirname(os.path.realpath(__file__)),f"../../docs/en/middleware/{output_file}") + + try: + with open(dds_file_path, 'r') as file: + data = yaml.safe_load(file) + + # Get messages and topics that are not published by default + # Start by getting all that are published. + all_messages_in_source = set() + all_message_types =set() + all_topics =set() + for message in data["publications"]: + all_message_types.add(message['type'].split("::")[-1]) + all_topics.add(message['topic'].split('/')[-1]) + for message in data["subscriptions"]: + all_message_types.add(message['type'].split("::")[-1]) + all_topics.add(message['topic'].split('/')[-1]) + if data["subscriptions_multi"]: # There is none now + dds_markdown += "None\n" + for message in data["subscriptions_multi"]: + all_message_types.add(message['type'].split("::")[-1]) + all_topics.add(message['topic'].split('/')[-1]) + for message in allMessageFiles: + all_messages_in_source.add(message.split('/')[-1].split('.')[0]) + messagesNotExported = all_messages_in_source - all_message_types + + # write out the dds file + dds_markdown="""# dds_topics.yaml + +::: info +This document is [auto-generated](https://github.com/PX4/PX4-Autopilot/blob/main/Tools/msg/generate_msg_docs.py) from the source code. +::: + + +The [dds_topics.yaml](https://github.com/PX4/PX4-Autopilot/blob/main/src/modules/uxrce_dds_client/dds_topics.yaml) file specifies which uORB message definitions are compiled into the [uxrce_dds_client](../modules/modules_system.md#uxrce-dds-client) module when [PX4 is built](../middleware/uxrce_dds.md#code-generation), and hence which topics are available for ROS 2 applications to subscribe or publish (by default). + +This document shows a markdown-rendered version of [dds_topics.yaml](https://github.com/PX4/PX4-Autopilot/blob/main/src/modules/uxrce_dds_client/dds_topics.yaml), listing the publications, subscriptions, and so on. + +## Publications + +Topic | Type| Rate Limit +--- | --- | --- +""" + + for message in data["publications"]: + type = message['type'] + px4Type=type.split("::")[-1] + dds_markdown += f"`{message['topic']}` | [{type}](../msg_docs/{px4Type}.md) | {message.get('rate','')}\n" + + dds_markdown += "\n## Subscriptions\n\nTopic | Type\n--- | ---\n" + + for message in data["subscriptions"]: + type = message['type'] + px4Type=type.split("::")[-1] + dds_markdown += f"{message['topic']} | [{type}](../msg_docs/{px4Type}.md)\n" + + dds_markdown += "\n## Subscriptions Multi\n\n" + + if not data["subscriptions_multi"]: # There is none now + dds_markdown += "None\n" + else: + print("Warning - we now have subscription_multi data - check format") + dds_markdown += "Topic | Type\n--- | ---\n" + for message in data["subscriptions_multi"]: + dds_markdown += f"{message['topic']} | {message['type']}\n" + + if messagesNotExported: + # Print the topics that are not exported to DDS + dds_markdown += "\n## Messages Not Published/Subscribed\n\nThese messages are not listed in the yaml file, and hence are neither published or subscribed\n\n" + for item in messagesNotExported: + dds_markdown += f"[{item}](../msg_docs/{item}.md), " + + #print(dds_markdown) + with open(output_file_path, 'w') as content_file: + content_file.write(dds_markdown) + + except yaml.YAMLError as exc: + print(f"Error parsing YAML: {exc}") + except FileNotFoundError: + print(f"Error: {dds_file_path} not found.") + + def get_msgs_list(msgdir): """ Makes a list of relative paths of .msg files in the given directory @@ -30,6 +122,7 @@ def get_msgs_list(msgdir): if __name__ == "__main__": + parser = argparse.ArgumentParser(description='Generate docs from .msg files') parser.add_argument('-d', dest='dir', help='output directory', required=True) args = parser.parse_args() @@ -132,3 +225,5 @@ Graphs showing how these are used [can be found here](../middleware/uorb_graph.m index_file = os.path.join(output_dir, 'index.md') with open(index_file, 'w') as content_file: content_file.write(index_text) + + generate_dds_yaml_doc(msg_files)