@@ -70,6 +70,10 @@ def add_arguments(self, parser, cli_name):
70
70
group .add_argument (
71
71
'--stdin' , action = 'store_true' ,
72
72
help = 'Read values from standard input' )
73
+ group .add_argument (
74
+ '--yaml-file' , type = str , default = None ,
75
+ help = 'YAML file that has message contents, '
76
+ 'e.g STDOUT from ros2 topic echo <topic>' )
73
77
parser .add_argument (
74
78
'-r' , '--rate' , metavar = 'N' , type = positive_float , default = 1.0 ,
75
79
help = 'Publishing rate in Hz (default: 1)' )
@@ -131,6 +135,7 @@ def main(args):
131
135
args .message_type ,
132
136
args .topic_name ,
133
137
values ,
138
+ args .yaml_file ,
134
139
1. / args .rate ,
135
140
args .print ,
136
141
times ,
@@ -146,6 +151,7 @@ def publisher(
146
151
message_type : MsgType ,
147
152
topic_name : str ,
148
153
values : dict ,
154
+ yaml_file : str ,
149
155
period : float ,
150
156
print_nth : int ,
151
157
times : int ,
@@ -159,9 +165,14 @@ def publisher(
159
165
msg_module = get_message (message_type )
160
166
except (AttributeError , ModuleNotFoundError , ValueError ):
161
167
raise RuntimeError ('The passed message type is invalid' )
162
- values_dictionary = yaml .safe_load (values )
163
- if not isinstance (values_dictionary , dict ):
164
- return 'The passed value needs to be a dictionary in YAML format'
168
+
169
+ msg_reader = None
170
+ if yaml_file :
171
+ msg_reader = read_msg_from_yaml (yaml_file )
172
+ else :
173
+ values_dictionary = yaml .safe_load (values )
174
+ if not isinstance (values_dictionary , dict ):
175
+ return 'The passed value needs to be a dictionary in YAML format'
165
176
166
177
pub = node .create_publisher (msg_module , topic_name , qos_profile )
167
178
@@ -184,15 +195,38 @@ def publisher(
184
195
total_wait_time += DEFAULT_WAIT_TIME
185
196
186
197
msg = msg_module ()
187
- try :
188
- timestamp_fields = set_message_fields (
189
- msg , values_dictionary , expand_header_auto = True , expand_time_now = True )
190
- except Exception as e :
191
- return 'Failed to populate field: {0}' .format (e )
198
+ timestamp_fields = None
199
+
200
+ if not msg_reader :
201
+ # Set the static message from specified values once
202
+ try :
203
+ timestamp_fields = set_message_fields (
204
+ msg , values_dictionary , expand_header_auto = True , expand_time_now = True )
205
+ except Exception as e :
206
+ return 'Failed to populate field: {0}' .format (e )
207
+
192
208
print ('publisher: beginning loop' )
193
209
count = 0
210
+ more_message = True
194
211
195
212
def timer_callback ():
213
+ if msg_reader :
214
+ # Try to read out the contents for each message
215
+ try :
216
+ one_msg = next (msg_reader )
217
+ if not isinstance (one_msg , dict ):
218
+ print ('The contents in YAML file need to be a YAML format' )
219
+ except StopIteration :
220
+ nonlocal more_message
221
+ more_message = False
222
+ return
223
+ # Set the message with contents
224
+ try :
225
+ nonlocal timestamp_fields
226
+ timestamp_fields = set_message_fields (
227
+ msg , one_msg , expand_header_auto = True , expand_time_now = True )
228
+ except Exception as e :
229
+ return 'Failed to populate field: {0}' .format (e )
196
230
stamp_now = node .get_clock ().now ().to_msg ()
197
231
for field_setter in timestamp_fields :
198
232
field_setter (stamp_now )
@@ -205,11 +239,20 @@ def timer_callback():
205
239
timer_callback ()
206
240
if times != 1 :
207
241
timer = node .create_timer (period , timer_callback )
208
- while times == 0 or count < times :
242
+ while ( times == 0 or count < times ) and more_message :
209
243
rclpy .spin_once (node )
210
244
# give some time for the messages to reach the wire before exiting
211
245
time .sleep (keep_alive )
212
246
node .destroy_timer (timer )
213
247
else :
214
248
# give some time for the messages to reach the wire before exiting
215
249
time .sleep (keep_alive )
250
+
251
+
252
+ def read_msg_from_yaml (yaml_file ):
253
+ with open (yaml_file , 'r' ) as f :
254
+ for document in yaml .load_all (f , Loader = yaml .FullLoader ):
255
+ if document is None :
256
+ continue # Skip if there's no more document
257
+
258
+ yield document
0 commit comments