Skip to content

Commit 085f5fa

Browse files
Raghumanimehta/582 advanced gps visualizer (#591)
* improved gps reference * added moving boat marker * added moving boat marker * Flake8 Linting * Fixed documentation for true_bearing_to_plotly_cartesian --------- Co-authored-by: Akshanjay Kompelli <63443017+FireBoyAJ24@users.noreply.github.com>
1 parent e6e9272 commit 085f5fa

File tree

4 files changed

+90
-27
lines changed

4 files changed

+90
-27
lines changed

src/local_pathfinding/local_pathfinding/coord_systems.py

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,24 @@ def cartesian_to_true_bearing(cartesian: float) -> float:
3434
return (90 - cartesian + 360) % 360
3535

3636

37+
def true_bearing_to_plotly_cartesian(true_bearing: float) -> float:
38+
"""Convert a true bearing angle to the equivalent cartesian angle .
39+
40+
Args:
41+
true_bearing (float): Angle where 0 is true north. Range: -180 < heading <= 180.
42+
Increases in the clockwise direction till 180 degrees.
43+
Decreases in the counter-clockwise direction till -180 (exclusive)
44+
Returns:
45+
float: Angle where 0 is north and values increases clockwise.
46+
"""
47+
assert -180 < true_bearing <= 180
48+
49+
plotly_cartesian = true_bearing
50+
if -180 < true_bearing < 0:
51+
plotly_cartesian += 360.0
52+
return plotly_cartesian
53+
54+
3755
def meters_to_km(meters: float) -> float:
3856
return meters / 1000
3957

src/local_pathfinding/local_pathfinding/visualizer.py

Lines changed: 48 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
Call the `dash_app` function with a multiprocessing shared Manager.queue to start the Dash app.
1616
"""
1717

18+
import math
1819
from multiprocessing import Queue
1920
from typing import List, Optional, Tuple
2021

@@ -190,32 +191,49 @@ def live_update_plot(state: VisualizerState) -> go.Figure:
190191
name="Intermediate",
191192
)
192193

194+
goal_x = [state.final_local_wp_x[-1]]
195+
goal_y = [state.final_local_wp_y[-1]]
196+
boat_x = [state.sailbot_pos_x[-1]]
197+
boat_y = [state.sailbot_pos_y[-1]]
198+
angle_from_boat = math.atan2(goal_x[0] - boat_x[0], goal_y[0] - boat_y[0])
199+
angle_degrees = math.degrees(angle_from_boat)
200+
193201
# goal local waypoint
194202
goal_trace = go.Scatter(
195-
x=[state.final_local_wp_x[-1]],
196-
y=[state.final_local_wp_y[-1]],
203+
x=goal_x,
204+
y=goal_y,
197205
mode="markers",
198206
marker=dict(color="red", size=10),
199207
name="Goal",
208+
hovertemplate="X: %{x:.2f} <br>"
209+
+ "Y: %{y:.2f} <br>"
210+
+ "Angle from the boat: "
211+
+ f"{angle_degrees:.1f}°"
212+
+ "<extra></extra>",
200213
)
201214

202-
# boat marker (current position)
203215
boat_trace = go.Scatter(
204216
x=[state.sailbot_pos_x[-1]],
205217
y=[state.sailbot_pos_y[-1]],
206218
mode="markers",
207-
marker_symbol="arrow",
208-
marker_line_color="darkseagreen",
209-
marker_color="lightgreen",
210-
marker_line_width=2,
211-
marker_size=15,
212219
name="Boat",
213-
hovertemplate="<b>🚢 Sailbot Current Position</b><br>" +
214-
"X: %{x:.2f} meters<br>" +
215-
"Y: %{y:.2f} meters<br>" +
216-
"Heading: " + f"{state.sailbot_gps[-1].heading.heading:.1f}°<br>" +
217-
"Speed: " + f"{state.sailbot_gps[-1].speed.speed:.1f}<br>" +
218-
"<extra></extra>"
220+
hovertemplate=(
221+
"<b>🚢 Sailbot Current Position</b><br>"
222+
"X: %{x:.2f} <br>"
223+
"Y: %{y:.2f} <br>"
224+
"Heading: " + f"{state.sailbot_gps[-1].heading.heading:.1f}°<br>"
225+
f"Speed: {state.sailbot_gps[-1].speed.speed:.1f}<br>"
226+
"<extra></extra>"
227+
),
228+
marker=dict(
229+
symbol="arrow-wide",
230+
line_color="darkseagreen",
231+
color="lightgreen",
232+
line_width=2,
233+
size=15,
234+
angleref="up",
235+
angle=cs.true_bearing_to_plotly_cartesian(state.sailbot_gps[-1].heading.heading),
236+
),
219237
)
220238

221239
# Add all traces to the figure
@@ -265,12 +283,14 @@ def animated_update_plot(state: VisualizerState) -> go.Figure:
265283
marker_size=15,
266284
text=["Boat"],
267285
name="Boat",
268-
hovertemplate="<b>🚢 Sailbot Current Position</b><br>" +
269-
"X: %{x:.2f} meters<br>" +
270-
"Y: %{y:.2f} meters<br>" +
271-
"Heading: " + f"{state.sailbot_gps[0].heading.heading:.1f}°<br>" +
272-
"Speed: " + f"{state.sailbot_gps[0].speed.speed:.1f}<br>" +
273-
"<extra></extra>"
286+
hovertemplate="<b>🚢 Sailbot Current Position</b><br>"
287+
+ "X: %{x:.2f} meters<br>"
288+
+ "Y: %{y:.2f} meters<br>"
289+
+ "Heading: "
290+
+ f"{state.sailbot_gps[0].heading.heading:.1f}°<br>"
291+
+ "Speed: "
292+
+ f"{state.sailbot_gps[0].speed.speed:.1f}<br>"
293+
+ "<extra></extra>",
274294
)
275295
initial_state = [
276296
go.Scatter(
@@ -338,12 +358,14 @@ def animated_update_plot(state: VisualizerState) -> go.Figure:
338358
marker_size=15,
339359
text=["Boat"],
340360
name="Boat",
341-
hovertemplate="<b>🚢 Sailbot Current Position</b><br>" +
342-
"X: %{x:.2f} meters<br>" +
343-
"Y: %{y:.2f} meters<br>" +
344-
"Heading: " + f"{state.sailbot_gps[i].heading.heading:.1f}°<br>" +
345-
"Speed: " + f"{state.sailbot_gps[i].speed.speed:.1f}<br>" +
346-
"<extra></extra>"
361+
hovertemplate="<b>🚢 Sailbot Current Position</b><br>"
362+
+ "X: %{x:.2f} meters<br>"
363+
+ "Y: %{y:.2f} meters<br>"
364+
+ "Heading: "
365+
+ f"{state.sailbot_gps[i].heading.heading:.1f}°<br>"
366+
+ "Speed: "
367+
+ f"{state.sailbot_gps[i].speed.speed:.1f}<br>"
368+
+ "<extra></extra>",
347369
)
348370
],
349371
name=f"Boat {i}",

src/local_pathfinding/test/test_coord_systems.py

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,29 @@ def test_cartesian_to_true_bearing(cartesian: float, true_bearing: float):
2323
), "incorrect angle conversion"
2424

2525

26+
@pytest.mark.parametrize(
27+
"true_bearing, plotly_cartesian",
28+
[
29+
(0.0, 0.0),
30+
(-90.0, 270.0),
31+
(180.0, 180.0),
32+
(90.0, 90.0),
33+
(45.0, 45.0),
34+
(-45.0, 315.0),
35+
(135.0, 135.0),
36+
(-135.0, 225.0),
37+
(1.0, 1.0),
38+
(-1.0, 359.0),
39+
(-179.0, 181.0),
40+
(179.0, 179.0),
41+
],
42+
)
43+
def test_true_bearing_to_plotly_cartesian(true_bearing: float, plotly_cartesian: float):
44+
assert cs.true_bearing_to_plotly_cartesian(true_bearing) == pytest.approx(
45+
plotly_cartesian
46+
), "incorrect angle conversion"
47+
48+
2649
@pytest.mark.parametrize(
2750
"meters,km",
2851
[(0.0, 0.0), (30, 0.03), (500, 0.5), (-30.5, -0.0305), (-0.0, 0.0)],

src/website/package-lock.json

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)