openscvx 2.dev4__tar.gz → 2.dev6__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 (357) hide show
  1. {openscvx-2.dev4/openscvx.egg-info → openscvx-2.dev6}/PKG-INFO +1 -1
  2. {openscvx-2.dev4 → openscvx-2.dev6}/examples/mjx/cartpole_mjx.py +13 -19
  3. {openscvx-2.dev4 → openscvx-2.dev6}/examples/mjx/double_cartpole_mjx.py +9 -18
  4. {openscvx-2.dev4 → openscvx-2.dev6}/examples/mjx/skydio_x2_mjx.py +14 -21
  5. {openscvx-2.dev4 → openscvx-2.dev6}/examples/mjx/triple_cartpole_3d_mjx.py +9 -18
  6. {openscvx-2.dev4 → openscvx-2.dev6}/examples/mjx/triple_cartpole_mjx.py +10 -19
  7. {openscvx-2.dev4 → openscvx-2.dev6}/openscvx/__init__.py +6 -0
  8. {openscvx-2.dev4 → openscvx-2.dev6}/openscvx/_version.py +3 -3
  9. {openscvx-2.dev4 → openscvx-2.dev6}/openscvx/algorithms/__init__.py +13 -4
  10. openscvx-2.dev6/openscvx/algorithms/autotuner/__init__.py +17 -0
  11. openscvx-2.dev6/openscvx/algorithms/autotuner/adaptive_proximal_weight.py +190 -0
  12. {openscvx-2.dev4/openscvx/algorithms → openscvx-2.dev6/openscvx/algorithms/autotuner}/augmented_lagrangian.py +9 -5
  13. {openscvx-2.dev4/openscvx/algorithms → openscvx-2.dev6/openscvx/algorithms/autotuner}/constant_proximal_weight.py +3 -3
  14. {openscvx-2.dev4/openscvx/algorithms → openscvx-2.dev6/openscvx/algorithms/autotuner}/ramp_proximal_weight.py +3 -3
  15. openscvx-2.dev6/openscvx/algorithms/scvx/__init__.py +5 -0
  16. {openscvx-2.dev4/openscvx/algorithms → openscvx-2.dev6/openscvx/algorithms/scvx}/penalized_trust_region.py +6 -6
  17. openscvx-2.dev6/openscvx/integrations/__init__.py +66 -0
  18. openscvx-2.dev6/openscvx/integrations/base.py +89 -0
  19. openscvx-2.dev6/openscvx/integrations/mjx.py +496 -0
  20. {openscvx-2.dev4 → openscvx-2.dev6}/openscvx/problem.py +13 -4
  21. {openscvx-2.dev4 → openscvx-2.dev6/openscvx.egg-info}/PKG-INFO +1 -1
  22. {openscvx-2.dev4 → openscvx-2.dev6}/openscvx.egg-info/SOURCES.txt +9 -4
  23. {openscvx-2.dev4 → openscvx-2.dev6}/tests/integrations/test_mjx.py +2 -69
  24. openscvx-2.dev6/tests/integrations/test_mjx_dynamics.py +542 -0
  25. {openscvx-2.dev4 → openscvx-2.dev6}/tests/test_autotuning.py +196 -4
  26. {openscvx-2.dev4 → openscvx-2.dev6}/tests/test_brachistochrone.py +3 -0
  27. openscvx-2.dev4/openscvx/integrations/__init__.py +0 -62
  28. openscvx-2.dev4/openscvx/integrations/mjx.py +0 -323
  29. {openscvx-2.dev4 → openscvx-2.dev6}/.github/assets/logo.svg +0 -0
  30. {openscvx-2.dev4 → openscvx-2.dev6}/.github/release-drafter.yml +0 -0
  31. {openscvx-2.dev4 → openscvx-2.dev6}/.github/workflows/_docs.yml +0 -0
  32. {openscvx-2.dev4 → openscvx-2.dev6}/.github/workflows/branch-name.yml +0 -0
  33. {openscvx-2.dev4 → openscvx-2.dev6}/.github/workflows/docs.yml +0 -0
  34. {openscvx-2.dev4 → openscvx-2.dev6}/.github/workflows/lint.yml +0 -0
  35. {openscvx-2.dev4 → openscvx-2.dev6}/.github/workflows/nightly.yml +0 -0
  36. {openscvx-2.dev4 → openscvx-2.dev6}/.github/workflows/release-drafter.yml +0 -0
  37. {openscvx-2.dev4 → openscvx-2.dev6}/.github/workflows/release.yml +0 -0
  38. {openscvx-2.dev4 → openscvx-2.dev6}/.github/workflows/tests-integration.yml +0 -0
  39. {openscvx-2.dev4 → openscvx-2.dev6}/.github/workflows/tests-unit.yml +0 -0
  40. {openscvx-2.dev4 → openscvx-2.dev6}/.gitignore +0 -0
  41. {openscvx-2.dev4 → openscvx-2.dev6}/.gitmodules +0 -0
  42. {openscvx-2.dev4 → openscvx-2.dev6}/CONTRIBUTING.md +0 -0
  43. {openscvx-2.dev4 → openscvx-2.dev6}/LICENSE +0 -0
  44. {openscvx-2.dev4 → openscvx-2.dev6}/README.md +0 -0
  45. {openscvx-2.dev4 → openscvx-2.dev6}/docs/Foundations/constraint_reformulation.md +0 -0
  46. {openscvx-2.dev4 → openscvx-2.dev6}/docs/Foundations/control_parameterization.md +0 -0
  47. {openscvx-2.dev4 → openscvx-2.dev6}/docs/Foundations/discretization.md +0 -0
  48. {openscvx-2.dev4 → openscvx-2.dev6}/docs/Foundations/ocp.md +0 -0
  49. {openscvx-2.dev4 → openscvx-2.dev6}/docs/Foundations/scvx.md +0 -0
  50. {openscvx-2.dev4 → openscvx-2.dev6}/docs/Foundations/time_dilation.md +0 -0
  51. {openscvx-2.dev4 → openscvx-2.dev6}/docs/UnderTheHood/lowering_architecture.md +0 -0
  52. {openscvx-2.dev4 → openscvx-2.dev6}/docs/UnderTheHood/vectorization_and_vmapping.md +0 -0
  53. {openscvx-2.dev4 → openscvx-2.dev6}/docs/UsersGuide/00_introduction.md +0 -0
  54. {openscvx-2.dev4 → openscvx-2.dev6}/docs/UsersGuide/01_hello_world_brachistochrone.md +0 -0
  55. {openscvx-2.dev4 → openscvx-2.dev6}/docs/UsersGuide/02_drone_racing_constraints.md +0 -0
  56. {openscvx-2.dev4 → openscvx-2.dev6}/docs/UsersGuide/03_obstacle_avoidance_vmap.md +0 -0
  57. {openscvx-2.dev4 → openscvx-2.dev6}/docs/UsersGuide/04_viewpoint_constraints.md +0 -0
  58. {openscvx-2.dev4 → openscvx-2.dev6}/docs/UsersGuide/05_visualization.md +0 -0
  59. {openscvx-2.dev4 → openscvx-2.dev6}/docs/UsersGuide/06_logic.md +0 -0
  60. {openscvx-2.dev4 → openscvx-2.dev6}/docs/UsersGuide/07_lie.md +0 -0
  61. {openscvx-2.dev4 → openscvx-2.dev6}/docs/UsersGuide/08_mpcc.md +0 -0
  62. {openscvx-2.dev4 → openscvx-2.dev6}/docs/assets/favicon.png +0 -0
  63. {openscvx-2.dev4 → openscvx-2.dev6}/docs/assets/images/ct-scvx_dark.png +0 -0
  64. {openscvx-2.dev4 → openscvx-2.dev6}/docs/assets/images/ct-scvx_light.png +0 -0
  65. {openscvx-2.dev4 → openscvx-2.dev6}/docs/assets/images/ctcs_dark.png +0 -0
  66. {openscvx-2.dev4 → openscvx-2.dev6}/docs/assets/images/ctcs_light.png +0 -0
  67. {openscvx-2.dev4 → openscvx-2.dev6}/docs/assets/images/problem_class_dark.png +0 -0
  68. {openscvx-2.dev4 → openscvx-2.dev6}/docs/assets/images/problem_class_light.png +0 -0
  69. {openscvx-2.dev4 → openscvx-2.dev6}/docs/assets/logo.svg +0 -0
  70. {openscvx-2.dev4 → openscvx-2.dev6}/docs/assets/openscvx_logo_square.png +0 -0
  71. {openscvx-2.dev4 → openscvx-2.dev6}/docs/assets/viser-client/index.html +0 -0
  72. {openscvx-2.dev4 → openscvx-2.dev6}/docs/assets/viser-recordings/drone_racing.viser +0 -0
  73. {openscvx-2.dev4 → openscvx-2.dev6}/docs/assets/viser-recordings/franka_fr3v2_pick_place.viser +0 -0
  74. {openscvx-2.dev4 → openscvx-2.dev6}/docs/citation.md +0 -0
  75. {openscvx-2.dev4 → openscvx-2.dev6}/docs/examples.md +0 -0
  76. {openscvx-2.dev4 → openscvx-2.dev6}/docs/index.md +0 -0
  77. {openscvx-2.dev4 → openscvx-2.dev6}/docs/javascripts/mathjax.js +0 -0
  78. {openscvx-2.dev4 → openscvx-2.dev6}/docs/versions.json +0 -0
  79. {openscvx-2.dev4 → openscvx-2.dev6}/examples/_viser_embed_export.py +0 -0
  80. {openscvx-2.dev4 → openscvx-2.dev6}/examples/abstract/brachistochrone.py +0 -0
  81. {openscvx-2.dev4 → openscvx-2.dev6}/examples/abstract/hypersensitive.py +0 -0
  82. {openscvx-2.dev4 → openscvx-2.dev6}/examples/abstract/impulsive.py +0 -0
  83. {openscvx-2.dev4 → openscvx-2.dev6}/examples/abstract/stl_integer_variable.py +0 -0
  84. {openscvx-2.dev4 → openscvx-2.dev6}/examples/abstract/stl_or.py +0 -0
  85. {openscvx-2.dev4 → openscvx-2.dev6}/examples/animations/7_dof_arm.py +0 -0
  86. {openscvx-2.dev4 → openscvx-2.dev6}/examples/animations/_camera.py +0 -0
  87. {openscvx-2.dev4 → openscvx-2.dev6}/examples/animations/_render.py +0 -0
  88. {openscvx-2.dev4 → openscvx-2.dev6}/examples/animations/_sensor_view.py +0 -0
  89. {openscvx-2.dev4 → openscvx-2.dev6}/examples/animations/dr_vp_polytope.py +0 -0
  90. {openscvx-2.dev4 → openscvx-2.dev6}/examples/animations/franka_fr3v2_pick_place.py +0 -0
  91. {openscvx-2.dev4 → openscvx-2.dev6}/examples/animations/logo.py +0 -0
  92. {openscvx-2.dev4 → openscvx-2.dev6}/examples/animations/obstacle_avoidance_vmap.py +0 -0
  93. {openscvx-2.dev4 → openscvx-2.dev6}/examples/arm/3_dof_arm.py +0 -0
  94. {openscvx-2.dev4 → openscvx-2.dev6}/examples/arm/7_dof_arm.py +0 -0
  95. {openscvx-2.dev4 → openscvx-2.dev6}/examples/arm/7_dof_arm_collision.py +0 -0
  96. {openscvx-2.dev4 → openscvx-2.dev6}/examples/arm/7_dof_arm_vp.py +0 -0
  97. {openscvx-2.dev4 → openscvx-2.dev6}/examples/arm/franka_fr3v2_pick_place.py +0 -0
  98. {openscvx-2.dev4 → openscvx-2.dev6}/examples/arm/franka_fr3v2_viewplanning.py +0 -0
  99. {openscvx-2.dev4 → openscvx-2.dev6}/examples/car/dubins_car.py +0 -0
  100. {openscvx-2.dev4 → openscvx-2.dev6}/examples/car/dubins_car_disjoint.py +0 -0
  101. {openscvx-2.dev4 → openscvx-2.dev6}/examples/car/dubins_car_obstacle_conditional.py +0 -0
  102. {openscvx-2.dev4 → openscvx-2.dev6}/examples/car/dubins_car_obstacle_stl.py +0 -0
  103. {openscvx-2.dev4 → openscvx-2.dev6}/examples/car/dubins_car_stl_or.py +0 -0
  104. {openscvx-2.dev4 → openscvx-2.dev6}/examples/car/dubins_car_waypoint_stl.py +0 -0
  105. {openscvx-2.dev4 → openscvx-2.dev6}/examples/drone/cinema_vp.py +0 -0
  106. {openscvx-2.dev4 → openscvx-2.dev6}/examples/drone/dr_double_integrator.py +0 -0
  107. {openscvx-2.dev4 → openscvx-2.dev6}/examples/drone/dr_vp.py +0 -0
  108. {openscvx-2.dev4 → openscvx-2.dev6}/examples/drone/dr_vp_nodal.py +0 -0
  109. {openscvx-2.dev4 → openscvx-2.dev6}/examples/drone/dr_vp_polytope.py +0 -0
  110. {openscvx-2.dev4 → openscvx-2.dev6}/examples/drone/drone_racing.py +0 -0
  111. {openscvx-2.dev4 → openscvx-2.dev6}/examples/drone/logo.py +0 -0
  112. {openscvx-2.dev4 → openscvx-2.dev6}/examples/drone/logo_utils/acl_logo.svg +0 -0
  113. {openscvx-2.dev4 → openscvx-2.dev6}/examples/drone/logo_utils/svg_path_utils.py +0 -0
  114. {openscvx-2.dev4 → openscvx-2.dev6}/examples/drone/obstacle_avoidance.py +0 -0
  115. {openscvx-2.dev4 → openscvx-2.dev6}/examples/drone/obstacle_avoidance_nodal.py +0 -0
  116. {openscvx-2.dev4 → openscvx-2.dev6}/examples/drone/obstacle_avoidance_vmap.py +0 -0
  117. {openscvx-2.dev4 → openscvx-2.dev6}/examples/mjx/triple_cartpole_game.py +0 -0
  118. {openscvx-2.dev4 → openscvx-2.dev6}/examples/mpc/double_integrator_discrete.py +0 -0
  119. {openscvx-2.dev4 → openscvx-2.dev6}/examples/mpc/double_integrator_drone_racing.py +0 -0
  120. {openscvx-2.dev4 → openscvx-2.dev6}/examples/mpc/dubins_car_circle_analytical.py +0 -0
  121. {openscvx-2.dev4 → openscvx-2.dev6}/examples/mpc/dubins_car_circle_discrete.py +0 -0
  122. {openscvx-2.dev4 → openscvx-2.dev6}/examples/mpc/realtime_double_integrator_drone_racing.py +0 -0
  123. {openscvx-2.dev4 → openscvx-2.dev6}/examples/plotting.py +0 -0
  124. {openscvx-2.dev4 → openscvx-2.dev6}/examples/plotting_viser.py +0 -0
  125. {openscvx-2.dev4 → openscvx-2.dev6}/examples/realtime/3DoF_pdg_realtime.py +0 -0
  126. {openscvx-2.dev4 → openscvx-2.dev6}/examples/realtime/6DoF_pdg_realtime.py +0 -0
  127. {openscvx-2.dev4 → openscvx-2.dev6}/examples/realtime/base_problems/3DoF_pdg_realtime_base.py +0 -0
  128. {openscvx-2.dev4 → openscvx-2.dev6}/examples/realtime/base_problems/6DoF_pdg_realtime_base.py +0 -0
  129. {openscvx-2.dev4 → openscvx-2.dev6}/examples/realtime/base_problems/cinema_vp_realtime_base.py +0 -0
  130. {openscvx-2.dev4 → openscvx-2.dev6}/examples/realtime/base_problems/drone_racing_realtime_base.py +0 -0
  131. {openscvx-2.dev4 → openscvx-2.dev6}/examples/realtime/base_problems/dubins_car_realtime_base.py +0 -0
  132. {openscvx-2.dev4 → openscvx-2.dev6}/examples/realtime/base_problems/obstacle_avoidance_realtime_base.py +0 -0
  133. {openscvx-2.dev4 → openscvx-2.dev6}/examples/realtime/cinema_vp_realtime.py +0 -0
  134. {openscvx-2.dev4 → openscvx-2.dev6}/examples/realtime/drone_racing_realtime.py +0 -0
  135. {openscvx-2.dev4 → openscvx-2.dev6}/examples/realtime/dubins_car_realtime.py +0 -0
  136. {openscvx-2.dev4 → openscvx-2.dev6}/examples/realtime/obstacle_avoidance_realtime.py +0 -0
  137. {openscvx-2.dev4 → openscvx-2.dev6}/examples/rocket/3DoF_pdg.py +0 -0
  138. {openscvx-2.dev4 → openscvx-2.dev6}/examples/rocket/6DoF_pdg.py +0 -0
  139. {openscvx-2.dev4 → openscvx-2.dev6}/examples/spacecraft/halo_orbit.py +0 -0
  140. {openscvx-2.dev4 → openscvx-2.dev6}/examples/spacecraft/hohmann_transfer.py +0 -0
  141. {openscvx-2.dev4 → openscvx-2.dev6}/examples/spacecraft/let_transfer.py +0 -0
  142. {openscvx-2.dev4 → openscvx-2.dev6}/examples/spacecraft/proxops_cw.py +0 -0
  143. {openscvx-2.dev4 → openscvx-2.dev6}/figures/ctlos_cine.gif +0 -0
  144. {openscvx-2.dev4 → openscvx-2.dev6}/figures/ctlos_dr.gif +0 -0
  145. {openscvx-2.dev4 → openscvx-2.dev6}/figures/dtlos_cine.gif +0 -0
  146. {openscvx-2.dev4 → openscvx-2.dev6}/figures/dtlos_dr.gif +0 -0
  147. {openscvx-2.dev4 → openscvx-2.dev6}/figures/openscvx_logo.svg +0 -0
  148. {openscvx-2.dev4 → openscvx-2.dev6}/figures/openscvx_logo_square.png +0 -0
  149. {openscvx-2.dev4 → openscvx-2.dev6}/figures/oscvx_structure_full_dark.svg +0 -0
  150. {openscvx-2.dev4 → openscvx-2.dev6}/figures/video_preview.png +0 -0
  151. {openscvx-2.dev4 → openscvx-2.dev6}/material/__init__.py +0 -0
  152. {openscvx-2.dev4 → openscvx-2.dev6}/material/overrides/assets/stylesheets/custom.css +0 -0
  153. {openscvx-2.dev4 → openscvx-2.dev6}/material/overrides/assets/stylesheets/home-dropin.css +0 -0
  154. {openscvx-2.dev4 → openscvx-2.dev6}/material/overrides/assets/stylesheets/home-hero.css +0 -0
  155. {openscvx-2.dev4 → openscvx-2.dev6}/material/overrides/assets/stylesheets/home-viser.css +0 -0
  156. {openscvx-2.dev4 → openscvx-2.dev6}/material/overrides/home.html +0 -0
  157. {openscvx-2.dev4 → openscvx-2.dev6}/material/overrides/main.html +0 -0
  158. {openscvx-2.dev4 → openscvx-2.dev6}/material/overrides/partials/home-diagram.html +0 -0
  159. {openscvx-2.dev4 → openscvx-2.dev6}/material/overrides/partials/home-dropin-banner.html +0 -0
  160. {openscvx-2.dev4 → openscvx-2.dev6}/material/overrides/partials/home-hero.html +0 -0
  161. {openscvx-2.dev4 → openscvx-2.dev6}/material/overrides/partials/home-pipeline.html +0 -0
  162. {openscvx-2.dev4 → openscvx-2.dev6}/material/overrides/partials/home-viser-strip.html +0 -0
  163. {openscvx-2.dev4 → openscvx-2.dev6}/mkdocs.yml +0 -0
  164. {openscvx-2.dev4 → openscvx-2.dev6}/openscvx/__main__.py +0 -0
  165. {openscvx-2.dev4 → openscvx-2.dev6}/openscvx/algorithms/base.py +0 -0
  166. {openscvx-2.dev4 → openscvx-2.dev6}/openscvx/algorithms/optimization_results.py +0 -0
  167. {openscvx-2.dev4 → openscvx-2.dev6}/openscvx/algorithms/weights.py +0 -0
  168. {openscvx-2.dev4 → openscvx-2.dev6}/openscvx/config.py +0 -0
  169. {openscvx-2.dev4 → openscvx-2.dev6}/openscvx/discretization/__init__.py +0 -0
  170. {openscvx-2.dev4 → openscvx-2.dev6}/openscvx/discretization/base.py +0 -0
  171. {openscvx-2.dev4 → openscvx-2.dev6}/openscvx/discretization/discretize_linearize.py +0 -0
  172. {openscvx-2.dev4 → openscvx-2.dev6}/openscvx/discretization/linearize_discretize.py +0 -0
  173. {openscvx-2.dev4 → openscvx-2.dev6}/openscvx/discretization/linearize_discretize_sparse.py +0 -0
  174. {openscvx-2.dev4 → openscvx-2.dev6}/openscvx/discretization/sparse_utils/__init__.py +0 -0
  175. {openscvx-2.dev4 → openscvx-2.dev6}/openscvx/discretization/sparse_utils/bcoo_helpers.py +0 -0
  176. {openscvx-2.dev4 → openscvx-2.dev6}/openscvx/discretization/sparse_utils/sparse_jacobian.py +0 -0
  177. {openscvx-2.dev4 → openscvx-2.dev6}/openscvx/expert/__init__.py +0 -0
  178. {openscvx-2.dev4 → openscvx-2.dev6}/openscvx/expert/byof.py +0 -0
  179. {openscvx-2.dev4 → openscvx-2.dev6}/openscvx/expert/lowering.py +0 -0
  180. {openscvx-2.dev4 → openscvx-2.dev6}/openscvx/expert/validation.py +0 -0
  181. {openscvx-2.dev4 → openscvx-2.dev6}/openscvx/init/__init__.py +0 -0
  182. {openscvx-2.dev4 → openscvx-2.dev6}/openscvx/init/interpolation.py +0 -0
  183. {openscvx-2.dev4 → openscvx-2.dev6}/openscvx/init/inverse_kinematics.py +0 -0
  184. {openscvx-2.dev4 → openscvx-2.dev6}/openscvx/integrations/menagerie.py +0 -0
  185. {openscvx-2.dev4 → openscvx-2.dev6}/openscvx/integrators/__init__.py +0 -0
  186. {openscvx-2.dev4 → openscvx-2.dev6}/openscvx/integrators/diffrax.py +0 -0
  187. {openscvx-2.dev4 → openscvx-2.dev6}/openscvx/integrators/runge_kutta.py +0 -0
  188. {openscvx-2.dev4 → openscvx-2.dev6}/openscvx/loader.py +0 -0
  189. {openscvx-2.dev4 → openscvx-2.dev6}/openscvx/lowered/__init__.py +0 -0
  190. {openscvx-2.dev4 → openscvx-2.dev6}/openscvx/lowered/cvxpy_constraints.py +0 -0
  191. {openscvx-2.dev4 → openscvx-2.dev6}/openscvx/lowered/cvxpy_variables.py +0 -0
  192. {openscvx-2.dev4 → openscvx-2.dev6}/openscvx/lowered/dynamics.py +0 -0
  193. {openscvx-2.dev4 → openscvx-2.dev6}/openscvx/lowered/jax_constraints.py +0 -0
  194. {openscvx-2.dev4 → openscvx-2.dev6}/openscvx/lowered/parameters.py +0 -0
  195. {openscvx-2.dev4 → openscvx-2.dev6}/openscvx/lowered/problem.py +0 -0
  196. {openscvx-2.dev4 → openscvx-2.dev6}/openscvx/lowered/unified.py +0 -0
  197. {openscvx-2.dev4 → openscvx-2.dev6}/openscvx/plotting/__init__.py +0 -0
  198. {openscvx-2.dev4 → openscvx-2.dev6}/openscvx/plotting/plotting.py +0 -0
  199. {openscvx-2.dev4 → openscvx-2.dev6}/openscvx/plotting/scp_iteration.py +0 -0
  200. {openscvx-2.dev4 → openscvx-2.dev6}/openscvx/plotting/viser/__init__.py +0 -0
  201. {openscvx-2.dev4 → openscvx-2.dev6}/openscvx/plotting/viser/animated.py +0 -0
  202. {openscvx-2.dev4 → openscvx-2.dev6}/openscvx/plotting/viser/orbits.py +0 -0
  203. {openscvx-2.dev4 → openscvx-2.dev6}/openscvx/plotting/viser/plotly_integration.py +0 -0
  204. {openscvx-2.dev4 → openscvx-2.dev6}/openscvx/plotting/viser/primitives.py +0 -0
  205. {openscvx-2.dev4 → openscvx-2.dev6}/openscvx/plotting/viser/scp.py +0 -0
  206. {openscvx-2.dev4 → openscvx-2.dev6}/openscvx/plotting/viser/server.py +0 -0
  207. {openscvx-2.dev4 → openscvx-2.dev6}/openscvx/propagation/__init__.py +0 -0
  208. {openscvx-2.dev4 → openscvx-2.dev6}/openscvx/propagation/post_processing.py +0 -0
  209. {openscvx-2.dev4 → openscvx-2.dev6}/openscvx/propagation/propagation.py +0 -0
  210. {openscvx-2.dev4 → openscvx-2.dev6}/openscvx/solvers/__init__.py +0 -0
  211. {openscvx-2.dev4 → openscvx-2.dev6}/openscvx/solvers/base.py +0 -0
  212. {openscvx-2.dev4 → openscvx-2.dev6}/openscvx/solvers/ptr_solver.py +0 -0
  213. {openscvx-2.dev4 → openscvx-2.dev6}/openscvx/symbolic/__init__.py +0 -0
  214. {openscvx-2.dev4 → openscvx-2.dev6}/openscvx/symbolic/augmentation.py +0 -0
  215. {openscvx-2.dev4 → openscvx-2.dev6}/openscvx/symbolic/builder.py +0 -0
  216. {openscvx-2.dev4 → openscvx-2.dev6}/openscvx/symbolic/constraint_set.py +0 -0
  217. {openscvx-2.dev4 → openscvx-2.dev6}/openscvx/symbolic/expr/__init__.py +0 -0
  218. {openscvx-2.dev4 → openscvx-2.dev6}/openscvx/symbolic/expr/arithmetic.py +0 -0
  219. {openscvx-2.dev4 → openscvx-2.dev6}/openscvx/symbolic/expr/array.py +0 -0
  220. {openscvx-2.dev4 → openscvx-2.dev6}/openscvx/symbolic/expr/constraint.py +0 -0
  221. {openscvx-2.dev4 → openscvx-2.dev6}/openscvx/symbolic/expr/control.py +0 -0
  222. {openscvx-2.dev4 → openscvx-2.dev6}/openscvx/symbolic/expr/expr.py +0 -0
  223. {openscvx-2.dev4 → openscvx-2.dev6}/openscvx/symbolic/expr/lie/__init__.py +0 -0
  224. {openscvx-2.dev4 → openscvx-2.dev6}/openscvx/symbolic/expr/lie/adjoint.py +0 -0
  225. {openscvx-2.dev4 → openscvx-2.dev6}/openscvx/symbolic/expr/lie/se3.py +0 -0
  226. {openscvx-2.dev4 → openscvx-2.dev6}/openscvx/symbolic/expr/lie/so3.py +0 -0
  227. {openscvx-2.dev4 → openscvx-2.dev6}/openscvx/symbolic/expr/linalg.py +0 -0
  228. {openscvx-2.dev4 → openscvx-2.dev6}/openscvx/symbolic/expr/logic.py +0 -0
  229. {openscvx-2.dev4 → openscvx-2.dev6}/openscvx/symbolic/expr/math.py +0 -0
  230. {openscvx-2.dev4 → openscvx-2.dev6}/openscvx/symbolic/expr/parameter.py +0 -0
  231. {openscvx-2.dev4 → openscvx-2.dev6}/openscvx/symbolic/expr/spatial.py +0 -0
  232. {openscvx-2.dev4 → openscvx-2.dev6}/openscvx/symbolic/expr/state.py +0 -0
  233. {openscvx-2.dev4 → openscvx-2.dev6}/openscvx/symbolic/expr/stl.py +0 -0
  234. {openscvx-2.dev4 → openscvx-2.dev6}/openscvx/symbolic/expr/stljax.py +0 -0
  235. {openscvx-2.dev4 → openscvx-2.dev6}/openscvx/symbolic/expr/time.py +0 -0
  236. {openscvx-2.dev4 → openscvx-2.dev6}/openscvx/symbolic/expr/variable.py +0 -0
  237. {openscvx-2.dev4 → openscvx-2.dev6}/openscvx/symbolic/expr/vmap.py +0 -0
  238. {openscvx-2.dev4 → openscvx-2.dev6}/openscvx/symbolic/hashing.py +0 -0
  239. {openscvx-2.dev4 → openscvx-2.dev6}/openscvx/symbolic/lower.py +0 -0
  240. {openscvx-2.dev4 → openscvx-2.dev6}/openscvx/symbolic/lowerers/__init__.py +0 -0
  241. {openscvx-2.dev4 → openscvx-2.dev6}/openscvx/symbolic/lowerers/cvxpy/__init__.py +0 -0
  242. {openscvx-2.dev4 → openscvx-2.dev6}/openscvx/symbolic/lowerers/cvxpy/_lowerer.py +0 -0
  243. {openscvx-2.dev4 → openscvx-2.dev6}/openscvx/symbolic/lowerers/cvxpy/_registry.py +0 -0
  244. {openscvx-2.dev4 → openscvx-2.dev6}/openscvx/symbolic/lowerers/cvxpy/arithmetic.py +0 -0
  245. {openscvx-2.dev4 → openscvx-2.dev6}/openscvx/symbolic/lowerers/cvxpy/array.py +0 -0
  246. {openscvx-2.dev4 → openscvx-2.dev6}/openscvx/symbolic/lowerers/cvxpy/constraint.py +0 -0
  247. {openscvx-2.dev4 → openscvx-2.dev6}/openscvx/symbolic/lowerers/cvxpy/control.py +0 -0
  248. {openscvx-2.dev4 → openscvx-2.dev6}/openscvx/symbolic/lowerers/cvxpy/expr.py +0 -0
  249. {openscvx-2.dev4 → openscvx-2.dev6}/openscvx/symbolic/lowerers/cvxpy/linalg.py +0 -0
  250. {openscvx-2.dev4 → openscvx-2.dev6}/openscvx/symbolic/lowerers/cvxpy/logic.py +0 -0
  251. {openscvx-2.dev4 → openscvx-2.dev6}/openscvx/symbolic/lowerers/cvxpy/math.py +0 -0
  252. {openscvx-2.dev4 → openscvx-2.dev6}/openscvx/symbolic/lowerers/cvxpy/state.py +0 -0
  253. {openscvx-2.dev4 → openscvx-2.dev6}/openscvx/symbolic/lowerers/jax/__init__.py +0 -0
  254. {openscvx-2.dev4 → openscvx-2.dev6}/openscvx/symbolic/lowerers/jax/_lowerer.py +0 -0
  255. {openscvx-2.dev4 → openscvx-2.dev6}/openscvx/symbolic/lowerers/jax/_registry.py +0 -0
  256. {openscvx-2.dev4 → openscvx-2.dev6}/openscvx/symbolic/lowerers/jax/arithmetic.py +0 -0
  257. {openscvx-2.dev4 → openscvx-2.dev6}/openscvx/symbolic/lowerers/jax/array.py +0 -0
  258. {openscvx-2.dev4 → openscvx-2.dev6}/openscvx/symbolic/lowerers/jax/constraint.py +0 -0
  259. {openscvx-2.dev4 → openscvx-2.dev6}/openscvx/symbolic/lowerers/jax/control.py +0 -0
  260. {openscvx-2.dev4 → openscvx-2.dev6}/openscvx/symbolic/lowerers/jax/expr.py +0 -0
  261. {openscvx-2.dev4 → openscvx-2.dev6}/openscvx/symbolic/lowerers/jax/lie.py +0 -0
  262. {openscvx-2.dev4 → openscvx-2.dev6}/openscvx/symbolic/lowerers/jax/linalg.py +0 -0
  263. {openscvx-2.dev4 → openscvx-2.dev6}/openscvx/symbolic/lowerers/jax/logic.py +0 -0
  264. {openscvx-2.dev4 → openscvx-2.dev6}/openscvx/symbolic/lowerers/jax/math.py +0 -0
  265. {openscvx-2.dev4 → openscvx-2.dev6}/openscvx/symbolic/lowerers/jax/spatial.py +0 -0
  266. {openscvx-2.dev4 → openscvx-2.dev6}/openscvx/symbolic/lowerers/jax/state.py +0 -0
  267. {openscvx-2.dev4 → openscvx-2.dev6}/openscvx/symbolic/lowerers/jax/stl.py +0 -0
  268. {openscvx-2.dev4 → openscvx-2.dev6}/openscvx/symbolic/lowerers/jax/stljax.py +0 -0
  269. {openscvx-2.dev4 → openscvx-2.dev6}/openscvx/symbolic/lowerers/jax/vmap.py +0 -0
  270. {openscvx-2.dev4 → openscvx-2.dev6}/openscvx/symbolic/parser/__init__.py +0 -0
  271. {openscvx-2.dev4 → openscvx-2.dev6}/openscvx/symbolic/parser/_registry.py +0 -0
  272. {openscvx-2.dev4 → openscvx-2.dev6}/openscvx/symbolic/parser/array.py +0 -0
  273. {openscvx-2.dev4 → openscvx-2.dev6}/openscvx/symbolic/parser/constraint.py +0 -0
  274. {openscvx-2.dev4 → openscvx-2.dev6}/openscvx/symbolic/parser/lie.py +0 -0
  275. {openscvx-2.dev4 → openscvx-2.dev6}/openscvx/symbolic/parser/linalg.py +0 -0
  276. {openscvx-2.dev4 → openscvx-2.dev6}/openscvx/symbolic/parser/logic.py +0 -0
  277. {openscvx-2.dev4 → openscvx-2.dev6}/openscvx/symbolic/parser/math.py +0 -0
  278. {openscvx-2.dev4 → openscvx-2.dev6}/openscvx/symbolic/parser/parser.py +0 -0
  279. {openscvx-2.dev4 → openscvx-2.dev6}/openscvx/symbolic/parser/spatial.py +0 -0
  280. {openscvx-2.dev4 → openscvx-2.dev6}/openscvx/symbolic/parser/stl.py +0 -0
  281. {openscvx-2.dev4 → openscvx-2.dev6}/openscvx/symbolic/parser/stljax.py +0 -0
  282. {openscvx-2.dev4 → openscvx-2.dev6}/openscvx/symbolic/parser/tokenizer.py +0 -0
  283. {openscvx-2.dev4 → openscvx-2.dev6}/openscvx/symbolic/preprocessing.py +0 -0
  284. {openscvx-2.dev4 → openscvx-2.dev6}/openscvx/symbolic/problem.py +0 -0
  285. {openscvx-2.dev4 → openscvx-2.dev6}/openscvx/symbolic/sparsity.py +0 -0
  286. {openscvx-2.dev4 → openscvx-2.dev6}/openscvx/symbolic/unified.py +0 -0
  287. {openscvx-2.dev4 → openscvx-2.dev6}/openscvx/utils/__init__.py +0 -0
  288. {openscvx-2.dev4 → openscvx-2.dev6}/openscvx/utils/cache.py +0 -0
  289. {openscvx-2.dev4 → openscvx-2.dev6}/openscvx/utils/caching.py +0 -0
  290. {openscvx-2.dev4 → openscvx-2.dev6}/openscvx/utils/printing.py +0 -0
  291. {openscvx-2.dev4 → openscvx-2.dev6}/openscvx/utils/profiling.py +0 -0
  292. {openscvx-2.dev4 → openscvx-2.dev6}/openscvx/utils/utils.py +0 -0
  293. {openscvx-2.dev4 → openscvx-2.dev6}/openscvx.egg-info/dependency_links.txt +0 -0
  294. {openscvx-2.dev4 → openscvx-2.dev6}/openscvx.egg-info/entry_points.txt +0 -0
  295. {openscvx-2.dev4 → openscvx-2.dev6}/openscvx.egg-info/requires.txt +0 -0
  296. {openscvx-2.dev4 → openscvx-2.dev6}/openscvx.egg-info/top_level.txt +0 -0
  297. {openscvx-2.dev4 → openscvx-2.dev6}/pyproject.toml +0 -0
  298. {openscvx-2.dev4 → openscvx-2.dev6}/scripts/gen_example_pages.py +0 -0
  299. {openscvx-2.dev4 → openscvx-2.dev6}/scripts/gen_ref_pages.py +0 -0
  300. {openscvx-2.dev4 → openscvx-2.dev6}/scripts/mkdocs_copy_viser_client_hook.py +0 -0
  301. {openscvx-2.dev4 → openscvx-2.dev6}/setup.cfg +0 -0
  302. {openscvx-2.dev4 → openscvx-2.dev6}/tests/__init__.py +0 -0
  303. {openscvx-2.dev4 → openscvx-2.dev6}/tests/brachistochrone_analytical.py +0 -0
  304. {openscvx-2.dev4 → openscvx-2.dev6}/tests/expr/__init__.py +0 -0
  305. {openscvx-2.dev4 → openscvx-2.dev6}/tests/expr/test_gmsr.py +0 -0
  306. {openscvx-2.dev4 → openscvx-2.dev6}/tests/fixtures/brachistochrone.json +0 -0
  307. {openscvx-2.dev4 → openscvx-2.dev6}/tests/fixtures/brachistochrone.yaml +0 -0
  308. {openscvx-2.dev4 → openscvx-2.dev6}/tests/hohmann_analytical.py +0 -0
  309. {openscvx-2.dev4 → openscvx-2.dev6}/tests/integrations/__init__.py +0 -0
  310. {openscvx-2.dev4 → openscvx-2.dev6}/tests/symbolic/__init__.py +0 -0
  311. {openscvx-2.dev4 → openscvx-2.dev6}/tests/symbolic/expr/__init__.py +0 -0
  312. {openscvx-2.dev4 → openscvx-2.dev6}/tests/symbolic/expr/test_arithmetic.py +0 -0
  313. {openscvx-2.dev4 → openscvx-2.dev6}/tests/symbolic/expr/test_array.py +0 -0
  314. {openscvx-2.dev4 → openscvx-2.dev6}/tests/symbolic/expr/test_constraint.py +0 -0
  315. {openscvx-2.dev4 → openscvx-2.dev6}/tests/symbolic/expr/test_expr.py +0 -0
  316. {openscvx-2.dev4 → openscvx-2.dev6}/tests/symbolic/expr/test_lie.py +0 -0
  317. {openscvx-2.dev4 → openscvx-2.dev6}/tests/symbolic/expr/test_linalg.py +0 -0
  318. {openscvx-2.dev4 → openscvx-2.dev6}/tests/symbolic/expr/test_logic.py +0 -0
  319. {openscvx-2.dev4 → openscvx-2.dev6}/tests/symbolic/expr/test_math.py +0 -0
  320. {openscvx-2.dev4 → openscvx-2.dev6}/tests/symbolic/expr/test_node_reference.py +0 -0
  321. {openscvx-2.dev4 → openscvx-2.dev6}/tests/symbolic/expr/test_parameters.py +0 -0
  322. {openscvx-2.dev4 → openscvx-2.dev6}/tests/symbolic/expr/test_scaling.py +0 -0
  323. {openscvx-2.dev4 → openscvx-2.dev6}/tests/symbolic/expr/test_spatial.py +0 -0
  324. {openscvx-2.dev4 → openscvx-2.dev6}/tests/symbolic/expr/test_stl.py +0 -0
  325. {openscvx-2.dev4 → openscvx-2.dev6}/tests/symbolic/expr/test_variable.py +0 -0
  326. {openscvx-2.dev4 → openscvx-2.dev6}/tests/symbolic/expr/test_vmap.py +0 -0
  327. {openscvx-2.dev4 → openscvx-2.dev6}/tests/symbolic/parser/__init__.py +0 -0
  328. {openscvx-2.dev4 → openscvx-2.dev6}/tests/symbolic/parser/test_array.py +0 -0
  329. {openscvx-2.dev4 → openscvx-2.dev6}/tests/symbolic/parser/test_constraint.py +0 -0
  330. {openscvx-2.dev4 → openscvx-2.dev6}/tests/symbolic/parser/test_lie.py +0 -0
  331. {openscvx-2.dev4 → openscvx-2.dev6}/tests/symbolic/parser/test_linalg.py +0 -0
  332. {openscvx-2.dev4 → openscvx-2.dev6}/tests/symbolic/parser/test_load.py +0 -0
  333. {openscvx-2.dev4 → openscvx-2.dev6}/tests/symbolic/parser/test_logic.py +0 -0
  334. {openscvx-2.dev4 → openscvx-2.dev6}/tests/symbolic/parser/test_math.py +0 -0
  335. {openscvx-2.dev4 → openscvx-2.dev6}/tests/symbolic/parser/test_parser.py +0 -0
  336. {openscvx-2.dev4 → openscvx-2.dev6}/tests/symbolic/parser/test_spatial.py +0 -0
  337. {openscvx-2.dev4 → openscvx-2.dev6}/tests/symbolic/parser/test_stl.py +0 -0
  338. {openscvx-2.dev4 → openscvx-2.dev6}/tests/symbolic/parser/test_tokenizer.py +0 -0
  339. {openscvx-2.dev4 → openscvx-2.dev6}/tests/symbolic/parser/test_vmap.py +0 -0
  340. {openscvx-2.dev4 → openscvx-2.dev6}/tests/symbolic/test_augmentation.py +0 -0
  341. {openscvx-2.dev4 → openscvx-2.dev6}/tests/symbolic/test_hashing.py +0 -0
  342. {openscvx-2.dev4 → openscvx-2.dev6}/tests/symbolic/test_lower_cvxpy.py +0 -0
  343. {openscvx-2.dev4 → openscvx-2.dev6}/tests/symbolic/test_lower_jax.py +0 -0
  344. {openscvx-2.dev4 → openscvx-2.dev6}/tests/symbolic/test_preprocessing.py +0 -0
  345. {openscvx-2.dev4 → openscvx-2.dev6}/tests/symbolic/test_sparsity.py +0 -0
  346. {openscvx-2.dev4 → openscvx-2.dev6}/tests/symbolic/test_unified.py +0 -0
  347. {openscvx-2.dev4 → openscvx-2.dev6}/tests/test_cvxpygen_optional.py +0 -0
  348. {openscvx-2.dev4 → openscvx-2.dev6}/tests/test_discretization.py +0 -0
  349. {openscvx-2.dev4 → openscvx-2.dev6}/tests/test_examples.py +0 -0
  350. {openscvx-2.dev4 → openscvx-2.dev6}/tests/test_expert.py +0 -0
  351. {openscvx-2.dev4 → openscvx-2.dev6}/tests/test_impulsive.py +0 -0
  352. {openscvx-2.dev4 → openscvx-2.dev6}/tests/test_init.py +0 -0
  353. {openscvx-2.dev4 → openscvx-2.dev6}/tests/test_integrators.py +0 -0
  354. {openscvx-2.dev4 → openscvx-2.dev6}/tests/test_loader.py +0 -0
  355. {openscvx-2.dev4 → openscvx-2.dev6}/tests/test_optimization_results.py +0 -0
  356. {openscvx-2.dev4 → openscvx-2.dev6}/tests/test_plotting.py +0 -0
  357. {openscvx-2.dev4 → openscvx-2.dev6}/tests/test_propagation.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: openscvx
