10
10
11
11
# Standard imports
12
12
import os
13
+ from typing import Optional
13
14
14
15
# Third-party imports
15
- from sensor_msgs .msg import CompressedImage as CompressedImageOutput
16
+ from sensor_msgs .msg import CameraInfo , CompressedImage as CompressedImageOutput
16
17
from rcl_interfaces .msg import ParameterDescriptor , ParameterType
17
18
import rclpy
18
19
from rclpy .callback_groups import MutuallyExclusiveCallbackGroup
@@ -40,10 +41,21 @@ def __init__(self) -> None:
40
41
41
42
# Load the parameters
42
43
self .__prefix = ""
44
+ self .__sync_camera_info_with_topic : Optional [str ] = None
45
+ self .__camera_info_pub_topic : Optional [str ] = None
46
+ self .__camera_info_msg = None
43
47
self .__load_parameters ()
44
48
45
49
# Create the publishers
46
50
self .__pubs : dict [str , Publisher ] = {}
51
+ if self .__sync_camera_info_with_topic is not None :
52
+ self .__pub_camera_info = self .create_publisher (
53
+ msg_type = CameraInfo ,
54
+ topic = self .__camera_info_pub_topic ,
55
+ qos_profile = QoSProfile (
56
+ depth = 1 , reliability = ReliabilityPolicy .BEST_EFFORT
57
+ ),
58
+ )
47
59
48
60
# Create the subscriber
49
61
# pylint: disable=unused-private-member
@@ -71,6 +83,162 @@ def __load_parameters(self) -> None:
71
83
)
72
84
self .__prefix = prefix .value
73
85
86
+ # Camera Info
87
+ sync_camera_info_with_topic = self .declare_parameter (
88
+ "sync_camera_info_with_topic" ,
89
+ None ,
90
+ descriptor = ParameterDescriptor (
91
+ name = "sync_camera_info_with_topic" ,
92
+ type = ParameterType .PARAMETER_STRING ,
93
+ description = ("Whether to sync camera info with topic." ),
94
+ read_only = True ,
95
+ ),
96
+ )
97
+ self .__sync_camera_info_with_topic = sync_camera_info_with_topic .value
98
+
99
+ camera_info_pub_topic = self .declare_parameter (
100
+ "camera_info_pub_topic" ,
101
+ None ,
102
+ descriptor = ParameterDescriptor (
103
+ name = "camera_info_pub_topic" ,
104
+ type = ParameterType .PARAMETER_STRING ,
105
+ description = ("The topic to publish camera info." ),
106
+ read_only = True ,
107
+ ),
108
+ )
109
+ self .__camera_info_pub_topic = camera_info_pub_topic .value
110
+ if (
111
+ self .__sync_camera_info_with_topic is not None
112
+ and self .__camera_info_pub_topic is None
113
+ ):
114
+ raise ValueError (
115
+ "If sync_camera_info_with_topic is set, camera_info_pub_topic must be set."
116
+ )
117
+
118
+ if self .__sync_camera_info_with_topic is not None :
119
+ self .__camera_info_msg = CameraInfo ()
120
+ frame_id = self .declare_parameter (
121
+ "camera_info.frame_id" ,
122
+ "camera_color_optical_frame" ,
123
+ descriptor = ParameterDescriptor (
124
+ name = "camera_info.frame_id" ,
125
+ type = ParameterType .PARAMETER_STRING ,
126
+ description = ("The frame ID of the camera." ),
127
+ read_only = True ,
128
+ ),
129
+ )
130
+ self .__camera_info_msg .header .frame_id = frame_id .value
131
+ height = self .declare_parameter (
132
+ "camera_info.height" ,
133
+ 480 ,
134
+ descriptor = ParameterDescriptor (
135
+ name = "camera_info.height" ,
136
+ type = ParameterType .PARAMETER_INTEGER ,
137
+ description = ("The height of the image." ),
138
+ read_only = True ,
139
+ ),
140
+ )
141
+ self .__camera_info_msg .height = height .value
142
+ width = self .declare_parameter (
143
+ "camera_info.width" ,
144
+ 640 ,
145
+ descriptor = ParameterDescriptor (
146
+ name = "camera_info.width" ,
147
+ type = ParameterType .PARAMETER_INTEGER ,
148
+ description = ("The width of the image." ),
149
+ read_only = True ,
150
+ ),
151
+ )
152
+ self .__camera_info_msg .width = width .value
153
+ distortion_model = self .declare_parameter (
154
+ "camera_info.distortion_model" ,
155
+ "plumb_bob" ,
156
+ descriptor = ParameterDescriptor (
157
+ name = "camera_info.distortion_model" ,
158
+ type = ParameterType .PARAMETER_STRING ,
159
+ description = ("The distortion model of the camera." ),
160
+ read_only = True ,
161
+ ),
162
+ )
163
+ self .__camera_info_msg .distortion_model = distortion_model .value
164
+ d = self .declare_parameter (
165
+ "camera_info.d" ,
166
+ [0.0 , 0.0 , 0.0 , 0.0 , 0.0 ],
167
+ descriptor = ParameterDescriptor (
168
+ name = "camera_info.d" ,
169
+ type = ParameterType .PARAMETER_DOUBLE_ARRAY ,
170
+ description = ("The distortion coefficients." ),
171
+ read_only = True ,
172
+ ),
173
+ )
174
+ self .__camera_info_msg .d = d .value
175
+ k = self .declare_parameter (
176
+ "camera_info.k" ,
177
+ [
178
+ 614.5933227539062 ,
179
+ 0.0 ,
180
+ 312.1358947753906 ,
181
+ 0.0 ,
182
+ 614.6914672851562 ,
183
+ 223.70831298828125 ,
184
+ 0.0 ,
185
+ 0.0 ,
186
+ 1.0 ,
187
+ ],
188
+ descriptor = ParameterDescriptor (
189
+ name = "camera_info.k" ,
190
+ type = ParameterType .PARAMETER_DOUBLE_ARRAY ,
191
+ description = ("The camera matrix." ),
192
+ read_only = True ,
193
+ ),
194
+ )
195
+ self .__camera_info_msg .k = k .value
196
+ r = self .declare_parameter (
197
+ "camera_info.r" ,
198
+ [
199
+ 1.0 ,
200
+ 0.0 ,
201
+ 0.0 ,
202
+ 0.0 ,
203
+ 1.0 ,
204
+ 0.0 ,
205
+ 0.0 ,
206
+ 0.0 ,
207
+ 1.0 ,
208
+ ],
209
+ descriptor = ParameterDescriptor (
210
+ name = "camera_info.r" ,
211
+ type = ParameterType .PARAMETER_DOUBLE_ARRAY ,
212
+ description = ("The rectification matrix." ),
213
+ read_only = True ,
214
+ ),
215
+ )
216
+ self .__camera_info_msg .r = r .value
217
+ p = self .declare_parameter (
218
+ "camera_info.p" ,
219
+ [
220
+ 614.5933227539062 ,
221
+ 0.0 ,
222
+ 312.1358947753906 ,
223
+ 0.0 ,
224
+ 0.0 ,
225
+ 614.6914672851562 ,
226
+ 223.70831298828125 ,
227
+ 0.0 ,
228
+ 0.0 ,
229
+ 0.0 ,
230
+ 1.0 ,
231
+ 0.0 ,
232
+ ],
233
+ descriptor = ParameterDescriptor (
234
+ name = "camera_info.p" ,
235
+ type = ParameterType .PARAMETER_DOUBLE_ARRAY ,
236
+ description = ("The projection matrix." ),
237
+ read_only = True ,
238
+ ),
239
+ )
240
+ self .__camera_info_msg .p = p .value
241
+
74
242
def __callback (self , msg : CompressedImageInput ) -> None :
75
243
"""
76
244
Callback function for the subscriber.
@@ -94,6 +262,11 @@ def __callback(self, msg: CompressedImageInput) -> None:
94
262
)
95
263
self .get_logger ().info (f"Created publisher for { repub_topic_name } ." )
96
264
265
+ # Create the camera info message
266
+ if self .__sync_camera_info_with_topic is not None :
267
+ self .__camera_info_msg .header .stamp = msg .data .header .stamp
268
+ self .__pub_camera_info .publish (self .__camera_info_msg )
269
+
97
270
# Publish the message
98
271
self .__pubs [topic_name ].publish (msg .data )
99
272
0 commit comments