openscvx 0.5.3.dev30__tar.gz → 0.5.3.dev32__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 (430) hide show
  1. {openscvx-0.5.3.dev30/openscvx.egg-info → openscvx-0.5.3.dev32}/PKG-INFO +1 -1
  2. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/examples/abstract/flappy_bird.py +7 -24
  3. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/examples/drone/logo.py +1 -1
  4. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/examples/frax/panda_frax_pick_place.py +4 -53
  5. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/examples/frax/panda_frax_viewplanning.py +4 -53
  6. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/examples/frax/panda_frax_waypoint.py +12 -62
  7. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/examples/mjx/double_cartpole_mjx.py +3 -53
  8. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/examples/mjx/triple_cartpole_3d_mjx.py +8 -82
  9. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/examples/mjx/triple_cartpole_mjx.py +8 -75
  10. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/examples/plotting_viser.py +14 -27
  11. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/openscvx/_version.py +3 -3
  12. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/openscvx/algorithms/__init__.py +8 -1
  13. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/openscvx/algorithms/autotuner/augmented_lagrangian.py +2 -2
  14. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/openscvx/algorithms/history.py +154 -2
  15. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/openscvx/algorithms/optimization_results.py +31 -1
  16. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/openscvx/algorithms/penalty.py +4 -2
  17. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/openscvx/algorithms/scvx/iteration.py +11 -2
  18. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/openscvx/lowered/jax_constraints.py +8 -0
  19. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/openscvx/plotting/scp_iteration.py +7 -5
  20. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/openscvx/plotting/viser/scp.py +9 -26
  21. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/openscvx/solvers/cvxpy_ptr_solver.py +6 -3
  22. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/openscvx/solvers/moreau_ptr_solver.py +6 -0
  23. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/openscvx/solvers/qpax_ptr_solver.py +6 -0
  24. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/openscvx/symbolic/augmentation.py +0 -36
  25. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/openscvx/symbolic/lower.py +3 -1
  26. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32/openscvx.egg-info}/PKG-INFO +1 -1
  27. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/openscvx.egg-info/SOURCES.txt +3 -0
  28. openscvx-0.5.3.dev32/openscvx.egg-info/scm_file_list.json +423 -0
  29. openscvx-0.5.3.dev32/openscvx.egg-info/scm_version.json +8 -0
  30. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/tests/solvers/test_qpax_ptr_solver.py +40 -0
  31. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/tests/symbolic/test_augmentation.py +12 -26
  32. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/tests/test_autotuning.py +25 -0
  33. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/tests/test_brachistochrone.py +71 -0
  34. openscvx-0.5.3.dev32/tests/test_multishot_propagation.py +128 -0
  35. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/.github/assets/logo.svg +0 -0
  36. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/.github/release-drafter.yml +0 -0
  37. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/.github/workflows/_docs.yml +0 -0
  38. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/.github/workflows/branch-name.yml +0 -0
  39. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/.github/workflows/docs.yml +0 -0
  40. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/.github/workflows/lint.yml +0 -0
  41. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/.github/workflows/nightly.yml +0 -0
  42. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/.github/workflows/release-drafter.yml +0 -0
  43. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/.github/workflows/release.yml +0 -0
  44. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/.github/workflows/tests-integration.yml +0 -0
  45. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/.github/workflows/tests-unit.yml +0 -0
  46. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/.gitignore +0 -0
  47. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/.gitmodules +0 -0
  48. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/CONTRIBUTING.md +0 -0
  49. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/LICENSE +0 -0
  50. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/README.md +0 -0
  51. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/docs/Foundations/constraint_reformulation.md +0 -0
  52. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/docs/Foundations/control_parameterization.md +0 -0
  53. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/docs/Foundations/discretization.md +0 -0
  54. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/docs/Foundations/ocp.md +0 -0
  55. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/docs/Foundations/scvx.md +0 -0
  56. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/docs/Foundations/time_dilation.md +0 -0
  57. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/docs/UnderTheHood/batching_jit_grad.md +0 -0
  58. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/docs/UnderTheHood/custom_algorithms_autotuners.md +0 -0
  59. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/docs/UnderTheHood/lowering_architecture.md +0 -0
  60. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/docs/UnderTheHood/vectorization_and_vmapping.md +0 -0
  61. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/docs/UsersGuide/00_introduction.md +0 -0
  62. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/docs/UsersGuide/01_hello_world_brachistochrone.md +0 -0
  63. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/docs/UsersGuide/02_drone_racing_constraints.md +0 -0
  64. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/docs/UsersGuide/03_obstacle_avoidance_vmap.md +0 -0
  65. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/docs/UsersGuide/04_viewpoint_constraints.md +0 -0
  66. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/docs/UsersGuide/05_visualization.md +0 -0
  67. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/docs/UsersGuide/06_logic.md +0 -0
  68. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/docs/UsersGuide/07_lie.md +0 -0
  69. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/docs/UsersGuide/08_mpcc.md +0 -0
  70. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/docs/UsersGuide/09_mjx_dynamics.md +0 -0
  71. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/docs/assets/favicon.png +0 -0
  72. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/docs/assets/images/ct-scvx_dark.png +0 -0
  73. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/docs/assets/images/ct-scvx_light.png +0 -0
  74. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/docs/assets/images/ctcs_dark.png +0 -0
  75. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/docs/assets/images/ctcs_light.png +0 -0
  76. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/docs/assets/images/problem_class_dark.png +0 -0
  77. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/docs/assets/images/problem_class_light.png +0 -0
  78. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/docs/assets/logo.svg +0 -0
  79. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/docs/assets/openscvx_logo_square.png +0 -0
  80. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/docs/assets/viser-client/index.html +0 -0
  81. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/docs/assets/viser-recordings/drone_racing.viser +0 -0
  82. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/docs/assets/viser-recordings/franka_fr3v2_pick_place.viser +0 -0
  83. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/docs/citation.md +0 -0
  84. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/docs/examples.md +0 -0
  85. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/docs/index.md +0 -0
  86. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/docs/javascripts/mathjax.js +0 -0
  87. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/docs/versions.json +0 -0
  88. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/examples/_viser_embed_export.py +0 -0
  89. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/examples/abstract/brachistochrone.py +0 -0
  90. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/examples/abstract/brachistochrone_batched.py +0 -0
  91. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/examples/abstract/hypersensitive.py +0 -0
  92. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/examples/abstract/impulsive.py +0 -0
  93. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/examples/abstract/stl_integer_variable.py +0 -0
  94. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/examples/abstract/stl_or.py +0 -0
  95. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/examples/aircraft/supersonic_time_to_climb.py +0 -0
  96. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/examples/animations/7_dof_arm.py +0 -0
  97. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/examples/animations/_camera.py +0 -0
  98. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/examples/animations/_render.py +0 -0
  99. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/examples/animations/_sensor_view.py +0 -0
  100. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/examples/animations/dr_vp_polytope.py +0 -0
  101. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/examples/animations/franka_fr3v2_pick_place.py +0 -0
  102. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/examples/animations/logo.py +0 -0
  103. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/examples/animations/obstacle_avoidance_vmap.py +0 -0
  104. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/examples/arm/3_dof_arm.py +0 -0
  105. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/examples/arm/7_dof_arm.py +0 -0
  106. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/examples/arm/7_dof_arm_collision.py +0 -0
  107. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/examples/arm/7_dof_arm_vp.py +0 -0
  108. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/examples/arm/franka_fr3v2_pick_place.py +0 -0
  109. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/examples/arm/franka_fr3v2_viewplanning.py +0 -0
  110. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/examples/arm/franka_fr3v2_viewplanning_nodal.py +0 -0
  111. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/examples/car/dubins_car.py +0 -0
  112. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/examples/car/dubins_car_disjoint.py +0 -0
  113. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/examples/car/dubins_car_obstacle_conditional.py +0 -0
  114. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/examples/car/dubins_car_obstacle_stl.py +0 -0
  115. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/examples/car/dubins_car_stl_or.py +0 -0
  116. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/examples/car/dubins_car_waypoint_stl.py +0 -0
  117. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/examples/double_integrator/_plotting.py +0 -0
  118. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/examples/double_integrator/moving_safe_zones.py +0 -0
  119. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/examples/drone/2d_obstacle_avoidance_batched_ic.py +0 -0
  120. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/examples/drone/cinema_vp.py +0 -0
  121. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/examples/drone/cinema_vp_nodal.py +0 -0
  122. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/examples/drone/dr_double_integrator.py +0 -0
  123. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/examples/drone/dr_vp.py +0 -0
  124. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/examples/drone/dr_vp_nodal.py +0 -0
  125. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/examples/drone/dr_vp_polytope.py +0 -0
  126. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/examples/drone/drone_racing.py +0 -0
  127. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/examples/drone/drone_racing_batched_gates.py +0 -0
  128. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/examples/drone/logo_utils/acl_logo.svg +0 -0
  129. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/examples/drone/logo_utils/openscvx_logo_single.svg +0 -0
  130. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/examples/drone/logo_utils/quadrotor_mesh.py +0 -0
  131. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/examples/drone/logo_utils/svg_path_utils.py +0 -0
  132. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/examples/drone/multi_agent_circle_swap.py +0 -0
  133. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/examples/drone/obstacle_avoidance.py +0 -0
  134. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/examples/drone/obstacle_avoidance_nodal.py +0 -0
  135. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/examples/drone/obstacle_avoidance_vmap.py +0 -0
  136. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/examples/drone/obstacle_avoidance_vmap_2d.py +0 -0
  137. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/examples/drone/openscvx_logo.py +0 -0
  138. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/examples/frax/panda_frax.py +0 -0
  139. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/examples/mjx/cartpole_mjx.py +0 -0
  140. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/examples/mjx/skydio_x2_mjx.py +0 -0
  141. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/examples/mjx/triple_cartpole_game.py +0 -0
  142. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/examples/mpc/double_integrator_discrete.py +0 -0
  143. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/examples/mpc/double_integrator_drone_racing.py +0 -0
  144. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/examples/mpc/dubins_car_circle_analytical.py +0 -0
  145. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/examples/mpc/dubins_car_circle_discrete.py +0 -0
  146. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/examples/mpc/realtime_double_integrator_drone_racing.py +0 -0
  147. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/examples/plotting.py +0 -0
  148. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/examples/realtime/3DoF_pdg_realtime.py +0 -0
  149. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/examples/realtime/6DoF_pdg_realtime.py +0 -0
  150. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/examples/realtime/base_problems/3DoF_pdg_realtime_base.py +0 -0
  151. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/examples/realtime/base_problems/6DoF_pdg_realtime_base.py +0 -0
  152. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/examples/realtime/base_problems/cinema_vp_realtime_base.py +0 -0
  153. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/examples/realtime/base_problems/drone_racing_realtime_base.py +0 -0
  154. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/examples/realtime/base_problems/dubins_car_realtime_base.py +0 -0
  155. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/examples/realtime/base_problems/obstacle_avoidance_realtime_base.py +0 -0
  156. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/examples/realtime/cinema_vp_realtime.py +0 -0
  157. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/examples/realtime/drone_racing_realtime.py +0 -0
  158. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/examples/realtime/dubins_car_realtime.py +0 -0
  159. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/examples/realtime/obstacle_avoidance_realtime.py +0 -0
  160. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/examples/rocket/3DoF_pdg.py +0 -0
  161. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/examples/rocket/6DoF_pdg.py +0 -0
  162. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/examples/rocket/6DoF_pdg_batched_ic.py +0 -0
  163. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/examples/rocket/ascent_launch_vehicle.py +0 -0
  164. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/examples/spacecraft/halo_orbit.py +0 -0
  165. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/examples/spacecraft/hohmann_transfer.py +0 -0
  166. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/examples/spacecraft/let_transfer.py +0 -0
  167. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/examples/spacecraft/proxops_cw.py +0 -0
  168. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/examples/spacecraft/relative_loitering.py +0 -0
  169. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/figures/ctlos_cine.gif +0 -0
  170. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/figures/ctlos_dr.gif +0 -0
  171. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/figures/dtlos_cine.gif +0 -0
  172. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/figures/dtlos_dr.gif +0 -0
  173. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/figures/openscvx_logo.svg +0 -0
  174. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/figures/openscvx_logo_square.png +0 -0
  175. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/figures/oscvx_structure_full_dark.svg +0 -0
  176. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/figures/video_preview.png +0 -0
  177. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/material/__init__.py +0 -0
  178. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/material/overrides/assets/stylesheets/custom.css +0 -0
  179. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/material/overrides/assets/stylesheets/home-dropin.css +0 -0
  180. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/material/overrides/assets/stylesheets/home-hero.css +0 -0
  181. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/material/overrides/assets/stylesheets/home-viser.css +0 -0
  182. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/material/overrides/home.html +0 -0
  183. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/material/overrides/main.html +0 -0
  184. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/material/overrides/partials/home-diagram.html +0 -0
  185. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/material/overrides/partials/home-dropin-banner.html +0 -0
  186. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/material/overrides/partials/home-hero.html +0 -0
  187. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/material/overrides/partials/home-pipeline.html +0 -0
  188. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/material/overrides/partials/home-viser-strip.html +0 -0
  189. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/mkdocs.yml +0 -0
  190. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/openscvx/__init__.py +0 -0
  191. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/openscvx/__main__.py +0 -0
  192. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/openscvx/algorithms/autotuner/__init__.py +0 -0
  193. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/openscvx/algorithms/autotuner/acceptance_ratio.py +0 -0
  194. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/openscvx/algorithms/autotuner/adaptive_proximal_weight.py +0 -0
  195. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/openscvx/algorithms/autotuner/base.py +0 -0
  196. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/openscvx/algorithms/autotuner/constant_proximal_weight.py +0 -0
  197. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/openscvx/algorithms/autotuner/ramp_proximal_weight.py +0 -0
  198. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/openscvx/algorithms/base.py +0 -0
  199. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/openscvx/algorithms/hyperparams.py +0 -0
  200. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/openscvx/algorithms/loop.py +0 -0
  201. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/openscvx/algorithms/scvx/__init__.py +0 -0
  202. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/openscvx/algorithms/scvx/penalized_trust_region.py +0 -0
  203. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/openscvx/algorithms/state.py +0 -0
  204. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/openscvx/algorithms/weights.py +0 -0
  205. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/openscvx/config.py +0 -0
  206. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/openscvx/discretization/__init__.py +0 -0
  207. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/openscvx/discretization/base.py +0 -0
  208. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/openscvx/discretization/discretize_linearize.py +0 -0
  209. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/openscvx/discretization/linearize_discretize.py +0 -0
  210. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/openscvx/discretization/linearize_discretize_sparse.py +0 -0
  211. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/openscvx/discretization/sparse_utils/__init__.py +0 -0
  212. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/openscvx/discretization/sparse_utils/bcoo_helpers.py +0 -0
  213. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/openscvx/discretization/sparse_utils/sparse_jacobian.py +0 -0
  214. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/openscvx/expert/__init__.py +0 -0
  215. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/openscvx/expert/byof.py +0 -0
  216. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/openscvx/expert/lowering.py +0 -0
  217. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/openscvx/expert/validation.py +0 -0
  218. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/openscvx/init/__init__.py +0 -0
  219. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/openscvx/init/interpolation.py +0 -0
  220. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/openscvx/init/inverse_kinematics.py +0 -0
  221. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/openscvx/integrations/__init__.py +0 -0
  222. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/openscvx/integrations/_utils.py +0 -0
  223. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/openscvx/integrations/base.py +0 -0
  224. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/openscvx/integrations/frax.py +0 -0
  225. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/openscvx/integrations/menagerie.py +0 -0
  226. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/openscvx/integrations/mjx.py +0 -0
  227. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/openscvx/integrators/__init__.py +0 -0
  228. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/openscvx/integrators/diffrax.py +0 -0
  229. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/openscvx/integrators/runge_kutta.py +0 -0
  230. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/openscvx/loader.py +0 -0
  231. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/openscvx/lowered/__init__.py +0 -0
  232. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/openscvx/lowered/cvxpy_constraints.py +0 -0
  233. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/openscvx/lowered/cvxpy_variables.py +0 -0
  234. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/openscvx/lowered/dynamics.py +0 -0
  235. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/openscvx/lowered/parameters.py +0 -0
  236. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/openscvx/lowered/problem.py +0 -0
  237. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/openscvx/lowered/unified.py +0 -0
  238. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/openscvx/plotting/__init__.py +0 -0
  239. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/openscvx/plotting/plotting.py +0 -0
  240. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/openscvx/plotting/publication.py +0 -0
  241. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/openscvx/plotting/viser/__init__.py +0 -0
  242. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/openscvx/plotting/viser/animated.py +0 -0
  243. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/openscvx/plotting/viser/coordinates.py +0 -0
  244. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/openscvx/plotting/viser/orbits.py +0 -0
  245. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/openscvx/plotting/viser/plotly_integration.py +0 -0
  246. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/openscvx/plotting/viser/primitives.py +0 -0
  247. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/openscvx/plotting/viser/server.py +0 -0
  248. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/openscvx/problem.py +0 -0
  249. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/openscvx/propagation/__init__.py +0 -0
  250. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/openscvx/propagation/post_processing.py +0 -0
  251. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/openscvx/propagation/propagation.py +0 -0
  252. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/openscvx/solvers/__init__.py +0 -0
  253. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/openscvx/solvers/base.py +0 -0
  254. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/openscvx/solvers/cones.py +0 -0
  255. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/openscvx/solvers/ptr_solver.py +0 -0
  256. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/openscvx/symbolic/__init__.py +0 -0
  257. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/openscvx/symbolic/affine.py +0 -0
  258. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/openscvx/symbolic/builder.py +0 -0
  259. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/openscvx/symbolic/canonicalize.py +0 -0
  260. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/openscvx/symbolic/constraint_set.py +0 -0
  261. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/openscvx/symbolic/expr/__init__.py +0 -0
  262. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/openscvx/symbolic/expr/arithmetic.py +0 -0
  263. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/openscvx/symbolic/expr/array.py +0 -0
  264. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/openscvx/symbolic/expr/constraint.py +0 -0
  265. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/openscvx/symbolic/expr/control.py +0 -0
  266. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/openscvx/symbolic/expr/expr.py +0 -0
  267. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/openscvx/symbolic/expr/lie/__init__.py +0 -0
  268. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/openscvx/symbolic/expr/lie/adjoint.py +0 -0
  269. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/openscvx/symbolic/expr/lie/se3.py +0 -0
  270. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/openscvx/symbolic/expr/lie/so3.py +0 -0
  271. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/openscvx/symbolic/expr/linalg.py +0 -0
  272. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/openscvx/symbolic/expr/logic.py +0 -0
  273. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/openscvx/symbolic/expr/math.py +0 -0
  274. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/openscvx/symbolic/expr/parameter.py +0 -0
  275. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/openscvx/symbolic/expr/spatial.py +0 -0
  276. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/openscvx/symbolic/expr/state.py +0 -0
  277. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/openscvx/symbolic/expr/stl.py +0 -0
  278. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/openscvx/symbolic/expr/stljax.py +0 -0
  279. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/openscvx/symbolic/expr/time.py +0 -0
  280. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/openscvx/symbolic/expr/variable.py +0 -0
  281. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/openscvx/symbolic/expr/vmap.py +0 -0
  282. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/openscvx/symbolic/hashing.py +0 -0
  283. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/openscvx/symbolic/lowerers/__init__.py +0 -0
  284. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/openscvx/symbolic/lowerers/cvxpy/__init__.py +0 -0
  285. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/openscvx/symbolic/lowerers/cvxpy/_lowerer.py +0 -0
  286. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/openscvx/symbolic/lowerers/cvxpy/_registry.py +0 -0
  287. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/openscvx/symbolic/lowerers/cvxpy/arithmetic.py +0 -0
  288. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/openscvx/symbolic/lowerers/cvxpy/array.py +0 -0
  289. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/openscvx/symbolic/lowerers/cvxpy/constraint.py +0 -0
  290. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/openscvx/symbolic/lowerers/cvxpy/control.py +0 -0
  291. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/openscvx/symbolic/lowerers/cvxpy/expr.py +0 -0
  292. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/openscvx/symbolic/lowerers/cvxpy/linalg.py +0 -0
  293. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/openscvx/symbolic/lowerers/cvxpy/logic.py +0 -0
  294. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/openscvx/symbolic/lowerers/cvxpy/math.py +0 -0
  295. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/openscvx/symbolic/lowerers/cvxpy/state.py +0 -0
  296. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/openscvx/symbolic/lowerers/jax/__init__.py +0 -0
  297. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/openscvx/symbolic/lowerers/jax/_lowerer.py +0 -0
  298. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/openscvx/symbolic/lowerers/jax/_registry.py +0 -0
  299. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/openscvx/symbolic/lowerers/jax/arithmetic.py +0 -0
  300. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/openscvx/symbolic/lowerers/jax/array.py +0 -0
  301. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/openscvx/symbolic/lowerers/jax/constraint.py +0 -0
  302. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/openscvx/symbolic/lowerers/jax/control.py +0 -0
  303. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/openscvx/symbolic/lowerers/jax/expr.py +0 -0
  304. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/openscvx/symbolic/lowerers/jax/lie.py +0 -0
  305. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/openscvx/symbolic/lowerers/jax/linalg.py +0 -0
  306. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/openscvx/symbolic/lowerers/jax/logic.py +0 -0
  307. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/openscvx/symbolic/lowerers/jax/math.py +0 -0
  308. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/openscvx/symbolic/lowerers/jax/spatial.py +0 -0
  309. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/openscvx/symbolic/lowerers/jax/state.py +0 -0
  310. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/openscvx/symbolic/lowerers/jax/stl.py +0 -0
  311. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/openscvx/symbolic/lowerers/jax/stljax.py +0 -0
  312. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/openscvx/symbolic/lowerers/jax/vmap.py +0 -0
  313. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/openscvx/symbolic/parser/__init__.py +0 -0
  314. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/openscvx/symbolic/parser/_registry.py +0 -0
  315. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/openscvx/symbolic/parser/array.py +0 -0
  316. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/openscvx/symbolic/parser/constraint.py +0 -0
  317. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/openscvx/symbolic/parser/lie.py +0 -0
  318. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/openscvx/symbolic/parser/linalg.py +0 -0
  319. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/openscvx/symbolic/parser/logic.py +0 -0
  320. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/openscvx/symbolic/parser/math.py +0 -0
  321. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/openscvx/symbolic/parser/parser.py +0 -0
  322. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/openscvx/symbolic/parser/spatial.py +0 -0
  323. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/openscvx/symbolic/parser/stl.py +0 -0
  324. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/openscvx/symbolic/parser/stljax.py +0 -0
  325. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/openscvx/symbolic/parser/tokenizer.py +0 -0
  326. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/openscvx/symbolic/preprocessing.py +0 -0
  327. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/openscvx/symbolic/problem.py +0 -0
  328. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/openscvx/symbolic/sparsity.py +0 -0
  329. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/openscvx/symbolic/unified.py +0 -0
  330. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/openscvx/utils/__init__.py +0 -0
  331. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/openscvx/utils/cache.py +0 -0
  332. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/openscvx/utils/caching.py +0 -0
  333. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/openscvx/utils/printing.py +0 -0
  334. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/openscvx/utils/profiling.py +0 -0
  335. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/openscvx/utils/utils.py +0 -0
  336. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/openscvx.egg-info/dependency_links.txt +0 -0
  337. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/openscvx.egg-info/entry_points.txt +0 -0
  338. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/openscvx.egg-info/requires.txt +0 -0
  339. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/openscvx.egg-info/top_level.txt +0 -0
  340. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/pyproject.toml +0 -0
  341. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/scripts/gen_example_pages.py +0 -0
  342. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/scripts/gen_ref_pages.py +0 -0
  343. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/scripts/mkdocs_copy_viser_client_hook.py +0 -0
  344. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/setup.cfg +0 -0
  345. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/tests/__init__.py +0 -0
  346. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/tests/_marks.py +0 -0
  347. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/tests/algorithms/__init__.py +0 -0
  348. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/tests/algorithms/_iteration_helpers.py +0 -0
  349. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/tests/algorithms/autotuner/__init__.py +0 -0
  350. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/tests/algorithms/autotuner/test_defaults_agreement.py +0 -0
  351. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/tests/algorithms/autotuner/test_hyper_overrides.py +0 -0
  352. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/tests/algorithms/autotuner/test_update_weights_jit.py +0 -0
  353. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/tests/algorithms/test_algorithm_state_pytree.py +0 -0
  354. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/tests/algorithms/test_iteration_fn_jit.py +0 -0
  355. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/tests/algorithms/test_iteration_fn_parity.py +0 -0
  356. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/tests/algorithms/test_make_solve_loop.py +0 -0
  357. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/tests/brachistochrone_analytical.py +0 -0
  358. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/tests/conftest.py +0 -0
  359. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/tests/expr/__init__.py +0 -0
  360. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/tests/expr/test_gmsr.py +0 -0
  361. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/tests/fixtures/brachistochrone.json +0 -0
  362. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/tests/fixtures/brachistochrone.yaml +0 -0
  363. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/tests/hohmann_analytical.py +0 -0
  364. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/tests/integrations/__init__.py +0 -0
  365. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/tests/integrations/test_mjx.py +0 -0
  366. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/tests/integrations/test_mjx_dynamics.py +0 -0
  367. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/tests/solvers/__init__.py +0 -0
  368. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/tests/solvers/_iteration_callback_helpers.py +0 -0
  369. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/tests/solvers/test_cvxpy_callback_jit_spike.py +0 -0
  370. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/tests/solvers/test_iteration_callback_cvxpy.py +0 -0
  371. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/tests/solvers/test_iteration_callback_moreau.py +0 -0
  372. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/tests/solvers/test_iteration_callback_qpax.py +0 -0
  373. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/tests/solvers/test_iteration_callback_vmap.py +0 -0
  374. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/tests/solvers/test_moreau_ptr_solver.py +0 -0
  375. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/tests/solvers/test_subproblem_pytree.py +0 -0
  376. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/tests/symbolic/__init__.py +0 -0
  377. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/tests/symbolic/expr/__init__.py +0 -0
  378. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/tests/symbolic/expr/test_arithmetic.py +0 -0
  379. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/tests/symbolic/expr/test_array.py +0 -0
  380. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/tests/symbolic/expr/test_constraint.py +0 -0
  381. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/tests/symbolic/expr/test_expr.py +0 -0
  382. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/tests/symbolic/expr/test_lie.py +0 -0
  383. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/tests/symbolic/expr/test_linalg.py +0 -0
  384. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/tests/symbolic/expr/test_logic.py +0 -0
  385. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/tests/symbolic/expr/test_math.py +0 -0
  386. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/tests/symbolic/expr/test_node_reference.py +0 -0
  387. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/tests/symbolic/expr/test_parameters.py +0 -0
  388. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/tests/symbolic/expr/test_scaling.py +0 -0
  389. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/tests/symbolic/expr/test_spatial.py +0 -0
  390. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/tests/symbolic/expr/test_stl.py +0 -0
  391. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/tests/symbolic/expr/test_variable.py +0 -0
  392. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/tests/symbolic/expr/test_vmap.py +0 -0
  393. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/tests/symbolic/parser/__init__.py +0 -0
  394. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/tests/symbolic/parser/test_array.py +0 -0
  395. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/tests/symbolic/parser/test_constraint.py +0 -0
  396. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/tests/symbolic/parser/test_lie.py +0 -0
  397. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/tests/symbolic/parser/test_linalg.py +0 -0
  398. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/tests/symbolic/parser/test_load.py +0 -0
  399. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/tests/symbolic/parser/test_logic.py +0 -0
  400. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/tests/symbolic/parser/test_math.py +0 -0
  401. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/tests/symbolic/parser/test_parser.py +0 -0
  402. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/tests/symbolic/parser/test_spatial.py +0 -0
  403. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/tests/symbolic/parser/test_stl.py +0 -0
  404. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/tests/symbolic/parser/test_tokenizer.py +0 -0
  405. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/tests/symbolic/parser/test_vmap.py +0 -0
  406. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/tests/symbolic/test_hashing.py +0 -0
  407. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/tests/symbolic/test_lower_cvxpy.py +0 -0
  408. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/tests/symbolic/test_lower_jax.py +0 -0
  409. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/tests/symbolic/test_preprocessing.py +0 -0
  410. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/tests/symbolic/test_sparsity.py +0 -0
  411. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/tests/symbolic/test_unified.py +0 -0
  412. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/tests/test_cvxpygen_optional.py +0 -0
  413. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/tests/test_discretization.py +0 -0
  414. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/tests/test_examples.py +0 -0
  415. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/tests/test_expert.py +0 -0
  416. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/tests/test_impulsive.py +0 -0
  417. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/tests/test_init.py +0 -0
  418. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/tests/test_integrators.py +0 -0
  419. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/tests/test_loader.py +0 -0
  420. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/tests/test_optimization_results.py +0 -0
  421. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/tests/test_plotting.py +0 -0
  422. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/tests/test_propagation.py +0 -0
  423. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/tests/test_solve_batched_brachistochrone.py +0 -0
  424. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/tests/test_solve_batched_cvxpy_export_errors.py +0 -0
  425. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/tests/test_solve_batched_export_roundtrip.py +0 -0
  426. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/tests/test_solve_batched_inference.py +0 -0
  427. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/tests/test_solve_jax_bare_brachistochrone.py +0 -0
  428. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/tests/test_solve_jax_jit_brachistochrone.py +0 -0
  429. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/tests/test_solve_jax_vmap_brachistochrone.py +0 -0
  430. {openscvx-0.5.3.dev30 → openscvx-0.5.3.dev32}/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.dev30
