openscvx 0.5.3.dev32__tar.gz → 0.5.3.dev34__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 (433) hide show
  1. {openscvx-0.5.3.dev32/openscvx.egg-info → openscvx-0.5.3.dev34}/PKG-INFO +1 -1
  2. openscvx-0.5.3.dev34/examples/aircraft/dynamic_soaring.py +333 -0
  3. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/openscvx/_version.py +3 -3
  4. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/openscvx/algorithms/optimization_results.py +18 -2
  5. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/openscvx/problem.py +61 -10
  6. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34/openscvx.egg-info}/PKG-INFO +1 -1
  7. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/openscvx.egg-info/SOURCES.txt +2 -0
  8. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/openscvx.egg-info/scm_file_list.json +2 -0
  9. openscvx-0.5.3.dev34/openscvx.egg-info/scm_version.json +8 -0
  10. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/tests/test_optimization_results.py +27 -0
  11. openscvx-0.5.3.dev34/tests/test_results_parameters.py +93 -0
  12. openscvx-0.5.3.dev32/openscvx.egg-info/scm_version.json +0 -8
  13. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/.github/assets/logo.svg +0 -0
  14. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/.github/release-drafter.yml +0 -0
  15. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/.github/workflows/_docs.yml +0 -0
  16. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/.github/workflows/branch-name.yml +0 -0
  17. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/.github/workflows/docs.yml +0 -0
  18. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/.github/workflows/lint.yml +0 -0
  19. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/.github/workflows/nightly.yml +0 -0
  20. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/.github/workflows/release-drafter.yml +0 -0
  21. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/.github/workflows/release.yml +0 -0
  22. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/.github/workflows/tests-integration.yml +0 -0
  23. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/.github/workflows/tests-unit.yml +0 -0
  24. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/.gitignore +0 -0
  25. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/.gitmodules +0 -0
  26. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/CONTRIBUTING.md +0 -0
  27. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/LICENSE +0 -0
  28. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/README.md +0 -0
  29. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/docs/Foundations/constraint_reformulation.md +0 -0
  30. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/docs/Foundations/control_parameterization.md +0 -0
  31. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/docs/Foundations/discretization.md +0 -0
  32. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/docs/Foundations/ocp.md +0 -0
  33. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/docs/Foundations/scvx.md +0 -0
  34. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/docs/Foundations/time_dilation.md +0 -0
  35. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/docs/UnderTheHood/batching_jit_grad.md +0 -0
  36. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/docs/UnderTheHood/custom_algorithms_autotuners.md +0 -0
  37. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/docs/UnderTheHood/lowering_architecture.md +0 -0
  38. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/docs/UnderTheHood/vectorization_and_vmapping.md +0 -0
  39. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/docs/UsersGuide/00_introduction.md +0 -0
  40. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/docs/UsersGuide/01_hello_world_brachistochrone.md +0 -0
  41. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/docs/UsersGuide/02_drone_racing_constraints.md +0 -0
  42. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/docs/UsersGuide/03_obstacle_avoidance_vmap.md +0 -0
  43. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/docs/UsersGuide/04_viewpoint_constraints.md +0 -0
  44. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/docs/UsersGuide/05_visualization.md +0 -0
  45. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/docs/UsersGuide/06_logic.md +0 -0
  46. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/docs/UsersGuide/07_lie.md +0 -0
  47. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/docs/UsersGuide/08_mpcc.md +0 -0
  48. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/docs/UsersGuide/09_mjx_dynamics.md +0 -0
  49. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/docs/assets/favicon.png +0 -0
  50. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/docs/assets/images/ct-scvx_dark.png +0 -0
  51. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/docs/assets/images/ct-scvx_light.png +0 -0
  52. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/docs/assets/images/ctcs_dark.png +0 -0
  53. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/docs/assets/images/ctcs_light.png +0 -0
  54. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/docs/assets/images/problem_class_dark.png +0 -0
  55. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/docs/assets/images/problem_class_light.png +0 -0
  56. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/docs/assets/logo.svg +0 -0
  57. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/docs/assets/openscvx_logo_square.png +0 -0
  58. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/docs/assets/viser-client/index.html +0 -0
  59. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/docs/assets/viser-recordings/drone_racing.viser +0 -0
  60. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/docs/assets/viser-recordings/franka_fr3v2_pick_place.viser +0 -0
  61. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/docs/citation.md +0 -0
  62. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/docs/examples.md +0 -0
  63. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/docs/index.md +0 -0
  64. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/docs/javascripts/mathjax.js +0 -0
  65. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/docs/versions.json +0 -0
  66. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/examples/_viser_embed_export.py +0 -0
  67. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/examples/abstract/brachistochrone.py +0 -0
  68. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/examples/abstract/brachistochrone_batched.py +0 -0
  69. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/examples/abstract/flappy_bird.py +0 -0
  70. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/examples/abstract/hypersensitive.py +0 -0
  71. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/examples/abstract/impulsive.py +0 -0
  72. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/examples/abstract/stl_integer_variable.py +0 -0
  73. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/examples/abstract/stl_or.py +0 -0
  74. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/examples/aircraft/supersonic_time_to_climb.py +0 -0
  75. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/examples/animations/7_dof_arm.py +0 -0
  76. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/examples/animations/_camera.py +0 -0
  77. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/examples/animations/_render.py +0 -0
  78. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/examples/animations/_sensor_view.py +0 -0
  79. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/examples/animations/dr_vp_polytope.py +0 -0
  80. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/examples/animations/franka_fr3v2_pick_place.py +0 -0
  81. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/examples/animations/logo.py +0 -0
  82. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/examples/animations/obstacle_avoidance_vmap.py +0 -0
  83. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/examples/arm/3_dof_arm.py +0 -0
  84. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/examples/arm/7_dof_arm.py +0 -0
  85. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/examples/arm/7_dof_arm_collision.py +0 -0
  86. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/examples/arm/7_dof_arm_vp.py +0 -0
  87. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/examples/arm/franka_fr3v2_pick_place.py +0 -0
  88. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/examples/arm/franka_fr3v2_viewplanning.py +0 -0
  89. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/examples/arm/franka_fr3v2_viewplanning_nodal.py +0 -0
  90. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/examples/car/dubins_car.py +0 -0
  91. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/examples/car/dubins_car_disjoint.py +0 -0
  92. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/examples/car/dubins_car_obstacle_conditional.py +0 -0
  93. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/examples/car/dubins_car_obstacle_stl.py +0 -0
  94. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/examples/car/dubins_car_stl_or.py +0 -0
  95. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/examples/car/dubins_car_waypoint_stl.py +0 -0
  96. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/examples/double_integrator/_plotting.py +0 -0
  97. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/examples/double_integrator/moving_safe_zones.py +0 -0
  98. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/examples/drone/2d_obstacle_avoidance_batched_ic.py +0 -0
  99. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/examples/drone/cinema_vp.py +0 -0
  100. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/examples/drone/cinema_vp_nodal.py +0 -0
  101. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/examples/drone/dr_double_integrator.py +0 -0
  102. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/examples/drone/dr_vp.py +0 -0
  103. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/examples/drone/dr_vp_nodal.py +0 -0
  104. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/examples/drone/dr_vp_polytope.py +0 -0
  105. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/examples/drone/drone_racing.py +0 -0
  106. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/examples/drone/drone_racing_batched_gates.py +0 -0
  107. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/examples/drone/logo.py +0 -0
  108. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/examples/drone/logo_utils/acl_logo.svg +0 -0
  109. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/examples/drone/logo_utils/openscvx_logo_single.svg +0 -0
  110. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/examples/drone/logo_utils/quadrotor_mesh.py +0 -0
  111. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/examples/drone/logo_utils/svg_path_utils.py +0 -0
  112. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/examples/drone/multi_agent_circle_swap.py +0 -0
  113. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/examples/drone/obstacle_avoidance.py +0 -0
  114. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/examples/drone/obstacle_avoidance_nodal.py +0 -0
  115. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/examples/drone/obstacle_avoidance_vmap.py +0 -0
  116. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/examples/drone/obstacle_avoidance_vmap_2d.py +0 -0
  117. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/examples/drone/openscvx_logo.py +0 -0
  118. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/examples/frax/panda_frax.py +0 -0
  119. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/examples/frax/panda_frax_pick_place.py +0 -0
  120. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/examples/frax/panda_frax_viewplanning.py +0 -0
  121. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/examples/frax/panda_frax_waypoint.py +0 -0
  122. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/examples/mjx/cartpole_mjx.py +0 -0
  123. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/examples/mjx/double_cartpole_mjx.py +0 -0
  124. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/examples/mjx/skydio_x2_mjx.py +0 -0
  125. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/examples/mjx/triple_cartpole_3d_mjx.py +0 -0
  126. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/examples/mjx/triple_cartpole_game.py +0 -0
  127. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/examples/mjx/triple_cartpole_mjx.py +0 -0
  128. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/examples/mpc/double_integrator_discrete.py +0 -0
  129. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/examples/mpc/double_integrator_drone_racing.py +0 -0
  130. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/examples/mpc/dubins_car_circle_analytical.py +0 -0
  131. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/examples/mpc/dubins_car_circle_discrete.py +0 -0
  132. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/examples/mpc/realtime_double_integrator_drone_racing.py +0 -0
  133. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/examples/plotting.py +0 -0
  134. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/examples/plotting_viser.py +0 -0
  135. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/examples/realtime/3DoF_pdg_realtime.py +0 -0
  136. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/examples/realtime/6DoF_pdg_realtime.py +0 -0
  137. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/examples/realtime/base_problems/3DoF_pdg_realtime_base.py +0 -0
  138. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/examples/realtime/base_problems/6DoF_pdg_realtime_base.py +0 -0
  139. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/examples/realtime/base_problems/cinema_vp_realtime_base.py +0 -0
  140. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/examples/realtime/base_problems/drone_racing_realtime_base.py +0 -0
  141. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/examples/realtime/base_problems/dubins_car_realtime_base.py +0 -0
  142. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/examples/realtime/base_problems/obstacle_avoidance_realtime_base.py +0 -0
  143. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/examples/realtime/cinema_vp_realtime.py +0 -0
  144. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/examples/realtime/drone_racing_realtime.py +0 -0
  145. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/examples/realtime/dubins_car_realtime.py +0 -0
  146. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/examples/realtime/obstacle_avoidance_realtime.py +0 -0
  147. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/examples/rocket/3DoF_pdg.py +0 -0
  148. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/examples/rocket/6DoF_pdg.py +0 -0
  149. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/examples/rocket/6DoF_pdg_batched_ic.py +0 -0
  150. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/examples/rocket/ascent_launch_vehicle.py +0 -0
  151. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/examples/spacecraft/halo_orbit.py +0 -0
  152. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/examples/spacecraft/hohmann_transfer.py +0 -0
  153. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/examples/spacecraft/let_transfer.py +0 -0
  154. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/examples/spacecraft/proxops_cw.py +0 -0
  155. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/examples/spacecraft/relative_loitering.py +0 -0
  156. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/figures/ctlos_cine.gif +0 -0
  157. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/figures/ctlos_dr.gif +0 -0
  158. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/figures/dtlos_cine.gif +0 -0
  159. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/figures/dtlos_dr.gif +0 -0
  160. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/figures/openscvx_logo.svg +0 -0
  161. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/figures/openscvx_logo_square.png +0 -0
  162. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/figures/oscvx_structure_full_dark.svg +0 -0
  163. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/figures/video_preview.png +0 -0
  164. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/material/__init__.py +0 -0
  165. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/material/overrides/assets/stylesheets/custom.css +0 -0
  166. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/material/overrides/assets/stylesheets/home-dropin.css +0 -0
  167. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/material/overrides/assets/stylesheets/home-hero.css +0 -0
  168. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/material/overrides/assets/stylesheets/home-viser.css +0 -0
  169. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/material/overrides/home.html +0 -0
  170. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/material/overrides/main.html +0 -0
  171. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/material/overrides/partials/home-diagram.html +0 -0
  172. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/material/overrides/partials/home-dropin-banner.html +0 -0
  173. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/material/overrides/partials/home-hero.html +0 -0
  174. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/material/overrides/partials/home-pipeline.html +0 -0
  175. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/material/overrides/partials/home-viser-strip.html +0 -0
  176. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/mkdocs.yml +0 -0
  177. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/openscvx/__init__.py +0 -0
  178. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/openscvx/__main__.py +0 -0
  179. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/openscvx/algorithms/__init__.py +0 -0
  180. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/openscvx/algorithms/autotuner/__init__.py +0 -0
  181. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/openscvx/algorithms/autotuner/acceptance_ratio.py +0 -0
  182. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/openscvx/algorithms/autotuner/adaptive_proximal_weight.py +0 -0
  183. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/openscvx/algorithms/autotuner/augmented_lagrangian.py +0 -0
  184. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/openscvx/algorithms/autotuner/base.py +0 -0
  185. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/openscvx/algorithms/autotuner/constant_proximal_weight.py +0 -0
  186. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/openscvx/algorithms/autotuner/ramp_proximal_weight.py +0 -0
  187. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/openscvx/algorithms/base.py +0 -0
  188. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/openscvx/algorithms/history.py +0 -0
  189. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/openscvx/algorithms/hyperparams.py +0 -0
  190. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/openscvx/algorithms/loop.py +0 -0
  191. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/openscvx/algorithms/penalty.py +0 -0
  192. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/openscvx/algorithms/scvx/__init__.py +0 -0
  193. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/openscvx/algorithms/scvx/iteration.py +0 -0
  194. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/openscvx/algorithms/scvx/penalized_trust_region.py +0 -0
  195. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/openscvx/algorithms/state.py +0 -0
  196. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/openscvx/algorithms/weights.py +0 -0
  197. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/openscvx/config.py +0 -0
  198. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/openscvx/discretization/__init__.py +0 -0
  199. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/openscvx/discretization/base.py +0 -0
  200. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/openscvx/discretization/discretize_linearize.py +0 -0
  201. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/openscvx/discretization/linearize_discretize.py +0 -0
  202. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/openscvx/discretization/linearize_discretize_sparse.py +0 -0
  203. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/openscvx/discretization/sparse_utils/__init__.py +0 -0
  204. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/openscvx/discretization/sparse_utils/bcoo_helpers.py +0 -0
  205. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/openscvx/discretization/sparse_utils/sparse_jacobian.py +0 -0
  206. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/openscvx/expert/__init__.py +0 -0
  207. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/openscvx/expert/byof.py +0 -0
  208. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/openscvx/expert/lowering.py +0 -0
  209. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/openscvx/expert/validation.py +0 -0
  210. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/openscvx/init/__init__.py +0 -0
  211. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/openscvx/init/interpolation.py +0 -0
  212. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/openscvx/init/inverse_kinematics.py +0 -0
  213. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/openscvx/integrations/__init__.py +0 -0
  214. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/openscvx/integrations/_utils.py +0 -0
  215. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/openscvx/integrations/base.py +0 -0
  216. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/openscvx/integrations/frax.py +0 -0
  217. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/openscvx/integrations/menagerie.py +0 -0
  218. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/openscvx/integrations/mjx.py +0 -0
  219. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/openscvx/integrators/__init__.py +0 -0
  220. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/openscvx/integrators/diffrax.py +0 -0
  221. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/openscvx/integrators/runge_kutta.py +0 -0
  222. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/openscvx/loader.py +0 -0
  223. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/openscvx/lowered/__init__.py +0 -0
  224. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/openscvx/lowered/cvxpy_constraints.py +0 -0
  225. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/openscvx/lowered/cvxpy_variables.py +0 -0
  226. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/openscvx/lowered/dynamics.py +0 -0
  227. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/openscvx/lowered/jax_constraints.py +0 -0
  228. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/openscvx/lowered/parameters.py +0 -0
  229. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/openscvx/lowered/problem.py +0 -0
  230. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/openscvx/lowered/unified.py +0 -0
  231. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/openscvx/plotting/__init__.py +0 -0
  232. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/openscvx/plotting/plotting.py +0 -0
  233. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/openscvx/plotting/publication.py +0 -0
  234. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/openscvx/plotting/scp_iteration.py +0 -0
  235. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/openscvx/plotting/viser/__init__.py +0 -0
  236. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/openscvx/plotting/viser/animated.py +0 -0
  237. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/openscvx/plotting/viser/coordinates.py +0 -0
  238. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/openscvx/plotting/viser/orbits.py +0 -0
  239. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/openscvx/plotting/viser/plotly_integration.py +0 -0
  240. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/openscvx/plotting/viser/primitives.py +0 -0
  241. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/openscvx/plotting/viser/scp.py +0 -0
  242. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/openscvx/plotting/viser/server.py +0 -0
  243. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/openscvx/propagation/__init__.py +0 -0
  244. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/openscvx/propagation/post_processing.py +0 -0
  245. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/openscvx/propagation/propagation.py +0 -0
  246. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/openscvx/solvers/__init__.py +0 -0
  247. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/openscvx/solvers/base.py +0 -0
  248. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/openscvx/solvers/cones.py +0 -0
  249. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/openscvx/solvers/cvxpy_ptr_solver.py +0 -0
  250. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/openscvx/solvers/moreau_ptr_solver.py +0 -0
  251. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/openscvx/solvers/ptr_solver.py +0 -0
  252. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/openscvx/solvers/qpax_ptr_solver.py +0 -0
  253. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/openscvx/symbolic/__init__.py +0 -0
  254. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/openscvx/symbolic/affine.py +0 -0
  255. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/openscvx/symbolic/augmentation.py +0 -0
  256. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/openscvx/symbolic/builder.py +0 -0
  257. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/openscvx/symbolic/canonicalize.py +0 -0
  258. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/openscvx/symbolic/constraint_set.py +0 -0
  259. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/openscvx/symbolic/expr/__init__.py +0 -0
  260. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/openscvx/symbolic/expr/arithmetic.py +0 -0
  261. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/openscvx/symbolic/expr/array.py +0 -0
  262. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/openscvx/symbolic/expr/constraint.py +0 -0
  263. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/openscvx/symbolic/expr/control.py +0 -0
  264. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/openscvx/symbolic/expr/expr.py +0 -0
  265. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/openscvx/symbolic/expr/lie/__init__.py +0 -0
  266. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/openscvx/symbolic/expr/lie/adjoint.py +0 -0
  267. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/openscvx/symbolic/expr/lie/se3.py +0 -0
  268. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/openscvx/symbolic/expr/lie/so3.py +0 -0
  269. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/openscvx/symbolic/expr/linalg.py +0 -0
  270. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/openscvx/symbolic/expr/logic.py +0 -0
  271. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/openscvx/symbolic/expr/math.py +0 -0
  272. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/openscvx/symbolic/expr/parameter.py +0 -0
  273. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/openscvx/symbolic/expr/spatial.py +0 -0
  274. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/openscvx/symbolic/expr/state.py +0 -0
  275. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/openscvx/symbolic/expr/stl.py +0 -0
  276. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/openscvx/symbolic/expr/stljax.py +0 -0
  277. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/openscvx/symbolic/expr/time.py +0 -0
  278. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/openscvx/symbolic/expr/variable.py +0 -0
  279. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/openscvx/symbolic/expr/vmap.py +0 -0
  280. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/openscvx/symbolic/hashing.py +0 -0
  281. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/openscvx/symbolic/lower.py +0 -0
  282. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/openscvx/symbolic/lowerers/__init__.py +0 -0
  283. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/openscvx/symbolic/lowerers/cvxpy/__init__.py +0 -0
  284. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/openscvx/symbolic/lowerers/cvxpy/_lowerer.py +0 -0
  285. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/openscvx/symbolic/lowerers/cvxpy/_registry.py +0 -0
  286. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/openscvx/symbolic/lowerers/cvxpy/arithmetic.py +0 -0
  287. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/openscvx/symbolic/lowerers/cvxpy/array.py +0 -0
  288. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/openscvx/symbolic/lowerers/cvxpy/constraint.py +0 -0
  289. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/openscvx/symbolic/lowerers/cvxpy/control.py +0 -0
  290. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/openscvx/symbolic/lowerers/cvxpy/expr.py +0 -0
  291. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/openscvx/symbolic/lowerers/cvxpy/linalg.py +0 -0
  292. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/openscvx/symbolic/lowerers/cvxpy/logic.py +0 -0
  293. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/openscvx/symbolic/lowerers/cvxpy/math.py +0 -0
  294. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/openscvx/symbolic/lowerers/cvxpy/state.py +0 -0
  295. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/openscvx/symbolic/lowerers/jax/__init__.py +0 -0
  296. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/openscvx/symbolic/lowerers/jax/_lowerer.py +0 -0
  297. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/openscvx/symbolic/lowerers/jax/_registry.py +0 -0
  298. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/openscvx/symbolic/lowerers/jax/arithmetic.py +0 -0
  299. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/openscvx/symbolic/lowerers/jax/array.py +0 -0
  300. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/openscvx/symbolic/lowerers/jax/constraint.py +0 -0
  301. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/openscvx/symbolic/lowerers/jax/control.py +0 -0
  302. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/openscvx/symbolic/lowerers/jax/expr.py +0 -0
  303. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/openscvx/symbolic/lowerers/jax/lie.py +0 -0
  304. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/openscvx/symbolic/lowerers/jax/linalg.py +0 -0
  305. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/openscvx/symbolic/lowerers/jax/logic.py +0 -0
  306. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/openscvx/symbolic/lowerers/jax/math.py +0 -0
  307. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/openscvx/symbolic/lowerers/jax/spatial.py +0 -0
  308. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/openscvx/symbolic/lowerers/jax/state.py +0 -0
  309. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/openscvx/symbolic/lowerers/jax/stl.py +0 -0
  310. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/openscvx/symbolic/lowerers/jax/stljax.py +0 -0
  311. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/openscvx/symbolic/lowerers/jax/vmap.py +0 -0
  312. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/openscvx/symbolic/parser/__init__.py +0 -0
  313. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/openscvx/symbolic/parser/_registry.py +0 -0
  314. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/openscvx/symbolic/parser/array.py +0 -0
  315. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/openscvx/symbolic/parser/constraint.py +0 -0
  316. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/openscvx/symbolic/parser/lie.py +0 -0
  317. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/openscvx/symbolic/parser/linalg.py +0 -0
  318. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/openscvx/symbolic/parser/logic.py +0 -0
  319. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/openscvx/symbolic/parser/math.py +0 -0
  320. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/openscvx/symbolic/parser/parser.py +0 -0
  321. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/openscvx/symbolic/parser/spatial.py +0 -0
  322. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/openscvx/symbolic/parser/stl.py +0 -0
  323. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/openscvx/symbolic/parser/stljax.py +0 -0
  324. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/openscvx/symbolic/parser/tokenizer.py +0 -0
  325. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/openscvx/symbolic/preprocessing.py +0 -0
  326. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/openscvx/symbolic/problem.py +0 -0
  327. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/openscvx/symbolic/sparsity.py +0 -0
  328. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/openscvx/symbolic/unified.py +0 -0
  329. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/openscvx/utils/__init__.py +0 -0
  330. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/openscvx/utils/cache.py +0 -0
  331. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/openscvx/utils/caching.py +0 -0
  332. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/openscvx/utils/printing.py +0 -0
  333. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/openscvx/utils/profiling.py +0 -0
  334. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/openscvx/utils/utils.py +0 -0
  335. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/openscvx.egg-info/dependency_links.txt +0 -0
  336. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/openscvx.egg-info/entry_points.txt +0 -0
  337. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/openscvx.egg-info/requires.txt +0 -0
  338. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/openscvx.egg-info/top_level.txt +0 -0
  339. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/pyproject.toml +0 -0
  340. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/scripts/gen_example_pages.py +0 -0
  341. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/scripts/gen_ref_pages.py +0 -0
  342. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/scripts/mkdocs_copy_viser_client_hook.py +0 -0
  343. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/setup.cfg +0 -0
  344. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/tests/__init__.py +0 -0
  345. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/tests/_marks.py +0 -0
  346. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/tests/algorithms/__init__.py +0 -0
  347. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/tests/algorithms/_iteration_helpers.py +0 -0
  348. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/tests/algorithms/autotuner/__init__.py +0 -0
  349. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/tests/algorithms/autotuner/test_defaults_agreement.py +0 -0
  350. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/tests/algorithms/autotuner/test_hyper_overrides.py +0 -0
  351. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/tests/algorithms/autotuner/test_update_weights_jit.py +0 -0
  352. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/tests/algorithms/test_algorithm_state_pytree.py +0 -0
  353. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/tests/algorithms/test_iteration_fn_jit.py +0 -0
  354. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/tests/algorithms/test_iteration_fn_parity.py +0 -0
  355. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/tests/algorithms/test_make_solve_loop.py +0 -0
  356. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/tests/brachistochrone_analytical.py +0 -0
  357. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/tests/conftest.py +0 -0
  358. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/tests/expr/__init__.py +0 -0
  359. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/tests/expr/test_gmsr.py +0 -0
  360. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/tests/fixtures/brachistochrone.json +0 -0
  361. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/tests/fixtures/brachistochrone.yaml +0 -0
  362. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/tests/hohmann_analytical.py +0 -0
  363. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/tests/integrations/__init__.py +0 -0
  364. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/tests/integrations/test_mjx.py +0 -0
  365. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/tests/integrations/test_mjx_dynamics.py +0 -0
  366. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/tests/solvers/__init__.py +0 -0
  367. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/tests/solvers/_iteration_callback_helpers.py +0 -0
  368. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/tests/solvers/test_cvxpy_callback_jit_spike.py +0 -0
  369. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/tests/solvers/test_iteration_callback_cvxpy.py +0 -0
  370. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/tests/solvers/test_iteration_callback_moreau.py +0 -0
  371. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/tests/solvers/test_iteration_callback_qpax.py +0 -0
  372. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/tests/solvers/test_iteration_callback_vmap.py +0 -0
  373. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/tests/solvers/test_moreau_ptr_solver.py +0 -0
  374. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/tests/solvers/test_qpax_ptr_solver.py +0 -0
  375. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/tests/solvers/test_subproblem_pytree.py +0 -0
  376. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/tests/symbolic/__init__.py +0 -0
  377. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/tests/symbolic/expr/__init__.py +0 -0
  378. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/tests/symbolic/expr/test_arithmetic.py +0 -0
  379. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/tests/symbolic/expr/test_array.py +0 -0
  380. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/tests/symbolic/expr/test_constraint.py +0 -0
  381. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/tests/symbolic/expr/test_expr.py +0 -0
  382. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/tests/symbolic/expr/test_lie.py +0 -0
  383. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/tests/symbolic/expr/test_linalg.py +0 -0
  384. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/tests/symbolic/expr/test_logic.py +0 -0
  385. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/tests/symbolic/expr/test_math.py +0 -0
  386. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/tests/symbolic/expr/test_node_reference.py +0 -0
  387. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/tests/symbolic/expr/test_parameters.py +0 -0
  388. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/tests/symbolic/expr/test_scaling.py +0 -0
  389. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/tests/symbolic/expr/test_spatial.py +0 -0
  390. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/tests/symbolic/expr/test_stl.py +0 -0
  391. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/tests/symbolic/expr/test_variable.py +0 -0
  392. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/tests/symbolic/expr/test_vmap.py +0 -0
  393. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/tests/symbolic/parser/__init__.py +0 -0
  394. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/tests/symbolic/parser/test_array.py +0 -0
  395. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/tests/symbolic/parser/test_constraint.py +0 -0
  396. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/tests/symbolic/parser/test_lie.py +0 -0
  397. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/tests/symbolic/parser/test_linalg.py +0 -0
  398. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/tests/symbolic/parser/test_load.py +0 -0
  399. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/tests/symbolic/parser/test_logic.py +0 -0
  400. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/tests/symbolic/parser/test_math.py +0 -0
  401. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/tests/symbolic/parser/test_parser.py +0 -0
  402. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/tests/symbolic/parser/test_spatial.py +0 -0
  403. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/tests/symbolic/parser/test_stl.py +0 -0
  404. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/tests/symbolic/parser/test_tokenizer.py +0 -0
  405. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/tests/symbolic/parser/test_vmap.py +0 -0
  406. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/tests/symbolic/test_augmentation.py +0 -0
  407. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/tests/symbolic/test_hashing.py +0 -0
  408. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/tests/symbolic/test_lower_cvxpy.py +0 -0
  409. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/tests/symbolic/test_lower_jax.py +0 -0
  410. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/tests/symbolic/test_preprocessing.py +0 -0
  411. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/tests/symbolic/test_sparsity.py +0 -0
  412. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/tests/symbolic/test_unified.py +0 -0
  413. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/tests/test_autotuning.py +0 -0
  414. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/tests/test_brachistochrone.py +0 -0
  415. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/tests/test_cvxpygen_optional.py +0 -0
  416. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/tests/test_discretization.py +0 -0
  417. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/tests/test_examples.py +0 -0
  418. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/tests/test_expert.py +0 -0
  419. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/tests/test_impulsive.py +0 -0
  420. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/tests/test_init.py +0 -0
  421. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/tests/test_integrators.py +0 -0
  422. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/tests/test_loader.py +0 -0
  423. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/tests/test_multishot_propagation.py +0 -0
  424. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/tests/test_plotting.py +0 -0
  425. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/tests/test_propagation.py +0 -0
  426. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/tests/test_solve_batched_brachistochrone.py +0 -0
  427. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/tests/test_solve_batched_cvxpy_export_errors.py +0 -0
  428. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/tests/test_solve_batched_export_roundtrip.py +0 -0
  429. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/tests/test_solve_batched_inference.py +0 -0
  430. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/tests/test_solve_jax_bare_brachistochrone.py +0 -0
  431. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/tests/test_solve_jax_jit_brachistochrone.py +0 -0
  432. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/tests/test_solve_jax_vmap_brachistochrone.py +0 -0
  433. {openscvx-0.5.3.dev32 → openscvx-0.5.3.dev34}/tests/test_solve_jax_vmap_converged_no_drift.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: openscvx
