Skip to content

Commit 9f4de1f

Browse files
API controllables
1 parent fb9e159 commit 9f4de1f

File tree

6 files changed

+134
-53
lines changed

6 files changed

+134
-53
lines changed

lgsvl/__init__.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,5 +7,6 @@
77
from .geometry import Vector, BoundingBox, Transform
88
from .simulator import Simulator, RaycastHit, WeatherState
99
from .sensor import Sensor, CameraSensor, LidarSensor, ImuSensor
10-
from .agent import AgentType, VehicleControl, AgentState, Vehicle, EgoVehicle, NpcVehicle, Pedestrian, DriveWaypoint, WalkWaypoint, NPCControl
10+
from .agent import AgentType, AgentState, VehicleControl, Vehicle, EgoVehicle, NpcVehicle, Pedestrian, DriveWaypoint, WalkWaypoint, NPCControl
1111
from .controllable import Controllable
12+
from .utils import ObjectState

lgsvl/agent.py

Lines changed: 2 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66

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

1111
from enum import Enum
1212
from collections.abc import Iterable, Callable
@@ -55,54 +55,6 @@ def __init__(self):
5555
self.turn_signal_left = None # bool
5656
self.turn_signal_right = None # bool
5757

58-
59-
class AgentState:
60-
def __init__(self, transform = None, velocity = None, angular_velocity = None):
61-
if transform is None: transform = Transform()
62-
if velocity is None: velocity = Vector()
63-
if angular_velocity is None: angular_velocity = Vector()
64-
self.transform = transform
65-
self.velocity = velocity
66-
self.angular_velocity = angular_velocity
67-
68-
@property
69-
def position(self):
70-
return self.transform.position
71-
72-
@property
73-
def rotation(self):
74-
return self.transform.rotation
75-
76-
@property
77-
def speed(self):
78-
return math.sqrt(
79-
self.velocity.x * self.velocity.x +
80-
self.velocity.y * self.velocity.y +
81-
self.velocity.z * self.velocity.z)
82-
83-
@staticmethod
84-
def from_json(j):
85-
return AgentState(
86-
Transform.from_json(j["transform"]),
87-
Vector.from_json(j["velocity"]),
88-
Vector.from_json(j["angular_velocity"]),
89-
)
90-
91-
def to_json(self):
92-
return {
93-
"transform": self.transform.to_json(),
94-
"velocity": self.velocity.to_json(),
95-
"angular_velocity": self.angular_velocity.to_json(),
96-
}
97-
98-
def __repr__(self):
99-
return str({
100-
"transform": str(self.transform),
101-
"velocity": str(self.velocity),
102-
"angular_velocity": str(self.angular_velocity),
103-
})
104-
105-
10658
class Agent:
10759
def __init__(self, uid, simulator):
10860
self.uid = uid
@@ -335,3 +287,4 @@ def follow(self, waypoints, loop = False):
335287
def on_waypoint_reached(self, fn):
336288
self.remote.command("agent/on_waypoint_reached", {"uid": self.uid})
337289
self.simulator._add_callback(self, "waypoint_reached", fn)
290+

lgsvl/controllable.py

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@
44
# This software contains code licensed as described in LICENSE.
55
#
66

7-
from .geometry import Transform
8-
from .utils import accepts
7+
from .geometry import Vector, Transform
8+
from .utils import accepts, ObjectState
99

1010
class Controllable:
1111
def __init__(self, remote, j):
@@ -16,6 +16,19 @@ def __init__(self, remote, j):
1616
self.valid_actions = j["valid_actions"]
1717
self.default_control_policy = j["default_control_policy"]
1818

19+
@property
20+
def object_state(self):
21+
j = self.remote.command("controllable/object_state/get", {"uid": self.uid})
22+
return ObjectState.from_json(j)
23+
24+
@object_state.setter
25+
@accepts(ObjectState)
26+
def object_state(self, object_state):
27+
self.remote.command("controllable/object_state/set", {
28+
"uid": self.uid,
29+
"state": object_state.to_json()
30+
})
31+
1932
@property
2033
def current_state(self):
2134
j = self.remote.command("controllable/current_state/get", {"uid": self.uid})

lgsvl/simulator.py

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
from .agent import Agent, AgentType, AgentState
99
from .sensor import GpsData
1010
from .geometry import Vector, Transform
11-
from .utils import accepts
11+
from .utils import accepts, ObjectState
1212
from .controllable import Controllable
1313

1414
from collections import namedtuple
@@ -240,6 +240,20 @@ def raycast_batch(self, args):
240240

