openscvx 0.3.2.dev333__tar.gz → 0.3.2.dev339__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.3.2.dev333/openscvx.egg-info → openscvx-0.3.2.dev339}/PKG-INFO +1 -1
- {openscvx-0.3.2.dev333 → openscvx-0.3.2.dev339}/openscvx/_version.py +3 -3
- {openscvx-0.3.2.dev333 → openscvx-0.3.2.dev339}/openscvx/problem.py +1 -2
- {openscvx-0.3.2.dev333 → openscvx-0.3.2.dev339}/openscvx/symbolic/builder.py +13 -7
- {openscvx-0.3.2.dev333 → openscvx-0.3.2.dev339}/openscvx/symbolic/preprocessing.py +136 -0
- {openscvx-0.3.2.dev333 → openscvx-0.3.2.dev339/openscvx.egg-info}/PKG-INFO +1 -1
- {openscvx-0.3.2.dev333 → openscvx-0.3.2.dev339}/tests/symbolic/test_preprocessing.py +175 -0
- {openscvx-0.3.2.dev333 → openscvx-0.3.2.dev339}/.github/assets/logo.svg +0 -0
- {openscvx-0.3.2.dev333 → openscvx-0.3.2.dev339}/.github/release-drafter.yml +0 -0
- {openscvx-0.3.2.dev333 → openscvx-0.3.2.dev339}/.github/workflows/_docs.yml +0 -0
- {openscvx-0.3.2.dev333 → openscvx-0.3.2.dev339}/.github/workflows/branch-name.yml +0 -0
- {openscvx-0.3.2.dev333 → openscvx-0.3.2.dev339}/.github/workflows/docs.yml +0 -0
- {openscvx-0.3.2.dev333 → openscvx-0.3.2.dev339}/.github/workflows/lint.yml +0 -0
- {openscvx-0.3.2.dev333 → openscvx-0.3.2.dev339}/.github/workflows/nightly.yml +0 -0
- {openscvx-0.3.2.dev333 → openscvx-0.3.2.dev339}/.github/workflows/release-drafter.yml +0 -0
- {openscvx-0.3.2.dev333 → openscvx-0.3.2.dev339}/.github/workflows/release.yml +0 -0
- {openscvx-0.3.2.dev333 → openscvx-0.3.2.dev339}/.github/workflows/tests-integration.yml +0 -0
- {openscvx-0.3.2.dev333 → openscvx-0.3.2.dev339}/.github/workflows/tests-unit.yml +0 -0
- {openscvx-0.3.2.dev333 → openscvx-0.3.2.dev339}/.gitignore +0 -0
- {openscvx-0.3.2.dev333 → openscvx-0.3.2.dev339}/CONTRIBUTING.md +0 -0
- {openscvx-0.3.2.dev333 → openscvx-0.3.2.dev339}/LICENSE +0 -0
- {openscvx-0.3.2.dev333 → openscvx-0.3.2.dev339}/README.md +0 -0
- {openscvx-0.3.2.dev333 → openscvx-0.3.2.dev339}/docs/Foundations/constraint_reformulation.md +0 -0
- {openscvx-0.3.2.dev333 → openscvx-0.3.2.dev339}/docs/Foundations/control_parameterization.md +0 -0
- {openscvx-0.3.2.dev333 → openscvx-0.3.2.dev339}/docs/Foundations/discretization.md +0 -0
- {openscvx-0.3.2.dev333 → openscvx-0.3.2.dev339}/docs/Foundations/ocp.md +0 -0
- {openscvx-0.3.2.dev333 → openscvx-0.3.2.dev339}/docs/Foundations/scvx.md +0 -0
- {openscvx-0.3.2.dev333 → openscvx-0.3.2.dev339}/docs/Foundations/time_dilation.md +0 -0
- {openscvx-0.3.2.dev333 → openscvx-0.3.2.dev339}/docs/UnderTheHood/lowering_architecture.md +0 -0
- {openscvx-0.3.2.dev333 → openscvx-0.3.2.dev339}/docs/UnderTheHood/vectorization_and_vmapping.md +0 -0
- {openscvx-0.3.2.dev333 → openscvx-0.3.2.dev339}/docs/UsersGuide/00_introduction.md +0 -0
- {openscvx-0.3.2.dev333 → openscvx-0.3.2.dev339}/docs/UsersGuide/01_hello_world_brachistochrone.md +0 -0
- {openscvx-0.3.2.dev333 → openscvx-0.3.2.dev339}/docs/UsersGuide/02_drone_racing_constraints.md +0 -0
- {openscvx-0.3.2.dev333 → openscvx-0.3.2.dev339}/docs/UsersGuide/03_obstacle_avoidance_vmap.md +0 -0
- {openscvx-0.3.2.dev333 → openscvx-0.3.2.dev339}/docs/UsersGuide/04_viewpoint_constraints.md +0 -0
- {openscvx-0.3.2.dev333 → openscvx-0.3.2.dev339}/docs/UsersGuide/05_visualization.md +0 -0
- {openscvx-0.3.2.dev333 → openscvx-0.3.2.dev339}/docs/UsersGuide/06_logic.md +0 -0
- {openscvx-0.3.2.dev333 → openscvx-0.3.2.dev339}/docs/UsersGuide/07_lie.md +0 -0
- {openscvx-0.3.2.dev333 → openscvx-0.3.2.dev339}/docs/assets/favicon.png +0 -0
- {openscvx-0.3.2.dev333 → openscvx-0.3.2.dev339}/docs/assets/images/ct-scvx_dark.png +0 -0
- {openscvx-0.3.2.dev333 → openscvx-0.3.2.dev339}/docs/assets/images/ct-scvx_light.png +0 -0
- {openscvx-0.3.2.dev333 → openscvx-0.3.2.dev339}/docs/assets/images/ctcs_dark.png +0 -0
- {openscvx-0.3.2.dev333 → openscvx-0.3.2.dev339}/docs/assets/images/ctcs_light.png +0 -0
- {openscvx-0.3.2.dev333 → openscvx-0.3.2.dev339}/docs/assets/images/problem_class_dark.png +0 -0
- {openscvx-0.3.2.dev333 → openscvx-0.3.2.dev339}/docs/assets/images/problem_class_light.png +0 -0
- {openscvx-0.3.2.dev333 → openscvx-0.3.2.dev339}/docs/assets/logo.svg +0 -0
- {openscvx-0.3.2.dev333 → openscvx-0.3.2.dev339}/docs/citation.md +0 -0
- {openscvx-0.3.2.dev333 → openscvx-0.3.2.dev339}/docs/examples.md +0 -0
- {openscvx-0.3.2.dev333 → openscvx-0.3.2.dev339}/docs/getting-started.md +0 -0
- {openscvx-0.3.2.dev333 → openscvx-0.3.2.dev339}/docs/index.md +0 -0
- {openscvx-0.3.2.dev333 → openscvx-0.3.2.dev339}/docs/javascripts/mathjax.js +0 -0
- {openscvx-0.3.2.dev333 → openscvx-0.3.2.dev339}/examples/abstract/brachistochrone.py +0 -0
- {openscvx-0.3.2.dev333 → openscvx-0.3.2.dev339}/examples/arm/three_link_arm.py +0 -0
- {openscvx-0.3.2.dev333 → openscvx-0.3.2.dev339}/examples/car/dubins_car.py +0 -0
- {openscvx-0.3.2.dev333 → openscvx-0.3.2.dev339}/examples/car/dubins_car_conditional.py +0 -0
- {openscvx-0.3.2.dev333 → openscvx-0.3.2.dev339}/examples/car/dubins_car_disjoint.py +0 -0
- {openscvx-0.3.2.dev333 → openscvx-0.3.2.dev339}/examples/car/dubins_car_stljax.py +0 -0
- {openscvx-0.3.2.dev333 → openscvx-0.3.2.dev339}/examples/drone/cinema_vp.py +0 -0
- {openscvx-0.3.2.dev333 → openscvx-0.3.2.dev339}/examples/drone/cinema_vp_realtime_base.py +0 -0
- {openscvx-0.3.2.dev333 → openscvx-0.3.2.dev339}/examples/drone/dr_double_integrator.py +0 -0
- {openscvx-0.3.2.dev333 → openscvx-0.3.2.dev339}/examples/drone/dr_vp.py +0 -0
- {openscvx-0.3.2.dev333 → openscvx-0.3.2.dev339}/examples/drone/dr_vp_nodal.py +0 -0
- {openscvx-0.3.2.dev333 → openscvx-0.3.2.dev339}/examples/drone/dr_vp_polytope.py +0 -0
- {openscvx-0.3.2.dev333 → openscvx-0.3.2.dev339}/examples/drone/drone_racing.py +0 -0
- {openscvx-0.3.2.dev333 → openscvx-0.3.2.dev339}/examples/drone/obstacle_avoidance.py +0 -0
- {openscvx-0.3.2.dev333 → openscvx-0.3.2.dev339}/examples/drone/obstacle_avoidance_nodal.py +0 -0
- {openscvx-0.3.2.dev333 → openscvx-0.3.2.dev339}/examples/drone/obstacle_avoidance_realtime_base.py +0 -0
- {openscvx-0.3.2.dev333 → openscvx-0.3.2.dev339}/examples/drone/obstacle_avoidance_vmap.py +0 -0
- {openscvx-0.3.2.dev333 → openscvx-0.3.2.dev339}/examples/plotting.py +0 -0
- {openscvx-0.3.2.dev333 → openscvx-0.3.2.dev339}/examples/plotting_viser.py +0 -0
- {openscvx-0.3.2.dev333 → openscvx-0.3.2.dev339}/examples/realtime/cinema_vp_realtime.py +0 -0
- {openscvx-0.3.2.dev333 → openscvx-0.3.2.dev339}/examples/realtime/drone_racing_realtime.py +0 -0
- {openscvx-0.3.2.dev333 → openscvx-0.3.2.dev339}/examples/realtime/dubins_car_realtime.py +0 -0
- {openscvx-0.3.2.dev333 → openscvx-0.3.2.dev339}/examples/realtime/obstacle_avoidance_realtime.py +0 -0
- {openscvx-0.3.2.dev333 → openscvx-0.3.2.dev339}/examples/rocket/3DoF_pdg.py +0 -0
- {openscvx-0.3.2.dev333 → openscvx-0.3.2.dev339}/examples/spacecraft/proxops_cw.py +0 -0
- {openscvx-0.3.2.dev333 → openscvx-0.3.2.dev339}/figures/ctlos_cine.gif +0 -0
- {openscvx-0.3.2.dev333 → openscvx-0.3.2.dev339}/figures/ctlos_dr.gif +0 -0
- {openscvx-0.3.2.dev333 → openscvx-0.3.2.dev339}/figures/dtlos_cine.gif +0 -0
- {openscvx-0.3.2.dev333 → openscvx-0.3.2.dev339}/figures/dtlos_dr.gif +0 -0
- {openscvx-0.3.2.dev333 → openscvx-0.3.2.dev339}/figures/openscvx_logo.svg +0 -0
- {openscvx-0.3.2.dev333 → openscvx-0.3.2.dev339}/figures/openscvx_logo_square.png +0 -0
- {openscvx-0.3.2.dev333 → openscvx-0.3.2.dev339}/figures/oscvx_structure_full_dark.svg +0 -0
- {openscvx-0.3.2.dev333 → openscvx-0.3.2.dev339}/figures/video_preview.png +0 -0
- {openscvx-0.3.2.dev333 → openscvx-0.3.2.dev339}/material/__init__.py +0 -0
- {openscvx-0.3.2.dev333 → openscvx-0.3.2.dev339}/material/overrides/assets/images/layers/1-background.avif +0 -0
- {openscvx-0.3.2.dev333 → openscvx-0.3.2.dev339}/material/overrides/assets/images/layers/1-background@1x.avif +0 -0
- {openscvx-0.3.2.dev333 → openscvx-0.3.2.dev339}/material/overrides/assets/images/layers/1-background@2x.avif +0 -0
- {openscvx-0.3.2.dev333 → openscvx-0.3.2.dev339}/material/overrides/assets/images/layers/1-background@3x.avif +0 -0
- {openscvx-0.3.2.dev333 → openscvx-0.3.2.dev339}/material/overrides/assets/images/layers/1-background@4x.avif +0 -0
- {openscvx-0.3.2.dev333 → openscvx-0.3.2.dev339}/material/overrides/assets/images/layers/2-mars.avif +0 -0
- {openscvx-0.3.2.dev333 → openscvx-0.3.2.dev339}/material/overrides/assets/images/layers/2-mars@1x.avif +0 -0
- {openscvx-0.3.2.dev333 → openscvx-0.3.2.dev339}/material/overrides/assets/images/layers/2-mars@2x.avif +0 -0
- {openscvx-0.3.2.dev333 → openscvx-0.3.2.dev339}/material/overrides/assets/images/layers/2-mars@3x.avif +0 -0
- {openscvx-0.3.2.dev333 → openscvx-0.3.2.dev339}/material/overrides/assets/images/layers/2-mars@4x.avif +0 -0
- {openscvx-0.3.2.dev333 → openscvx-0.3.2.dev339}/material/overrides/assets/images/layers/3-moon.avif +0 -0
- {openscvx-0.3.2.dev333 → openscvx-0.3.2.dev339}/material/overrides/assets/images/layers/3-moon@1x.avif +0 -0
- {openscvx-0.3.2.dev333 → openscvx-0.3.2.dev339}/material/overrides/assets/images/layers/3-moon@2x.avif +0 -0
- {openscvx-0.3.2.dev333 → openscvx-0.3.2.dev339}/material/overrides/assets/images/layers/3-moon@3x.avif +0 -0
- {openscvx-0.3.2.dev333 → openscvx-0.3.2.dev339}/material/overrides/assets/images/layers/3-moon@4x.avif +0 -0
- {openscvx-0.3.2.dev333 → openscvx-0.3.2.dev339}/material/overrides/assets/images/layers/4-sat1.avif +0 -0
- {openscvx-0.3.2.dev333 → openscvx-0.3.2.dev339}/material/overrides/assets/images/layers/4-sat1@1x.avif +0 -0
- {openscvx-0.3.2.dev333 → openscvx-0.3.2.dev339}/material/overrides/assets/images/layers/4-sat1@2x.avif +0 -0
- {openscvx-0.3.2.dev333 → openscvx-0.3.2.dev339}/material/overrides/assets/images/layers/4-sat1@3x.avif +0 -0
- {openscvx-0.3.2.dev333 → openscvx-0.3.2.dev339}/material/overrides/assets/images/layers/4-sat1@4x.avif +0 -0
- {openscvx-0.3.2.dev333 → openscvx-0.3.2.dev339}/material/overrides/assets/images/layers/5-space.avif +0 -0
- {openscvx-0.3.2.dev333 → openscvx-0.3.2.dev339}/material/overrides/assets/images/layers/5-space@1x.avif +0 -0
- {openscvx-0.3.2.dev333 → openscvx-0.3.2.dev339}/material/overrides/assets/images/layers/5-space@2x.avif +0 -0
- {openscvx-0.3.2.dev333 → openscvx-0.3.2.dev339}/material/overrides/assets/images/layers/5-space@3x.avif +0 -0
- {openscvx-0.3.2.dev333 → openscvx-0.3.2.dev339}/material/overrides/assets/images/layers/5-space@4x.avif +0 -0
- {openscvx-0.3.2.dev333 → openscvx-0.3.2.dev339}/material/overrides/assets/images/layers/6-earth.avif +0 -0
- {openscvx-0.3.2.dev333 → openscvx-0.3.2.dev339}/material/overrides/assets/images/layers/6-earth@1x.avif +0 -0
- {openscvx-0.3.2.dev333 → openscvx-0.3.2.dev339}/material/overrides/assets/images/layers/6-earth@2x.avif +0 -0
- {openscvx-0.3.2.dev333 → openscvx-0.3.2.dev339}/material/overrides/assets/images/layers/6-earth@3x.avif +0 -0
- {openscvx-0.3.2.dev333 → openscvx-0.3.2.dev339}/material/overrides/assets/images/layers/6-earth@4x.avif +0 -0
- {openscvx-0.3.2.dev333 → openscvx-0.3.2.dev339}/material/overrides/assets/javascripts/parallax.js +0 -0
- {openscvx-0.3.2.dev333 → openscvx-0.3.2.dev339}/material/overrides/assets/logo.svg +0 -0
- {openscvx-0.3.2.dev333 → openscvx-0.3.2.dev339}/material/overrides/assets/stylesheets/custom.css +0 -0
- {openscvx-0.3.2.dev333 → openscvx-0.3.2.dev339}/material/overrides/assets/stylesheets/parallax.css +0 -0
- {openscvx-0.3.2.dev333 → openscvx-0.3.2.dev339}/material/overrides/home.html +0 -0
- {openscvx-0.3.2.dev333 → openscvx-0.3.2.dev339}/material/overrides/main.html +0 -0
- {openscvx-0.3.2.dev333 → openscvx-0.3.2.dev339}/material/overrides/partials/parallax/hero.html +0 -0
- {openscvx-0.3.2.dev333 → openscvx-0.3.2.dev339}/material/overrides/partials/parallax.html +0 -0
- {openscvx-0.3.2.dev333 → openscvx-0.3.2.dev339}/mkdocs.yml +0 -0
- {openscvx-0.3.2.dev333 → openscvx-0.3.2.dev339}/openscvx/__init__.py +0 -0
- {openscvx-0.3.2.dev333 → openscvx-0.3.2.dev339}/openscvx/algorithms/__init__.py +0 -0
- {openscvx-0.3.2.dev333 → openscvx-0.3.2.dev339}/openscvx/algorithms/autotuning.py +0 -0
- {openscvx-0.3.2.dev333 → openscvx-0.3.2.dev339}/openscvx/algorithms/base.py +0 -0
- {openscvx-0.3.2.dev333 → openscvx-0.3.2.dev339}/openscvx/algorithms/optimization_results.py +0 -0
- {openscvx-0.3.2.dev333 → openscvx-0.3.2.dev339}/openscvx/algorithms/penalized_trust_region.py +0 -0
- {openscvx-0.3.2.dev333 → openscvx-0.3.2.dev339}/openscvx/config.py +0 -0
- {openscvx-0.3.2.dev333 → openscvx-0.3.2.dev339}/openscvx/discretization/__init__.py +0 -0
- {openscvx-0.3.2.dev333 → openscvx-0.3.2.dev339}/openscvx/discretization/discretization.py +0 -0
- {openscvx-0.3.2.dev333 → openscvx-0.3.2.dev339}/openscvx/expert/__init__.py +0 -0
- {openscvx-0.3.2.dev333 → openscvx-0.3.2.dev339}/openscvx/expert/byof.py +0 -0
- {openscvx-0.3.2.dev333 → openscvx-0.3.2.dev339}/openscvx/expert/lowering.py +0 -0
- {openscvx-0.3.2.dev333 → openscvx-0.3.2.dev339}/openscvx/expert/validation.py +0 -0
- {openscvx-0.3.2.dev333 → openscvx-0.3.2.dev339}/openscvx/init/__init__.py +0 -0
- {openscvx-0.3.2.dev333 → openscvx-0.3.2.dev339}/openscvx/init/interpolation.py +0 -0
- {openscvx-0.3.2.dev333 → openscvx-0.3.2.dev339}/openscvx/integrators/__init__.py +0 -0
- {openscvx-0.3.2.dev333 → openscvx-0.3.2.dev339}/openscvx/integrators/runge_kutta.py +0 -0
- {openscvx-0.3.2.dev333 → openscvx-0.3.2.dev339}/openscvx/lowered/__init__.py +0 -0
- {openscvx-0.3.2.dev333 → openscvx-0.3.2.dev339}/openscvx/lowered/cvxpy_constraints.py +0 -0
- {openscvx-0.3.2.dev333 → openscvx-0.3.2.dev339}/openscvx/lowered/cvxpy_variables.py +0 -0
- {openscvx-0.3.2.dev333 → openscvx-0.3.2.dev339}/openscvx/lowered/dynamics.py +0 -0
- {openscvx-0.3.2.dev333 → openscvx-0.3.2.dev339}/openscvx/lowered/jax_constraints.py +0 -0
- {openscvx-0.3.2.dev333 → openscvx-0.3.2.dev339}/openscvx/lowered/parameters.py +0 -0
- {openscvx-0.3.2.dev333 → openscvx-0.3.2.dev339}/openscvx/lowered/problem.py +0 -0
- {openscvx-0.3.2.dev333 → openscvx-0.3.2.dev339}/openscvx/lowered/unified.py +0 -0
- {openscvx-0.3.2.dev333 → openscvx-0.3.2.dev339}/openscvx/plotting/__init__.py +0 -0
- {openscvx-0.3.2.dev333 → openscvx-0.3.2.dev339}/openscvx/plotting/plotting.py +0 -0
- {openscvx-0.3.2.dev333 → openscvx-0.3.2.dev339}/openscvx/plotting/scp_iteration.py +0 -0
- {openscvx-0.3.2.dev333 → openscvx-0.3.2.dev339}/openscvx/plotting/viser/__init__.py +0 -0
- {openscvx-0.3.2.dev333 → openscvx-0.3.2.dev339}/openscvx/plotting/viser/animated.py +0 -0
- {openscvx-0.3.2.dev333 → openscvx-0.3.2.dev339}/openscvx/plotting/viser/plotly_integration.py +0 -0
- {openscvx-0.3.2.dev333 → openscvx-0.3.2.dev339}/openscvx/plotting/viser/primitives.py +0 -0
- {openscvx-0.3.2.dev333 → openscvx-0.3.2.dev339}/openscvx/plotting/viser/scp.py +0 -0
- {openscvx-0.3.2.dev333 → openscvx-0.3.2.dev339}/openscvx/plotting/viser/server.py +0 -0
- {openscvx-0.3.2.dev333 → openscvx-0.3.2.dev339}/openscvx/propagation/__init__.py +0 -0
- {openscvx-0.3.2.dev333 → openscvx-0.3.2.dev339}/openscvx/propagation/post_processing.py +0 -0
- {openscvx-0.3.2.dev333 → openscvx-0.3.2.dev339}/openscvx/propagation/propagation.py +0 -0
- {openscvx-0.3.2.dev333 → openscvx-0.3.2.dev339}/openscvx/solvers/__init__.py +0 -0
- {openscvx-0.3.2.dev333 → openscvx-0.3.2.dev339}/openscvx/solvers/base.py +0 -0
- {openscvx-0.3.2.dev333 → openscvx-0.3.2.dev339}/openscvx/solvers/ptr_solver.py +0 -0
- {openscvx-0.3.2.dev333 → openscvx-0.3.2.dev339}/openscvx/symbolic/__init__.py +0 -0
- {openscvx-0.3.2.dev333 → openscvx-0.3.2.dev339}/openscvx/symbolic/augmentation.py +0 -0
- {openscvx-0.3.2.dev333 → openscvx-0.3.2.dev339}/openscvx/symbolic/constraint_set.py +0 -0
- {openscvx-0.3.2.dev333 → openscvx-0.3.2.dev339}/openscvx/symbolic/expr/__init__.py +0 -0
- {openscvx-0.3.2.dev333 → openscvx-0.3.2.dev339}/openscvx/symbolic/expr/arithmetic.py +0 -0
- {openscvx-0.3.2.dev333 → openscvx-0.3.2.dev339}/openscvx/symbolic/expr/array.py +0 -0
- {openscvx-0.3.2.dev333 → openscvx-0.3.2.dev339}/openscvx/symbolic/expr/constraint.py +0 -0
- {openscvx-0.3.2.dev333 → openscvx-0.3.2.dev339}/openscvx/symbolic/expr/control.py +0 -0
- {openscvx-0.3.2.dev333 → openscvx-0.3.2.dev339}/openscvx/symbolic/expr/expr.py +0 -0
- {openscvx-0.3.2.dev333 → openscvx-0.3.2.dev339}/openscvx/symbolic/expr/lie/__init__.py +0 -0
- {openscvx-0.3.2.dev333 → openscvx-0.3.2.dev339}/openscvx/symbolic/expr/lie/adjoint.py +0 -0
- {openscvx-0.3.2.dev333 → openscvx-0.3.2.dev339}/openscvx/symbolic/expr/lie/se3.py +0 -0
- {openscvx-0.3.2.dev333 → openscvx-0.3.2.dev339}/openscvx/symbolic/expr/lie/so3.py +0 -0
- {openscvx-0.3.2.dev333 → openscvx-0.3.2.dev339}/openscvx/symbolic/expr/linalg.py +0 -0
- {openscvx-0.3.2.dev333 → openscvx-0.3.2.dev339}/openscvx/symbolic/expr/logic.py +0 -0
- {openscvx-0.3.2.dev333 → openscvx-0.3.2.dev339}/openscvx/symbolic/expr/math.py +0 -0
- {openscvx-0.3.2.dev333 → openscvx-0.3.2.dev339}/openscvx/symbolic/expr/spatial.py +0 -0
- {openscvx-0.3.2.dev333 → openscvx-0.3.2.dev339}/openscvx/symbolic/expr/state.py +0 -0
- {openscvx-0.3.2.dev333 → openscvx-0.3.2.dev339}/openscvx/symbolic/expr/stl.py +0 -0
- {openscvx-0.3.2.dev333 → openscvx-0.3.2.dev339}/openscvx/symbolic/expr/variable.py +0 -0
- {openscvx-0.3.2.dev333 → openscvx-0.3.2.dev339}/openscvx/symbolic/expr/vmap.py +0 -0
- {openscvx-0.3.2.dev333 → openscvx-0.3.2.dev339}/openscvx/symbolic/hashing.py +0 -0
- {openscvx-0.3.2.dev333 → openscvx-0.3.2.dev339}/openscvx/symbolic/lower.py +0 -0
- {openscvx-0.3.2.dev333 → openscvx-0.3.2.dev339}/openscvx/symbolic/lowerers/__init__.py +0 -0
- {openscvx-0.3.2.dev333 → openscvx-0.3.2.dev339}/openscvx/symbolic/lowerers/cvxpy/__init__.py +0 -0
- {openscvx-0.3.2.dev333 → openscvx-0.3.2.dev339}/openscvx/symbolic/lowerers/cvxpy/_lowerer.py +0 -0
- {openscvx-0.3.2.dev333 → openscvx-0.3.2.dev339}/openscvx/symbolic/lowerers/cvxpy/_registry.py +0 -0
- {openscvx-0.3.2.dev333 → openscvx-0.3.2.dev339}/openscvx/symbolic/lowerers/cvxpy/arithmetic.py +0 -0
- {openscvx-0.3.2.dev333 → openscvx-0.3.2.dev339}/openscvx/symbolic/lowerers/cvxpy/array.py +0 -0
- {openscvx-0.3.2.dev333 → openscvx-0.3.2.dev339}/openscvx/symbolic/lowerers/cvxpy/constraint.py +0 -0
- {openscvx-0.3.2.dev333 → openscvx-0.3.2.dev339}/openscvx/symbolic/lowerers/cvxpy/control.py +0 -0
- {openscvx-0.3.2.dev333 → openscvx-0.3.2.dev339}/openscvx/symbolic/lowerers/cvxpy/expr.py +0 -0
- {openscvx-0.3.2.dev333 → openscvx-0.3.2.dev339}/openscvx/symbolic/lowerers/cvxpy/linalg.py +0 -0
- {openscvx-0.3.2.dev333 → openscvx-0.3.2.dev339}/openscvx/symbolic/lowerers/cvxpy/logic.py +0 -0
- {openscvx-0.3.2.dev333 → openscvx-0.3.2.dev339}/openscvx/symbolic/lowerers/cvxpy/math.py +0 -0
- {openscvx-0.3.2.dev333 → openscvx-0.3.2.dev339}/openscvx/symbolic/lowerers/cvxpy/state.py +0 -0
- {openscvx-0.3.2.dev333 → openscvx-0.3.2.dev339}/openscvx/symbolic/lowerers/jax/__init__.py +0 -0
- {openscvx-0.3.2.dev333 → openscvx-0.3.2.dev339}/openscvx/symbolic/lowerers/jax/_lowerer.py +0 -0
- {openscvx-0.3.2.dev333 → openscvx-0.3.2.dev339}/openscvx/symbolic/lowerers/jax/_registry.py +0 -0
- {openscvx-0.3.2.dev333 → openscvx-0.3.2.dev339}/openscvx/symbolic/lowerers/jax/arithmetic.py +0 -0
- {openscvx-0.3.2.dev333 → openscvx-0.3.2.dev339}/openscvx/symbolic/lowerers/jax/array.py +0 -0
- {openscvx-0.3.2.dev333 → openscvx-0.3.2.dev339}/openscvx/symbolic/lowerers/jax/constraint.py +0 -0
- {openscvx-0.3.2.dev333 → openscvx-0.3.2.dev339}/openscvx/symbolic/lowerers/jax/control.py +0 -0
- {openscvx-0.3.2.dev333 → openscvx-0.3.2.dev339}/openscvx/symbolic/lowerers/jax/expr.py +0 -0
- {openscvx-0.3.2.dev333 → openscvx-0.3.2.dev339}/openscvx/symbolic/lowerers/jax/lie.py +0 -0
- {openscvx-0.3.2.dev333 → openscvx-0.3.2.dev339}/openscvx/symbolic/lowerers/jax/linalg.py +0 -0
- {openscvx-0.3.2.dev333 → openscvx-0.3.2.dev339}/openscvx/symbolic/lowerers/jax/logic.py +0 -0
- {openscvx-0.3.2.dev333 → openscvx-0.3.2.dev339}/openscvx/symbolic/lowerers/jax/math.py +0 -0
- {openscvx-0.3.2.dev333 → openscvx-0.3.2.dev339}/openscvx/symbolic/lowerers/jax/spatial.py +0 -0
- {openscvx-0.3.2.dev333 → openscvx-0.3.2.dev339}/openscvx/symbolic/lowerers/jax/state.py +0 -0
- {openscvx-0.3.2.dev333 → openscvx-0.3.2.dev339}/openscvx/symbolic/lowerers/jax/stl.py +0 -0
- {openscvx-0.3.2.dev333 → openscvx-0.3.2.dev339}/openscvx/symbolic/lowerers/jax/vmap.py +0 -0
- {openscvx-0.3.2.dev333 → openscvx-0.3.2.dev339}/openscvx/symbolic/problem.py +0 -0
- {openscvx-0.3.2.dev333 → openscvx-0.3.2.dev339}/openscvx/symbolic/time.py +0 -0
- {openscvx-0.3.2.dev333 → openscvx-0.3.2.dev339}/openscvx/symbolic/unified.py +0 -0
- {openscvx-0.3.2.dev333 → openscvx-0.3.2.dev339}/openscvx/utils/__init__.py +0 -0
- {openscvx-0.3.2.dev333 → openscvx-0.3.2.dev339}/openscvx/utils/cache.py +0 -0
- {openscvx-0.3.2.dev333 → openscvx-0.3.2.dev339}/openscvx/utils/caching.py +0 -0
- {openscvx-0.3.2.dev333 → openscvx-0.3.2.dev339}/openscvx/utils/printing.py +0 -0
- {openscvx-0.3.2.dev333 → openscvx-0.3.2.dev339}/openscvx/utils/profiling.py +0 -0
- {openscvx-0.3.2.dev333 → openscvx-0.3.2.dev339}/openscvx/utils/utils.py +0 -0
- {openscvx-0.3.2.dev333 → openscvx-0.3.2.dev339}/openscvx.egg-info/SOURCES.txt +0 -0
- {openscvx-0.3.2.dev333 → openscvx-0.3.2.dev339}/openscvx.egg-info/dependency_links.txt +0 -0
- {openscvx-0.3.2.dev333 → openscvx-0.3.2.dev339}/openscvx.egg-info/requires.txt +0 -0
- {openscvx-0.3.2.dev333 → openscvx-0.3.2.dev339}/openscvx.egg-info/top_level.txt +0 -0
- {openscvx-0.3.2.dev333 → openscvx-0.3.2.dev339}/pyproject.toml +0 -0
- {openscvx-0.3.2.dev333 → openscvx-0.3.2.dev339}/scripts/gen_example_pages.py +0 -0
- {openscvx-0.3.2.dev333 → openscvx-0.3.2.dev339}/scripts/gen_ref_pages.py +0 -0
- {openscvx-0.3.2.dev333 → openscvx-0.3.2.dev339}/setup.cfg +0 -0
- {openscvx-0.3.2.dev333 → openscvx-0.3.2.dev339}/tests/__init__.py +0 -0
- {openscvx-0.3.2.dev333 → openscvx-0.3.2.dev339}/tests/brachistochrone_analytical.py +0 -0
- {openscvx-0.3.2.dev333 → openscvx-0.3.2.dev339}/tests/symbolic/__init__.py +0 -0
- {openscvx-0.3.2.dev333 → openscvx-0.3.2.dev339}/tests/symbolic/expr/__init__.py +0 -0
- {openscvx-0.3.2.dev333 → openscvx-0.3.2.dev339}/tests/symbolic/expr/test_arithmetic.py +0 -0
- {openscvx-0.3.2.dev333 → openscvx-0.3.2.dev339}/tests/symbolic/expr/test_array.py +0 -0
- {openscvx-0.3.2.dev333 → openscvx-0.3.2.dev339}/tests/symbolic/expr/test_constraint.py +0 -0
- {openscvx-0.3.2.dev333 → openscvx-0.3.2.dev339}/tests/symbolic/expr/test_expr.py +0 -0
- {openscvx-0.3.2.dev333 → openscvx-0.3.2.dev339}/tests/symbolic/expr/test_lie.py +0 -0
- {openscvx-0.3.2.dev333 → openscvx-0.3.2.dev339}/tests/symbolic/expr/test_linalg.py +0 -0
- {openscvx-0.3.2.dev333 → openscvx-0.3.2.dev339}/tests/symbolic/expr/test_logic.py +0 -0
- {openscvx-0.3.2.dev333 → openscvx-0.3.2.dev339}/tests/symbolic/expr/test_math.py +0 -0
- {openscvx-0.3.2.dev333 → openscvx-0.3.2.dev339}/tests/symbolic/expr/test_node_reference.py +0 -0
- {openscvx-0.3.2.dev333 → openscvx-0.3.2.dev339}/tests/symbolic/expr/test_parameters.py +0 -0
- {openscvx-0.3.2.dev333 → openscvx-0.3.2.dev339}/tests/symbolic/expr/test_scaling.py +0 -0
- {openscvx-0.3.2.dev333 → openscvx-0.3.2.dev339}/tests/symbolic/expr/test_spatial.py +0 -0
- {openscvx-0.3.2.dev333 → openscvx-0.3.2.dev339}/tests/symbolic/expr/test_variable.py +0 -0
- {openscvx-0.3.2.dev333 → openscvx-0.3.2.dev339}/tests/symbolic/expr/test_vmap.py +0 -0
- {openscvx-0.3.2.dev333 → openscvx-0.3.2.dev339}/tests/symbolic/test_augmentation.py +0 -0
- {openscvx-0.3.2.dev333 → openscvx-0.3.2.dev339}/tests/symbolic/test_hashing.py +0 -0
- {openscvx-0.3.2.dev333 → openscvx-0.3.2.dev339}/tests/symbolic/test_lower_cvxpy.py +0 -0
- {openscvx-0.3.2.dev333 → openscvx-0.3.2.dev339}/tests/symbolic/test_lower_jax.py +0 -0
- {openscvx-0.3.2.dev333 → openscvx-0.3.2.dev339}/tests/symbolic/test_unified.py +0 -0
- {openscvx-0.3.2.dev333 → openscvx-0.3.2.dev339}/tests/test_brachistochrone.py +0 -0
- {openscvx-0.3.2.dev333 → openscvx-0.3.2.dev339}/tests/test_cvxpygen_optional.py +0 -0
- {openscvx-0.3.2.dev333 → openscvx-0.3.2.dev339}/tests/test_discretization.py +0 -0
- {openscvx-0.3.2.dev333 → openscvx-0.3.2.dev339}/tests/test_examples.py +0 -0
- {openscvx-0.3.2.dev333 → openscvx-0.3.2.dev339}/tests/test_expert.py +0 -0
- {openscvx-0.3.2.dev333 → openscvx-0.3.2.dev339}/tests/test_init.py +0 -0
- {openscvx-0.3.2.dev333 → openscvx-0.3.2.dev339}/tests/test_integrators.py +0 -0
- {openscvx-0.3.2.dev333 → openscvx-0.3.2.dev339}/tests/test_plotting.py +0 -0
- {openscvx-0.3.2.dev333 → openscvx-0.3.2.dev339}/tests/test_propagation.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: openscvx
|
|
3
|
-
Version: 0.3.2.
|
|
3
|
+
Version: 0.3.2.dev339
|
|
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.3.2.
|
|
32
|
-
__version_tuple__ = version_tuple = (0, 3, 2, '
|
|
31
|
+
__version__ = version = '0.3.2.dev339'
|
|
32
|
+
__version_tuple__ = version_tuple = (0, 3, 2, 'dev339')
|
|
33
33
|
|
|
34
|
-
__commit_id__ = commit_id = '
|
|
34
|
+
__commit_id__ = commit_id = 'g0ad465892'
|
|
@@ -50,7 +50,6 @@ from openscvx.lowered.jax_constraints import (
|
|
|
50
50
|
from openscvx.propagation import get_propagation_solver, propagate_trajectory_results
|
|
51
51
|
from openscvx.solvers import PTRSolver
|
|
52
52
|
from openscvx.symbolic.builder import preprocess_symbolic_problem
|
|
53
|
-
from openscvx.symbolic.constraint_set import ConstraintSet
|
|
54
53
|
from openscvx.symbolic.expr import CTCS, Constraint
|
|
55
54
|
from openscvx.symbolic.expr.control import Control
|
|
56
55
|
from openscvx.symbolic.expr.state import State
|
|
@@ -128,7 +127,7 @@ class Problem:
|
|
|
128
127
|
# Symbolic Preprocessing & Augmentation
|
|
129
128
|
self.symbolic: SymbolicProblem = preprocess_symbolic_problem(
|
|
130
129
|
dynamics=dynamics,
|
|
131
|
-
constraints=
|
|
130
|
+
constraints=constraints,
|
|
132
131
|
states=states,
|
|
133
132
|
controls=controls,
|
|
134
133
|
N=N,
|
|
@@ -55,6 +55,8 @@ from openscvx.symbolic.preprocessing import (
|
|
|
55
55
|
validate_dynamics_dict_dimensions,
|
|
56
56
|
validate_dynamics_dimension,
|
|
57
57
|
validate_guesses,
|
|
58
|
+
validate_input_types,
|
|
59
|
+
validate_propagation_input_types,
|
|
58
60
|
validate_shapes,
|
|
59
61
|
validate_variable_names,
|
|
60
62
|
)
|
|
@@ -64,7 +66,7 @@ from openscvx.symbolic.time import Time
|
|
|
64
66
|
|
|
65
67
|
def preprocess_symbolic_problem(
|
|
66
68
|
dynamics: dict,
|
|
67
|
-
constraints:
|
|
69
|
+
constraints: list,
|
|
68
70
|
states: List[State],
|
|
69
71
|
controls: List[Control],
|
|
70
72
|
N: int,
|
|
@@ -99,8 +101,8 @@ def preprocess_symbolic_problem(
|
|
|
99
101
|
Args:
|
|
100
102
|
dynamics: Dictionary mapping state names to dynamics expressions.
|
|
101
103
|
Example: {"x": v, "v": u}
|
|
102
|
-
constraints:
|
|
103
|
-
|
|
104
|
+
constraints: List of constraint objects (Constraint, NodalConstraint,
|
|
105
|
+
CrossNodeConstraint, or CTCS).
|
|
104
106
|
states: List of user-defined State objects (should NOT include time or CTCS states)
|
|
105
107
|
controls: List of user-defined Control objects (should NOT include time dilation)
|
|
106
108
|
N: Number of discretization nodes in the trajectory
|
|
@@ -140,16 +142,13 @@ def preprocess_symbolic_problem(
|
|
|
140
142
|
Basic usage with CTCS constraint::
|
|
141
143
|
|
|
142
144
|
import openscvx as ox
|
|
143
|
-
from openscvx.symbolic.constraint_set import ConstraintSet
|
|
144
145
|
|
|
145
146
|
x = ox.State("x", shape=(2,))
|
|
146
147
|
v = ox.State("v", shape=(2,))
|
|
147
148
|
u = ox.Control("u", shape=(2,))
|
|
148
149
|
|
|
149
150
|
dynamics = {"x": v, "v": u}
|
|
150
|
-
constraints =
|
|
151
|
-
(ox.Norm(x) <= 5.0).over((0, 50))
|
|
152
|
-
])
|
|
151
|
+
constraints = [(ox.Norm(x) <= 5.0).over((0, 50))]
|
|
153
152
|
|
|
154
153
|
problem = preprocess_symbolic_problem(
|
|
155
154
|
dynamics=dynamics,
|
|
@@ -187,6 +186,13 @@ def preprocess_symbolic_problem(
|
|
|
187
186
|
print([s.name for s in problem.states_prop])
|
|
188
187
|
"""
|
|
189
188
|
|
|
189
|
+
# Validate input types before anything else
|
|
190
|
+
validate_input_types(dynamics, states, controls, constraints, N, time)
|
|
191
|
+
validate_propagation_input_types(dynamics_prop_extra, states_prop_extra)
|
|
192
|
+
|
|
193
|
+
# Wrap validated constraints into a ConstraintSet
|
|
194
|
+
constraints = ConstraintSet(unsorted=list(constraints))
|
|
195
|
+
|
|
190
196
|
# Validate user-provided variables have required attributes
|
|
191
197
|
validate_boundary_conditions(states)
|
|
192
198
|
validate_bounds(states + controls)
|
|
@@ -748,6 +748,142 @@ def validate_bounds(variables: List[Variable]) -> None:
|
|
|
748
748
|
)
|
|
749
749
|
|
|
750
750
|
|
|
751
|
+
def validate_input_types(
|
|
752
|
+
dynamics: any,
|
|
753
|
+
states: any,
|
|
754
|
+
controls: any,
|
|
755
|
+
constraints: any,
|
|
756
|
+
N: any,
|
|
757
|
+
time: any,
|
|
758
|
+
) -> None:
|
|
759
|
+
"""Validate that all user-facing inputs have correct types.
|
|
760
|
+
|
|
761
|
+
This catches common user errors like passing a single State or Control
|
|
762
|
+
instead of a list, or passing wrong types for dynamics, N, or time.
|
|
763
|
+
Should be called before any other validation in the preprocessing pipeline.
|
|
764
|
+
|
|
765
|
+
Raises:
|
|
766
|
+
TypeError: If any input has the wrong type
|
|
767
|
+
ValueError: If N is not positive
|
|
768
|
+
"""
|
|
769
|
+
from openscvx.symbolic.expr import CTCS, Constraint, CrossNodeConstraint, NodalConstraint
|
|
770
|
+
from openscvx.symbolic.time import Time
|
|
771
|
+
|
|
772
|
+
if not isinstance(dynamics, dict):
|
|
773
|
+
raise TypeError(
|
|
774
|
+
f"'dynamics' must be a dict mapping state names to expressions, "
|
|
775
|
+
f"got {type(dynamics).__name__}"
|
|
776
|
+
)
|
|
777
|
+
|
|
778
|
+
if not isinstance(states, list):
|
|
779
|
+
hint = ""
|
|
780
|
+
if isinstance(states, State):
|
|
781
|
+
hint = f" Hint: use states=[{states.name}] instead of states={states.name}"
|
|
782
|
+
raise TypeError(
|
|
783
|
+
f"'states' must be a list of State objects, got {type(states).__name__}.{hint}"
|
|
784
|
+
)
|
|
785
|
+
|
|
786
|
+
for i, s in enumerate(states):
|
|
787
|
+
if not isinstance(s, State):
|
|
788
|
+
raise TypeError(f"states[{i}] must be a State, got {type(s).__name__}")
|
|
789
|
+
|
|
790
|
+
if not isinstance(controls, list):
|
|
791
|
+
hint = ""
|
|
792
|
+
if isinstance(controls, Control):
|
|
793
|
+
hint = f" Hint: use controls=[{controls.name}] instead of controls={controls.name}"
|
|
794
|
+
raise TypeError(
|
|
795
|
+
f"'controls' must be a list of Control objects, got {type(controls).__name__}.{hint}"
|
|
796
|
+
)
|
|
797
|
+
|
|
798
|
+
for i, c in enumerate(controls):
|
|
799
|
+
if not isinstance(c, Control):
|
|
800
|
+
raise TypeError(f"controls[{i}] must be a Control, got {type(c).__name__}")
|
|
801
|
+
|
|
802
|
+
if not isinstance(constraints, list):
|
|
803
|
+
raise TypeError(
|
|
804
|
+
f"'constraints' must be a list of Constraint objects, got {type(constraints).__name__}"
|
|
805
|
+
)
|
|
806
|
+
|
|
807
|
+
valid_constraint_types = (Constraint, NodalConstraint, CrossNodeConstraint, CTCS)
|
|
808
|
+
for i, c in enumerate(constraints):
|
|
809
|
+
if not isinstance(c, valid_constraint_types):
|
|
810
|
+
raise TypeError(
|
|
811
|
+
f"constraints[{i}] must be a Constraint, NodalConstraint, "
|
|
812
|
+
f"CrossNodeConstraint, or CTCS, got {type(c).__name__}"
|
|
813
|
+
)
|
|
814
|
+
|
|
815
|
+
if not isinstance(N, int):
|
|
816
|
+
raise TypeError(f"'N' must be an integer, got {type(N).__name__}")
|
|
817
|
+
|
|
818
|
+
if N < 1:
|
|
819
|
+
raise ValueError(f"'N' must be positive, got {N}")
|
|
820
|
+
|
|
821
|
+
if not isinstance(time, Time):
|
|
822
|
+
raise TypeError(f"'time' must be a Time object, got {type(time).__name__}")
|
|
823
|
+
|
|
824
|
+
|
|
825
|
+
def validate_propagation_input_types(
|
|
826
|
+
dynamics_prop_extra: any,
|
|
827
|
+
states_prop_extra: any,
|
|
828
|
+
) -> None:
|
|
829
|
+
"""Validate types for optional propagation inputs.
|
|
830
|
+
|
|
831
|
+
These parameters must either both be None or both be provided.
|
|
832
|
+
When provided, dynamics_prop_extra must be a dict and states_prop_extra
|
|
833
|
+
must be a list of State objects.
|
|
834
|
+
|
|
835
|
+
Args:
|
|
836
|
+
dynamics_prop_extra: Should be None or a dict mapping state names to expressions
|
|
837
|
+
states_prop_extra: Should be None or a list of State objects
|
|
838
|
+
|
|
839
|
+
Raises:
|
|
840
|
+
TypeError: If either input has the wrong type
|
|
841
|
+
ValueError: If only one of the two is provided
|
|
842
|
+
|
|
843
|
+
Example:
|
|
844
|
+
distance = ox.State("distance", shape=(1,))
|
|
845
|
+
|
|
846
|
+
# Wrong: passing bare State instead of list
|
|
847
|
+
validate_propagation_input_types({"distance": expr}, distance)
|
|
848
|
+
# Raises TypeError: 'states_prop_extra' must be a list ...
|
|
849
|
+
"""
|
|
850
|
+
both_none = dynamics_prop_extra is None and states_prop_extra is None
|
|
851
|
+
both_set = dynamics_prop_extra is not None and states_prop_extra is not None
|
|
852
|
+
|
|
853
|
+
if not both_none and not both_set:
|
|
854
|
+
provided = "dynamics_prop" if dynamics_prop_extra is not None else "states_prop"
|
|
855
|
+
missing = "states_prop" if dynamics_prop_extra is not None else "dynamics_prop"
|
|
856
|
+
raise ValueError(
|
|
857
|
+
f"'{provided}' was provided but '{missing}' was not. "
|
|
858
|
+
f"Both must be provided together, or both omitted."
|
|
859
|
+
)
|
|
860
|
+
|
|
861
|
+
if both_none:
|
|
862
|
+
return
|
|
863
|
+
|
|
864
|
+
if not isinstance(dynamics_prop_extra, dict):
|
|
865
|
+
raise TypeError(
|
|
866
|
+
f"'dynamics_prop' must be a dict mapping state names to expressions, "
|
|
867
|
+
f"got {type(dynamics_prop_extra).__name__}"
|
|
868
|
+
)
|
|
869
|
+
|
|
870
|
+
if not isinstance(states_prop_extra, list):
|
|
871
|
+
hint = ""
|
|
872
|
+
if isinstance(states_prop_extra, State):
|
|
873
|
+
hint = (
|
|
874
|
+
f" Hint: use states_prop=[{states_prop_extra.name}]"
|
|
875
|
+
f" instead of states_prop={states_prop_extra.name}"
|
|
876
|
+
)
|
|
877
|
+
raise TypeError(
|
|
878
|
+
f"'states_prop' must be a list of State objects, "
|
|
879
|
+
f"got {type(states_prop_extra).__name__}.{hint}"
|
|
880
|
+
)
|
|
881
|
+
|
|
882
|
+
for i, s in enumerate(states_prop_extra):
|
|
883
|
+
if not isinstance(s, State):
|
|
884
|
+
raise TypeError(f"states_prop[{i}] must be a State, got {type(s).__name__}")
|
|
885
|
+
|
|
886
|
+
|
|
751
887
|
def validate_guesses(variables: List[Variable]) -> None:
|
|
752
888
|
"""Validate that all variables have initial guesses set.
|
|
753
889
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: openscvx
|
|
3
|
-
Version: 0.3.2.
|
|
3
|
+
Version: 0.3.2.dev339
|
|
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
|
|
@@ -15,6 +15,8 @@ from openscvx.symbolic.preprocessing import (
|
|
|
15
15
|
validate_dynamics_dict_dimensions,
|
|
16
16
|
validate_dynamics_dimension,
|
|
17
17
|
validate_guesses,
|
|
18
|
+
validate_input_types,
|
|
19
|
+
validate_propagation_input_types,
|
|
18
20
|
validate_variable_names,
|
|
19
21
|
)
|
|
20
22
|
|
|
@@ -976,3 +978,176 @@ def test_validate_guesses_raises_missing():
|
|
|
976
978
|
match="Control 'thrust' is missing initial guess.*controls require explicit guesses",
|
|
977
979
|
):
|
|
978
980
|
validate_guesses([u])
|
|
981
|
+
|
|
982
|
+
|
|
983
|
+
# =============================================================================
|
|
984
|
+
# validate_input_types Tests
|
|
985
|
+
# =============================================================================
|
|
986
|
+
|
|
987
|
+
|
|
988
|
+
@pytest.fixture
|
|
989
|
+
def valid_inputs():
|
|
990
|
+
"""Provide a minimal set of valid inputs for validate_input_types."""
|
|
991
|
+
from openscvx.symbolic.time import Time
|
|
992
|
+
|
|
993
|
+
x = State("x", shape=(3,))
|
|
994
|
+
u = Control("u", shape=(2,))
|
|
995
|
+
dynamics = {"x": x}
|
|
996
|
+
constraints = [x <= 5]
|
|
997
|
+
time = Time(initial=0.0, final=10.0, min=0.0, max=20.0)
|
|
998
|
+
return dynamics, [x], [u], constraints, 50, time
|
|
999
|
+
|
|
1000
|
+
|
|
1001
|
+
def test_validate_input_types_passes(valid_inputs):
|
|
1002
|
+
"""Test that valid inputs pass validation."""
|
|
1003
|
+
dynamics, states, controls, constraints, N, time = valid_inputs
|
|
1004
|
+
validate_input_types(dynamics, states, controls, constraints, N, time)
|
|
1005
|
+
|
|
1006
|
+
|
|
1007
|
+
def test_validate_input_types_bare_control(valid_inputs):
|
|
1008
|
+
"""Test that passing a bare Control instead of a list raises TypeError with hint."""
|
|
1009
|
+
dynamics, states, _, constraints, N, time = valid_inputs
|
|
1010
|
+
u = Control("thrust", shape=(2,))
|
|
1011
|
+
|
|
1012
|
+
with pytest.raises(
|
|
1013
|
+
TypeError, match=r"'controls' must be a list.*Control.*Hint.*controls=\[thrust\]"
|
|
1014
|
+
):
|
|
1015
|
+
validate_input_types(dynamics, states, u, constraints, N, time)
|
|
1016
|
+
|
|
1017
|
+
|
|
1018
|
+
def test_validate_input_types_bare_state(valid_inputs):
|
|
1019
|
+
"""Test that passing a bare State instead of a list raises TypeError with hint."""
|
|
1020
|
+
dynamics, _, controls, constraints, N, time = valid_inputs
|
|
1021
|
+
x = State("position", shape=(3,))
|
|
1022
|
+
|
|
1023
|
+
with pytest.raises(
|
|
1024
|
+
TypeError, match=r"'states' must be a list.*State.*Hint.*states=\[position\]"
|
|
1025
|
+
):
|
|
1026
|
+
validate_input_types(dynamics, x, controls, constraints, N, time)
|
|
1027
|
+
|
|
1028
|
+
|
|
1029
|
+
def test_validate_input_types_wrong_element_in_states(valid_inputs):
|
|
1030
|
+
"""Test that a non-State element in the states list raises TypeError."""
|
|
1031
|
+
dynamics, _, controls, constraints, N, time = valid_inputs
|
|
1032
|
+
|
|
1033
|
+
with pytest.raises(TypeError, match=r"states\[0\] must be a State, got str"):
|
|
1034
|
+
validate_input_types(dynamics, ["not_a_state"], controls, constraints, N, time)
|
|
1035
|
+
|
|
1036
|
+
|
|
1037
|
+
def test_validate_input_types_wrong_element_in_controls(valid_inputs):
|
|
1038
|
+
"""Test that a non-Control element in the controls list raises TypeError."""
|
|
1039
|
+
dynamics, states, _, constraints, N, time = valid_inputs
|
|
1040
|
+
|
|
1041
|
+
with pytest.raises(TypeError, match=r"controls\[0\] must be a Control, got int"):
|
|
1042
|
+
validate_input_types(dynamics, states, [42], constraints, N, time)
|
|
1043
|
+
|
|
1044
|
+
|
|
1045
|
+
def test_validate_input_types_dynamics_not_dict(valid_inputs):
|
|
1046
|
+
"""Test that passing non-dict dynamics raises TypeError."""
|
|
1047
|
+
_, states, controls, constraints, N, time = valid_inputs
|
|
1048
|
+
|
|
1049
|
+
with pytest.raises(TypeError, match="'dynamics' must be a dict"):
|
|
1050
|
+
validate_input_types([1, 2, 3], states, controls, constraints, N, time)
|
|
1051
|
+
|
|
1052
|
+
|
|
1053
|
+
def test_validate_input_types_constraints_not_list(valid_inputs):
|
|
1054
|
+
"""Test that passing a non-list constraints raises TypeError."""
|
|
1055
|
+
dynamics, states, controls, _, N, time = valid_inputs
|
|
1056
|
+
|
|
1057
|
+
with pytest.raises(TypeError, match="'constraints' must be a list"):
|
|
1058
|
+
validate_input_types(dynamics, states, controls, "not_a_list", N, time)
|
|
1059
|
+
|
|
1060
|
+
|
|
1061
|
+
def test_validate_input_types_constraints_invalid_element(valid_inputs):
|
|
1062
|
+
"""Test that non-constraint elements raise TypeError."""
|
|
1063
|
+
dynamics, states, controls, _, N, time = valid_inputs
|
|
1064
|
+
|
|
1065
|
+
with pytest.raises(TypeError, match=r"constraints\[0\] must be a Constraint.*got int"):
|
|
1066
|
+
validate_input_types(dynamics, states, controls, [42], N, time)
|
|
1067
|
+
|
|
1068
|
+
|
|
1069
|
+
def test_validate_input_types_constraints_mixed_valid_and_invalid(valid_inputs):
|
|
1070
|
+
"""Test that invalid element is caught even after valid ones."""
|
|
1071
|
+
dynamics, states, controls, _, N, time = valid_inputs
|
|
1072
|
+
x = State("x", shape=(3,))
|
|
1073
|
+
|
|
1074
|
+
with pytest.raises(TypeError, match=r"constraints\[1\] must be a Constraint.*got str"):
|
|
1075
|
+
validate_input_types(dynamics, states, controls, [x <= 5, "bad"], N, time)
|
|
1076
|
+
|
|
1077
|
+
|
|
1078
|
+
def test_validate_input_types_N_not_int(valid_inputs):
|
|
1079
|
+
"""Test that passing non-int N raises TypeError."""
|
|
1080
|
+
dynamics, states, controls, constraints, _, time = valid_inputs
|
|
1081
|
+
|
|
1082
|
+
with pytest.raises(TypeError, match="'N' must be an integer, got float"):
|
|
1083
|
+
validate_input_types(dynamics, states, controls, constraints, 50.0, time)
|
|
1084
|
+
|
|
1085
|
+
|
|
1086
|
+
def test_validate_input_types_N_not_positive(valid_inputs):
|
|
1087
|
+
"""Test that passing non-positive N raises ValueError."""
|
|
1088
|
+
dynamics, states, controls, constraints, _, time = valid_inputs
|
|
1089
|
+
|
|
1090
|
+
with pytest.raises(ValueError, match="'N' must be positive, got 0"):
|
|
1091
|
+
validate_input_types(dynamics, states, controls, constraints, 0, time)
|
|
1092
|
+
|
|
1093
|
+
with pytest.raises(ValueError, match="'N' must be positive, got -5"):
|
|
1094
|
+
validate_input_types(dynamics, states, controls, constraints, -5, time)
|
|
1095
|
+
|
|
1096
|
+
|
|
1097
|
+
def test_validate_input_types_time_not_time(valid_inputs):
|
|
1098
|
+
"""Test that passing non-Time object raises TypeError."""
|
|
1099
|
+
dynamics, states, controls, constraints, N, _ = valid_inputs
|
|
1100
|
+
|
|
1101
|
+
with pytest.raises(TypeError, match="'time' must be a Time object, got float"):
|
|
1102
|
+
validate_input_types(dynamics, states, controls, constraints, N, 10.0)
|
|
1103
|
+
|
|
1104
|
+
|
|
1105
|
+
# =============================================================================
|
|
1106
|
+
# validate_propagation_input_types Tests
|
|
1107
|
+
# =============================================================================
|
|
1108
|
+
|
|
1109
|
+
|
|
1110
|
+
def test_validate_propagation_input_types_both_none():
|
|
1111
|
+
"""Test that both None passes validation."""
|
|
1112
|
+
validate_propagation_input_types(None, None)
|
|
1113
|
+
|
|
1114
|
+
|
|
1115
|
+
def test_validate_propagation_input_types_both_valid():
|
|
1116
|
+
"""Test that valid dict + list passes validation."""
|
|
1117
|
+
distance = State("distance", shape=(1,))
|
|
1118
|
+
validate_propagation_input_types({"distance": distance}, [distance])
|
|
1119
|
+
|
|
1120
|
+
|
|
1121
|
+
def test_validate_propagation_input_types_only_dynamics():
|
|
1122
|
+
"""Test that providing dynamics_prop without states_prop raises ValueError."""
|
|
1123
|
+
with pytest.raises(ValueError, match="'dynamics_prop' was provided but 'states_prop' was not"):
|
|
1124
|
+
validate_propagation_input_types({"distance": 1.0}, None)
|
|
1125
|
+
|
|
1126
|
+
|
|
1127
|
+
def test_validate_propagation_input_types_only_states():
|
|
1128
|
+
"""Test that providing states_prop without dynamics_prop raises ValueError."""
|
|
1129
|
+
distance = State("distance", shape=(1,))
|
|
1130
|
+
with pytest.raises(ValueError, match="'states_prop' was provided but 'dynamics_prop' was not"):
|
|
1131
|
+
validate_propagation_input_types(None, [distance])
|
|
1132
|
+
|
|
1133
|
+
|
|
1134
|
+
def test_validate_propagation_input_types_bare_state():
|
|
1135
|
+
"""Test that passing a bare State instead of a list raises TypeError with hint."""
|
|
1136
|
+
distance = State("distance", shape=(1,))
|
|
1137
|
+
with pytest.raises(
|
|
1138
|
+
TypeError, match=r"'states_prop' must be a list.*Hint.*states_prop=\[distance\]"
|
|
1139
|
+
):
|
|
1140
|
+
validate_propagation_input_types({"distance": distance}, distance)
|
|
1141
|
+
|
|
1142
|
+
|
|
1143
|
+
def test_validate_propagation_input_types_dynamics_not_dict():
|
|
1144
|
+
"""Test that passing non-dict dynamics_prop raises TypeError."""
|
|
1145
|
+
distance = State("distance", shape=(1,))
|
|
1146
|
+
with pytest.raises(TypeError, match="'dynamics_prop' must be a dict"):
|
|
1147
|
+
validate_propagation_input_types([distance], [distance])
|
|
1148
|
+
|
|
1149
|
+
|
|
1150
|
+
def test_validate_propagation_input_types_wrong_element_in_states():
|
|
1151
|
+
"""Test that a non-State element in states_prop raises TypeError."""
|
|
1152
|
+
with pytest.raises(TypeError, match=r"states_prop\[0\] must be a State, got str"):
|
|
1153
|
+
validate_propagation_input_types({"x": 1.0}, ["not_a_state"])
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{openscvx-0.3.2.dev333 → openscvx-0.3.2.dev339}/docs/Foundations/constraint_reformulation.md
RENAMED
|
File without changes
|
{openscvx-0.3.2.dev333 → openscvx-0.3.2.dev339}/docs/Foundations/control_parameterization.md
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{openscvx-0.3.2.dev333 → openscvx-0.3.2.dev339}/docs/UnderTheHood/vectorization_and_vmapping.md
RENAMED
|
File without changes
|
|
File without changes
|
{openscvx-0.3.2.dev333 → openscvx-0.3.2.dev339}/docs/UsersGuide/01_hello_world_brachistochrone.md
RENAMED
|
File without changes
|
{openscvx-0.3.2.dev333 → openscvx-0.3.2.dev339}/docs/UsersGuide/02_drone_racing_constraints.md
RENAMED
|
File without changes
|
{openscvx-0.3.2.dev333 → openscvx-0.3.2.dev339}/docs/UsersGuide/03_obstacle_avoidance_vmap.md
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{openscvx-0.3.2.dev333 → openscvx-0.3.2.dev339}/examples/drone/obstacle_avoidance_realtime_base.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{openscvx-0.3.2.dev333 → openscvx-0.3.2.dev339}/examples/realtime/obstacle_avoidance_realtime.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|