3
- Version: 0.5.3.dev32
3
+ Version: 0.5.3.dev34
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,333 @@
1
+ """Minimum wind-gradient dynamic soaring of a glider (Zhao 2004).
2
+
3
+ The dynamic soaring benchmark from Zhao, *"Optimal Pattern of Glider Dynamic
4
+ Soaring,"* Optimal Control Applications and Methods, Vol. 25, 2004, pp. 67-89,
5
+ reproduced in the GPOPS-II user's guide. A glider flies one closed loop through
6
+ a linear wind shear, extracting enough energy from the gradient to return to
7
+ its initial airspeed, flight-path angle, and (heading - 2 pi). The objective is
8
+ the *smallest* wind-gradient slope ``beta`` for which such an energy-neutral
9
+ loop exists.
10
+
11
+ Point-mass dynamics over a flat Earth with horizontal wind ``W_x = beta h``
12
+ (state ``[x, y, h, v, gamma, psi]`` = position, airspeed, flight-path angle,
13
+ heading; controls ``C_L`` = lift coefficient and ``phi`` = bank angle):
14
+
15
+ x_dot = v cos(gamma) sin(psi) + beta h
16
+ y_dot = v cos(gamma) cos(psi)
17
+ h_dot = v sin(gamma)
18
+ v_dot = -(rho S / 2 m)(CD0 + K C_L^2) v^2 - g sin(gamma) - W sin(psi) cos(gamma)
19
+ gamma_dot = (rho S / 2 m) C_L v cos(phi) - g cos(gamma) / v + W sin(psi) sin(gamma) / v
20
+ psi_dot = ((rho S / 2 m) C_L v sin(phi) - W cos(psi) / v) / cos(gamma)
21
+
22
+ with wind-shear rate ``W = dW_x/dt = beta v sin(gamma)``. The load factor
23
+ ``n = (rho S / 2 m g) C_L v^2`` is limited to ``[-2, 5]`` along the whole loop.
24
+
25
+ Three GPOPS features map onto OpenSCvx as follows:
26
+
27
+ - The free static parameter ``beta`` becomes a state with zero dynamics, so a
28
+ single optimized value is shared by every node. Its final value carries a
29
+ ``Minimize`` boundary condition — the Mayer objective.
30
+ - The periodicity events ``v_f = v_0``, ``gamma_f = gamma_0``, and
31
+ ``psi_f = psi_0 - 2 pi`` become cross-node equality constraints tying node
32
+ ``N-1`` to node 0. They are affine, so they are marked ``.convex()`` and
33
+ enforced exactly by the subproblem solver.
34
+ - The load-factor path constraint becomes a CTCS constraint, satisfied in
35
+ continuous time between nodes — which is why far fewer nodes are needed
36
+ here than GPOPS' collocation mesh.
37
+
38
+ The problem is nonconvex with several locally optimal loops; from the guide's
39
+ initial guess the SCP converges to ``beta ~ 0.069 1/s`` with a ~20 s period, a
40
+ slightly different basin than the IPOPT solution pictured in the guide. The
41
+ solution rides the ``n = 5`` load-factor ceiling through the high-speed bottom
42
+ turn, and forward propagation confirms the loop is periodic in continuous time.
43
+
44
+ Units are English (ft, s, slug), matching the reference.
45
+ """
46
+
47
+ import os
48
+ import sys
49
+
50
+ import numpy as np
51
+ import plotly.graph_objects as go
52
+ from plotly.subplots import make_subplots
53
+
54
+ current_dir = os.path.dirname(os.path.abspath(__file__))
55
+ grandparent_dir = os.path.dirname(os.path.dirname(current_dir))
56
+ if grandparent_dir not in sys.path:
57
+ sys.path.append(grandparent_dir)
58
+
59
+ import openscvx as ox
60
+ from openscvx.plotting import plot_controls, plot_scp_iterations, plot_states
61
+
62
+ # ---------------------------------------------------------------------------
63
+ # Physical constants (English units, Zhao 2004)
64
+ # ---------------------------------------------------------------------------
65
+ rho = 0.002378 # air density (slug/ft^3)
66
+ CD0 = 0.00873 # zero-lift drag coefficient
67
+ K = 0.045 # induced drag factor
68
+ g = 32.2 # gravitational acceleration (ft/s^2)
69
+ m = 5.6 # glider mass (slug)
70
+ S = 45.09703 # wing reference area (ft^2)
71
+
72
+ load_min, load_max = -2.0, 5.0 # load factor limits
73
+ beta_min, beta_max = 0.005, 0.15 # wind-gradient slope bounds (1/s)
74
+
75
+ n = 20 # discretization nodes — CTCS keeps the path constraint tight between them
76
+ tf_guess = 24.0 # initial guess for the (free) loop period
77
+
78
+ # ---------------------------------------------------------------------------
79
+ # States — the guess is one circular loop through the shear layer: climbing
80
+ # into the wind, diving out of it.
81
+ # ---------------------------------------------------------------------------
82
+ _t = np.linspace(0.0, tf_guess, n)
83
+ _th = 2 * np.pi * _t / tf_guess
84
+
85
+ position = ox.State("position", shape=(3,)) # [x, y, h] (ft)
86
+ position.min = [-1000.0, -1000.0, 0.0]
87
+ position.max = [1000.0, 1000.0, 1000.0]
88
+ position.initial = [0.0, 0.0, 0.0]
89
+ position.final = [0.0, 0.0, 0.0]
90
+ position.guess = np.stack(
91
+ [500 * np.cos(_th) - 500, 300 * np.sin(_th), 400 - 400 * np.cos(_th)], axis=1
92
+ )
93
+
94
+ v = ox.State("speed", shape=(1,)) # airspeed (ft/s)
95
+ v.min, v.max = [10.0], [350.0]
96
+ v.initial, v.final = [ox.Free(200.0)], [ox.Free(200.0)]
97
+ v.guess = (80 * (1.5 + np.cos(_th))).reshape(-1, 1)
98
+
99
+ gamma = ox.State("flight_path_angle", shape=(1,))
100
+ gamma.min, gamma.max = [np.deg2rad(-75.0)], [np.deg2rad(75.0)]
101
+ gamma.initial, gamma.final = [ox.Free(0.0)], [ox.Free(0.0)]
102
+ gamma.guess = (np.pi / 6 * np.sin(_th)).reshape(-1, 1)
103
+
104
+ psi = ox.State("heading", shape=(1,))
105
+ psi.min, psi.max = [-3 * np.pi], [np.pi / 2]
106
+ psi.initial, psi.final = [ox.Free(-1.0)], [ox.Free(-1.0 - 2 * np.pi)]
107
+ psi.guess = (-1.0 - _t / 4).reshape(-1, 1)
108
+
109
+ # The wind-gradient slope is a single optimized constant: a state with zero
110
+ # dynamics whose final value is the Mayer objective.
111
+ beta = ox.State("wind_gradient", shape=(1,))
112
+ beta.min, beta.max = [beta_min], [beta_max]
113
+ beta.initial, beta.final = [ox.Free(0.08)], [ox.Minimize(0.08)]
114
+ beta.guess = np.full((n, 1), 0.08)
115
+
116
+ # ---------------------------------------------------------------------------
117
+ # Controls
118
+ # ---------------------------------------------------------------------------
119
+ CL = ox.Control("lift_coefficient", shape=(1,))
120
+ CL.min, CL.max = [-0.5], [1.5]
121
+ CL.guess = np.full((n, 1), 0.5)
122
+
123
+ phi = ox.Control("bank_angle", shape=(1,))
124
+ phi.min, phi.max = [np.deg2rad(-75.0)], [np.deg2rad(75.0)]
125
+ phi.guess = np.full((n, 1), -1.0)
126
+
127
+ states = [position, v, gamma, psi, beta]
128
+ controls = [CL, phi]
129
+
130
+ # ---------------------------------------------------------------------------
131
+ # Dynamics
132
+ # ---------------------------------------------------------------------------
133
+ hs = position[2]
134
+ vs, fpa, head, b = v[0], gamma[0], psi[0], beta[0]
135
+ cl, bank = CL[0], phi[0]
136
+
137
+ aero = rho * S / (2 * m) # (rho S / 2 m), the common aerodynamic factor
138
+ shear = b * vs * ox.Sin(fpa) # W = dW_x/dt, the wind-shear rate
139
+
140
+ dynamics = {
141
+ "position": ox.Concat(
142
+ vs * ox.Cos(fpa) * ox.Sin(head) + b * hs,
143
+ vs * ox.Cos(fpa) * ox.Cos(head),
144
+ vs * ox.Sin(fpa),
145
+ ),
146
+ "speed": -aero * (CD0 + K * cl**2) * vs**2
147
+ - g * ox.Sin(fpa)
148
+ - shear * ox.Sin(head) * ox.Cos(fpa),
149
+ "flight_path_angle": aero * cl * vs * ox.Cos(bank)
150
+ - g * ox.Cos(fpa) / vs
151
+ + shear * ox.Sin(head) * ox.Sin(fpa) / vs,
152
+ "heading": (aero * cl * vs * ox.Sin(bank) - shear * ox.Cos(head) / vs) / ox.Cos(fpa),
153
+ "wind_gradient": 0.0 * b,
154
+ }
155
+
156
+ # ---------------------------------------------------------------------------
157
+ # Constraints: state boxes and the load-factor limit hold in continuous time;
158
+ # the periodicity events tie the last node back to the first.
159
+ # ---------------------------------------------------------------------------
160
+ constraints = []
161
+ for state in states:
162
+ constraints.extend([ox.ctcs(state <= state.max), ox.ctcs(state.min <= state)])
163
+
164
+ load_factor = (aero / g) * cl * vs**2
165
+ constraints.extend([ox.ctcs(load_factor <= load_max), ox.ctcs(load_min <= load_factor)])
166
+
167
+ constraints.extend(
168
+ [
169
+ (v.at(n - 1) - v.at(0) == 0.0).convex(),
170
+ (gamma.at(n - 1) - gamma.at(0) == 0.0).convex(),
171
+ (psi.at(n - 1) - psi.at(0) == -2 * np.pi).convex(),
172
+ ]
173
+ )
174
+
175
+ # ---------------------------------------------------------------------------
176
+ # Free final time — the loop period is optimized but carries no cost.
177
+ # ---------------------------------------------------------------------------
178
+ time = ox.Time(
179
+ initial=0.0,
180
+ final=ox.Free(tf_guess),
181
+ min=0.0,
182
+ max=30.0,
183
+ )
184
+
185
+ # A fixed proximal weight converges in ~25 iterations here, where the adaptive
186
+ # default stalls just short of the dynamics-feasibility tolerance.
187
+ problem = ox.Problem(
188
+ dynamics=dynamics,
189
+ states=states,
190
+ controls=controls,
191
+ time=time,
192
+ constraints=constraints,
193
+ N=n,
194
+ licq_max=1e-8,
195
+ algorithm={"lam_prox": 2e-2, "autotuner": ox.ConstantProximalWeight()},
196
+ )
197
+
198
+
199
+ def plot_gpops_comparison(results):
200
+ """Reproduce the six GPOPS-II diagnostic plots for this benchmark.
201
+
202
+ Lays out the 3-D soaring loop (x, y, h) followed by airspeed, flight-path
203
+ angle, heading, lift coefficient, and bank angle versus time. The
204
+ high-resolution propagated trajectory is drawn as a line with the
205
+ discretization nodes overlaid.
206
+ """
207
+ nodes, traj = results.nodes, results.trajectory
208
+
209
+ def col(source, key, idx=0):
210
+ arr = np.asarray(source[key])
211
+ return arr[:, idx] if arr.ndim > 1 else arr
212
+
213
+ fig = make_subplots(
214
+ rows=2,
215
+ cols=3,
216
+ specs=[
217
+ [{"type": "scene"}, {"type": "xy"}, {"type": "xy"}],
218
+ [{"type": "xy"}, {"type": "xy"}, {"type": "xy"}],
219
+ ],
220
+ subplot_titles=(
221
+ "Soaring Loop",
222
+ "Airspeed vs. Time",
223
+ "Flight-Path Angle vs. Time",
224
+ "Heading vs. Time",
225
+ "Lift Coefficient vs. Time",
226
+ "Bank Angle vs. Time",
227
+ ),
228
+ )
229
+
230
+ line_style = {"color": "#19d3f3", "width": 3}
231
+ marker_style = {"color": "#ffa600", "size": 5}
232
+
233
+ fig.add_trace(
234
+ go.Scatter3d(
235
+ x=col(traj, "position", 0),
236
+ y=col(traj, "position", 1),
237
+ z=col(traj, "position", 2),
238
+ mode="lines",
239
+ name="Propagated",
240
+ line=line_style,
241
+ legendgroup="traj",
242
+ ),
243
+ row=1,
244
+ col=1,
245
+ )
246
+ fig.add_trace(
247
+ go.Scatter3d(
248
+ x=col(nodes, "position", 0),
249
+ y=col(nodes, "position", 1),
250
+ z=col(nodes, "position", 2),
251
+ mode="markers",
252
+ name="Nodes",
253
+ marker=marker_style,
254
+ legendgroup="nodes",
255
+ ),
256
+ row=1,
257
+ col=1,
258
+ )
259
+
260
+ # (row, col, y-trajectory, y-nodes) for the five time-series panels.
261
+ t_traj, t_nodes = col(traj, "time"), col(nodes, "time")
262
+ panels = [
263
+ (1, 2, col(traj, "speed"), col(nodes, "speed")),
264
+ (
265
+ 1,
266
+ 3,
267
+ np.rad2deg(col(traj, "flight_path_angle")),
268
+ np.rad2deg(col(nodes, "flight_path_angle")),
269
+ ),
270
+ (2, 1, np.rad2deg(col(traj, "heading")), np.rad2deg(col(nodes, "heading"))),
271
+ (2, 2, col(traj, "lift_coefficient"), col(nodes, "lift_coefficient")),
272
+ (2, 3, np.rad2deg(col(traj, "bank_angle")), np.rad2deg(col(nodes, "bank_angle"))),
273
+ ]
274
+ for r, c, yt, yn in panels:
275
+ fig.add_trace(
276
+ go.Scatter(
277
+ x=t_traj,
278
+ y=yt,
279
+ mode="lines",
280
+ name="Propagated",
281
+ line={"color": line_style["color"], "width": 2},
282
+ legendgroup="traj",
283
+ showlegend=False,
284
+ ),
285
+ row=r,
286
+ col=c,
287
+ )
288
+ fig.add_trace(
289
+ go.Scatter(
290
+ x=t_nodes,
291
+ y=yn,
292
+ mode="markers",
293
+ name="Nodes",
294
+ marker=marker_style,
295
+ legendgroup="nodes",
296
+ showlegend=False,
297
+ ),
298
+ row=r,
299
+ col=c,
300
+ )
301
+ fig.update_xaxes(title_text="Time [s]", row=r, col=c)
302
+
303
+ fig.update_yaxes(title_text="Airspeed [ft/s]", row=1, col=2)
304
+ fig.update_yaxes(title_text="Flight-path angle [deg]", row=1, col=3)
305
+ fig.update_yaxes(title_text="Heading [deg]", row=2, col=1)
306
+ fig.update_yaxes(title_text="Lift coefficient", row=2, col=2)
307
+ fig.update_yaxes(title_text="Bank angle [deg]", row=2, col=3)
308
+ fig.update_layout(
309
+ title="Dynamic Soaring",
310
+ template="plotly_dark",
311
+ scene={
312
+ "xaxis_title": "x [ft]",
313
+ "yaxis_title": "y [ft]",
314
+ "zaxis_title": "h [ft]",
315
+ "aspectmode": "data",
316
+ },
317
+ )
318
+ return fig
319
+
320
+
321
+ if __name__ == "__main__":
322
+ problem.initialize()
323
+ results = problem.solve()
324
+ results = problem.post_process()
325
+
326
+ beta_opt = float(np.asarray(results.nodes["wind_gradient"]).flatten()[-1])
327
+ final_time = float(np.asarray(results.nodes["time"]).flatten()[-1])
328
+ print(f"Minimum wind-gradient slope: {beta_opt:.4f} 1/s (loop period {final_time:.2f} s)")
329
+
330
+ plot_gpops_comparison(results).show()
331
+ plot_states(results).show()
332
+ plot_controls(results).show()
333
+ plot_scp_iterations(results).show()
@@ -18,7 +18,7 @@ version_tuple: tuple[int | str, ...]
18
18
  commit_id: str | None
