openscvx 0.5.3.dev45__tar.gz → 0.5.3.dev46__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.5.3.dev45/openscvx.egg-info → openscvx-0.5.3.dev46}/PKG-INFO +1 -1
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/docs/Foundations/control_parameterization.md +3 -2
- openscvx-0.5.3.dev46/docs/Foundations/discretization.md +94 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/docs/Foundations/ocp.md +124 -68
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/docs/UnderTheHood/batching_jit_grad.md +6 -8
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/docs/UnderTheHood/custom_algorithms_autotuners.md +1 -1
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/docs/UnderTheHood/lowering_architecture.md +13 -13
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/docs/UnderTheHood/vectorization_and_vmapping.md +22 -31
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/docs/UsersGuide/01_hello_world_brachistochrone.md +1 -6
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/docs/UsersGuide/02_drone_racing_constraints.md +7 -20
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/docs/UsersGuide/03_obstacle_avoidance_vmap.md +12 -17
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/docs/UsersGuide/04_viewpoint_constraints.md +29 -29
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/docs/UsersGuide/05_visualization.md +19 -21
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/docs/UsersGuide/07_lie.md +53 -54
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/docs/UsersGuide/08_mpcc.md +75 -73
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/docs/UsersGuide/09_mjx_dynamics.md +2 -2
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/openscvx/_version.py +3 -3
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46/openscvx.egg-info}/PKG-INFO +1 -1
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/openscvx.egg-info/scm_file_list.json +379 -379
- openscvx-0.5.3.dev46/openscvx.egg-info/scm_version.json +8 -0
- openscvx-0.5.3.dev45/docs/Foundations/discretization.md +0 -85
- openscvx-0.5.3.dev45/openscvx.egg-info/scm_version.json +0 -8
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/.github/assets/logo.svg +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/.github/release-drafter.yml +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/.github/workflows/_docs.yml +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/.github/workflows/_extra.yml +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/.github/workflows/branch-name.yml +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/.github/workflows/docs.yml +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/.github/workflows/lint.yml +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/.github/workflows/nightly.yml +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/.github/workflows/release-drafter.yml +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/.github/workflows/release.yml +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/.github/workflows/tests-cvxpygen.yml +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/.github/workflows/tests-examples.yml +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/.github/workflows/tests-lie.yml +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/.github/workflows/tests-mjx.yml +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/.github/workflows/tests-qpax.yml +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/.github/workflows/tests.yml +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/.gitignore +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/.gitmodules +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/CITATION.cff +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/CONTRIBUTING.md +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/LICENSE +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/README.md +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/docs/Foundations/constraint_reformulation.md +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/docs/Foundations/scvx.md +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/docs/Foundations/time_dilation.md +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/docs/UsersGuide/00_introduction.md +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/docs/UsersGuide/06_logic.md +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/docs/assets/favicon.png +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/docs/assets/images/ct-scvx_dark.png +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/docs/assets/images/ct-scvx_light.png +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/docs/assets/images/ctcs_dark.png +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/docs/assets/images/ctcs_light.png +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/docs/assets/images/problem_class_dark.png +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/docs/assets/images/problem_class_light.png +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/docs/assets/logo.svg +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/docs/assets/openscvx_logo_square.png +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/docs/assets/viser-client/index.html +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/docs/assets/viser-recordings/drone_racing.viser +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/docs/assets/viser-recordings/franka_fr3v2_pick_place.viser +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/docs/changelog.md +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/docs/citation.md +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/docs/examples.md +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/docs/index.md +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/docs/installation.md +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/docs/javascripts/mathjax.js +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/docs/llms.txt +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/docs/versions.json +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/examples/_viser_embed_export.py +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/examples/abstract/brachistochrone.py +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/examples/abstract/brachistochrone_batched.py +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/examples/abstract/flappy_bird.py +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/examples/abstract/hypersensitive.py +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/examples/abstract/impulsive.py +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/examples/abstract/stl_integer_variable.py +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/examples/abstract/stl_or.py +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/examples/aircraft/dynamic_soaring.py +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/examples/aircraft/supersonic_time_to_climb.py +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/examples/animations/7_dof_arm.py +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/examples/animations/_camera.py +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/examples/animations/_render.py +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/examples/animations/_sensor_view.py +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/examples/animations/dr_vp_polytope.py +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/examples/animations/franka_fr3v2_pick_place.py +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/examples/animations/logo.py +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/examples/animations/obstacle_avoidance_vmap.py +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/examples/arm/3_dof_arm.py +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/examples/arm/7_dof_arm.py +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/examples/arm/7_dof_arm_collision.py +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/examples/arm/7_dof_arm_vp.py +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/examples/arm/franka_fr3v2_pick_place.py +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/examples/arm/franka_fr3v2_viewplanning.py +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/examples/arm/franka_fr3v2_viewplanning_nodal.py +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/examples/car/dubins_car.py +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/examples/car/dubins_car_disjoint.py +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/examples/car/dubins_car_obstacle_conditional.py +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/examples/car/dubins_car_obstacle_stl.py +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/examples/car/dubins_car_stl_or.py +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/examples/car/dubins_car_waypoint_stl.py +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/examples/double_integrator/_plotting.py +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/examples/double_integrator/moving_safe_zones.py +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/examples/drone/2d_obstacle_avoidance_batched_ic.py +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/examples/drone/boresight_trace_mpcc.py +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/examples/drone/cinema_vp.py +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/examples/drone/cinema_vp_nodal.py +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/examples/drone/dr_double_integrator.py +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/examples/drone/dr_vp.py +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/examples/drone/dr_vp_nodal.py +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/examples/drone/dr_vp_polytope.py +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/examples/drone/drone_racing.py +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/examples/drone/drone_racing_batched_gates.py +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/examples/drone/logo.py +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/examples/drone/logo_utils/acl_logo.svg +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/examples/drone/logo_utils/circle.svg +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/examples/drone/logo_utils/openscvx_logo_single.svg +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/examples/drone/logo_utils/quadrotor_mesh.py +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/examples/drone/logo_utils/svg_path_utils.py +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/examples/drone/multi_agent_circle_swap.py +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/examples/drone/obstacle_avoidance.py +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/examples/drone/obstacle_avoidance_nodal.py +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/examples/drone/obstacle_avoidance_vmap.py +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/examples/drone/obstacle_avoidance_vmap_2d.py +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/examples/drone/openscvx_logo.py +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/examples/frax/panda_frax.py +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/examples/frax/panda_frax_pick_place.py +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/examples/frax/panda_frax_viewplanning.py +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/examples/frax/panda_frax_waypoint.py +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/examples/frax/ur5e_assets/ur5e.urdf +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/examples/frax/ur5e_pen_trace.py +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/examples/mjx/cartpole_mjx.py +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/examples/mjx/double_cartpole_mjx.py +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/examples/mjx/skydio_x2_mjx.py +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/examples/mjx/triple_cartpole_3d_mjx.py +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/examples/mjx/triple_cartpole_game.py +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/examples/mjx/triple_cartpole_mjx.py +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/examples/mpc/double_integrator_discrete.py +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/examples/mpc/double_integrator_drone_racing.py +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/examples/mpc/dubins_car_circle_analytical.py +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/examples/mpc/dubins_car_circle_discrete.py +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/examples/mpc/realtime_double_integrator_drone_racing.py +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/examples/plotting.py +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/examples/plotting_viser.py +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/examples/realtime/3DoF_pdg_realtime.py +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/examples/realtime/6DoF_pdg_realtime.py +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/examples/realtime/base_problems/3DoF_pdg_realtime_base.py +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/examples/realtime/base_problems/6DoF_pdg_realtime_base.py +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/examples/realtime/base_problems/cinema_vp_realtime_base.py +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/examples/realtime/base_problems/drone_racing_realtime_base.py +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/examples/realtime/base_problems/dubins_car_realtime_base.py +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/examples/realtime/base_problems/obstacle_avoidance_realtime_base.py +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/examples/realtime/cinema_vp_realtime.py +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/examples/realtime/drone_racing_realtime.py +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/examples/realtime/dubins_car_realtime.py +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/examples/realtime/obstacle_avoidance_realtime.py +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/examples/rocket/3DoF_pdg.py +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/examples/rocket/6DoF_pdg.py +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/examples/rocket/6DoF_pdg_batched_ic.py +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/examples/rocket/ascent_launch_vehicle.py +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/examples/spacecraft/halo_orbit.py +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/examples/spacecraft/hohmann_transfer.py +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/examples/spacecraft/let_transfer.py +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/examples/spacecraft/proxops_cw.py +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/examples/spacecraft/relative_loitering.py +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/figures/ctlos_cine.gif +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/figures/ctlos_dr.gif +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/figures/dtlos_cine.gif +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/figures/dtlos_dr.gif +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/figures/openscvx_logo.svg +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/figures/openscvx_logo_square.png +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/figures/oscvx_structure_full_dark.svg +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/figures/video_preview.png +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/material/__init__.py +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/material/overrides/assets/stylesheets/custom.css +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/material/overrides/assets/stylesheets/home-dropin.css +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/material/overrides/assets/stylesheets/home-hero.css +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/material/overrides/assets/stylesheets/home-viser.css +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/material/overrides/home.html +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/material/overrides/main.html +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/material/overrides/partials/home-diagram.html +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/material/overrides/partials/home-dropin-banner.html +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/material/overrides/partials/home-hero.html +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/material/overrides/partials/home-pipeline.html +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/material/overrides/partials/home-viser-strip.html +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/material/overrides/sitemap.xml +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/mkdocs.yml +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/openscvx/__init__.py +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/openscvx/__main__.py +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/openscvx/algorithms/__init__.py +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/openscvx/algorithms/autotuner/__init__.py +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/openscvx/algorithms/autotuner/acceptance_ratio.py +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/openscvx/algorithms/autotuner/adaptive_proximal_weight.py +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/openscvx/algorithms/autotuner/augmented_lagrangian.py +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/openscvx/algorithms/autotuner/base.py +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/openscvx/algorithms/autotuner/constant_proximal_weight.py +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/openscvx/algorithms/autotuner/ramp_proximal_weight.py +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/openscvx/algorithms/base.py +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/openscvx/algorithms/history.py +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/openscvx/algorithms/hyperparams.py +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/openscvx/algorithms/loop.py +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/openscvx/algorithms/optimization_results.py +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/openscvx/algorithms/penalty.py +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/openscvx/algorithms/scvx/__init__.py +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/openscvx/algorithms/scvx/iteration.py +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/openscvx/algorithms/scvx/penalized_trust_region.py +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/openscvx/algorithms/state.py +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/openscvx/algorithms/weights.py +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/openscvx/config.py +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/openscvx/discretization/__init__.py +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/openscvx/discretization/base.py +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/openscvx/discretization/discretize_linearize.py +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/openscvx/discretization/linearize_discretize.py +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/openscvx/discretization/linearize_discretize_sparse.py +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/openscvx/discretization/sparse_utils/__init__.py +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/openscvx/discretization/sparse_utils/bcoo_helpers.py +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/openscvx/discretization/sparse_utils/sparse_jacobian.py +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/openscvx/expert/__init__.py +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/openscvx/expert/byof.py +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/openscvx/expert/lowering.py +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/openscvx/expert/validation.py +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/openscvx/init/__init__.py +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/openscvx/init/interpolation.py +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/openscvx/init/inverse_kinematics.py +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/openscvx/integrations/__init__.py +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/openscvx/integrations/_utils.py +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/openscvx/integrations/base.py +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/openscvx/integrations/frax.py +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/openscvx/integrations/menagerie.py +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/openscvx/integrations/mjx.py +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/openscvx/integrators/__init__.py +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/openscvx/integrators/diffrax.py +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/openscvx/integrators/runge_kutta.py +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/openscvx/loader.py +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/openscvx/lowered/__init__.py +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/openscvx/lowered/cvxpy_constraints.py +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/openscvx/lowered/cvxpy_variables.py +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/openscvx/lowered/dynamics.py +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/openscvx/lowered/jax_constraints.py +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/openscvx/lowered/parameters.py +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/openscvx/lowered/problem.py +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/openscvx/lowered/unified.py +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/openscvx/plotting/__init__.py +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/openscvx/plotting/plotting.py +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/openscvx/plotting/publication.py +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/openscvx/plotting/scp_iteration.py +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/openscvx/plotting/viser/__init__.py +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/openscvx/plotting/viser/animated.py +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/openscvx/plotting/viser/coordinates.py +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/openscvx/plotting/viser/orbits.py +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/openscvx/plotting/viser/plotly_integration.py +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/openscvx/plotting/viser/primitives.py +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/openscvx/plotting/viser/scp.py +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/openscvx/plotting/viser/server.py +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/openscvx/problem.py +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/openscvx/propagation/__init__.py +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/openscvx/propagation/post_processing.py +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/openscvx/propagation/propagation.py +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/openscvx/solvers/__init__.py +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/openscvx/solvers/base.py +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/openscvx/solvers/cones.py +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/openscvx/solvers/cvxpy_ptr_solver.py +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/openscvx/solvers/moreau_ptr_solver.py +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/openscvx/solvers/ptr_solver.py +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/openscvx/solvers/qpax_ptr_solver.py +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/openscvx/symbolic/__init__.py +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/openscvx/symbolic/affine.py +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/openscvx/symbolic/augmentation.py +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/openscvx/symbolic/builder.py +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/openscvx/symbolic/canonicalize.py +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/openscvx/symbolic/constraint_set.py +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/openscvx/symbolic/expr/__init__.py +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/openscvx/symbolic/expr/arithmetic.py +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/openscvx/symbolic/expr/array.py +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/openscvx/symbolic/expr/constraint.py +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/openscvx/symbolic/expr/control.py +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/openscvx/symbolic/expr/expr.py +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/openscvx/symbolic/expr/lie/__init__.py +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/openscvx/symbolic/expr/lie/adjoint.py +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/openscvx/symbolic/expr/lie/se3.py +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/openscvx/symbolic/expr/lie/so3.py +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/openscvx/symbolic/expr/linalg.py +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/openscvx/symbolic/expr/logic.py +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/openscvx/symbolic/expr/math.py +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/openscvx/symbolic/expr/parameter.py +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/openscvx/symbolic/expr/spatial.py +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/openscvx/symbolic/expr/state.py +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/openscvx/symbolic/expr/stl.py +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/openscvx/symbolic/expr/stljax.py +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/openscvx/symbolic/expr/time.py +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/openscvx/symbolic/expr/variable.py +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/openscvx/symbolic/expr/vmap.py +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/openscvx/symbolic/hashing.py +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/openscvx/symbolic/lower.py +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/openscvx/symbolic/lowerers/__init__.py +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/openscvx/symbolic/lowerers/cvxpy/__init__.py +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/openscvx/symbolic/lowerers/cvxpy/_lowerer.py +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/openscvx/symbolic/lowerers/cvxpy/_registry.py +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/openscvx/symbolic/lowerers/cvxpy/arithmetic.py +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/openscvx/symbolic/lowerers/cvxpy/array.py +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/openscvx/symbolic/lowerers/cvxpy/constraint.py +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/openscvx/symbolic/lowerers/cvxpy/control.py +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/openscvx/symbolic/lowerers/cvxpy/expr.py +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/openscvx/symbolic/lowerers/cvxpy/linalg.py +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/openscvx/symbolic/lowerers/cvxpy/logic.py +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/openscvx/symbolic/lowerers/cvxpy/math.py +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/openscvx/symbolic/lowerers/cvxpy/state.py +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/openscvx/symbolic/lowerers/jax/__init__.py +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/openscvx/symbolic/lowerers/jax/_lowerer.py +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/openscvx/symbolic/lowerers/jax/_registry.py +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/openscvx/symbolic/lowerers/jax/arithmetic.py +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/openscvx/symbolic/lowerers/jax/array.py +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/openscvx/symbolic/lowerers/jax/constraint.py +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/openscvx/symbolic/lowerers/jax/control.py +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/openscvx/symbolic/lowerers/jax/expr.py +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/openscvx/symbolic/lowerers/jax/lie.py +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/openscvx/symbolic/lowerers/jax/linalg.py +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/openscvx/symbolic/lowerers/jax/logic.py +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/openscvx/symbolic/lowerers/jax/math.py +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/openscvx/symbolic/lowerers/jax/spatial.py +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/openscvx/symbolic/lowerers/jax/state.py +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/openscvx/symbolic/lowerers/jax/stl.py +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/openscvx/symbolic/lowerers/jax/stljax.py +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/openscvx/symbolic/lowerers/jax/vmap.py +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/openscvx/symbolic/lowerers/latex/__init__.py +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/openscvx/symbolic/lowerers/latex/_lowerer.py +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/openscvx/symbolic/lowerers/latex/_registry.py +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/openscvx/symbolic/lowerers/latex/arithmetic.py +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/openscvx/symbolic/lowerers/latex/array.py +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/openscvx/symbolic/lowerers/latex/constraint.py +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/openscvx/symbolic/lowerers/latex/control.py +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/openscvx/symbolic/lowerers/latex/expr.py +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/openscvx/symbolic/lowerers/latex/formulation.py +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/openscvx/symbolic/lowerers/latex/lie.py +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/openscvx/symbolic/lowerers/latex/linalg.py +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/openscvx/symbolic/lowerers/latex/logic.py +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/openscvx/symbolic/lowerers/latex/math.py +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/openscvx/symbolic/lowerers/latex/spatial.py +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/openscvx/symbolic/lowerers/latex/state.py +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/openscvx/symbolic/lowerers/latex/stl.py +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/openscvx/symbolic/lowerers/latex/vmap.py +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/openscvx/symbolic/parser/__init__.py +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/openscvx/symbolic/parser/_registry.py +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/openscvx/symbolic/parser/array.py +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/openscvx/symbolic/parser/constraint.py +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/openscvx/symbolic/parser/lie.py +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/openscvx/symbolic/parser/linalg.py +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/openscvx/symbolic/parser/logic.py +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/openscvx/symbolic/parser/math.py +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/openscvx/symbolic/parser/parser.py +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/openscvx/symbolic/parser/spatial.py +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/openscvx/symbolic/parser/stl.py +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/openscvx/symbolic/parser/stljax.py +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/openscvx/symbolic/parser/tokenizer.py +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/openscvx/symbolic/preprocessing.py +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/openscvx/symbolic/problem.py +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/openscvx/symbolic/sparsity.py +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/openscvx/symbolic/unified.py +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/openscvx/utils/__init__.py +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/openscvx/utils/cache.py +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/openscvx/utils/caching.py +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/openscvx/utils/printing.py +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/openscvx/utils/profiling.py +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/openscvx/utils/utils.py +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/openscvx.egg-info/SOURCES.txt +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/openscvx.egg-info/dependency_links.txt +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/openscvx.egg-info/entry_points.txt +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/openscvx.egg-info/requires.txt +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/openscvx.egg-info/top_level.txt +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/pyproject.toml +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/scripts/gen_example_pages.py +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/scripts/gen_ref_pages.py +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/scripts/mkdocs_copy_viser_client_hook.py +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/scripts/mkdocs_seo_hook.py +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/setup.cfg +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/tests/__init__.py +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/tests/algorithms/__init__.py +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/tests/algorithms/_iteration_helpers.py +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/tests/algorithms/autotuner/__init__.py +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/tests/algorithms/autotuner/test_defaults_agreement.py +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/tests/algorithms/autotuner/test_hyper_overrides.py +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/tests/algorithms/autotuner/test_update_weights_jit.py +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/tests/algorithms/test_algorithm_state_pytree.py +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/tests/algorithms/test_iteration_fn_jit.py +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/tests/algorithms/test_iteration_fn_parity.py +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/tests/algorithms/test_make_solve_loop.py +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/tests/brachistochrone_analytical.py +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/tests/conftest.py +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/tests/e2e/__init__.py +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/tests/e2e/test_brachistochrone.py +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/tests/e2e/test_impulsive.py +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/tests/e2e/test_multishot_propagation.py +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/tests/e2e/test_solve_batched_brachistochrone.py +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/tests/e2e/test_solve_batched_cvxpy_export_errors.py +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/tests/e2e/test_solve_batched_export_roundtrip.py +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/tests/e2e/test_solve_jax_bare_brachistochrone.py +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/tests/e2e/test_solve_jax_jit_brachistochrone.py +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/tests/e2e/test_solve_jax_vmap_brachistochrone.py +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/tests/e2e/test_solve_jax_vmap_converged_no_drift.py +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/tests/fixtures/brachistochrone.json +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/tests/fixtures/brachistochrone.yaml +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/tests/hohmann_analytical.py +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/tests/integrations/__init__.py +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/tests/integrations/test_mjx.py +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/tests/integrations/test_mjx_dynamics.py +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/tests/solvers/__init__.py +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/tests/solvers/_iteration_callback_helpers.py +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/tests/solvers/test_cvxpy_callback_jit_spike.py +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/tests/solvers/test_iteration_callback_cvxpy.py +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/tests/solvers/test_iteration_callback_moreau.py +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/tests/solvers/test_iteration_callback_qpax.py +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/tests/solvers/test_iteration_callback_vmap.py +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/tests/solvers/test_moreau_ptr_solver.py +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/tests/solvers/test_qpax_ptr_solver.py +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/tests/solvers/test_subproblem_pytree.py +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/tests/symbolic/__init__.py +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/tests/symbolic/expr/__init__.py +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/tests/symbolic/expr/test_arithmetic.py +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/tests/symbolic/expr/test_array.py +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/tests/symbolic/expr/test_constraint.py +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/tests/symbolic/expr/test_expr.py +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/tests/symbolic/expr/test_lie.py +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/tests/symbolic/expr/test_linalg.py +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/tests/symbolic/expr/test_logic.py +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/tests/symbolic/expr/test_math.py +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/tests/symbolic/expr/test_node_reference.py +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/tests/symbolic/expr/test_parameters.py +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/tests/symbolic/expr/test_scaling.py +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/tests/symbolic/expr/test_spatial.py +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/tests/symbolic/expr/test_stl.py +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/tests/symbolic/expr/test_variable.py +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/tests/symbolic/expr/test_vmap.py +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/tests/symbolic/parser/__init__.py +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/tests/symbolic/parser/test_array.py +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/tests/symbolic/parser/test_constraint.py +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/tests/symbolic/parser/test_lie.py +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/tests/symbolic/parser/test_linalg.py +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/tests/symbolic/parser/test_load.py +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/tests/symbolic/parser/test_logic.py +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/tests/symbolic/parser/test_math.py +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/tests/symbolic/parser/test_parser.py +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/tests/symbolic/parser/test_spatial.py +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/tests/symbolic/parser/test_stl.py +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/tests/symbolic/parser/test_tokenizer.py +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/tests/symbolic/parser/test_vmap.py +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/tests/symbolic/test_augmentation.py +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/tests/symbolic/test_gmsr.py +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/tests/symbolic/test_hashing.py +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/tests/symbolic/test_latex_formulation.py +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/tests/symbolic/test_lower_cvxpy.py +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/tests/symbolic/test_lower_jax.py +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/tests/symbolic/test_lower_latex.py +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/tests/symbolic/test_preprocessing.py +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/tests/symbolic/test_sparsity.py +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/tests/symbolic/test_unified.py +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/tests/test_autotuning.py +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/tests/test_cvxpygen_optional.py +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/tests/test_discretization.py +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/tests/test_examples.py +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/tests/test_expert.py +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/tests/test_init.py +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/tests/test_initialize_syncs_guesses.py +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/tests/test_integrators.py +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/tests/test_loader.py +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/tests/test_optimization_results.py +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/tests/test_plotting.py +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/tests/test_post_process_batched_tau_clamp.py +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/tests/test_propagation.py +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/tests/test_results_parameters.py +0 -0
- {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/tests/test_solve_batched_inference.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: openscvx
|
|
3
|
-
Version: 0.5.3.
|
|
3
|
+
Version: 0.5.3.dev46
|
|
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
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Exact Discretization
|
|
3
|
+
description: >-
|
|
4
|
+
How OpenSCvx discretizes and linearizes continuous-time dynamics by
|
|
5
|
+
integrating an augmented state vector to build the ZOH/FOH transition matrices.
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# Exact Discretization
|
|
9
|
+
|
|
10
|
+
``` py title="dVdt.py"
|
|
11
|
+
def dVdt(self, tau: float, V: jnp.ndarray, u_cur: np.ndarray, u_next: np.ndarray) -> jnp.ndarray:
|
|
12
|
+
"""
|
|
13
|
+
Computes the time derivative of the augmented state vector for the system for a sequence of states.
|
|
14
|
+
|
|
15
|
+
Parameters:
|
|
16
|
+
tau (float): Current time.
|
|
17
|
+
V (np.ndarray): Sequence of augmented state vectors.
|
|
18
|
+
u_cur (np.ndarray): Sequence of current control inputs.
|
|
19
|
+
u_next (np.ndarray): Sequence of next control inputs.
|
|
20
|
+
A: Function that computes the Jacobian of the system dynamics with respect to the state.
|
|
21
|
+
B: Function that computes the Jacobian of the system dynamics with respect to the control input.
|
|
22
|
+
obstacles: List of obstacles in the environment.
|
|
23
|
+
params (dict): Parameters of the system.
|
|
24
|
+
|
|
25
|
+
Returns:
|
|
26
|
+
np.ndarray: Time derivatives of the augmented state vectors.
|
|
27
|
+
"""
|
|
28
|
+
|
|
29
|
+
# Extract the number of states and controls from the parameters
|
|
30
|
+
n_x = self.params.sim.n_states
|
|
31
|
+
n_u = self.params.sim.n_controls
|
|
32
|
+
|
|
33
|
+
# Unflatten V
|
|
34
|
+
V = V.reshape(-1, self.i5)
|
|
35
|
+
|
|
36
|
+
# Compute the interpolation factor based on the discretization type
|
|
37
|
+
if self.dis_type == "ZOH":
|
|
38
|
+
beta = 0.0
|
|
39
|
+
elif self.dis_type == "FOH":
|
|
40
|
+
beta = (tau) * self.params.sim.n
|
|
41
|
+
alpha = 1 - beta
|
|
42
|
+
|
|
43
|
+
# Interpolate the control input
|
|
44
|
+
u = u_cur + beta * (u_next - u_cur)
|
|
45
|
+
s = u[:, -1]
|
|
46
|
+
|
|
47
|
+
# Initialize the augmented Jacobians
|
|
48
|
+
dfdx = jnp.zeros((V.shape[0], n_x, n_x))
|
|
49
|
+
dfdu = jnp.zeros((V.shape[0], n_x, n_u))
|
|
50
|
+
|
|
51
|
+
# Ensure x_seq and u have the same batch size
|
|
52
|
+
x = V[:, : self.params.sim.n_states]
|
|
53
|
+
u = u[: x.shape[0]]
|
|
54
|
+
|
|
55
|
+
# Compute the nonlinear propagation term
|
|
56
|
+
f = self.params.dyn.state_dot(x, u[:, :-1])
|
|
57
|
+
F = s[:, None] * f
|
|
58
|
+
|
|
59
|
+
# Evaluate the State Jacobian
|
|
60
|
+
dfdx = self.params.dyn.A(x, u[:, :-1])
|
|
61
|
+
sdfdx = s[:, None, None] * dfdx
|
|
62
|
+
|
|
63
|
+
# Evaluate the Control Jacobian
|
|
64
|
+
dfdu_veh = self.params.dyn.B(x, u[:, :-1])
|
|
65
|
+
dfdu = dfdu.at[:, :, :-1].set(s[:, None, None] * dfdu_veh)
|
|
66
|
+
dfdu = dfdu.at[:, :, -1].set(f)
|
|
67
|
+
|
|
68
|
+
# Compute the defect
|
|
69
|
+
z = F - jnp.einsum("ijk,ik->ij", sdfdx, x) - jnp.einsum("ijk,ik->ij", dfdu, u)
|
|
70
|
+
|
|
71
|
+
# Stack up the results into the augmented state vector
|
|
72
|
+
dVdt = jnp.zeros_like(V)
|
|
73
|
+
dVdt = dVdt.at[:, self.i0 : self.i1].set(F)
|
|
74
|
+
dVdt = dVdt.at[:, self.i1 : self.i2].set(
|
|
75
|
+
jnp.matmul(sdfdx, V[:, self.i1 : self.i2].reshape(-1, n_x, n_x)).reshape(-1, n_x * n_x)
|
|
76
|
+
)
|
|
77
|
+
dVdt = dVdt.at[:, self.i2 : self.i3].set(
|
|
78
|
+
(jnp.matmul(sdfdx, V[:, self.i2 : self.i3].reshape(-1, n_x, n_u)) + dfdu * alpha).reshape(
|
|
79
|
+
-1, n_x * n_u
|
|
80
|
+
)
|
|
81
|
+
)
|
|
82
|
+
dVdt = dVdt.at[:, self.i3 : self.i4].set(
|
|
83
|
+
(jnp.matmul(sdfdx, V[:, self.i3 : self.i4].reshape(-1, n_x, n_u)) + dfdu * beta).reshape(
|
|
84
|
+
-1, n_x * n_u
|
|
85
|
+
)
|
|
86
|
+
)
|
|
87
|
+
dVdt = dVdt.at[:, self.i4 : self.i5].set(
|
|
88
|
+
(
|
|
89
|
+
jnp.matmul(sdfdx, V[:, self.i4 : self.i5].reshape(-1, n_x)[..., None]).squeeze(-1) + z
|
|
90
|
+
).reshape(-1, n_x)
|
|
91
|
+
)
|
|
92
|
+
return dVdt.flatten()
|
|
93
|
+
```
|
|
94
|
+
|
|
@@ -18,21 +18,21 @@ The problem is defined as a function that takes in a `Config` object, which cont
|
|
|
18
18
|
The state, constrol and additional parameters are defined as follows:
|
|
19
19
|
|
|
20
20
|
```python
|
|
21
|
+
lam_prox = cp.Parameter(nonneg=True, name="lam_prox") # Weight on the Trust Region
|
|
22
|
+
lam_cost = cp.Parameter(nonneg=True, name="lam_cost") # Weight on the Nonlinear Cost
|
|
23
|
+
lam_vc = cp.Parameter(
|
|
24
|
+
(params.sim.n - 1, params.sim.n_states), nonneg=True, name="lam_vc"
|
|
25
|
+
) # Weight on Virtual Control
|
|
26
|
+
lam_vb = cp.Parameter(nonneg=True, name="lam_vb") # Weight on Virtual Buffer
|
|
21
27
|
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
lam_vb = cp.Parameter(nonneg=True, name='lam_vb') # Weight on Virtual Buffer
|
|
28
|
+
x = cp.Variable((params.sim.n, params.sim.n_states), name="x") # State
|
|
29
|
+
dx = cp.Variable((params.sim.n, params.sim.n_states), name="dx") # State Trust Region
|
|
30
|
+
x_bar = cp.Parameter((params.sim.n, params.sim.n_states), name="x_bar") # Previous SCP State
|
|
26
31
|
|
|
27
|
-
x = cp.Variable((params.sim.n, params.sim.n_states), name='x') # State
|
|
28
|
-
dx = cp.Variable((params.sim.n, params.sim.n_states), name='dx') # State Trust Region
|
|
29
|
-
x_bar = cp.Parameter((params.sim.n, params.sim.n_states), name='x_bar') # Previous SCP State
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
u = cp.Variable((params.sim.n, params.sim.n_controls), name='u') # Control
|
|
33
|
-
du = cp.Variable((params.sim.n, params.sim.n_controls), name='du') # Control Trust Region
|
|
34
|
-
u_bar = cp.Parameter((params.sim.n, params.sim.n_controls), name='u_bar') # Previous SCP Control
|
|
35
32
|
|
|
33
|
+
u = cp.Variable((params.sim.n, params.sim.n_controls), name="u") # Control
|
|
34
|
+
du = cp.Variable((params.sim.n, params.sim.n_controls), name="du") # Control Trust Region
|
|
35
|
+
u_bar = cp.Parameter((params.sim.n, params.sim.n_controls), name="u_bar") # Previous SCP Control
|
|
36
36
|
```
|
|
37
37
|
|
|
38
38
|
## Scaling Definitions
|
|
@@ -104,15 +104,15 @@ def OptimalControlProblem(params: Config):
|
|
|
104
104
|
########################
|
|
105
105
|
|
|
106
106
|
# Parameters
|
|
107
|
-
lam_prox = cp.Parameter(nonneg
|
|
108
|
-
lam_cost = cp.Parameter(nonneg=True, name=
|
|
109
|
-
lam_vc = cp.Parameter((params.sim.n - 1, params.sim.n_states), nonneg=True, name=
|
|
110
|
-
lam_vb = cp.Parameter(nonneg=True, name=
|
|
107
|
+
lam_prox = cp.Parameter(nonneg=True, name="lam_prox")
|
|
108
|
+
lam_cost = cp.Parameter(nonneg=True, name="lam_cost")
|
|
109
|
+
lam_vc = cp.Parameter((params.sim.n - 1, params.sim.n_states), nonneg=True, name="lam_vc")
|
|
110
|
+
lam_vb = cp.Parameter(nonneg=True, name="lam_vb")
|
|
111
111
|
|
|
112
112
|
# State
|
|
113
|
-
x = cp.Variable((params.sim.n, params.sim.n_states), name=
|
|
114
|
-
dx = cp.Variable((params.sim.n, params.sim.n_states), name=
|
|
115
|
-
x_bar = cp.Parameter((params.sim.n, params.sim.n_states), name=
|
|
113
|
+
x = cp.Variable((params.sim.n, params.sim.n_states), name="x")
|
|
114
|
+
dx = cp.Variable((params.sim.n, params.sim.n_states), name="dx") # State Trust Region
|
|
115
|
+
x_bar = cp.Parameter((params.sim.n, params.sim.n_states), name="x_bar") # Previous SCP State
|
|
116
116
|
|
|
117
117
|
# Affine Scaling for State
|
|
118
118
|
S_x = params.sim.S_x
|
|
@@ -120,9 +120,11 @@ def OptimalControlProblem(params: Config):
|
|
|
120
120
|
c_x = params.sim.c_x
|
|
121
121
|
|
|
122
122
|
# Control
|
|
123
|
-
u = cp.Variable((params.sim.n, params.sim.n_controls), name=
|
|
124
|
-
du = cp.Variable((params.sim.n, params.sim.n_controls), name=
|
|
125
|
-
u_bar = cp.Parameter(
|
|
123
|
+
u = cp.Variable((params.sim.n, params.sim.n_controls), name="u")
|
|
124
|
+
du = cp.Variable((params.sim.n, params.sim.n_controls), name="du") # Control Trust Region
|
|
125
|
+
u_bar = cp.Parameter(
|
|
126
|
+
(params.sim.n, params.sim.n_controls), name="u_bar"
|
|
127
|
+
) # Previous SCP Control
|
|
126
128
|
|
|
127
129
|
# Affine Scaling for Control
|
|
128
130
|
S_u = params.sim.S_u
|
|
@@ -130,11 +132,11 @@ def OptimalControlProblem(params: Config):
|
|
|
130
132
|
c_u = params.sim.c_u
|
|
131
133
|
|
|
132
134
|
# Discretized Augmented Dynamics Constraints
|
|
133
|
-
A_d = cp.Parameter((params.sim.n - 1, params.sim.n_states, params.sim.n_states), name=
|
|
134
|
-
B_d = cp.Parameter((params.sim.n - 1, params.sim.n_states, params.sim.n_controls), name=
|
|
135
|
-
C_d = cp.Parameter((params.sim.n - 1, params.sim.n_states, params.sim.n_controls), name=
|
|
136
|
-
z_d = cp.Parameter((params.sim.n - 1, params.sim.n_states), name=
|
|
137
|
-
nu
|
|
135
|
+
A_d = cp.Parameter((params.sim.n - 1, params.sim.n_states, params.sim.n_states), name="A_d")
|
|
136
|
+
B_d = cp.Parameter((params.sim.n - 1, params.sim.n_states, params.sim.n_controls), name="B_d")
|
|
137
|
+
C_d = cp.Parameter((params.sim.n - 1, params.sim.n_states, params.sim.n_controls), name="C_d")
|
|
138
|
+
z_d = cp.Parameter((params.sim.n - 1, params.sim.n_states), name="z_d")
|
|
139
|
+
nu = cp.Variable((params.sim.n - 1, params.sim.n_states), name="nu") # Virtual Control
|
|
138
140
|
|
|
139
141
|
# Linearized Nonconvex Nodal Constraints
|
|
140
142
|
if params.sim.constraints_nodal:
|
|
@@ -144,10 +146,20 @@ def OptimalControlProblem(params: Config):
|
|
|
144
146
|
nu_vb = []
|
|
145
147
|
for idx_ncvx, constraint in enumerate(params.sim.constraints_nodal):
|
|
146
148
|
if not constraint.convex:
|
|
147
|
-
g.append(cp.Parameter(params.sim.n, name
|
|
148
|
-
grad_g_x.append(
|
|
149
|
-
|
|
150
|
-
|
|
149
|
+
g.append(cp.Parameter(params.sim.n, name="g_" + str(idx_ncvx)))
|
|
150
|
+
grad_g_x.append(
|
|
151
|
+
cp.Parameter(
|
|
152
|
+
(params.sim.n, params.sim.n_states), name="grad_g_x_" + str(idx_ncvx)
|
|
153
|
+
)
|
|
154
|
+
)
|
|
155
|
+
grad_g_u.append(
|
|
156
|
+
cp.Parameter(
|
|
157
|
+
(params.sim.n, params.sim.n_controls), name="grad_g_u_" + str(idx_ncvx)
|
|
158
|
+
)
|
|
159
|
+
)
|
|
160
|
+
nu_vb.append(
|
|
161
|
+
cp.Variable(params.sim.n, name="nu_vb_" + str(idx_ncvx))
|
|
162
|
+
) # Virtual Control for VB
|
|
151
163
|
|
|
152
164
|
# Applying the affine scaling to state and control
|
|
153
165
|
x_nonscaled = []
|
|
@@ -174,50 +186,90 @@ def OptimalControlProblem(params: Config):
|
|
|
174
186
|
constr += [constraint(x_nonscaled[node], u_nonscaled[node]) for node in nodes]
|
|
175
187
|
|
|
176
188
|
elif not constraint.convex:
|
|
177
|
-
constr += [
|
|
189
|
+
constr += [
|
|
190
|
+
(
|
|
191
|
+
g[idx_ncvx][node]
|
|
192
|
+
+ grad_g_x[idx_ncvx][node] @ dx[node]
|
|
193
|
+
+ grad_g_u[idx_ncvx][node] @ du[node]
|
|
194
|
+
)
|
|
195
|
+
== nu_vb[idx_ncvx][node]
|
|
196
|
+
for node in nodes
|
|
197
|
+
]
|
|
178
198
|
idx_ncvx += 1
|
|
179
199
|
|
|
180
200
|
for i in range(params.sim.idx_x_true.start, params.sim.idx_x_true.stop):
|
|
181
|
-
if params.sim.initial_state.type[i] ==
|
|
182
|
-
constr += [
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
if params.sim.
|
|
201
|
+
if params.sim.initial_state.type[i] == "Fix":
|
|
202
|
+
constr += [
|
|
203
|
+
x_nonscaled[0][i] == params.sim.initial_state.value[i]
|
|
204
|
+
] # Initial Boundary Conditions
|
|
205
|
+
if params.sim.final_state.type[i] == "Fix":
|
|
206
|
+
constr += [
|
|
207
|
+
x_nonscaled[-1][i] == params.sim.final_state.value[i]
|
|
208
|
+
] # Final Boundary Conditions
|
|
209
|
+
if params.sim.initial_state.type[i] == "Minimize":
|
|
186
210
|
cost += lam_cost * x_nonscaled[0][i]
|
|
187
|
-
if params.sim.final_state.type[i] ==
|
|
211
|
+
if params.sim.final_state.type[i] == "Minimize":
|
|
188
212
|
cost += lam_cost * x_nonscaled[-1][i]
|
|
189
|
-
if params.sim.initial_state.type[i] ==
|
|
213
|
+
if params.sim.initial_state.type[i] == "Maximize":
|
|
190
214
|
cost += lam_cost * x_nonscaled[0][i]
|
|
191
|
-
if params.sim.final_state.type[i] ==
|
|
215
|
+
if params.sim.final_state.type[i] == "Maximize":
|
|
192
216
|
cost += lam_cost * x_nonscaled[-1][i]
|
|
193
217
|
|
|
194
218
|
if params.sim._uniform_time_grid:
|
|
195
|
-
constr += [
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
constr += [
|
|
219
|
+
constr += [
|
|
220
|
+
x_nonscaled[i][params.sim.idx_t] - x_nonscaled[i - 1][params.sim.idx_t]
|
|
221
|
+
== x_nonscaled[i - 1][params.sim.idx_t] - x_nonscaled[i - 2][params.sim.idx_t]
|
|
222
|
+
for i in range(2, params.sim.n)
|
|
223
|
+
] # Uniform Time Step
|
|
224
|
+
|
|
225
|
+
constr += [
|
|
226
|
+
0 == la.inv(S_x) @ (x_nonscaled[i] - x_bar[i] - dx[i]) for i in range(params.sim.n)
|
|
227
|
+
] # State Error
|
|
228
|
+
constr += [
|
|
229
|
+
0 == la.inv(S_u) @ (u_nonscaled[i] - u_bar[i] - du[i]) for i in range(params.sim.n)
|
|
230
|
+
] # Control Error
|
|
231
|
+
|
|
232
|
+
constr += [
|
|
233
|
+
x_nonscaled[i]
|
|
234
|
+
== A_d[i - 1] @ x_nonscaled[i - 1]
|
|
235
|
+
+ B_d[i - 1] @ u_nonscaled[i - 1]
|
|
236
|
+
+ C_d[i - 1] @ u_nonscaled[i]
|
|
237
|
+
+ z_d[i - 1]
|
|
238
|
+
+ nu[i - 1]
|
|
239
|
+
for i in range(1, params.sim.n)
|
|
240
|
+
] # Dynamics Constraint
|
|
209
241
|
|
|
210
|
-
constr += [
|
|
211
|
-
constr += [
|
|
242
|
+
constr += [u_nonscaled[i] <= params.sim.max_control for i in range(params.sim.n)]
|
|
243
|
+
constr += [
|
|
244
|
+
u_nonscaled[i] >= params.sim.min_control for i in range(params.sim.n)
|
|
245
|
+
] # Control Constraints
|
|
246
|
+
|
|
247
|
+
constr += [
|
|
248
|
+
x_nonscaled[i][params.sim.idx_x_true] <= params.sim.max_state[params.sim.idx_x_true]
|
|
249
|
+
for i in range(params.sim.n)
|
|
250
|
+
]
|
|
251
|
+
constr += [
|
|
252
|
+
x_nonscaled[i][params.sim.idx_x_true] >= params.sim.min_state[params.sim.idx_x_true]
|
|
253
|
+
for i in range(params.sim.n)
|
|
254
|
+
] # State Constraints (Also implemented in CTCS but included for numerical stability)
|
|
212
255
|
|
|
213
256
|
########
|
|
214
257
|
# COSTS
|
|
215
258
|
########
|
|
216
|
-
|
|
217
|
-
inv = block(
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
259
|
+
|
|
260
|
+
inv = block(
|
|
261
|
+
[
|
|
262
|
+
[inv_S_x, np.zeros((S_x.shape[0], S_u.shape[1]))],
|
|
263
|
+
[np.zeros((S_u.shape[0], S_x.shape[1])), inv_S_u],
|
|
264
|
+
]
|
|
265
|
+
)
|
|
266
|
+
cost += sum(
|
|
267
|
+
lam_prox * cp.sum_squares(inv @ cp.hstack((dx[i], du[i]))) for i in range(params.sim.n)
|
|
268
|
+
) # Trust Region Cost
|
|
269
|
+
cost += sum(
|
|
270
|
+
lam_vc * cp.sum(cp.abs(nu[i - 1])) for i in range(1, params.sim.n)
|
|
271
|
+
) # Virtual Control Slack
|
|
272
|
+
|
|
221
273
|
idx_ncvx = 0
|
|
222
274
|
if params.sim.constraints_nodal:
|
|
223
275
|
for constraint in params.sim.constraints_nodal:
|
|
@@ -225,28 +277,32 @@ def OptimalControlProblem(params: Config):
|
|
|
225
277
|
cost += lam_vb * cp.sum(cp.pos(nu_vb[idx_ncvx]))
|
|
226
278
|
idx_ncvx += 1
|
|
227
279
|
|
|
228
|
-
for idx, nodes in zip(
|
|
280
|
+
for idx, nodes in zip(
|
|
281
|
+
np.arange(params.sim.idx_y.start, params.sim.idx_y.stop), params.sim.ctcs_node_intervals
|
|
282
|
+
):
|
|
229
283
|
if nodes[0] == 0:
|
|
230
284
|
start_idx = 1
|
|
231
285
|
else:
|
|
232
286
|
start_idx = nodes[0]
|
|
233
|
-
constr += [
|
|
287
|
+
constr += [
|
|
288
|
+
cp.abs(x_nonscaled[i][idx] - x_nonscaled[i - 1][idx]) <= params.sim.max_state[idx]
|
|
289
|
+
for i in range(start_idx, nodes[1])
|
|
290
|
+
]
|
|
234
291
|
constr += [x_nonscaled[0][idx] == 0]
|
|
235
292
|
|
|
236
|
-
|
|
237
293
|
#########
|
|
238
294
|
# PROBLEM
|
|
239
295
|
#########
|
|
240
296
|
prob = cp.Problem(cp.Minimize(cost), constr)
|
|
241
297
|
if solver.cvxpygen:
|
|
242
298
|
# Check to see if solver directory exists
|
|
243
|
-
if not os.path.exists(
|
|
244
|
-
cpg.generate_code(prob, solver
|
|
299
|
+
if not os.path.exists("solver"):
|
|
300
|
+
cpg.generate_code(prob, solver=solver.cvx_solver, code_dir="solver", wrapper=True)
|
|
245
301
|
else:
|
|
246
302
|
# Prompt the use to indicate if they wish to overwrite the solver directory or use the existing compiled solver
|
|
247
303
|
overwrite = input("Solver directory already exists. Overwrite? (y/n): ")
|
|
248
|
-
if overwrite.lower() ==
|
|
249
|
-
cpg.generate_code(prob, solver
|
|
304
|
+
if overwrite.lower() == "y":
|
|
305
|
+
cpg.generate_code(prob, solver=solver.cvx_solver, code_dir="solver", wrapper=True)
|
|
250
306
|
else:
|
|
251
307
|
pass
|
|
252
308
|
return prob
|
|
@@ -25,9 +25,7 @@ result = problem.solve()
|
|
|
25
25
|
result = problem.solve_jax()
|
|
26
26
|
|
|
27
27
|
# Batched — standard jax.vmap, no library-specific API.
|
|
28
|
-
batched = jax.vmap(problem.solve_jax, in_axes=(0, 0, None))(
|
|
29
|
-
x_initial_stack, x_final_stack, params
|
|
30
|
-
)
|
|
28
|
+
batched = jax.vmap(problem.solve_jax, in_axes=(0, 0, None))(x_initial_stack, x_final_stack, params)
|
|
31
29
|
|
|
32
30
|
# JIT-compile once, solve forever (e.g. MPC inner loop).
|
|
33
31
|
fast_solve = jax.jit(problem.solve_jax)
|
|
@@ -101,10 +99,10 @@ batched inputs agree.)
|
|
|
101
99
|
|
|
102
100
|
```python
|
|
103
101
|
results = problem.solve_batched(
|
|
104
|
-
x_initial=x0_batch,
|
|
102
|
+
x_initial=x0_batch, # (B, n_x): rank = declared+1 -> batched
|
|
105
103
|
parameters={
|
|
106
|
-
"gate_center": centers,
|
|
107
|
-
"gate_radius": 0.5,
|
|
104
|
+
"gate_center": centers, # (B, 3) vs declared (3,) -> batched
|
|
105
|
+
"gate_radius": 0.5, # declared shape -> shared
|
|
108
106
|
},
|
|
109
107
|
)
|
|
110
108
|
```
|
|
@@ -117,7 +115,7 @@ fall back to the rank rule):
|
|
|
117
115
|
|
|
118
116
|
```python
|
|
119
117
|
results = problem.solve_batched(
|
|
120
|
-
parameters={"weights": w},
|
|
118
|
+
parameters={"weights": w}, # (B,) is also w's declared shape...
|
|
121
119
|
in_axes={"parameters": {"weights": 0}}, # ...so say "batched" explicitly
|
|
122
120
|
)
|
|
123
121
|
|
|
@@ -157,7 +155,7 @@ kwarg's field. Construction-only keys of the constructor dict — `autotuner`,
|
|
|
157
155
|
|
|
158
156
|
```python
|
|
159
157
|
B = 8 # batch size. Just an int for building the arrays below — there is no
|
|
160
|
-
|
|
158
|
+
# B argument; solve_batched infers it from the leading-axis lengths.
|
|
161
159
|
sweep = problem.solve_batched(algorithm={"ep_tr": jnp.logspace(-6, -3, B)})
|
|
162
160
|
weights = problem.solve_batched(algorithm={"lam_prox": jnp.array([0.5, 1.0, 4.0])})
|
|
163
161
|
budgets = problem.solve_batched(max_iters=jnp.array([5, 10, 20])) # per-element caps
|
{openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/docs/UnderTheHood/custom_algorithms_autotuners.md
RENAMED
|
@@ -183,7 +183,7 @@ the rule:
|
|
|
183
183
|
|
|
184
184
|
```python
|
|
185
185
|
def converged(self, state):
|
|
186
|
-
return state.J_vc < state.ep_vc
|
|
186
|
+
return state.J_vc < state.ep_vc # custom: virtual control alone
|
|
187
187
|
```
|
|
188
188
|
|
|
189
189
|
The default — every metric below its threshold — is algorithm-agnostic, since
|
|
@@ -71,12 +71,12 @@ After preprocessing, all symbolic definitions are collected into a `SymbolicProb
|
|
|
71
71
|
```python
|
|
72
72
|
@dataclass
|
|
73
73
|
class SymbolicProblem:
|
|
74
|
-
dynamics: Expr
|
|
75
|
-
states: List[State]
|
|
76
|
-
controls: List[Control]
|
|
74
|
+
dynamics: Expr # Symbolic dx/dt = f(x, u)
|
|
75
|
+
states: List[State] # All state variables (including augmented)
|
|
76
|
+
controls: List[Control] # All control variables (including virtual)
|
|
77
77
|
constraints: ConstraintSet # Categorized constraints
|
|
78
|
-
parameters: dict
|
|
79
|
-
N: int
|
|
78
|
+
parameters: dict # User-defined parameters
|
|
79
|
+
N: int # Discretization nodes
|
|
80
80
|
# ... plus propagation variants
|
|
81
81
|
```
|
|
82
82
|
|
|
@@ -88,20 +88,20 @@ Lowering produces a `LoweredProblem` containing everything needed for optimizati
|
|
|
88
88
|
@dataclass
|
|
89
89
|
class LoweredProblem:
|
|
90
90
|
# JAX dynamics (callable functions with Jacobians)
|
|
91
|
-
dynamics: Dynamics
|
|
92
|
-
dynamics_prop: Dynamics
|
|
91
|
+
dynamics: Dynamics # f, A=df/dx, B=df/du
|
|
92
|
+
dynamics_prop: Dynamics # For forward propagation
|
|
93
93
|
|
|
94
94
|
# Lowered constraints (by backend)
|
|
95
95
|
jax_constraints: LoweredJaxConstraints
|
|
96
96
|
cvxpy_constraints: LoweredCvxpyConstraints
|
|
97
97
|
|
|
98
98
|
# Unified state/control interfaces
|
|
99
|
-
x_unified: UnifiedState
|
|
100
|
-
u_unified: UnifiedControl
|
|
99
|
+
x_unified: UnifiedState # Aggregates all states into one vector
|
|
100
|
+
u_unified: UnifiedControl # Aggregates all controls into one vector
|
|
101
101
|
|
|
102
102
|
# CVXPy optimization variables
|
|
103
|
-
ocp_vars: OCPVariables
|
|
104
|
-
cvxpy_params: dict
|
|
103
|
+
ocp_vars: OCPVariables # x, u, dx, du, nu, etc.
|
|
104
|
+
cvxpy_params: dict # User parameters as cp.Parameter
|
|
105
105
|
```
|
|
106
106
|
|
|
107
107
|
## Constraint Routing
|
|
@@ -123,9 +123,9 @@ Non-convex constraints become JAX functions with gradients:
|
|
|
123
123
|
```python
|
|
124
124
|
@dataclass
|
|
125
125
|
class LoweredJaxConstraints:
|
|
126
|
-
nodal: List[LoweredNodalConstraint]
|
|
126
|
+
nodal: List[LoweredNodalConstraint] # func, grad_g_x, grad_g_u
|
|
127
127
|
cross_node: List[LoweredCrossNodeConstraint] # func, grad_g_X, grad_g_U
|
|
128
|
-
ctcs: List[CTCS]
|
|
128
|
+
ctcs: List[CTCS] # Handled via dynamics augmentation
|
|
129
129
|
```
|
|
130
130
|
|
|
131
131
|
### CVXPy-Lowered Constraints
|
{openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/docs/UnderTheHood/vectorization_and_vmapping.md
RENAMED
|
@@ -80,16 +80,16 @@ The unification process (in `openscvx/symbolic/unified.py`) sorts variables (use
|
|
|
80
80
|
For a problem with `N` decision nodes:
|
|
81
81
|
|
|
82
82
|
```python
|
|
83
|
-
x_unified.shape = (n_x,)
|
|
84
|
-
u_unified.shape = (n_u,)
|
|
83
|
+
x_unified.shape = (n_x,) # Sum of all state dimensions
|
|
84
|
+
u_unified.shape = (n_u,) # Sum of all control dimensions
|
|
85
85
|
x_unified.guess.shape = (N, n_x) # State trajectory
|
|
86
86
|
u_unified.guess.shape = (N, n_u) # Control trajectory
|
|
87
87
|
```
|
|
88
88
|
|
|
89
89
|
**Concrete example** (brachistochrone with N=10, no CTCS constraints):
|
|
90
90
|
```python
|
|
91
|
-
x_unified.shape = (4,)
|
|
92
|
-
u_unified.shape = (2,)
|
|
91
|
+
x_unified.shape = (4,) # position(2) + velocity(1) + time(1)
|
|
92
|
+
u_unified.shape = (2,) # theta(1) + _time_dilation(1)
|
|
93
93
|
x_unified.guess.shape = (10, 4)
|
|
94
94
|
u_unified.guess.shape = (10, 2)
|
|
95
95
|
```
|
|
@@ -116,9 +116,9 @@ dyn_fn = lower_to_jax(dynamics_aug)
|
|
|
116
116
|
|
|
117
117
|
# Create Dynamics object with Jacobians
|
|
118
118
|
dynamics_augmented = Dynamics(
|
|
119
|
-
f=dyn_fn,
|
|
120
|
-
A=jacfwd(dyn_fn, argnums=0),
|
|
121
|
-
B=jacfwd(dyn_fn, argnums=1),
|
|
119
|
+
f=dyn_fn, # State derivative function
|
|
120
|
+
A=jacfwd(dyn_fn, argnums=0), # Jacobian df/dx
|
|
121
|
+
B=jacfwd(dyn_fn, argnums=1), # Jacobian df/du
|
|
122
122
|
)
|
|
123
123
|
```
|
|
124
124
|
|
|
@@ -158,10 +158,10 @@ constraints_nodal_fns = lower_to_jax(constraints_nodal)
|
|
|
158
158
|
# Create LoweredNodalConstraint objects with Jacobians
|
|
159
159
|
for i, fn in enumerate(constraints_nodal_fns):
|
|
160
160
|
constraint = LoweredNodalConstraint(
|
|
161
|
-
func=fn,
|
|
161
|
+
func=fn, # Constraint function
|
|
162
162
|
grad_g_x=jacfwd(fn, argnums=0), # Jacobian dg/dx
|
|
163
163
|
grad_g_u=jacfwd(fn, argnums=1), # Jacobian dg/du
|
|
164
|
-
nodes=constraints_nodal[i].nodes,
|
|
164
|
+
nodes=constraints_nodal[i].nodes, # Node indices where constraint applies
|
|
165
165
|
)
|
|
166
166
|
```
|
|
167
167
|
|
|
@@ -239,18 +239,9 @@ Dynamics functions are vmapped to process all intervals in parallel (in `Problem
|
|
|
239
239
|
|
|
240
240
|
```python
|
|
241
241
|
# Vectorize dynamics functions across decision nodes
|
|
242
|
-
self.dynamics_augmented.f = jax.vmap(
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
)
|
|
246
|
-
self.dynamics_augmented.A = jax.vmap(
|
|
247
|
-
self.dynamics_augmented.A,
|
|
248
|
-
in_axes=(0, 0, 0, None)
|
|
249
|
-
)
|
|
250
|
-
self.dynamics_augmented.B = jax.vmap(
|
|
251
|
-
self.dynamics_augmented.B,
|
|
252
|
-
in_axes=(0, 0, 0, None)
|
|
253
|
-
)
|
|
242
|
+
self.dynamics_augmented.f = jax.vmap(self.dynamics_augmented.f, in_axes=(0, 0, 0, None))
|
|
243
|
+
self.dynamics_augmented.A = jax.vmap(self.dynamics_augmented.A, in_axes=(0, 0, 0, None))
|
|
244
|
+
self.dynamics_augmented.B = jax.vmap(self.dynamics_augmented.B, in_axes=(0, 0, 0, None))
|
|
254
245
|
```
|
|
255
246
|
|
|
256
247
|
**Dynamics Vmap Configuration: `in_axes=(0, 0, 0, None)`**
|
|
@@ -372,9 +363,9 @@ Cross-node constraints are **not vmapped** because they already operate on full
|
|
|
372
363
|
|
|
373
364
|
```python
|
|
374
365
|
# Each LoweredCrossNodeConstraint operates on full trajectories
|
|
375
|
-
residual = constraint.func(X, U, params)
|
|
376
|
-
grad_X = constraint.grad_g_X(X, U, params)
|
|
377
|
-
grad_U = constraint.grad_g_U(X, U, params)
|
|
366
|
+
residual = constraint.func(X, U, params) # scalar
|
|
367
|
+
grad_X = constraint.grad_g_X(X, U, params) # (N, n_x) - sparse, mostly zeros
|
|
368
|
+
grad_U = constraint.grad_g_U(X, U, params) # (N, n_u) - sparse, mostly zeros
|
|
378
369
|
```
|
|
379
370
|
|
|
380
371
|
The Jacobians are dense arrays but exhibit sparsity patterns determined by which nodes the constraint couples.
|
|
@@ -385,23 +376,23 @@ The vmapped dynamics functions are called during discretization (in `calculate_d
|
|
|
385
376
|
|
|
386
377
|
```python
|
|
387
378
|
# Setup batch inputs
|
|
388
|
-
x = V[:, :n_x]
|
|
389
|
-
u = u[: x.shape[0]]
|
|
390
|
-
nodes = jnp.arange(0, N-1)
|
|
379
|
+
x = V[:, :n_x] # Shape: (N-1, n_x) - States at interval starts
|
|
380
|
+
u = u[: x.shape[0]] # Shape: (N-1, n_u) - Controls (includes time dilation)
|
|
381
|
+
nodes = jnp.arange(0, N - 1) # Shape: (N-1,) - Node indices
|
|
391
382
|
|
|
392
383
|
# Extract time dilation (last control dimension)
|
|
393
|
-
s = u[:, -1]
|
|
384
|
+
s = u[:, -1] # Shape: (N-1,) - Time dilation values
|
|
394
385
|
|
|
395
386
|
# Call vmapped dynamics - evaluates all intervals in parallel
|
|
396
387
|
# Note: dynamics receive u[:, :-1] (vehicle controls only, excluding time dilation)
|
|
397
388
|
f = state_dot(x, u[:, :-1], nodes, params) # Shape: (N-1, n_x)
|
|
398
|
-
dfdx = A(x, u[:, :-1], nodes, params)
|
|
399
|
-
dfdu_veh = B(x, u[:, :-1], nodes, params)
|
|
389
|
+
dfdx = A(x, u[:, :-1], nodes, params) # Shape: (N-1, n_x, n_x)
|
|
390
|
+
dfdu_veh = B(x, u[:, :-1], nodes, params) # Shape: (N-1, n_x, n_u-1)
|
|
400
391
|
|
|
401
392
|
# Build full control Jacobian including time dilation
|
|
402
393
|
dfdu = jnp.zeros((x.shape[0], n_x, n_u))
|
|
403
394
|
dfdu = dfdu.at[:, :, :-1].set(s[:, None, None] * dfdu_veh) # Vehicle control derivatives
|
|
404
|
-
dfdu = dfdu.at[:, :, -1].set(f)
|
|
395
|
+
dfdu = dfdu.at[:, :, -1].set(f) # Time dilation derivative = f
|
|
405
396
|
```
|
|
406
397
|
|
|
407
398
|
**Why exclude time dilation from dynamics?** Time dilation is a meta-control that scales the entire dynamics (used for time-optimal problems). The actual vehicle dynamics are defined without it, and time dilation is applied as a scaling factor during discretization. This is why `n_u-1` appears in the vehicle dynamics Jacobians.
|
{openscvx-0.5.3.dev45 → openscvx-0.5.3.dev46}/docs/UsersGuide/01_hello_world_brachistochrone.md
RENAMED
|
@@ -214,12 +214,7 @@ To mark these as CTCS constraints we simply wrap them in `ox.ctcs(...)`
|
|
|
214
214
|
# Generate box constraints for all states
|
|
215
215
|
constraints = []
|
|
216
216
|
for state in states:
|
|
217
|
-
constraints.extend(
|
|
218
|
-
[
|
|
219
|
-
ox.ctcs(state <= state.max),
|
|
220
|
-
ox.ctcs(state.min <= state)
|
|
221
|
-
]
|
|
222
|
-
)
|
|
217
|
+
constraints.extend([ox.ctcs(state <= state.max), ox.ctcs(state.min <= state)])
|
|
223
218
|
```
|
|
224
219
|
|
|
225
220
|
This style of constraint definition as a list should feel familiar to CVXPY users.
|