openscvx 0.4.1.dev140__tar.gz → 0.4.1.dev144__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {openscvx-0.4.1.dev140/openscvx.egg-info → openscvx-0.4.1.dev144}/PKG-INFO +1 -1
- {openscvx-0.4.1.dev140 → openscvx-0.4.1.dev144}/openscvx/_version.py +3 -3
- {openscvx-0.4.1.dev140 → openscvx-0.4.1.dev144}/openscvx/algorithms/__init__.py +2 -1
- {openscvx-0.4.1.dev140 → openscvx-0.4.1.dev144}/openscvx/algorithms/augmented_lagrangian.py +12 -6
- {openscvx-0.4.1.dev140 → openscvx-0.4.1.dev144}/openscvx/algorithms/base.py +181 -25
- {openscvx-0.4.1.dev140 → openscvx-0.4.1.dev144}/openscvx/algorithms/penalized_trust_region.py +8 -10
- {openscvx-0.4.1.dev140 → openscvx-0.4.1.dev144}/openscvx/lowered/cvxpy_variables.py +4 -2
- {openscvx-0.4.1.dev140 → openscvx-0.4.1.dev144}/openscvx/problem.py +14 -0
- {openscvx-0.4.1.dev140 → openscvx-0.4.1.dev144}/openscvx/propagation/post_processing.py +35 -4
- {openscvx-0.4.1.dev140 → openscvx-0.4.1.dev144}/openscvx/solvers/base.py +1 -1
- {openscvx-0.4.1.dev140 → openscvx-0.4.1.dev144}/openscvx/solvers/ptr_solver.py +15 -8
- {openscvx-0.4.1.dev140 → openscvx-0.4.1.dev144}/openscvx/symbolic/augmentation.py +43 -1
- {openscvx-0.4.1.dev140 → openscvx-0.4.1.dev144}/openscvx/symbolic/expr/constraint.py +106 -4
- {openscvx-0.4.1.dev140 → openscvx-0.4.1.dev144}/openscvx/symbolic/lower.py +4 -2
- {openscvx-0.4.1.dev140 → openscvx-0.4.1.dev144/openscvx.egg-info}/PKG-INFO +1 -1
- {openscvx-0.4.1.dev140 → openscvx-0.4.1.dev144}/tests/test_autotuning.py +100 -35
- {openscvx-0.4.1.dev140 → openscvx-0.4.1.dev144}/.github/assets/logo.svg +0 -0
- {openscvx-0.4.1.dev140 → openscvx-0.4.1.dev144}/.github/release-drafter.yml +0 -0
- {openscvx-0.4.1.dev140 → openscvx-0.4.1.dev144}/.github/workflows/_docs.yml +0 -0
- {openscvx-0.4.1.dev140 → openscvx-0.4.1.dev144}/.github/workflows/branch-name.yml +0 -0
- {openscvx-0.4.1.dev140 → openscvx-0.4.1.dev144}/.github/workflows/docs.yml +0 -0
- {openscvx-0.4.1.dev140 → openscvx-0.4.1.dev144}/.github/workflows/lint.yml +0 -0
- {openscvx-0.4.1.dev140 → openscvx-0.4.1.dev144}/.github/workflows/nightly.yml +0 -0
- {openscvx-0.4.1.dev140 → openscvx-0.4.1.dev144}/.github/workflows/release-drafter.yml +0 -0
- {openscvx-0.4.1.dev140 → openscvx-0.4.1.dev144}/.github/workflows/release.yml +0 -0
- {openscvx-0.4.1.dev140 → openscvx-0.4.1.dev144}/.github/workflows/tests-integration.yml +0 -0
- {openscvx-0.4.1.dev140 → openscvx-0.4.1.dev144}/.github/workflows/tests-unit.yml +0 -0
- {openscvx-0.4.1.dev140 → openscvx-0.4.1.dev144}/.gitignore +0 -0
- {openscvx-0.4.1.dev140 → openscvx-0.4.1.dev144}/CONTRIBUTING.md +0 -0
- {openscvx-0.4.1.dev140 → openscvx-0.4.1.dev144}/LICENSE +0 -0
- {openscvx-0.4.1.dev140 → openscvx-0.4.1.dev144}/README.md +0 -0
- {openscvx-0.4.1.dev140 → openscvx-0.4.1.dev144}/docs/Foundations/constraint_reformulation.md +0 -0
- {openscvx-0.4.1.dev140 → openscvx-0.4.1.dev144}/docs/Foundations/control_parameterization.md +0 -0
- {openscvx-0.4.1.dev140 → openscvx-0.4.1.dev144}/docs/Foundations/discretization.md +0 -0
- {openscvx-0.4.1.dev140 → openscvx-0.4.1.dev144}/docs/Foundations/ocp.md +0 -0
- {openscvx-0.4.1.dev140 → openscvx-0.4.1.dev144}/docs/Foundations/scvx.md +0 -0
- {openscvx-0.4.1.dev140 → openscvx-0.4.1.dev144}/docs/Foundations/time_dilation.md +0 -0
- {openscvx-0.4.1.dev140 → openscvx-0.4.1.dev144}/docs/UnderTheHood/lowering_architecture.md +0 -0
- {openscvx-0.4.1.dev140 → openscvx-0.4.1.dev144}/docs/UnderTheHood/vectorization_and_vmapping.md +0 -0
- {openscvx-0.4.1.dev140 → openscvx-0.4.1.dev144}/docs/UsersGuide/00_introduction.md +0 -0
- {openscvx-0.4.1.dev140 → openscvx-0.4.1.dev144}/docs/UsersGuide/01_hello_world_brachistochrone.md +0 -0
- {openscvx-0.4.1.dev140 → openscvx-0.4.1.dev144}/docs/UsersGuide/02_drone_racing_constraints.md +0 -0
- {openscvx-0.4.1.dev140 → openscvx-0.4.1.dev144}/docs/UsersGuide/03_obstacle_avoidance_vmap.md +0 -0
- {openscvx-0.4.1.dev140 → openscvx-0.4.1.dev144}/docs/UsersGuide/04_viewpoint_constraints.md +0 -0
- {openscvx-0.4.1.dev140 → openscvx-0.4.1.dev144}/docs/UsersGuide/05_visualization.md +0 -0
- {openscvx-0.4.1.dev140 → openscvx-0.4.1.dev144}/docs/UsersGuide/06_logic.md +0 -0
- {openscvx-0.4.1.dev140 → openscvx-0.4.1.dev144}/docs/UsersGuide/07_lie.md +0 -0
- {openscvx-0.4.1.dev140 → openscvx-0.4.1.dev144}/docs/assets/favicon.png +0 -0
- {openscvx-0.4.1.dev140 → openscvx-0.4.1.dev144}/docs/assets/images/ct-scvx_dark.png +0 -0
- {openscvx-0.4.1.dev140 → openscvx-0.4.1.dev144}/docs/assets/images/ct-scvx_light.png +0 -0
- {openscvx-0.4.1.dev140 → openscvx-0.4.1.dev144}/docs/assets/images/ctcs_dark.png +0 -0
- {openscvx-0.4.1.dev140 → openscvx-0.4.1.dev144}/docs/assets/images/ctcs_light.png +0 -0
- {openscvx-0.4.1.dev140 → openscvx-0.4.1.dev144}/docs/assets/images/problem_class_dark.png +0 -0
- {openscvx-0.4.1.dev140 → openscvx-0.4.1.dev144}/docs/assets/images/problem_class_light.png +0 -0
- {openscvx-0.4.1.dev140 → openscvx-0.4.1.dev144}/docs/assets/logo.svg +0 -0
- {openscvx-0.4.1.dev140 → openscvx-0.4.1.dev144}/docs/citation.md +0 -0
- {openscvx-0.4.1.dev140 → openscvx-0.4.1.dev144}/docs/examples.md +0 -0
- {openscvx-0.4.1.dev140 → openscvx-0.4.1.dev144}/docs/getting-started.md +0 -0
- {openscvx-0.4.1.dev140 → openscvx-0.4.1.dev144}/docs/index.md +0 -0
- {openscvx-0.4.1.dev140 → openscvx-0.4.1.dev144}/docs/javascripts/mathjax.js +0 -0
- {openscvx-0.4.1.dev140 → openscvx-0.4.1.dev144}/examples/abstract/brachistochrone.py +0 -0
- {openscvx-0.4.1.dev140 → openscvx-0.4.1.dev144}/examples/abstract/impulsive.py +0 -0
- {openscvx-0.4.1.dev140 → openscvx-0.4.1.dev144}/examples/arm/three_link_arm.py +0 -0
- {openscvx-0.4.1.dev140 → openscvx-0.4.1.dev144}/examples/car/dubins_car.py +0 -0
- {openscvx-0.4.1.dev140 → openscvx-0.4.1.dev144}/examples/car/dubins_car_conditional.py +0 -0
- {openscvx-0.4.1.dev140 → openscvx-0.4.1.dev144}/examples/car/dubins_car_disjoint.py +0 -0
- {openscvx-0.4.1.dev140 → openscvx-0.4.1.dev144}/examples/car/dubins_car_stljax.py +0 -0
- {openscvx-0.4.1.dev140 → openscvx-0.4.1.dev144}/examples/drone/cinema_vp.py +0 -0
- {openscvx-0.4.1.dev140 → openscvx-0.4.1.dev144}/examples/drone/dr_double_integrator.py +0 -0
- {openscvx-0.4.1.dev140 → openscvx-0.4.1.dev144}/examples/drone/dr_vp.py +0 -0
- {openscvx-0.4.1.dev140 → openscvx-0.4.1.dev144}/examples/drone/dr_vp_nodal.py +0 -0
- {openscvx-0.4.1.dev140 → openscvx-0.4.1.dev144}/examples/drone/dr_vp_polytope.py +0 -0
- {openscvx-0.4.1.dev140 → openscvx-0.4.1.dev144}/examples/drone/drone_racing.py +0 -0
- {openscvx-0.4.1.dev140 → openscvx-0.4.1.dev144}/examples/drone/logo.py +0 -0
- {openscvx-0.4.1.dev140 → openscvx-0.4.1.dev144}/examples/drone/logo_utils/acl_logo.svg +0 -0
- {openscvx-0.4.1.dev140 → openscvx-0.4.1.dev144}/examples/drone/logo_utils/svg_path_utils.py +0 -0
- {openscvx-0.4.1.dev140 → openscvx-0.4.1.dev144}/examples/drone/obstacle_avoidance.py +0 -0
- {openscvx-0.4.1.dev140 → openscvx-0.4.1.dev144}/examples/drone/obstacle_avoidance_nodal.py +0 -0
- {openscvx-0.4.1.dev140 → openscvx-0.4.1.dev144}/examples/drone/obstacle_avoidance_vmap.py +0 -0
- {openscvx-0.4.1.dev140 → openscvx-0.4.1.dev144}/examples/plotting.py +0 -0
- {openscvx-0.4.1.dev140 → openscvx-0.4.1.dev144}/examples/plotting_viser.py +0 -0
- {openscvx-0.4.1.dev140 → openscvx-0.4.1.dev144}/examples/realtime/base_problems/cinema_vp_realtime_base.py +0 -0
- {openscvx-0.4.1.dev140 → openscvx-0.4.1.dev144}/examples/realtime/base_problems/drone_racing_realtime_base.py +0 -0
- {openscvx-0.4.1.dev140 → openscvx-0.4.1.dev144}/examples/realtime/base_problems/obstacle_avoidance_realtime_base.py +0 -0
- {openscvx-0.4.1.dev140 → openscvx-0.4.1.dev144}/examples/realtime/cinema_vp_realtime.py +0 -0
- {openscvx-0.4.1.dev140 → openscvx-0.4.1.dev144}/examples/realtime/drone_racing_realtime.py +0 -0
- {openscvx-0.4.1.dev140 → openscvx-0.4.1.dev144}/examples/realtime/dubins_car_realtime.py +0 -0
- {openscvx-0.4.1.dev140 → openscvx-0.4.1.dev144}/examples/realtime/obstacle_avoidance_realtime.py +0 -0
- {openscvx-0.4.1.dev140 → openscvx-0.4.1.dev144}/examples/rocket/3DoF_pdg.py +0 -0
- {openscvx-0.4.1.dev140 → openscvx-0.4.1.dev144}/examples/spacecraft/hohmann_transfer.py +0 -0
- {openscvx-0.4.1.dev140 → openscvx-0.4.1.dev144}/examples/spacecraft/proxops_cw.py +0 -0
- {openscvx-0.4.1.dev140 → openscvx-0.4.1.dev144}/figures/ctlos_cine.gif +0 -0
- {openscvx-0.4.1.dev140 → openscvx-0.4.1.dev144}/figures/ctlos_dr.gif +0 -0
- {openscvx-0.4.1.dev140 → openscvx-0.4.1.dev144}/figures/dtlos_cine.gif +0 -0
- {openscvx-0.4.1.dev140 → openscvx-0.4.1.dev144}/figures/dtlos_dr.gif +0 -0
- {openscvx-0.4.1.dev140 → openscvx-0.4.1.dev144}/figures/openscvx_logo.svg +0 -0
- {openscvx-0.4.1.dev140 → openscvx-0.4.1.dev144}/figures/openscvx_logo_square.png +0 -0
- {openscvx-0.4.1.dev140 → openscvx-0.4.1.dev144}/figures/oscvx_structure_full_dark.svg +0 -0
- {openscvx-0.4.1.dev140 → openscvx-0.4.1.dev144}/figures/video_preview.png +0 -0
- {openscvx-0.4.1.dev140 → openscvx-0.4.1.dev144}/material/__init__.py +0 -0
- {openscvx-0.4.1.dev140 → openscvx-0.4.1.dev144}/material/overrides/assets/images/layers/1-background.avif +0 -0
- {openscvx-0.4.1.dev140 → openscvx-0.4.1.dev144}/material/overrides/assets/images/layers/1-background@1x.avif +0 -0
- {openscvx-0.4.1.dev140 → openscvx-0.4.1.dev144}/material/overrides/assets/images/layers/1-background@2x.avif +0 -0
- {openscvx-0.4.1.dev140 → openscvx-0.4.1.dev144}/material/overrides/assets/images/layers/1-background@3x.avif +0 -0
- {openscvx-0.4.1.dev140 → openscvx-0.4.1.dev144}/material/overrides/assets/images/layers/1-background@4x.avif +0 -0
- {openscvx-0.4.1.dev140 → openscvx-0.4.1.dev144}/material/overrides/assets/images/layers/2-mars.avif +0 -0
- {openscvx-0.4.1.dev140 → openscvx-0.4.1.dev144}/material/overrides/assets/images/layers/2-mars@1x.avif +0 -0
- {openscvx-0.4.1.dev140 → openscvx-0.4.1.dev144}/material/overrides/assets/images/layers/2-mars@2x.avif +0 -0
- {openscvx-0.4.1.dev140 → openscvx-0.4.1.dev144}/material/overrides/assets/images/layers/2-mars@3x.avif +0 -0
- {openscvx-0.4.1.dev140 → openscvx-0.4.1.dev144}/material/overrides/assets/images/layers/2-mars@4x.avif +0 -0
- {openscvx-0.4.1.dev140 → openscvx-0.4.1.dev144}/material/overrides/assets/images/layers/3-moon.avif +0 -0
- {openscvx-0.4.1.dev140 → openscvx-0.4.1.dev144}/material/overrides/assets/images/layers/3-moon@1x.avif +0 -0
- {openscvx-0.4.1.dev140 → openscvx-0.4.1.dev144}/material/overrides/assets/images/layers/3-moon@2x.avif +0 -0
- {openscvx-0.4.1.dev140 → openscvx-0.4.1.dev144}/material/overrides/assets/images/layers/3-moon@3x.avif +0 -0
- {openscvx-0.4.1.dev140 → openscvx-0.4.1.dev144}/material/overrides/assets/images/layers/3-moon@4x.avif +0 -0
- {openscvx-0.4.1.dev140 → openscvx-0.4.1.dev144}/material/overrides/assets/images/layers/4-sat1.avif +0 -0
- {openscvx-0.4.1.dev140 → openscvx-0.4.1.dev144}/material/overrides/assets/images/layers/4-sat1@1x.avif +0 -0
- {openscvx-0.4.1.dev140 → openscvx-0.4.1.dev144}/material/overrides/assets/images/layers/4-sat1@2x.avif +0 -0
- {openscvx-0.4.1.dev140 → openscvx-0.4.1.dev144}/material/overrides/assets/images/layers/4-sat1@3x.avif +0 -0
- {openscvx-0.4.1.dev140 → openscvx-0.4.1.dev144}/material/overrides/assets/images/layers/4-sat1@4x.avif +0 -0
- {openscvx-0.4.1.dev140 → openscvx-0.4.1.dev144}/material/overrides/assets/images/layers/5-space.avif +0 -0
- {openscvx-0.4.1.dev140 → openscvx-0.4.1.dev144}/material/overrides/assets/images/layers/5-space@1x.avif +0 -0
- {openscvx-0.4.1.dev140 → openscvx-0.4.1.dev144}/material/overrides/assets/images/layers/5-space@2x.avif +0 -0
- {openscvx-0.4.1.dev140 → openscvx-0.4.1.dev144}/material/overrides/assets/images/layers/5-space@3x.avif +0 -0
- {openscvx-0.4.1.dev140 → openscvx-0.4.1.dev144}/material/overrides/assets/images/layers/5-space@4x.avif +0 -0
- {openscvx-0.4.1.dev140 → openscvx-0.4.1.dev144}/material/overrides/assets/images/layers/6-earth.avif +0 -0
- {openscvx-0.4.1.dev140 → openscvx-0.4.1.dev144}/material/overrides/assets/images/layers/6-earth@1x.avif +0 -0
- {openscvx-0.4.1.dev140 → openscvx-0.4.1.dev144}/material/overrides/assets/images/layers/6-earth@2x.avif +0 -0
- {openscvx-0.4.1.dev140 → openscvx-0.4.1.dev144}/material/overrides/assets/images/layers/6-earth@3x.avif +0 -0
- {openscvx-0.4.1.dev140 → openscvx-0.4.1.dev144}/material/overrides/assets/images/layers/6-earth@4x.avif +0 -0
- {openscvx-0.4.1.dev140 → openscvx-0.4.1.dev144}/material/overrides/assets/javascripts/parallax.js +0 -0
- {openscvx-0.4.1.dev140 → openscvx-0.4.1.dev144}/material/overrides/assets/logo.svg +0 -0
- {openscvx-0.4.1.dev140 → openscvx-0.4.1.dev144}/material/overrides/assets/stylesheets/custom.css +0 -0
- {openscvx-0.4.1.dev140 → openscvx-0.4.1.dev144}/material/overrides/assets/stylesheets/parallax.css +0 -0
- {openscvx-0.4.1.dev140 → openscvx-0.4.1.dev144}/material/overrides/home.html +0 -0
- {openscvx-0.4.1.dev140 → openscvx-0.4.1.dev144}/material/overrides/main.html +0 -0
- {openscvx-0.4.1.dev140 → openscvx-0.4.1.dev144}/material/overrides/partials/parallax/hero.html +0 -0
- {openscvx-0.4.1.dev140 → openscvx-0.4.1.dev144}/material/overrides/partials/parallax.html +0 -0
- {openscvx-0.4.1.dev140 → openscvx-0.4.1.dev144}/mkdocs.yml +0 -0
- {openscvx-0.4.1.dev140 → openscvx-0.4.1.dev144}/openscvx/__init__.py +0 -0
- {openscvx-0.4.1.dev140 → openscvx-0.4.1.dev144}/openscvx/__main__.py +0 -0
- {openscvx-0.4.1.dev140 → openscvx-0.4.1.dev144}/openscvx/algorithms/constant_proximal_weight.py +0 -0
- {openscvx-0.4.1.dev140 → openscvx-0.4.1.dev144}/openscvx/algorithms/optimization_results.py +0 -0
- {openscvx-0.4.1.dev140 → openscvx-0.4.1.dev144}/openscvx/algorithms/ramp_proximal_weight.py +0 -0
- {openscvx-0.4.1.dev140 → openscvx-0.4.1.dev144}/openscvx/config.py +0 -0
- {openscvx-0.4.1.dev140 → openscvx-0.4.1.dev144}/openscvx/discretization/__init__.py +0 -0
- {openscvx-0.4.1.dev140 → openscvx-0.4.1.dev144}/openscvx/discretization/base.py +0 -0
- {openscvx-0.4.1.dev140 → openscvx-0.4.1.dev144}/openscvx/discretization/linearize_discretize.py +0 -0
- {openscvx-0.4.1.dev140 → openscvx-0.4.1.dev144}/openscvx/expert/__init__.py +0 -0
- {openscvx-0.4.1.dev140 → openscvx-0.4.1.dev144}/openscvx/expert/byof.py +0 -0
- {openscvx-0.4.1.dev140 → openscvx-0.4.1.dev144}/openscvx/expert/lowering.py +0 -0
- {openscvx-0.4.1.dev140 → openscvx-0.4.1.dev144}/openscvx/expert/validation.py +0 -0
- {openscvx-0.4.1.dev140 → openscvx-0.4.1.dev144}/openscvx/init/__init__.py +0 -0
- {openscvx-0.4.1.dev140 → openscvx-0.4.1.dev144}/openscvx/init/interpolation.py +0 -0
- {openscvx-0.4.1.dev140 → openscvx-0.4.1.dev144}/openscvx/integrators/__init__.py +0 -0
- {openscvx-0.4.1.dev140 → openscvx-0.4.1.dev144}/openscvx/integrators/runge_kutta.py +0 -0
- {openscvx-0.4.1.dev140 → openscvx-0.4.1.dev144}/openscvx/loader.py +0 -0
- {openscvx-0.4.1.dev140 → openscvx-0.4.1.dev144}/openscvx/lowered/__init__.py +0 -0
- {openscvx-0.4.1.dev140 → openscvx-0.4.1.dev144}/openscvx/lowered/cvxpy_constraints.py +0 -0
- {openscvx-0.4.1.dev140 → openscvx-0.4.1.dev144}/openscvx/lowered/dynamics.py +0 -0
- {openscvx-0.4.1.dev140 → openscvx-0.4.1.dev144}/openscvx/lowered/jax_constraints.py +0 -0
- {openscvx-0.4.1.dev140 → openscvx-0.4.1.dev144}/openscvx/lowered/parameters.py +0 -0
- {openscvx-0.4.1.dev140 → openscvx-0.4.1.dev144}/openscvx/lowered/problem.py +0 -0
- {openscvx-0.4.1.dev140 → openscvx-0.4.1.dev144}/openscvx/lowered/unified.py +0 -0
- {openscvx-0.4.1.dev140 → openscvx-0.4.1.dev144}/openscvx/plotting/__init__.py +0 -0
- {openscvx-0.4.1.dev140 → openscvx-0.4.1.dev144}/openscvx/plotting/plotting.py +0 -0
- {openscvx-0.4.1.dev140 → openscvx-0.4.1.dev144}/openscvx/plotting/scp_iteration.py +0 -0
- {openscvx-0.4.1.dev140 → openscvx-0.4.1.dev144}/openscvx/plotting/viser/__init__.py +0 -0
- {openscvx-0.4.1.dev140 → openscvx-0.4.1.dev144}/openscvx/plotting/viser/animated.py +0 -0
- {openscvx-0.4.1.dev140 → openscvx-0.4.1.dev144}/openscvx/plotting/viser/orbits.py +0 -0
- {openscvx-0.4.1.dev140 → openscvx-0.4.1.dev144}/openscvx/plotting/viser/plotly_integration.py +0 -0
- {openscvx-0.4.1.dev140 → openscvx-0.4.1.dev144}/openscvx/plotting/viser/primitives.py +0 -0
- {openscvx-0.4.1.dev140 → openscvx-0.4.1.dev144}/openscvx/plotting/viser/scp.py +0 -0
- {openscvx-0.4.1.dev140 → openscvx-0.4.1.dev144}/openscvx/plotting/viser/server.py +0 -0
- {openscvx-0.4.1.dev140 → openscvx-0.4.1.dev144}/openscvx/propagation/__init__.py +0 -0
- {openscvx-0.4.1.dev140 → openscvx-0.4.1.dev144}/openscvx/propagation/propagation.py +0 -0
- {openscvx-0.4.1.dev140 → openscvx-0.4.1.dev144}/openscvx/solvers/__init__.py +0 -0
- {openscvx-0.4.1.dev140 → openscvx-0.4.1.dev144}/openscvx/symbolic/__init__.py +0 -0
- {openscvx-0.4.1.dev140 → openscvx-0.4.1.dev144}/openscvx/symbolic/builder.py +0 -0
- {openscvx-0.4.1.dev140 → openscvx-0.4.1.dev144}/openscvx/symbolic/constraint_set.py +0 -0
- {openscvx-0.4.1.dev140 → openscvx-0.4.1.dev144}/openscvx/symbolic/expr/__init__.py +0 -0
- {openscvx-0.4.1.dev140 → openscvx-0.4.1.dev144}/openscvx/symbolic/expr/arithmetic.py +0 -0
- {openscvx-0.4.1.dev140 → openscvx-0.4.1.dev144}/openscvx/symbolic/expr/array.py +0 -0
- {openscvx-0.4.1.dev140 → openscvx-0.4.1.dev144}/openscvx/symbolic/expr/control.py +0 -0
- {openscvx-0.4.1.dev140 → openscvx-0.4.1.dev144}/openscvx/symbolic/expr/expr.py +0 -0
- {openscvx-0.4.1.dev140 → openscvx-0.4.1.dev144}/openscvx/symbolic/expr/lie/__init__.py +0 -0
- {openscvx-0.4.1.dev140 → openscvx-0.4.1.dev144}/openscvx/symbolic/expr/lie/adjoint.py +0 -0
- {openscvx-0.4.1.dev140 → openscvx-0.4.1.dev144}/openscvx/symbolic/expr/lie/se3.py +0 -0
- {openscvx-0.4.1.dev140 → openscvx-0.4.1.dev144}/openscvx/symbolic/expr/lie/so3.py +0 -0
- {openscvx-0.4.1.dev140 → openscvx-0.4.1.dev144}/openscvx/symbolic/expr/linalg.py +0 -0
- {openscvx-0.4.1.dev140 → openscvx-0.4.1.dev144}/openscvx/symbolic/expr/logic.py +0 -0
- {openscvx-0.4.1.dev140 → openscvx-0.4.1.dev144}/openscvx/symbolic/expr/math.py +0 -0
- {openscvx-0.4.1.dev140 → openscvx-0.4.1.dev144}/openscvx/symbolic/expr/spatial.py +0 -0
- {openscvx-0.4.1.dev140 → openscvx-0.4.1.dev144}/openscvx/symbolic/expr/state.py +0 -0
- {openscvx-0.4.1.dev140 → openscvx-0.4.1.dev144}/openscvx/symbolic/expr/stl.py +0 -0
- {openscvx-0.4.1.dev140 → openscvx-0.4.1.dev144}/openscvx/symbolic/expr/time.py +0 -0
- {openscvx-0.4.1.dev140 → openscvx-0.4.1.dev144}/openscvx/symbolic/expr/variable.py +0 -0
- {openscvx-0.4.1.dev140 → openscvx-0.4.1.dev144}/openscvx/symbolic/expr/vmap.py +0 -0
- {openscvx-0.4.1.dev140 → openscvx-0.4.1.dev144}/openscvx/symbolic/hashing.py +0 -0
- {openscvx-0.4.1.dev140 → openscvx-0.4.1.dev144}/openscvx/symbolic/lowerers/__init__.py +0 -0
- {openscvx-0.4.1.dev140 → openscvx-0.4.1.dev144}/openscvx/symbolic/lowerers/cvxpy/__init__.py +0 -0
- {openscvx-0.4.1.dev140 → openscvx-0.4.1.dev144}/openscvx/symbolic/lowerers/cvxpy/_lowerer.py +0 -0
- {openscvx-0.4.1.dev140 → openscvx-0.4.1.dev144}/openscvx/symbolic/lowerers/cvxpy/_registry.py +0 -0
- {openscvx-0.4.1.dev140 → openscvx-0.4.1.dev144}/openscvx/symbolic/lowerers/cvxpy/arithmetic.py +0 -0
- {openscvx-0.4.1.dev140 → openscvx-0.4.1.dev144}/openscvx/symbolic/lowerers/cvxpy/array.py +0 -0
- {openscvx-0.4.1.dev140 → openscvx-0.4.1.dev144}/openscvx/symbolic/lowerers/cvxpy/constraint.py +0 -0
- {openscvx-0.4.1.dev140 → openscvx-0.4.1.dev144}/openscvx/symbolic/lowerers/cvxpy/control.py +0 -0
- {openscvx-0.4.1.dev140 → openscvx-0.4.1.dev144}/openscvx/symbolic/lowerers/cvxpy/expr.py +0 -0
- {openscvx-0.4.1.dev140 → openscvx-0.4.1.dev144}/openscvx/symbolic/lowerers/cvxpy/linalg.py +0 -0
- {openscvx-0.4.1.dev140 → openscvx-0.4.1.dev144}/openscvx/symbolic/lowerers/cvxpy/logic.py +0 -0
- {openscvx-0.4.1.dev140 → openscvx-0.4.1.dev144}/openscvx/symbolic/lowerers/cvxpy/math.py +0 -0
- {openscvx-0.4.1.dev140 → openscvx-0.4.1.dev144}/openscvx/symbolic/lowerers/cvxpy/state.py +0 -0
- {openscvx-0.4.1.dev140 → openscvx-0.4.1.dev144}/openscvx/symbolic/lowerers/jax/__init__.py +0 -0
- {openscvx-0.4.1.dev140 → openscvx-0.4.1.dev144}/openscvx/symbolic/lowerers/jax/_lowerer.py +0 -0
- {openscvx-0.4.1.dev140 → openscvx-0.4.1.dev144}/openscvx/symbolic/lowerers/jax/_registry.py +0 -0
- {openscvx-0.4.1.dev140 → openscvx-0.4.1.dev144}/openscvx/symbolic/lowerers/jax/arithmetic.py +0 -0
- {openscvx-0.4.1.dev140 → openscvx-0.4.1.dev144}/openscvx/symbolic/lowerers/jax/array.py +0 -0
- {openscvx-0.4.1.dev140 → openscvx-0.4.1.dev144}/openscvx/symbolic/lowerers/jax/constraint.py +0 -0
- {openscvx-0.4.1.dev140 → openscvx-0.4.1.dev144}/openscvx/symbolic/lowerers/jax/control.py +0 -0
- {openscvx-0.4.1.dev140 → openscvx-0.4.1.dev144}/openscvx/symbolic/lowerers/jax/expr.py +0 -0
- {openscvx-0.4.1.dev140 → openscvx-0.4.1.dev144}/openscvx/symbolic/lowerers/jax/lie.py +0 -0
- {openscvx-0.4.1.dev140 → openscvx-0.4.1.dev144}/openscvx/symbolic/lowerers/jax/linalg.py +0 -0
- {openscvx-0.4.1.dev140 → openscvx-0.4.1.dev144}/openscvx/symbolic/lowerers/jax/logic.py +0 -0
- {openscvx-0.4.1.dev140 → openscvx-0.4.1.dev144}/openscvx/symbolic/lowerers/jax/math.py +0 -0
- {openscvx-0.4.1.dev140 → openscvx-0.4.1.dev144}/openscvx/symbolic/lowerers/jax/spatial.py +0 -0
- {openscvx-0.4.1.dev140 → openscvx-0.4.1.dev144}/openscvx/symbolic/lowerers/jax/state.py +0 -0
- {openscvx-0.4.1.dev140 → openscvx-0.4.1.dev144}/openscvx/symbolic/lowerers/jax/stl.py +0 -0
- {openscvx-0.4.1.dev140 → openscvx-0.4.1.dev144}/openscvx/symbolic/lowerers/jax/vmap.py +0 -0
- {openscvx-0.4.1.dev140 → openscvx-0.4.1.dev144}/openscvx/symbolic/parser/__init__.py +0 -0
- {openscvx-0.4.1.dev140 → openscvx-0.4.1.dev144}/openscvx/symbolic/parser/_registry.py +0 -0
- {openscvx-0.4.1.dev140 → openscvx-0.4.1.dev144}/openscvx/symbolic/parser/array.py +0 -0
- {openscvx-0.4.1.dev140 → openscvx-0.4.1.dev144}/openscvx/symbolic/parser/constraint.py +0 -0
- {openscvx-0.4.1.dev140 → openscvx-0.4.1.dev144}/openscvx/symbolic/parser/lie.py +0 -0
- {openscvx-0.4.1.dev140 → openscvx-0.4.1.dev144}/openscvx/symbolic/parser/linalg.py +0 -0
- {openscvx-0.4.1.dev140 → openscvx-0.4.1.dev144}/openscvx/symbolic/parser/logic.py +0 -0
- {openscvx-0.4.1.dev140 → openscvx-0.4.1.dev144}/openscvx/symbolic/parser/math.py +0 -0
- {openscvx-0.4.1.dev140 → openscvx-0.4.1.dev144}/openscvx/symbolic/parser/parser.py +0 -0
- {openscvx-0.4.1.dev140 → openscvx-0.4.1.dev144}/openscvx/symbolic/parser/spatial.py +0 -0
- {openscvx-0.4.1.dev140 → openscvx-0.4.1.dev144}/openscvx/symbolic/parser/stl.py +0 -0
- {openscvx-0.4.1.dev140 → openscvx-0.4.1.dev144}/openscvx/symbolic/parser/tokenizer.py +0 -0
- {openscvx-0.4.1.dev140 → openscvx-0.4.1.dev144}/openscvx/symbolic/preprocessing.py +0 -0
- {openscvx-0.4.1.dev140 → openscvx-0.4.1.dev144}/openscvx/symbolic/problem.py +0 -0
- {openscvx-0.4.1.dev140 → openscvx-0.4.1.dev144}/openscvx/symbolic/sparsity.py +0 -0
- {openscvx-0.4.1.dev140 → openscvx-0.4.1.dev144}/openscvx/symbolic/unified.py +0 -0
- {openscvx-0.4.1.dev140 → openscvx-0.4.1.dev144}/openscvx/utils/__init__.py +0 -0
- {openscvx-0.4.1.dev140 → openscvx-0.4.1.dev144}/openscvx/utils/cache.py +0 -0
- {openscvx-0.4.1.dev140 → openscvx-0.4.1.dev144}/openscvx/utils/caching.py +0 -0
- {openscvx-0.4.1.dev140 → openscvx-0.4.1.dev144}/openscvx/utils/printing.py +0 -0
- {openscvx-0.4.1.dev140 → openscvx-0.4.1.dev144}/openscvx/utils/profiling.py +0 -0
- {openscvx-0.4.1.dev140 → openscvx-0.4.1.dev144}/openscvx/utils/utils.py +0 -0
- {openscvx-0.4.1.dev140 → openscvx-0.4.1.dev144}/openscvx.egg-info/SOURCES.txt +0 -0
- {openscvx-0.4.1.dev140 → openscvx-0.4.1.dev144}/openscvx.egg-info/dependency_links.txt +0 -0
- {openscvx-0.4.1.dev140 → openscvx-0.4.1.dev144}/openscvx.egg-info/entry_points.txt +0 -0
- {openscvx-0.4.1.dev140 → openscvx-0.4.1.dev144}/openscvx.egg-info/requires.txt +0 -0
- {openscvx-0.4.1.dev140 → openscvx-0.4.1.dev144}/openscvx.egg-info/top_level.txt +0 -0
- {openscvx-0.4.1.dev140 → openscvx-0.4.1.dev144}/pyproject.toml +0 -0
- {openscvx-0.4.1.dev140 → openscvx-0.4.1.dev144}/scripts/gen_example_pages.py +0 -0
- {openscvx-0.4.1.dev140 → openscvx-0.4.1.dev144}/scripts/gen_ref_pages.py +0 -0
- {openscvx-0.4.1.dev140 → openscvx-0.4.1.dev144}/setup.cfg +0 -0
- {openscvx-0.4.1.dev140 → openscvx-0.4.1.dev144}/tests/__init__.py +0 -0
- {openscvx-0.4.1.dev140 → openscvx-0.4.1.dev144}/tests/brachistochrone_analytical.py +0 -0
- {openscvx-0.4.1.dev140 → openscvx-0.4.1.dev144}/tests/fixtures/brachistochrone.json +0 -0
- {openscvx-0.4.1.dev140 → openscvx-0.4.1.dev144}/tests/fixtures/brachistochrone.yaml +0 -0
- {openscvx-0.4.1.dev140 → openscvx-0.4.1.dev144}/tests/hohmann_analytical.py +0 -0
- {openscvx-0.4.1.dev140 → openscvx-0.4.1.dev144}/tests/symbolic/__init__.py +0 -0
- {openscvx-0.4.1.dev140 → openscvx-0.4.1.dev144}/tests/symbolic/expr/__init__.py +0 -0
- {openscvx-0.4.1.dev140 → openscvx-0.4.1.dev144}/tests/symbolic/expr/test_arithmetic.py +0 -0
- {openscvx-0.4.1.dev140 → openscvx-0.4.1.dev144}/tests/symbolic/expr/test_array.py +0 -0
- {openscvx-0.4.1.dev140 → openscvx-0.4.1.dev144}/tests/symbolic/expr/test_constraint.py +0 -0
- {openscvx-0.4.1.dev140 → openscvx-0.4.1.dev144}/tests/symbolic/expr/test_expr.py +0 -0
- {openscvx-0.4.1.dev140 → openscvx-0.4.1.dev144}/tests/symbolic/expr/test_lie.py +0 -0
- {openscvx-0.4.1.dev140 → openscvx-0.4.1.dev144}/tests/symbolic/expr/test_linalg.py +0 -0
- {openscvx-0.4.1.dev140 → openscvx-0.4.1.dev144}/tests/symbolic/expr/test_logic.py +0 -0
- {openscvx-0.4.1.dev140 → openscvx-0.4.1.dev144}/tests/symbolic/expr/test_math.py +0 -0
- {openscvx-0.4.1.dev140 → openscvx-0.4.1.dev144}/tests/symbolic/expr/test_node_reference.py +0 -0
- {openscvx-0.4.1.dev140 → openscvx-0.4.1.dev144}/tests/symbolic/expr/test_parameters.py +0 -0
- {openscvx-0.4.1.dev140 → openscvx-0.4.1.dev144}/tests/symbolic/expr/test_scaling.py +0 -0
- {openscvx-0.4.1.dev140 → openscvx-0.4.1.dev144}/tests/symbolic/expr/test_spatial.py +0 -0
- {openscvx-0.4.1.dev140 → openscvx-0.4.1.dev144}/tests/symbolic/expr/test_variable.py +0 -0
- {openscvx-0.4.1.dev140 → openscvx-0.4.1.dev144}/tests/symbolic/expr/test_vmap.py +0 -0
- {openscvx-0.4.1.dev140 → openscvx-0.4.1.dev144}/tests/symbolic/parser/__init__.py +0 -0
- {openscvx-0.4.1.dev140 → openscvx-0.4.1.dev144}/tests/symbolic/parser/test_array.py +0 -0
- {openscvx-0.4.1.dev140 → openscvx-0.4.1.dev144}/tests/symbolic/parser/test_constraint.py +0 -0
- {openscvx-0.4.1.dev140 → openscvx-0.4.1.dev144}/tests/symbolic/parser/test_lie.py +0 -0
- {openscvx-0.4.1.dev140 → openscvx-0.4.1.dev144}/tests/symbolic/parser/test_linalg.py +0 -0
- {openscvx-0.4.1.dev140 → openscvx-0.4.1.dev144}/tests/symbolic/parser/test_load.py +0 -0
- {openscvx-0.4.1.dev140 → openscvx-0.4.1.dev144}/tests/symbolic/parser/test_logic.py +0 -0
- {openscvx-0.4.1.dev140 → openscvx-0.4.1.dev144}/tests/symbolic/parser/test_math.py +0 -0
- {openscvx-0.4.1.dev140 → openscvx-0.4.1.dev144}/tests/symbolic/parser/test_parser.py +0 -0
- {openscvx-0.4.1.dev140 → openscvx-0.4.1.dev144}/tests/symbolic/parser/test_spatial.py +0 -0
- {openscvx-0.4.1.dev140 → openscvx-0.4.1.dev144}/tests/symbolic/parser/test_stl.py +0 -0
- {openscvx-0.4.1.dev140 → openscvx-0.4.1.dev144}/tests/symbolic/parser/test_tokenizer.py +0 -0
- {openscvx-0.4.1.dev140 → openscvx-0.4.1.dev144}/tests/symbolic/parser/test_vmap.py +0 -0
- {openscvx-0.4.1.dev140 → openscvx-0.4.1.dev144}/tests/symbolic/test_augmentation.py +0 -0
- {openscvx-0.4.1.dev140 → openscvx-0.4.1.dev144}/tests/symbolic/test_hashing.py +0 -0
- {openscvx-0.4.1.dev140 → openscvx-0.4.1.dev144}/tests/symbolic/test_lower_cvxpy.py +0 -0
- {openscvx-0.4.1.dev140 → openscvx-0.4.1.dev144}/tests/symbolic/test_lower_jax.py +0 -0
- {openscvx-0.4.1.dev140 → openscvx-0.4.1.dev144}/tests/symbolic/test_preprocessing.py +0 -0
- {openscvx-0.4.1.dev140 → openscvx-0.4.1.dev144}/tests/symbolic/test_sparsity.py +0 -0
- {openscvx-0.4.1.dev140 → openscvx-0.4.1.dev144}/tests/symbolic/test_unified.py +0 -0
- {openscvx-0.4.1.dev140 → openscvx-0.4.1.dev144}/tests/test_brachistochrone.py +0 -0
- {openscvx-0.4.1.dev140 → openscvx-0.4.1.dev144}/tests/test_cvxpygen_optional.py +0 -0
- {openscvx-0.4.1.dev140 → openscvx-0.4.1.dev144}/tests/test_discretization.py +0 -0
- {openscvx-0.4.1.dev140 → openscvx-0.4.1.dev144}/tests/test_examples.py +0 -0
- {openscvx-0.4.1.dev140 → openscvx-0.4.1.dev144}/tests/test_expert.py +0 -0
- {openscvx-0.4.1.dev140 → openscvx-0.4.1.dev144}/tests/test_impulsive.py +0 -0
- {openscvx-0.4.1.dev140 → openscvx-0.4.1.dev144}/tests/test_init.py +0 -0
- {openscvx-0.4.1.dev140 → openscvx-0.4.1.dev144}/tests/test_integrators.py +0 -0
- {openscvx-0.4.1.dev140 → openscvx-0.4.1.dev144}/tests/test_loader.py +0 -0
- {openscvx-0.4.1.dev140 → openscvx-0.4.1.dev144}/tests/test_optimization_results.py +0 -0
- {openscvx-0.4.1.dev140 → openscvx-0.4.1.dev144}/tests/test_plotting.py +0 -0
- {openscvx-0.4.1.dev140 → openscvx-0.4.1.dev144}/tests/test_propagation.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: openscvx
|
|
3
|
-
Version: 0.4.1.
|
|
3
|
+
Version: 0.4.1.dev144
|
|
4
4
|
Summary: A general Python-based successive convexification implementation which uses a JAX backend.
|
|
5
5
|
Author-email: Chris Hayner and Griffin Norris <haynec@uw.edu>
|
|
6
6
|
License: Apache Software License
|
|
@@ -28,7 +28,7 @@ version_tuple: VERSION_TUPLE
|
|
|
28
28
|
commit_id: COMMIT_ID
|
|
29
29
|
__commit_id__: COMMIT_ID
|
|
30
30
|
|
|
31
|
-
__version__ = version = '0.4.1.
|
|
32
|
-
__version_tuple__ = version_tuple = (0, 4, 1, '
|
|
31
|
+
__version__ = version = '0.4.1.dev144'
|
|
32
|
+
__version_tuple__ = version_tuple = (0, 4, 1, 'dev144')
|
|
33
33
|
|
|
34
|
-
__commit_id__ = commit_id = '
|
|
34
|
+
__commit_id__ = commit_id = 'g137ef78b8'
|
|
@@ -164,7 +164,8 @@ class AugmentedLagrangian(AutotuningBase):
|
|
|
164
164
|
candidate.x,
|
|
165
165
|
candidate.u,
|
|
166
166
|
state.lam_vc,
|
|
167
|
-
state.
|
|
167
|
+
state.lam_vb_nodal,
|
|
168
|
+
state.lam_vb_cross,
|
|
168
169
|
state.lam_cost,
|
|
169
170
|
nodal_constraints,
|
|
170
171
|
params,
|
|
@@ -197,7 +198,8 @@ class AugmentedLagrangian(AutotuningBase):
|
|
|
197
198
|
state.x,
|
|
198
199
|
state.u,
|
|
199
200
|
state.lam_vc,
|
|
200
|
-
state.
|
|
201
|
+
state.lam_vb_nodal,
|
|
202
|
+
state.lam_vb_cross,
|
|
201
203
|
state.lam_cost,
|
|
202
204
|
nodal_constraints,
|
|
203
205
|
params,
|
|
@@ -232,7 +234,8 @@ class AugmentedLagrangian(AutotuningBase):
|
|
|
232
234
|
candidate.lam_vc = self._update_virtual_control_weights(
|
|
233
235
|
candidate, candidate_x_prop, settings, state.lam_vc, state.lam_prox
|
|
234
236
|
)
|
|
235
|
-
candidate.
|
|
237
|
+
candidate.lam_vb_nodal = state.lam_vb_nodal
|
|
238
|
+
candidate.lam_vb_cross = state.lam_vb_cross
|
|
236
239
|
|
|
237
240
|
state.accept_solution(candidate)
|
|
238
241
|
adaptive_state = "Accept Higher"
|
|
@@ -245,7 +248,8 @@ class AugmentedLagrangian(AutotuningBase):
|
|
|
245
248
|
candidate.lam_vc = self._update_virtual_control_weights(
|
|
246
249
|
candidate, candidate_x_prop, settings, state.lam_vc, state.lam_prox
|
|
247
250
|
)
|
|
248
|
-
candidate.
|
|
251
|
+
candidate.lam_vb_nodal = state.lam_vb_nodal
|
|
252
|
+
candidate.lam_vb_cross = state.lam_vb_cross
|
|
249
253
|
|
|
250
254
|
state.accept_solution(candidate)
|
|
251
255
|
adaptive_state = "Accept Constant"
|
|
@@ -257,14 +261,16 @@ class AugmentedLagrangian(AutotuningBase):
|
|
|
257
261
|
candidate.lam_vc = self._update_virtual_control_weights(
|
|
258
262
|
candidate, candidate_x_prop, settings, state.lam_vc, state.lam_prox
|
|
259
263
|
)
|
|
260
|
-
candidate.
|
|
264
|
+
candidate.lam_vb_nodal = state.lam_vb_nodal
|
|
265
|
+
candidate.lam_vb_cross = state.lam_vb_cross
|
|
261
266
|
state.accept_solution(candidate)
|
|
262
267
|
adaptive_state = "Accept Lower"
|
|
263
268
|
|
|
264
269
|
else:
|
|
265
270
|
state.lam_prox_history.append(lam_prox_k)
|
|
266
271
|
candidate.lam_vc = state.lam_vc
|
|
267
|
-
candidate.
|
|
272
|
+
candidate.lam_vb_nodal = state.lam_vb_nodal
|
|
273
|
+
candidate.lam_vb_cross = state.lam_vb_cross
|
|
268
274
|
state.accept_solution(candidate)
|
|
269
275
|
adaptive_state = "Initial"
|
|
270
276
|
|
|
@@ -124,22 +124,38 @@ class Weights:
|
|
|
124
124
|
lam_vc: Virtual control penalty weight (normalized).
|
|
125
125
|
lam_cost: Cost weight per state (normalized). Scalar or array of
|
|
126
126
|
shape ``(n_states,)`` for per-state weighting.
|
|
127
|
-
lam_vb:
|
|
127
|
+
lam_vb: Global virtual buffer penalty weight (normalized). Scalar
|
|
128
|
+
default applied to every constraint. Use ``.weight()`` on
|
|
129
|
+
individual constraints for per-constraint or per-node overrides.
|
|
130
|
+
lam_vb_nodal: Virtual buffer penalty weights for nodal constraints
|
|
131
|
+
(normalized), shape ``(N, n_nodal)``. Set by
|
|
132
|
+
:meth:`set_vb_arrays`.
|
|
133
|
+
lam_vb_cross: Virtual buffer penalty weights for cross-node
|
|
134
|
+
constraints (normalized), shape ``(n_cross,)``. Set by
|
|
135
|
+
:meth:`set_vb_arrays`.
|
|
128
136
|
"""
|
|
129
137
|
|
|
130
138
|
lam_prox: float = 1e0
|
|
131
139
|
lam_vc: float = 1e1
|
|
132
140
|
lam_cost: Union[float, np.ndarray] = 1e-1
|
|
133
141
|
lam_vb: float = 0.0
|
|
142
|
+
lam_vb_nodal: Optional[np.ndarray] = None
|
|
143
|
+
lam_vb_cross: Optional[np.ndarray] = None
|
|
134
144
|
|
|
135
145
|
def __post_init__(self):
|
|
146
|
+
# Coerce lists/lists-of-lists to numpy arrays.
|
|
147
|
+
if isinstance(self.lam_cost, (list, tuple)):
|
|
148
|
+
self.lam_cost = np.asarray(self.lam_cost, dtype=float)
|
|
149
|
+
|
|
136
150
|
# Snapshot the user-specified values so normalize() is idempotent.
|
|
137
151
|
self._raw_lam_prox = self.lam_prox
|
|
138
152
|
self._raw_lam_vc = self.lam_vc
|
|
139
153
|
self._raw_lam_cost = (
|
|
140
154
|
self.lam_cost.copy() if isinstance(self.lam_cost, np.ndarray) else self.lam_cost
|
|
141
155
|
)
|
|
142
|
-
self._raw_lam_vb = self.lam_vb
|
|
156
|
+
self._raw_lam_vb = float(self.lam_vb)
|
|
157
|
+
self._raw_lam_vb_nodal: Optional[np.ndarray] = None
|
|
158
|
+
self._raw_lam_vb_cross: Optional[np.ndarray] = None
|
|
143
159
|
|
|
144
160
|
def normalize(self) -> None:
|
|
145
161
|
"""Normalize weights so the largest equals 1.0.
|
|
@@ -153,12 +169,42 @@ class Weights:
|
|
|
153
169
|
if isinstance(self._raw_lam_cost, np.ndarray)
|
|
154
170
|
else self._raw_lam_cost
|
|
155
171
|
)
|
|
156
|
-
|
|
172
|
+
if self._raw_lam_vb_nodal is not None:
|
|
173
|
+
raw_vb_max = max(
|
|
174
|
+
float(np.max(self._raw_lam_vb_nodal)),
|
|
175
|
+
float(np.max(self._raw_lam_vb_cross)),
|
|
176
|
+
)
|
|
177
|
+
else:
|
|
178
|
+
raw_vb_max = self._raw_lam_vb
|
|
179
|
+
scale = max(self._raw_lam_prox, self._raw_lam_vc, raw_cost_max, raw_vb_max)
|
|
157
180
|
if scale > 0:
|
|
158
181
|
self.lam_prox = self._raw_lam_prox / scale
|
|
159
182
|
self.lam_vc = self._raw_lam_vc / scale
|
|
160
183
|
self.lam_cost = self._raw_lam_cost / scale
|
|
161
184
|
self.lam_vb = self._raw_lam_vb / scale
|
|
185
|
+
if self._raw_lam_vb_nodal is not None:
|
|
186
|
+
self.lam_vb_nodal = self._raw_lam_vb_nodal / scale
|
|
187
|
+
self.lam_vb_cross = self._raw_lam_vb_cross / scale
|
|
188
|
+
|
|
189
|
+
def set_vb_arrays(
|
|
190
|
+
self,
|
|
191
|
+
lam_vb_nodal: np.ndarray,
|
|
192
|
+
lam_vb_cross: np.ndarray,
|
|
193
|
+
) -> None:
|
|
194
|
+
"""Set pre-built virtual buffer weight arrays.
|
|
195
|
+
|
|
196
|
+
Stores the given arrays as both the current (normalized) and raw
|
|
197
|
+
(pre-normalization) values. Call :meth:`normalize` afterwards to
|
|
198
|
+
rescale all weights consistently.
|
|
199
|
+
|
|
200
|
+
Args:
|
|
201
|
+
lam_vb_nodal: Weight array of shape ``(N, n_nodal)``.
|
|
202
|
+
lam_vb_cross: Weight array of shape ``(n_cross,)``.
|
|
203
|
+
"""
|
|
204
|
+
self.lam_vb_nodal = lam_vb_nodal
|
|
205
|
+
self.lam_vb_cross = lam_vb_cross
|
|
206
|
+
self._raw_lam_vb_nodal = lam_vb_nodal.copy()
|
|
207
|
+
self._raw_lam_vb_cross = lam_vb_cross.copy()
|
|
162
208
|
|
|
163
209
|
|
|
164
210
|
@dataclass
|
|
@@ -175,7 +221,8 @@ class CandidateIterate:
|
|
|
175
221
|
TR: Optional[np.ndarray] = None
|
|
176
222
|
lam_vc: Optional[Union[float, np.ndarray]] = None
|
|
177
223
|
lam_cost: Optional[Union[float, np.ndarray]] = None
|
|
178
|
-
|
|
224
|
+
lam_vb_nodal: Optional[np.ndarray] = None
|
|
225
|
+
lam_vb_cross: Optional[np.ndarray] = None
|
|
179
226
|
J_lin: Optional[float] = None
|
|
180
227
|
J_nonlin: Optional[float] = None
|
|
181
228
|
|
|
@@ -306,7 +353,8 @@ class AutotuningBase(ABC):
|
|
|
306
353
|
x_bar: np.ndarray,
|
|
307
354
|
u_bar: np.ndarray,
|
|
308
355
|
lam_vc: np.ndarray,
|
|
309
|
-
|
|
356
|
+
lam_vb_nodal: np.ndarray,
|
|
357
|
+
lam_vb_cross: np.ndarray,
|
|
310
358
|
lam_cost: Union[float, np.ndarray],
|
|
311
359
|
nodal_constraints: "LoweredJaxConstraints",
|
|
312
360
|
params: dict,
|
|
@@ -324,7 +372,10 @@ class AutotuningBase(ABC):
|
|
|
324
372
|
x_bar: Previous iteration state (n_nodes, n_states)
|
|
325
373
|
u_bar: Solution control (n_nodes, n_controls)
|
|
326
374
|
lam_vc: Virtual control weight (scalar or matrix)
|
|
327
|
-
|
|
375
|
+
lam_vb_nodal: Virtual buffer penalty weights for nodal
|
|
376
|
+
constraints, shape ``(N, n_nodal)``.
|
|
377
|
+
lam_vb_cross: Virtual buffer penalty weights for cross-node
|
|
378
|
+
constraints, shape ``(n_cross,)``.
|
|
328
379
|
lam_cost: Cost weight. Scalar (applied uniformly) or
|
|
329
380
|
array of shape ``(n_states,)`` for per-state weighting.
|
|
330
381
|
nodal_constraints: Lowered JAX constraints
|
|
@@ -340,28 +391,28 @@ class AutotuningBase(ABC):
|
|
|
340
391
|
nodal_penalty = 0.0
|
|
341
392
|
|
|
342
393
|
# Evaluate nodal constraints
|
|
343
|
-
for constraint in nodal_constraints.nodal:
|
|
394
|
+
for idx, constraint in enumerate(nodal_constraints.nodal):
|
|
344
395
|
# Nodal constraint function is vmapped: func(x, u, node, params)
|
|
345
396
|
# When called with arrays, it evaluates at all nodes
|
|
346
397
|
g = constraint.func(x_bar, u_bar, 0, params)
|
|
347
398
|
# Only sum violations at nodes where constraint is enforced
|
|
348
399
|
if constraint.nodes is not None:
|
|
349
|
-
# Filter to only specified nodes
|
|
350
|
-
# Convert to numpy array for JAX compatibility
|
|
351
400
|
nodes_array = np.array(constraint.nodes)
|
|
352
401
|
g_filtered = g[nodes_array]
|
|
402
|
+
w = lam_vb_nodal[nodes_array, idx]
|
|
353
403
|
else:
|
|
354
|
-
# If no nodes specified, check all nodes
|
|
355
404
|
g_filtered = g
|
|
356
|
-
|
|
405
|
+
w = lam_vb_nodal[:, idx]
|
|
406
|
+
nodal_penalty += np.sum(w * np.maximum(0, g_filtered))
|
|
357
407
|
|
|
358
408
|
# Evaluate cross-node constraints
|
|
359
|
-
for constraint in nodal_constraints.cross_node:
|
|
409
|
+
for idx, constraint in enumerate(nodal_constraints.cross_node):
|
|
410
|
+
w = lam_vb_cross[idx]
|
|
360
411
|
# Cross-node constraint function signature: func(X, U, params)
|
|
361
412
|
# No node argument - operates on full trajectory
|
|
362
413
|
g = constraint.func(x_bar, u_bar, params)
|
|
363
414
|
# Cross-node constraints return scalar or array, sum all violations
|
|
364
|
-
nodal_penalty +=
|
|
415
|
+
nodal_penalty += w * np.sum(np.maximum(0, g))
|
|
365
416
|
|
|
366
417
|
# lam_cost weighting is applied inside calculate_cost_from_state,
|
|
367
418
|
# so the returned cost is already weighted (no outer multiplication).
|
|
@@ -421,7 +472,8 @@ class AlgorithmState:
|
|
|
421
472
|
lam_prox: Current trust region weight (may adapt during solve)
|
|
422
473
|
lam_cost: Current cost weight (may relax during solve)
|
|
423
474
|
lam_vc: Current virtual control penalty weight
|
|
424
|
-
|
|
475
|
+
lam_vb_nodal: Current per-node nodal virtual buffer penalty weights
|
|
476
|
+
lam_vb_cross: Current cross-node virtual buffer penalty weights
|
|
425
477
|
n_x: Number of states (for unpacking V vectors)
|
|
426
478
|
n_u: Number of controls (for unpacking V vectors)
|
|
427
479
|
N: Number of trajectory nodes (for unpacking V vectors)
|
|
@@ -455,7 +507,8 @@ class AlgorithmState:
|
|
|
455
507
|
TR_history: List[np.ndarray] = field(default_factory=list)
|
|
456
508
|
lam_vc_history: List[Union[float, np.ndarray]] = field(default_factory=list)
|
|
457
509
|
lam_cost_history: List[Union[float, np.ndarray]] = field(default_factory=list)
|
|
458
|
-
|
|
510
|
+
lam_vb_nodal_history: List[np.ndarray] = field(default_factory=list)
|
|
511
|
+
lam_vb_cross_history: List[np.ndarray] = field(default_factory=list)
|
|
459
512
|
lam_prox_history: List[float] = field(default_factory=list)
|
|
460
513
|
x_full: List[np.ndarray] = field(default_factory=list)
|
|
461
514
|
x_prop_full: List[np.ndarray] = field(default_factory=list)
|
|
@@ -501,8 +554,10 @@ class AlgorithmState:
|
|
|
501
554
|
self.lam_vc_history.append(cand.lam_vc)
|
|
502
555
|
if cand.lam_cost is not None:
|
|
503
556
|
self.lam_cost_history.append(cand.lam_cost)
|
|
504
|
-
if cand.
|
|
505
|
-
self.
|
|
557
|
+
if cand.lam_vb_nodal is not None:
|
|
558
|
+
self.lam_vb_nodal_history.append(cand.lam_vb_nodal)
|
|
559
|
+
if cand.lam_vb_cross is not None:
|
|
560
|
+
self.lam_vb_cross_history.append(cand.lam_vb_cross)
|
|
506
561
|
|
|
507
562
|
if cand.J_nonlin is not None:
|
|
508
563
|
self.J_nonlin_history.append(cand.J_nonlin)
|
|
@@ -694,18 +749,37 @@ class AlgorithmState:
|
|
|
694
749
|
return self.lam_vc_history[-1]
|
|
695
750
|
|
|
696
751
|
@property
|
|
697
|
-
def
|
|
698
|
-
"""Get current virtual buffer penalty
|
|
752
|
+
def lam_vb_nodal(self) -> np.ndarray:
|
|
753
|
+
"""Get current virtual buffer penalty weights for nodal constraints.
|
|
754
|
+
|
|
755
|
+
Returns:
|
|
756
|
+
Array of shape ``(N, n_nodal_constraints)``.
|
|
757
|
+
"""
|
|
758
|
+
if not self.lam_vb_nodal_history:
|
|
759
|
+
raise ValueError(
|
|
760
|
+
"lam_vb_nodal_history is empty. Initialize state using from_settings()."
|
|
761
|
+
)
|
|
762
|
+
return self.lam_vb_nodal_history[-1]
|
|
763
|
+
|
|
764
|
+
@property
|
|
765
|
+
def lam_vb_cross(self) -> np.ndarray:
|
|
766
|
+
"""Get current virtual buffer penalty weights for cross-node constraints.
|
|
699
767
|
|
|
700
768
|
Returns:
|
|
701
|
-
|
|
769
|
+
Array of shape ``(n_cross_node_constraints,)``.
|
|
702
770
|
"""
|
|
703
|
-
if not self.
|
|
704
|
-
raise ValueError(
|
|
705
|
-
|
|
771
|
+
if not self.lam_vb_cross_history:
|
|
772
|
+
raise ValueError(
|
|
773
|
+
"lam_vb_cross_history is empty. Initialize state using from_settings()."
|
|
774
|
+
)
|
|
775
|
+
return self.lam_vb_cross_history[-1]
|
|
706
776
|
|
|
707
777
|
@classmethod
|
|
708
|
-
def from_settings(
|
|
778
|
+
def from_settings(
|
|
779
|
+
cls,
|
|
780
|
+
settings: "Config",
|
|
781
|
+
weights: "Weights",
|
|
782
|
+
) -> "AlgorithmState":
|
|
709
783
|
"""Create initial algorithm state from configuration.
|
|
710
784
|
|
|
711
785
|
Copies only the trajectory arrays from settings, leaving all metadata
|
|
@@ -749,7 +823,8 @@ class AlgorithmState:
|
|
|
749
823
|
TR_history=[],
|
|
750
824
|
lam_vc_history=[lam_vc_array],
|
|
751
825
|
lam_cost_history=[lam_cost_init],
|
|
752
|
-
|
|
826
|
+
lam_vb_nodal_history=[weights.lam_vb_nodal.copy()],
|
|
827
|
+
lam_vb_cross_history=[weights.lam_vb_cross.copy()],
|
|
753
828
|
lam_prox_history=[weights.lam_prox],
|
|
754
829
|
)
|
|
755
830
|
|
|
@@ -840,6 +915,87 @@ class Algorithm(ABC):
|
|
|
840
915
|
return _expand_lam_cost_dict(lam_cost, states)
|
|
841
916
|
return lam_cost
|
|
842
917
|
|
|
918
|
+
def _resolve_lam_vb(
|
|
919
|
+
self,
|
|
920
|
+
N: int,
|
|
921
|
+
nodal_constraints: list,
|
|
922
|
+
cross_node_constraints: list,
|
|
923
|
+
n_byof_nodal: int = 0,
|
|
924
|
+
n_byof_cross: int = 0,
|
|
925
|
+
) -> None:
|
|
926
|
+
"""Resolve per-constraint virtual buffer weight arrays and re-normalize.
|
|
927
|
+
|
|
928
|
+
Inspects each symbolic constraint's shape (to account for vector
|
|
929
|
+
decomposition) and ``.weight()`` overrides, populates
|
|
930
|
+
``weights.lam_vb_nodal`` and ``weights.lam_vb_cross``, then
|
|
931
|
+
re-normalizes all weights so the overrides participate in the scale.
|
|
932
|
+
|
|
933
|
+
Args:
|
|
934
|
+
N: Number of trajectory nodes.
|
|
935
|
+
nodal_constraints: Symbolic ``NodalConstraint`` objects (post-
|
|
936
|
+
preprocessing, pre-lowering).
|
|
937
|
+
cross_node_constraints: Symbolic ``CrossNodeConstraint`` objects.
|
|
938
|
+
n_byof_nodal: Number of byof nodal constraints (each adds one
|
|
939
|
+
column with the default weight).
|
|
940
|
+
n_byof_cross: Number of byof cross-node constraints (each adds
|
|
941
|
+
one entry with the default weight).
|
|
942
|
+
"""
|
|
943
|
+
default_vb = float(self.weights._raw_lam_vb)
|
|
944
|
+
|
|
945
|
+
# Count decomposed nodal constraints (vector → multiple scalars).
|
|
946
|
+
# Vector constraints are decomposed element-wise during lowering
|
|
947
|
+
# (see decompose_vector_nodal_constraints), so each element gets its
|
|
948
|
+
# own column. We mirror that here via check_shape() to ensure the
|
|
949
|
+
# array dimensions match the post-decomposition constraint count.
|
|
950
|
+
n_nodal = 0
|
|
951
|
+
for nc in nodal_constraints:
|
|
952
|
+
shape = nc.constraint.lhs.check_shape()
|
|
953
|
+
n_nodal += int(np.prod(shape)) if len(shape) > 0 else 1
|
|
954
|
+
|
|
955
|
+
# Byof constraints are scalar (one column each), added after symbolic.
|
|
956
|
+
n_nodal += n_byof_nodal
|
|
957
|
+
n_cross = len(cross_node_constraints) + n_byof_cross
|
|
958
|
+
|
|
959
|
+
# max(..., 1) avoids size-0 CVXPy parameters.
|
|
960
|
+
n_nodal_param = max(n_nodal, 1)
|
|
961
|
+
n_cross_param = max(n_cross, 1)
|
|
962
|
+
|
|
963
|
+
lam_vb_nodal = np.full((N, n_nodal_param), default_vb)
|
|
964
|
+
lam_vb_cross = np.full(n_cross_param, default_vb)
|
|
965
|
+
|
|
966
|
+
# Apply per-constraint .weight() overrides for nodal constraints.
|
|
967
|
+
col = 0
|
|
968
|
+
for nc in nodal_constraints:
|
|
969
|
+
shape = nc.constraint.lhs.check_shape()
|
|
970
|
+
n_elem = int(np.prod(shape)) if len(shape) > 0 else 1
|
|
971
|
+
|
|
972
|
+
w = nc._lam_vb
|
|
973
|
+
if w is not None:
|
|
974
|
+
nodes = nc.nodes if nc.nodes is not None else list(range(N))
|
|
975
|
+
if isinstance(w, (int, float)):
|
|
976
|
+
lam_vb_nodal[nodes, col : col + n_elem] = float(w)
|
|
977
|
+
elif isinstance(w, np.ndarray):
|
|
978
|
+
if w.ndim == 1:
|
|
979
|
+
# (n_elem,) — broadcast across nodes
|
|
980
|
+
for i in range(n_elem):
|
|
981
|
+
val = float(w[0]) if len(w) == 1 else float(w[i])
|
|
982
|
+
lam_vb_nodal[nodes, col + i] = val
|
|
983
|
+
elif w.ndim == 2:
|
|
984
|
+
# (n_nodes, n_elem) — per-node-per-element
|
|
985
|
+
for i in range(n_elem):
|
|
986
|
+
c_i = 0 if w.shape[1] == 1 else i
|
|
987
|
+
lam_vb_nodal[nodes, col + i] = w[:, c_i]
|
|
988
|
+
|
|
989
|
+
col += n_elem
|
|
990
|
+
|
|
991
|
+
# Apply per-constraint .weight() overrides for cross-node constraints.
|
|
992
|
+
for idx, cc in enumerate(cross_node_constraints):
|
|
993
|
+
if cc._lam_vb is not None:
|
|
994
|
+
lam_vb_cross[idx] = float(cc._lam_vb)
|
|
995
|
+
|
|
996
|
+
self.weights.set_vb_arrays(lam_vb_nodal, lam_vb_cross)
|
|
997
|
+
self.weights.normalize()
|
|
998
|
+
|
|
843
999
|
@abstractmethod
|
|
844
1000
|
def initialize(
|
|
845
1001
|
self,
|
{openscvx-0.4.1.dev140 → openscvx-0.4.1.dev144}/openscvx/algorithms/penalized_trust_region.py
RENAMED
|
@@ -241,21 +241,18 @@ class PenalizedTrustRegion(Algorithm):
|
|
|
241
241
|
|
|
242
242
|
@property
|
|
243
243
|
def lam_vb(self) -> float:
|
|
244
|
-
"""
|
|
244
|
+
"""Global virtual buffer penalty weight (pre-normalization).
|
|
245
245
|
|
|
246
|
-
This is the user-specified
|
|
247
|
-
property triggers automatic re-normalization
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
The autotuner may modify the normalized weight in
|
|
251
|
-
``self.weights.lam_vb`` during iteration. Those changes are
|
|
252
|
-
internal and do not alter the value returned here.
|
|
246
|
+
This is the user-specified scalar default before normalization.
|
|
247
|
+
Setting this property triggers automatic re-normalization.
|
|
248
|
+
Per-constraint overrides are set via ``.weight()`` on individual
|
|
249
|
+
constraints.
|
|
253
250
|
"""
|
|
254
251
|
return self.weights._raw_lam_vb
|
|
255
252
|
|
|
256
253
|
@lam_vb.setter
|
|
257
254
|
def lam_vb(self, value: float) -> None:
|
|
258
|
-
self.weights._raw_lam_vb = value
|
|
255
|
+
self.weights._raw_lam_vb = float(value)
|
|
259
256
|
self.weights.normalize()
|
|
260
257
|
|
|
261
258
|
def get_columns(self, verbosity: int = Verbosity.STANDARD) -> List[Column]:
|
|
@@ -614,7 +611,8 @@ class PenalizedTrustRegion(Algorithm):
|
|
|
614
611
|
lam_prox=state.lam_prox,
|
|
615
612
|
lam_cost=state.lam_cost,
|
|
616
613
|
lam_vc=state.lam_vc,
|
|
617
|
-
|
|
614
|
+
lam_vb_nodal=state.lam_vb_nodal,
|
|
615
|
+
lam_vb_cross=state.lam_vb_cross,
|
|
618
616
|
)
|
|
619
617
|
|
|
620
618
|
# Solve the convex subproblem
|
|
@@ -31,7 +31,8 @@ class CVXPyVariables:
|
|
|
31
31
|
lam_prox: Trust region weight parameter (scalar, nonneg)
|
|
32
32
|
lam_cost: Cost function weight parameter (n_states, nonneg)
|
|
33
33
|
lam_vc: Virtual control penalty weights (N-1 x n_states, nonneg)
|
|
34
|
-
|
|
34
|
+
lam_vb_nodal: Virtual buffer penalty weights for nodal constraints (N x n_nodal, nonneg)
|
|
35
|
+
lam_vb_cross: Virtual buffer penalty weights for cross-node constraints (n_cross, nonneg)
|
|
35
36
|
|
|
36
37
|
x: State variable (N x n_states)
|
|
37
38
|
dx: State error variable (N x n_states)
|
|
@@ -79,7 +80,8 @@ class CVXPyVariables:
|
|
|
79
80
|
lam_prox: "cp.Parameter"
|
|
80
81
|
lam_cost: "cp.Parameter"
|
|
81
82
|
lam_vc: "cp.Parameter"
|
|
82
|
-
|
|
83
|
+
lam_vb_nodal: "cp.Parameter"
|
|
84
|
+
lam_vb_cross: "cp.Parameter"
|
|
83
85
|
|
|
84
86
|
# State variables and parameters
|
|
85
87
|
x: "cp.Variable"
|
|
@@ -285,6 +285,20 @@ class Problem:
|
|
|
285
285
|
)
|
|
286
286
|
self._algorithm = algorithm
|
|
287
287
|
|
|
288
|
+
# Build per-constraint lam_vb arrays from symbolic constraints and
|
|
289
|
+
# re-normalize so that per-constraint .weight() overrides participate
|
|
290
|
+
# in the normalization scale. Include byof constraint counts so the
|
|
291
|
+
# arrays are sized to match the post-lowering constraint list.
|
|
292
|
+
n_byof_nodal = len(byof.get("nodal_constraints", [])) if byof else 0
|
|
293
|
+
n_byof_cross = len(byof.get("cross_nodal_constraints", [])) if byof else 0
|
|
294
|
+
self._algorithm._resolve_lam_vb(
|
|
295
|
+
N=self.symbolic.N,
|
|
296
|
+
nodal_constraints=self.symbolic.constraints.nodal,
|
|
297
|
+
cross_node_constraints=self.symbolic.constraints.cross_node,
|
|
298
|
+
n_byof_nodal=n_byof_nodal,
|
|
299
|
+
n_byof_cross=n_byof_cross,
|
|
300
|
+
)
|
|
301
|
+
|
|
288
302
|
# Resolve discretizer: None → default, dict → LinearizeDiscretize(**dict), instance → use
|
|
289
303
|
if discretizer is None:
|
|
290
304
|
self._discretizer = LinearizeDiscretize()
|
|
@@ -26,6 +26,12 @@ def propagate_trajectory_results(
|
|
|
26
26
|
This function takes the optimal control solution and propagates it through the
|
|
27
27
|
nonlinear dynamics to compute the actual state trajectory and other metrics.
|
|
28
28
|
|
|
29
|
+
When ``states_prop`` includes propagation-only states (e.g. via ``dynamics_prop`` /
|
|
30
|
+
``states_prop``), ``x_full`` has shape ``(n_times, n_prop_states)`` with
|
|
31
|
+
``n_prop_states > n_opt_states``. The discrete dynamics and cost use only the
|
|
32
|
+
optimization-state portion; propagation-only states are preserved from the last
|
|
33
|
+
propagated step and included in ``trajectory``.
|
|
34
|
+
|
|
29
35
|
Args:
|
|
30
36
|
params (dict): System parameters.
|
|
31
37
|
settings (Config): Configuration settings.
|
|
@@ -100,14 +106,39 @@ def propagate_trajectory_results(
|
|
|
100
106
|
settings.sim.x_prop = original_x_prop
|
|
101
107
|
|
|
102
108
|
# Calculate cost using utility function and metadata from settings
|
|
109
|
+
# dynamics_discrete operates on optimization states only; when propagation has
|
|
110
|
+
# extra states, pass only the opt-state portion and then reattach the prop-only tail
|
|
111
|
+
x_minus = np.asarray(x_full[-1, :n_opt_states])
|
|
112
|
+
x_plus = np.asarray(
|
|
113
|
+
dynamics_discrete(
|
|
114
|
+
x_minus,
|
|
115
|
+
np.asarray(u[-1]),
|
|
116
|
+
int(settings.sim.n - 1),
|
|
117
|
+
params,
|
|
118
|
+
)
|
|
119
|
+
).reshape(-1)
|
|
120
|
+
if n_prop_states > n_opt_states:
|
|
121
|
+
# Preserve propagation-only states (not updated by discrete dynamics)
|
|
122
|
+
full_final = np.concatenate([x_plus, np.asarray(x_full[-1, n_opt_states:])], axis=0)
|
|
123
|
+
else:
|
|
124
|
+
full_final = x_plus
|
|
125
|
+
x_for_cost = np.concatenate([x_full[:-1], full_final[None, :]], axis=0)
|
|
126
|
+
|
|
103
127
|
cost = calculate_cost_from_boundaries(
|
|
104
|
-
|
|
128
|
+
x_for_cost[:, :n_opt_states],
|
|
129
|
+
settings.sim.x.initial_type,
|
|
130
|
+
settings.sim.x.final_type,
|
|
105
131
|
)
|
|
106
132
|
|
|
107
|
-
# Calculate CTCS constraint violation
|
|
108
|
-
|
|
133
|
+
# Calculate CTCS constraint violation (use state after final impulse when applicable)
|
|
134
|
+
if dynamics_discrete is not None and np.any(settings.sim.u.is_impulsive):
|
|
135
|
+
ctcs_violation = full_final[settings.sim.ctcs_slice_prop]
|
|
136
|
+
else:
|
|
137
|
+
ctcs_violation = x_full[-1, settings.sim.ctcs_slice_prop]
|
|
109
138
|
|
|
110
|
-
# Build trajectory dictionary with all states and controls
|
|
139
|
+
# Build trajectory dictionary with all states and controls.
|
|
140
|
+
# result._states is states_prop (opt + propagation-only); each state._slice
|
|
141
|
+
# indexes into the full propagation state, so propagation-only states are included.
|
|
111
142
|
trajectory_dict = {}
|
|
112
143
|
|
|
113
144
|
# Add all states (user-defined and augmented)
|
|
@@ -350,7 +350,8 @@ class PTRSolver(ConvexSolver):
|
|
|
350
350
|
lam_prox = ocp_vars.lam_prox
|
|
351
351
|
lam_cost = ocp_vars.lam_cost
|
|
352
352
|
lam_vc = ocp_vars.lam_vc
|
|
353
|
-
|
|
353
|
+
lam_vb_nodal = ocp_vars.lam_vb_nodal
|
|
354
|
+
lam_vb_cross = ocp_vars.lam_vb_cross
|
|
354
355
|
_ = ocp_vars.x_nonscaled
|
|
355
356
|
dx = ocp_vars.dx
|
|
356
357
|
du = ocp_vars.du
|
|
@@ -359,7 +360,8 @@ class PTRSolver(ConvexSolver):
|
|
|
359
360
|
nu_vb_cross = ocp_vars.nu_vb_cross
|
|
360
361
|
|
|
361
362
|
cost = cp.sum(lam_cost) * 0
|
|
362
|
-
cost +=
|
|
363
|
+
cost += cp.sum(lam_vb_nodal) * 0
|
|
364
|
+
cost += cp.sum(lam_vb_cross) * 0
|
|
363
365
|
|
|
364
366
|
# Boundary condition cost terms (use scaled x for numerical conditioning)
|
|
365
367
|
x = ocp_vars.x
|
|
@@ -381,18 +383,18 @@ class PTRSolver(ConvexSolver):
|
|
|
381
383
|
# Virtual Control Slack
|
|
382
384
|
cost += sum(cp.sum(lam_vc[i - 1] * cp.abs(nu[i - 1])) for i in range(1, settings.sim.n))
|
|
383
385
|
|
|
384
|
-
# Virtual buffer penalty for nodal constraints
|
|
386
|
+
# Virtual buffer penalty for nodal constraints (per-node weighting)
|
|
385
387
|
idx_ncvx = 0
|
|
386
388
|
if jax_constraints.nodal:
|
|
387
389
|
for constraint in jax_constraints.nodal:
|
|
388
|
-
cost +=
|
|
390
|
+
cost += lam_vb_nodal[:, idx_ncvx] @ cp.pos(nu_vb[idx_ncvx])
|
|
389
391
|
idx_ncvx += 1
|
|
390
392
|
|
|
391
393
|
# Virtual slack penalty for cross-node constraints
|
|
392
394
|
idx_cross = 0
|
|
393
395
|
if jax_constraints.cross_node:
|
|
394
396
|
for constraint in jax_constraints.cross_node:
|
|
395
|
-
cost +=
|
|
397
|
+
cost += lam_vb_cross[idx_cross] * cp.pos(nu_vb_cross[idx_cross])
|
|
396
398
|
idx_cross += 1
|
|
397
399
|
|
|
398
400
|
return cost
|
|
@@ -725,7 +727,8 @@ class PTRSolver(ConvexSolver):
|
|
|
725
727
|
lam_prox: float,
|
|
726
728
|
lam_cost: Union[float, np.ndarray],
|
|
727
729
|
lam_vc: np.ndarray,
|
|
728
|
-
|
|
730
|
+
lam_vb_nodal: np.ndarray,
|
|
731
|
+
lam_vb_cross: np.ndarray,
|
|
729
732
|
) -> None:
|
|
730
733
|
"""Update SCP penalty weights.
|
|
731
734
|
|
|
@@ -737,12 +740,16 @@ class PTRSolver(ConvexSolver):
|
|
|
737
740
|
lam_cost: Cost function weight. Scalar or array of shape
|
|
738
741
|
``(n_states,)`` for per-state weighting.
|
|
739
742
|
lam_vc: Virtual control penalty weights, shape (N-1, n_states)
|
|
740
|
-
|
|
743
|
+
lam_vb_nodal: Virtual buffer penalty weights for nodal constraints,
|
|
744
|
+
shape ``(N, n_nodal_constraints)``.
|
|
745
|
+
lam_vb_cross: Virtual buffer penalty weights for cross-node
|
|
746
|
+
constraints, shape ``(n_cross_node_constraints,)``.
|
|
741
747
|
"""
|
|
742
748
|
self._set_param("lam_prox", lam_prox)
|
|
743
749
|
self._set_param("lam_cost", lam_cost)
|
|
744
750
|
self._set_param("lam_vc", lam_vc)
|
|
745
|
-
self._set_param("
|
|
751
|
+
self._set_param("lam_vb_nodal", lam_vb_nodal)
|
|
752
|
+
self._set_param("lam_vb_cross", lam_vb_cross)
|
|
746
753
|
|
|
747
754
|
def update_boundary_conditions(
|
|
748
755
|
self,
|