|
|
lucid
0.0.1
Lifting-based Uncertain Control Invariant Dynamics
|
Lucid supports a wide range of configuration options and can run on systems with different parameters. Hence, it is important to understand how to configure Lucid for your specific use case.
For the user's convenience, Lucid can be configured from the command line or through a configuration file. Moreover, the configuration can be expressed as a json or yaml file for convenience, or as an arbitrary Python script for a complex custom configuration.
The command line options are used to configure Lucid at runtime. Lucid will run a default scenario with the parameters provided through the command line. To know the available options, you can run the following command:
lucid --helpFor example, you can run Lucid with the following command:
lucid --verbose 3 \
--seed 42 \
--system_dynamics "x1**2 + x2 / 2 + cos(x3)" "2 * x1 + sin(-x2)" \
--X_bounds "RectSet([-3, -2, 0.1], [2.5, 1, 0.2])" \
--X_init "MultiSet([RectSet([0.1, 0.2], [0.1, 0.2], [0.1, 0.2]), SphereSet([0.7, -0.7], 0.3)])" \
--X_unsafe "RectSet([0.4, 0.1, 1], [0.8, 0.3, 0])" \
--gamma 10.0 \
--C_coeff 1.0 \
--lambda 0.0001 \
--num_samples 1000 \
--time_horizon 10 \
--sigma_f 15.1 \
--sigma_l 1.1 2.0 3.0 \
--num_frequencies 4 \
--oversample_factor 2.1 \
--lattice_resolution -1 \
--noise_scale 0.01 \
--plot true \
--verify true \
--problem_log_file "problem.lp" \
--iis_log_file "iis.ilp"YAML configuration (recommended)
Create a file named config.yaml and define your configuration options. You can use the following example as a template:
# yaml-language-server: \f$schema=https://tendto.github.io/lucid/configuration_schema.json
# Basic configuration
verbose: 3 # LOG_INFO
seed: 42
# System transition function
# (x1, x2, ..., xn) are the components of the n-dimensional input state space
# All components of the input state space must appear in the system dynamics
# Each element of the list corresponds to a component of the output state space
# E.g., the following system has 3D input state space (x1, x2, x3)
# and 2D output state space (y1, y2)
system_dynamics:
- x1**2 + x2 / 2 + cos(x3) # y1
- 2 * x1 + sin(-x2) # y2
# Sets definition
# RectSets can be defined 3 ways:
X_bounds:
RectSet: # - As a pair of lower and upper bounds
lower: [-3, -2, 0.1]
upper: [2.5, 1, 0.2]
X_init:
MultiSet: # MultiSet are just lists of RectSets
- RectSet: # - As a list of lower and upper bounds pair for each dimension
- [0.1, 0.2]
- [0.1, 0.2]
- [0.1, 0.2]
- SphereSet:
center: [0.7, -0.7]
radius: 0.3
X_unsafe: "RectSet([0.4, 0.1, 1], [0.8, 0.3, 0])" # - As a string
# Algorithm parameters
gamma: 10.0
C_coeff: 1.0
lambda: 0.0001
num_samples: 1000
time_horizon: 10
# Feature map parameters
sigma_f: 15.1
sigma_l: [1.1, 2.0, 3.0] # Can be a single float or a list
num_frequencies: 4
oversample_factor: 2.1
lattice_resolution: -1
# Execution options
noise_scale: 0.01
plot: true
verify: true
# Output options
problem_log_file: "problem.lp"
iis_log_file: "iis.ilp"Then, you can run Lucid with the following command:
lucid config.yamlThe full JSON schema of the configuration options can be found here.
JSON configuration
Create a file named config.json and define your configuration options. You can use the following example as a template:
{
"\f$schema": "https://tendto.github.io/lucid/configuration_schema.json",
// Basic configuration
"verbose": 3, // LOG_INFO
"seed": 42,
/*
* System transition function
* (x1, x2, ..., xn) are the components of the n-dimensional input state space
* All components of the input state space must appear in the system dynamics
* Each element of the list corresponds to a component of the output state space
* E.g., the following system has 3D input state space (x1, x2, x3)
* and 2D output state space (y1, y2)
*/
"system_dynamics": [
"x1**2 + x2 / 2 + cos(x3)", // y1
"2 * x1 + sin(-x2)" // y2
],
/*
* Sets definition
* RectSets can be defined 3 ways:
*/
"X_bounds": {
// - As a pair of lower and upper bounds
"RectSet": {
"lower": [-3, -2, 0.1],
"upper": [2.5, 1, 0.2]
}
},
"X_init": {
// MultiSet are just lists of RectSets
"MultiSet": [
{
// - As a list of lower and upper bounds pair for each dimension
"RectSet": [
[0.1, 0.2],
[0.1, 0.2],
[0.1, 0.2]
]
},
{
"SphereSet": {
"center": [0.7, -0.7],
"radius": 0.3
}
}
]
},
// - As a string
"X_unsafe": "RectSet([0.4, 0.1, 1], [0.8, 0.3, 0])",
"gamma": 10.0,
"C_coeff": 1.0,
"lambda": 0.0001,
"num_samples": 1000,
"time_horizon": 10,
"sigma_f": 15.1,
"sigma_l": [1.1, 2.0, 3.0],
"num_frequencies": 4,
"oversample_factor": 2.1,
"lattice_resolution": -1,
"noise_scale": 0.01,
"plot": true,
"verify": true,
"problem_log_file": "problem.lp",
"iis_log_file": "iis.ilp"
}Then, you can run Lucid with the following command:
lucid config.jsonThe full JSON schema of the configuration options can be found here.
Python configuration
Create a file named config.py and define your configuration options. There are no restrictions on how what you do in the script, as long as you define a scenario_config(args: Configuration) function that returns a Configuration object. For example:
# my_config.py
from pylucid import *
# args will contain the command line arguments and default values.
# You can choose to use or ignore them.
def scenario_config(args: Configuration) -> Configuration:
# Model
args.system_dynamics = lambda x: 0.5 * x
noisy_system_dynamics = lambda x: args.system_dynamics(x) + np.random.normal(scale=args.noise_scale)
# Sets
args.X_bounds = RectSet([(-1, 1)])
args.X_init = RectSet([(-0.5, 0.5)])
args.X_unsafe = MultiSet(RectSet([(-1, -0.9)]),
SphereSet(center=(0.7, -0.7), radius=0.3))
# Sampling
args.x_samples = args.X_bounds.sample(args.num_samples)
args.xp_samples = noisy_system_dynamics(args.x_samples)
# Estimator
args.estimator = KernelRidgeRegressor(
kernel=GaussianKernel(sigma_f=args.sigma_f, sigma_l=args.sigma_l),
regularization_constant=args.lambda_,
)
# Oversampling
args.oversample_factor = 16.0
# Plotting and verification
args.plot = True
args.verify = True
# You have to return a Configuration object
return argsThen, you can run Lucid with the following command:
lucid config.py
Configuration files and command line options can be mixed, but with a few caveats.
pylucid config.yaml --verbose 2 first applies the configuration from config.yaml and then overrides verbose with the value 2.pylucid --verbose 2 config.yaml first sets verbose to 2 and then overrides it with the value from config.yaml, if presentpylucid config.py --verbose 2 will forward the verbose argument to the user's scenario_config function, which can then choose to use it or ignore it.