Skip to content

Commit 019d232

Browse files
PetervdPerk-NXPdagar
authored andcommitted
Add Zenoh pico support
1 parent 5137ca1 commit 019d232

38 files changed

+3479
-3
lines changed

.gitmodules

+10
Original file line numberDiff line numberDiff line change
@@ -62,3 +62,13 @@
6262
path = src/modules/uxrce_dds_client/Micro-XRCE-DDS-Client
6363
url = https://github.com/PX4/Micro-XRCE-DDS-Client.git
6464
branch = px4
65+
[submodule "src/lib/cdrstream/cyclonedds"]
66+
path = src/lib/cdrstream/cyclonedds
67+
url = https://github.com/px4/cyclonedds
68+
[submodule "src/lib/cdrstream/rosidl"]
69+
path = src/lib/cdrstream/rosidl
70+
url = https://github.com/px4/rosidl
71+
[submodule "src/modules/zenoh/zenoh-pico"]
72+
path = src/modules/zenoh/zenoh-pico
73+
url = https://github.com/px4/zenoh-pico
74+
branch = pr-zubf-werror-fix

Kconfig

+2
Original file line numberDiff line numberDiff line change
@@ -205,3 +205,5 @@ menu "platforms"
205205
depends on PLATFORM_QURT || PLATFORM_POSIX
206206
source "platforms/common/Kconfig"
207207
endmenu
208+
209+
source "src/lib/*/Kconfig"

ROMFS/px4fmu_common/init.d/rcS

+4
Original file line numberDiff line numberDiff line change
@@ -537,6 +537,10 @@ else
537537
cyphal start
538538
fi
539539
fi
540+
if param greater -s ZENOH_ENABLE 0
541+
then
542+
zenoh start
543+
fi
540544

541545
#
542546
# End of autostart.

Tools/astyle/files_to_check_code_style.sh

+3
Original file line numberDiff line numberDiff line change
@@ -26,4 +26,7 @@ exec find boards msg src platforms test \
2626
-path src/lib/crypto/libtomcrypt -prune -o \
2727
-path src/lib/crypto/libtommath -prune -o \
2828
-path src/modules/uxrce_dds_client/Micro-XRCE-DDS-Client -prune -o \
29+
-path src/lib/cdrstream/cyclonedds -prune -o \
30+
-path src/lib/cdrstream/rosidl -prune -o \
31+
-path src/drivers/zenoh/zenoh-pico -prune -o \
2932
-type f \( -name "*.c" -o -name "*.h" -o -name "*.cpp" -o -name "*.hpp" \) | grep $PATTERN

Tools/msg/px_generate_uorb_topic_files.py

+13-3
Original file line numberDiff line numberDiff line change
@@ -70,9 +70,9 @@
7070
__email__ = "thomasgubler@gmail.com"
7171

7272

