Merge branch 'ros2' of github.com:introlab/rtabmap_ros into rolling-devel

This commit is contained in:
matlabbe
2026-06-24 18:04:57 -07:00
161 changed files with 9713 additions and 2149 deletions
@@ -0,0 +1,453 @@
[Core]
Rtabmap\WorkingDirectory=/home/vscode/.ros
[Gui]
AboutDialog\geometry=@ByteArray(\x1\xd9\xd0\xcb\0\x3\0\0\0\0\0\0\0\0\0/\0\0\x2\xf7\0\0\x3\x10\0\0\0\0\0\0\0/\0\0\x2\xf7\0\0\x3\x10\0\0\0\0\0\0\0\0\a\x80\0\0\0\0\0\0\0/\0\0\x2\xf7\0\0\x3\x10)
DepthCalibrationDialog\bin_depth=2
DepthCalibrationDialog\bin_height=6
DepthCalibrationDialog\bin_width=8
DepthCalibrationDialog\cone_radius=0.02
DepthCalibrationDialog\cone_stddev_thresh=0.1
DepthCalibrationDialog\decimation=1
DepthCalibrationDialog\laser_scan=false
DepthCalibrationDialog\max_depth=3.5
DepthCalibrationDialog\max_model_depth=10
DepthCalibrationDialog\min_depth=0
DepthCalibrationDialog\smoothing=1
DepthCalibrationDialog\voxel=0.01
ExportBundlerDialog\exportPoints=false
ExportBundlerDialog\laplacianThr=0
ExportBundlerDialog\maxAngularSpeed=0
ExportBundlerDialog\maxLinearSpeed=0
ExportBundlerDialog\sba_iterations=20
ExportBundlerDialog\sba_rematch_features=true
ExportBundlerDialog\sba_type=0
ExportBundlerDialog\sba_variance=1
ExportCloudsDialog\assemble=true
ExportCloudsDialog\assemble_samples=0
ExportCloudsDialog\assemble_voxel=0.01
ExportCloudsDialog\bilateral=false
ExportCloudsDialog\bilateral_sigma_r=0.1
ExportCloudsDialog\bilateral_sigma_s=10
ExportCloudsDialog\binary=true
ExportCloudsDialog\cam_proj=false
ExportCloudsDialog\cam_proj_decimation=1
ExportCloudsDialog\cam_proj_distance_policy=true
ExportCloudsDialog\cam_proj_export_format=0
ExportCloudsDialog\cam_proj_keep_points=false
ExportCloudsDialog\cam_proj_mask=
ExportCloudsDialog\cam_proj_max_angle=0
ExportCloudsDialog\cam_proj_max_depth_error=0
ExportCloudsDialog\cam_proj_max_distance=0
ExportCloudsDialog\cam_proj_recolor_points=true
ExportCloudsDialog\cam_proj_roi_ratios=0.0 0.0 0.0 0.0
ExportCloudsDialog\cputsdf_flattenRadius=0.005
ExportCloudsDialog\cputsdf_minWeight=0
ExportCloudsDialog\cputsdf_randomSplit=1
ExportCloudsDialog\cputsdf_resolution=0.01
ExportCloudsDialog\cputsdf_size=12
ExportCloudsDialog\cputsdf_truncNeg=0.03
ExportCloudsDialog\cputsdf_truncPos=0.03
ExportCloudsDialog\filtering=false
ExportCloudsDialog\filtering_min_neighbors=5
ExportCloudsDialog\filtering_radius=0
ExportCloudsDialog\frame=0
ExportCloudsDialog\from_depth=true
ExportCloudsDialog\gain=false
ExportCloudsDialog\gain_beta=10
ExportCloudsDialog\gain_full=false
ExportCloudsDialog\gain_overlap=0
ExportCloudsDialog\gain_radius=0.02
ExportCloudsDialog\gain_rgb=true
ExportCloudsDialog\intensity_colormap=0
ExportCloudsDialog\mesh=false
ExportCloudsDialog\mesh_angle_tolerance=15
ExportCloudsDialog\mesh_clean=true
ExportCloudsDialog\mesh_color_radius=0.05
ExportCloudsDialog\mesh_decimation_factor=0
ExportCloudsDialog\mesh_dense_strategy=1
ExportCloudsDialog\mesh_max_polygons=0
ExportCloudsDialog\mesh_min_cluster_size=0
ExportCloudsDialog\mesh_mu=2.5
ExportCloudsDialog\mesh_quad=false
ExportCloudsDialog\mesh_radius=0.2
ExportCloudsDialog\mesh_texture=false
ExportCloudsDialog\mesh_textureBlending=true
ExportCloudsDialog\mesh_textureBlendingDecimation=0
ExportCloudsDialog\mesh_textureBrightnessConstrastRatioHigh=5
ExportCloudsDialog\mesh_textureBrightnessConstrastRatioLow=0
ExportCloudsDialog\mesh_textureCameraFiltering=false
ExportCloudsDialog\mesh_textureCameraFilteringAngle=30
ExportCloudsDialog\mesh_textureCameraFilteringLaplacian=0
ExportCloudsDialog\mesh_textureCameraFilteringRadius=0
ExportCloudsDialog\mesh_textureCameraFilteringVel=0
ExportCloudsDialog\mesh_textureCameraFilteringVelRad=0
ExportCloudsDialog\mesh_textureDistanceToCamPolicy=false
ExportCloudsDialog\mesh_textureExposureFusion=false
ExportCloudsDialog\mesh_textureFormat=0
ExportCloudsDialog\mesh_textureMaxAngle=0
ExportCloudsDialog\mesh_textureMaxCount=1
ExportCloudsDialog\mesh_textureMaxDepthError=0
ExportCloudsDialog\mesh_textureMaxDistance=3
ExportCloudsDialog\mesh_textureMinCluster=50
ExportCloudsDialog\mesh_textureMultiband=false
ExportCloudsDialog\mesh_textureMultibandAngleHardThr=90
ExportCloudsDialog\mesh_textureMultibandBestScoreThr=0.1
ExportCloudsDialog\mesh_textureMultibandDownScale=2
ExportCloudsDialog\mesh_textureMultibandFillHoles=false
ExportCloudsDialog\mesh_textureMultibandForceVisible=false
ExportCloudsDialog\mesh_textureMultibandNbContrib=1 5 10 0
ExportCloudsDialog\mesh_textureMultibandPadding=5
ExportCloudsDialog\mesh_textureMultibandUnwrap=0
ExportCloudsDialog\mesh_textureRoiRatios=0.0 0.0 0.0 0.0
ExportCloudsDialog\mesh_textureSize=6
ExportCloudsDialog\mesh_textureVertexColorPolicy=0
ExportCloudsDialog\mesh_triangle_size=1
ExportCloudsDialog\mls=false
ExportCloudsDialog\mls_dilation_iterations=1
ExportCloudsDialog\mls_dilation_voxel_size=0.005
ExportCloudsDialog\mls_output_voxel_size=0
ExportCloudsDialog\mls_point_density=10
ExportCloudsDialog\mls_polygonial_order=2
ExportCloudsDialog\mls_radius=0.04
ExportCloudsDialog\mls_upsampling_method=0
ExportCloudsDialog\mls_upsampling_radius=0.01
ExportCloudsDialog\mls_upsampling_step=0.005
ExportCloudsDialog\nodes_filtering=false
ExportCloudsDialog\nodes_filtering_xmax=0
ExportCloudsDialog\nodes_filtering_xmin=0
ExportCloudsDialog\nodes_filtering_ymax=0
ExportCloudsDialog\nodes_filtering_ymin=0
ExportCloudsDialog\nodes_filtering_zmax=0
ExportCloudsDialog\nodes_filtering_zmin=0
ExportCloudsDialog\normals_ground_normals_up=0
ExportCloudsDialog\normals_k=20
ExportCloudsDialog\normals_radius=0
ExportCloudsDialog\openchisel_carving_dist_m=0.05
ExportCloudsDialog\openchisel_chunk_size_x=16
ExportCloudsDialog\openchisel_chunk_size_y=16
ExportCloudsDialog\openchisel_chunk_size_z=16
ExportCloudsDialog\openchisel_far_plane_dist=1.1
ExportCloudsDialog\openchisel_integration_weight=1
ExportCloudsDialog\openchisel_merge_vertices=true
ExportCloudsDialog\openchisel_near_plane_dist=0.05
ExportCloudsDialog\openchisel_truncation_constant=0.001504
ExportCloudsDialog\openchisel_truncation_linear=0.00152
ExportCloudsDialog\openchisel_truncation_quadratic=0.0019
ExportCloudsDialog\openchisel_truncation_scale=10
ExportCloudsDialog\openchisel_use_voxel_carving=false
ExportCloudsDialog\pipeline=1
ExportCloudsDialog\poisson_depth=0
ExportCloudsDialog\poisson_iso=8
ExportCloudsDialog\poisson_manifold=true
ExportCloudsDialog\poisson_minDepth=5
ExportCloudsDialog\poisson_outputPolygons=false
ExportCloudsDialog\poisson_pointWeight=4
ExportCloudsDialog\poisson_polygon_size=0.03
ExportCloudsDialog\poisson_samples=1
ExportCloudsDialog\poisson_scale=1.1
ExportCloudsDialog\poisson_solver=8
ExportCloudsDialog\regenerate=false
ExportCloudsDialog\regenerate_ceiling=0
ExportCloudsDialog\regenerate_decimation=1
ExportCloudsDialog\regenerate_distortion_model=
ExportCloudsDialog\regenerate_edge_bleeding_error=0
ExportCloudsDialog\regenerate_fill_error=2
ExportCloudsDialog\regenerate_fill_size=0
ExportCloudsDialog\regenerate_floor=0
ExportCloudsDialog\regenerate_footprint_height=0
ExportCloudsDialog\regenerate_footprint_length=0
ExportCloudsDialog\regenerate_footprint_width=0
ExportCloudsDialog\regenerate_max_depth=4
ExportCloudsDialog\regenerate_min_depth=0
ExportCloudsDialog\regenerate_min_depth_confidence=0
ExportCloudsDialog\regenerate_offaxis_filtering=false
ExportCloudsDialog\regenerate_offaxis_filtering_angle=10
ExportCloudsDialog\regenerate_offaxis_filtering_neg_x=true
ExportCloudsDialog\regenerate_offaxis_filtering_neg_y=true
ExportCloudsDialog\regenerate_offaxis_filtering_neg_z=true
ExportCloudsDialog\regenerate_offaxis_filtering_pos_x=true
ExportCloudsDialog\regenerate_offaxis_filtering_pos_y=true
ExportCloudsDialog\regenerate_offaxis_filtering_pos_z=true
ExportCloudsDialog\regenerate_roi=0.0 0.0 0.0 0.0
ExportCloudsDialog\regenerate_scan_decimation=1
ExportCloudsDialog\regenerate_scan_max_range=0
ExportCloudsDialog\regenerate_scan_min_range=0
ExportCloudsDialog\subtract=false
ExportCloudsDialog\subtract_min_neighbors=5
ExportCloudsDialog\subtract_point_angle=0
ExportCloudsDialog\subtract_point_radius=0.02
Figures\counts=
Figures\curves=
Figures\thresholds=
General\beep=false
General\cloudCeilingHeight=0
General\cloudFiltering=false
General\cloudFilteringAngle=30
General\cloudFilteringRadius=0.1
General\cloudFloorHeight=0
General\cloudNoiseMinNeighbors=5
General\cloudNoiseRadius=0
General\cloudVoxel=0
General\cloudsKept=true
General\colorScheme0=0
General\colorScheme1=0
General\colorSchemeScan0=0
General\colorSchemeScan1=0
General\decimation0=8
General\decimation1=4
General\depthConf0=0
General\depthConf1=0
General\downsamplingScan0=1
General\downsamplingScan1=1
General\elevationMapShown=0
General\figure_cache=true
General\figure_time=true
General\gravityLength0=1
General\gravityLength1=1
General\gravityShown0=false
General\gravityShown1=true
General\gridMapOpacity=0.75
General\gridMapShown=false
General\gridUIResolution=0
General\gtAlign=true
General\imageHighestHypShown=false
General\imageRejectedShown=true
General\imagesKept=true
General\landmarkSize=0
General\localizationsGraphView=false
General\localizationsGraphViewOdomCache=false
General\loggerEventLevel=3
General\loggerLevel=2
General\loggerPauseLevel=3
General\loggerPrintThreadId=false
General\loggerPrintTime=true
General\loggerType=1
General\maxDepth0=5
General\maxDepth1=0
General\maxRange0=0
General\maxRange1=0
General\meshing=false
General\meshing_angle=15
General\meshing_quad=true
General\meshing_texture=false
General\meshing_triangle_size=2
General\minDepth0=0
General\minDepth1=0
General\minRange0=0
General\minRange1=0
General\missingRepublished=true
General\noFiltering=true
General\nochangeGraphView=false
General\normalKSearch=10
General\normalRadiusSearch=0
General\notifyNewGlobalPath=false
General\octomap=false
General\octomap_2dgrid=true
General\octomap_3dmap=true
General\octomap_depth=16
General\octomap_point_size=5
General\octomap_rendering_type=0
General\odomDisabled=false
General\odomF2MGravitySigma=-1
General\odomOnlyInliersShown=false
General\odomQualityThr=50
General\odomRegistration=3
General\opacity0=1
General\opacity1=0.75
General\opacityScan0=1
General\opacityScan1=0.5
General\posteriorGraphView=true
General\ptSize0=1
General\ptSize1=2
General\ptSizeFeatures0=3
General\ptSizeFeatures1=3
General\ptSizeScan0=1
General\ptSizeScan1=2
General\roiRatios0=0.0 0.0 0.0 0.0
General\roiRatios1=0.0 0.0 0.0 0.0
General\scanCeilingHeight=0
General\scanFloorHeight=0
General\scanNormalKSearch=0
General\scanNormalRadiusSearch=0
General\showClouds0=true
General\showClouds1=false
General\showFeatures0=false
General\showFeatures1=true
General\showFrames=false
General\showFrustums0=false
General\showFrustums1=false
General\showGraphs=true
General\showIMUAcc=false
General\showIMUGravity=false
General\showLabels=false
General\showLandmarks=true
General\showScans0=true
General\showScans1=true
General\subtractFiltering=false
General\subtractFilteringAngle=0
General\subtractFilteringMinPts=5
General\subtractFilteringRadius=0.02
General\verticalLayoutUsed=true
General\voxelSizeScan0=0
General\voxelSizeScan1=0
General\wordsGraphView=false
MainWindow\geometry=@ByteArray(\x1\xd9\xd0\xcb\0\x3\0\0\0\0\0\x32\0\0\0\x1b\0\0\x6\xf2\0\0\x3\xf\0\0\0\x32\0\0\0@\0\0\x6\xf2\0\0\x3\xf\0\0\0\0\0\0\0\0\a\x80\0\0\0\x32\0\0\0@\0\0\x6\xf2\0\0\x3\xf)
MainWindow\maximized=false
MainWindow\state="@ByteArray(\0\0\0\xff\0\0\0\0\xfd\0\0\0\x3\0\0\0\0\0\0\x3\\\0\0\x2\x95\xfc\x2\0\0\0\x3\xfb\0\0\0$\0\x64\0o\0\x63\0k\0W\0i\0\x64\0g\0\x65\0t\0_\0s\0t\0\x61\0t\0s\0V\0\x32\x2\0\0\0\x32\0\0\0\x1b\0\0\0\xc8\0\0\0\xc1\xfb\0\0\0(\0\x64\0o\0\x63\0k\0W\0i\0\x64\0g\0\x65\0t\0_\0i\0m\0\x61\0g\0\x65\0V\0i\0\x65\0w\x1\0\0\0;\0\0\x1\xaa\0\0\0\x37\0\xff\xff\xff\xfb\0\0\0&\0\x64\0o\0\x63\0k\0W\0i\0\x64\0g\0\x65\0t\0_\0o\0\x64\0o\0m\0\x65\0t\0r\0y\x1\0\0\x1\xeb\0\0\0\xe5\0\0\0\x13\0\xff\xff\xff\0\0\0\x1\0\0\x3_\0\0\x2\x95\xfc\x2\0\0\0\x4\xfb\0\0\0,\0\x64\0o\0\x63\0k\0W\0i\0\x64\0g\0\x65\0t\0_\0\x63\0l\0o\0u\0\x64\0V\0i\0\x65\0w\0\x65\0r\x1\0\0\0;\0\0\x2\x95\0\0\0\xdb\0\xff\xff\xff\xfb\0\0\0\x38\0\x64\0o\0\x63\0k\0W\0i\0\x64\0g\0\x65\0t\0_\0l\0o\0o\0p\0\x43\0l\0o\0s\0u\0r\0\x65\0V\0i\0\x65\0w\0\x65\0r\0\0\0\0\0\xff\xff\xff\xff\0\0\0\xf0\0\xff\xff\xff\xfb\0\0\0,\0\x64\0o\0\x63\0k\0W\0i\0\x64\0g\0\x65\0t\0_\0g\0r\0\x61\0p\0h\0V\0i\0\x65\0w\0\x65\0r\x2\0\0\x4\xf2\0\0\x1\x39\0\0\x2}\0\0\x1\x90\xfb\0\0\0\x34\0\x64\0o\0\x63\0k\0W\0i\0\x64\0g\0\x65\0t\0_\0m\0u\0l\0t\0i\0S\0\x65\0s\0s\0i\0o\0n\0L\0o\0\x63\0\0\0\0\0\xff\xff\xff\xff\0\0\0\x13\0\xff\xff\xff\0\0\0\x3\0\0\0\0\0\0\0\0\xfc\x1\0\0\0\x5\xfb\0\0\0(\0\x64\0o\0\x63\0k\0W\0i\0\x64\0g\0\x65\0t\0_\0p\0o\0s\0t\0\x65\0r\0i\0o\0r\0\0\0\0\0\xff\xff\xff\xff\0\0\0\xcb\0\xff\xff\xff\xfb\0\0\0*\0\x64\0o\0\x63\0k\0W\0i\0\x64\0g\0\x65\0t\0_\0l\0i\0k\0\x65\0l\0i\0h\0o\0o\0\x64\0\0\0\0\0\xff\xff\xff\xff\0\0\0\xcb\0\xff\xff\xff\xfb\0\0\0$\0\x64\0o\0\x63\0k\0W\0i\0\x64\0g\0\x65\0t\0_\0\x63\0o\0n\0s\0o\0l\0\x65\0\0\0\0\0\xff\xff\xff\xff\0\0\x1(\0\xff\xff\xff\xfb\0\0\0\x30\0\x64\0o\0\x63\0k\0W\0i\0\x64\0g\0\x65\0t\0_\0r\0\x61\0w\0l\0i\0k\0\x65\0l\0i\0h\0o\0o\0\x64\0\0\0\0\0\xff\xff\xff\xff\0\0\0\xcb\0\xff\xff\xff\xfb\0\0\0\x30\0\x64\0o\0\x63\0k\0W\0i\0\x64\0g\0\x65\0t\0_\0m\0\x61\0p\0V\0i\0s\0i\0\x62\0i\0l\0i\0t\0y\x2\0\0\0\x32\0\0\0\x1b\0\0\0\xc8\0\0\0\x88\0\0\0\0\0\0\x2\x95\0\0\0\x4\0\0\0\x4\0\0\0\b\0\0\0\b\xfc\0\0\0\x1\0\0\0\x2\0\0\0\x2\0\0\0\xe\0t\0o\0o\0l\0\x42\0\x61\0r\0\0\0\0\0\xff\xff\xff\xff\0\0\0\0\0\0\0\0\0\0\0\x12\0t\0o\0o\0l\0\x42\0\x61\0r\0_\0\x32\x1\0\0\0\0\xff\xff\xff\xff\0\0\0\0\0\0\0\0)"
MainWindow\status_bar=false
PostProcessingDialog\cluster_angle=30
PostProcessingDialog\cluster_radius=1
PostProcessingDialog\detect_more_lc=true
PostProcessingDialog\inter_session=true
PostProcessingDialog\intra_session=true
PostProcessingDialog\iterations=5
PostProcessingDialog\refine_lc=false
PostProcessingDialog\refine_neigbors=false
PostProcessingDialog\sba=false
PostProcessingDialog\sba_iterations=20
PostProcessingDialog\sba_rematch_features=true
PostProcessingDialog\sba_type=1
PostProcessingDialog\sba_variance=1
PreferencesDialog\geometry=@ByteArray(\x1\xd9\xd0\xcb\0\x3\0\0\0\0\x1\xa8\xff\xff\xff\xf6\0\0\x5{\0\0\x3\xb7\0\0\x1\xa8\0\0\0\x1b\0\0\x5{\0\0\x3\xb7\0\0\0\0\0\0\0\0\a\x80\0\0\x1\xa8\0\0\0\x1b\0\0\x5{\0\0\x3\xb7)
graphicsView_graphView\current_goal_color=@Variant(\0\0\0\x43\x1\xff\xff\x80\x80\0\0\x80\x80\0\0)
graphicsView_graphView\ensure_frame_visible=1
graphicsView_graphView\global_color=@Variant(\0\0\0\x43\x1\xff\xff\xff\xff\0\0\0\0\0\0)
graphicsView_graphView\global_path_color=@Variant(\0\0\0\x43\x1\xff\xff\x80\x80\0\0\x80\x80\0\0)
graphicsView_graphView\global_path_visible=true
graphicsView_graphView\gps_color=@Variant(\0\0\0\x43\x1\xff\xff\0\0\x80\x80\x80\x80\0\0)
graphicsView_graphView\gps_graph_visible=true
graphicsView_graphView\graph_visible=true
graphicsView_graphView\grid_visible=true
graphicsView_graphView\gt_color=@Variant(\0\0\0\x43\x1\xff\xff\xa0\xa0\xa0\xa0\xa4\xa4\0\0)
graphicsView_graphView\gt_graph_visible=true
graphicsView_graphView\highlighting_color_0=@Variant(\0\0\0\x43\x1\xff\xff\xff\xff\xff\xff\0\0\0\0)
graphicsView_graphView\highlighting_color_1=@Variant(\0\0\0\x43\x1\xff\xff\xff\xff\0\0\xff\xff\0\0)
graphicsView_graphView\inter_session_color=@Variant(\0\0\0\x43\x1\xff\xff\0\0\xff\xff\0\0\0\0)
graphicsView_graphView\intra_inter_session_colors_enabled=false
graphicsView_graphView\intra_session_color=@Variant(\0\0\0\x43\x1\xff\xff\xff\xff\0\0\0\0\0\0)
graphicsView_graphView\link_width=0
graphicsView_graphView\local_color=@Variant(\0\0\0\x43\x1\xff\xff\xff\xff\xff\xff\0\0\0\0)
graphicsView_graphView\local_path_color=@Variant(\0\0\0\x43\x1\xff\xff\0\0\xff\xff\xff\xff\0\0)
graphicsView_graphView\local_path_visible=true
graphicsView_graphView\local_radius_visible=false
graphicsView_graphView\loop_closure_outlier_thr=@Variant(\0\0\0\x87\0\0\0\0)
graphicsView_graphView\min_link_length=@Variant(\0\0\0\x87<\xa3\xd7\n)
graphicsView_graphView\neighbor_color=@Variant(\0\0\0\x43\x1\xff\xff\0\0\0\0\xff\xff\0\0)
graphicsView_graphView\neighbor_merged_color=@Variant(\0\0\0\x43\x1\xff\xff\xff\xff\xaa\xaa\0\0\0\0)
graphicsView_graphView\node_color=@Variant(\0\0\0\x43\x1\xff\xff\0\0\0\0\xff\xff\0\0)
graphicsView_graphView\node_odom_cache_color=@Variant(\0\0\0\x43\x1\xff\xff\0\0\x80\x80\0\0\0\0)
graphicsView_graphView\node_radius=0.009999999776482582
graphicsView_graphView\node_visible=true
graphicsView_graphView\odom_cache_overlay=true
graphicsView_graphView\orientation_ENU=false
graphicsView_graphView\origin_visible=true
graphicsView_graphView\referential_visible=true
graphicsView_graphView\rejected_color=@Variant(\0\0\0\x43\x1\xff\xff\0\0\0\0\0\0\0\0)
graphicsView_graphView\user_color=@Variant(\0\0\0\x43\x1\xff\xff\xff\xff\0\0\0\0\0\0)
graphicsView_graphView\view_plane=0
graphicsView_graphView\virtual_color=@Variant(\0\0\0\x43\x1\xff\xff\xff\xff\0\0\xff\xff\0\0)
imageView_loopClosure\alpha=100
imageView_loopClosure\bg_color=@Variant(\0\0\0\x43\x1\xff\xff\0\0\0\0\0\0\0\0)
imageView_loopClosure\colormap=2
imageView_loopClosure\colormap_camera_frame=true
imageView_loopClosure\colormap_max_range=@Variant(\0\0\0\x87\0\0\0\0)
imageView_loopClosure\colormap_min_range=@Variant(\0\0\0\x87\0\0\0\0)
imageView_loopClosure\confidence_shown=false
imageView_loopClosure\depth_shown=false
imageView_loopClosure\feature_color=@Variant(\0\0\0\x43\x1\xff\xff\xff\xff\xff\xff\0\0\0\0)
imageView_loopClosure\features_shown=true
imageView_loopClosure\features_size=0
imageView_loopClosure\graphics_view=false
imageView_loopClosure\graphics_view_scale=true
imageView_loopClosure\graphics_view_scale_to_height=false
imageView_loopClosure\image_shown=true
imageView_loopClosure\lines_shown=true
imageView_loopClosure\lines_width=0
imageView_loopClosure\matching_feature_color=@Variant(\0\0\0\x43\x1\xff\xff\xff\xff\0\0\xff\xff\0\0)
imageView_loopClosure\matching_line_color=@Variant(\0\0\0\x43\x1\xff\xff\0\0\xff\xff\xff\xff\0\0)
imageView_odometry\alpha=200
imageView_odometry\bg_color=@Variant(\0\0\0\x43\x1\xff\xff\0\0\0\0\0\0\0\0)
imageView_odometry\colormap=2
imageView_odometry\colormap_camera_frame=true
imageView_odometry\colormap_max_range=@Variant(\0\0\0\x87\0\0\0\0)
imageView_odometry\colormap_min_range=@Variant(\0\0\0\x87\0\0\0\0)
imageView_odometry\confidence_shown=false
imageView_odometry\depth_shown=false
imageView_odometry\feature_color=@Variant(\0\0\0\x43\x1\xff\xff\xff\xff\xff\xff\0\0\0\0)
imageView_odometry\features_shown=true
imageView_odometry\features_size=0
imageView_odometry\graphics_view=false
imageView_odometry\graphics_view_scale=true
imageView_odometry\graphics_view_scale_to_height=false
imageView_odometry\image_shown=true
imageView_odometry\lines_shown=true
imageView_odometry\lines_width=0
imageView_odometry\matching_feature_color=@Variant(\0\0\0\x43\x1\xff\xff\xff\xff\0\0\xff\xff\0\0)
imageView_odometry\matching_line_color=@Variant(\0\0\0\x43\x1\xff\xff\0\0\xff\xff\xff\xff\0\0)
imageView_source\alpha=100
imageView_source\bg_color=@Variant(\0\0\0\x43\x1\xff\xff\0\0\0\0\0\0\0\0)
imageView_source\colormap=2
imageView_source\colormap_camera_frame=true
imageView_source\colormap_max_range=@Variant(\0\0\0\x87\0\0\0\0)
imageView_source\colormap_min_range=@Variant(\0\0\0\x87\0\0\0\0)
imageView_source\confidence_shown=false
imageView_source\depth_shown=false
imageView_source\feature_color=@Variant(\0\0\0\x43\x1\xff\xff\xff\xff\xff\xff\0\0\0\0)
imageView_source\features_shown=true
imageView_source\features_size=0
imageView_source\graphics_view=false
imageView_source\graphics_view_scale=true
imageView_source\graphics_view_scale_to_height=false
imageView_source\image_shown=true
imageView_source\lines_shown=true
imageView_source\lines_width=0
imageView_source\matching_feature_color=@Variant(\0\0\0\x43\x1\xff\xff\xff\xff\0\0\xff\xff\0\0)
imageView_source\matching_line_color=@Variant(\0\0\0\x43\x1\xff\xff\0\0\xff\xff\xff\xff\0\0)
multisession_imageview\alpha=100
multisession_imageview\bg_color=@Variant(\0\0\0\x43\x1\xff\xff\0\0\0\0\0\0\0\0)
multisession_imageview\colormap=2
multisession_imageview\colormap_camera_frame=true
multisession_imageview\colormap_max_range=@Variant(\0\0\0\x87\0\0\0\0)
multisession_imageview\colormap_min_range=@Variant(\0\0\0\x87\0\0\0\0)
multisession_imageview\confidence_shown=false
multisession_imageview\depth_shown=false
multisession_imageview\feature_color=@Variant(\0\0\0\x43\x1\xff\xff\xff\xff\xff\xff\0\0\0\0)
multisession_imageview\features_shown=true
multisession_imageview\features_size=0
multisession_imageview\graphics_view=false
multisession_imageview\graphics_view_scale=true
multisession_imageview\graphics_view_scale_to_height=false
multisession_imageview\image_shown=true
multisession_imageview\lines_shown=true
multisession_imageview\lines_width=0
multisession_imageview\matching_feature_color=@Variant(\0\0\0\x43\x1\xff\xff\xff\xff\0\0\xff\xff\0\0)
multisession_imageview\matching_line_color=@Variant(\0\0\0\x43\x1\xff\xff\0\0\xff\xff\xff\xff\0\0)
widget_cloudViewer\bg_color=@Variant(\0\0\0\x43\x1\xff\xff\0\0\0\0\0\0\0\0)
widget_cloudViewer\camera_axis_shown=true
widget_cloudViewer\camera_focal=@Variant(\0\0\0T8\xb6\0\0\x37s\0\0\xb5\xd5\0\0)
widget_cloudViewer\camera_free=false
widget_cloudViewer\camera_lockZ=true
widget_cloudViewer\camera_pose=@Variant(\0\0\0T\xc0\xc0\x9b\x36@\x80\xf7\xea\x41\x17p\xe)
widget_cloudViewer\camera_target_follow=true
widget_cloudViewer\camera_target_locked=false
widget_cloudViewer\camera_up=@Variant(\0\0\0T\0\0\0\0\0\0\0\0?\x80\0\0)
widget_cloudViewer\color_range_inverted=0
widget_cloudViewer\color_range_max=0
widget_cloudViewer\color_range_min=0
widget_cloudViewer\coordinate_frame_scale=1
widget_cloudViewer\frustum_color=@Variant(\0\0\0\x43\x1\xff\xff\0\0\xff\xff\0\0\0\0)
widget_cloudViewer\frustum_scale=@Variant(\0\0\0\x87?\0\0\0)
widget_cloudViewer\frustum_shown=true
widget_cloudViewer\grid=false
widget_cloudViewer\grid_cell_count=50
widget_cloudViewer\grid_cell_size=1
widget_cloudViewer\intensity_max=100
widget_cloudViewer\intensity_rainbow_colormap=false
widget_cloudViewer\intensity_red_colormap=true
widget_cloudViewer\normals=false
widget_cloudViewer\normals_scale=0.20000000298023224
widget_cloudViewer\normals_step=1
widget_cloudViewer\rendering_rate=5
widget_cloudViewer\trajectory_shown=true
widget_cloudViewer\trajectory_size=100
@@ -0,0 +1,27 @@
#%YAML:1.0
---
camera_name: MULTI_RGBD_INERTIAL_DATASET_FRONT
image_width: 640
image_height: 360
camera_matrix:
rows: 3
cols: 3
data: [ 319.1610, 0., 329.5844, 0.,
319.0881, 182.1654, 0., 0., 1. ]
distortion_coefficients:
rows: 1
cols: 4
data: [ -0.0535, 0.0589, -0.0176, 0.0 ]
distortion_model: plumb_bob
rectification_matrix:
rows: 3
cols: 3
data: [ 1., 0., 0.,
0., 1., 0.,
0., 0., 1. ]
projection_matrix:
rows: 3
cols: 4
data: [ 319.1610, 0., 329.5844, 0., 0.,
319.0881, 182.1654, 0., 0., 0., 1.,
0. ]
@@ -0,0 +1,27 @@
#%YAML:1.0
---
camera_name: MULTI_RGBD_INERTIAL_DATASET_LEFT
image_width: 640
image_height: 360
camera_matrix:
rows: 3
cols: 3
data: [ 319.1506, 0., 321.8367, 0.,
318.9474, 180.0959, 0., 0., 1. ]
distortion_coefficients:
rows: 1
cols: 4
data: [ -0.0556, 0.0576, -0.0174, 0.0 ]
distortion_model: plumb_bob
rectification_matrix:
rows: 3
cols: 3
data: [ 1., 0., 0.,
0., 1., 0.,
0., 0., 1. ]
projection_matrix:
rows: 3
cols: 4
data: [ 319.1506, 0., 321.8367, 0., 0.,
318.9474, 180.0959, 0., 0., 0., 1.,
0. ]
@@ -0,0 +1,27 @@
#%YAML:1.0
---
camera_name: MULTI_RGBD_INERTIAL_DATASET_REAR
image_width: 640
image_height: 360
camera_matrix:
rows: 3
cols: 3
data: [ 319.3360, 0., 323.9265, 0.,
319.1947, 181.9133, 0., 0., 1. ]
distortion_coefficients:
rows: 1
cols: 4
data: [ -0.0534, 0.0542, -0.0155, 0.0 ]
distortion_model: plumb_bob
rectification_matrix:
rows: 3
cols: 3
data: [ 1., 0., 0.,
0., 1., 0.,
0., 0., 1. ]
projection_matrix:
rows: 3
cols: 4
data: [ 319.3360, 0., 323.9265, 0., 0.,
319.1947, 181.9133, 0., 0., 0., 1.,
0. ]
@@ -0,0 +1,27 @@
#%YAML:1.0
---
camera_name: MULTI_RGBD_INERTIAL_DATASET_RIGHT
image_width: 640
image_height: 360
camera_matrix:
rows: 3
cols: 3
data: [ 320.7208, 0., 325.4179, 0.,
320.7359, 184.8089, 0., 0., 1. ]
distortion_coefficients:
rows: 1
cols: 4
data: [ -0.0531, 0.0549, -0.0166, 0.0 ]
distortion_model: plumb_bob
rectification_matrix:
rows: 3
cols: 3
data: [ 1., 0., 0.,
0., 1., 0.,
0., 0., 1. ]
projection_matrix:
rows: 3
cols: 4
data: [ 320.7208, 0., 325.4179, 0., 0.,
320.7359, 184.8089, 0., 0., 0., 1.,
0. ]
+7 -1
View File
@@ -1,8 +1,14 @@
# Requirements:
# A OAK-D camera
# Install depthai-ros package (https://github.com/luxonis/depthai-ros)
# Install depthai-ros package (https://github.com/luxonis/depthai-ros). Tested on Humble branch!
# Example:
# $ ros2 launch rtabmap_examples depthai.launch.py camera_model:=OAK-D
#
# Description: In this example, we feed IR-D images to rtabmap
#
# Note: The first frames may be too bright or too dark till camera exposure adjusts
# to an appriopriate level. Do "Detection->Reset odometry", then
# "Edit->Delete memory" if tracking is lost on start.
import os
@@ -0,0 +1,81 @@
# Requirements:
# A OAK-D camera
# Install depthai-ros package (https://github.com/luxonis/depthai-ros). Tested on Humble branch!
# Example:
# $ ros2 launch rtabmap_examples depthai_color.launch.py camera_model:=OAK-D
#
# Description: In this example, we feed RGB-D images to rtabmap
#
# Note: The first frames may be too bright or too dark till camera exposure adjusts
# to an appriopriate level. Do "Detection->Reset odometry", then
# "Edit->Delete memory" if tracking is lost on start.
import os
from ament_index_python.packages import get_package_share_directory
from launch import LaunchDescription
from launch_ros.actions import Node
from launch.actions import IncludeLaunchDescription
from launch.launch_description_sources import PythonLaunchDescriptionSource
def generate_launch_description():
parameters=[{'frame_id':'oak-d-base-frame',
'subscribe_rgbd':True,
'subscribe_odom_info':True,
'approx_sync':False}]
sync_parameters=[{'approx_sync':True,
'approx_sync_max_interval':0.005}]
remappings=[('imu', '/imu/data')]
return LaunchDescription([
# Launch camera driver
IncludeLaunchDescription(
PythonLaunchDescriptionSource([os.path.join(
get_package_share_directory('depthai_examples'), 'launch'),
'/stereo_inertial_node.launch.py']),
launch_arguments={'enableRviz': 'false',
'rgbResolution': '1080p',
'rgbScaleNumerator': '2', # Convert to 720p (same size than depth)
'rgbScaleDinominator': '3'}.items(),
),
# Sync right/depth/camera_info together
Node(
package='rtabmap_sync', executable='rgbd_sync', output='screen',
parameters=sync_parameters,
remappings=[('rgb/image', '/color/image'),
('rgb/camera_info', '/color/camera_info'),
('depth/image', '/stereo/depth')]),
# Compute quaternion of the IMU
Node(
package='imu_filter_madgwick', executable='imu_filter_madgwick_node', output='screen',
parameters=[{'use_mag': False,
'world_frame':'enu',
'publish_tf':False}],
remappings=[('imu/data_raw', '/imu')]),
# Visual odometry
Node(
package='rtabmap_odom', executable='rgbd_odometry', output='screen',
parameters=parameters,
remappings=remappings),
# VSLAM
Node(
package='rtabmap_slam', executable='rtabmap', output='screen',
parameters=parameters,
remappings=remappings,
arguments=['-d']),
# Visualization
Node(
package='rtabmap_viz', executable='rtabmap_viz', output='screen',
parameters=parameters,
remappings=remappings)
])
@@ -0,0 +1,90 @@
# Requirements:
# A OAK-D camera
# Install depthai-ros package (https://github.com/luxonis/depthai-ros). Tested on Humble branch!
#
# Issue: To have compatible stereo camera info with rtabmap (P[0,3] should be positive on left camera info or negative in right camera info),
# we should add the following line here (https://github.com/luxonis/depthai-ros/blob/887248d72cc6b9515793f828645346408b9cad47/depthai_examples/src/stereo_inertial_publisher.cpp#L593)
# so that left camera info has a positive P[0,3] instead of negative to correctly compute the baseline:
#
# <line 593> leftCameraInfo.p[3] *=-1;
#
# Example:
# $ ros2 launch rtabmap_examples depthai_stereo.launch.py camera_model:=OAK-D
#
# Description: In this example, we feed stereo IR images to rtabmap
#
# Note: The first frames may be too bright or too dark till camera exposure adjusts
# to an appriopriate level. Do "Detection->Reset odometry", then
# "Edit->Delete memory" if tracking is lost on start.
import os
from ament_index_python.packages import get_package_share_directory
from launch import LaunchDescription
from launch_ros.actions import Node
from launch.actions import IncludeLaunchDescription
from launch.launch_description_sources import PythonLaunchDescriptionSource
def generate_launch_description():
parameters={'frame_id':'oak-d-base-frame',
'subscribe_rgbd':True,
'subscribe_odom_info':True,
'approx_sync':False,
'wait_imu_to_init':True}
sync_parameters=[{'approx_sync':True,
'approx_sync_max_interval':0.005}]
remappings=[('imu', '/imu/data')]
return LaunchDescription([
# Launch camera driver
IncludeLaunchDescription(
PythonLaunchDescriptionSource([os.path.join(
get_package_share_directory('depthai_examples'), 'launch'),
'/stereo_inertial_node.launch.py']),
launch_arguments={'depth_aligned': 'false', # not color mode
'enableRviz': 'false',
'monoResolution': '400p'}.items(),
),
# Sync right/depth/camera_info together
Node(
package='rtabmap_sync', executable='stereo_sync', output='screen',
parameters=sync_parameters,
remappings=[('left/image', '/left/image_rect'),
('left/camera_info', '/left/camera_info'),
('right/image', '/right/image_rect'),
('right/camera_info', '/right/camera_info')]),
# Compute quaternion of the IMU
Node(
package='imu_filter_madgwick', executable='imu_filter_madgwick_node', output='screen',
parameters=[{'use_mag': False,
'world_frame':'enu',
'publish_tf':False}],
remappings=[('imu/data_raw', '/imu')]),
# Visual odometry
Node(
package='rtabmap_odom', executable='stereo_odometry', output='screen',
parameters=[parameters],
remappings=remappings),
# VSLAM
Node(
package='rtabmap_slam', executable='rtabmap', output='screen',
parameters=[parameters],
remappings=remappings,
arguments=['-d']),
# Visualization
Node(
package='rtabmap_viz', executable='rtabmap_viz', output='screen',
parameters=[parameters,
{'odometry_node_name': "stereo_odometry"}],
remappings=remappings)
])
@@ -62,7 +62,8 @@ def generate_launch_description():
# Nodes to launch
Node(
package='rtabmap_odom', executable='stereo_odometry', output='screen',
parameters=[parameters],
parameters=[parameters,
{ 'always_process_most_recent_frame':True}],
remappings=remappings),
Node(
@@ -82,7 +83,8 @@ def generate_launch_description():
Node(
package='rtabmap_viz', executable='rtabmap_viz', output='screen',
parameters=[parameters],
parameters=[parameters,
{'odometry_node_name': "stereo_odometry"}],
remappings=remappings),
# Image rectification and publishing synchronized camera_info
@@ -103,15 +105,13 @@ def generate_launch_description():
namespace='stereo_camera'),
Node(
package='image_proc', executable='image_proc', output='screen',
package='image_proc', executable='rectify_node', output='screen',
remappings=[
('image_raw', '/cam0/image_raw'),
('image', '/cam0/image_raw')],
namespace='stereo_camera/left'),
Node(
package='image_proc', executable='image_proc', output='screen',
package='image_proc', executable='rectify_node', output='screen',
remappings=[
('image_raw', '/cam1/image_raw'),
('image', '/cam1/image_raw')],
namespace='stereo_camera/right'),
+2 -1
View File
@@ -154,7 +154,8 @@ def launch_setup(context: LaunchContext, *args, **kwargs):
Node(
package='rtabmap_viz', executable='rtabmap_viz', output='screen',
parameters=[shared_parameters, rtabmap_parameters],
parameters=[shared_parameters, rtabmap_parameters,
{'odometry_node_name': "icp_odometry"}],
remappings=remappings + [('scan_cloud', 'odom_filtered_input_scan')])
]
@@ -173,7 +173,8 @@ def launch_setup(context: LaunchContext, *args, **kwargs):
# Just for visualization
Node(
package='rtabmap_viz', executable='rtabmap_viz', output='screen',
parameters=[shared_parameters, rtabmap_parameters],
parameters=[shared_parameters, rtabmap_parameters,
{'odometry_node_name': "icp_odometry"}],
remappings=remappings + [('scan_cloud', viz_topic)])
]
@@ -201,7 +201,8 @@ def launch_setup(context: LaunchContext, *args, **kwargs):
# Just for visualization
Node(
package='rtabmap_viz', executable='rtabmap_viz', output='screen',
parameters=[shared_parameters, rtabmap_parameters],
parameters=[shared_parameters, rtabmap_parameters,
{'odometry_node_name': "icp_odometry"}],
remappings=remappings + [('scan_cloud', viz_topic)])
]
@@ -0,0 +1,162 @@
#
# Example launch file to run VSLAM on this dataset: https://github.com/seungsang07/multi-rgbd-inertial-dataset
#
# Requirement(s):
# * RTAB-Map should be built with OpenGV support.
#
# To convert ROS1 bags to ROS2 (https://docs.openvins.com/dev-ros1-to-ros2.html):
# sudo pip install rosbags
# rosbags-convert --src Indoor.bag --dst Indoor
#
# Usage:
# ros2 launch rtabmap_examples multi_rgbd_inertial_dataset.launch.py
# ros2 bag play Indoor/Indoor.db3 --clock
#
# Note(s):
# * Communication performance could be improved using the composable nodes of these nodes instead,
# but we are using nodes here to better understand what is going on with rqt_graph.
#
# To get RMSE after the run (using https://github.com/MichaelGrupp/evo):
# rtabmap-export --poses --pose_format 10 ~/.ros/rtabmap.db
# evo_ape tum -a -p --plot_mode xy ~/Downloads/GroundTruth/gt_indoor.txt ~/.ros/rtabmap_poses.txt
#
from launch import LaunchDescription, LaunchContext
from launch_ros.actions import SetParameter
from launch_ros.substitutions import FindPackageShare
from launch_ros.actions import Node
from launch.actions import DeclareLaunchArgument, OpaqueFunction
from launch.substitutions import LaunchConfiguration
def make_yaml_to_camera_info_node(camera):
# the dataset doesn't provide camera_info topics of the camera in the rosbags, so we need to generate them
return Node(
package='rtabmap_util', executable='yaml_to_camera_info.py', name=f'yaml_to_camera_info_{camera}', output='screen',
parameters=[{'yaml_path': [FindPackageShare('rtabmap_examples'), f'/config/multi_rgbd_inertial_dataset_{camera}.yaml']}],
remappings=[
('image', 'color/image_raw'),
('camera_info', 'color/camera_info')],
namespace=f'camera_{camera}')
def make_rgbd_sync_node(camera):
# synchronize topics of each camera together
return Node(
package='rtabmap_sync', executable='rgbd_sync', name=f'rgbd_sync_{camera}', output="screen",
parameters=[{"approx_sync": False}],
remappings=[
("rgb/image", 'color/image_raw'),
("depth/image", 'aligned_depth_to_color/image_raw'),
("rgb/camera_info", 'color/camera_info'),
("rgbd_image", 'rgbd_image')],
namespace=f'camera_{camera}')
def make_static_transform_publisher_node(x, y, z, yaw, pitch, roll, parent_frame, child_frame):
return Node(
package='tf2_ros', executable='static_transform_publisher', name=f"static_transform_publisher_{parent_frame}_{child_frame}", output='screen',
arguments=['--frame-id', parent_frame,
'--child-frame-id', child_frame,
'--x', str(x),
'--y', str(y),
'--z', str(z),
'--yaw', str(yaw),
'--pitch', str(pitch),
'--roll', str(roll)])
def launch_setup(context: LaunchContext, *args, **kwargs):
use_imu = LaunchConfiguration('use_imu').perform(context)
use_imu = use_imu == 'true' or use_imu == 'True'
# Synchronize all cameras together
rgbdx_sync_node = Node(
package='rtabmap_sync', executable='rgbdx_sync', output="screen",
parameters=[{
"rgbd_cameras": 4,
"approx_sync": True,
"approx_sync_max_interval": 0.015}],
remappings=[
("rgbd_image0", '/camera_left/rgbd_image'),
("rgbd_image1", '/camera_front/rgbd_image'),
("rgbd_image2", '/camera_right/rgbd_image'),
("rgbd_image3", '/camera_rear/rgbd_image')],
namespace='rtabmap'
)
# RGB-D odometry
remappings = []
if use_imu:
remappings = [("imu", '/imu')]
rgbd_odometry_node = Node(
package='rtabmap_odom', executable='rgbd_odometry', output="screen",
parameters=[{
"frame_id": 'base_link',
"rgbd_cameras": 0, # make it subscribe to rgbd_images topic from rgbdx_sync
"subscribe_rgbd": True,
"wait_imu_to_init": use_imu}],
remappings=remappings,
namespace='rtabmap'
)
# SLAM
remappings=[("sensor_data", 'odom_sensor_data/raw')]
if(use_imu):
remappings.append(('imu', '/imu'))
slam_node = Node(
package='rtabmap_slam', executable='rtabmap', output="screen",
parameters=[{
"subscribe_sensor_data": True,
"frame_id": 'base_link',
"approx_sync": False,
"Grid/3D": 'false',
"Grid/RayTracing": 'true',
"Grid/NormalsSegmentation": 'false',
"Grid/MaxGroundHeight": '0.05',
"Rtabmap/CreateIntermediateNodes": 'true' # Only to record all odometry poses for trajectory evaluation purpose
}],
remappings=remappings,
arguments=["--delete_db_on_start"],
namespace='rtabmap'
)
# Visualization
viz_node = Node(
package='rtabmap_viz', executable='rtabmap_viz', output="screen",
parameters=[{
"subscribe_sensor_data": True,
"frame_id": 'base_link',
"approx_sync": False,
"subscribe_odom_info": True
}],
remappings=[("sensor_data", 'odom_sensor_data/raw')],
arguments=["-d", [FindPackageShare('rtabmap_examples'), '/config/multi_rgbd_inertial_dataset.ini']],
namespace='rtabmap'
)
return [
make_yaml_to_camera_info_node('left'),
make_rgbd_sync_node('left'),
make_yaml_to_camera_info_node('front'),
make_rgbd_sync_node('front'),
make_yaml_to_camera_info_node('right'),
make_rgbd_sync_node('right'),
make_yaml_to_camera_info_node('rear'),
make_rgbd_sync_node('rear'),
# The dataset doesn't provide /tf or /tf_static for the extrinsics between imu and the cameras, so we add them here
make_static_transform_publisher_node(0., 0., 0.22, 3.1415926, 0., 0., 'base_link', 'imu_link'),
make_static_transform_publisher_node(-0.099307, -0.208806, 0.024309, 3.108592, -0.051480, -1.592415, 'imu_link', 'camera_left_color_optical_frame'),
make_static_transform_publisher_node(-0.435392, 0.022256, 0.053441, 1.532258, -0.007768, -1.580204, 'imu_link', 'camera_front_color_optical_frame'),
make_static_transform_publisher_node(-0.063987, 0.212966, 0.032071, -0.010030, 0.021977, -1.553814, 'imu_link', 'camera_right_color_optical_frame'),
make_static_transform_publisher_node(0.178893, -0.006307, 0.017677, -1.606156, 0.027545, -1.587179, 'imu_link', 'camera_rear_color_optical_frame'),
make_static_transform_publisher_node(0.045872, -0.026775, 0.284806, 3.141063, -0.014869, -0.014969, 'imu_link', 'os_sensor'),
rgbdx_sync_node,
rgbd_odometry_node,
slam_node,
viz_node
]
def generate_launch_description():
return LaunchDescription([
DeclareLaunchArgument('use_imu', default_value='false', description='Use IMU'),
SetParameter(name='use_sim_time', value=True),
OpaqueFunction(function=launch_setup),
])
@@ -37,6 +37,15 @@ def generate_launch_description():
# Make sure IR emitter is enabled
SetParameter(name='depth_module.emitter_enabled', value=1),
DeclareLaunchArgument(
'args', default_value='',
description='Extra arguments set to rtabmap and odometry nodes.'),
DeclareLaunchArgument(
'odom_args', default_value='',
description='Extra arguments just for odometry node. If the same argument is already set in \"args\", it will be overwritten by the one in \"odom_args\".'),
# Launch camera driver
IncludeLaunchDescription(
@@ -55,13 +64,14 @@ def generate_launch_description():
Node(
package='rtabmap_odom', executable='rgbd_odometry', output='screen',
parameters=parameters,
arguments=[LaunchConfiguration("args"), LaunchConfiguration("odom_args")],
remappings=remappings),
Node(
package='rtabmap_slam', executable='rtabmap', output='screen',
parameters=parameters,
remappings=remappings,
arguments=['-d']),
arguments=['-d', LaunchConfiguration("args")]),
Node(
package='rtabmap_viz', executable='rtabmap_viz', output='screen',
@@ -0,0 +1,130 @@
# Requirements:
# A realsense D435i
# Install realsense2 ros2 package (ros-$ROS_DISTRO-realsense2-camera)
# Example:
# $ ros2 launch rtabmap_examples realsense_d435i_color_composition.launch.py
#
# This is the "composition" variant of realsense_d435i_color.launch.py: the
# camera driver, IMU filter, RGB-D odometry and SLAM all run as composable
# nodes in a single component container (rtabmap_container) with
# use_intra_process_comms enabled, so messages can be passed by pointer instead
# of being serialized/copied between processes.
#
# As in the non-composed example, the color stream is used as RGB and paired
# with the depth aligned to color (align_depth.enable), with the IR emitter on.
#
# Notes:
# * Unlike the non-composed example, we do NOT include realsense2's rs_launch.py:
# that launch file always starts the camera as a standalone node and exposes
# no way to load it into an existing container. Instead we instantiate the
# camera component (realsense2_camera::RealSenseNodeFactory) ourselves, the
# same way realsense's own rs_intra_process_demo_launch.py does.
# * ComposableNode has no "arguments" field, so the args/odom_args/-d
# command-line mechanism of the non-composed example is not available here.
# To override rtabmap parameters, add them directly to the 'parameters' dict
# below. '-d' (delete database on start) becomes the 'delete_db_on_start'
# parameter.
#
import os
from ament_index_python.packages import get_package_share_directory
from launch import LaunchDescription
from launch.actions import DeclareLaunchArgument
from launch.substitutions import LaunchConfiguration
from launch.conditions import IfCondition
from launch_ros.actions import Node, ComposableNodeContainer
from launch_ros.descriptions import ComposableNode
def generate_launch_description():
parameters={
'frame_id':'camera_link',
'subscribe_depth':True,
'subscribe_odom_info':True,
'approx_sync':False,
'wait_imu_to_init':True}
remappings=[
('imu', '/imu/data'),
('rgb/image', '/camera/color/image_raw'),
('rgb/camera_info', '/camera/color/camera_info'),
('depth/image', '/camera/aligned_depth_to_color/image_raw')]
# Enable zero-copy intra-process communication on every composable node.
intra_process = [{'use_intra_process_comms': True}]
return LaunchDescription([
# Launch arguments
DeclareLaunchArgument(
'unite_imu_method', default_value='2',
description='0-None, 1-copy, 2-linear_interpolation. Use unite_imu_method:="1" if imu topics stop being published.'),
DeclareLaunchArgument(
'rtabmap_viz', default_value='true', description='Launch RTAB-Map UI (optional).'),
# Single component container holding the whole pipeline.
ComposableNodeContainer(
name='rtabmap_container',
namespace='',
package='rclcpp_components',
executable='component_container',
output='screen',
composable_node_descriptions=[
# Camera driver (replaces the rs_launch.py include).
ComposableNode(
package='realsense2_camera', plugin='realsense2_camera::RealSenseNodeFactory',
name='camera', namespace='',
parameters=[{
'enable_gyro': True,
'enable_accel': True,
'unite_imu_method': LaunchConfiguration('unite_imu_method'),
'align_depth.enable': True,
'enable_sync': True,
'rgb_camera.profile': '640x360x30',
'depth_module.emitter_enabled': 1}], # Make sure IR emitter is enabled
extra_arguments=intra_process),
# Compute quaternion of the IMU
ComposableNode(
package='imu_filter_madgwick', plugin='ImuFilterMadgwickRos',
name='imu_filter', namespace='',
parameters=[{'use_mag': False,
'world_frame':'enu',
'publish_tf':False}],
remappings=[('imu/data_raw', '/camera/imu')],
extra_arguments=intra_process),
# RGB-D odometry (color + depth aligned to color)
ComposableNode(
package='rtabmap_odom', plugin='rtabmap_odom::RGBDOdometry',
parameters=[parameters],
remappings=remappings,
extra_arguments=intra_process),
# SLAM
# Note: latch=False. rtabmap latches its map/cloud/octomap/mapGraph
# topics by default (transient_local QoS), which is incompatible
# with intra-process comms ("intraprocess communication allowed
# only with volatile durability"). latch=False makes them volatile
# so the node can join the zero-copy container.
ComposableNode(
package='rtabmap_slam', plugin='rtabmap_slam::CoreWrapper',
parameters=[parameters,
{'delete_db_on_start': True, # Equivalent of '-d'
'latch': False}],
remappings=remappings,
extra_arguments=intra_process),
]),
# Visualization:
# Note: rtabmap_viz is launched as a standalone node, not as a component.
# It is a Qt application and its UI must run in the process main thread,
# while components run in container worker threads, so it cannot be
# composed (the same applies to rviz2).
Node(
package='rtabmap_viz', executable='rtabmap_viz', output='screen',
condition=IfCondition(LaunchConfiguration('rtabmap_viz')),
parameters=[parameters],
remappings=remappings),
])
@@ -0,0 +1,106 @@
# Requirements:
# A realsense D435i
# Install realsense2 ros2 package (ros-$ROS_DISTRO-realsense2-camera)
# Example:
# $ ros2 launch rtabmap_examples realsense_d435i_combined.launch.py
#
# Description: In this example, we feed visual odometry with IR stereo images
# for better pose estimation while seding RGB-D data to slam for
# a colored map.
#
import os
from ament_index_python.packages import get_package_share_directory
from launch import LaunchDescription
from launch_ros.actions import Node, SetParameter
from launch.actions import IncludeLaunchDescription
from launch.actions import DeclareLaunchArgument, IncludeLaunchDescription
from launch.launch_description_sources import PythonLaunchDescriptionSource
from launch.substitutions import LaunchConfiguration
def generate_launch_description():
vo_parameters={
'frame_id':'camera_link',
'wait_imu_to_init':True}
vo_remappings=[
('imu', '/imu/data'),
('left/image_rect', '/camera/infra1/image_rect_raw'),
('left/camera_info', '/camera/infra1/camera_info'),
('right/image_rect', '/camera/infra2/image_rect_raw'),
('right/camera_info', '/camera/infra2/camera_info')]
slam_parameters={
'frame_id':'camera_link',
'subscribe_depth':True,
'subscribe_odom_info':True,
'approx_sync':False}
slam_remappings=[
('imu', '/imu/data'),
('rgb/image', '/camera/color/image_raw'),
('rgb/camera_info', '/camera/color/camera_info'),
('depth/image', '/camera/aligned_depth_to_color/image_raw')]
return LaunchDescription([
# Launch arguments
DeclareLaunchArgument(
'unite_imu_method', default_value='2',
description='0-None, 1-copy, 2-linear_interpolation. Use unite_imu_method:="1" if imu topics stop being published.'),
#Hack to disable IR emitter
SetParameter(name='depth_module.emitter_enabled', value=0),
DeclareLaunchArgument(
'args', default_value='',
description='Extra arguments set to rtabmap and odometry nodes.'),
DeclareLaunchArgument(
'odom_args', default_value='',
description='Extra arguments just for odometry node. If the same argument is already set in \"args\", it will be overwritten by the one in \"odom_args\".'),
# Launch camera driver
IncludeLaunchDescription(
PythonLaunchDescriptionSource([os.path.join(
get_package_share_directory('realsense2_camera'), 'launch'),
'/rs_launch.py']),
launch_arguments={'camera_namespace': '',
'enable_gyro': 'true',
'enable_accel': 'true',
'unite_imu_method': LaunchConfiguration('unite_imu_method'),
'enable_infra1': 'true',
'enable_infra2': 'true',
'align_depth.enable': 'true',
'enable_sync': 'true',
'rgb_camera.profile': '640x360x30'}.items(),
),
Node(
package='rtabmap_odom', executable='stereo_odometry', output='screen',
parameters=[vo_parameters],
arguments=[LaunchConfiguration("args"), LaunchConfiguration("odom_args")],
remappings=vo_remappings),
Node(
package='rtabmap_slam', executable='rtabmap', output='screen',
parameters=[slam_parameters],
remappings=slam_remappings,
arguments=['-d', LaunchConfiguration("args")]),
Node(
package='rtabmap_viz', executable='rtabmap_viz', output='screen',
parameters=[slam_parameters,
{'odometry_node_name': "stereo_odometry"}],
remappings=slam_remappings),
# Compute quaternion of the IMU
Node(
package='imu_filter_madgwick', executable='imu_filter_madgwick_node', output='screen',
parameters=[{'use_mag': False,
'world_frame':'enu',
'publish_tf':False}],
remappings=[('imu/data_raw', '/camera/imu')]),
])
@@ -35,6 +35,14 @@ def generate_launch_description():
DeclareLaunchArgument(
'unite_imu_method', default_value='2',
description='0-None, 1-copy, 2-linear_interpolation. Use unite_imu_method:="1" if imu topics stop being published.'),
DeclareLaunchArgument(
'args', default_value='',
description='Extra arguments set to rtabmap and odometry nodes.'),
DeclareLaunchArgument(
'odom_args', default_value='',
description='Extra arguments just for odometry node. If the same argument is already set in \"args\", it will be overwritten by the one in \"odom_args\".'),
#Hack to disable IR emitter
SetParameter(name='depth_module.emitter_enabled', value=0),
@@ -56,13 +64,14 @@ def generate_launch_description():
Node(
package='rtabmap_odom', executable='rgbd_odometry', output='screen',
parameters=parameters,
arguments=[LaunchConfiguration("args"), LaunchConfiguration("odom_args")],
remappings=remappings),
Node(
package='rtabmap_slam', executable='rtabmap', output='screen',
parameters=parameters,
remappings=remappings,
arguments=['-d']),
arguments=['-d', LaunchConfiguration("args")]),
Node(
package='rtabmap_viz', executable='rtabmap_viz', output='screen',
@@ -0,0 +1,132 @@
# Requirements:
# A realsense D435i
# Install realsense2 ros2 package (ros-$ROS_DISTRO-realsense2-camera)
# Example:
# $ ros2 launch rtabmap_examples realsense_d435i_infra_composition.launch.py
#
# This is the "composition" variant of realsense_d435i_infra.launch.py: the
# camera driver, IMU filter, RGB-D odometry and SLAM all run as composable
# nodes in a single component container (rtabmap_container) with
# use_intra_process_comms enabled, so messages can be passed by pointer instead
# of being serialized/copied between processes.
#
# As in the non-composed example, the left infrared image (infra1) is used as
# the grayscale "RGB" input and paired with the depth stream. This works because
# on the D435i the depth is computed in the left-infrared frame, so infra1 and
# depth share the same intrinsics/frame (already registered, no align needed).
#
# Notes:
# * Unlike the non-composed example, we do NOT include realsense2's rs_launch.py:
# that launch file always starts the camera as a standalone node and exposes
# no way to load it into an existing container. Instead we instantiate the
# camera component (realsense2_camera::RealSenseNodeFactory) ourselves, the
# same way realsense's own rs_intra_process_demo_launch.py does.
# * ComposableNode has no "arguments" field, so the args/odom_args/-d
# command-line mechanism of the non-composed example is not available here.
# To override rtabmap parameters, add them directly to the 'parameters' dict
# below. '-d' (delete database on start) becomes the 'delete_db_on_start'
# parameter.
#
import os
from ament_index_python.packages import get_package_share_directory
from launch import LaunchDescription
from launch.actions import DeclareLaunchArgument
from launch.substitutions import LaunchConfiguration
from launch.conditions import IfCondition
from launch_ros.actions import Node, ComposableNodeContainer
from launch_ros.descriptions import ComposableNode
def generate_launch_description():
parameters={
'frame_id':'camera_link',
'subscribe_depth':True,
'subscribe_odom_info':True,
'approx_sync':False,
'wait_imu_to_init':True}
remappings=[
('imu', '/imu/data'),
('rgb/image', '/camera/infra1/image_rect_raw'),
('rgb/camera_info', '/camera/infra1/camera_info'),
('depth/image', '/camera/depth/image_rect_raw')]
# Enable zero-copy intra-process communication on every composable node.
intra_process = [{'use_intra_process_comms': True}]
return LaunchDescription([
# Launch arguments
DeclareLaunchArgument(
'unite_imu_method', default_value='2',
description='0-None, 1-copy, 2-linear_interpolation. Use unite_imu_method:="1" if imu topics stop being published.'),
DeclareLaunchArgument(
'rtabmap_viz', default_value='true', description='Launch RTAB-Map UI (optional).'),
# Single component container holding the whole pipeline.
ComposableNodeContainer(
name='rtabmap_container',
namespace='',
package='rclcpp_components',
executable='component_container',
output='screen',
composable_node_descriptions=[
# Camera driver (replaces the rs_launch.py include).
ComposableNode(
package='realsense2_camera', plugin='realsense2_camera::RealSenseNodeFactory',
name='camera', namespace='',
parameters=[{
'enable_gyro': True,
'enable_accel': True,
'unite_imu_method': LaunchConfiguration('unite_imu_method'),
'enable_infra1': True,
'enable_infra2': True,
'enable_sync': True,
'depth_module.emitter_enabled': 0}], # Hack to disable IR emitter
extra_arguments=intra_process),
# Compute quaternion of the IMU
ComposableNode(
package='imu_filter_madgwick', plugin='ImuFilterMadgwickRos',
name='imu_filter', namespace='',
parameters=[{'use_mag': False,
'world_frame':'enu',
'publish_tf':False}],
remappings=[('imu/data_raw', '/camera/imu')],
extra_arguments=intra_process),
# RGB-D odometry (infra1 as grayscale RGB + depth)
ComposableNode(
package='rtabmap_odom', plugin='rtabmap_odom::RGBDOdometry',
parameters=[parameters],
remappings=remappings,
extra_arguments=intra_process),
# SLAM
# Note: latch=False. rtabmap latches its map/cloud/octomap/mapGraph
# topics by default (transient_local QoS), which is incompatible
# with intra-process comms ("intraprocess communication allowed
# only with volatile durability"). latch=False makes them volatile
# so the node can join the zero-copy container.
ComposableNode(
package='rtabmap_slam', plugin='rtabmap_slam::CoreWrapper',
parameters=[parameters,
{'delete_db_on_start': True, # Equivalent of '-d'
'latch': False}],
remappings=remappings,
extra_arguments=intra_process),
]),
# Visualization:
# Note: rtabmap_viz is launched as a standalone node, not as a component.
# It is a Qt application and its UI must run in the process main thread,
# while components run in container worker threads, so it cannot be
# composed (the same applies to rviz2).
Node(
package='rtabmap_viz', executable='rtabmap_viz', output='screen',
condition=IfCondition(LaunchConfiguration('rtabmap_viz')),
parameters=[parameters],
remappings=remappings),
])
@@ -3,7 +3,21 @@
# Install realsense2 ros2 package (ros-$ROS_DISTRO-realsense2-camera)
# Example:
# $ ros2 launch rtabmap_examples realsense_d435i_stereo.launch.py
#
#
#
#
# VINS-Fusion example:
# Add to your ros2 workspace the package https://github.com/zinuok/VINS-Fusion-ROS2
# Apply this patch https://gist.github.com/matlabbe/ebbb343cd744da9d6d6d6ded2e1557fd
# -> Revert "#define USE_GPU" change if you want to build VINS-Fusion with GPU support.
# That may be counterintuitive, but we need to build VINS-Fusion first, then rebuild rtabmap with VINS-Fusion support.
# -> in your ros2 workspace, do "colcon build --packages-select vins"
# -> go back under rtabmap library repo, then rebuild/install with "cmake -DWITH_VINS_FUSION=ON ..."
# -> do "colcon build" in your ros2 workspace again to rebuild rtabmap_ros
# $ ros2 launch rtabmap_examples realsense_d435i_stereo.launch.py odom_args:="--Odom/Strategy 9 OdomVINSFusion/ConfigPath ~/ros2_ws/src/VINS-Fusion-ROS2/config/realsense_d435i/realsense_stereo_imu_config.yaml"
# -> set "imu: 1" in realsense_stereo_imu_config.yaml to do stereo inertial odometry, otherwise only stereo odometry is done.
#
import os
from ament_index_python.packages import get_package_share_directory
@@ -16,11 +30,11 @@ from launch.launch_description_sources import PythonLaunchDescriptionSource
from launch.substitutions import LaunchConfiguration
def generate_launch_description():
parameters=[{
parameters={
'frame_id':'camera_link',
'subscribe_stereo':True,
'subscribe_odom_info':True,
'wait_imu_to_init':True}]
'wait_imu_to_init':True}
remappings=[
('imu', '/imu/data'),
@@ -38,6 +52,15 @@ def generate_launch_description():
#Hack to disable IR emitter
SetParameter(name='depth_module.emitter_enabled', value=0),
DeclareLaunchArgument(
'args', default_value='',
description='Extra arguments set to rtabmap and odometry nodes.'),
DeclareLaunchArgument(
'odom_args', default_value='',
description='Extra arguments just for odometry node. If the same argument is already set in \"args\", it will be overwritten by the one in \"odom_args\".'),
# Launch camera driver
IncludeLaunchDescription(
@@ -55,18 +78,20 @@ def generate_launch_description():
Node(
package='rtabmap_odom', executable='stereo_odometry', output='screen',
parameters=parameters,
parameters=[parameters],
arguments=[LaunchConfiguration("args"), LaunchConfiguration("odom_args")],
remappings=remappings),
Node(
package='rtabmap_slam', executable='rtabmap', output='screen',
parameters=parameters,
parameters=[parameters],
remappings=remappings,
arguments=['-d']),
arguments=['-d', LaunchConfiguration("args")]),
Node(
package='rtabmap_viz', executable='rtabmap_viz', output='screen',
parameters=parameters,
parameters=[parameters,
{'odometry_node_name': "stereo_odometry"}],
remappings=remappings),
# Compute quaternion of the IMU
@@ -0,0 +1,128 @@
# Requirements:
# A realsense D435i
# Install realsense2 ros2 package (ros-$ROS_DISTRO-realsense2-camera)
# Example:
# $ ros2 launch rtabmap_examples realsense_d435i_stereo_composition.launch.py
#
# This is the "composition" variant of realsense_d435i_stereo.launch.py: the
# camera driver, IMU filter, stereo odometry and SLAM all run as composable
# nodes in a single component container (rtabmap_container) with
# use_intra_process_comms enabled, so messages can be passed by pointer instead
# of being serialized/copied between processes.
#
# Notes:
# * Unlike the non-composed example, we do NOT include realsense2's rs_launch.py:
# that launch file always starts the camera as a standalone node and exposes
# no way to load it into an existing container. Instead we instantiate the
# camera component (realsense2_camera::RealSenseNodeFactory) ourselves, the
# same way realsense's own rs_intra_process_demo_launch.py does.
# * ComposableNode has no "arguments" field, so the args/odom_args/-d
# command-line mechanism of the non-composed example is not available here.
# To override rtabmap parameters, add them directly to the 'parameters' dict
# below. '-d' (delete database on start) becomes the 'delete_db_on_start'
# parameter.
#
import os
from ament_index_python.packages import get_package_share_directory
from launch import LaunchDescription
from launch.actions import DeclareLaunchArgument
from launch.substitutions import LaunchConfiguration
from launch.conditions import IfCondition
from launch_ros.actions import Node, ComposableNodeContainer
from launch_ros.descriptions import ComposableNode
def generate_launch_description():
parameters={
'frame_id':'camera_link',
'subscribe_stereo':True,
'subscribe_odom_info':True,
'wait_imu_to_init':True}
remappings=[
('imu', '/imu/data'),
('left/image_rect', '/camera/infra1/image_rect_raw'),
('left/camera_info', '/camera/infra1/camera_info'),
('right/image_rect', '/camera/infra2/image_rect_raw'),
('right/camera_info', '/camera/infra2/camera_info')]
# Enable zero-copy intra-process communication on every composable node.
intra_process = [{'use_intra_process_comms': True}]
return LaunchDescription([
# Launch arguments
DeclareLaunchArgument(
'unite_imu_method', default_value='2',
description='0-None, 1-copy, 2-linear_interpolation. Use unite_imu_method:="1" if imu topics stop being published.'),
DeclareLaunchArgument(
'rtabmap_viz', default_value='true', description='Launch RTAB-Map UI (optional).'),
# Single component container holding the whole pipeline.
ComposableNodeContainer(
name='rtabmap_container',
namespace='',
package='rclcpp_components',
executable='component_container',
output='screen',
composable_node_descriptions=[
# Camera driver (replaces the rs_launch.py include).
ComposableNode(
package='realsense2_camera', plugin='realsense2_camera::RealSenseNodeFactory',
name='camera', namespace='',
parameters=[{
'enable_gyro': True,
'enable_accel': True,
'unite_imu_method': LaunchConfiguration('unite_imu_method'),
'enable_infra1': True,
'enable_infra2': True,
'enable_sync': True,
'depth_module.emitter_enabled': 0}], # Hack to disable IR emitter
extra_arguments=intra_process),
# Compute quaternion of the IMU
ComposableNode(
package='imu_filter_madgwick', plugin='ImuFilterMadgwickRos',
name='imu_filter', namespace='',
parameters=[{'use_mag': False,
'world_frame':'enu',
'publish_tf':False}],
remappings=[('imu/data_raw', '/camera/imu')],
extra_arguments=intra_process),
# Stereo odometry
ComposableNode(
package='rtabmap_odom', plugin='rtabmap_odom::StereoOdometry',
parameters=[parameters],
remappings=remappings,
extra_arguments=intra_process),
# SLAM
# Note: latch=False. rtabmap latches its map/cloud/octomap/mapGraph
# topics by default (transient_local QoS), which is incompatible
# with intra-process comms ("intraprocess communication allowed
# only with volatile durability"). latch=False makes them volatile
# so the node can join the zero-copy container.
ComposableNode(
package='rtabmap_slam', plugin='rtabmap_slam::CoreWrapper',
parameters=[parameters,
{'delete_db_on_start': True, # Equivalent of '-d'
'latch': False}],
remappings=remappings,
extra_arguments=intra_process),
]),
# Visualization:
# Note: rtabmap_viz is launched as a standalone node, not as a component.
# It is a Qt application and its UI must run in the process main thread,
# while components run in container worker threads, so it cannot be
# composed (the same applies to rviz2).
Node(
package='rtabmap_viz', executable='rtabmap_viz', output='screen',
condition=IfCondition(LaunchConfiguration('rtabmap_viz')),
parameters=[parameters,
{'odometry_node_name': "stereo_odometry"}],
remappings=remappings),
])
@@ -74,7 +74,6 @@ def generate_launch_description():
remappings=[
("rgbd_image", '/realsense_camera1/rgbd_image'),
("odom", 'odom')],
arguments=["--delete_db_on_start", ''],
prefix='',
namespace='rtabmap'
)
@@ -88,7 +88,6 @@ def generate_launch_description():
remappings=[
("rgbd_image", '/realsense_camera1/rgbd_image'),
("odom", 'odom')],
arguments=["--delete_db_on_start", ''],
prefix='',
namespace='rtabmap'
)
+20 -6
View File
@@ -23,13 +23,26 @@ remappings = []
def launch_setup(context: LaunchContext, *args, **kwargs):
# Hack to override grab_resolution parameter without changing any files
use_zed_odometry = LaunchConfiguration('use_zed_odometry').perform(context) in ["True", "true"]
# Override some ZED parameters without changing any files:
# * grab_resolution: VGA
# * pos_tracking_enabled: disabled when rtabmap computes the odometry, so
# the ZED node does not publish the odom->camera_link TF (which would
# conflict with rtabmap's odometry). We still set publish_tf:=true below
# so the ZED node keeps broadcasting the IMU TF, which rtabmap needs
# (wait_imu_to_init). sensors.publish_imu_tf is ignored when publish_tf
# is false, and the IMU frame is not in the ZED URDF, so this is the only
# way to get the IMU TF while rtabmap owns the odometry.
pos_tracking_enabled = 'true' if use_zed_odometry else 'false'
with tempfile.NamedTemporaryFile(mode='w+t', delete=False) as zed_override_file:
zed_override_file.write("---\n"+
"/**:\n"+
" ros__parameters:\n"+
" general:\n"+
" grab_resolution: 'VGA'")
" grab_resolution: 'VGA'\n"+
" pos_tracking:\n"+
" pos_tracking_enabled: "+pos_tracking_enabled)
parameters=[{'frame_id':'zed_camera_link',
'subscribe_rgbd':True,
@@ -38,7 +51,7 @@ def launch_setup(context: LaunchContext, *args, **kwargs):
remappings=[('imu', '/zed/zed_node/imu/data')]
if LaunchConfiguration('use_zed_odometry').perform(context) in ["True", "true"]:
if use_zed_odometry:
remappings.append(('odom', '/zed/zed_node/odom'))
else:
parameters.append({'subscribe_odom_info': True})
@@ -51,7 +64,8 @@ def launch_setup(context: LaunchContext, *args, **kwargs):
'/zed_camera.launch.py']),
launch_arguments={'camera_model': LaunchConfiguration('camera_model'),
'ros_params_override_path': zed_override_file.name,
'publish_tf': LaunchConfiguration('use_zed_odometry'),
'publish_tf': 'true',
'publish_imu_tf': 'true',
'publish_map_tf': 'false'}.items(),
),
@@ -59,8 +73,8 @@ def launch_setup(context: LaunchContext, *args, **kwargs):
Node(
package='rtabmap_sync', executable='rgbd_sync', output='screen',
parameters=parameters,
remappings=[('rgb/image', '/zed/zed_node/rgb/image_rect_color'),
('rgb/camera_info', '/zed/zed_node/rgb/camera_info'),
remappings=[('rgb/image', '/zed/zed_node/rgb/color/rect/image'),
('rgb/camera_info', '/zed/zed_node/rgb/color/rect/camera_info'),
('depth/image', '/zed/zed_node/depth/depth_registered')]),
# Visual odometry
@@ -0,0 +1,164 @@
# Requirements:
# A ZED camera
# Install zed ros2 wrapper package (https://github.com/stereolabs/zed-ros2-wrapper)
# Example:
# $ ros2 launch rtabmap_examples zed_composition.launch.py camera_model:=zed2i
#
# This is the "composition" variant of zed.launch.py: the ZED driver, RGB-D
# synchronization, visual odometry and SLAM all run as composable nodes in a
# single component container with use_intra_process_comms enabled, so messages
# can be passed by pointer instead of being serialized/copied between processes.
#
# Notes:
# * The ZED wrapper's zed_camera.launch.py already creates its own component
# container ("zed_container") and loads the ZedCamera component into it with
# intra-process comms enabled by default (enable_ipc:=true). So instead of
# creating our own container, we let the ZED wrapper create it and load the
# rtabmap nodes into the SAME container (/zed/zed_container) with
# LoadComposableNodes. This assumes the default ZED namespace ("zed"), which
# is independent of camera_model.
# * ComposableNode has no "arguments" or "condition" field. So the '-d'
# argument becomes the 'delete_db_on_start' parameter, and the conditional
# odometry node is included in Python depending on use_zed_odometry.
#
import os
from ament_index_python.packages import get_package_share_directory
from launch import LaunchDescription, LaunchContext
from launch.actions import DeclareLaunchArgument
from launch_ros.actions import Node, LoadComposableNodes
from launch_ros.descriptions import ComposableNode
from launch.actions import IncludeLaunchDescription, OpaqueFunction
from launch.substitutions import LaunchConfiguration
from launch.launch_description_sources import PythonLaunchDescriptionSource
import tempfile
def launch_setup(context: LaunchContext, *args, **kwargs):
use_zed_odometry = LaunchConfiguration('use_zed_odometry').perform(context) in ["True", "true"]
# Override some ZED parameters without changing any files:
# * grab_resolution: VGA
# * pos_tracking_enabled: disabled when rtabmap computes the odometry, so
# the ZED node does not publish the odom->camera_link TF (which would
# conflict with rtabmap's odometry). We still set publish_tf:=true below
# so the ZED node keeps broadcasting the IMU TF, which rtabmap needs
# (wait_imu_to_init). sensors.publish_imu_tf is ignored when publish_tf
# is false, and the IMU frame is not in the ZED URDF, so this is the only
# way to get the IMU TF while rtabmap owns the odometry.
pos_tracking_enabled = 'true' if use_zed_odometry else 'false'
with tempfile.NamedTemporaryFile(mode='w+t', delete=False) as zed_override_file:
zed_override_file.write("---\n"+
"/**:\n"+
" ros__parameters:\n"+
" general:\n"+
" grab_resolution: 'VGA'\n"+
" pos_tracking:\n"+
" pos_tracking_enabled: "+pos_tracking_enabled)
# ZED topics are /zed/zed_node/* and the container created by the wrapper is
# /zed/zed_container (default ZED namespace "zed").
zed_ns = '/zed/zed_node'
zed_container = '/zed/zed_container'
parameters=[{'frame_id':'zed_camera_link',
'subscribe_rgbd':True,
'approx_sync':False,
'wait_imu_to_init':True}]
remappings=[('imu', zed_ns + '/imu/data')]
if use_zed_odometry:
remappings.append(('odom', zed_ns + '/odom'))
else:
parameters.append({'subscribe_odom_info': True})
# Enable zero-copy intra-process communication on every composable node.
intra_process = [{'use_intra_process_comms': True}]
# rtabmap nodes loaded into the ZED container.
composable_nodes = [
# Sync rgb/depth/camera_info together
ComposableNode(
package='rtabmap_sync', plugin='rtabmap_sync::RGBDSync',
parameters=parameters,
remappings=[('rgb/image', zed_ns + '/rgb/color/rect/image'),
('rgb/camera_info', zed_ns + '/rgb/color/rect/camera_info'),
('depth/image', zed_ns + '/depth/depth_registered')],
extra_arguments=intra_process),
]
# Visual odometry (only when not using ZED's own odometry). ComposableNode
# has no 'condition', so we add it here based on use_zed_odometry.
if not use_zed_odometry:
composable_nodes.append(
ComposableNode(
package='rtabmap_odom', plugin='rtabmap_odom::RGBDOdometry',
parameters=parameters,
remappings=remappings,
extra_arguments=intra_process))
# VSLAM
# Note: latch=False. rtabmap latches its map/cloud/octomap/mapGraph topics
# by default (transient_local QoS), which is incompatible with intra-process
# comms ("intraprocess communication allowed only with volatile durability").
# latch=False makes them volatile so the node can join the container.
composable_nodes.append(
ComposableNode(
package='rtabmap_slam', plugin='rtabmap_slam::CoreWrapper',
parameters=parameters + [{'delete_db_on_start': True, # Equivalent of '-d'
'latch': False}],
remappings=remappings,
extra_arguments=intra_process))
return [
# Launch camera driver. It creates the "zed_container" component
# container (enable_ipc:=true by default) and loads the ZedCamera
# component into it.
IncludeLaunchDescription(
PythonLaunchDescriptionSource([os.path.join(
get_package_share_directory('zed_wrapper'), 'launch'),
'/zed_camera.launch.py']),
launch_arguments={'camera_model': LaunchConfiguration('camera_model'),
'ros_params_override_path': zed_override_file.name,
# publish_tf must be true so the ZED node broadcasts the
# IMU TF (gated by publish_tf). The odom->camera_link TF is
# disabled via pos_tracking_enabled=false (override file)
# when rtabmap computes the odometry.
'publish_tf': 'true',
'publish_imu_tf': 'true',
'publish_map_tf': 'false'}.items(),
),
# Load the rtabmap pipeline into the ZED container.
LoadComposableNodes(
target_container=zed_container,
composable_node_descriptions=composable_nodes),
# Visualization
# Note: rtabmap_viz is a Qt application; its UI must run in the process
# main thread, while components run in container worker threads. So it
# cannot be composed and stays a standalone node.
Node(
package='rtabmap_viz', executable='rtabmap_viz', output='screen',
parameters=parameters,
remappings=remappings)
]
def generate_launch_description():
return LaunchDescription([
# Launch arguments
DeclareLaunchArgument(
'use_zed_odometry', default_value='false',
description='Use zed\'s computed odometry instead of using rtabmap\'s odometry.'),
DeclareLaunchArgument(
'camera_model', default_value='',
description="[REQUIRED] The model of the camera. Using a wrong camera model can disable camera features. Valid choices are: ['zed', 'zedm', 'zed2', 'zed2i', 'zedx', 'zedxm', 'virtual']"),
OpaqueFunction(function=launch_setup)
])
+1 -1
View File
@@ -2,7 +2,7 @@
<?xml-model href="http://download.ros.org/schema/package_format3.xsd" schematypens="http://www.w3.org/2001/XMLSchema"?>
<package format="3">
<name>rtabmap_examples</name>
<version>0.22.1</version>
<version>0.23.7</version>
<description>RTAB-Map's example launch files.</description>
<maintainer email="[email protected]">Mathieu Labbe</maintainer>
<author>Mathieu Labbe</author>