19
19
  __commit_id__: str | None
20
20
 
21
- __version__ = version = '0.5.3.dev32'
22
- __version_tuple__ = version_tuple = (0, 5, 3, 'dev32')
21
+ __version__ = version = '0.5.3.dev34'
22
+ __version_tuple__ = version_tuple = (0, 5, 3, 'dev34')
23
23
 
24
- __commit_id__ = commit_id = 'gd1964080e'
24
+ __commit_id__ = commit_id = 'g264808b5c'
@@ -50,6 +50,14 @@ class OptimizationResults:
50
50
  Added by propagate_trajectory_results.
51
51
  ctcs_violation (Optional[np.ndarray]): Continuous-time constraint violations.
52
52
  Added by propagate_trajectory_results.
53
+ parameters (dict[str, np.ndarray]): Parameter values the solve used, recorded
54
+ by :meth:`~openscvx.problem.Problem.solve` and
55
+ :meth:`~openscvx.problem.Problem.solve_batched` (batched solves store every
56
+ value with a leading ``(B,)`` axis, shared values replicated). Results
57
+ record what happened: post-processing propagates with these values, and
58
+ the Problem's parameter dict only seeds the next solve. Empty when no
59
+ snapshot was recorded (e.g. ``solve_jax``, whose callers manage
60
+ parameters themselves).
53
61
  plotting_data (dict[str, Any]): Flexible storage for plotting and application data.
