Skip to content

Commit b1ca37e

Browse files
committed
add lidar sensor and use obstacle_layer in costmap params
1 parent f064b5d commit b1ca37e

10 files changed

Lines changed: 246 additions & 59 deletions

File tree

src/hangar_sim/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ pluginlib_export_plugin_description_file(
2525
install(PROGRAMS
2626
script/odometry_joint_state_publisher.py
2727
script/odom_qos_relay.py
28+
script/scan_mirror_fix.py
2829
DESTINATION lib/${PROJECT_NAME}
2930
)
3031

src/hangar_sim/config/config.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ hardware:
2020
package: "hangar_sim"
2121
path: "config/moveit/joint_limits.yaml"
2222
- mujoco_model: "description/hangar_scene.xml"
23+
- mujoco_viewer: "false"
2324

2425
# Specify any additional launch files for running the robot in simulation mode.
2526
# Used when hardware.simulated is True.

src/hangar_sim/description/hangar_scene.xml

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -14,17 +14,16 @@
1414
</visual>
1515

1616
<worldbody>
17-
<!-- Scene Camera -->
18-
<site
17+
<site
1918
name="scene_camera_optical_frame"
2019
pos="-14.4207 -4.39686 9.04094"
21-
quat="0.415847 -0.883719 0.194298 -0.09143"
20+
quat="0 0.7071 -0.7071 0"
2221
/>
2322
<camera
2423
name="scene_camera"
2524
pos="-14.4207 -4.39686 9.04094"
26-
quat="0.883719 0.415847 -0.09143 -0.194298"
27-
fovy="45"
25+
quat="0.7071 0 0 -0.7071"
26+
fovy="75"
2827
mode="fixed"
2928
resolution="1280 720"
3029
/>

src/hangar_sim/description/ur5e_ridgeback.xml

Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33

44
<option integrator="implicitfast" />
55

6+
<size nuser_sensor="6" />
7+
68
<default>
79
<default class="ur5e">
810
<material specular="0.5" shininess="0.25" />
@@ -208,6 +210,87 @@
208210
<joint name="rotational_yaw_joint" type="hinge" axis="0 0 1" />
209211
<body name="base_platform" pos="0 0 0" euler="0 0 0">
210212
<body name="ridgeback_base_link">
213+
<!-- Front SICK TIM571: mounted at x=+0.45m (front bumper), z=0.15m.
214+
31 beams × 9 deg = 270 deg FOV, sweeping CCW from beam-0 at -135 deg.
215+
quat="0.6533 0.2706 -0.6533 0.2706": beam-0 +Z fires at -135 deg from +X. -->
216+
<body name="lidar_front_mount" pos="0.45 0 0.15">
217+
<inertial
218+
mass="0.25"
219+
pos="0 0 0"
220+
diaginertia="0.0001 0.0001 0.0001"
221+
/>
222+
<replicate count="31" sep="-" offset="0 0 0" euler="0 0 0.15708">
223+
<site
224+
name="lidar_front"
225+
size="0.01"
226+
pos="0 0 0"
227+
quat="0.6533 0.2706 -0.6533 0.2706"
228+
/>
229+
</replicate>
230+
<!-- TIM571 body: dark cylinder, visual-only -->
231+
<geom
232+
name="lidar_front_body"
233+
type="cylinder"
234+
size="0.030 0.042"
235+
pos="0 0 0"
236+
rgba="0.2 0.2 0.2 1"
237+
contype="0"
238+
conaffinity="0"
239+
group="2"
240+
/>
241+
<!-- Scan plane: cyan disk showing sweep area -->
242+
<geom
243+
name="lidar_front_scan_plane"
244+
type="cylinder"
245+
size="0.30 0.002"
246+
pos="0 0 0"
247+
rgba="0 1 1 0.3"
248+
contype="0"
249+
conaffinity="0"
250+
group="2"
251+
/>
252+
</body>
253+
254+
<!-- Rear SICK TIM571: mounted at x=-0.45m (rear bumper), z=0.15m.
255+
31 beams × 9 deg = 270 deg FOV, sweeping CCW from beam-0 at +45 deg.
256+
quat="0.2706 -0.6533 -0.2706 -0.6533": beam-0 +Z fires at +45 deg from +X. -->
257+
<body name="lidar_rear_mount" pos="-0.45 0 0.15">
258+
<inertial
259+
mass="0.25"
260+
pos="0 0 0"
261+
diaginertia="0.0001 0.0001 0.0001"
262+
/>
263+
<replicate count="31" sep="-" offset="0 0 0" euler="0 0 0.15708">
264+
<site
265+
name="lidar_rear"
266+
size="0.01"
267+
pos="0 0 0"
268+
quat="0.2706 -0.6533 -0.2706 -0.6533"
269+
/>
270+
</replicate>
271+
<!-- TIM571 body: dark cylinder, visual-only -->
272+
<geom
273+
name="lidar_rear_body"
274+
type="cylinder"
275+
size="0.030 0.042"
276+
pos="0 0 0"
277+
rgba="0.2 0.2 0.2 1"
278+
contype="0"
279+
conaffinity="0"
280+
group="2"
281+
/>
282+
<!-- Scan plane: magenta disk showing sweep area -->
283+
<geom
284+
name="lidar_rear_scan_plane"
285+
type="cylinder"
286+
size="0.30 0.002"
287+
pos="0 0 0"
288+
rgba="1 0 1 0.3"
289+
contype="0"
290+
conaffinity="0"
291+
group="2"
292+
/>
293+
</body>
211294
<geom
212295
name="chassis_link"
213296
mesh="chassis_link"
@@ -586,5 +669,15 @@
586669
<framequat objtype="site" objname="imu_site" />
587670
<gyro site="imu_site" />
588671
<accelerometer site="imu_site" />
672+
<!-- Front TIM571: 270 deg FOV, 9 deg resolution (31 beams), 0.05-25m range -->
673+
<rangefinder
674+
site="lidar_front"
675+
user="0.05 -2.35619 2.35619 0.15708 0.05 25.0"
676+
/>
677+
<!-- Rear TIM571: same specs, mounted facing backward for 360 deg coverage -->
678+
<rangefinder
679+
site="lidar_rear"
680+
user="0.05 -2.35619 2.35619 0.15708 0.05 25.0"
681+
/>
589682
</sensor>
590683
</mujoco>

src/hangar_sim/launch/sim/localization_launch.py

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ def generate_launch_description():
5656
use_respawn = LaunchConfiguration("use_respawn")
5757
log_level = LaunchConfiguration("log_level")
5858

59-
lifecycle_nodes = ["map_server", "amcl"]
59+
lifecycle_nodes = ["map_server"]
6060

6161
# Map fully qualified names to relative ones so the node's namespace can be prepended.
6262
# In case of the transforms (tf), currently, there doesn't seem to be a better alternative
@@ -181,13 +181,6 @@ def generate_launch_description():
181181
parameters=[configured_params],
182182
remappings=remappings,
183183
),
184-
ComposableNode(
185-
package="nav2_amcl",
186-
plugin="nav2_amcl::AmclNode",
187-
name="amcl",
188-
parameters=[configured_params],
189-
remappings=remappings,
190-
),
191184
ComposableNode(
192185
package="nav2_lifecycle_manager",
193186
plugin="nav2_lifecycle_manager::LifecycleManager",

src/hangar_sim/launch/sim/robot_drivers_to_persist_sim.launch.py

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -284,8 +284,38 @@ def generate_launch_description():
284284
output="log",
285285
)
286286