73-
TEMPLATE_FILE = ['msg.h.em', 'msg.cpp.em']
73+
TEMPLATE_FILE = ['msg.h.em', 'msg.cpp.em', 'uorb_idl_header.h.em']
7474
TOPICS_LIST_TEMPLATE_FILE = ['uORBTopics.hpp.em', 'uORBTopics.cpp.em']
75-
OUTPUT_FILE_EXT = ['.h', '.cpp']
75+
OUTPUT_FILE_EXT = ['.h', '.cpp', '.h']
7676
INCL_DEFAULT = ['std_msgs:./msg/std_msgs']
7777
PACKAGE = 'px4'
7878
TOPICS_TOKEN = '# TOPICS '
@@ -150,6 +150,7 @@ def generate_output_from_file(format_idx, filename, outputdir, package, template
150150
em_globals = {
151151
"name_snake_case": full_type_name_snake,
152152
"file_name_in": filename,
153+
"file_base_name": file_base_name,
153154
"search_path": search_path,
154155
"msg_context": msg_context,
155156
"spec": spec,
@@ -161,7 +162,10 @@ def generate_output_from_file(format_idx, filename, outputdir, package, template
161162
os.makedirs(outputdir)
162163

163164
template_file = os.path.join(templatedir, TEMPLATE_FILE[format_idx])
164-
output_file = os.path.join(outputdir, full_type_name_snake + OUTPUT_FILE_EXT[format_idx])
165+
if format_idx == 2:
166+
output_file = os.path.join(outputdir, file_base_name + OUTPUT_FILE_EXT[format_idx])
167+
else:
168+
output_file = os.path.join(outputdir, full_type_name_snake + OUTPUT_FILE_EXT[format_idx])
165169

166170
return generate_by_template(output_file, template_file, em_globals)
167171

@@ -217,6 +221,7 @@ def append_to_include_path(path_to_append, curr_include, package):
217221
parser = argparse.ArgumentParser(description='Convert msg files to uorb headers/sources')
218222
parser.add_argument('--headers', help='Generate header files', action='store_true')
219223
parser.add_argument('--sources', help='Generate source files', action='store_true')
224+
parser.add_argument('--uorb-idl-header', help='Generate uORB compatible idl header', action='store_true')
220225
parser.add_argument('-f', dest='file',
221226
help="files to convert (use only without -d)",
222227
nargs="+")
@@ -241,6 +246,11 @@ def append_to_include_path(path_to_append, curr_include, package):
241246
generate_idx = 0
242247
elif args.sources:
243248
generate_idx = 1
249+
elif args.uorb_idl_header:
250+
for f in args.file:
251+
print(f)
252+
generate_output_from_file(2, f, args.outputdir, args.package, args.templatedir, INCL_DEFAULT)
253+
exit(0)
244254
else:
245255
print('Error: either --headers or --sources must be specified')
246256
exit(-1)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
@{
2+
import genmsg.msgs
3+
import re
4+
5+
from px_generate_uorb_topic_helper import * # this is in Tools/
6+
7+
uorb_struct = '%s_s'%name_snake_case
8+
uorb_struct_upper = name_snake_case.upper()
9+
}@
10+
11+
/****************************************************************
12+
13+
PX4 Cyclone DDS IDL to C Translator compatible idl struct
14+
Source: @file_name_in
15+
Compatible with Cyclone DDS: V0.11.0
16+
17+
*****************************************************************/
18+
#ifndef DDSC_IDL_UORB_@(uorb_struct_upper)_H
19+
#define DDSC_IDL_UORB_@(uorb_struct_upper)_H
20+
21+
#include "dds/ddsc/dds_public_impl.h"
22+
#include "dds/cdr/dds_cdrstream.h"
23+
#include <uORB/topics/@(name_snake_case).h>
24+
25+
@##############################
26+
@# Includes for dependencies
27+
@##############################
28+
@{
29+
for field in spec.parsed_fields():
30+
if (not field.is_builtin):
31+
if (not field.is_header):
32+
(package, name) = genmsg.names.package_resource_name(field.base_type)
33+
package = package or spec.package # convert '' to package
34+
35+
print('#include "%s.h"'%(name))
36+
name = re.sub(r'(?<!^)(?=[A-Z])', '_', name).lower()
37+
print('#include <uORB/topics/%s.h>'%(name))
38+
}@
39+
40+
41+
#ifdef __cplusplus
42+
extern "C" {
43+
#endif
44+
45+
@{
46+
for field in spec.parsed_fields():
47+
if (not field.is_builtin):
48+
if (not field.is_header):
49+
(package, name) = genmsg.names.package_resource_name(field.base_type)
50+
package = package or spec.package # convert '' to package
51+
52+
print('typedef px4_msg_%s px4_msg_px4__msg__%s;' % (name,name))
53+
}@
54+
55+
56+
57+
typedef struct @uorb_struct px4_msg_@(file_base_name);
58+
59+
extern const struct dds_cdrstream_desc px4_msg_@(file_base_name)_cdrstream_desc;
60+
61+
#ifdef __cplusplus
62+
}
63+
#endif
64+
65+
#endif /* DDSC_IDL_UORB_@(uorb_struct_upper)_H */
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,175 @@
1+
#!/usr/bin/env python3
2+
#############################################################################
3+
#
4+
# Copyright (C) 2013-2022 PX4 Pro Development Team. All rights reserved.
5+
#
6+
# Redistribution and use in source and binary forms, with or without
7+
# modification, are permitted provided that the following conditions
8+
# are met:
9+
#
10+
# 1. Redistributions of source code must retain the above copyright
11+
# notice, this list of conditions and the following disclaimer.
12+
# 2. Redistributions in binary form must reproduce the above copyright
13+
# notice, this list of conditions and the following disclaimer in
14+
# the documentation and/or other materials provided with the
15+
# distribution.
16+
# 3. Neither the name PX4 nor the names of its contributors may be
17+
# used to endorse or promote products derived from this software
18+
# without specific prior written permission.
19+
#
20+
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21+
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22+
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
23+
# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
24+
# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
25+
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
26+
# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
27+
# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
28+
# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29+
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
30+
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
31+
# POSSIBILITY OF SUCH DAMAGE.
32+
#
33+
#############################################################################
34+
35+
"""
36+
px_generate_zenoh_topic_files.py
37+
Generates c/cpp header/source files for use with zenoh
38+
message files
39+
"""
40+
41+
import os
42+
import argparse
43+
import re
44+
import sys
45+
46+
try:
47+
import em
48+
except ImportError as e:
49+
print("Failed to import em: " + str(e))
50+
print("")
51+
print("You may need to install it using:")
52+
print(" pip3 install --user empy")
53+
print("")
54+
sys.exit(1)
55+
56+
try:
57+
import genmsg.template_tools
58+
except ImportError as e:
59+
print("Failed to import genmsg: " + str(e))
60+
print("")
61+
print("You may need to install it using:")
62+
print(" pip3 install --user pyros-genmsg")
63+
print("")
64+
sys.exit(1)
65+
66+
67+
__author__ = "Sergey Belash, Thomas Gubler, Beat Kueng"
68+
__copyright__ = "Copyright (C) 2013-2022 PX4 Development Team."
69+
__license__ = "BSD"
70+
__email__ = "thomasgubler@gmail.com"
71+
72+
ZENOH_TEMPLATE_FILE = ['Kconfig.topics.em', 'uorb_pubsub_factory.hpp.em']
73+
TOPICS_TOKEN = '# TOPICS '
74+
75+
76+
def get_topics(filename):
77+
"""
78+
Get TOPICS names from a "# TOPICS" line
79+
"""
80+
ofile = open(filename, 'r')
81+
text = ofile.read()
82+
result = []
83+
for each_line in text.split('\n'):
84+
if each_line.startswith(TOPICS_TOKEN):
85+
topic_names_str = each_line.strip()
86+
topic_names_str = topic_names_str.replace(TOPICS_TOKEN, "")
87+
topic_names_list = topic_names_str.split(" ")
88+
for topic in topic_names_list:
89+
# topic name PascalCase (file name) to snake_case (topic name)
90+
topic_name = re.sub(r'(?<!^)(?=[A-Z])', '_', topic).lower()
91+
result.append(topic_name)
92+
ofile.close()
93+
94+
if len(result) == 0:
95+
# topic name PascalCase (file name) to snake_case (topic name)
96+
file_base_name = os.path.basename(filename).replace(".msg", "")
97+
topic_name = re.sub(r'(?<!^)(?=[A-Z])', '_', file_base_name).lower()
98+
result.append(topic_name)
99+
100+
return result
101+
102+
def generate_by_template(output_file, template_file, em_globals):
103+
"""
104+
Invokes empy intepreter to geneate output_file by the
105+
given template_file and predefined em_globals dict
106+
"""
107+
# check if folder exists:
108+
folder_name = os.path.dirname(output_file)
109+
if not os.path.exists(folder_name):
110+
os.makedirs(folder_name)
111+
112+
ofile = open(output_file, 'w')
113+
# todo, reuse interpreter
114+
interpreter = em.Interpreter(output=ofile, globals=em_globals, options={
115+
em.RAW_OPT: True, em.BUFFERED_OPT: True})
116+
try:
117+
interpreter.file(open(template_file))
118+
except OSError as e:
119+
ofile.close()
120+
os.remove(output_file)
121+
raise
122+
interpreter.shutdown()
123+
ofile.close()
124+
return True
125+
126+
127+
def generate_topics_list_file_from_files(files, outputdir, template_filename, templatedir):
128+
# generate cpp file with topics list
129+
filenames = []
130+
for filename in [os.path.basename(p) for p in files if os.path.basename(p).endswith(".msg")]:
131+
filenames.append(re.sub(r'(?<!^)(?=[A-Z])', '_', filename).lower())
132+
133+
datatypes = []
134+
for filename in [os.path.basename(p) for p in files if os.path.basename(p).endswith(".msg")]:
135+
datatypes.append(re.sub(r'(?<!^)(?=[A-Z])', '_', filename).lower().replace(".msg",""))
136+
137+
full_base_names = []
138+
for filename in [os.path.basename(p) for p in files if os.path.basename(p).endswith(".msg")]:
139+
full_base_names.append(filename.replace(".msg",""))
140+
141+
topics = []
142+
for msg_filename in files:
143+
topics.extend(get_topics(msg_filename))
144+
145+
tl_globals = {"msgs": filenames, "topics": topics, "datatypes": datatypes, "full_base_names": full_base_names}
146+
tl_template_file = os.path.join(templatedir, template_filename)
147+
tl_out_file = os.path.join(outputdir, template_filename.replace(".em", ""))
148+
149+
generate_by_template(tl_out_file, tl_template_file, tl_globals)
150+
151+
if __name__ == "__main__":
152+
parser = argparse.ArgumentParser(description='Convert msg files to uorb headers/sources')
153+
parser.add_argument('--zenoh-config', help='Generate Zenoh Kconfig file', action='store_true')
154+
parser.add_argument('--zenoh-pub-sub', help='Generate Zenoh Pubsub factory', action='store_true')
155+
parser.add_argument('-f', dest='file',
156+
help="files to convert (use only without -d)",
157+
nargs="+")
158+
parser.add_argument('-e', dest='templatedir',
159+
help='directory with template files',)
160+
parser.add_argument('-o', dest='outputdir',
161+
help='output directory for header files')
162+
parser.add_argument('-p', dest='prefix', default='',
163+
help='string added as prefix to the output file '
164+
' name when converting directories')
165+
args = parser.parse_args()
166+
167+
if args.zenoh_config:
168+
generate_topics_list_file_from_files(args.file, args.outputdir, ZENOH_TEMPLATE_FILE[0], args.templatedir)
169+
exit(0)
170+
elif args.zenoh_pub_sub:
171+
generate_topics_list_file_from_files(args.file, args.outputdir, ZENOH_TEMPLATE_FILE[1], args.templatedir)
172+
exit(0)
173+
else:
174+
print('Error: either --headers or --sources must be specified')
175+
exit(-1)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
@{
2+
topics_count = len(topics)
3+
topic_names_all = list(set(topics)) # set() filters duplicates
4+
topic_names_all.sort()
5+
6+
datatypes = list(set(datatypes)) # set() filters duplicates
7+
datatypes.sort()
8+
}@
9+
10+
menu "Zenoh publishers/subscribers"
11+
depends on MODULES_ZENOH
12+
@[for idx, topic_name in enumerate(datatypes)]@
13+
config ZENOH_PUBSUB_@(topic_name.upper())
14+
bool "@(topic_name)"
15+
default n
16+
17+
@[end for]
18+
19+
config ZENOH_PUBSUB_ALL_SELECTION
20+
bool
21+
default y if ZENOH_PUBSUB_ALL
22+
@[for idx, topic_name in enumerate(datatypes)]@
23+
select ZENOH_PUBSUB_@(topic_name.upper())
24+
@[end for]
25+
endmenu

0 commit comments

Comments
 (0)