54
62
 
55
63
  !!! note "JAX pytree registration"
@@ -59,8 +67,9 @@ class OptimizationResults:
59
67
  ``converged``, ``t_final``, ``nodes``, ``trajectory``, ``X``, ``U``,
60
68
  and every ``*_history`` field — the data the user actually consumes.
61
69
  Post-process fields (``t_full``, ``x_full``, ``u_full``, ``cost``,
62
- ``ctcs_violation``), ``plotting_data``, and the internal ``_states`` /
63
- ``_controls`` metadata are stashed in the treedef's *aux* instead, so
70
+ ``ctcs_violation``), ``parameters``, ``plotting_data``, and the
71
+ internal ``_states`` / ``_controls`` metadata are stashed in the
72
+ treedef's *aux* instead, so
64
73
  a batched ``solve_jax`` doesn't force callers to handle ``None``
65
74
  leaves and ``post_process()`` outputs stay outside the vmap surface
66
75
  (post-process per element after the batched solve).
@@ -217,6 +226,10 @@ class OptimizationResults:
217
226
  cost: Optional[float] = field(default=None, metadata={"npz": "optional_scalar"})
218
227
  ctcs_violation: Optional[np.ndarray] = field(default=None, metadata={"npz": "optional_array"})
219
228
 
229
+ # Parameter values the solve used (recorded by Problem.solve() /
230
+ # Problem.solve_batched(); empty when nothing was recorded)
231
+ parameters: dict[str, np.ndarray] = field(default_factory=dict, metadata={"npz": "dict"})
232
+
220
233
  # Additional plotting/application data (added by user)
