Skip to content

Commit 90ba386

Browse files
hadiTabmartins-mozeiko
authored andcommitted
Extend API waypoint mode to include angle
1 parent 609c4a9 commit 90ba386

File tree

4 files changed

+195
-10
lines changed

4 files changed

+195
-10
lines changed

lgsvl/agent.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
from collections.abc import Iterable, Callable
1414
import math
1515

16-
DriveWaypoint = namedtuple("DriveWaypoint", "position speed")
16+
DriveWaypoint = namedtuple("DriveWaypoint", "position speed angle idle trigger_distance")
1717
WalkWaypoint = namedtuple("WalkWaypoint", "position idle")
1818

1919
class AgentType(Enum):
@@ -202,7 +202,7 @@ def __init__(self, uid, simulator):
202202
def follow(self, waypoints, loop = False):
203203
self.remote.command("vehicle/follow_waypoints", {
204204
"uid": self.uid,
205-
"waypoints": [{"position": wp.position.to_json(), "speed": wp.speed} for wp in waypoints],
205+
"waypoints": [{"position": wp.position.to_json(), "speed": wp.speed, "angle": wp.angle.to_json(), "idle": wp.idle, "trigger_distance": wp.trigger_distance} for wp in waypoints],
206206
"loop": loop,
207207
})
208208

quickstart/13-npc-follow-waypoints.py

Lines changed: 25 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
import os
99
import lgsvl
1010
import math
11+
import copy
1112

1213
sim = lgsvl.Simulator(os.environ.get("SIMULATOR_HOST", "127.0.0.1"), 8181)
1314
if sim.current_scene == "BorregasAve":
@@ -21,7 +22,9 @@
2122

2223
state = lgsvl.AgentState()
2324
state.transform = spawns[0]
24-
a = sim.add_agent("Jaguar2015XE (Apollo 5.0)", lgsvl.AgentType.EGO, state)
25+
state2 = copy.deepcopy(state)
26+
state2.transform.position.z += 50
27+
a = sim.add_agent("Jaguar2015XE (Apollo 5.0)", lgsvl.AgentType.EGO, state2)
2528

2629
# NPC, 10 meters ahead
2730

@@ -35,7 +38,20 @@
3538
state.transform.position.z = sz
3639
npc = sim.add_agent("Sedan", lgsvl.AgentType.NPC, state)
3740

38-
# snake-drive
41+
vehicles = {
42+
a: "EGO",
43+
npc: "Sedan",
44+
}
45+
46+
# Executed upon receiving collision callback -- NPC is expected to drive through colliding objects
47+
def on_collision(agent1, agent2, contact):
48+
name1 = vehicles[agent1]
49+
name2 = vehicles[agent2] if agent2 is not None else "OBSTACLE"
50+
print("{} collided with {}".format(name1, name2))
51+
52+
a.on_collision(on_collision)
53+
npc.on_collision(on_collision)
54+
3955
# This block creates the list of waypoints that the NPC will follow
4056
# Each waypoint is an position vector paired with the speed that the NPC will drive to it
4157
waypoints = []
@@ -46,18 +62,19 @@
4662
layer_mask |= 1 << 0 # 0 is the layer for the road (default)
4763

4864
for i in range(20):
49-
speed = 6 if i % 2 == 0 else 12
50-
px = x_max * (-1 if i % 2 == 0 else 1)
65+
speed = 24# if i % 2 == 0 else 12
66+
px = 0
5167
pz = (i + 1) * z_delta
52-
68+
# Waypoint angles are input as Euler angles (roll, pitch, yaw)
69+
angle = lgsvl.Vector(0, 0, 0)
5370
# Raycast the points onto the ground because BorregasAve is not flat
5471
hit = sim.raycast(lgsvl.Vector(sx + px, sy, sz + pz), lgsvl.Vector(0,-1,0), layer_mask)
5572

56-
wp = lgsvl.DriveWaypoint(hit.point, speed)
57-
#wp = lgsvl.DriveWaypoint(lgsvl.Vector(sx + px, sy, sz + pz), speed)
73+
# NPC will wait for 1 second at each waypoint
74+
wp = lgsvl.DriveWaypoint(hit.point, speed, angle, 1, 0)
5875
waypoints.append(wp)
5976

