Skip to content

Commit fdf9865

Browse files
authored
Generalize nav2 tests and add GPS test. (#338)
* Generalize Nav2 tests. Signed-off-by: Jelmer de Wolde <jelmer.de.wolde@alliander.com> * Create simplified nav2_manager using nav2 commander API. Signed-off-by: Jelmer de Wolde <jelmer.de.wolde@alliander.com> * Add GPS navigation and extend UI. Signed-off-by: Jelmer de Wolde <jelmer.de.wolde@alliander.com> * WIP Signed-off-by: Jelmer de Wolde <jelmer.de.wolde@alliander.com> * Fix tests. Signed-off-by: Jelmer de Wolde <jelmer.de.wolde@alliander.com> * Switch to using tf2 listener directly. Signed-off-by: Jelmer de Wolde <jelmer.de.wolde@alliander.com> * Apply feedback. Signed-off-by: Jelmer de Wolde <jelmer.de.wolde@alliander.com> * Try spin_once function with zero timeouts. Signed-off-by: Jelmer de Wolde <jelmer.de.wolde@alliander.com> * Apply feedback. Signed-off-by: Jelmer de Wolde <jelmer.de.wolde@alliander.com> * Apply feedback. Signed-off-by: Jelmer de Wolde <jelmer.de.wolde@alliander.com> --------- Signed-off-by: Jelmer de Wolde <jelmer.de.wolde@alliander.com>
1 parent a0bf0d6 commit fdf9865

17 files changed

Lines changed: 878 additions & 731 deletions

File tree

conftest.py

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,3 +80,27 @@ def joint_movement_tolerance() -> float:
8080
float: The tolerance value for joint movements.
8181
"""
8282
return 0.01
83+
84+
85+
@pytest.fixture(scope="session")
86+
def navigation_distance_tolerance() -> float:
87+
"""Distance tolerance of testing navigation.
88+
89+
This is the maximum allowed deviation for navigation during tests.
90+
91+
Returns:
92+
float: The tolerance value for navigation.
93+
"""
94+
return 0.2
95+
96+
97+
@pytest.fixture(scope="session")
98+
def navigation_degree_tolerance() -> float:
99+
"""Latitude/Longitude degree tolerance of testing navigation.
100+
101+
This is the maximum allowed deviation for navigation during tests.
102+
103+
Returns:
104+
float: The tolerance value for navigation.
105+
"""
106+
return 2e-6

ros2_ws/src/rcdt_launch/launch/bringup.launch.py

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44

55
from launch import LaunchContext, LaunchDescription
66
from launch.actions import OpaqueFunction
7-
from launch_ros.actions import SetParameter
7+
from launch_ros.actions import Node, SetParameter
88
from rcdt_launch.environment_configuration import EnvironmentConfiguration
99
from rcdt_launch.predefined_configurations import PredefinedConfigurations
1010
from rcdt_launch.rviz import Rviz
@@ -79,8 +79,19 @@ def launch_setup(context: LaunchContext) -> list:
7979
get_file_path("rcdt_panther", ["launch"], "vizanti.launch.py")
8080
)
8181

82+
platforms_dict = {
83+
platform.namespace: type(platform).__name__
84+
for platform in EnvironmentConfiguration.platforms
85+
}
86+
rcdt_gui = Node(
87+
package="rcdt_utilities",
88+
executable="rcdt_gui.py",
89+
parameters=[{"platforms": str(platforms_dict)}],
90+
)
91+
start_rcdt_gui = not set(platforms_dict.values()).isdisjoint(["Arm", "Vehicle"])
8292
return [
8393
SetParameter(name="use_sim_time", value=EnvironmentConfiguration.simulation),
94+
Register.on_start(rcdt_gui, context) if start_rcdt_gui else launch_utils.SKIP,
8495
Register.group(rviz, context) if use_rviz else launch_utils.SKIP,
8596
*[Register.on_start(node, context) for node in state_publishers],
8697
Register.group(gazebo, context)

ros2_ws/src/rcdt_launch/rcdt_launch/platforms/arm.py

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,17 @@
1717

1818

1919
class Arm(Platform):
20-
"""Extension on Platform with arm specific functionalities."""
20+
"""Extension on Platform with arm specific functionalities.
21+
22+
Attributes:
23+
SUPPORTED_PLATFORMS: The supported platforms.
24+
"""
25+
26+
SUPPORTED_PLATFORMS = Literal["franka"]
2127

2228
def __init__( # noqa: PLR0913
2329
self,
24-
platform: Literal["franka"],
30+
platform: SUPPORTED_PLATFORMS,
2531
position: list,
2632
orientation: list | None = None,
2733
namespace: str | None = None,
@@ -34,7 +40,7 @@ def __init__( # noqa: PLR0913
3440
"""Initialize the Arm platform.
3541
3642
Args:
37-
platform (Literal["franka"]): The platform type.
43+
platform (SUPPORTED_PLATFORMS): The platform type.
3844
position (list): The position of the arm.
3945
orientation (list | None): The initial orientation of the arm.
4046
namespace (str | None): The namespace of the arm.

ros2_ws/src/rcdt_launch/rcdt_launch/platforms/camera.py

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,11 +18,17 @@
1818

1919

2020
class Camera(Platform):
21-
"""Extension on Platform with camera specific functionalities."""
21+
"""Extension on Platform with camera specific functionalities.
22+
23+
Attributes:
24+
SUPPORTED_PLATFORMS: The supported platforms.
25+
"""
26+
27+
SUPPORTED_PLATFORMS = Literal["realsense", "zed"]
2228

2329
def __init__( # noqa: PLR0913
2430
self,
25-
platform: Literal["realsense", "zed"],
31+
platform: SUPPORTED_PLATFORMS,
2632
position: list,
2733
orientation: list | None = None,
2834
namespace: str | None = None,
@@ -32,7 +38,7 @@ def __init__( # noqa: PLR0913
3238
"""Initialize the Camera platform.
3339
3440
Args:
35-
platform (Literal["realsense", "zed"]): The platform type.
41+
platform (SUPPORTED_PLATFORMS): The platform type.
3642
position (list): The position of the camera.
3743
orientation (list | None): The initial orientation of the camera.
3844
namespace (str | None): The namespace of the camera.

ros2_ws/src/rcdt_launch/rcdt_launch/platforms/gps.py

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,11 +18,17 @@
1818

1919

2020
class GPS(Platform):
21-
"""Extension on Platform with GPS specific functionalities."""
21+
"""Extension on Platform with GPS specific functionalities.
22+
23+
Attributes:
24+
SUPPORTED_PLATFORMS: The supported platforms.
25+
"""
26+
27+
SUPPORTED_PLATFORMS = Literal["nmea"]
2228

2329
def __init__( # noqa: PLR0913
2430
self,
25-
platform: Literal["nmea"],
31+
platform: SUPPORTED_PLATFORMS,
2632
position: list,
2733
orientation: list | None = None,
2834
namespace: str | None = None,
@@ -32,7 +38,7 @@ def __init__( # noqa: PLR0913
3238
"""Initialize the GPS platform.
3339
3440
Args:
35-
platform (Literal["nmea"]): The platform type.
41+
platform (SUPPORTED_PLATFORMS): The platform type.
3642
position (list): The position of the platform.
3743
orientation (list | None): The orientation of the platform.
3844
namespace (str | None): The namespace of the platform.

ros2_ws/src/rcdt_launch/rcdt_launch/platforms/lidar.py

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,11 +18,17 @@
1818

1919

2020
class Lidar(Platform):
21-
"""Extension on Platform with lidar specific functionalities."""
21+
"""Extension on Platform with lidar specific functionalities.
22+
23+
Attributes:
24+
SUPPORTED_PLATFORMS: The supported platforms.
25+
"""
26+
27+
SUPPORTED_PLATFORMS = Literal["velodyne", "ouster"]
2228

2329
def __init__( # noqa: PLR0913
2430
self,
25-
platform: Literal["velodyne", "ouster"],
31+
platform: SUPPORTED_PLATFORMS,
2632
position: list,
2733
orientation: list | None = None,
2834
namespace: str | None = None,
@@ -32,7 +38,7 @@ def __init__( # noqa: PLR0913
3238
"""Initialize the Lidar platform.
3339
3440
Args:
35-
platform (Literal["velodyne", "ouster"]): The platform type.
41+
platform (SUPPORTED_PLATFORMS): The platform type.
3642
position (list): The position of the lidar.
3743
orientation (list | None): The initial orientation of the lidar.
3844
namespace (str | None): The namespace of the lidar.

ros2_ws/src/rcdt_launch/rcdt_launch/platforms/platform.py

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,11 +15,17 @@
1515

1616

1717
class Platform: # noqa: PLR0904
18-
"""A class used to dynamically create all the required nodes for a platform."""
18+
"""A class used to dynamically create all the required nodes for a platform.
19+
20+
Attributes:
21+
SUPPORTED_PLATFORMS: The supported platforms.
22+
"""
23+
24+
SUPPORTED_PLATFORMS = Literal["axis"]
1925

2026
def __init__( # noqa: PLR0913
2127
self,
22-
platform: Literal["axis"],
28+
platform: SUPPORTED_PLATFORMS,
2329
position: list,
2430
orientation: list | None = None,
2531
namespace: str | None = None,
@@ -29,7 +35,7 @@ def __init__( # noqa: PLR0913
2935
"""Initialize a platform instance.
3036
3137
Args:
32-
platform (Literal["axis"]): The platform type of the platform.
38+
platform (SUPPORTED_PLATFORMS): The platform type of the platform.
3339
position (list): The initial position of the platform.
3440
orientation (list | None): The initial orientation of the platform.
3541
namespace (str | None): The namespace of the platform. If None, a unique namespace will be generated.

ros2_ws/src/rcdt_launch/rcdt_launch/platforms/vehicle.py

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,11 +19,17 @@
1919

2020

2121
class Vehicle(Platform):
22-
"""Extension on Platform with vehicle specific functionalities."""
22+
"""Extension on Platform with vehicle specific functionalities.
23+
24+
Attributes:
25+
SUPPORTED_PLATFORMS: The supported platforms.
26+
"""
27+
28+
SUPPORTED_PLATFORMS = Literal["panther"]
2329

2430
def __init__( # noqa: PLR0913
2531
self,
26-
platform: Literal["panther"],
32+
platform: SUPPORTED_PLATFORMS,
2733
position: list,
2834
orientation: list | None = None,
2935
namespace: str | None = None,
@@ -38,7 +44,7 @@ def __init__( # noqa: PLR0913
3844
"""Initialize the Vehicle platform.
3945
4046
Args:
41-
platform (Literal["panther"]): The platform type.
47+
platform (SUPPORTED_PLATFORMS): The platform type.
4248
position (list): The position of the vehicle.
4349
orientation (list | None): The initial orientation of the vehicle.
4450
namespace (str | None): The namespace of the vehicle.

ros2_ws/src/rcdt_launch/rcdt_launch/predefined_configurations.py

Lines changed: 25 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -110,29 +110,29 @@ def config_franka() -> None: # noqa: D103
110110

111111
@register_configuration("franka_axis")
112112
def config_franka_axis() -> None: # noqa: D103
113-
EnvironmentConfiguration.world = "table_with_1_brick.sdf"
114-
Rviz.add_markers()
115-
Rviz.load_robot_state = True
116-
Rviz.load_trajectory = True
117-
Rviz.load_planning_scene = True
118-
arm = Arm("franka", [0, 0, 0], moveit=True)
119-
Camera("realsense", [0.05, 0, 0], [0, -90, 180], parent=arm)
120-
121-
122-
@register_configuration("franka_double")
123-
def config_franka_double() -> None: # noqa: D103
124113
franka = Arm("franka", [0, 0, 0], [0, 0, 20])
125114
Platform("axis", [0, 0, 0.1], [0, 20, 0], parent=franka)
126115

127116

128-
@register_configuration("franka_planning")
129-
def config_franka_planning() -> None: # noqa: D103
117+
@register_configuration("franka_double")
118+
def config_franka_double() -> None: # noqa: D103
130119
EnvironmentConfiguration.use_joystick = False
131120
Rviz.load_motion_planning_plugin = True
132121
Arm("franka", [1.0, 0, 0], gripper=True, moveit=True)
133122
Arm("franka", [-1.0, 0, 0], gripper=True, moveit=True)
134123

135124

125+
@register_configuration("franka_planning")
126+
def config_franka_planning() -> None: # noqa: D103
127+
EnvironmentConfiguration.world = "table_with_1_brick.sdf"
128+
Rviz.add_markers()
129+
Rviz.load_robot_state = True
130+
Rviz.load_trajectory = True
131+
Rviz.load_planning_scene = True
132+
arm = Arm("franka", [0, 0, 0], moveit=True)
133+
Camera("realsense", [0.05, 0, 0], [0, -90, 180], parent=arm)
134+
135+
136136
@register_configuration("franka_realsense")
137137
def config_franka_realsense() -> None: # noqa: D103
138138
arm = Arm("franka", [0, 0, 0], moveit=True)
@@ -175,6 +175,7 @@ def config_panther_zed() -> None: # noqa: D103
175175

176176
@register_configuration("panther_velodyne")
177177
def config_panther_velodyne() -> None: # noqa: D103
178+
EnvironmentConfiguration.use_vizanti = True
178179
panther = Vehicle("panther", [0, 0, 0.2], navigation=True)
179180
Lidar("velodyne", [0.13, -0.13, 0.35], parent=panther)
180181

@@ -205,6 +206,17 @@ def config_mm_ouster() -> None: # noqa: D103
205206
Lidar("ouster", [0.13, -0.13, 0.35], parent=panther)
206207

207208

209+
@register_configuration("mm_gps")
210+
def config_mm_gps() -> None: # noqa: D103
211+
EnvironmentConfiguration.world = "map_5.940906_51.966960"
212+
panther = Vehicle(
213+
"panther", [0, 0, 0.2], navigation=True, use_gps=True, window_size=50
214+
)
215+
Arm("franka", [0, 0, 0.14], gripper=True, parent=panther, moveit=True)
216+
Lidar("velodyne", [0.13, -0.13, 0.35], parent=panther)
217+
GPS("nmea", [0, 0, 0.2], parent=panther)
218+
219+
208220
@register_configuration("panther_and_franka")
209221
def config_panther_and_franka() -> None: # noqa: D103
210222
Vehicle("panther", [0, -0.5, 0.2])

ros2_ws/src/rcdt_panther/launch/nav2.launch.py

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -308,7 +308,6 @@ def launch_setup(context: LaunchContext) -> list: # noqa: PLR0915
308308
respawn=use_respawn,
309309
respawn_delay=2.0,
310310
parameters=[bt_navigator_params],
311-
remappings=[(f"/{namespace_vehicle}/goal_pose", "/goal_pose")],
312311
namespace=namespace_vehicle,
313312
)
314313

@@ -335,17 +334,20 @@ def launch_setup(context: LaunchContext) -> list: # noqa: PLR0915
335334
remappings = []
336335
if use_gps:
337336
remappings.append(("/gps/fix", f"/{namespace_gps}/fix"))
337+
remappings.append(("/fromLL", f"/{namespace_gps}/fromLL"))
338+
338339
waypoint_follower = Node(
339340
package="nav2_waypoint_follower",
340341
executable="waypoint_follower",
341342
namespace=namespace_vehicle,
342343
remappings=remappings,
343344
)
344345

345-
waypoint_follower_controller = Node(
346+
nav2_manager = Node(
346347
package="rcdt_panther",
347-
executable="waypoint_follower_controller.py",
348+
executable="nav2_manager.py",
348349
namespace=namespace_vehicle,
350+
remappings=remappings,
349351
)
350352

351353
pub_topic = (
@@ -370,7 +372,7 @@ def launch_setup(context: LaunchContext) -> list: # noqa: PLR0915
370372
Register.on_log(lifecycle_manager, "Managed nodes are active", context)
371373
if lifecycle_nodes
372374
else SKIP,
373-
Register.on_log(waypoint_follower_controller, "Controller is ready.", context)
375+
Register.on_log(nav2_manager, "Controller is ready.", context)
374376
if use_navigation
375377
else SKIP,
376378
]

0 commit comments

Comments
 (0)