openscvx 0.5.3.dev45__tar.gz → 0.5.3.dev47__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.
Files changed (470) hide show
  1. {openscvx-0.5.3.dev45/openscvx.egg-info → openscvx-0.5.3.dev47}/PKG-INFO +1 -1
  2. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/docs/Foundations/control_parameterization.md +3 -2
  3. openscvx-0.5.3.dev47/docs/Foundations/discretization.md +94 -0
  4. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/docs/Foundations/ocp.md +124 -68
  5. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/docs/UnderTheHood/batching_jit_grad.md +6 -8
  6. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/docs/UnderTheHood/custom_algorithms_autotuners.md +1 -1
  7. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/docs/UnderTheHood/lowering_architecture.md +13 -13
  8. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/docs/UnderTheHood/vectorization_and_vmapping.md +22 -31
  9. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/docs/UsersGuide/01_hello_world_brachistochrone.md +1 -6
  10. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/docs/UsersGuide/02_drone_racing_constraints.md +7 -20
  11. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/docs/UsersGuide/03_obstacle_avoidance_vmap.md +12 -17
  12. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/docs/UsersGuide/04_viewpoint_constraints.md +29 -29
  13. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/docs/UsersGuide/05_visualization.md +19 -21
  14. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/docs/UsersGuide/07_lie.md +53 -54
  15. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/docs/UsersGuide/08_mpcc.md +75 -73
  16. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/docs/UsersGuide/09_mjx_dynamics.md +2 -2
  17. openscvx-0.5.3.dev47/examples/frax/ur5e_pen_trace_mpcc.py +749 -0
  18. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/openscvx/_version.py +3 -3
  19. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47/openscvx.egg-info}/PKG-INFO +1 -1
  20. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/openscvx.egg-info/SOURCES.txt +1 -0
  21. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/openscvx.egg-info/scm_file_list.json +413 -412
  22. openscvx-0.5.3.dev47/openscvx.egg-info/scm_version.json +8 -0
  23. openscvx-0.5.3.dev45/docs/Foundations/discretization.md +0 -85
  24. openscvx-0.5.3.dev45/openscvx.egg-info/scm_version.json +0 -8
  25. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/.github/assets/logo.svg +0 -0
  26. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/.github/release-drafter.yml +0 -0
  27. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/.github/workflows/_docs.yml +0 -0
  28. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/.github/workflows/_extra.yml +0 -0
  29. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/.github/workflows/branch-name.yml +0 -0
  30. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/.github/workflows/docs.yml +0 -0
  31. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/.github/workflows/lint.yml +0 -0
  32. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/.github/workflows/nightly.yml +0 -0
  33. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/.github/workflows/release-drafter.yml +0 -0
  34. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/.github/workflows/release.yml +0 -0
  35. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/.github/workflows/tests-cvxpygen.yml +0 -0
  36. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/.github/workflows/tests-examples.yml +0 -0
  37. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/.github/workflows/tests-lie.yml +0 -0
  38. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/.github/workflows/tests-mjx.yml +0 -0
  39. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/.github/workflows/tests-qpax.yml +0 -0
  40. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/.github/workflows/tests.yml +0 -0
  41. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/.gitignore +0 -0
  42. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/.gitmodules +0 -0
  43. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/CITATION.cff +0 -0
  44. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/CONTRIBUTING.md +0 -0
  45. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/LICENSE +0 -0
  46. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/README.md +0 -0
  47. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/docs/Foundations/constraint_reformulation.md +0 -0
  48. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/docs/Foundations/scvx.md +0 -0
  49. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/docs/Foundations/time_dilation.md +0 -0
  50. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/docs/UsersGuide/00_introduction.md +0 -0
  51. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/docs/UsersGuide/06_logic.md +0 -0
  52. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/docs/assets/favicon.png +0 -0
  53. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/docs/assets/images/ct-scvx_dark.png +0 -0
  54. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/docs/assets/images/ct-scvx_light.png +0 -0
  55. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/docs/assets/images/ctcs_dark.png +0 -0
  56. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/docs/assets/images/ctcs_light.png +0 -0
  57. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/docs/assets/images/problem_class_dark.png +0 -0
  58. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/docs/assets/images/problem_class_light.png +0 -0
  59. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/docs/assets/logo.svg +0 -0
  60. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/docs/assets/openscvx_logo_square.png +0 -0
  61. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/docs/assets/viser-client/index.html +0 -0
  62. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/docs/assets/viser-recordings/drone_racing.viser +0 -0
  63. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/docs/assets/viser-recordings/franka_fr3v2_pick_place.viser +0 -0
  64. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/docs/changelog.md +0 -0
  65. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/docs/citation.md +0 -0
  66. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/docs/examples.md +0 -0
  67. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/docs/index.md +0 -0
  68. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/docs/installation.md +0 -0
  69. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/docs/javascripts/mathjax.js +0 -0
  70. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/docs/llms.txt +0 -0
  71. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/docs/versions.json +0 -0
  72. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/examples/_viser_embed_export.py +0 -0
  73. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/examples/abstract/brachistochrone.py +0 -0
  74. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/examples/abstract/brachistochrone_batched.py +0 -0
  75. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/examples/abstract/flappy_bird.py +0 -0
  76. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/examples/abstract/hypersensitive.py +0 -0
  77. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/examples/abstract/impulsive.py +0 -0
  78. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/examples/abstract/stl_integer_variable.py +0 -0
  79. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/examples/abstract/stl_or.py +0 -0
  80. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/examples/aircraft/dynamic_soaring.py +0 -0
  81. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/examples/aircraft/supersonic_time_to_climb.py +0 -0
  82. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/examples/animations/7_dof_arm.py +0 -0
  83. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/examples/animations/_camera.py +0 -0
  84. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/examples/animations/_render.py +0 -0
  85. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/examples/animations/_sensor_view.py +0 -0
  86. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/examples/animations/dr_vp_polytope.py +0 -0
  87. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/examples/animations/franka_fr3v2_pick_place.py +0 -0
  88. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/examples/animations/logo.py +0 -0
  89. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/examples/animations/obstacle_avoidance_vmap.py +0 -0
  90. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/examples/arm/3_dof_arm.py +0 -0
  91. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/examples/arm/7_dof_arm.py +0 -0
  92. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/examples/arm/7_dof_arm_collision.py +0 -0
  93. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/examples/arm/7_dof_arm_vp.py +0 -0
  94. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/examples/arm/franka_fr3v2_pick_place.py +0 -0
  95. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/examples/arm/franka_fr3v2_viewplanning.py +0 -0
  96. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/examples/arm/franka_fr3v2_viewplanning_nodal.py +0 -0
  97. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/examples/car/dubins_car.py +0 -0
  98. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/examples/car/dubins_car_disjoint.py +0 -0
  99. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/examples/car/dubins_car_obstacle_conditional.py +0 -0
  100. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/examples/car/dubins_car_obstacle_stl.py +0 -0
  101. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/examples/car/dubins_car_stl_or.py +0 -0
  102. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/examples/car/dubins_car_waypoint_stl.py +0 -0
  103. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/examples/double_integrator/_plotting.py +0 -0
  104. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/examples/double_integrator/moving_safe_zones.py +0 -0
  105. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/examples/drone/2d_obstacle_avoidance_batched_ic.py +0 -0
  106. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/examples/drone/boresight_trace_mpcc.py +0 -0
  107. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/examples/drone/cinema_vp.py +0 -0
  108. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/examples/drone/cinema_vp_nodal.py +0 -0
  109. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/examples/drone/dr_double_integrator.py +0 -0
  110. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/examples/drone/dr_vp.py +0 -0
  111. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/examples/drone/dr_vp_nodal.py +0 -0
  112. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/examples/drone/dr_vp_polytope.py +0 -0
  113. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/examples/drone/drone_racing.py +0 -0
  114. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/examples/drone/drone_racing_batched_gates.py +0 -0
  115. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/examples/drone/logo.py +0 -0
  116. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/examples/drone/logo_utils/acl_logo.svg +0 -0
  117. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/examples/drone/logo_utils/circle.svg +0 -0
  118. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/examples/drone/logo_utils/openscvx_logo_single.svg +0 -0
  119. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/examples/drone/logo_utils/quadrotor_mesh.py +0 -0
  120. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/examples/drone/logo_utils/svg_path_utils.py +0 -0
  121. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/examples/drone/multi_agent_circle_swap.py +0 -0
  122. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/examples/drone/obstacle_avoidance.py +0 -0
  123. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/examples/drone/obstacle_avoidance_nodal.py +0 -0
  124. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/examples/drone/obstacle_avoidance_vmap.py +0 -0
  125. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/examples/drone/obstacle_avoidance_vmap_2d.py +0 -0
  126. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/examples/drone/openscvx_logo.py +0 -0
  127. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/examples/frax/panda_frax.py +0 -0
  128. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/examples/frax/panda_frax_pick_place.py +0 -0
  129. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/examples/frax/panda_frax_viewplanning.py +0 -0
  130. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/examples/frax/panda_frax_waypoint.py +0 -0
  131. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/examples/frax/ur5e_assets/ur5e.urdf +0 -0
  132. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/examples/frax/ur5e_pen_trace.py +0 -0
  133. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/examples/mjx/cartpole_mjx.py +0 -0
  134. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/examples/mjx/double_cartpole_mjx.py +0 -0
  135. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/examples/mjx/skydio_x2_mjx.py +0 -0
  136. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/examples/mjx/triple_cartpole_3d_mjx.py +0 -0
  137. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/examples/mjx/triple_cartpole_game.py +0 -0
  138. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/examples/mjx/triple_cartpole_mjx.py +0 -0
  139. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/examples/mpc/double_integrator_discrete.py +0 -0
  140. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/examples/mpc/double_integrator_drone_racing.py +0 -0
  141. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/examples/mpc/dubins_car_circle_analytical.py +0 -0
  142. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/examples/mpc/dubins_car_circle_discrete.py +0 -0
  143. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/examples/mpc/realtime_double_integrator_drone_racing.py +0 -0
  144. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/examples/plotting.py +0 -0
  145. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/examples/plotting_viser.py +0 -0
  146. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/examples/realtime/3DoF_pdg_realtime.py +0 -0
  147. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/examples/realtime/6DoF_pdg_realtime.py +0 -0
  148. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/examples/realtime/base_problems/3DoF_pdg_realtime_base.py +0 -0
  149. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/examples/realtime/base_problems/6DoF_pdg_realtime_base.py +0 -0
  150. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/examples/realtime/base_problems/cinema_vp_realtime_base.py +0 -0
  151. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/examples/realtime/base_problems/drone_racing_realtime_base.py +0 -0
  152. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/examples/realtime/base_problems/dubins_car_realtime_base.py +0 -0
  153. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/examples/realtime/base_problems/obstacle_avoidance_realtime_base.py +0 -0
  154. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/examples/realtime/cinema_vp_realtime.py +0 -0
  155. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/examples/realtime/drone_racing_realtime.py +0 -0
  156. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/examples/realtime/dubins_car_realtime.py +0 -0
  157. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/examples/realtime/obstacle_avoidance_realtime.py +0 -0
  158. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/examples/rocket/3DoF_pdg.py +0 -0
  159. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/examples/rocket/6DoF_pdg.py +0 -0
  160. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/examples/rocket/6DoF_pdg_batched_ic.py +0 -0
  161. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/examples/rocket/ascent_launch_vehicle.py +0 -0
  162. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/examples/spacecraft/halo_orbit.py +0 -0
  163. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/examples/spacecraft/hohmann_transfer.py +0 -0
  164. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/examples/spacecraft/let_transfer.py +0 -0
  165. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/examples/spacecraft/proxops_cw.py +0 -0
  166. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/examples/spacecraft/relative_loitering.py +0 -0
  167. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/figures/ctlos_cine.gif +0 -0
  168. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/figures/ctlos_dr.gif +0 -0
  169. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/figures/dtlos_cine.gif +0 -0
  170. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/figures/dtlos_dr.gif +0 -0
  171. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/figures/openscvx_logo.svg +0 -0
  172. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/figures/openscvx_logo_square.png +0 -0
  173. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/figures/oscvx_structure_full_dark.svg +0 -0
  174. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/figures/video_preview.png +0 -0
  175. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/material/__init__.py +0 -0
  176. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/material/overrides/assets/stylesheets/custom.css +0 -0
  177. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/material/overrides/assets/stylesheets/home-dropin.css +0 -0
  178. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/material/overrides/assets/stylesheets/home-hero.css +0 -0
  179. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/material/overrides/assets/stylesheets/home-viser.css +0 -0
  180. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/material/overrides/home.html +0 -0
  181. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/material/overrides/main.html +0 -0
  182. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/material/overrides/partials/home-diagram.html +0 -0
  183. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/material/overrides/partials/home-dropin-banner.html +0 -0
  184. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/material/overrides/partials/home-hero.html +0 -0
  185. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/material/overrides/partials/home-pipeline.html +0 -0
  186. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/material/overrides/partials/home-viser-strip.html +0 -0
  187. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/material/overrides/sitemap.xml +0 -0
  188. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/mkdocs.yml +0 -0
  189. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/openscvx/__init__.py +0 -0
  190. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/openscvx/__main__.py +0 -0
  191. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/openscvx/algorithms/__init__.py +0 -0
  192. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/openscvx/algorithms/autotuner/__init__.py +0 -0
  193. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/openscvx/algorithms/autotuner/acceptance_ratio.py +0 -0
  194. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/openscvx/algorithms/autotuner/adaptive_proximal_weight.py +0 -0
  195. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/openscvx/algorithms/autotuner/augmented_lagrangian.py +0 -0
  196. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/openscvx/algorithms/autotuner/base.py +0 -0
  197. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/openscvx/algorithms/autotuner/constant_proximal_weight.py +0 -0
  198. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/openscvx/algorithms/autotuner/ramp_proximal_weight.py +0 -0
  199. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/openscvx/algorithms/base.py +0 -0
  200. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/openscvx/algorithms/history.py +0 -0
  201. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/openscvx/algorithms/hyperparams.py +0 -0
  202. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/openscvx/algorithms/loop.py +0 -0
  203. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/openscvx/algorithms/optimization_results.py +0 -0
  204. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/openscvx/algorithms/penalty.py +0 -0
  205. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/openscvx/algorithms/scvx/__init__.py +0 -0
  206. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/openscvx/algorithms/scvx/iteration.py +0 -0
  207. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/openscvx/algorithms/scvx/penalized_trust_region.py +0 -0
  208. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/openscvx/algorithms/state.py +0 -0
  209. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/openscvx/algorithms/weights.py +0 -0
  210. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/openscvx/config.py +0 -0
  211. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/openscvx/discretization/__init__.py +0 -0
  212. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/openscvx/discretization/base.py +0 -0
  213. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/openscvx/discretization/discretize_linearize.py +0 -0
  214. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/openscvx/discretization/linearize_discretize.py +0 -0
  215. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/openscvx/discretization/linearize_discretize_sparse.py +0 -0
  216. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/openscvx/discretization/sparse_utils/__init__.py +0 -0
  217. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/openscvx/discretization/sparse_utils/bcoo_helpers.py +0 -0
  218. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/openscvx/discretization/sparse_utils/sparse_jacobian.py +0 -0
  219. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/openscvx/expert/__init__.py +0 -0
  220. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/openscvx/expert/byof.py +0 -0
  221. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/openscvx/expert/lowering.py +0 -0
  222. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/openscvx/expert/validation.py +0 -0
  223. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/openscvx/init/__init__.py +0 -0
  224. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/openscvx/init/interpolation.py +0 -0
  225. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/openscvx/init/inverse_kinematics.py +0 -0
  226. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/openscvx/integrations/__init__.py +0 -0
  227. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/openscvx/integrations/_utils.py +0 -0
  228. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/openscvx/integrations/base.py +0 -0
  229. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/openscvx/integrations/frax.py +0 -0
  230. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/openscvx/integrations/menagerie.py +0 -0
  231. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/openscvx/integrations/mjx.py +0 -0
  232. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/openscvx/integrators/__init__.py +0 -0
  233. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/openscvx/integrators/diffrax.py +0 -0
  234. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/openscvx/integrators/runge_kutta.py +0 -0
  235. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/openscvx/loader.py +0 -0
  236. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/openscvx/lowered/__init__.py +0 -0
  237. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/openscvx/lowered/cvxpy_constraints.py +0 -0
  238. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/openscvx/lowered/cvxpy_variables.py +0 -0
  239. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/openscvx/lowered/dynamics.py +0 -0
  240. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/openscvx/lowered/jax_constraints.py +0 -0
  241. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/openscvx/lowered/parameters.py +0 -0
  242. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/openscvx/lowered/problem.py +0 -0
  243. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/openscvx/lowered/unified.py +0 -0
  244. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/openscvx/plotting/__init__.py +0 -0
  245. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/openscvx/plotting/plotting.py +0 -0
  246. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/openscvx/plotting/publication.py +0 -0
  247. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/openscvx/plotting/scp_iteration.py +0 -0
  248. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/openscvx/plotting/viser/__init__.py +0 -0
  249. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/openscvx/plotting/viser/animated.py +0 -0
  250. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/openscvx/plotting/viser/coordinates.py +0 -0
  251. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/openscvx/plotting/viser/orbits.py +0 -0
  252. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/openscvx/plotting/viser/plotly_integration.py +0 -0
  253. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/openscvx/plotting/viser/primitives.py +0 -0
  254. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/openscvx/plotting/viser/scp.py +0 -0
  255. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/openscvx/plotting/viser/server.py +0 -0
  256. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/openscvx/problem.py +0 -0
  257. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/openscvx/propagation/__init__.py +0 -0
  258. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/openscvx/propagation/post_processing.py +0 -0
  259. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/openscvx/propagation/propagation.py +0 -0
  260. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/openscvx/solvers/__init__.py +0 -0
  261. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/openscvx/solvers/base.py +0 -0
  262. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/openscvx/solvers/cones.py +0 -0
  263. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/openscvx/solvers/cvxpy_ptr_solver.py +0 -0
  264. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/openscvx/solvers/moreau_ptr_solver.py +0 -0
  265. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/openscvx/solvers/ptr_solver.py +0 -0
  266. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/openscvx/solvers/qpax_ptr_solver.py +0 -0
  267. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/openscvx/symbolic/__init__.py +0 -0
  268. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/openscvx/symbolic/affine.py +0 -0
  269. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/openscvx/symbolic/augmentation.py +0 -0
  270. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/openscvx/symbolic/builder.py +0 -0
  271. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/openscvx/symbolic/canonicalize.py +0 -0
  272. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/openscvx/symbolic/constraint_set.py +0 -0
  273. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/openscvx/symbolic/expr/__init__.py +0 -0
  274. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/openscvx/symbolic/expr/arithmetic.py +0 -0
  275. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/openscvx/symbolic/expr/array.py +0 -0
  276. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/openscvx/symbolic/expr/constraint.py +0 -0
  277. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/openscvx/symbolic/expr/control.py +0 -0
  278. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/openscvx/symbolic/expr/expr.py +0 -0
  279. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/openscvx/symbolic/expr/lie/__init__.py +0 -0
  280. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/openscvx/symbolic/expr/lie/adjoint.py +0 -0
  281. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/openscvx/symbolic/expr/lie/se3.py +0 -0
  282. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/openscvx/symbolic/expr/lie/so3.py +0 -0
  283. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/openscvx/symbolic/expr/linalg.py +0 -0
  284. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/openscvx/symbolic/expr/logic.py +0 -0
  285. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/openscvx/symbolic/expr/math.py +0 -0
  286. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/openscvx/symbolic/expr/parameter.py +0 -0
  287. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/openscvx/symbolic/expr/spatial.py +0 -0
  288. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/openscvx/symbolic/expr/state.py +0 -0
  289. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/openscvx/symbolic/expr/stl.py +0 -0
  290. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/openscvx/symbolic/expr/stljax.py +0 -0
  291. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/openscvx/symbolic/expr/time.py +0 -0
  292. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/openscvx/symbolic/expr/variable.py +0 -0
  293. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/openscvx/symbolic/expr/vmap.py +0 -0
  294. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/openscvx/symbolic/hashing.py +0 -0
  295. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/openscvx/symbolic/lower.py +0 -0
  296. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/openscvx/symbolic/lowerers/__init__.py +0 -0
  297. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/openscvx/symbolic/lowerers/cvxpy/__init__.py +0 -0
  298. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/openscvx/symbolic/lowerers/cvxpy/_lowerer.py +0 -0
  299. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/openscvx/symbolic/lowerers/cvxpy/_registry.py +0 -0
  300. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/openscvx/symbolic/lowerers/cvxpy/arithmetic.py +0 -0
  301. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/openscvx/symbolic/lowerers/cvxpy/array.py +0 -0
  302. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/openscvx/symbolic/lowerers/cvxpy/constraint.py +0 -0
  303. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/openscvx/symbolic/lowerers/cvxpy/control.py +0 -0
  304. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/openscvx/symbolic/lowerers/cvxpy/expr.py +0 -0
  305. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/openscvx/symbolic/lowerers/cvxpy/linalg.py +0 -0
  306. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/openscvx/symbolic/lowerers/cvxpy/logic.py +0 -0
  307. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/openscvx/symbolic/lowerers/cvxpy/math.py +0 -0
  308. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/openscvx/symbolic/lowerers/cvxpy/state.py +0 -0
  309. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/openscvx/symbolic/lowerers/jax/__init__.py +0 -0
  310. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/openscvx/symbolic/lowerers/jax/_lowerer.py +0 -0
  311. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/openscvx/symbolic/lowerers/jax/_registry.py +0 -0
  312. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/openscvx/symbolic/lowerers/jax/arithmetic.py +0 -0
  313. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/openscvx/symbolic/lowerers/jax/array.py +0 -0
  314. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/openscvx/symbolic/lowerers/jax/constraint.py +0 -0
  315. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/openscvx/symbolic/lowerers/jax/control.py +0 -0
  316. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/openscvx/symbolic/lowerers/jax/expr.py +0 -0
  317. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/openscvx/symbolic/lowerers/jax/lie.py +0 -0
  318. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/openscvx/symbolic/lowerers/jax/linalg.py +0 -0
  319. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/openscvx/symbolic/lowerers/jax/logic.py +0 -0
  320. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/openscvx/symbolic/lowerers/jax/math.py +0 -0
  321. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/openscvx/symbolic/lowerers/jax/spatial.py +0 -0
  322. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/openscvx/symbolic/lowerers/jax/state.py +0 -0
  323. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/openscvx/symbolic/lowerers/jax/stl.py +0 -0
  324. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/openscvx/symbolic/lowerers/jax/stljax.py +0 -0
  325. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/openscvx/symbolic/lowerers/jax/vmap.py +0 -0
  326. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/openscvx/symbolic/lowerers/latex/__init__.py +0 -0
  327. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/openscvx/symbolic/lowerers/latex/_lowerer.py +0 -0
  328. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/openscvx/symbolic/lowerers/latex/_registry.py +0 -0
  329. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/openscvx/symbolic/lowerers/latex/arithmetic.py +0 -0
  330. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/openscvx/symbolic/lowerers/latex/array.py +0 -0
  331. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/openscvx/symbolic/lowerers/latex/constraint.py +0 -0
  332. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/openscvx/symbolic/lowerers/latex/control.py +0 -0
  333. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/openscvx/symbolic/lowerers/latex/expr.py +0 -0
  334. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/openscvx/symbolic/lowerers/latex/formulation.py +0 -0
  335. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/openscvx/symbolic/lowerers/latex/lie.py +0 -0
  336. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/openscvx/symbolic/lowerers/latex/linalg.py +0 -0
  337. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/openscvx/symbolic/lowerers/latex/logic.py +0 -0
  338. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/openscvx/symbolic/lowerers/latex/math.py +0 -0
  339. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/openscvx/symbolic/lowerers/latex/spatial.py +0 -0
  340. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/openscvx/symbolic/lowerers/latex/state.py +0 -0
  341. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/openscvx/symbolic/lowerers/latex/stl.py +0 -0
  342. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/openscvx/symbolic/lowerers/latex/vmap.py +0 -0
  343. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/openscvx/symbolic/parser/__init__.py +0 -0
  344. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/openscvx/symbolic/parser/_registry.py +0 -0
  345. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/openscvx/symbolic/parser/array.py +0 -0
  346. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/openscvx/symbolic/parser/constraint.py +0 -0
  347. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/openscvx/symbolic/parser/lie.py +0 -0
  348. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/openscvx/symbolic/parser/linalg.py +0 -0
  349. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/openscvx/symbolic/parser/logic.py +0 -0
  350. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/openscvx/symbolic/parser/math.py +0 -0
  351. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/openscvx/symbolic/parser/parser.py +0 -0
  352. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/openscvx/symbolic/parser/spatial.py +0 -0
  353. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/openscvx/symbolic/parser/stl.py +0 -0
  354. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/openscvx/symbolic/parser/stljax.py +0 -0
  355. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/openscvx/symbolic/parser/tokenizer.py +0 -0
  356. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/openscvx/symbolic/preprocessing.py +0 -0
  357. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/openscvx/symbolic/problem.py +0 -0
  358. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/openscvx/symbolic/sparsity.py +0 -0
  359. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/openscvx/symbolic/unified.py +0 -0
  360. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/openscvx/utils/__init__.py +0 -0
  361. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/openscvx/utils/cache.py +0 -0
  362. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/openscvx/utils/caching.py +0 -0
  363. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/openscvx/utils/printing.py +0 -0
  364. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/openscvx/utils/profiling.py +0 -0
  365. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/openscvx/utils/utils.py +0 -0
  366. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/openscvx.egg-info/dependency_links.txt +0 -0
  367. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/openscvx.egg-info/entry_points.txt +0 -0
  368. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/openscvx.egg-info/requires.txt +0 -0
  369. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/openscvx.egg-info/top_level.txt +0 -0
  370. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/pyproject.toml +0 -0
  371. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/scripts/gen_example_pages.py +0 -0
  372. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/scripts/gen_ref_pages.py +0 -0
  373. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/scripts/mkdocs_copy_viser_client_hook.py +0 -0
  374. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/scripts/mkdocs_seo_hook.py +0 -0
  375. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/setup.cfg +0 -0
  376. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/tests/__init__.py +0 -0
  377. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/tests/algorithms/__init__.py +0 -0
  378. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/tests/algorithms/_iteration_helpers.py +0 -0
  379. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/tests/algorithms/autotuner/__init__.py +0 -0
  380. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/tests/algorithms/autotuner/test_defaults_agreement.py +0 -0
  381. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/tests/algorithms/autotuner/test_hyper_overrides.py +0 -0
  382. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/tests/algorithms/autotuner/test_update_weights_jit.py +0 -0
  383. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/tests/algorithms/test_algorithm_state_pytree.py +0 -0
  384. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/tests/algorithms/test_iteration_fn_jit.py +0 -0
  385. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/tests/algorithms/test_iteration_fn_parity.py +0 -0
  386. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/tests/algorithms/test_make_solve_loop.py +0 -0
  387. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/tests/brachistochrone_analytical.py +0 -0
  388. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/tests/conftest.py +0 -0
  389. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/tests/e2e/__init__.py +0 -0
  390. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/tests/e2e/test_brachistochrone.py +0 -0
  391. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/tests/e2e/test_impulsive.py +0 -0
  392. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/tests/e2e/test_multishot_propagation.py +0 -0
  393. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/tests/e2e/test_solve_batched_brachistochrone.py +0 -0
  394. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/tests/e2e/test_solve_batched_cvxpy_export_errors.py +0 -0
  395. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/tests/e2e/test_solve_batched_export_roundtrip.py +0 -0
  396. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/tests/e2e/test_solve_jax_bare_brachistochrone.py +0 -0
  397. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/tests/e2e/test_solve_jax_jit_brachistochrone.py +0 -0
  398. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/tests/e2e/test_solve_jax_vmap_brachistochrone.py +0 -0
  399. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/tests/e2e/test_solve_jax_vmap_converged_no_drift.py +0 -0
  400. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/tests/fixtures/brachistochrone.json +0 -0
  401. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/tests/fixtures/brachistochrone.yaml +0 -0
  402. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/tests/hohmann_analytical.py +0 -0
  403. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/tests/integrations/__init__.py +0 -0
  404. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/tests/integrations/test_mjx.py +0 -0
  405. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/tests/integrations/test_mjx_dynamics.py +0 -0
  406. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/tests/solvers/__init__.py +0 -0
  407. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/tests/solvers/_iteration_callback_helpers.py +0 -0
  408. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/tests/solvers/test_cvxpy_callback_jit_spike.py +0 -0
  409. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/tests/solvers/test_iteration_callback_cvxpy.py +0 -0
  410. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/tests/solvers/test_iteration_callback_moreau.py +0 -0
  411. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/tests/solvers/test_iteration_callback_qpax.py +0 -0
  412. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/tests/solvers/test_iteration_callback_vmap.py +0 -0
  413. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/tests/solvers/test_moreau_ptr_solver.py +0 -0
  414. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/tests/solvers/test_qpax_ptr_solver.py +0 -0
  415. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/tests/solvers/test_subproblem_pytree.py +0 -0
  416. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/tests/symbolic/__init__.py +0 -0
  417. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/tests/symbolic/expr/__init__.py +0 -0
  418. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/tests/symbolic/expr/test_arithmetic.py +0 -0
  419. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/tests/symbolic/expr/test_array.py +0 -0
  420. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/tests/symbolic/expr/test_constraint.py +0 -0
  421. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/tests/symbolic/expr/test_expr.py +0 -0
  422. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/tests/symbolic/expr/test_lie.py +0 -0
  423. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/tests/symbolic/expr/test_linalg.py +0 -0
  424. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/tests/symbolic/expr/test_logic.py +0 -0
  425. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/tests/symbolic/expr/test_math.py +0 -0
  426. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/tests/symbolic/expr/test_node_reference.py +0 -0
  427. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/tests/symbolic/expr/test_parameters.py +0 -0
  428. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/tests/symbolic/expr/test_scaling.py +0 -0
  429. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/tests/symbolic/expr/test_spatial.py +0 -0
  430. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/tests/symbolic/expr/test_stl.py +0 -0
  431. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/tests/symbolic/expr/test_variable.py +0 -0
  432. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/tests/symbolic/expr/test_vmap.py +0 -0
  433. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/tests/symbolic/parser/__init__.py +0 -0
  434. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/tests/symbolic/parser/test_array.py +0 -0
  435. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/tests/symbolic/parser/test_constraint.py +0 -0
  436. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/tests/symbolic/parser/test_lie.py +0 -0
  437. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/tests/symbolic/parser/test_linalg.py +0 -0
  438. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/tests/symbolic/parser/test_load.py +0 -0
  439. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/tests/symbolic/parser/test_logic.py +0 -0
  440. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/tests/symbolic/parser/test_math.py +0 -0
  441. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/tests/symbolic/parser/test_parser.py +0 -0
  442. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/tests/symbolic/parser/test_spatial.py +0 -0
  443. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/tests/symbolic/parser/test_stl.py +0 -0
  444. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/tests/symbolic/parser/test_tokenizer.py +0 -0
  445. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/tests/symbolic/parser/test_vmap.py +0 -0
  446. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/tests/symbolic/test_augmentation.py +0 -0
  447. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/tests/symbolic/test_gmsr.py +0 -0
  448. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/tests/symbolic/test_hashing.py +0 -0
  449. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/tests/symbolic/test_latex_formulation.py +0 -0
  450. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/tests/symbolic/test_lower_cvxpy.py +0 -0
  451. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/tests/symbolic/test_lower_jax.py +0 -0
  452. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/tests/symbolic/test_lower_latex.py +0 -0
  453. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/tests/symbolic/test_preprocessing.py +0 -0
  454. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/tests/symbolic/test_sparsity.py +0 -0
  455. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/tests/symbolic/test_unified.py +0 -0
  456. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/tests/test_autotuning.py +0 -0
  457. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/tests/test_cvxpygen_optional.py +0 -0
  458. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/tests/test_discretization.py +0 -0
  459. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/tests/test_examples.py +0 -0
  460. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/tests/test_expert.py +0 -0
  461. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/tests/test_init.py +0 -0
  462. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/tests/test_initialize_syncs_guesses.py +0 -0
  463. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/tests/test_integrators.py +0 -0
  464. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/tests/test_loader.py +0 -0
  465. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/tests/test_optimization_results.py +0 -0
  466. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/tests/test_plotting.py +0 -0
  467. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/tests/test_post_process_batched_tau_clamp.py +0 -0
  468. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/tests/test_propagation.py +0 -0
  469. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/tests/test_results_parameters.py +0 -0
  470. {openscvx-0.5.3.dev45 → openscvx-0.5.3.dev47}/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.dev45
