Skip to content

Commit 935b2de

Browse files
committed
print sim time when waypoint is reached
1 parent 96720c7 commit 935b2de

File tree

2 files changed

+120
-31
lines changed

2 files changed

+120
-31
lines changed

src/sam_bot_nav2_gz/scripts/follow_waypoints.py

Lines changed: 12 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
import rclpy
1919
from rclpy.duration import Duration
2020
import yaml
21+
from rosgraph_msgs.msg import Clock
2122

2223

2324
waypoints = yaml.safe_load('''
@@ -96,30 +97,16 @@
9697
w: 0.6960848684271199
9798
''')
9899

99-
waypoints = yaml.safe_load('''
100-
waypoints:
101-
- position:
102-
x: 0.8006443977355957
103-
y: 0.5491957664489746
104-
z: 0.0
105-
orientation:
106-
x: 0.0
107-
y: 0.0
108-
z: -0.0055409271259092485
109-
w: 0.9999846489454652
110-
- position:
111-
x: 1.8789787292480469
112-
y: 0.5389942526817322
113-
z: 0.0
114-
orientation:
115-
x: 0.0
116-
y: 0.0
117-
z: 0.010695864295550759
118-
w: 0.9999427976074288
119-
''')
100+
sim_time = 0.0
101+
102+
def update_sim_time(msg):
103+
global sim_time
104+
sim_time = msg.clock.sec + msg.clock.nanosec * 1e-9
105+
120106
def main():
121107
rclpy.init()
122108
navigator = BasicNavigator()
109+
navigator.create_subscription(Clock, '/clock', lambda msg: update_sim_time(msg), 10)
123110

124111
def create_pose(transform):
125112
pose = PoseStamped()
@@ -162,7 +149,9 @@ def create_pose(transform):
162149

163150
if feedback and i % 5 == 0:
164151
if current_wp >= 0 and current_wp != feedback.current_waypoint:
165-
print(f"Reached waypoint: {current_wp}")
152+
print(sim_time)
153+
print(navigator.get_clock().now())
154+
print(f"Reached waypoint: {current_wp} @{sim_time}")
166155
current_wp = feedback.current_waypoint
167156
print('Executing current waypoint: ' +
168157
str(feedback.current_waypoint) + '/' + str(len(goal_poses)))
@@ -172,7 +161,7 @@ def create_pose(transform):
172161
if now - nav_start > Duration(seconds=600):
173162
navigator.cancelTask()
174163

175-
print(f"Reached waypoint: {current_wp}")
164+
print(f"Reached waypoint: {current_wp} @{sim_time}")
176165
# Do something depending on the return code
177166
result = navigator.getResult()
178167
if result == TaskResult.SUCCEEDED:

src/sam_bot_nav2_gz/test/test_waypoints_pytest.py