3
- Version: 2.dev4
3
+ Version: 2.dev6
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
@@ -34,7 +34,6 @@ except ImportError:
34
34
  sys.exit(1)
35
35
 
36
36
  import openscvx as ox
37
- from openscvx.integrations import mjx_byof
38
37
 
39
38
  CARTPOLE_XML = """
40
39
  <mujoco model="cartpole">
@@ -69,36 +68,32 @@ n_u = int(mjx_model.nu)
69
68
  n = 60
70
69
  total_time = 3.0
71
70
 
72
- qpos = ox.State("qpos", shape=(n_q,))
71
+ # ── MJX dynamics as a first-class adapter ─────────────────────────────────────
72
+ # `MjxDynamics` builds default qpos / qvel / ctrl State and Control objects
73
+ # matching the model's nq / nv / nu and routes the MJX forward dynamics into
74
+ # the BYOF channel internally — no separate `byof=` plumbing required.
75
+ dyn = ox.MjxDynamics(mjx_model)
76
+ qpos, qvel = dyn.states
77
+ (ctrl,) = dyn.controls
78
+
73
79
  qpos.min = np.array([-3.0, -2.0 * np.pi])
74
80
  qpos.max = np.array([3.0, 2.0 * np.pi])
75
81
  qpos.initial = np.array([0.0, np.pi])
76
82
  qpos.final = np.array([0.0, 0.0])
77
83
 
78
- qvel = ox.State("qvel", shape=(n_v,))
79
84
  qvel.min = np.array([-10.0, -15.0])
80
85
  qvel.max = np.array([10.0, 15.0])
81
86
  qvel.initial = np.array([0.0, 0.0])
82
87
  qvel.final = np.array([0.0, 0.0])
83
88
 
84
- ctrl = ox.Control("ctrl", shape=(n_u,))
85
89
  ctrl.min = np.array([-1.0])
86
90
  ctrl.max = np.array([1.0])
87
91
  ctrl.guess = np.zeros((n, n_u))
88
92
 
89
- states = [qpos, qvel]
90
- controls = [ctrl]
91
-
92
- dynamics = {
93
- "qpos": qvel,
94
- }
95
-
96
- byof: ox.ByofSpec = {"dynamics": mjx_byof(mjx_model, qpos=qpos, qvel=qvel, ctrl=ctrl)}
97
-
98
93
  constraints = []
99
- for state in states:
94
+ for state in dyn.states:
100
95
  constraints.extend([ox.ctcs(state <= state.max), ox.ctcs(state.min <= state)])
101
- for control in controls:
96
+ for control in dyn.controls:
102
97
  constraints.extend([ox.ctcs(control <= control.max), ox.ctcs(control.min <= control)])
103
98
 
104
99
  theta_guess = np.linspace(np.pi, 0.0, n)
@@ -115,13 +110,12 @@ time = ox.Time(
115
110
  )
116
111
 
117
112
  problem = ox.Problem(
118
- dynamics=dynamics,
119
- states=states,
120
- controls=controls,
113
+ dynamics=dyn,
114
+ states=dyn.states,
115
+ controls=dyn.controls,
121
116
  time=time,
122
117
  constraints=constraints,
123
118
  N=n,
124
- byof=byof,
125
119
  algorithm={
126
120
  "lam_prox": 1e-1,
127
121
  "lam_cost": 1e-2,
@@ -34,8 +34,6 @@ except ImportError:
34
34
  sys.exit(1)
35
35
 
36
36
  import openscvx as ox
37
- from openscvx import ByofSpec
38
- from openscvx.integrations import mjx_byof
39
37
 
40
38
  L1, L2 = 0.5, 0.4 # link lengths (m)
41
39
 
@@ -81,32 +79,26 @@ n_u = int(mjx_model.nu) # 1: cart force
81
79
  n = 400
82
80
  total_time = 2.5
83
81
 
84
- # ── State / control definitions ───────────────────────────────────────────────
85
- qpos = ox.State("qpos", shape=(n_q,))
82
+ # ── MJX dynamics adapter ──────────────────────────────────────────────────────
83
+ dyn = ox.MjxDynamics(mjx_model)
84
+ qpos, qvel = dyn.states
85
+ (ctrl,) = dyn.controls
86
+ ctrl.parameterization = "ZOH"
87
+
86
88
  qpos.min = np.array([-8.0, -2 * np.pi, -2 * np.pi])
87
89
  qpos.max = np.array([8.0, 2 * np.pi, 2 * np.pi])
88
90
  qpos.initial = np.array([0.0, np.pi, 0.0]) # cart at origin, link1 hanging down
89
91
  qpos.final = [ox.Free(0.0), 0.0, 0.0] # cart free, both links upright
90
92
 
91
- qvel = ox.State("qvel", shape=(n_v,))
92
93
  qvel.min = np.array([-12.0, -12.0, -12.0])
93
94
  qvel.max = np.array([12.0, 12.0, 12.0])
94
95
  qvel.initial = np.zeros(n_v)
95
96
  qvel.final = [0.0, 0.0, 0.0]
96
97
 
97
- ctrl = ox.Control("ctrl", shape=(n_u,), parameterization="ZOH")
98
98
  ctrl.min = np.array([-2.0])
99
99
  ctrl.max = np.array([2.0])
100
100
  ctrl.guess = np.zeros((n, n_u))
101
101
 
102
- states = [qpos, qvel]
103
- controls = [ctrl]
104
-
105
- # ── Dynamics: position kinematics symbolically, velocity via MJX ──────────────
106
- dynamics: dict = {"qpos": qvel} # nq == nv, valid for all-revolute/prismatic joints
107
-
108
- byof: ByofSpec = {"dynamics": mjx_byof(mjx_model, qpos=qpos, qvel=qvel, ctrl=ctrl)}
109
-
110
102
  # ── Constraints (CTCS on state / control bounds) ───────────────────────────────
111
103
  constraints = []
112
104
 
@@ -123,13 +115,12 @@ time = ox.Time(
123
115
  )
124
116
 
125
117
  problem = ox.Problem(
126
- dynamics=dynamics,
127
- states=states,
128
- controls=controls,
118
+ dynamics=dyn,
119
+ states=dyn.states,
120
+ controls=dyn.controls,
129
121
  time=time,
130
122
  constraints=constraints,
131
123
  N=n,
132
- byof=byof,
133
124
  algorithm={
134
125
  "lam_prox": 1e-1,
135
126
  "lam_cost": 0e0,
@@ -51,8 +51,7 @@ from examples.plotting_viser import (
51
51
  create_animated_plotting_server,
52
52
  create_scp_animated_plotting_server,
53
53
  )
54
- from openscvx import ByofSpec, Problem
55
- from openscvx.integrations import mjx_byof
54
+ from openscvx import Problem
56
55
  from openscvx.utils import gen_vertices, rot
57
56
 
58
57
  HOVER_CTRL = 3.2495625 # N per motor for level hover (from menagerie keyframe)
@@ -78,33 +77,28 @@ n_u = int(mjx_model.nu) # 4 — rotor thrusts
78
77
  n = 22
79
78
  total_time = 24.0
80
79
 
81
- # ── State / control definitions ───────────────────────────────────────────────
82
- qpos = ox.State("qpos", shape=(n_q,))
80
+ # ── MJX dynamics adapter ──────────────────────────────────────────────────────
81
+ # The free joint has nq=7 but nv=6 (quaternion adds one extra position DOF).
82
+ # MjxDynamics detects nq > nv and automatically routes quaternion kinematics
83
+ # for "qpos" alongside the MJX "qvel" dynamics through the BYOF channel.
84
+ dyn = ox.MjxDynamics(mjx_model)
85
+ qpos, qvel = dyn.states
86
+ (ctrl,) = dyn.controls
87
+
83
88
  qpos.min = np.array([-200.0, -100.0, 15.0, -1.0, -1.0, -1.0, -1.0])
84
89
  qpos.max = np.array([200.0, 100.0, 200.0, 1.0, 1.0, 1.0, 1.0])
85
90
  qpos.initial = np.concatenate([START_POS, HOVER_QUAT])
86
91
  qpos.final = [10.0, 0.0, 20.0, ("free", 1.0), ("free", 0.0), ("free", 0.0), ("free", 0.0)]
87
92
 
88
- qvel = ox.State("qvel", shape=(n_v,))
89
93
  qvel.min = np.array([-100.0, -100.0, -100.0, -10.0, -10.0, -10.0])
90
94
  qvel.max = np.array([100.0, 100.0, 100.0, 10.0, 10.0, 10.0])
91
95
  qvel.initial = np.zeros(n_v)
92
96
  qvel.final = [("free", 0.0)] * n_v
93
97
 
94
- ctrl = ox.Control("ctrl", shape=(n_u,))
95
98
  ctrl.min = np.zeros(n_u)
96
99
  ctrl.max = 13.0 * np.ones(n_u)
97
100
  ctrl.guess = HOVER_CTRL * np.ones((n, n_u))
98
101
 
99
- states = [qpos, qvel]
100
- controls = [ctrl]
101
-
102
- # ── Dynamics via BYOF ─────────────────────────────────────────────────────────
103
- # The free joint has nq=7 but nv=6 (quaternion adds one extra position DOF).
104
- # nq=7, nv=6 (free joint): mjx_byof detects nq > nv and automatically
105
- # includes quaternion kinematics for "qpos" alongside the MJX "qvel" dynamics.
106
- byof: ByofSpec = {"dynamics": mjx_byof(mjx_model, qpos=qpos, qvel=qvel, ctrl=ctrl)}
107
-
108
102
  # ── Gate parameters (matching examples/drone/drone_racing.py) ───────────────
109
103
  n_gates = 10
110
104
  initial_gate_centers = [
@@ -135,9 +129,9 @@ gate_centers = np.array(modified_centers)
135
129
 
136
130
  # ── Constraints ───────────────────────────────────────────────────────────────
137
131
  constraints = []
138
- for state in states:
132
+ for state in dyn.states:
139
133
  constraints.extend([ox.ctcs(state <= state.max), ox.ctcs(state.min <= state)])
140
- for control in controls:
134
+ for control in dyn.controls:
141
135
  constraints.extend([ox.ctcs(control <= control.max), ox.ctcs(control.min <= control)])
142
136
 
143
137
  # Enforce sequential gate traversal using nodal constraints on qpos position.
@@ -172,13 +166,12 @@ time = ox.Time(
172
166
  )
173
167
 
174
168
  problem = Problem(
175
- dynamics={}, # all dynamics go through BYOF
176
- states=states,
177
- controls=controls,
169
+ dynamics=dyn,
170
+ states=dyn.states,
171
+ controls=dyn.controls,
178
172
  time=time,
179
173
  constraints=constraints,
180
174
  N=n,
181
- byof=byof,
182
175
  algorithm={
183
176
  "lam_prox": 1e-1,
184
177
  "lam_cost": 1e-2,
@@ -57,8 +57,7 @@ except ImportError:
57
57
  sys.exit(1)
58
58
 
59
59
  import openscvx as ox
60
- from openscvx import ByofSpec, Problem
61
- from openscvx.integrations import mjx_byof
60
+ from openscvx import Problem
62
61
 
63
62
  L1, L2, L3 = 0.5, 0.4, 0.3 # link lengths (m)
64
63
 
@@ -122,8 +121,11 @@ IDX_A1, IDX_B1 = 2, 3
122
121
  IDX_A2, IDX_B2 = 4, 5
123
122
  IDX_A3, IDX_B3 = 6, 7
124
123
 
125
- # ── State / control definitions ───────────────────────────────────────────────
126
- qpos = ox.State("qpos", shape=(n_q,))
124
+ # ── MJX dynamics adapter ──────────────────────────────────────────────────────
125
+ dyn = ox.MjxDynamics(mjx_model)
126
+ qpos, qvel = dyn.states
127
+ (ctrl,) = dyn.controls
128
+
127
129
  qpos.min = np.array(
128
130
  [-8.0, -8.0, -2 * np.pi, -2 * np.pi, -2 * np.pi, -2 * np.pi, -2 * np.pi, -2 * np.pi]
129
131
  )
@@ -142,25 +144,15 @@ qpos.final = [
142
144
  0.0, # link 3 upright
143
145
  ]
144
146
 
145
- qvel = ox.State("qvel", shape=(n_v,))
146
147
  qvel.min = np.full(n_v, -12.0)
147
148
  qvel.max = np.full(n_v, 12.0)
148
149
  qvel.initial = np.zeros(n_v)
149
150
  qvel.final = [0.0] * n_v
150
151
 
151
- ctrl = ox.Control("ctrl", shape=(n_u,))
152
152
  ctrl.min = np.array([-2.0, -2.0])
153
153
  ctrl.max = np.array([2.0, 2.0])
154
154
  ctrl.guess = np.zeros((n, n_u))
155
155
 
156
- states = [qpos, qvel]
157
- controls = [ctrl]
158
-
159
- # ── Dynamics: position kinematics symbolically, velocity via MJX ──────────────
160
- dynamics: dict = {"qpos": qvel} # nq == nv
161
-
162
- byof: ByofSpec = {"dynamics": mjx_byof(mjx_model, qpos=qpos, qvel=qvel, ctrl=ctrl)}
163
-
164
156
  # ── Constraints (CTCS on state / control bounds) ─────────────────────────────
165
157
  constraints = []
166
158
 
@@ -179,13 +171,12 @@ time = ox.Time(
179
171
  )
180
172
 
181
173
  problem = Problem(
182
- dynamics=dynamics,
183
- states=states,
184
- controls=controls,
174
+ dynamics=dyn,
175
+ states=dyn.states,
176
+ controls=dyn.controls,
185
177
  time=time,
186
178
  constraints=constraints,
187
179
  N=n,
188
- byof=byof,
189
180
  algorithm={
190
181
  "lam_prox": 1e-1,
191
182
  "lam_cost": 0e0,
@@ -35,8 +35,7 @@ except ImportError:
35
35
  sys.exit(1)
36
36
 
37
37
  import openscvx as ox
38
- from openscvx import ByofSpec, Problem
39
- from openscvx.integrations import mjx_byof
38
+ from openscvx import Problem
40
39
 
41
40
  L1, L2, L3 = 0.5, 0.4, 0.3 # link lengths (m)
42
41
 
@@ -88,35 +87,28 @@ n_u = int(mjx_model.nu) # 1: cart force
88
87
  n = 60 # more nodes → finer resolution near the unstable upright equilibrium
89
88
  total_time = 2.5
90
89
 
91
- # ── State / control definitions ───────────────────────────────────────────────
92
- qpos = ox.State("qpos", shape=(n_q,))
90
+ # ── MJX dynamics adapter ──────────────────────────────────────────────────────
91
+ dyn = ox.MjxDynamics(mjx_model)
92
+ qpos, qvel = dyn.states
93
+ (ctrl,) = dyn.controls
94
+
93
95
  qpos.min = np.array([-100.0, -2 * np.pi, -2 * np.pi, -2 * np.pi])
94
96
  qpos.max = np.array([100.0, 2 * np.pi, 2 * np.pi, 2 * np.pi])
95
97
  qpos.initial = np.array([0.0, np.pi, 0.0, 0.0]) # all links hanging down
96
98
  qpos.final = [ox.Free(0.0), 0.0, 0.0, 0.0] # all links upright
97
99
 
98
- qvel = ox.State("qvel", shape=(n_v,))
99
100
  qvel.min = np.array([-12.0, -12.0, -12.0, -12.0])
100
101
  qvel.max = np.array([12.0, 12.0, 12.0, 12.0])
101
102
  qvel.initial = np.zeros(n_v)
102
103
  qvel.final = [0.0, 0.0, 0.0, 0.0]
103
104
 
104
- ctrl = ox.Control("ctrl", shape=(n_u,))
105
105
  ctrl.min = np.array([-3.0])
106
106
  ctrl.max = np.array([3.0])
107
107
  ctrl.guess = np.zeros((n, n_u))
108
108
 
109
- states = [qpos, qvel]
110
- controls = [ctrl]
111
-
112
- # ── Dynamics: position kinematics symbolically, velocity via MJX ──────────────
113
- dynamics: dict = {"qpos": qvel} # nq==nv so this is always valid
114
-
115
- byof: ByofSpec = {"dynamics": mjx_byof(mjx_model, qpos=qpos, qvel=qvel, ctrl=ctrl)}
116
-
117
109
  # ── Constraints (CTCS on state / control bounds) ───────────────────────────────
118
110
  constraints = []
119
- for state in states:
111
+ for state in dyn.states:
120
112
  constraints.extend([ox.ctcs(state <= state.max), ox.ctcs(state.min <= state)])
121
113
 
122
114
  # ── Initial guess: linearly swing θ₁ from π → 0, others stay 0 ───────────────
@@ -132,13 +124,12 @@ time = ox.Time(
132
124
  )
133
125
 
134
126
  problem = Problem(
135
- dynamics=dynamics,
136
- states=states,
137
- controls=controls,
127
+ dynamics=dyn,
128
+ states=dyn.states,
129
+ controls=dyn.controls,
138
130
  time=time,
139
131
  constraints=constraints,
140
132
  N=n,
141
- byof=byof,
142
133
  algorithm={
143
134
  "lam_prox": 1e0,
144
135
  "lam_cost": 0e0,
@@ -12,6 +12,7 @@ import openscvx.symbolic.expr.spatial as spatial
12
12
  import openscvx.symbolic.expr.stl as stl
13
13
  import openscvx.symbolic.expr.stljax as stljax
14
14
  from openscvx.algorithms import (
15
+ AdaptiveProximalWeight,
15
16
  AugmentedLagrangian,
16
17
  ConstantProximalWeight,
17
18
  PenalizedTrustRegion,
@@ -25,6 +26,7 @@ from openscvx.discretization import (
25
26
  VectorizeDiscretizeLinearize,
26
27
  )
27
28
  from openscvx.expert import ByofSpec
29
+ from openscvx.integrations import DynamicsAdapter, MjxDynamics
28
30
  from openscvx.loader import load_dict, load_json, load_yaml
29
31
  from openscvx.problem import Problem
30
32
  from openscvx.solvers import PTRSolver
@@ -176,6 +178,9 @@ __all__ = [
176
178
  "lie",
177
179
  # Expert mode types
178
180
  "ByofSpec",
181
+ # External-backend dynamics adapters
182
+ "DynamicsAdapter",
183
+ "MjxDynamics",
179
184
  # Discretization
180
185
  "DiscretizeLinearizeVectorize",
181
186
  "LinearizeDiscretize",
@@ -186,6 +191,7 @@ __all__ = [
186
191
  # Algorithm & Autotuning
187
192
  "PenalizedTrustRegion",
188
193
  "AugmentedLagrangian",
194
+ "AdaptiveProximalWeight",
189
195
  "ConstantProximalWeight",
190
196
  "RampProximalWeight",
191
197
  ]
@@ -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 = '2.dev4'
22
- __version_tuple__ = version_tuple = (2, 'dev4')
21
+ __version__ = version = '2.dev6'
22
+ __version_tuple__ = version_tuple = (2, 'dev6')
23
23
 
24
- __commit_id__ = commit_id = 'g85f47e152'
24
+ __commit_id__ = commit_id = 'gcabefce07'
@@ -82,12 +82,19 @@ from typing import Annotated, Any, Dict, List, Optional, Union
82
82
 
83
83
  from pydantic import BaseModel, ConfigDict, Field, field_validator
84
84
 
85
- from .augmented_lagrangian import AugmentedLagrangian, AugmentedLagrangianSpec
85
+ from .autotuner import (
86
+ AdaptiveProximalWeight,
87
+ AdaptiveProximalWeightSpec,
88
+ AugmentedLagrangian,
89
+ AugmentedLagrangianSpec,
90
+ ConstantProximalWeight,
91
+ ConstantProximalWeightSpec,
92
+ RampProximalWeight,
93
+ RampProximalWeightSpec,
94
+ )
86
95
  from .base import Algorithm, AlgorithmState, AutotuningBase, DiscretizationResult
87
- from .constant_proximal_weight import ConstantProximalWeight, ConstantProximalWeightSpec
88
96
  from .optimization_results import OptimizationResults
89
- from .penalized_trust_region import PenalizedTrustRegion
90
- from .ramp_proximal_weight import RampProximalWeight, RampProximalWeightSpec
97
+ from .scvx import PenalizedTrustRegion
91
98
  from .weights import Weights
92
99
 
93
100
  # ---------------------------------------------------------------------------
@@ -97,6 +104,7 @@ from .weights import Weights
97
104
  AutotunerConfig = Annotated[
98
105
  Union[
99
106
  AugmentedLagrangianSpec,
107
+ AdaptiveProximalWeightSpec,
100
108
  RampProximalWeightSpec,
101
109
  ConstantProximalWeightSpec,
102
110
  ],
@@ -173,6 +181,7 @@ __all__ = [
173
181
  "PenalizedTrustRegion",
174
182
  "AutotuningBase",
175
183
  "AugmentedLagrangian",
184
+ "AdaptiveProximalWeight",
176
185
  "ConstantProximalWeight",
177
186
  "RampProximalWeight",
178
187
  # Config models
@@ -0,0 +1,17 @@
1
+ """SCP weight autotuning strategies."""
2
+
3
+ from .adaptive_proximal_weight import AdaptiveProximalWeight, AdaptiveProximalWeightSpec
4
+ from .augmented_lagrangian import AugmentedLagrangian, AugmentedLagrangianSpec
5
+ from .constant_proximal_weight import ConstantProximalWeight, ConstantProximalWeightSpec
6
+ from .ramp_proximal_weight import RampProximalWeight, RampProximalWeightSpec
7
+
8
+ __all__ = [
9
+ "AdaptiveProximalWeight",
10
+ "AdaptiveProximalWeightSpec",
11
+ "AugmentedLagrangian",
12
+ "AugmentedLagrangianSpec",
13
+ "ConstantProximalWeight",
14
+ "ConstantProximalWeightSpec",
15
+ "RampProximalWeight",
16
+ "RampProximalWeightSpec",
17
+ ]
@@ -0,0 +1,190 @@
1
+ """Autotuning functions for SCP (Successive Convex Programming) parameters."""
2
+
3
+ from copy import deepcopy
4
+ from typing import TYPE_CHECKING, Literal
5
+
6
+ import numpy as np
7
+ from pydantic import BaseModel, ConfigDict
8
+
9
+ from openscvx.config import Config
10
+
11
+ from ..base import AutotuningBase
12
+ from .augmented_lagrangian import AugmentedLagrangian
13
+
14
+ if TYPE_CHECKING:
15
+ from openscvx.lowered import LoweredJaxConstraints
16
+
17
+ from ..base import AlgorithmState, CandidateIterate
18
+ from ..weights import Weights
19
+
20
+
21
+ class AdaptiveProximalWeight(AutotuningBase):
22
+ """PTR-style proximal adaptation with fixed virtual penalty weights.
23
+
24
+ Same acceptance-ratio logic as :class:`AugmentedLagrangian` for ``lam_prox``,
25
+ but ``lam_vc`` and ``lam_vb_*`` are held constant at their current state values.
26
+ """
27
+
28
+ COLUMNS = AugmentedLagrangian.COLUMNS
29
+
30
+ def __init__(
31
+ self,
32
+ gamma_1: float = 2.0,
33
+ gamma_2: float = 0.5,
34
+ eta_0: float = 1e-2,
35
+ eta_1: float = 1e-1,
36
+ eta_2: float = 0.8,
37
+ lam_prox_min: float = 1e-3,
38
+ lam_prox_max: float = 1e4,
39
+ lam_cost_drop: int = -1,
40
+ lam_cost_relax: float = 1.0,
41
+ ):
42
+ self.gamma_1 = gamma_1
43
+ self.gamma_2 = gamma_2
44
+ self.eta_0 = eta_0
45
+ self.eta_1 = eta_1
46
+ self.eta_2 = eta_2
47
+ self.lam_prox_min = lam_prox_min
48
+ self.lam_prox_max = lam_prox_max
49
+ self.lam_cost_drop = lam_cost_drop
50
+ self.lam_cost_relax = lam_cost_relax
51
+
52
+ @staticmethod
53
+ def _copy_virtual_weights(
54
+ candidate: "CandidateIterate",
55
+ state: "AlgorithmState",
56
+ ) -> None:
57
+ candidate.lam_vc = state.lam_vc
58
+ candidate.lam_vb_nodal = state.lam_vb_nodal
59
+ candidate.lam_vb_cross = state.lam_vb_cross
60
+
61
+ def update_weights(
62
+ self,
63
+ state: "AlgorithmState",
64
+ candidate: "CandidateIterate",
65
+ nodal_constraints: "LoweredJaxConstraints",
66
+ settings: Config,
67
+ params: dict,
68
+ weights: "Weights",
69
+ ) -> str:
70
+ """Update SCP proximal weight based on acceptance ratio; keep VC/VB fixed."""
71
+ candidate_x_prop = (
72
+ candidate.x_prop_plus[1:] if candidate.x_prop_plus is not None else candidate.x_prop
73
+ )
74
+ (
75
+ nonlinear_cost,
76
+ nonlinear_penalty,
77
+ nodal_penalty,
78
+ ) = self.calculate_nonlinear_penalty(
79
+ candidate_x_prop,
80
+ candidate.x,
81
+ candidate.u,
82
+ state.lam_vc,
83
+ state.lam_vb_nodal,
84
+ state.lam_vb_cross,
85
+ state.lam_cost,
86
+ nodal_constraints,
87
+ params,
88
+ settings,
89
+ )
90
+
91
+ candidate.J_nonlin = nonlinear_cost + nonlinear_penalty + nodal_penalty
92
+
93
+ if state.k > self.lam_cost_drop:
94
+ candidate.lam_cost = state.lam_cost * self.lam_cost_relax
95
+ else:
96
+ candidate.lam_cost = weights.lam_cost
97
+
98
+ lam_prox_k = deepcopy(state.lam_prox)
99
+
100
+ if state.k > 1:
101
+ state_x_prop_plus = state.x_prop_plus()
102
+ state_x_prop = (
103
+ state_x_prop_plus[1:] if state_x_prop_plus is not None else state.x_prop()
104
+ )
105
+ (
106
+ prev_nonlinear_cost,
107
+ prev_nonlinear_penalty,
108
+ prev_nodal_penalty,
109
+ ) = self.calculate_nonlinear_penalty(
110
+ state_x_prop,
111
+ state.x,
112
+ state.u,
113
+ state.lam_vc,
114
+ state.lam_vb_nodal,
115
+ state.lam_vb_cross,
116
+ state.lam_cost,
117
+ nodal_constraints,
118
+ params,
119
+ settings,
120
+ )
121
+
122
+ J_nonlin_prev = prev_nonlinear_cost + prev_nonlinear_penalty + prev_nodal_penalty
123
+
124
+ actual_reduction = J_nonlin_prev - candidate.J_nonlin
125
+ predicted_reduction = J_nonlin_prev - candidate.J_lin
126
+
127
+ if predicted_reduction == 0:
128
+ raise ValueError("Predicted reduction is 0.")
129
+
130
+ rho = actual_reduction / predicted_reduction
131
+
132
+ state.pred_reduction_history.append(predicted_reduction)
133
+ state.actual_reduction_history.append(actual_reduction)
134
+ state.acceptance_ratio_history.append(rho)
135
+
136
+ if rho < self.eta_0:
137
+ lam_prox_k1 = np.minimum(self.lam_prox_max, self.gamma_1 * lam_prox_k)
138
+ candidate.lam_prox = lam_prox_k1
139
+ state.reject_solution(candidate)
140
+ adaptive_state = "Reject Higher"
141
+ elif rho >= self.eta_0 and rho < self.eta_1:
142
+ lam_prox_k1 = np.minimum(self.lam_prox_max, self.gamma_1 * lam_prox_k)
143
+ candidate.lam_prox = lam_prox_k1
144
+ self._copy_virtual_weights(candidate, state)
145
+ state.accept_solution(candidate)
146
+ adaptive_state = "Accept Higher"
147
+ elif rho >= self.eta_1 and rho < self.eta_2:
148
+ candidate.lam_prox = lam_prox_k
149
+ self._copy_virtual_weights(candidate, state)
150
+ state.accept_solution(candidate)
151
+ adaptive_state = "Accept Constant"
152
+ else:
153
+ lam_prox_k1 = np.maximum(self.lam_prox_min, self.gamma_2 * lam_prox_k)
154
+ candidate.lam_prox = lam_prox_k1
155
+ self._copy_virtual_weights(candidate, state)
156
+ state.accept_solution(candidate)
157
+ adaptive_state = "Accept Lower"
158
+
159
+ else:
160
+ candidate.lam_prox = lam_prox_k
161
+ self._copy_virtual_weights(candidate, state)
162
+ state.accept_solution(candidate)
163
+ adaptive_state = "Initial"
164
+
165
+ return adaptive_state
166
+
167
+
168
+ # =============================================================================
169
+ # Pydantic spec for dict / YAML validation
170
+ # =============================================================================
171
+
172
+
173
+ class AdaptiveProximalWeightSpec(BaseModel):
174
+ """Validates AdaptiveProximalWeight configuration from dict/YAML input."""
175
+
176
+ type: Literal["AdaptiveProximalWeight"] = "AdaptiveProximalWeight"
177
+ gamma_1: float = 2.0
178
+ gamma_2: float = 0.5
179
+ eta_0: float = 1e-2
180
+ eta_1: float = 1e-1
181
+ eta_2: float = 0.8
182
+ lam_prox_min: float = 1e-3
183
+ lam_prox_max: float = 1e4
184
+ lam_cost_drop: int = -1
185
+ lam_cost_relax: float = 1.0
186
+
187
+ model_config = ConfigDict(extra="forbid")
188
+
189
+ def build(self) -> AdaptiveProximalWeight:
190
+ return AdaptiveProximalWeight(**self.model_dump(exclude={"type"}, exclude_unset=True))