3
+ Version: 0.5.3.dev47
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
@@ -44,8 +44,9 @@ discretizer:
44
44
  import openscvx as ox
45
45
 
46
46
  problem = ox.Problem(
47
- dynamics, ...,
48
- discretizer={"dis_type": "ZOH"}, # or "FOH" (default)
47
+ dynamics,
48
+ ...,
49
+ discretizer={"dis_type": "ZOH"}, # or "FOH" (default)
49
50
  )
50
51
  ```
51
52
 
@@ -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
- lam_prox = cp.Parameter(nonneg = True, name='lam_prox') # Weight on the Trust Region
23
- lam_cost = cp.Parameter(nonneg=True, name='lam_cost') # Weight on the Nonlinear Cost
24
- lam_vc = cp.Parameter((params.sim.n - 1, params.sim.n_states), nonneg=True, name='lam_vc') # Weight on Virtual Control
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 = 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')
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='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
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='u')
124
- du = cp.Variable((params.sim.n, params.sim.n_controls), name='du') # Control Trust Region
125
- u_bar = cp.Parameter((params.sim.n, params.sim.n_controls), name='u_bar') # Previous SCP Control
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='A_d')
134
- B_d = cp.Parameter((params.sim.n - 1, params.sim.n_states, params.sim.n_controls), name='B_d')
135
- C_d = cp.Parameter((params.sim.n - 1, params.sim.n_states, params.sim.n_controls), name='C_d')
136
- z_d = cp.Parameter((params.sim.n - 1, params.sim.n_states), name='z_d')
137
- nu = cp.Variable((params.sim.n - 1, params.sim.n_states), name='nu') # Virtual Control
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 = 'g_' + str(idx_ncvx)))
148
- grad_g_x.append(cp.Parameter((params.sim.n, params.sim.n_states), name='grad_g_x_' + str(idx_ncvx)))
149
- grad_g_u.append(cp.Parameter((params.sim.n, params.sim.n_controls), name='grad_g_u_' + str(idx_ncvx)))
150
- nu_vb.append(cp.Variable(params.sim.n, name='nu_vb_' + str(idx_ncvx))) # Virtual Control for VB
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 += [((g[idx_ncvx][node] + grad_g_x[idx_ncvx][node] @ dx[node] + grad_g_u[idx_ncvx][node] @ du[node])) == nu_vb[idx_ncvx][node] for node in nodes]
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] == 'Fix':
182
- constr += [x_nonscaled[0][i] == params.sim.initial_state.value[i]] # Initial Boundary Conditions
183
- if params.sim.final_state.type[i] == 'Fix':
184
- constr += [x_nonscaled[-1][i] == params.sim.final_state.value[i]] # Final Boundary Conditions
185
- if params.sim.initial_state.type[i] == 'Minimize':
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] == 'Minimize':
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] == 'Maximize':
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] == 'Maximize':
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 += [x_nonscaled[i][params.sim.idx_t] - x_nonscaled[i-1][params.sim.idx_t] == x_nonscaled[i-1][params.sim.idx_t] - x_nonscaled[i-2][params.sim.idx_t] for i in range(2, params.sim.n)] # Uniform Time Step
196
-
197
- constr += [0 == la.inv(S_x) @ (x_nonscaled[i] - x_bar[i] - dx[i]) for i in range(params.sim.n)] # State Error
198
- constr += [0 == la.inv(S_u) @ (u_nonscaled[i] - u_bar[i] - du[i]) for i in range(params.sim.n)] # Control Error
199
-
200
- constr += [x_nonscaled[i] == \
201
- A_d[i-1] @ x_nonscaled[i-1] \
202
- + B_d[i-1] @ u_nonscaled[i-1] \
203
- + C_d[i-1] @ u_nonscaled[i] \
204
- + z_d[i-1] \
205
- + nu[i-1] for i in range(1, params.sim.n)] # Dynamics Constraint
206
-
207
- constr += [u_nonscaled[i] <= params.sim.max_control for i in range(params.sim.n)]
208
- constr += [u_nonscaled[i] >= params.sim.min_control for i in range(params.sim.n)] # Control Constraints
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 += [x_nonscaled[i][params.sim.idx_x_true] <= params.sim.max_state[params.sim.idx_x_true] for i in range(params.sim.n)]
211
- constr += [x_nonscaled[i][params.sim.idx_x_true] >= params.sim.min_state[params.sim.idx_x_true] for i in range(params.sim.n)] # State Constraints (Also implemented in CTCS but included for numerical stability)
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([[inv_S_x, np.zeros((S_x.shape[0], S_u.shape[1]))], [np.zeros((S_u.shape[0], S_x.shape[1])), inv_S_u]])
218
- cost += sum(lam_prox * cp.sum_squares(inv @ cp.hstack((dx[i], du[i]))) for i in range(params.sim.n)) # Trust Region Cost
219
- cost += sum(lam_vc * cp.sum(cp.abs(nu[i-1])) for i in range(1, params.sim.n)) # Virtual Control Slack
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(np.arange(params.sim.idx_y.start, params.sim.idx_y.stop), params.sim.ctcs_node_intervals):
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 += [cp.abs(x_nonscaled[i][idx] - x_nonscaled[i-1][idx]) <= params.sim.max_state[idx] for i in range(start_idx, nodes[1])]
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('solver'):
244
- cpg.generate_code(prob, solver = solver.cvx_solver, code_dir='solver', wrapper = True)
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() == 'y':
249
- cpg.generate_code(prob, solver = solver.cvx_solver, code_dir='solver', wrapper = True)
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, # (B, n_x): rank = declared+1 -> batched
102
+ x_initial=x0_batch, # (B, n_x): rank = declared+1 -> batched
105
103
  parameters={
106
- "gate_center": centers, # (B, 3) vs declared (3,) -> batched
107
- "gate_radius": 0.5, # declared shape -> shared
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}, # (B,) is also w's declared shape...
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
- # B argument; solve_batched infers it from the leading-axis lengths.
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
@@ -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 # custom: virtual control alone
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 # Symbolic dx/dt = f(x, u)
75
- states: List[State] # All state variables (including augmented)
76
- controls: List[Control] # All control variables (including virtual)
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 # User-defined parameters
79
- N: int # Discretization nodes
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 # f, A=df/dx, B=df/du
92
- dynamics_prop: Dynamics # For forward propagation
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 # Aggregates all states into one vector
100
- u_unified: UnifiedControl # Aggregates all controls into one vector
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 # x, u, dx, du, nu, etc.
104
- cvxpy_params: dict # User parameters as cp.Parameter
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] # func, grad_g_x, grad_g_u
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] # Handled via dynamics augmentation
128
+ ctcs: List[CTCS] # Handled via dynamics augmentation
129
129
  ```