221
234
  plotting_data: dict[str, Any] = field(default_factory=dict, metadata={"npz": "dict"})
222
235
 
@@ -245,6 +258,7 @@ class OptimizationResults:
245
258
  self.u_full,
246
259
  self.cost,
247
260
  self.ctcs_violation,
261
+ self.parameters,
248
262
  self.plotting_data,
249
263
  )
250
264
  return children, aux
@@ -260,6 +274,7 @@ class OptimizationResults:
260
274
  u_full,
261
275
  cost,
262
276
  ctcs_violation,
277
+ parameters,
263
278
  plotting_data,
264
279
  ) = aux
265
280
  return cls(
@@ -271,6 +286,7 @@ class OptimizationResults:
271
286
  u_full=u_full,
272
287
  cost=cost,
273
288
  ctcs_violation=ctcs_violation,
289
+ parameters=parameters,
274
290
  plotting_data=plotting_data,
275
291
  )
276
292
 
@@ -23,6 +23,7 @@ import os
23
23
  import queue
24
24
  import threading
25
25
  import time
26
+ import warnings
26
27
  from dataclasses import fields as dc_fields
27
28
  from dataclasses import replace as dc_replace
28
29
  from typing import Any, Dict, List, Optional, Tuple, Union
@@ -672,6 +673,7 @@ class Problem:
672
673
  # Final solution state (saved after successful solve)