287-
# Fuse state estimator for mobile base localization
288287
hangar_sim_pkg = FindPackageShare("hangar_sim")
288+
289+
# Reverses the ranges array in /scan to correct the Y-axis flip caused by the
290+
# MuJoCo lidar plugin's 180-deg roll in the lidar_*_ROS TF frames.
291+
scan_mirror_fix = Node(
292+
package="hangar_sim",
293+
executable="scan_mirror_fix.py",
294+
name="scan_mirror_fix",
295+
output="log",
296+
)
297+
298+
# Angular bounds filter: clips chassis self-hitting beams (±93° to ±135°) from
299+
# /scan_mirrored, publishes clean scan to /scan_filtered for Nav2 costmap.
300+
laser_filter_node = Node(
301+
package="laser_filters",
302+
executable="scan_to_scan_filter_chain",
303+
name="laser_angular_filter",
304+
parameters=[
305+
PathJoinSubstitution(
306+
[hangar_sim_pkg, "params", "laser_filter_params.yaml"]
307+
),
308+
{"use_sim_time": use_sim_time},
309+
{"qos_overrides./scan_mirrored.subscription.reliability": "best_effort"},
310+
],
311+
remappings=[
312+
("scan", "/scan_mirrored"),
313+
("scan_filtered", "/scan_filtered"),
314+
],
315+
output="log",
316+
)
317+
318+
# Fuse state estimator for mobile base localization
289319
fuse_state_estimator = Node(
290320
package="fuse_optimizers",
291321
executable="fixed_lag_smoother_node",
@@ -326,6 +356,8 @@ def generate_launch_description():
326356
ld.add_action(static_tf_map_to_odom)
327357
ld.add_action(odom_to_joint_state_repub)
328358
ld.add_action(odom_qos_relay)
359+
ld.add_action(scan_mirror_fix)
360+
ld.add_action(laser_filter_node)
329361
ld.add_action(fuse_state_estimator)
330362

331363
return ld

src/hangar_sim/package.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
<exec_depend>moveit_ros_perception</exec_depend>
2020
<exec_depend>moveit_studio_agent</exec_depend>
2121
<exec_depend>moveit_pro_behavior</exec_depend>
22+
<exec_depend>laser_filters</exec_depend>
2223
<exec_depend>nav2_bringup</exec_depend>
2324
<exec_depend>picknik_accessories</exec_depend>
2425
<exec_depend>picknik_mujoco_ros</exec_depend>
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
# Angular bounds filter for the dual SICK TIM571 lidars.
2+
#
3+
# Both lidars (lidar_front_ROS and lidar_rear_ROS) publish to /scan.
4+
# Each covers -135 deg to +135 deg. Beams from +/-93 deg to +/-135 deg
5+
# point backward past the chassis edges and produce self-hits.
6+
#
7+
# This filter keeps only beams within +/-93 deg (-1.6231 to 1.6231 rad),
8+
# removing the self-hitting beams at the edges. Combined, both lidars
9+
# give 360 deg coverage.
10+
laser_angular_filter:
11+
ros__parameters:
12+
filter1:
13+
name: angular_bounds
14+
type: laser_filters/LaserScanAngularBoundsFilter
15+
params:
16+
lower_angle: -1.6231
17+
upper_angle: 1.6231

src/hangar_sim/params/nav2_params.yaml

Lines changed: 38 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -126,7 +126,7 @@ controller_server:
126126
progress_checker:
127127
plugin: "nav2_controller::SimpleProgressChecker"
128128
required_movement_radius: 0.5
129-
movement_time_allowance: 10.0
129+
movement_time_allowance: 20.0
130130
# Goal checker parameters
131131
#precise_goal_checker:
132132
# plugin: "nav2_controller::SimpleGoalChecker"
@@ -142,7 +142,7 @@ controller_server:
142142
plugin: "nav2_mppi_controller::MPPIController"
143143
time_steps: 56
144144
model_dt: 0.05
145-
batch_size: 2000
145+
batch_size: 500
146146
vx_std: 0.2
147147
vy_std: 0.2
148148
wz_std: 0.4
@@ -241,41 +241,36 @@ local_costmap:
241241
robot_base_frame: ridgeback_base_link
242242
use_sim_time: True
243243
rolling_window: true
244-
width: 3
245-
height: 3
244+
width: 10
245+
height: 10
246246
resolution: 0.05
247247
footprint: "[[0.45, 0.375], [0.45, -0.375], [-0.45, -0.375], [-0.45, 0.375]]"
248248
footprint_padding: 0.025
249-
plugins: ["voxel_layer", "inflation_layer"]
249+
plugins: ["obstacle_layer", "inflation_layer"]
250250
inflation_layer:
251251
plugin: "nav2_costmap_2d::InflationLayer"
252-
cost_scaling_factor: 1.50
253-
inflation_radius: 2.2
254-
voxel_layer:
255-
plugin: "nav2_costmap_2d::VoxelLayer"
252+
cost_scaling_factor: 3.0
253+
inflation_radius: 0.75
254+
obstacle_layer:
255+
plugin: "nav2_costmap_2d::ObstacleLayer"
256256
enabled: True
257-
publish_voxel_map: True
258-
origin_z: 0.0
259-
z_resolution: 0.1
260-
z_voxels: 16
261-
max_obstacle_height: 3.0
262-
mark_threshold: 1
263-
observation_sources: pointcloud
264-
pointcloud:
265-
topic: /left_camera/points
266-
max_obstacle_height: 3.0
257+
observation_sources: scan
258+
scan:
259+
topic: /scan_filtered
260+
max_obstacle_height: 2.0
267261
clearing: True
268262
marking: True
269-
raytrace_max_range: 3.0
263+
data_type: "LaserScan"
264+
raytrace_max_range: 10.0
270265
raytrace_min_range: 0.0
271-
obstacle_max_range: 2.5
272-
obstacle_min_range: 0.0
273-
data_type: "PointCloud2"
274-
static_layer:
275-
plugin: "nav2_costmap_2d::StaticLayer"
276-
map_subscribe_transient_local: True
266+
obstacle_max_range: 8.0
267+
inf_is_valid: false
268+
qos_overriding_options:
269+
policy_kinds: [reliability]
270+
reliability: best_effort
277271
always_send_full_costmap: True
278272

273+
279274
global_costmap:
280275
global_costmap:
281276
ros__parameters:
@@ -288,34 +283,32 @@ global_costmap:
288283
footprint_padding: 0.025
289284
resolution: 0.05
290285
track_unknown_space: true
291-
plugins: ["static_layer", "voxel_layer", "inflation_layer"]
292-
voxel_layer:
293-
plugin: "nav2_costmap_2d::VoxelLayer"
286+
plugins: ["static_layer", "obstacle_layer", "inflation_layer"]
287+
static_layer:
288+
plugin: "nav2_costmap_2d::StaticLayer"
289+
map_subscribe_transient_local: True
290+
obstacle_layer:
291+
plugin: "nav2_costmap_2d::ObstacleLayer"
294292
enabled: True
295-
publish_voxel_map: True
296-
origin_z: 0.1
297-
z_resolution: 0.0
298-
z_voxels: 16
299-
max_obstacle_height: 3.0
300-
mark_threshold: 2
301-
observation_sources: pointcloud
302-
pointcloud:
303-
topic: /left_camera/points
304-
max_obstacle_height: 3.0
293+
observation_sources: scan
294+
scan:
295+
topic: /scan_filtered
296+
max_obstacle_height: 2.0
305297
clearing: True
306298
marking: True
299+
data_type: "LaserScan"
307300
raytrace_max_range: 3.0
308301
raytrace_min_range: 0.0
309302
obstacle_max_range: 2.5
310303
obstacle_min_range: 0.0
311-
data_type: "PointCloud2"
312-
static_layer:
313-
plugin: "nav2_costmap_2d::StaticLayer"
314-
map_subscribe_transient_local: True
304+
inf_is_valid: false
305+
qos_overriding_options:
306+
policy_kinds: [reliability]
307+
reliability: best_effort
315308
inflation_layer:
316309
plugin: "nav2_costmap_2d::InflationLayer"
317-
cost_scaling_factor: 1.50
318-
inflation_radius: 2.20
310+
cost_scaling_factor: 4.0
311+
inflation_radius: 0.7
319312
always_send_full_costmap: True
320313

321314
map_server:

0 commit comments

Comments
 (0)