241241
return results
242242

243+
@accepts(str, ObjectState)
244+
def controllable_add(self, name, object_state = None):
245+
if object_state is None: object_state = ObjectState()
246+
args = {"name": name, "state": object_state.to_json()}
247+
j = self.remote.command("simulator/controllable_add", args)
248+
controllable = Controllable(self.remote, j)
249+
controllable.name = name
250+
return controllable
251+
252+
@accepts(Controllable)
253+
def controllable_remove(self, controllable):
254+
self.remote.command("simulator/controllable_remove", {"uid": controllable.uid})
255+
del self.controllables[controllable.uid]
256+
243257
@accepts(str)
244258
def get_controllables(self, control_type = None):
245259
j = self.remote.command("controllable/get/all", {

lgsvl/utils.py

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,51 @@ def new_f(*args, **kwargs):
2323
return new_f
2424
return check_accepts
2525

26+
class ObjectState:
27+
def __init__(self, transform = None, velocity = None, angular_velocity = None):
28+
if transform is None: transform = Transform()
29+
if velocity is None: velocity = Vector()
30+
if angular_velocity is None: angular_velocity = Vector()
31+
self.transform = transform
32+
self.velocity = velocity
33+
self.angular_velocity = angular_velocity
34+
35+
@property
36+
def position(self):
37+
return self.transform.position
38+
39+
@property
40+
def rotation(self):
41+
return self.transform.rotation
42+
43+
@property
44+
def speed(self):
45+
return math.sqrt(
46+
self.velocity.x * self.velocity.x +
47+
self.velocity.y * self.velocity.y +
48+
self.velocity.z * self.velocity.z)
49+
50+
@staticmethod
51+
def from_json(j):
52+
return ObjectState(
53+
Transform.from_json(j["transform"]),
54+
Vector.from_json(j["velocity"]),
55+
Vector.from_json(j["angular_velocity"]),
56+
)
57+
58+
def to_json(self):
59+
return {
60+
"transform": self.transform.to_json(),
61+
"velocity": self.velocity.to_json(),
62+
"angular_velocity": self.angular_velocity.to_json(),
63+
}
64+
65+
def __repr__(self):
66+
return str({
67+
"transform": str(self.transform),
68+
"velocity": str(self.velocity),
69+
"angular_velocity": str(self.angular_velocity),
70+
})
2671

2772
def transform_to_matrix(tr):
2873
px = tr.position.x
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
#!/usr/bin/env python3
2+
#
3+
# Copyright (c) 2020 LG Electronics, Inc.
4+
#
5+
# This software contains code licensed as described in LICENSE.
6+
#
7+
8+
import os
9+
import lgsvl
10+
11+
sim = lgsvl.Simulator(os.environ.get("SIMULATOR_HOST", "127.0.0.1"), 8181)
12+
13+
scene_name = "CubeTown"
14+
15+
if sim.current_scene == scene_name:
16+
sim.reset()
17+
else:
18+
sim.load(scene_name, 42)
19+
20+
spawns = sim.get_spawn()
21+
22+
state = lgsvl.AgentState()
23+
forward = lgsvl.utils.transform_to_forward(spawns[0])
24+
right = lgsvl.utils.transform_to_right(spawns[0])
25+
up = lgsvl.utils.transform_to_up(spawns[0])
26+
state.transform = spawns[0]
27+
28+
ego = sim.add_agent("Lincoln2017MKZ (Apollo 5.0)", lgsvl.AgentType.EGO, state)
29+
30+
print("Python API Quickstart #28: How to Add/Control Traffic Cone")
31+
32+
for i in range(10*3):
33+
# Create controllables in a block
34+
start = spawns[0].position + (5 + (1.0 * (i//6))) * forward - (2 + (1.0 * (i % 6))) * right
35+
end = start + 10 * forward
36+
37+
state = lgsvl.ObjectState()
38+
state.transform.position = start
39+
state.transform.rotation = spawns[0].rotation
40+
# Set velocity and angular_velocity
41+
state.velocity = 10 * up
42+
state.angular_velocity = 6.5 * right
43+
44+
# add controllable
45+
o = sim.controllable_add("TrafficCone", state)
46+
47+
48+
print("\nAdded {} Traffic Cones".format(i + 1))
49+
50+
seconds = 10
51+
input("\nPress Enter to run simulation for {} seconds".format(seconds))
52+
print("\nRunning simulation for {} seconds...".format(seconds))
53+
sim.run(seconds)
54+
55+
print("\nDone!")

0 commit comments

Comments
 (0)