673
674
  self._solution: Optional[AlgorithmState] = None
674
675
  self._solution_history: Optional[AlgorithmHistory] = None
676
+ self._solution_parameters: Optional[Dict[str, np.ndarray]] = None
675
677
 
676
678
  # SCP algorithm (resolved from `algorithm` parameter above)
677
679
 
@@ -1287,6 +1289,7 @@ class Problem:
1287
1289
  # Reset solution
1288
1290
  self._solution = None
1289
1291
  self._solution_history = None
1292
+ self._solution_parameters = None
1290
1293
 
1291
1294
  # Reset timing
1292
1295
  self.timing_solve = None
@@ -1355,7 +1358,10 @@ class Problem:
1355
1358
 
1356
1359
  Returns:
1357
1360
  OptimizationResults with trajectory and convergence info
1358
- (call post_process() for full propagation)
1361
+ (call post_process() for full propagation). The parameter
1362
+ values used for the solve are recorded on
1363
+ ``results.parameters``; :meth:`post_process` propagates
1364
+ with them.
1359
1365
  """
1360
1366
  # Sync parameters, boundary conditions, and SCP constants before solving
1361
1367
  self._sync_parameters()
@@ -1408,16 +1414,22 @@ class Problem:
1408
1414
 
1409
1415
  profiling.profiling_end(pr, "solve")
1410
1416
 
1411
- # Snapshot state + history for post_process() / plotting reuse.
1417
+ # Snapshot state, history, and parameters for post_process() / plotting
1418
+ # reuse.
1412
1419
  self._solution = self._state
1413
1420
  self._solution_history = copy.deepcopy(self._history)
1421
+ self._solution_parameters = {
1422
+ name: np.array(value) for name, value in self._parameters.items()
1423
+ }
1414
1424
 
1415
1425
  timed_out = t_max is not None and self.timing_solve >= t_max
1416
- return self._format_result(
1426
+ result = self._format_result(
1417
1427
  self._state,
1418
1428
  self._history,
1419
1429
  int(self._state.k) <= k_max and not timed_out,
1420
1430
  )
1431
+ result.parameters = self._solution_parameters
1432
+ return result
1421
1433
 
1422
1434
  def _default_state(self) -> AlgorithmState:
1423
1435
  """Fresh :class:`AlgorithmState` from settings and the algorithm's SCP constants.
