1+ # Copyright 2026 Dimensional Inc.
2+ #
3+ # Licensed under the Apache License, Version 2.0 (the "License");
4+ # you may not use this file except in compliance with the License.
5+ # You may obtain a copy of the License at
6+ #
7+ # http://www.apache.org/licenses/LICENSE-2.0
8+ #
9+ # Unless required by applicable law or agreed to in writing, software
10+ # distributed under the License is distributed on an "AS IS" BASIS,
11+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+ # See the License for the specific language governing permissions and
13+ # limitations under the License.
14+
115"""
216Configuration constants and settings for the LCM-Foxglove bridge.
317"""
620import os
721
822# Configure logging
9- logging .basicConfig (level = logging .INFO , format = '%(asctime)s - %(name)s - %(levelname)s - %(message)s' )
23+ logging .basicConfig (
24+ level = logging .INFO , format = "%(asctime)s - %(name)s - %(levelname)s - %(message)s"
25+ )
1026logger = logging .getLogger ("lcm_foxglove_bridge" )
1127
1228# Get the directory where this config.py file is located
1329_CONFIG_DIR = os .path .dirname (os .path .abspath (__file__ ))
14- # Project root is two levels up from tools/foxglove_bridge/
15- _PROJECT_ROOT = os .path .abspath (os .path .join (_CONFIG_DIR , ".." , ".." ))
30+ # One level up from foxglove_bridge/ to get to package root (dimos_lcm/ when installed)
31+ _PACKAGE_ROOT = os .path .dirname (_CONFIG_DIR )
32+
33+ # Directory paths - try installed location first, fall back to editable
34+ ROS_MSGS_DIR = os .path .join (_PACKAGE_ROOT , "sources" , "ros_msgs" )
35+ if not os .path .isdir (ROS_MSGS_DIR ):
36+ # Editable install - project root is two levels up from tools/foxglove_bridge/
37+ _PROJECT_ROOT = os .path .dirname (_PACKAGE_ROOT )
38+ ROS_MSGS_DIR = os .path .join (_PROJECT_ROOT , "sources" , "ros_msgs" )
1639
17- # Directory paths - using paths relative to project root
18- ROS_MSGS_DIR = os .path .join (_PROJECT_ROOT , "sources" , "ros_msgs" )
19- LCM_PYTHON_MODULES_PATH = os .path .join (_PROJECT_ROOT , "generated" , "python_lcm_msgs" , "lcm_msgs" )
40+ LCM_PYTHON_MODULES_PATH = os .path .join (_PACKAGE_ROOT , "generated" , "python_lcm_msgs" , "lcm_msgs" )
41+ if not os .path .isdir (LCM_PYTHON_MODULES_PATH ):
42+ _PROJECT_ROOT = os .path .dirname (_PACKAGE_ROOT )
43+ LCM_PYTHON_MODULES_PATH = os .path .join (
44+ _PROJECT_ROOT , "generated" , "python_lcm_msgs" , "lcm_msgs"
45+ )
2046
2147# Thread pool settings
2248DEFAULT_THREAD_POOL_SIZE = 8
3561 "properties" : {
3662 "stamp" : {
3763 "type" : "object" ,
38- "properties" : {
39- "sec" : {"type" : "integer" },
40- "nsec" : {"type" : "integer" }
41- }
64+ "properties" : {"sec" : {"type" : "integer" }, "nsec" : {"type" : "integer" }},
4265 },
43- "frame_id" : {"type" : "string" }
44- }
66+ "frame_id" : {"type" : "string" },
67+ },
4568 },
4669 "height" : {"type" : "integer" },
4770 "width" : {"type" : "integer" },
4871 "encoding" : {"type" : "string" },
4972 "is_bigendian" : {"type" : "boolean" },
5073 "step" : {"type" : "integer" },
51- "data" : {
52- "type" : "string" ,
53- "contentEncoding" : "base64"
54- }
55- }
56- }
74+ "data" : {"type" : "string" , "contentEncoding" : "base64" },
75+ },
76+ },
5777 },
5878 "sensor_msgs.CompressedImage" : {
5979 "foxglove_name" : "sensor_msgs/msg/CompressedImage" ,
6585 "properties" : {
6686 "stamp" : {
6787 "type" : "object" ,
68- "properties" : {
69- "sec" : {"type" : "integer" },
70- "nsec" : {"type" : "integer" }
71- }
88+ "properties" : {"sec" : {"type" : "integer" }, "nsec" : {"type" : "integer" }},
7289 },
73- "frame_id" : {"type" : "string" }
74- }
90+ "frame_id" : {"type" : "string" },
91+ },
7592 },
7693 "format" : {"type" : "string" },
77- "data" : {
78- "type" : "string" ,
79- "contentEncoding" : "base64"
80- }
81- }
82- }
94+ "data" : {"type" : "string" , "contentEncoding" : "base64" },
95+ },
96+ },
8397 },
8498 "sensor_msgs.JointState" : {
8599 "foxglove_name" : "sensor_msgs/msg/JointState" ,
91105 "properties" : {
92106 "stamp" : {
93107 "type" : "object" ,
94- "properties" : {
95- "sec" : {"type" : "integer" },
96- "nsec" : {"type" : "integer" }
97- }
108+ "properties" : {"sec" : {"type" : "integer" }, "nsec" : {"type" : "integer" }},
98109 },
99- "frame_id" : {"type" : "string" }
100- }
101- },
102- "name" : {
103- "type" : "array" ,
104- "items" : {"type" : "string" }
105- },
106- "position" : {
107- "type" : "array" ,
108- "items" : {"type" : "number" }
109- },
110- "velocity" : {
111- "type" : "array" ,
112- "items" : {"type" : "number" }
110+ "frame_id" : {"type" : "string" },
111+ },
113112 },
114- "effort " : {
115- "type" : "array" ,
116- "items" : {"type" : "number" }
117- }
113+ "name " : {"type" : "array" , "items" : { "type" : "string" }},
114+ "position" : { "type" : "array" , "items" : { "type" : "number" }} ,
115+ "velocity" : { "type" : "array" , "items" : {"type" : "number" }},
116+ "effort" : { "type" : "array" , "items" : { "type" : "number" }},
118117 },
119- "required" : ["header" , "name" , "position" , "velocity" , "effort" ]
120- }
118+ "required" : ["header" , "name" , "position" , "velocity" , "effort" ],
119+ },
121120 },
122121 "tf2_msgs.TFMessage" : {
123122 "foxglove_name" : "tf2_msgs/msg/TFMessage" ,
136135 "type" : "object" ,
137136 "properties" : {
138137 "sec" : {"type" : "integer" },
139- "nsec" : {"type" : "integer" }
140- }
138+ "nsec" : {"type" : "integer" },
139+ },
141140 },
142- "frame_id" : {"type" : "string" }
143- }
141+ "frame_id" : {"type" : "string" },
142+ },
144143 },
145144 "child_frame_id" : {"type" : "string" },
146145 "transform" : {
151150 "properties" : {
152151 "x" : {"type" : "number" },
153152 "y" : {"type" : "number" },
154- "z" : {"type" : "number" }
155- }
153+ "z" : {"type" : "number" },
154+ },
156155 },
157156 "rotation" : {
158157 "type" : "object" ,
159158 "properties" : {
160159 "x" : {"type" : "number" },
161160 "y" : {"type" : "number" },
162161 "z" : {"type" : "number" },
163- "w" : {"type" : "number" }
164- }
165- }
166- }
167- }
168- }
169- }
162+ "w" : {"type" : "number" },
163+ },
164+ },
165+ },
166+ },
167+ },
168+ },
170169 }
171- }
172- }
170+ },
171+ },
173172 },
174173 "sensor_msgs.PointCloud2" : {
175174 "foxglove_name" : "sensor_msgs/msg/PointCloud2" ,
181180 "properties" : {
182181 "stamp" : {
183182 "type" : "object" ,
184- "properties" : {
185- "sec" : {"type" : "integer" },
186- "nsec" : {"type" : "integer" }
187- },
188- "required" : ["sec" , "nsec" ]
183+ "properties" : {"sec" : {"type" : "integer" }, "nsec" : {"type" : "integer" }},
184+ "required" : ["sec" , "nsec" ],
189185 },
190- "frame_id" : {"type" : "string" }
186+ "frame_id" : {"type" : "string" },
191187 },
192- "required" : ["stamp" , "frame_id" ]
188+ "required" : ["stamp" , "frame_id" ],
193189 },
194190 "height" : {"type" : "integer" },
195191 "width" : {"type" : "integer" },
203199 "datatype" : {"type" : "integer" },
204200 "count" : {"type" : "integer" },
205201 },
206- "required" : ["name" ,"offset" ,"datatype" ,"count" ]
207- }
202+ "required" : ["name" , "offset" , "datatype" , "count" ],
203+ },
208204 },
209205 "is_bigendian" : {"type" : "boolean" },
210206 "point_step" : {"type" : "integer" },
211207 "row_step" : {"type" : "integer" },
212- "data" : {
213- "type" : "string" ,
214- "contentEncoding" : "base64"
215- },
216- "is_dense" : {"type" : "boolean" }
208+ "data" : {"type" : "string" , "contentEncoding" : "base64" },
209+ "is_dense" : {"type" : "boolean" },
217210 },
218211 "required" : [
219- "header" ,"height" ,"width" ,"fields" ,
220- "is_bigendian" ,"point_step" ,"row_step" ,
221- "data" ,"is_dense"
222- ]
223- }
224- }
212+ "header" ,
213+ "height" ,
214+ "width" ,
215+ "fields" ,
216+ "is_bigendian" ,
217+ "point_step" ,
218+ "row_step" ,
219+ "data" ,
220+ "is_dense" ,
221+ ],
222+ },
223+ },
225224}
226225
227226# Mapping of ROS primitive types to JSON schema types
242241 "byte" : {"type" : "integer" , "minimum" : 0 , "maximum" : 255 },
243242 "time" : {
244243 "type" : "object" ,
245- "properties" : {
246- "sec" : {"type" : "integer" },
247- "nsec" : {"type" : "integer" }
248- },
249- "required" : ["sec" , "nsec" ]
244+ "properties" : {"sec" : {"type" : "integer" }, "nsec" : {"type" : "integer" }},
245+ "required" : ["sec" , "nsec" ],
250246 },
251247 "duration" : {
252248 "type" : "object" ,
253- "properties" : {
254- "sec" : {"type" : "integer" },
255- "nsec" : {"type" : "integer" }
256- },
257- "required" : ["sec" , "nsec" ]
249+ "properties" : {"sec" : {"type" : "integer" }, "nsec" : {"type" : "integer" }},
250+ "required" : ["sec" , "nsec" ],
258251 },
259- }
252+ }
0 commit comments