60-
# When the NPC is within 1m of the waypoint, this will be called
77+
# When the NPC is within 0.5m of the waypoint, this will be called
6178
def on_waypoint(agent, index):
6279
print("waypoint {} reached".format(index))
6380

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
#!/usr/bin/env python3
2+
#
3+
# Copyright (c) 2019 LG Electronics, Inc.
4+
#
5+
# This software contains code licensed as described in LICENSE.
6+
#
7+
8+
import os
9+
import lgsvl
10+
import math
11+
12+
sim = lgsvl.Simulator(os.environ.get("SIMULATOR_HOST", "127.0.0.1"), 8181)
13+
if sim.current_scene == "BorregasAve":
14+
sim.reset()
15+
else:
16+
sim.load("BorregasAve")
17+
18+
spawns = sim.get_spawn()
19+
20+
# EGO
21+
22+
state = lgsvl.AgentState()
23+
state.transform = spawns[0]
24+
a = sim.add_agent("Jaguar2015XE (Apollo 5.0)", lgsvl.AgentType.EGO, state)
25+
26+
# NPC, 10 meters ahead
27+
28+
sx = spawns[0].position.x
29+
sy = spawns[0].position.y
30+
sz = spawns[0].position.z + 10.0
31+
32+
state = lgsvl.AgentState()
33+
state.transform = spawns[0]
34+
state.transform.position.x = sx
35+
state.transform.position.z = sz
36+
npc = sim.add_agent("Sedan", lgsvl.AgentType.NPC, state)
37+
38+
39+
# This block creates the list of waypoints that the NPC will follow
40+
# Each waypoint consists of a position vector, speed, and an angular orientation vector
41+
waypoints = []
42+
x_max = 2
43+
y_max = 2
44+
z_delta = 12
45+
46+
layer_mask = 0
47+
layer_mask |= 1 << 0 # 0 is the layer for the road (default)
48+
px = 0
49+
py = 0.5
50+
51+
for i in range(75):
52+
speed = 6
53+
px = 0
54+
py = ((i + 1) * 0.05) if (i < 50) else (50 * 0.05 + (50 - i) * 0.05)
55+
pz = i * z_delta * 0.05
56+
57+
angle = lgsvl.Vector(i, 0, 3*i)
58+
59+
# Raycast the points onto the ground because BorregasAve is not flat
60+
hit = sim.raycast(lgsvl.Vector(sx + px, sy, sz + pz), lgsvl.Vector(0,-1,0), layer_mask)
61+
62+
wp = lgsvl.DriveWaypoint(lgsvl.Vector(sx + px, sy + py, sz + pz), speed, angle, 0, 0)
63+
waypoints.append(wp)
64+
65+
# When the NPC is within 1m of the waypoint, this will be called
66+
def on_waypoint(agent, index):
67+
print("waypoint {} reached".format(index))
68+
69+
# The above function needs to be added to the list of callbacks for the NPC
70+
npc.on_waypoint_reached(on_waypoint)
71+
72+
# The NPC needs to be given the list of waypoints.
73+
# A bool can be passed as the 2nd argument that controls whether or not the NPC loops over the waypoints (default false)
74+
npc.follow(waypoints)
75+
76+
input("Press Enter to run")
77+
78+
sim.run()
Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
#!/usr/bin/env python3
2+
#
3+
# Copyright (c) 2019 LG Electronics, Inc.
4+
#
5+
# This software contains code licensed as described in LICENSE.
6+
#
7+
8+
import os
9+
import lgsvl
10+
import math
11+
12+
sim = lgsvl.Simulator(os.environ.get("SIMULATOR_HOST", "127.0.0.1"), 8181)
13+
if sim.current_scene == "BorregasAve":
14+
sim.reset()
15+
else:
16+
sim.load("BorregasAve")
17+
18+
spawns = sim.get_spawn()
19+
20+
# EGO
21+
22+
state = lgsvl.AgentState()
23+
state.transform = spawns[0]
24+
a = sim.add_agent("Jaguar2015XE (Apollo 5.0)", lgsvl.AgentType.EGO, state)
25+
26+
# NPC, 10 meters ahead
27+
28+
sx = spawns[0].position.x
29+
sy = spawns[0].position.y
30+
sz = spawns[0].position.z + 10.0
31+
32+
state = lgsvl.AgentState()
33+
state.transform = spawns[0]
34+
state.transform.position.x = sx
35+
state.transform.position.z = sz
36+
npc = sim.add_agent("Sedan", lgsvl.AgentType.NPC, state)
37+
38+
vehicles = {
39+
a: "EGO",
40+
npc: "Sedan",
41+
}
42+
43+
# Executed upon receiving collision callback -- NPC is expected to drive through colliding objects
44+
def on_collision(agent1, agent2, contact):
45+
name1 = vehicles[agent1]
46+
name2 = vehicles[agent2] if agent2 is not None else "OBSTACLE"
47+
print("{} collided with {}".format(name1, name2))
48+
49+
a.on_collision(on_collision)
50+
npc.on_collision(on_collision)
51+
52+
# This block creates the list of waypoints that the NPC will follow
53+
# Each waypoint is an position vector paired with the speed that the NPC will drive to it
54+
waypoints = []
55+
x_max = 2
56+
z_delta = 12
57+
58+
layer_mask = 0
59+
layer_mask |= 1 << 0 # 0 is the layer for the road (default)
60+
61+
for i in range(20):
62+
speed = 24# if i % 2 == 0 else 12
63+
px = 0
64+
pz = (i + 1) * z_delta
65+
# Waypoint angles are input as Euler angles (roll, pitch, yaw)
66+
angle = lgsvl.Vector(0, 0, 0)
67+
# Raycast the points onto the ground because BorregasAve is not flat
68+
hit = sim.raycast(lgsvl.Vector(sx + px, sy, sz + pz), lgsvl.Vector(0,-1,0), layer_mask)
69+
70+
# Trigger is set to 10 meters for every other waypoint (0 means no trigger)
71+
tr = 0
72+
if (i % 2):
73+
tr = 10
74+
wp = lgsvl.DriveWaypoint(hit.point, speed, angle, 0, tr)
75+
waypoints.append(wp)
76+
77+
# When the NPC is within 0.5m of the waypoint, this will be called
78+
def on_waypoint(agent, index):
79+
print("waypoint {} reached".format(index))
80+
81+
# The above function needs to be added to the list of callbacks for the NPC
82+
npc.on_waypoint_reached(on_waypoint)
83+
84+
# The NPC needs to be given the list of waypoints.
85+
# A bool can be passed as the 2nd argument that controls whether or not the NPC loops over the waypoints (default false)
86+
npc.follow(waypoints)
87+
88+
input("Press Enter to run")
89+
90+
sim.run()

0 commit comments

Comments
 (0)