@@ -1665,6 +1677,11 @@ class Problem:
1665
1677
  parameters: Problem parameters dict for the current solve. Use
1666
1678
  this rather than mutating ``self.parameters`` if the
1667
1679
  parameters are traced. ``None`` reuses ``self._parameters``.
1680
+ Unlike :meth:`solve` / :meth:`solve_batched`, the merged
1681
+ values are *not* recorded on the returned results — under a
1682
+ caller's ``jit`` / ``vmap`` they are tracers, which must not
1683
+ leak into the pytree's aux — so callers that post-process
1684
+ manage parameter bookkeeping themselves.
1668
1685
  x_guess: Initial state trajectory guess, shape ``(N, n_states)``.
1669
1686
  Replaces ``state.x``; ``None`` uses the default from
1670
1687
  settings (``State.guess`` at ``initialize()``).
@@ -1846,7 +1863,12 @@ class Problem:
1846
1863
 
1847
1864
  Returns:
1848
1865
  :class:`OptimizationResults` pytree with a leading ``B`` axis on
1849
- every leaf and empty per-iteration histories.
1866
+ every leaf and empty per-iteration histories. The merged
1867
+ parameter values used for the solve are recorded on
1868
+ ``results.parameters``, post-broadcast — every value carries the
1869
+ leading ``(B,)`` axis, shared values replicated — and
1870
+ :meth:`post_process_batched` propagates each element with its
1871
+ own values.
1850
1872
  """
1851
1873
  if self._iteration_fn_jit_inner is None:
1852
1874
  raise ValueError(
@@ -1953,7 +1975,16 @@ class Problem:
1953
1975
  final_states = batched_solve(states, params_for_solve)
1954
1976
  jax.block_until_ready(final_states)
1955
1977
  self.timing_solve = time.time() - t_0_solve
1956
- return OptimizationResults.from_final_state(final_states, problem=self)
1978
+ results = OptimizationResults.from_final_state(final_states, problem=self)
1979
+ # Record the as-used parameter values with a leading (B,) axis on
1980
+ # every leaf, so post_process_batched() can index element b directly.
1981
+ results.parameters = {
1982
+ name: np.array(np.moveaxis(np.asarray(value), param_axes[name], 0))
1983
+ if param_axes[name] is not None
1984
+ else np.broadcast_to(np.asarray(value), (B,) + np.shape(value)).copy()
1985
+ for name, value in params_for_solve.items()
1986
+ }
1987
+ return results
1957
1988
 
1958
1989
  def post_process(self) -> OptimizationResults:
1959
1990
  """Propagate solution through full nonlinear dynamics for high-fidelity trajectory.