3
+ Version: 0.5.3.dev32
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
@@ -193,34 +193,17 @@ plotting_dict = {
193
193
 
194
194
  def _extract_multishot_position_segments(results) -> list[np.ndarray]:
195
195
  """Extract per-segment propagated states from SCP discretization history."""
196
- v_history = getattr(results, "discretization_history", None) or []
197
- if not v_history:
196
+ prop = results.multishot_propagation()
197
+ if prop is None:
198
198
  return []
199
-
200
- position_slice = None
201
- for state in results._states:
199
+ pos_slice = None
200
+ for state in prop.states:
202
201
  if state.name == "position":
203
- position_slice = state._slice
202
+ pos_slice = state._slice
204
203
  break
205
- if position_slice is None:
204
+ if pos_slice is None:
206
205
  return []
207
-
208
- n_x = results.x.shape[1]
209
- n_u = results.u.shape[1]
210
- i4 = n_x + n_x * n_x + 2 * n_x * n_u
211
-
212
- v = np.asarray(v_history[-1])
213
- n_segments = v.shape[0] // i4
214
- segments = []
215
- for seg_idx in range(n_segments):
216
- seg_start = seg_idx * i4
217
- seg_end = seg_start + i4
218
- seg_positions = []
219
- for t_idx in range(v.shape[1]):
220
- state = v[seg_start:seg_end, t_idx][:n_x]
221
- seg_positions.append(state[position_slice])
222
- segments.append(np.asarray(seg_positions))
223
- return segments
206
+ return [seg[:, pos_slice] for seg in prop.segments()]
224
207
 
225
208
 
226
209
  def _build_singleshot_propagated_trajectory(
@@ -388,7 +388,7 @@ if __name__ == "__main__":
388
388
 
389
389
  results.update_plotting_data(**plotting_dict)
390
390
 
391
- # Define the plane the logo actually lies in (from three points on the logo)
391
+ # Define the plane the logo actually lies in
392
392
  p0 = np.asarray(get_kp_pose(0.0))
393
393
  p1 = np.asarray(get_kp_pose(0.33))
394
394
  p2 = np.asarray(get_kp_pose(0.67))
@@ -248,43 +248,6 @@ def _compute_panda_keypoints(
248
248
  return keypoints, ee_pos
249
249
 
250
250
 
251
- def _q_from_V_multishot(
252
- V: np.ndarray,
253
- n_x: int,
254
- n_u: int,
255
- q_slice: slice,
256
- t_nodes: np.ndarray,
257
- ) -> tuple[np.ndarray | None, np.ndarray | None]:
258
- """Unpack joint angles from the SCP multi-shoot V matrix.
259
-
260
- V has shape ``((N-1) * i4, n_substeps)`` where
261
- ``i4 = n_x + n_x² + 2·n_x·n_u``. The first ``n_x`` rows of each
262
- ``i4``-row block are the integrated state at that substep.
263
-
264
- Returns ``(q_traj, t_traj)`` or ``(None, None)`` if extraction fails.
265
- """
266
- i4 = n_x + n_x * n_x + 2 * n_x * n_u
267
- n_rows, n_sub = V.shape
268
- if i4 <= 0 or n_rows % i4 != 0 or n_sub < 1:
269
- return None, None
270
- n_seg = n_rows // i4
271
- if n_seg != len(t_nodes) - 1:
272
- return None, None
273
- q_rows: list[np.ndarray] = []
274
- t_rows: list[float] = []
275
- for seg in range(n_seg):
276
- t0, t1 = float(t_nodes[seg]), float(t_nodes[seg + 1])
277
- j0 = 0 if seg == 0 else 1 # skip duplicated segment-start sample
278
- for j in range(j0, n_sub):
279
- alpha = j / (n_sub - 1) if n_sub > 1 else 0.0
280
- x_vec = np.asarray(V[seg * i4 : seg * i4 + n_x, j], dtype=np.float64)
281
- q_rows.append(x_vec[q_slice])
282
- t_rows.append((1.0 - alpha) * t0 + alpha * t1)
283
- if not q_rows:
284
- return None, None
285
- return np.stack(q_rows), np.asarray(t_rows, dtype=np.float64)
286
-
287
-
288
251
  def visualize(results, robot) -> None:
289
252
  """Animate the optimised trajectory in Viser (CAD mesh + markers).
290
253
 
@@ -307,22 +270,10 @@ def visualize(results, robot) -> None:
307
270
  q_traj = np.asarray(results.trajectory["q"])
308
271
 
309
272
  # ── Prefer multishot V over post-process single propagation ──────────────
310
- _dh = getattr(results, "discretization_history", None) or []
311
- if _dh:
312
- _V = np.asarray(_dh[-1], dtype=np.float64)
313
- _n_x = results.x.shape[1]
314
- _n_u = results.u.shape[1]
315
- _t_nodes_raw = results.nodes.get("time", None)
316
- if _t_nodes_raw is None:
317
- _t_nodes = np.linspace(0.0, float(t_vec[-1]), len(results.nodes["q"]))
318
- else:
319
- _t_nodes = np.asarray(_t_nodes_raw).flatten()
320
- _q_ms, _t_ms = _q_from_V_multishot(_V, _n_x, _n_u, q.slice, _t_nodes)
321
- if _q_ms is not None:
322
- print(f"[viser] Multishot V: {len(_q_ms)} frames across {len(_t_nodes) - 1} segments.")
323
- q_traj, t_vec = _q_ms, _t_ms
324
- else:
325
- print("[viser] Multishot V extraction failed; using post-process trajectory.")
273
+ prop = results.multishot_propagation()
274
+ if prop is not None:
275
+ q_traj, t_vec = prop.state("q")
276
+ print(f"[viser] Multishot V: {len(q_traj)} frames across {prop.n_segments} segments.")
326
277
 
327
278
  n_frames = len(q_traj)
328
279
  n_segs = robot.num_joints + 1
@@ -267,43 +267,6 @@ def _compute_panda_keypoints(
267
267
  return keypoints, ee_pos, ee_quats
268
268
 
269
269
 
270
- def _q_from_V_multishot(
271
- V: np.ndarray,
272
- n_x: int,
273
- n_u: int,
274
- q_slice: slice,
275
- t_nodes: np.ndarray,
276
- ) -> tuple[np.ndarray | None, np.ndarray | None]:
277
- """Unpack joint angles from the SCP multi-shoot V matrix.
278
-
279
- V has shape ``((N-1) * i4, n_substeps)`` where
280
- ``i4 = n_x + n_x² + 2·n_x·n_u``. The first ``n_x`` rows of each
281
- ``i4``-row block are the integrated state at that substep.
282
-
283
- Returns ``(q_traj, t_traj)`` or ``(None, None)`` if extraction fails.
284
- """
285
- i4 = n_x + n_x * n_x + 2 * n_x * n_u
286
- n_rows, n_sub = V.shape
287
- if i4 <= 0 or n_rows % i4 != 0 or n_sub < 1:
288
- return None, None
289
- n_seg = n_rows // i4
290
- if n_seg != len(t_nodes) - 1:
291
- return None, None
292
- q_rows: list[np.ndarray] = []
293
- t_rows: list[float] = []
294
- for seg in range(n_seg):
295
- t0, t1 = float(t_nodes[seg]), float(t_nodes[seg + 1])
296
- j0 = 0 if seg == 0 else 1 # skip duplicated segment-start sample
297
- for j in range(j0, n_sub):
298
- alpha = j / (n_sub - 1) if n_sub > 1 else 0.0
299
- x_vec = np.asarray(V[seg * i4 : seg * i4 + n_x, j], dtype=np.float64)
300
- q_rows.append(x_vec[q_slice])
301
- t_rows.append((1.0 - alpha) * t0 + alpha * t1)
302
- if not q_rows:
303
- return None, None
304
- return np.stack(q_rows), np.asarray(t_rows, dtype=np.float64)
305
-
306
-
307
270
  def visualize(results, robot) -> None:
308
271
  """Animate the trajectory in Viser: CAD mesh + viewcone + markers.
309
272
 
@@ -327,22 +290,10 @@ def visualize(results, robot) -> None:
327
290
  q_traj = np.asarray(results.trajectory["q"])
328
291
 
329
292
  # ── Prefer multishot V over post-process single propagation ──────────────
330
- _dh = getattr(results, "discretization_history", None) or []
331
- if _dh:
332
- _V = np.asarray(_dh[-1], dtype=np.float64)
333
- _n_x = results.x.shape[1]
334
- _n_u = results.u.shape[1]
335
- _t_nodes_raw = results.nodes.get("time", None)
336
- if _t_nodes_raw is None:
337
- _t_nodes = np.linspace(0.0, float(t_vec[-1]), len(results.nodes["q"]))
338
- else:
339
- _t_nodes = np.asarray(_t_nodes_raw).flatten()
340
- _q_ms, _t_ms = _q_from_V_multishot(_V, _n_x, _n_u, q.slice, _t_nodes)
341
- if _q_ms is not None:
342
- print(f"[viser] Multishot V: {len(_q_ms)} frames across {len(_t_nodes) - 1} segments.")
343
- q_traj, t_vec = _q_ms, _t_ms
344
- else:
345
- print("[viser] Multishot V extraction failed; using post-process trajectory.")
293
+ prop = results.multishot_propagation()
294
+ if prop is not None:
295
+ q_traj, t_vec = prop.state("q")
296
+ print(f"[viser] Multishot V: {len(q_traj)} frames across {prop.n_segments} segments.")
346
297
 
347
298
  n_frames = len(q_traj)
348
299
  n_segs = robot.num_joints + 1
@@ -197,43 +197,6 @@ def _compute_panda_keypoints(q_traj: np.ndarray, robot) -> tuple[np.ndarray, np.
197
197
  return keypoints, ee_pos
198
198
 
199
199
 
200
- def _q_from_V_multishot(
201
- V: np.ndarray,
202
- n_x: int,
203
- n_u: int,
204
- q_slice: slice,
205
- t_nodes: np.ndarray,
206
- ) -> tuple[np.ndarray | None, np.ndarray | None]:
207
- """Unpack joint angles from the SCP multi-shoot V matrix.
208
-
209
- V has shape ``((N-1) * i4, n_substeps)`` where
210
- ``i4 = n_x + n_x² + 2·n_x·n_u``. The first ``n_x`` rows of each
211
- ``i4``-row block are the integrated state at that substep.
212
-
213
- Returns ``(q_traj, t_traj)`` or ``(None, None)`` if extraction fails.
214
- """
215
- i4 = n_x + n_x * n_x + 2 * n_x * n_u
216
- n_rows, n_sub = V.shape
217
- if i4 <= 0 or n_rows % i4 != 0 or n_sub < 1:
218
- return None, None
219
- n_seg = n_rows // i4
220
- if n_seg != len(t_nodes) - 1:
221
- return None, None
222
- q_rows: list[np.ndarray] = []
223
- t_rows: list[float] = []
224
- for seg in range(n_seg):
225
- t0, t1 = float(t_nodes[seg]), float(t_nodes[seg + 1])
226
- j0 = 0 if seg == 0 else 1 # skip duplicated segment-start sample
227
- for j in range(j0, n_sub):
228
- alpha = j / (n_sub - 1) if n_sub > 1 else 0.0
229
- x_vec = np.asarray(V[seg * i4 : seg * i4 + n_x, j], dtype=np.float64)
230
- q_rows.append(x_vec[q_slice])
231
- t_rows.append((1.0 - alpha) * t0 + alpha * t1)
232
- if not q_rows:
233
- return None, None
234
- return np.stack(q_rows), np.asarray(t_rows, dtype=np.float64)
235
-
236
-
237
200
  def visualize(
238
201
  results,
239
202
  robot,
@@ -265,31 +228,18 @@ def visualize(
265
228
  tau_traj = np.asarray(results.trajectory["tau"])
266
229
 
267
230
  # ── Prefer multishot V over post-process single propagation ──────────────
268
- _dh = getattr(results, "discretization_history", None) or []
269
- if _dh:
270
- _V = np.asarray(_dh[-1], dtype=np.float64)
271
- _n_x = results.x.shape[1]
272
- _n_u = results.u.shape[1]
273
- _t_nodes_raw = results.nodes.get("time", None)
274
- if _t_nodes_raw is None:
275
- _t_nodes = np.linspace(0.0, float(t_vec[-1]), len(results.nodes["q"]))
276
- else:
277
- _t_nodes = np.asarray(_t_nodes_raw).flatten()
278
- _q_ms, _t_ms = _q_from_V_multishot(_V, _n_x, _n_u, q.slice, _t_nodes)
279
- if _q_ms is not None:
280
- print(f"[viser] Multishot V: {len(_q_ms)} frames across {len(_t_nodes) - 1} segments.")
281
- q_traj, t_vec = _q_ms, _t_ms
282
- # Torque is ZOH: replicate each node's tau value across its substeps.
283
- _tau_nodes = np.asarray(results.nodes["tau"])
284
- _n_sub = _V.shape[1]
285
- _tau_rows: list[np.ndarray] = []
286
- for _seg in range(len(_t_nodes) - 1):
287
- _j0 = 0 if _seg == 0 else 1
288
- for _j in range(_j0, _n_sub):
289
- _tau_rows.append(_tau_nodes[_seg])
290
- tau_traj = np.stack(_tau_rows)
291
- else:
292
- print("[viser] Multishot V extraction failed; using post-process trajectory.")
231
+ prop = results.multishot_propagation()
232
+ if prop is not None:
233
+ q_traj, t_vec = prop.state("q")
234
+ print(f"[viser] Multishot V: {len(q_traj)} frames across {prop.n_segments} segments.")
235
+ # Torque is ZOH: replicate each node's tau value across its substeps.
236
+ _tau_nodes = np.asarray(results.nodes["tau"])
237
+ _tau_rows: list[np.ndarray] = []
238
+ for _seg in range(prop.n_segments):
239
+ _j0 = 0 if _seg == 0 else 1
240
+ for _j in range(_j0, prop.n_substeps):
241
+ _tau_rows.append(_tau_nodes[_seg])
242
+ tau_traj = np.stack(_tau_rows)
293
243
 
294
244
  keypoints, ee_pos = _compute_panda_keypoints(q_traj, robot)
295
245
  n_segs = robot.num_joints + 1
@@ -212,44 +212,6 @@ def simulate_mujoco(results) -> dict:
212
212
  return {"time": rec_t, "qpos": rec_q, "qvel": rec_qd}
213
213
 
214
214
 
215
- def qpos_from_V_multishot(
216
- V: np.ndarray,
217
- *,
218
- n_q: int,
219
- n_v: int,
220
- n_u: int,
221
- t_nodes: np.ndarray,
222
- ) -> tuple[np.ndarray | None, np.ndarray | None]:
223
- """Unpack generalized coordinates from the SCP multi-shoot matrix ``V``."""
224
- if V.size == 0:
225
- return None, None
226
- n_x = n_q + n_v
227
- i4 = n_x + n_x * n_x + 2 * n_x * n_u
228
- n_rows, n_sub = V.shape
229
- if i4 <= 0 or n_rows % i4 != 0 or n_sub < 1:
230
- return None, None
231
- n_seg = n_rows // i4
232
- if n_seg != len(t_nodes) - 1:
233
- return None, None
234
-
235
- q_rows: list[np.ndarray] = []
236
- t_rows: list[float] = []
237
- for seg in range(n_seg):
238
- t0 = float(t_nodes[seg])
239
- t1 = float(t_nodes[seg + 1])
240
- j0 = 0 if seg == 0 else 1
241
- for j in range(j0, n_sub):
242
- alpha = j / (n_sub - 1) if n_sub > 1 else 0.0
243
- t_s = (1.0 - alpha) * t0 + alpha * t1
244
- row0 = seg * i4
245
- x_vec = np.asarray(V[row0 : row0 + n_x, j], dtype=np.float64).ravel()
246
- q_rows.append(x_vec[:n_q])
247
- t_rows.append(t_s)
248
- if not q_rows:
249
- return None, None
250
- return np.stack(q_rows, axis=0), np.asarray(t_rows, dtype=np.float64)
251
-
252
-
253
215
  def visualize(results, sim: dict | None = None) -> None:
254
216
  """Animate the double-link cartpole in a Viser 3D scene.
255
217
 
@@ -288,21 +250,9 @@ def visualize(results, sim: dict | None = None) -> None:
288
250
  fk_nodes = [fk_joints(q_nodes[i]) for i in range(len(q_nodes))]
289
251
 
290
252
  # Multi-shoot integrated trajectory from ``V``
291
- _dh = getattr(results, "discretization_history", None) or []
292
- V_multishot = _dh[-1] if len(_dh) > 0 else None
293
- q_ms_v, t_ms_v = (
294
- qpos_from_V_multishot(
295
- np.asarray(V_multishot, dtype=np.float64),
296
- n_q=n_q,
297
- n_v=n_v,
298
- n_u=n_u,
299
- t_nodes=t_nodes,
300
- )
301
- if V_multishot is not None
302
- else (None, None)
303
- )
304
-
305
- if q_ms_v is not None and t_ms_v is not None:
253
+ prop = results.multishot_propagation(t_nodes=t_nodes)
254
+ if prop is not None:
255
+ q_ms_v, t_ms_v = prop.state("qpos")
306
256
  fk_multishot_anim = [fk_joints(q_ms_v[i]) for i in range(len(q_ms_v))]
307
257
  t_multishot_lookup = t_ms_v
308
258
  else:
@@ -59,7 +59,6 @@ except ImportError:
59
59
  import openscvx as ox
60
60
  from examples.plotting_viser import (
61
61
  create_snapshot_plotting_server,
62
- extract_multishoot_trajectory,
63
62
  )
64
63
  from openscvx import Problem
65
64
 
@@ -252,62 +251,6 @@ def _foh_controls_at_times(
252
251
  return u_out
253
252
 
254
253
 
255
- def extract_multishoot_qpos_chronological(
256
- V_multi_shoot: np.ndarray,
257
- *,
258
- n_x: int,
259
- n_u: int,
260
- n_q: int,
261
- t_nodes: np.ndarray,
262
- ) -> tuple[np.ndarray, np.ndarray, np.ndarray, np.ndarray] | None:
263
- """Unpack propagated states from ``V`` in time order (SCP / realtime layout).
264
-
265
- ``V`` has shape ``((N-1) * segment_size, n_substeps)``. Each segment block
266
- stores the integrated state in its first ``n_x`` rows at every substep column.
267
- This matches :func:`openscvx.plotting.viser.scp.extract_propagation_positions`
268
- and the realtime ``extract_multishoot_trajectory`` helpers — **not** nodal
269
- linear interpolation of ``results.nodes``.
270
- """
271
- V_multi_shoot = np.asarray(V_multi_shoot, dtype=np.float64)
272
- if V_multi_shoot.size == 0:
273
- return None
274
-
275
- segment_size = n_x + n_x * n_x + 2 * n_x * n_u
276
- n_rows, n_sub = V_multi_shoot.shape
277
- if segment_size <= 0 or n_rows % segment_size != 0 or n_sub < 1:
278
- return None
279
- n_seg = n_rows // segment_size
280
-
281
- t_nodes = np.asarray(t_nodes, dtype=np.float64).ravel()
282
- if t_nodes.size != n_seg + 1:
283
- if t_nodes.size < 2:
284
- return None
285
- t_nodes = np.linspace(float(t_nodes[0]), float(t_nodes[-1]), n_seg + 1)
286
-
287
- q_rows: list[np.ndarray] = []
288
- qd_rows: list[np.ndarray] = []
289
- t_rows: list[float] = []
290
- for seg_idx in range(n_seg):
291
- seg_start = seg_idx * segment_size
292
- t0, t1 = float(t_nodes[seg_idx]), float(t_nodes[seg_idx + 1])
293
- j0 = 0 if seg_idx == 0 else 1
294
- for t_idx in range(j0, n_sub):
295
- alpha = t_idx / (n_sub - 1) if n_sub > 1 else 0.0
296
- state = np.asarray(
297
- V_multi_shoot[seg_start : seg_start + n_x, t_idx], dtype=np.float64
298
- ).ravel()
299
- q_rows.append(state[:n_q])
300
- qd_rows.append(state[n_q:n_x])
301
- t_rows.append((1.0 - alpha) * t0 + alpha * t1)
302
- if not q_rows:
303
- return None
304
-
305
- t_ms = np.asarray(t_rows, dtype=np.float64)
306
- q_ms = np.stack(q_rows, axis=0)
307
- qd_ms = np.stack(qd_rows, axis=0)
308
- return q_ms, qd_ms, t_ms, t_nodes
309
-
310
-
311
254
  def segment_tip_paths_from_V(
312
255
  V_multi_shoot: np.ndarray,
313
256
  *,
@@ -362,23 +305,11 @@ def visualize(results) -> None:
362
305
  else:
363
306
  t_nodes = np.asarray(t_nodes).flatten()
364
307
 
365
- _dh = getattr(results, "discretization_history", None) or []
366
- V_multishot = np.asarray(_dh[-1], dtype=np.float64) if len(_dh) > 0 else None
367
- ms_traj = (
368
- extract_multishoot_qpos_chronological(
369
- V_multishot,
370
- n_x=n_x,
371
- n_u=n_u,
372
- n_q=n_q,
373
- t_nodes=t_nodes,
374
- )
375
- if V_multishot is not None
376
- else None
377
- )
378
-
379
- using_multishot = ms_traj is not None
308
+ prop = results.multishot_propagation(t_nodes=t_nodes)
309
+ using_multishot = prop is not None
380
310
  if using_multishot:
381
- q_angle, _, t_play, t_nodes_ms = ms_traj
311
+ q_angle, t_play = prop.state("qpos")
312
+ t_nodes_ms = prop.t_nodes
382
313
  u_play = _foh_controls_at_times(t_play, u_nodes, t_nodes_ms)
383
314
  fk_multishot_anim = [fk_joints(q_angle[i]) for i in range(len(q_angle))]
384
315
  tip_pos = np.array([fk[4] for fk in fk_multishot_anim], dtype=np.float64)
@@ -386,12 +317,13 @@ def visualize(results) -> None:
386
317
  tip_vel = np.gradient(tip_pos, t_play, axis=0)
387
318
  else:
388
319
  tip_vel = np.zeros_like(tip_pos)
389
- n_seg = V_multishot.shape[0] // (n_x + n_x * n_x + 2 * n_x * n_u)
320
+ V_multishot = prop.V
390
321
  print(
391
322
  f"[viser] Multi-shoot V: {len(t_play)} propagated samples "
392
- f"({V_multishot.shape[1]} cols × {n_seg} segments)."
323
+ f"({prop.n_substeps} cols × {prop.n_segments} segments)."
393
324
  )
394
325
  else:
326
+ V_multishot = None
395
327
  print(
396
328
  "[viser] WARNING: could not decode discretization_history V; "
397
329
  "falling back to nodal linear interpolation."
@@ -481,13 +413,7 @@ def visualize(results) -> None:
481
413
  tip_multishot_segs = None
482
414
  if using_multishot and V_multishot is not None:
483
415
  # Faint cloud of every integrated state (realtime-style unpack).
484
- all_qpos, _ = extract_multishoot_trajectory(
485
- V_multishot,
486
- n_x,
487
- n_u,
488
- position_slice=slice(0, n_q),
489
- velocity_slice=None,
490
- )
416
+ all_qpos, _ = prop.state("qpos")
491
417
  if len(all_qpos) > 0:
492
418
  tip_cloud = np.array(
493
419
  [fk_joints(all_qpos[i])[4] for i in range(len(all_qpos))],
@@ -37,7 +37,6 @@ except ImportError:
37
37
  import openscvx as ox
38
38
  from examples.plotting_viser import (
39
39
  create_snapshot_plotting_server,
40
- extract_multishoot_trajectory,
41
40
  )
42
41
  from openscvx import Problem
43
42
 
@@ -175,55 +174,6 @@ def _foh_controls_at_times(
175
174
  return u_out
176
175
 
177
176
 
178
- def extract_multishoot_qpos_chronological(
179
- V_multi_shoot: np.ndarray,
180
- *,
181
- n_x: int,
182
- n_u: int,
183
- n_q: int,
184
- t_nodes: np.ndarray,
185
- ) -> tuple[np.ndarray, np.ndarray, np.ndarray, np.ndarray] | None:
186
- """Unpack propagated states from ``V`` in time order (SCP / realtime layout)."""
187
- V_multi_shoot = np.asarray(V_multi_shoot, dtype=np.float64)
188
- if V_multi_shoot.size == 0:
189
- return None
190
-
191
- segment_size = n_x + n_x * n_x + 2 * n_x * n_u
192
- n_rows, n_sub = V_multi_shoot.shape
193
- if segment_size <= 0 or n_rows % segment_size != 0 or n_sub < 1:
194
- return None
195
- n_seg = n_rows // segment_size
196
-
197
- t_nodes = np.asarray(t_nodes, dtype=np.float64).ravel()
198
- if t_nodes.size != n_seg + 1:
199
- if t_nodes.size < 2:
200
- return None
201
- t_nodes = np.linspace(float(t_nodes[0]), float(t_nodes[-1]), n_seg + 1)
202
-
203
- q_rows: list[np.ndarray] = []
204
- qd_rows: list[np.ndarray] = []
205
- t_rows: list[float] = []
206
- for seg_idx in range(n_seg):
207
- seg_start = seg_idx * segment_size
208
- t0, t1 = float(t_nodes[seg_idx]), float(t_nodes[seg_idx + 1])
209
- j0 = 0 if seg_idx == 0 else 1
210
- for t_idx in range(j0, n_sub):
211
- alpha = t_idx / (n_sub - 1) if n_sub > 1 else 0.0
212
- state = np.asarray(
213
- V_multi_shoot[seg_start : seg_start + n_x, t_idx], dtype=np.float64
214
- ).ravel()
215
- q_rows.append(state[:n_q])
216
- qd_rows.append(state[n_q:n_x])
217
- t_rows.append((1.0 - alpha) * t0 + alpha * t1)
218
- if not q_rows:
219
- return None
220
-
221
- t_ms = np.asarray(t_rows, dtype=np.float64)
222
- q_ms = np.stack(q_rows, axis=0)
223
- qd_ms = np.stack(qd_rows, axis=0)
224
- return q_ms, qd_ms, t_ms, t_nodes
225
-
226
-
227
177
  def segment_tip_paths_from_V(
228
178
  V_multi_shoot: np.ndarray,
229
179
  *,
@@ -277,23 +227,11 @@ def visualize(results) -> None:
277
227
  else:
278
228
  t_nodes = np.asarray(t_nodes).flatten()
279
229
 
280
- _dh = getattr(results, "discretization_history", None) or []
281
- V_multishot = np.asarray(_dh[-1], dtype=np.float64) if len(_dh) > 0 else None
282
- ms_traj = (
283
- extract_multishoot_qpos_chronological(
284
- V_multishot,
285
- n_x=n_x,
286
- n_u=n_u,
287
- n_q=n_q,
288
- t_nodes=t_nodes,
289
- )
290
- if V_multishot is not None
291
- else None
292
- )
293
-
294
- using_multishot = ms_traj is not None
230
+ prop = results.multishot_propagation(t_nodes=t_nodes)
231
+ using_multishot = prop is not None
295
232
  if using_multishot:
296
- q_angle, _, t_play, t_nodes_ms = ms_traj
233
+ q_angle, t_play = prop.state("qpos")
234
+ t_nodes_ms = prop.t_nodes
297
235
  u_play = _foh_controls_at_times(t_play, u_nodes, t_nodes_ms)
298
236
  fk_multishot_anim = [fk_joints(q_angle[i]) for i in range(len(q_angle))]
299
237
  tip_pos = np.array([fk[4] for fk in fk_multishot_anim], dtype=np.float64)
@@ -301,12 +239,13 @@ def visualize(results) -> None:
301
239
  tip_vel = np.gradient(tip_pos, t_play, axis=0)
302
240
  else:
303
241
  tip_vel = np.zeros_like(tip_pos)
304
- n_seg = V_multishot.shape[0] // (n_x + n_x * n_x + 2 * n_x * n_u)
242
+ V_multishot = prop.V
305
243
  print(
306
244
  f"[viser] Multi-shoot V: {len(t_play)} propagated samples "
307
- f"({V_multishot.shape[1]} cols × {n_seg} segments)."
245
+ f"({prop.n_substeps} cols × {prop.n_segments} segments)."
308
246
  )
309
247
  else:
248
+ V_multishot = None
310
249
  print(
311
250
  "[viser] WARNING: could not decode discretization_history V; "
312
251
  "falling back to nodal linear interpolation."
@@ -363,13 +302,7 @@ def visualize(results) -> None:
363
302
  cart_multishot_segs = None
364
303
  tip_multishot_segs = None
365
304
  if using_multishot and V_multishot is not None:
366
- all_qpos, _ = extract_multishoot_trajectory(
367
- V_multishot,
368
- n_x,
369
- n_u,
370
- position_slice=slice(0, n_q),
371
- velocity_slice=None,
372
- )
305
+ all_qpos, _ = prop.state("qpos")
373
306
  if len(all_qpos) > 0:
374
307
  tip_cloud = np.array(
375
308
  [fk_joints(all_qpos[i])[4] for i in range(len(all_qpos))],
@@ -1756,12 +1756,10 @@ def extract_multishoot_trajectory(
1756
1756
  ) -> tuple[np.ndarray, np.ndarray | None]:
1757
1757
  """Extract position and velocity trajectories from multi-shoot data.
1758
1758
 
1759
- The multi-shoot format stores propagation segments with state, STM, and
1760
- sensitivity data packed together. This function extracts the state
1761
- components from each segment.
1759
+ Uses time-ordered chronological stitching with deduplicated segment boundaries.
1762
1760
 
1763
1761
  Args:
1764
- V_multi_shoot: Multi-shoot data array of shape (n_segments * segment_size, n_nodes)
1762
+ V_multi_shoot: Multi-shoot data array of shape (n_segments * segment_size, n_substeps)
1765
1763
  n_x: Number of states
1766
1764
  n_u: Number of controls
1767
1765
  position_slice: Slice for extracting position from state (default: first 3)
@@ -1772,30 +1770,19 @@ def extract_multishoot_trajectory(
1772
1770
  Tuple of (positions, velocities) as float32 arrays.
1773
1771
  positions: Shape (n_total_points, 3)
1774
1772
  velocities: Shape (n_total_points, 3) or None if velocity_slice is None
1775
-
1776
- Note:
1777
- The segment size is computed as: n_x + n_x² + 2*n_x*n_u
1778
- This accounts for: state (n_x) + STM (n_x²) + sensitivities (2*n_x*n_u)
1779
1773
  """
1780
- # Segment size: state + STM + control sensitivities
1781
- segment_size = n_x + n_x * n_x + 2 * n_x * n_u
1782
-
1783
- all_pos_segments = []
1784
- all_vel_segments = [] if velocity_slice is not None else None
1785
-
1786
- for i_node in range(V_multi_shoot.shape[1]):
1787
- node_data = V_multi_shoot[:, i_node]
1788
- segments_for_node = node_data.reshape(-1, segment_size)
1789
- pos_segments = segments_for_node[:, position_slice]
1790
- all_pos_segments.append(pos_segments)
1791
-
1792
- if velocity_slice is not None:
1793
- vel_segments = segments_for_node[:, velocity_slice]
1794
- all_vel_segments.append(vel_segments)
1795
-
1796
- positions = np.vstack(all_pos_segments).astype(np.float32)
1797
- velocities = np.vstack(all_vel_segments).astype(np.float32) if all_vel_segments else None
1798
-
1774
+ from openscvx.algorithms.history import unpack_multishot_V
1775
+
1776
+ n_segments = V_multi_shoot.shape[0] // (n_x + n_x * n_x + 2 * n_x * n_u)
1777
+ placeholder_t = np.linspace(0.0, 1.0, n_segments + 1)
1778
+ prop = unpack_multishot_V(V_multi_shoot, n_x=n_x, n_u=n_u, t_nodes=placeholder_t, states=())
1779
+ positions, _ = prop.slice_states(position_slice)
1780
+ positions = positions.astype(np.float32)
1781
+ if velocity_slice is not None:
1782
+ velocities, _ = prop.slice_states(velocity_slice)
1783
+ velocities = velocities.astype(np.float32)
1784
+ else:
1785
+ velocities = None
1799
1786
  return positions, velocities
1800
1787
 
1801
1788