Lines changed: 108 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,99 @@
4949
y: 0.0
5050
z: 0.010695864295550759
5151
w: 0.9999427976074288
52+
- position:
53+
x: 3.0792641639709473
54+
y: 0.6118782758712769
55+
z: 0.0
56+
orientation:
57+
x: 0.0
58+
y: 0.0
59+
z: 0.01899610435153287
60+
w: 0.9998195577300264
61+
- position:
62+
x: 3.8347740173339844
63+
y: 0.012513279914855957
64+
z: 0.0
65+
orientation:
66+
x: 0.0
67+
y: 0.0
68+
z: -0.7548200584119721
69+
w: 0.6559319167558071
70+
''')
71+
waypoints = yaml.safe_load('''
72+
waypoints:
73+
- position:
74+
x: 0.8006443977355957
75+
y: 0.5491957664489746
76+
z: 0.0
77+
orientation:
78+
x: 0.0
79+
y: 0.0
80+
z: -0.0055409271259092485
81+
w: 0.9999846489454652
82+
- position:
83+
x: 1.8789787292480469
84+
y: 0.5389942526817322
85+
z: 0.0
86+
orientation:
87+
x: 0.0
88+
y: 0.0
89+
z: 0.010695864295550759
90+
w: 0.9999427976074288
91+
- position:
92+
x: 3.0792641639709473
93+
y: 0.6118782758712769
94+
z: 0.0
95+
orientation:
96+
x: 0.0
97+
y: 0.0
98+
z: 0.01899610435153287
99+
w: 0.9998195577300264
100+
- position:
101+
x: 3.8347740173339844
102+
y: 0.012513279914855957
103+
z: 0.0
104+
orientation:
105+
x: 0.0
106+
y: 0.0
107+
z: -0.7548200584119721
108+
w: 0.6559319167558071
109+
- position:
110+
x: 3.084421157836914
111+
y: -0.5701640844345093
112+
z: 0.0
113+
orientation:
114+
x: 0.0
115+
y: 0.0
116+
z: -0.9998472894684893
117+
w: 0.01747563282157926
118+
- position:
119+
x: 2.19096302986145
120+
y: -0.609535813331604
121+
z: 0.0
122+
orientation:
123+
x: 0.0
124+
y: 0.0
125+
z: 0.9999322787364863
126+
w: 0.011637780753125607
127+
- position:
128+
x: 0.8946757316589355
129+
y: -0.5464844703674316
130+
z: 0.0
131+
orientation:
132+
x: 0.0
133+
y: 0.0
134+
z: 0.9850211921086874
135+
w: 0.1724333236262069
136+
- position:
137+
x: -0.14899730682373047
138+
y: -0.011111736297607422
139+
z: 0.0
140+
orientation:
141+
x: 0.0
142+
y: 0.0
143+
z: 0.7179595085705036
144+
w: 0.6960848684271199
52145
''')
53146

54147
def deep_merge_dicts(source, override):
@@ -233,7 +326,7 @@ def sim():
233326

234327

235328
@pytest.mark.launch(fixture=launch_description)
236-
def test_0_nav2_started(follow_waypoints_proc, launch_context):
329+
async def test_0_nav2_started(follow_waypoints_proc, launch_context):
237330
"""Test that Nav2 starts successfully"""
238331

239332
def validate_nav2_output(output):
@@ -249,15 +342,15 @@ def validate_nav2_output(output):
249342

250343
# Get the follow_waypoints process from the launch context
251344
print("Starting to wait for follow_waypoints process output...")
252-
process_tools.assert_output_sync(
345+
await process_tools.assert_output(
253346
launch_context, follow_waypoints_proc, validate_nav2_output, timeout=120
254347
)
255348
print(datetime.now().strftime("%Y-%m-%d %H:%M:%S"))
256349

257350

258351
@pytest.mark.launch(fixture=launch_description)
259-
@pytest.mark.parametrize("waypoint_idx", [0, 1]) #TODO use list
260-
async def test_1_reached_waypoint(follow_waypoints_proc, launch_context, sim, artefacts_metrics, waypoint_idx):
352+
@pytest.mark.parametrize("waypoint_idx", range(len(waypoints["waypoints"])))
353+
def test_1_reached_waypoint(follow_waypoints_proc, launch_context, sim, artefacts_metrics, waypoint_idx):
261354
"""Check that each waypoint is reached"""
262355
#TODO, without async, check timing could be way too late
263356

@@ -276,19 +369,26 @@ async def test_1_reached_waypoint(follow_waypoints_proc, launch_context, sim, ar
276369
qx=wp["orientation"]["x"], qy=wp["orientation"]["y"], qz=wp["orientation"]["z"], qw=wp["orientation"]["w"],
277370
frame="custom_odom"
278371
)
372+
sim_time = 0
279373
def validate_goal_output(output):
280374
if not output.strip():
281375
print("WARNING: follow_waypoints process produced no output!")
282376
text = f"Reached waypoint: {waypoint_idx}"
283377
assert text in output, f"process never printed {text}"
378+
# the format is f"Reached waypoint: {current_wp} @{sim_time}" we want to extract the sim_time. there could be more lines afterwards
379+
nonlocal sim_time
380+
sim_state_str = output.split(text)[1].splitlines()[0].strip().lstrip("@").strip()
381+
sim_time = float(sim_state_str)
284382

285383
# Get the follow_waypoints process from the launch context
286384
print("Starting to wait for goal completion...")
287-
await process_tools.assert_output(
385+
#await process_tools.assert_output(
386+
process_tools.assert_output_sync(
288387
launch_context, follow_waypoints_proc, validate_goal_output, timeout=60
289388
)
290389

291-
current_pose = robot.pose(frame_id="custom_odom").now()
390+
current_pose = robot.pose(frame_id="custom_odom").at(sim_time)
391+
print(sim_time)
292392
print(datetime.now().strftime("%Y-%m-%d %H:%M:%S"))
293393
print(
294394
f"Current robot position: x={current_pose.x:.3f}, y={current_pose.y:.3f}, z={current_pose.z:.3f}"
@@ -299,11 +399,11 @@ def validate_goal_output(output):
299399

300400
# Calculate distance to goal using the new waypoint feature
301401
distance_to_goal_metric = robot.distance_to(goal_waypoint)
302-
waypoint_dist = distance_to_goal_metric.now()
402+
waypoint_dist = distance_to_goal_metric.at(sim_time)
303403
# Check if assertion should pass
304404
artefacts_metrics["distance_to_goal"] = waypoint_dist
305405
# asserts
306-
assert waypoint_dist < 0.2, (
406+
assert waypoint_dist < 0.25, (
307407
f"Robot did not reach close enough to goal, distance: {waypoint_dist:.3f}m"
308408
)
309409

0 commit comments

Comments
 (0)