@@ -1961,6 +1992,10 @@ class Problem:
1961
1992
  Integrates the converged SCP solution through the nonlinear dynamics to
1962
1993
  produce x_full, u_full, and t_full. Call after solve() for final results.
1963
1994
 
1995
+ Propagation uses the parameter values recorded at solve time
1996
+ (``results.parameters``), so mutating ``self.parameters`` between
1997
+ :meth:`solve` and here only seeds the next solve.
1998
+
1964
1999
  Returns:
1965
2000
  OptimizationResults with propagated trajectory fields
1966
2001
 
@@ -1980,9 +2015,11 @@ class Problem:
1980
2015
  int(self._solution.k) <= self._algorithm.k_max,
1981
2016
  )
1982
2017
 
2018
+ result.parameters = self._solution_parameters
2019
+
1983
2020
  t_0_post = time.time()
1984
2021
  result = propagate_trajectory_results(
1985
- self._parameters,
2022
+ self._solution_parameters,
1986
2023
  self.settings,
1987
2024
  result,
1988
2025
  self._propagation_solver,
@@ -2022,9 +2059,11 @@ class Problem:
2022
2059
  - ``results.cost`` — ``(B,)``
2023
2060
  - ``results.ctcs_violation`` — ``(B, ...)`` or ``None``
2024
2061
 
2025
- Propagation runs sequentially over the batch in a Python loop;
2026
- all elements share ``self._parameters`` for any parameter values not
2027
- embedded in the trajectory state vector.
2062
+ Propagation runs sequentially over the batch in a Python loop; each
2063
+ element propagates with its own parameter values from the snapshot
2064
+ :meth:`solve_batched` recorded on ``results.parameters``. Results
2065
+ without a snapshot (e.g. loaded from an older save) fall back to
2066
+ ``self.parameters`` with a warning.
2028
2067
 
2029
2068
  Args:
2030
2069
  results: Batched :class:`~openscvx.algorithms.OptimizationResults`
@@ -2068,11 +2107,23 @@ class Problem:
2068
2107
  costs: List[float] = []
2069
2108
  ctcs_violations = []
2070
2109
 
2110
+ # Empty for results saved before the snapshot existed — those fall
2111
+ # back to the Problem's current values, the pre-snapshot behaviour.
2112
+ snapshot = getattr(results, "parameters", None) or {}
2113
+ if not snapshot and self._parameters:
2114
+ warnings.warn(
2115
+ "results carry no record of the parameter values they were solved "
2116
+ "with; propagating every element with the Problem's current "
2117
+ "parameters, which may differ from the solved values.",
2118
+ UserWarning,
2119
+ stacklevel=2,
2120
+ )
2121
+
2071
2122
  t_0_post = time.time()
2072
2123
  for b in range(B):
2073
2124
  single = _make_single_result(results, b)
2074
2125
  prop = propagate_trajectory_results(
2075
- self._parameters,
2126
+ dict(self._parameters, **{k: np.asarray(v)[b] for k, v in snapshot.items()}),
2076
2127
  self.settings,
2077
2128
  single,
2078
2129
  self._propagation_solver,
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: openscvx
3
- Version: 0.5.3.dev32
3
+ Version: 0.5.3.dev34
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
@@ -63,6 +63,7 @@ examples/abstract/hypersensitive.py
63
63
  examples/abstract/impulsive.py
64
64
  examples/abstract/stl_integer_variable.py
65
65
  examples/abstract/stl_or.py
66
+ examples/aircraft/dynamic_soaring.py
66
67
  examples/aircraft/supersonic_time_to_climb.py
67
68
  examples/animations/7_dof_arm.py
68
69
  examples/animations/_camera.py
@@ -354,6 +355,7 @@ tests/test_multishot_propagation.py
354
355
  tests/test_optimization_results.py
355
356
  tests/test_plotting.py
356
357
  tests/test_propagation.py
358
+ tests/test_results_parameters.py
357
359
  tests/test_solve_batched_brachistochrone.py
358
360
  tests/test_solve_batched_cvxpy_export_errors.py
359
361
  tests/test_solve_batched_export_roundtrip.py
@@ -220,6 +220,7 @@
220
220
  "tests/test_propagation.py",
221
221
  "tests/hohmann_analytical.py",
222
222
  "tests/test_expert.py",
223
+ "tests/test_results_parameters.py",
223
224
  "tests/test_solve_batched_inference.py",
224
225
  "tests/test_solve_jax_bare_brachistochrone.py",
225
226
  "tests/test_cvxpygen_optional.py",
@@ -333,6 +334,7 @@
333
334
  "examples/abstract/stl_or.py",
334
335
  "examples/abstract/stl_integer_variable.py",
335
336
  "examples/abstract/brachistochrone.py",
337
+ "examples/aircraft/dynamic_soaring.py",
336
338
  "examples/aircraft/supersonic_time_to_climb.py",
337
339
  "examples/drone/dr_vp.py",
338
340
  "examples/drone/openscvx_logo.py",
@@ -0,0 +1,8 @@
1
+ {
2
+ "tag": "0.5.2",
3
+ "distance": 34,
4
+ "node": "g264808b5c8dfd13d52b35c4d96c885b010058203",
5
+ "dirty": false,
6
+ "branch": "main",
7
+ "node_date": "2026-07-06"
8
+ }
@@ -1,5 +1,6 @@
1
1
  """Tests for OptimizationResults save/load round-trip."""
2
2
 
3
+ import jax
3
4
  import numpy as np
4
5
  import pytest
5
6
 
@@ -184,3 +185,29 @@ def test_plotting_data_skips_non_array(tmp_path):
184
185
  loaded = OptimizationResults.load(path)
185
186
  np.testing.assert_array_equal(loaded.plotting_data["good"], np.array([1, 2, 3]))
186
187
  assert "bad_func" not in loaded.plotting_data
188
+
189
+
190
+ def test_save_load_roundtrip_parameters(tmp_path):
191
+ """The recorded parameter snapshot survives a save/load round-trip."""
192
+ original = _make_result()
193
+ original.parameters = {"gain": np.array([2.0]), "center": np.array([1.0, 2.0, 3.0])}
194
+ path = tmp_path / "with_parameters.npz"
195
+ original.save(path)
196
+
197
+ loaded = OptimizationResults.load(path)
198
+ assert set(loaded.parameters) == set(original.parameters)
199
+ for key, value in original.parameters.items():
200
+ np.testing.assert_array_equal(loaded.parameters[key], value)
201
+
202
+
203
+ def test_parameters_snapshot_is_pytree_aux_not_child():
204
+ """The parameter snapshot rides the treedef's aux, leaving the children unchanged."""
205
+ result = _make_result()
206
+ n_leaves = len(jax.tree_util.tree_leaves(result))
207
+
208
+ result.parameters = {"gain": np.array([2.0])}
209
+ leaves, treedef = jax.tree_util.tree_flatten(result)
210
+ assert len(leaves) == n_leaves # no new pytree children
211
+
212
+ restored = jax.tree_util.tree_unflatten(treedef, leaves)
213
+ np.testing.assert_array_equal(restored.parameters["gain"], np.array([2.0]))