symbolic
Symbolic expression system for trajectory optimization.
See openscvx.symbolic.expr for detailed documentation and examples.
ConstraintSet
dataclass
¶
Container for categorized symbolic constraints.
This dataclass holds all symbolic constraint types in a structured way, providing type safety and a clear API for accessing constraint categories. This is a pre-lowering container - after lowering, constraints live in LoweredJaxConstraints and LoweredCvxpyConstraints.
The constraint set supports two lifecycle stages:
- Before preprocessing: Raw constraints live in
unsorted - After preprocessing:
unsortedis empty, constraints are categorized
Use is_categorized to check which stage the constraint set is in.
Attributes:
| Name | Type | Description |
|---|---|---|
unsorted |
List[Union[Constraint, CTCS]]
|
Raw constraints before categorization. Empty after preprocessing. |
ctcs |
List[CTCS]
|
CTCS (continuous-time) constraints. |
nodal |
List[NodalConstraint]
|
Non-convex nodal constraints (will be lowered to JAX). |
nodal_convex |
List[NodalConstraint]
|
Convex nodal constraints (will be lowered to CVXPy). |
cross_node |
List[CrossNodeConstraint]
|
Non-convex cross-node constraints (will be lowered to JAX). |
cross_node_convex |
List[CrossNodeConstraint]
|
Convex cross-node constraints (will be lowered to CVXPy). |
Example
Before preprocessing (raw constraints)::
constraints = ConstraintSet(unsorted=[c1, c2, c3])
assert not constraints.is_categorized
After preprocessing (categorized)::
# preprocess_symbolic_problem drains unsorted -> fills categories
assert constraints.is_categorized
for c in constraints.nodal:
# Process non-convex nodal constraints
pass
Source code in openscvx/symbolic/constraint_set.py
is_categorized: bool
property
¶
True if all constraints have been sorted into categories.
After preprocessing, unsorted should be empty and all constraints
should be in their appropriate category lists.
SymbolicProblem
dataclass
¶
Container for symbolic problem specification.
This dataclass holds a trajectory optimization problem in symbolic form, either as raw user input or after preprocessing/augmentation. It provides a typed interface for the preprocessing and lowering pipeline.
Lifecycle Stages
- Before preprocessing: User creates with raw dynamics, states, controls, and unsorted constraints. Propagation fields are None.
- After preprocessing: Dynamics and states are augmented (CTCS, time dilation), constraints are categorized, propagation fields are populated.
Use is_preprocessed to check whether preprocessing has completed.
Attributes:
| Name | Type | Description |
|---|---|---|
dynamics |
Expr
|
Symbolic dynamics expression (dx/dt = f(x, u)). After preprocessing, includes CTCS augmented state dynamics. |
states |
List[State]
|
List of State objects. After preprocessing, includes time state and CTCS augmented states. |
controls |
List[Control]
|
List of Control objects. After preprocessing, includes time dilation control. |
constraints |
ConstraintSet
|
ConstraintSet holding all constraints. Before preprocessing,
raw constraints live in |
parameters |
Dict[str, any]
|
Dictionary mapping parameter names to numpy arrays. |
N |
int
|
Number of discretization nodes. |
node_intervals |
List[Tuple[int, int]]
|
List of (start, end) tuples for CTCS constraint intervals. Populated during preprocessing when CTCS constraints are sorted. |
dynamics_prop |
Optional[Expr]
|
Propagation dynamics (may include extra states). None before preprocessing, populated after. |
states_prop |
Optional[List[State]]
|
Propagation states (may include extra states). None before preprocessing, populated after. |
controls_prop |
Optional[List[Control]]
|
Propagation controls (typically same as controls). None before preprocessing, populated after. |
Example
Before preprocessing::
problem = SymbolicProblem(
dynamics=dynamics_expr,
states=[x, v],
controls=[u],
constraints=ConstraintSet(unsorted=[c1, c2, c3]),
parameters={"mass": 1.0},
N=50,
)
assert not problem.is_preprocessed
After preprocessing::
processed = preprocess_symbolic_problem(problem, time=time_config)
assert processed.is_preprocessed
assert processed.constraints.is_categorized
# Now ready for lowering
lowered = lower_symbolic_problem(processed)
Source code in openscvx/symbolic/problem.py
is_preprocessed: bool
property
¶
True if the problem has been preprocessed and is ready for lowering.
A problem is considered preprocessed when: 1. All constraints have been categorized (unsorted is empty) 2. Propagation dynamics have been set up