Controllable - ChargingStation
This contains detailed documentation on the ChargingStation controllable plugin.
To use this Controllable Plugin:
1) Clone the repo into Assets/External/Controllables/ChargingStation inside of your Simulator Unity Project
2) Build the Controllable Plugin for use with the Simulator, navigate to the Simulator -> Build Controllables
Unity Editor menu item. Select ChargingStation controllable and build. Output bundle will be in AssetBundles/Controllables folder in root of Simulator Unity Project
3) Simulator will load, at runtime, all custom Controllable Plugin bundles in AssetBundles/Controllables directory
Custom Logic top#
To implement custom logic, contained in a given Controllable Plugin project there must be an IControllable
The interface requires the following to be implemented:
public bool Spawned { get; set; } = false;
public string UID { get; set; }
public string GUID => UID;
public string ControlType { get; set; } = "chargingstation";
public string CurrentState { get; set; }
public string[] ValidStates { get; set; } = new[] { "on", "off" };
public string[] ValidActions { get; set; } = new string[] { };
public List<ControlAction> DefaultControlPolicy { get; set; } =
new List<ControlAction>
{
new ControlAction { Action = "state", Value = "off" }
};
public List<ControlAction> CurrentControlPolicy { get; set; }
public Control(List<ControlAction> controlActions)
{
//
}
On Awake()
CurrentControlPolicy and CurrentState must be set, e.g.
private void Awake()
{
Lights.AddRange(GetComponentsInChildren<Light>());
SetLights(false);
ChargingStationRenderer = GetComponent<Renderer>();
foreach (var mat in ChargingStationRenderer.materials)
{
if (mat.name.Contains("Emission"))
{
EmissionMaterials.Add(mat);
}
}
CurrentControlPolicy = DefaultControlPolicy;
Control(CurrentControlPolicy);
}
Control checks the parsed ControlActions and sets the CurrentState
public void Control(List<ControlAction> controlActions)
{
foreach (var action in controlActions)
{
switch (action.Action)
{
case "state":
SetChargingStationState(action.Value);
break;
default:
Debug.LogError($"'{action.Value}' is an invalid action for '{ControlType}'");
break;
}
}
}
public void SetChargingStationState(string value)
{
if (!ValidStates.Contains(value))
{
Debug.LogError($"'{value}' is an invalid state for '{ControlType}'");
return;
}
CurrentState = value;
switch (CurrentState)
{
case "on":
EmissionMaterials?.ForEach(x => x.SetColor("_EmissiveColor", Color.white));
EmissionMaterials?.ForEach(x => x.SetFloat("_EmissiveIntensity", 3f));
SetLights(true);
break;
case "off":
EmissionMaterials?.ForEach(x => x.SetColor("_EmissiveColor", Color.black));
EmissionMaterials?.ForEach(x => x.SetFloat("_EmissiveIntensity", 0f));
SetLights(false);
break;
default:
break;
}
}
private void SetLights(bool state)
{
Lights.ForEach(l => l.enabled = state);
}
Python API example top#
Each controllable object has its own valid actions
(e.g., green, yellow, red, trigger, wait, loop, on, off, "") that it can take and is controlled based on control policy
, which defines rules for control actions.
To get a list of controllable objects in a scene:
controllables = sim.get_controllables()
For a controllable object of interest, you can get following information:
station = controllables[0]
print("Type:", station.type)
print("Transform:", station.transform)
print("Current state:", station.current_state)
print("Valid actions:", station.valid_actions)
For control policy, each controllable object always has default control policy (read-only). When you load a scene for the first time or reset a scene to the initial state, a controllable object resets current control policy to default one follows it.
You can get default control policy and current control policy as follows:
print("Default control policy:", station.default_control_policy)
print("Current control policy:", station.control_policy)
To change a current control policy, you can create a new control policy and call control
function as below:
control_policy = "on"
station.control(control_policy)
To add a plugin controllable and set object state
state = lgsvl.ObjectState()
state.transform.position = lgsvl.Vector(0,0,0)
state.transform.rotation = lgsvl.Vector(0,0,0)
state.velocity = lgsvl.Vector(0,10,0)
state.angular_velocity = lgsvl.Vector(6.5,0,0)
cone = sim.controllable_add("ChargingStation", state)
To get plugin controllable object state
station.object_state
To set plugin controllable object state
state = lgsvl.ObjectState()
state.transform.position = lgsvl.Vector(0, 0, -10)
station.object_state = state
Controllables can also have a Unity RigidBody component at the root and apply velocity from the API. If no rigidbody exists then the velocity is ignored.
#!/usr/bin/env python3
#
# Copyright (c) 2020-2021 LG Electronics, Inc.
#
# This software contains code licensed as described in LICENSE.
#
from environs import Env
import lgsvl
sim = lgsvl.Simulator(env.str("LGSVL__SIMULATOR_HOST", lgsvl.wise.SimulatorSettings.simulator_host), env.int("LGSVL__SIMULATOR_PORT", lgsvl.wise.SimulatorSettings.simulator_port))
if sim.current_scene == lgsvl.wise.DefaultAssets.map_borregasave:
sim.reset()
else:
sim.load(lgsvl.wise.DefaultAssets.map_borregasave)
spawns = sim.get_spawn()
state = lgsvl.AgentState()
forward = lgsvl.utils.transform_to_forward(spawns[0])
right = lgsvl.utils.transform_to_right(spawns[0])
up = lgsvl.utils.transform_to_up(spawns[0])
state.transform = spawns[0]
ego = sim.add_agent(env.str("LGSVL__VEHICLE_0", lgsvl.wise.DefaultAssets.ego_lincoln2017mkz_apollo5), lgsvl.AgentType.EGO, state)
print("Python API Quickstart #28: How to Add/Control Charging Station")
obj_state = lgsvl.ObjectState()
obj_state.transform.position = lgsvl.Vector(38, 0, 7)
obj_state.transform.rotation = lgsvl.Vector(0, 180, 0)
station = sim.controllable_add("ChargingStation", obj_state)
station = sim.get_controllable(lgsvl.Vector(38, 0, 7), "chargingstation")
print("\n# Charging Station of interest:")
print(station)
seconds = 1
input("\nPress Enter to run simulation for {} seconds".format(seconds))
print("\nRunning simulation for {} seconds...".format(seconds))
sim.run(seconds)
# Get current controllable state
print("\n# Current charging station control policy:")
print(station.control_policy)
print("\n# Current charging station object state")
print(station.object_state)
print("\n# Update charging station object state")
new_state = lgsvl.ObjectState()
new_state.transform.position = lgsvl.Vector(38, 0, 7)
new_state.transform.rotation = lgsvl.Vector(0, 180, 0)
station.object_state = new_state
print("\n# New object state")
print(station.object_state)
# Set time of day for light effects
sim.set_time_of_day(19.0)
print(sim.time_of_day)
# Create a new control policy
control_policy = "on"
# Control this traffic light with a new control policy
station.control(control_policy)
print("\n# Updated control policy:")
print(station.control_policy)
# Get current state of charging station
print("\n# Current station state:")
print(station.current_state)
print("\nDone!")