130
130
 
131
131
  ### CVXPy-Lowered Constraints
@@ -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,) # Sum of all state dimensions
84
- u_unified.shape = (n_u,) # Sum of all control dimensions
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,) # position(2) + velocity(1) + time(1)
92
- u_unified.shape = (2,) # theta(1) + _time_dilation(1)
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, # State derivative function
120
- A=jacfwd(dyn_fn, argnums=0), # Jacobian df/dx
121
- B=jacfwd(dyn_fn, argnums=1), # Jacobian df/du
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, # Constraint function
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, # Node indices where constraint applies
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
- self.dynamics_augmented.f,
244
- in_axes=(0, 0, 0, None)
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) # scalar
376
- grad_X = constraint.grad_g_X(X, U, params) # (N, n_x) - sparse, mostly zeros
377
- grad_U = constraint.grad_g_U(X, U, params) # (N, n_u) - sparse, mostly zeros
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] # Shape: (N-1, n_x) - States at interval starts
389
- u = u[: x.shape[0]] # Shape: (N-1, n_u) - Controls (includes time dilation)
390
- nodes = jnp.arange(0, N-1) # Shape: (N-1,) - Node indices
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] # Shape: (N-1,) - Time dilation values
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) # Shape: (N-1, n_x, n_x)
399
- dfdu_veh = B(x, u[:, :-1], nodes, params) # Shape: (N-1, n_x, n_u-1)
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) # Time dilation derivative = 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.
@@ -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.