Skip to content

Commit a6739c7

Browse files
daviduhmEricBoiseLGSVL
authored andcommitted
[AUTO-7321] Add python API functions to send destination to Nav2
1 parent 9132959 commit a6739c7

File tree

5 files changed

+126
-3
lines changed

5 files changed

+126
-3
lines changed

lgsvl/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
# This software contains code licensed as described in LICENSE.
55
#
66

7-
from .geometry import Vector, BoundingBox, Transform
7+
from .geometry import Vector, BoundingBox, Transform, Quaternion
88
from .simulator import Simulator, RaycastHit, WeatherState
99
from .sensor import Sensor, CameraSensor, LidarSensor, ImuSensor
1010
from .agent import (

lgsvl/agent.py

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
# This software contains code licensed as described in LICENSE.
55
#
66

7-
from .geometry import Vector, BoundingBox
7+
from .geometry import Vector, BoundingBox, Transform
88
from .sensor import Sensor
99
from .utils import accepts, ObjectState as AgentState
1010

@@ -222,6 +222,28 @@ def cancel_destination(self):
222222
}
223223
)
224224

225+
def set_initial_pose(self):
226+
self.remote.command(
227+
"vehicle/set_initial_pose",
228+
{
229+
"uid": self.uid,
230+
}
231+
)
232+
233+
@accepts(Transform)
234+
def set_destination(self, transform):
235+
self.remote.command(
236+
"vehicle/set_destination",
237+
{
238+
"uid": self.uid,
239+
"transform": transform.to_json(),
240+
}
241+
)
242+
243+
def on_destination_reached(self, fn):
244+
self.remote.command("agent/on_destination_reached", {"uid": self.uid})
245+
self.simulator._add_callback(self, "destination_reached", fn)
246+
225247

226248
class NpcVehicle(Vehicle):
227249
def __init__(self, uid, simulator):

lgsvl/geometry.py

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -132,3 +132,21 @@ def __repr__(self):
132132
return "Spawn(position={}, rotation={}, destinations={})".format(
133133
self.position, self.rotation, self.destinations
134134
)
135+
136+
137+
class Quaternion:
138+
def __init__(self, x=0.0, y=0.0, z=0.0, w=0.0):
139+
self.x = x
140+
self.y = y
141+
self.z = z
142+
self.w = w
143+
144+
@staticmethod
145+
def from_json(j):
146+
return Quaternion(j["x"], j["y"], j["z"], j["w"])
147+
148+
def to_json(self):
149+
return {"x": self.x, "y": self.y, "z": self.z, "w": self.w}
150+
151+
def __repr__(self):
152+
return "Quaternion({}, {}, {}, {})".format(self.x, self.y, self.z, self.w)

lgsvl/simulator.py

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
from .remote import Remote
88
from .agent import Agent, AgentType, AgentState
99
from .sensor import GpsData
10-
from .geometry import Vector, Transform, Spawn
10+
from .geometry import Vector, Transform, Spawn, Quaternion
1111
from .utils import accepts, ObjectState
1212
from .controllable import Controllable
1313

@@ -131,6 +131,8 @@ def _process_events(self, events):
131131
fn(agent)
132132
elif event_type == "lane_change":
133133
fn(agent)
134+
elif event_type == "destination_reached":
135+
fn(agent)
134136
elif event_type == "custom":
135137
fn(agent, ev["kind"], ev["context"])
136138
if self.stopped:
@@ -281,6 +283,17 @@ def map_point_on_lane(self, point):
281283
j = self.remote.command("map/point_on_lane", {"point": point.to_json()})
282284
return Transform.from_json(j)
283285

286+
@accepts(Vector, Quaternion)
287+
def map_from_nav(self, position, orientation):
288+
res = self.remote.command(
289+
"map/from_nav",
290+
{
291+
"position": position.to_json(),
292+
"orientation": orientation.to_json()
293+
}
294+
)
295+
return Transform.from_json(res)
296+
284297
@accepts(Vector, Vector, int, float)
285298
def raycast(self, origin, direction, layer_mask=-1, max_distance=float("inf")):
286299
hit = self.remote.command("simulator/raycast", [{
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
#!/usr/bin/env python3
2+
#
3+
# Copyright (c) 2021 LG Electronics, Inc.
4+
#
5+
# This software contains code licensed as described in LICENSE.
6+
#
7+
8+
import lgsvl
9+
from environs import Env
10+
from lgsvl import Vector, Quaternion
11+
12+
print("Python API Quickstart #36: Sending destinations to Navigation2")
13+
env = Env()
14+
15+
sim = lgsvl.Simulator(env.str("LGSVL__SIMULATOR_HOST", lgsvl.wise.SimulatorSettings.simulator_host), env.int("LGSVL__SIMULATOR_PORT", lgsvl.wise.SimulatorSettings.simulator_port))
16+
17+
# TODO: Make public assets for LGSeocho with NavOrigin and cloi sensor config
18+
map_seocho = "9b494638-b3e9-4239-9f3f-51b2c68cd292"
19+
ego_cloi = "4717598d-6c67-48a1-9a02-988a89d8660c"
20+
21+
if sim.current_scene == map_seocho:
22+
sim.reset()
23+
else:
24+
sim.load(map_seocho)
25+
26+
sim.set_time_of_day(0, fixed=True)
27+
spawns = sim.get_spawn()
28+
state = lgsvl.AgentState()
29+
state.transform = spawns[0]
30+
31+
ego = sim.add_agent(env.str("LGSVL__VEHICLE_0", ego_cloi), lgsvl.AgentType.EGO, state)
32+
ego.connect_bridge(env.str("LGSVL__AUTOPILOT_0_HOST", lgsvl.wise.SimulatorSettings.bridge_host), env.int("LGSVL__AUTOPILOT_0_PORT", lgsvl.wise.SimulatorSettings.bridge_port))
33+
34+
i = 0
35+
36+
# List of destinations in Nav2 costmap coordinates
37+
ros_destinations = [
38+
((3.118, -0.016, 0), (0, 0, 0.0004, 0.999)),
39+
((3.126, -10.025, 0), (0, 0, 0.006, 0.999)),
40+
((11.171, -9.875, 0), (0, 0, 0.707, 0.707)),
41+
((11.882, -0.057, 0), (0, 0, 0.699, 0.715)),
42+
((12.351, 11.820, 0), (0, 0, -0.999, 0.0004)),
43+
((2.965, 11.190, 0), (0, 0, -0.707, 0.707)),
44+
((2.687, -0.399, 0), (0, 0, -0.0036, 0.999)),
45+
]
46+
47+
ego.set_initial_pose()
48+
sim.run(5)
49+
50+
def send_next_destination(agent):
51+
global i
52+
print(f"{i}: {agent.name} reached destination")
53+
i += 1
54+
if i >= len(ros_destinations):
55+
print("Iterated all destinations successfully. Stopping...")
56+
sim.stop()
57+
return
58+
59+
ros_dst = ros_destinations[i]
60+
next_dst = sim.map_from_nav(Vector(*ros_dst[0]), Quaternion(*ros_dst[1]))
61+
ego.set_destination(next_dst)
62+
63+
ros_dst = ros_destinations[0]
64+
first_dst = sim.map_from_nav(Vector(*ros_dst[0]), Quaternion(*ros_dst[1]))
65+
ego.set_destination(first_dst)
66+
ego.on_destination_reached(send_next_destination)
67+
68+
sim.run()
69+
70+
print("Done!")

0 commit comments

Comments
 (0)