mirror of
https://github.com/PX4/PX4-Autopilot.git
synced 2026-05-28 02:36:37 +08:00
Update cdrstream code generator including typehash
This commit is contained in:
committed by
Beat Küng
parent
a87456b38b
commit
e1a7fbce71
@@ -49,14 +49,14 @@ for field in spec.parsed_fields():
|
|||||||
(package, name) = genmsg.names.package_resource_name(field.base_type)
|
(package, name) = genmsg.names.package_resource_name(field.base_type)
|
||||||
package = package or spec.package # convert '' to package
|
package = package or spec.package # convert '' to package
|
||||||
|
|
||||||
print('typedef px4_msg_%s px4_msg_px4__msg__%s;' % (name,name))
|
print('typedef px4_msgs_msg_%s px4_msgs_msg_px4_msgs__msg__%s;' % (name,name))
|
||||||
}@
|
}@
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
typedef struct @uorb_struct px4_msg_@(file_base_name);
|
typedef struct @uorb_struct px4_msgs_msg_@(file_base_name);
|
||||||
|
|
||||||
extern const struct dds_cdrstream_desc px4_msg_@(file_base_name)_cdrstream_desc;
|
extern const struct dds_cdrstream_desc px4_msgs_msg_@(file_base_name)_cdrstream_desc;
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -42,6 +42,7 @@ import os
|
|||||||
import argparse
|
import argparse
|
||||||
import re
|
import re
|
||||||
import sys
|
import sys
|
||||||
|
import json
|
||||||
|
|
||||||
try:
|
try:
|
||||||
import em
|
import em
|
||||||
@@ -124,7 +125,7 @@ def generate_by_template(output_file, template_file, em_globals):
|
|||||||
return True
|
return True
|
||||||
|
|
||||||
|
|
||||||
def generate_topics_list_file_from_files(files, outputdir, template_filename, templatedir):
|
def generate_topics_list_file_from_files(files, outputdir, template_filename, templatedir, rihs_path):
|
||||||
# generate cpp file with topics list
|
# generate cpp file with topics list
|
||||||
filenames = []
|
filenames = []
|
||||||
for filename in [os.path.basename(p) for p in files if os.path.basename(p).endswith(".msg")]:
|
for filename in [os.path.basename(p) for p in files if os.path.basename(p).endswith(".msg")]:
|
||||||
@@ -138,11 +139,23 @@ def generate_topics_list_file_from_files(files, outputdir, template_filename, te
|
|||||||
for filename in [os.path.basename(p) for p in files if os.path.basename(p).endswith(".msg")]:
|
for filename in [os.path.basename(p) for p in files if os.path.basename(p).endswith(".msg")]:
|
||||||
full_base_names.append(filename.replace(".msg",""))
|
full_base_names.append(filename.replace(".msg",""))
|
||||||
|
|
||||||
|
rihs01_hashes = dict()
|
||||||
|
if rihs_path != '':
|
||||||
|
for topic in full_base_names:
|
||||||
|
with open(rihs_path + "/msg/" + topic + ".json") as f:
|
||||||
|
d = json.load(f)
|
||||||
|
|
||||||
|
rihs01_hash = d['type_hashes'][0]['hash_string'][7:]
|
||||||
|
|
||||||
|
byte_array = [f"0x{rihs01_hash[i:i+2]}" for i in range(0, len(rihs01_hash), 2)]
|
||||||
|
c_code = f"{{ {', '.join(byte_array)} }};"
|
||||||
|
rihs01_hashes[topic] = c_code
|
||||||
|
|
||||||
topics = []
|
topics = []
|
||||||
for msg_filename in files:
|
for msg_filename in files:
|
||||||
topics.extend(get_topics(msg_filename))
|
topics.extend(get_topics(msg_filename))
|
||||||
|
|
||||||
tl_globals = {"msgs": filenames, "topics": topics, "datatypes": datatypes, "full_base_names": full_base_names}
|
tl_globals = {"msgs": filenames, "topics": topics, "datatypes": datatypes, "full_base_names": full_base_names, "rihs01_hashes": rihs01_hashes}
|
||||||
tl_template_file = os.path.join(templatedir, template_filename)
|
tl_template_file = os.path.join(templatedir, template_filename)
|
||||||
tl_out_file = os.path.join(outputdir, template_filename.replace(".em", ""))
|
tl_out_file = os.path.join(outputdir, template_filename.replace(".em", ""))
|
||||||
|
|
||||||
@@ -162,13 +175,15 @@ if __name__ == "__main__":
|
|||||||
parser.add_argument('-p', dest='prefix', default='',
|
parser.add_argument('-p', dest='prefix', default='',
|
||||||
help='string added as prefix to the output file '
|
help='string added as prefix to the output file '
|
||||||
' name when converting directories')
|
' name when converting directories')
|
||||||
|
parser.add_argument('-rihs', dest='rihs', default='',
|
||||||
|
help='path where rihs01 json files located')
|
||||||
args = parser.parse_args()
|
args = parser.parse_args()
|
||||||
|
|
||||||
if args.zenoh_config:
|
if args.zenoh_config:
|
||||||
generate_topics_list_file_from_files(args.file, args.outputdir, ZENOH_TEMPLATE_FILE[0], args.templatedir)
|
generate_topics_list_file_from_files(args.file, args.outputdir, ZENOH_TEMPLATE_FILE[0], args.templatedir, args.rihs)
|
||||||
exit(0)
|
exit(0)
|
||||||
elif args.zenoh_pub_sub:
|
elif args.zenoh_pub_sub:
|
||||||
generate_topics_list_file_from_files(args.file, args.outputdir, ZENOH_TEMPLATE_FILE[1], args.templatedir)
|
generate_topics_list_file_from_files(args.file, args.outputdir, ZENOH_TEMPLATE_FILE[1], args.templatedir, args.rihs)
|
||||||
exit(0)
|
exit(0)
|
||||||
else:
|
else:
|
||||||
print('Error: either --headers or --sources must be specified')
|
print('Error: either --headers or --sources must be specified')
|
||||||
|
|||||||
@@ -88,9 +88,14 @@ type_topic_count = len([e for e in topic_names_all if e.startswith(topic_name)])
|
|||||||
CONFIG_ZENOH_PUBSUB_@(topic_name.upper())_COUNT + \
|
CONFIG_ZENOH_PUBSUB_@(topic_name.upper())_COUNT + \
|
||||||
@[end for] 0
|
@[end for] 0
|
||||||
|
|
||||||
|
@[for topic_name, rihs01_hash in rihs01_hashes.items()]@
|
||||||
|
const uint8_t @(topic_name)_hash[32] = @(rihs01_hash)
|
||||||
|
@[end for]
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
const uint32_t *ops;
|
const uint32_t *ops;
|
||||||
const orb_metadata* orb_meta;
|
const orb_metadata* orb_meta;
|
||||||
|
const uint8_t *hash;
|
||||||
} UorbPubSubTopicBinder;
|
} UorbPubSubTopicBinder;
|
||||||
|
|
||||||
const UorbPubSubTopicBinder _topics[ZENOH_PUBSUB_COUNT] {
|
const UorbPubSubTopicBinder _topics[ZENOH_PUBSUB_COUNT] {
|
||||||
@@ -104,8 +109,9 @@ topic_names = [e for e in topic_names_all if e.startswith(topic_name)]
|
|||||||
}@
|
}@
|
||||||
@[for topic_name_inst in topic_names]@
|
@[for topic_name_inst in topic_names]@
|
||||||
{
|
{
|
||||||
px4_msg_@(topic_dict[topic_name])_cdrstream_desc.ops.ops,
|
px4_msgs_msg_@(topic_dict[topic_name])_cdrstream_desc.ops.ops,
|
||||||
ORB_ID(@(topic_name_inst))
|
ORB_ID(@(topic_name_inst)),
|
||||||
|
@(topic_dict[topic_name])_hash
|
||||||
},
|
},
|
||||||
@{
|
@{
|
||||||
uorb_id_idx += 1
|
uorb_id_idx += 1
|
||||||
@@ -152,3 +158,21 @@ Zenoh_Subscriber* genSubscriber(const char *name) {
|
|||||||
}
|
}
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const uint8_t* getRIHS01_Hash(const orb_metadata *meta) {
|
||||||
|
for (auto &sub : _topics) {
|
||||||
|
if(sub.orb_meta->o_id == meta->o_id) {
|
||||||
|
return sub.hash;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
const uint8_t* getRIHS01_Hash(const char *name) {
|
||||||
|
for (auto &sub : _topics) {
|
||||||
|
if(strcmp(sub.orb_meta->o_name, name) == 0) {
|
||||||
|
return sub.hash;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|||||||
@@ -424,9 +424,11 @@ add_dependencies(uorb_msgs prebuild_targets uorb_headers)
|
|||||||
if(CONFIG_LIB_CDRSTREAM)
|
if(CONFIG_LIB_CDRSTREAM)
|
||||||
set(uorb_cdr_idl)
|
set(uorb_cdr_idl)
|
||||||
set(uorb_cdr_msg)
|
set(uorb_cdr_msg)
|
||||||
|
set(uorb_cdr_hash)
|
||||||
set(uorb_cdr_idl_uorb)
|
set(uorb_cdr_idl_uorb)
|
||||||
set(idl_include_path ${PX4_BINARY_DIR}/uORB/idl)
|
set(idl_include_path ${PX4_BINARY_DIR}/uORB/idl)
|
||||||
set(idl_out_path ${idl_include_path}/px4/msg)
|
set(idl_out_path ${idl_include_path}/px4/msg)
|
||||||
|
set(idl_rihs01_out_path ${idl_include_path}/px4)
|
||||||
set(idl_uorb_path ${PX4_BINARY_DIR}/msg/px4/msg)
|
set(idl_uorb_path ${PX4_BINARY_DIR}/msg/px4/msg)
|
||||||
|
|
||||||
# Make sure that CycloneDDS has been checkout out
|
# Make sure that CycloneDDS has been checkout out
|
||||||
@@ -457,6 +459,7 @@ if(CONFIG_LIB_CDRSTREAM)
|
|||||||
configure_file(${msg_file} ${idl_out_path}/${msg}.msg COPYONLY)
|
configure_file(${msg_file} ${idl_out_path}/${msg}.msg COPYONLY)
|
||||||
list(APPEND uorb_cdr_idl ${idl_out_path}/${msg}.idl)
|
list(APPEND uorb_cdr_idl ${idl_out_path}/${msg}.idl)
|
||||||
list(APPEND uorb_cdr_msg ${idl_out_path}/${msg}.msg)
|
list(APPEND uorb_cdr_msg ${idl_out_path}/${msg}.msg)
|
||||||
|
list(APPEND uorb_cdr_hash ${idl_out_path}/${msg}.json)
|
||||||
list(APPEND uorb_cdr_idl_uorb ${idl_uorb_path}/${msg}.h)
|
list(APPEND uorb_cdr_idl_uorb ${idl_uorb_path}/${msg}.h)
|
||||||
endforeach()
|
endforeach()
|
||||||
|
|
||||||
@@ -476,6 +479,25 @@ if(CONFIG_LIB_CDRSTREAM)
|
|||||||
VERBATIM
|
VERBATIM
|
||||||
)
|
)
|
||||||
|
|
||||||
|
file(CREATE_LINK ${idl_rihs01_out_path} ${idl_include_path}/px4_msgs SYMBOLIC)
|
||||||
|
|
||||||
|
# Generate IDL from .msg using rosidl_adapter
|
||||||
|
# Note this a submodule inside PX4 hence no ROS2 installation required
|
||||||
|
add_custom_command(
|
||||||
|
OUTPUT ${uorb_cdr_hash}
|
||||||
|
COMMAND ${CMAKE_COMMAND}
|
||||||
|
-E env "PYTHONPATH=${PX4_SOURCE_DIR}/src/lib/cdrstream/rosidl/rosidl_adapter:${PX4_SOURCE_DIR}/src/lib/cdrstream/rosidl/rosidl_cli:${PX4_SOURCE_DIR}/src/lib/cdrstream/rosidl/rosidl_parser:${PX4_SOURCE_DIR}/src/lib/cdrstream/rosidl/rosidl_generator_type_description"
|
||||||
|
${PYTHON_EXECUTABLE} ${PX4_SOURCE_DIR}/src/lib/cdrstream/idl2rihs01.py
|
||||||
|
--output-dir ${idl_rihs01_out_path}
|
||||||
|
${uorb_cdr_idl}
|
||||||
|
DEPENDS
|
||||||
|
${uorb_cdr_idl}
|
||||||
|
git_cyclonedds
|
||||||
|
COMMENT "Generating RIHS01 hashes from IDL"
|
||||||
|
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
|
||||||
|
VERBATIM
|
||||||
|
)
|
||||||
|
|
||||||
# Generate C definitions from IDL
|
# Generate C definitions from IDL
|
||||||
set(CYCLONEDDS_DIR ${PX4_SOURCE_DIR}/src/lib/cdrstream/cyclonedds)
|
set(CYCLONEDDS_DIR ${PX4_SOURCE_DIR}/src/lib/cdrstream/cyclonedds)
|
||||||
include("${CYCLONEDDS_DIR}/cmake/Modules/Generate.cmake")
|
include("${CYCLONEDDS_DIR}/cmake/Modules/Generate.cmake")
|
||||||
@@ -505,6 +527,7 @@ if(CONFIG_LIB_CDRSTREAM)
|
|||||||
DEPENDS
|
DEPENDS
|
||||||
uorb_cdrstream
|
uorb_cdrstream
|
||||||
${msg_files}
|
${msg_files}
|
||||||
|
${uorb_cdr_hash}
|
||||||
${PX4_SOURCE_DIR}/Tools/msg/templates/cdrstream/uorb_idl_header.h.em
|
${PX4_SOURCE_DIR}/Tools/msg/templates/cdrstream/uorb_idl_header.h.em
|
||||||
${PX4_SOURCE_DIR}/Tools/msg/px_generate_uorb_topic_files.py
|
${PX4_SOURCE_DIR}/Tools/msg/px_generate_uorb_topic_files.py
|
||||||
${PX4_SOURCE_DIR}/Tools/msg/px_generate_uorb_topic_helper.py
|
${PX4_SOURCE_DIR}/Tools/msg/px_generate_uorb_topic_helper.py
|
||||||
@@ -534,8 +557,10 @@ if(CONFIG_MODULES_ZENOH)
|
|||||||
-f ${msg_files}
|
-f ${msg_files}
|
||||||
-o ${PX4_BINARY_DIR}/src/modules/zenoh/
|
-o ${PX4_BINARY_DIR}/src/modules/zenoh/
|
||||||
-e ${PX4_SOURCE_DIR}/Tools/zenoh/templates/zenoh
|
-e ${PX4_SOURCE_DIR}/Tools/zenoh/templates/zenoh
|
||||||
|
-rihs ${idl_rihs01_out_path}
|
||||||
DEPENDS
|
DEPENDS
|
||||||
${msg_files}
|
${msg_files}
|
||||||
|
${uorb_cdr_hash}
|
||||||
${PX4_SOURCE_DIR}/Tools/zenoh/templates/zenoh/uorb_pubsub_factory.hpp.em
|
${PX4_SOURCE_DIR}/Tools/zenoh/templates/zenoh/uorb_pubsub_factory.hpp.em
|
||||||
${PX4_SOURCE_DIR}/Tools/zenoh/px_generate_zenoh_topic_files.py
|
${PX4_SOURCE_DIR}/Tools/zenoh/px_generate_zenoh_topic_files.py
|
||||||
COMMENT "Generating Zenoh Topic Code"
|
COMMENT "Generating Zenoh Topic Code"
|
||||||
|
|||||||
@@ -0,0 +1,92 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
|
||||||
|
############################################################################
|
||||||
|
#
|
||||||
|
# Copyright (C) 2023 PX4 Development Team. All rights reserved.
|
||||||
|
#
|
||||||
|
# Redistribution and use in source and binary forms, with or without
|
||||||
|
# modification, are permitted provided that the following conditions
|
||||||
|
# are met:
|
||||||
|
#
|
||||||
|
# 1. Redistributions of source code must retain the above copyright
|
||||||
|
# notice, this list of conditions and the following disclaimer.
|
||||||
|
# 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
# notice, this list of conditions and the following disclaimer in
|
||||||
|
# the documentation and/or other materials provided with the
|
||||||
|
# distribution.
|
||||||
|
# 3. Neither the name PX4 nor the names of its contributors may be
|
||||||
|
# used to endorse or promote products derived from this software
|
||||||
|
# without specific prior written permission.
|
||||||
|
#
|
||||||
|
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||||
|
# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||||
|
# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
|
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||||
|
# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
|
||||||
|
# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
||||||
|
# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||||
|
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
# POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
#
|
||||||
|
############################################################################
|
||||||
|
|
||||||
|
import argparse
|
||||||
|
import pathlib
|
||||||
|
import sys
|
||||||
|
import os
|
||||||
|
import tempfile
|
||||||
|
import json
|
||||||
|
|
||||||
|
try:
|
||||||
|
from rosidl_generator_type_description import generate_type_hash
|
||||||
|
except ImportError:
|
||||||
|
# modifying sys.path and importing the Python package with the same
|
||||||
|
# name as this script does not work on Windows
|
||||||
|
rosidl_generator_type_description_root = os.path.dirname(os.path.dirname(__file__))
|
||||||
|
rosidl_generator_type_description_module = os.path.join(
|
||||||
|
rosidl_generator_type_description_root, 'rosidl_generator_type_description', '__init__.py')
|
||||||
|
if not os.path.exists(rosidl_generator_type_description_module):
|
||||||
|
raise
|
||||||
|
from importlib.machinery import SourceFileLoader
|
||||||
|
|
||||||
|
loader = SourceFileLoader('rosidl_generator_type_description', rosidl_generator_type_description_module)
|
||||||
|
rosidl_generator_type_description = loader.load_module()
|
||||||
|
generate_type_hash = rosidl_generator_type_description.generate_type_hash
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
parser = argparse.ArgumentParser(
|
||||||
|
description=f'Convert px4 .idl files to rihs01')
|
||||||
|
parser.add_argument(
|
||||||
|
'interface_files', nargs='+',
|
||||||
|
help='The interface files to convert')
|
||||||
|
parser.add_argument(
|
||||||
|
'--output-dir', '-o',
|
||||||
|
help='The directory to save converted files (default: current directory)')
|
||||||
|
args = parser.parse_args(sys.argv[1:])
|
||||||
|
|
||||||
|
# So for some odd reason rosidl doesn't do proper cli arguments but believes
|
||||||
|
# that some magically crafted json is better
|
||||||
|
|
||||||
|
idl_files = []
|
||||||
|
|
||||||
|
type_hash_arguments = {}
|
||||||
|
type_hash_arguments['package_name'] = "px4_msgs"
|
||||||
|
type_hash_arguments['output_dir'] = args.output_dir
|
||||||
|
type_hash_arguments["idl_tuples"] = idl_files
|
||||||
|
|
||||||
|
for interface_file in args.interface_files:
|
||||||
|
# So file path need to be magically encoded with a : to let the parser do its thing
|
||||||
|
|
||||||
|
interface_file = str(pathlib.Path(interface_file)).replace("px4/msg", "px4:msg")
|
||||||
|
idl_files.append(interface_file)
|
||||||
|
|
||||||
|
json_file = tempfile.NamedTemporaryFile(mode="w+",delete=False)
|
||||||
|
json.dump(type_hash_arguments, json_file)
|
||||||
|
json_file.flush()
|
||||||
|
|
||||||
|
print(json_file.name)
|
||||||
|
|
||||||
|
generate_type_hash(json_file.name)
|
||||||
@@ -52,6 +52,6 @@ if __name__ == '__main__':
|
|||||||
package_dir = interface_file.parent.absolute()
|
package_dir = interface_file.parent.absolute()
|
||||||
|
|
||||||
convert_msg_to_idl(
|
convert_msg_to_idl(
|
||||||
package_dir, 'px4',
|
package_dir, 'px4_msgs',
|
||||||
interface_file.absolute().relative_to(package_dir),
|
interface_file.absolute().relative_to(package_dir),
|
||||||
interface_file.parent)
|
interface_file.parent)
|
||||||
|
|||||||
Reference in New Issue
Block a user