openscvx 0.3.2.dev173__tar.gz → 0.3.2.dev195__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 (235) hide show
  1. {openscvx-0.3.2.dev173/openscvx.egg-info → openscvx-0.3.2.dev195}/PKG-INFO +1 -1
  2. {openscvx-0.3.2.dev173 → openscvx-0.3.2.dev195}/examples/drone/dr_vp.py +18 -15
  3. {openscvx-0.3.2.dev173 → openscvx-0.3.2.dev195}/examples/drone/dr_vp_nodal.py +18 -15
  4. {openscvx-0.3.2.dev173 → openscvx-0.3.2.dev195}/examples/drone/dr_vp_polytope.py +13 -12
  5. openscvx-0.3.2.dev195/examples/drone/obstacle_avoidance_vmap.py +238 -0
  6. {openscvx-0.3.2.dev173 → openscvx-0.3.2.dev195}/examples/plotting_viser.py +6 -2
  7. openscvx-0.3.2.dev195/examples/spacecraft/proxops_cw.py +188 -0
  8. {openscvx-0.3.2.dev173 → openscvx-0.3.2.dev195}/openscvx/__init__.py +3 -0
  9. {openscvx-0.3.2.dev173 → openscvx-0.3.2.dev195}/openscvx/_version.py +3 -3
  10. {openscvx-0.3.2.dev173 → openscvx-0.3.2.dev195}/openscvx/plotting/viser/primitives.py +37 -17
  11. {openscvx-0.3.2.dev173 → openscvx-0.3.2.dev195}/openscvx/plotting/viser/server.py +10 -7
  12. {openscvx-0.3.2.dev173 → openscvx-0.3.2.dev195}/openscvx/symbolic/expr/__init__.py +5 -0
  13. openscvx-0.3.2.dev195/openscvx/symbolic/expr/vmap.py +321 -0
  14. {openscvx-0.3.2.dev173 → openscvx-0.3.2.dev195}/openscvx/symbolic/lowerers/jax.py +71 -0
  15. {openscvx-0.3.2.dev173 → openscvx-0.3.2.dev195/openscvx.egg-info}/PKG-INFO +1 -1
  16. {openscvx-0.3.2.dev173 → openscvx-0.3.2.dev195}/openscvx.egg-info/SOURCES.txt +5 -1
  17. openscvx-0.3.2.dev195/tests/symbolic/expr/test_vmap.py +414 -0
  18. {openscvx-0.3.2.dev173 → openscvx-0.3.2.dev195}/.github/assets/logo.svg +0 -0
  19. {openscvx-0.3.2.dev173 → openscvx-0.3.2.dev195}/.github/release-drafter.yml +0 -0
  20. {openscvx-0.3.2.dev173 → openscvx-0.3.2.dev195}/.github/workflows/_docs.yml +0 -0
  21. {openscvx-0.3.2.dev173 → openscvx-0.3.2.dev195}/.github/workflows/docs.yml +0 -0
  22. {openscvx-0.3.2.dev173 → openscvx-0.3.2.dev195}/.github/workflows/lint.yml +0 -0
  23. {openscvx-0.3.2.dev173 → openscvx-0.3.2.dev195}/.github/workflows/nightly.yml +0 -0
  24. {openscvx-0.3.2.dev173 → openscvx-0.3.2.dev195}/.github/workflows/release-drafter.yml +0 -0
  25. {openscvx-0.3.2.dev173 → openscvx-0.3.2.dev195}/.github/workflows/release.yml +0 -0
  26. {openscvx-0.3.2.dev173 → openscvx-0.3.2.dev195}/.github/workflows/tests-integration.yml +0 -0
  27. {openscvx-0.3.2.dev173 → openscvx-0.3.2.dev195}/.github/workflows/tests-unit.yml +0 -0
  28. {openscvx-0.3.2.dev173 → openscvx-0.3.2.dev195}/.gitignore +0 -0
  29. {openscvx-0.3.2.dev173 → openscvx-0.3.2.dev195}/CONTRIBUTING.md +0 -0
  30. {openscvx-0.3.2.dev173 → openscvx-0.3.2.dev195}/LICENSE +0 -0
  31. {openscvx-0.3.2.dev173 → openscvx-0.3.2.dev195}/README.md +0 -0
  32. {openscvx-0.3.2.dev173 → openscvx-0.3.2.dev195}/docs/Overview/constraint_reformulation.md +0 -0
  33. {openscvx-0.3.2.dev173 → openscvx-0.3.2.dev195}/docs/Overview/control_parameterization.md +0 -0
  34. {openscvx-0.3.2.dev173 → openscvx-0.3.2.dev195}/docs/Overview/discretization.md +0 -0
  35. {openscvx-0.3.2.dev173 → openscvx-0.3.2.dev195}/docs/Overview/ocp.md +0 -0
  36. {openscvx-0.3.2.dev173 → openscvx-0.3.2.dev195}/docs/Overview/scvx.md +0 -0
  37. {openscvx-0.3.2.dev173 → openscvx-0.3.2.dev195}/docs/Overview/time_dilation.md +0 -0
  38. {openscvx-0.3.2.dev173 → openscvx-0.3.2.dev195}/docs/UnderTheHood/lowering_architecture.md +0 -0
  39. {openscvx-0.3.2.dev173 → openscvx-0.3.2.dev195}/docs/UnderTheHood/vectorization_and_vmapping.md +0 -0
  40. {openscvx-0.3.2.dev173 → openscvx-0.3.2.dev195}/docs/Usage/advanced_problem_setup.md +0 -0
  41. {openscvx-0.3.2.dev173 → openscvx-0.3.2.dev195}/docs/Usage/api.md +0 -0
  42. {openscvx-0.3.2.dev173 → openscvx-0.3.2.dev195}/docs/Usage/api_constraints.md +0 -0
  43. {openscvx-0.3.2.dev173 → openscvx-0.3.2.dev195}/docs/Usage/api_control.md +0 -0
  44. {openscvx-0.3.2.dev173 → openscvx-0.3.2.dev195}/docs/Usage/api_integrators.md +0 -0
  45. {openscvx-0.3.2.dev173 → openscvx-0.3.2.dev195}/docs/Usage/api_state.md +0 -0
  46. {openscvx-0.3.2.dev173 → openscvx-0.3.2.dev195}/docs/Usage/api_trajoptproblem.md +0 -0
  47. {openscvx-0.3.2.dev173 → openscvx-0.3.2.dev195}/docs/Usage/api_variable.md +0 -0
  48. {openscvx-0.3.2.dev173 → openscvx-0.3.2.dev195}/docs/Usage/basic_problem_setup.md +0 -0
  49. {openscvx-0.3.2.dev173 → openscvx-0.3.2.dev195}/docs/Usage/tutorial_6dof_los_guidance.md +0 -0
  50. {openscvx-0.3.2.dev173 → openscvx-0.3.2.dev195}/docs/Usage/tutorial_6dof_obstacle_avoidance.md +0 -0
  51. {openscvx-0.3.2.dev173 → openscvx-0.3.2.dev195}/docs/Usage/tutorials.md +0 -0
  52. {openscvx-0.3.2.dev173 → openscvx-0.3.2.dev195}/docs/assets/favicon.png +0 -0
  53. {openscvx-0.3.2.dev173 → openscvx-0.3.2.dev195}/docs/assets/images/ct-scvx_dark.png +0 -0
  54. {openscvx-0.3.2.dev173 → openscvx-0.3.2.dev195}/docs/assets/images/ct-scvx_light.png +0 -0
  55. {openscvx-0.3.2.dev173 → openscvx-0.3.2.dev195}/docs/assets/images/ctcs_dark.png +0 -0
  56. {openscvx-0.3.2.dev173 → openscvx-0.3.2.dev195}/docs/assets/images/ctcs_light.png +0 -0
  57. {openscvx-0.3.2.dev173 → openscvx-0.3.2.dev195}/docs/assets/images/problem_class_dark.png +0 -0
  58. {openscvx-0.3.2.dev173 → openscvx-0.3.2.dev195}/docs/assets/images/problem_class_light.png +0 -0
  59. {openscvx-0.3.2.dev173 → openscvx-0.3.2.dev195}/docs/assets/logo.svg +0 -0
  60. {openscvx-0.3.2.dev173 → openscvx-0.3.2.dev195}/docs/citation.md +0 -0
  61. {openscvx-0.3.2.dev173 → openscvx-0.3.2.dev195}/docs/examples.md +0 -0
  62. {openscvx-0.3.2.dev173 → openscvx-0.3.2.dev195}/docs/getting-started.md +0 -0
  63. {openscvx-0.3.2.dev173 → openscvx-0.3.2.dev195}/docs/index.md +0 -0
  64. {openscvx-0.3.2.dev173 → openscvx-0.3.2.dev195}/docs/javascripts/mathjax.js +0 -0
  65. {openscvx-0.3.2.dev173 → openscvx-0.3.2.dev195}/examples/abstract/3DoF_pdg.py +0 -0
  66. {openscvx-0.3.2.dev173 → openscvx-0.3.2.dev195}/examples/abstract/brachistochrone.py +0 -0
  67. {openscvx-0.3.2.dev173 → openscvx-0.3.2.dev195}/examples/arm/three_link_arm.py +0 -0
  68. {openscvx-0.3.2.dev173 → openscvx-0.3.2.dev195}/examples/car/dubins_car.py +0 -0
  69. {openscvx-0.3.2.dev173 → openscvx-0.3.2.dev195}/examples/car/dubins_car_disjoint.py +0 -0
  70. {openscvx-0.3.2.dev173 → openscvx-0.3.2.dev195}/examples/car/dubins_car_stljax.py +0 -0
  71. {openscvx-0.3.2.dev173 → openscvx-0.3.2.dev195}/examples/drone/cinema_vp.py +0 -0
  72. {openscvx-0.3.2.dev173 → openscvx-0.3.2.dev195}/examples/drone/cinema_vp_realtime_base.py +0 -0
  73. {openscvx-0.3.2.dev173 → openscvx-0.3.2.dev195}/examples/drone/dr_double_integrator.py +0 -0
  74. {openscvx-0.3.2.dev173 → openscvx-0.3.2.dev195}/examples/drone/drone_racing.py +0 -0
  75. {openscvx-0.3.2.dev173 → openscvx-0.3.2.dev195}/examples/drone/obstacle_avoidance.py +0 -0
  76. {openscvx-0.3.2.dev173 → openscvx-0.3.2.dev195}/examples/drone/obstacle_avoidance_nodal.py +0 -0
  77. {openscvx-0.3.2.dev173 → openscvx-0.3.2.dev195}/examples/drone/obstacle_avoidance_realtime_base.py +0 -0
  78. {openscvx-0.3.2.dev173 → openscvx-0.3.2.dev195}/examples/plotting.py +0 -0
  79. {openscvx-0.3.2.dev173 → openscvx-0.3.2.dev195}/examples/realtime/cinema_vp_realtime.py +0 -0
  80. {openscvx-0.3.2.dev173 → openscvx-0.3.2.dev195}/examples/realtime/drone_racing_realtime.py +0 -0
  81. {openscvx-0.3.2.dev173 → openscvx-0.3.2.dev195}/examples/realtime/dubins_car_realtime.py +0 -0
  82. {openscvx-0.3.2.dev173 → openscvx-0.3.2.dev195}/examples/realtime/obstacle_avoidance_realtime.py +0 -0
  83. {openscvx-0.3.2.dev173 → openscvx-0.3.2.dev195}/figures/ctlos_cine.gif +0 -0
  84. {openscvx-0.3.2.dev173 → openscvx-0.3.2.dev195}/figures/ctlos_dr.gif +0 -0
  85. {openscvx-0.3.2.dev173 → openscvx-0.3.2.dev195}/figures/dtlos_cine.gif +0 -0
  86. {openscvx-0.3.2.dev173 → openscvx-0.3.2.dev195}/figures/dtlos_dr.gif +0 -0
  87. {openscvx-0.3.2.dev173 → openscvx-0.3.2.dev195}/figures/openscvx_logo.svg +0 -0
  88. {openscvx-0.3.2.dev173 → openscvx-0.3.2.dev195}/figures/openscvx_logo_square.png +0 -0
  89. {openscvx-0.3.2.dev173 → openscvx-0.3.2.dev195}/figures/oscvx_structure_full_dark.svg +0 -0
  90. {openscvx-0.3.2.dev173 → openscvx-0.3.2.dev195}/figures/video_preview.png +0 -0
  91. {openscvx-0.3.2.dev173 → openscvx-0.3.2.dev195}/material/__init__.py +0 -0
  92. {openscvx-0.3.2.dev173 → openscvx-0.3.2.dev195}/material/overrides/assets/images/layers/1-background.avif +0 -0
  93. {openscvx-0.3.2.dev173 → openscvx-0.3.2.dev195}/material/overrides/assets/images/layers/1-background@1x.avif +0 -0
  94. {openscvx-0.3.2.dev173 → openscvx-0.3.2.dev195}/material/overrides/assets/images/layers/1-background@2x.avif +0 -0
  95. {openscvx-0.3.2.dev173 → openscvx-0.3.2.dev195}/material/overrides/assets/images/layers/1-background@3x.avif +0 -0
  96. {openscvx-0.3.2.dev173 → openscvx-0.3.2.dev195}/material/overrides/assets/images/layers/1-background@4x.avif +0 -0
  97. {openscvx-0.3.2.dev173 → openscvx-0.3.2.dev195}/material/overrides/assets/images/layers/2-mars.avif +0 -0
  98. {openscvx-0.3.2.dev173 → openscvx-0.3.2.dev195}/material/overrides/assets/images/layers/2-mars@1x.avif +0 -0
  99. {openscvx-0.3.2.dev173 → openscvx-0.3.2.dev195}/material/overrides/assets/images/layers/2-mars@2x.avif +0 -0
  100. {openscvx-0.3.2.dev173 → openscvx-0.3.2.dev195}/material/overrides/assets/images/layers/2-mars@3x.avif +0 -0
  101. {openscvx-0.3.2.dev173 → openscvx-0.3.2.dev195}/material/overrides/assets/images/layers/2-mars@4x.avif +0 -0
  102. {openscvx-0.3.2.dev173 → openscvx-0.3.2.dev195}/material/overrides/assets/images/layers/3-moon.avif +0 -0
  103. {openscvx-0.3.2.dev173 → openscvx-0.3.2.dev195}/material/overrides/assets/images/layers/3-moon@1x.avif +0 -0
  104. {openscvx-0.3.2.dev173 → openscvx-0.3.2.dev195}/material/overrides/assets/images/layers/3-moon@2x.avif +0 -0
  105. {openscvx-0.3.2.dev173 → openscvx-0.3.2.dev195}/material/overrides/assets/images/layers/3-moon@3x.avif +0 -0
  106. {openscvx-0.3.2.dev173 → openscvx-0.3.2.dev195}/material/overrides/assets/images/layers/3-moon@4x.avif +0 -0
  107. {openscvx-0.3.2.dev173 → openscvx-0.3.2.dev195}/material/overrides/assets/images/layers/4-sat1.avif +0 -0
  108. {openscvx-0.3.2.dev173 → openscvx-0.3.2.dev195}/material/overrides/assets/images/layers/4-sat1@1x.avif +0 -0
  109. {openscvx-0.3.2.dev173 → openscvx-0.3.2.dev195}/material/overrides/assets/images/layers/4-sat1@2x.avif +0 -0
  110. {openscvx-0.3.2.dev173 → openscvx-0.3.2.dev195}/material/overrides/assets/images/layers/4-sat1@3x.avif +0 -0
  111. {openscvx-0.3.2.dev173 → openscvx-0.3.2.dev195}/material/overrides/assets/images/layers/4-sat1@4x.avif +0 -0
  112. {openscvx-0.3.2.dev173 → openscvx-0.3.2.dev195}/material/overrides/assets/images/layers/5-space.avif +0 -0
  113. {openscvx-0.3.2.dev173 → openscvx-0.3.2.dev195}/material/overrides/assets/images/layers/5-space@1x.avif +0 -0
  114. {openscvx-0.3.2.dev173 → openscvx-0.3.2.dev195}/material/overrides/assets/images/layers/5-space@2x.avif +0 -0
  115. {openscvx-0.3.2.dev173 → openscvx-0.3.2.dev195}/material/overrides/assets/images/layers/5-space@3x.avif +0 -0
  116. {openscvx-0.3.2.dev173 → openscvx-0.3.2.dev195}/material/overrides/assets/images/layers/5-space@4x.avif +0 -0
  117. {openscvx-0.3.2.dev173 → openscvx-0.3.2.dev195}/material/overrides/assets/images/layers/6-earth.avif +0 -0
  118. {openscvx-0.3.2.dev173 → openscvx-0.3.2.dev195}/material/overrides/assets/images/layers/6-earth@1x.avif +0 -0
  119. {openscvx-0.3.2.dev173 → openscvx-0.3.2.dev195}/material/overrides/assets/images/layers/6-earth@2x.avif +0 -0
  120. {openscvx-0.3.2.dev173 → openscvx-0.3.2.dev195}/material/overrides/assets/images/layers/6-earth@3x.avif +0 -0
  121. {openscvx-0.3.2.dev173 → openscvx-0.3.2.dev195}/material/overrides/assets/images/layers/6-earth@4x.avif +0 -0
  122. {openscvx-0.3.2.dev173 → openscvx-0.3.2.dev195}/material/overrides/assets/javascripts/parallax.js +0 -0
  123. {openscvx-0.3.2.dev173 → openscvx-0.3.2.dev195}/material/overrides/assets/logo.svg +0 -0
  124. {openscvx-0.3.2.dev173 → openscvx-0.3.2.dev195}/material/overrides/assets/stylesheets/custom.css +0 -0
  125. {openscvx-0.3.2.dev173 → openscvx-0.3.2.dev195}/material/overrides/assets/stylesheets/parallax.css +0 -0
  126. {openscvx-0.3.2.dev173 → openscvx-0.3.2.dev195}/material/overrides/home.html +0 -0
  127. {openscvx-0.3.2.dev173 → openscvx-0.3.2.dev195}/material/overrides/main.html +0 -0
  128. {openscvx-0.3.2.dev173 → openscvx-0.3.2.dev195}/material/overrides/partials/parallax/hero.html +0 -0
  129. {openscvx-0.3.2.dev173 → openscvx-0.3.2.dev195}/material/overrides/partials/parallax.html +0 -0
  130. {openscvx-0.3.2.dev173 → openscvx-0.3.2.dev195}/mkdocs.yml +0 -0
  131. {openscvx-0.3.2.dev173 → openscvx-0.3.2.dev195}/openscvx/algorithms/__init__.py +0 -0
  132. {openscvx-0.3.2.dev173 → openscvx-0.3.2.dev195}/openscvx/algorithms/autotuning.py +0 -0
  133. {openscvx-0.3.2.dev173 → openscvx-0.3.2.dev195}/openscvx/algorithms/base.py +0 -0
  134. {openscvx-0.3.2.dev173 → openscvx-0.3.2.dev195}/openscvx/algorithms/optimization_results.py +0 -0
  135. {openscvx-0.3.2.dev173 → openscvx-0.3.2.dev195}/openscvx/algorithms/penalized_trust_region.py +0 -0
  136. {openscvx-0.3.2.dev173 → openscvx-0.3.2.dev195}/openscvx/config.py +0 -0
  137. {openscvx-0.3.2.dev173 → openscvx-0.3.2.dev195}/openscvx/discretization/__init__.py +0 -0
  138. {openscvx-0.3.2.dev173 → openscvx-0.3.2.dev195}/openscvx/discretization/discretization.py +0 -0
  139. {openscvx-0.3.2.dev173 → openscvx-0.3.2.dev195}/openscvx/expert/__init__.py +0 -0
  140. {openscvx-0.3.2.dev173 → openscvx-0.3.2.dev195}/openscvx/expert/byof.py +0 -0
  141. {openscvx-0.3.2.dev173 → openscvx-0.3.2.dev195}/openscvx/expert/lowering.py +0 -0
  142. {openscvx-0.3.2.dev173 → openscvx-0.3.2.dev195}/openscvx/expert/validation.py +0 -0
  143. {openscvx-0.3.2.dev173 → openscvx-0.3.2.dev195}/openscvx/integrators/__init__.py +0 -0
  144. {openscvx-0.3.2.dev173 → openscvx-0.3.2.dev195}/openscvx/integrators/runge_kutta.py +0 -0
  145. {openscvx-0.3.2.dev173 → openscvx-0.3.2.dev195}/openscvx/lowered/__init__.py +0 -0
  146. {openscvx-0.3.2.dev173 → openscvx-0.3.2.dev195}/openscvx/lowered/cvxpy_constraints.py +0 -0
  147. {openscvx-0.3.2.dev173 → openscvx-0.3.2.dev195}/openscvx/lowered/cvxpy_variables.py +0 -0
  148. {openscvx-0.3.2.dev173 → openscvx-0.3.2.dev195}/openscvx/lowered/dynamics.py +0 -0
  149. {openscvx-0.3.2.dev173 → openscvx-0.3.2.dev195}/openscvx/lowered/jax_constraints.py +0 -0
  150. {openscvx-0.3.2.dev173 → openscvx-0.3.2.dev195}/openscvx/lowered/parameters.py +0 -0
  151. {openscvx-0.3.2.dev173 → openscvx-0.3.2.dev195}/openscvx/lowered/problem.py +0 -0
  152. {openscvx-0.3.2.dev173 → openscvx-0.3.2.dev195}/openscvx/lowered/unified.py +0 -0
  153. {openscvx-0.3.2.dev173 → openscvx-0.3.2.dev195}/openscvx/plotting/__init__.py +0 -0
  154. {openscvx-0.3.2.dev173 → openscvx-0.3.2.dev195}/openscvx/plotting/plotting.py +0 -0
  155. {openscvx-0.3.2.dev173 → openscvx-0.3.2.dev195}/openscvx/plotting/scp_iteration.py +0 -0
  156. {openscvx-0.3.2.dev173 → openscvx-0.3.2.dev195}/openscvx/plotting/viser/__init__.py +0 -0
  157. {openscvx-0.3.2.dev173 → openscvx-0.3.2.dev195}/openscvx/plotting/viser/animated.py +0 -0
  158. {openscvx-0.3.2.dev173 → openscvx-0.3.2.dev195}/openscvx/plotting/viser/plotly_integration.py +0 -0
  159. {openscvx-0.3.2.dev173 → openscvx-0.3.2.dev195}/openscvx/plotting/viser/scp.py +0 -0
  160. {openscvx-0.3.2.dev173 → openscvx-0.3.2.dev195}/openscvx/problem.py +0 -0
  161. {openscvx-0.3.2.dev173 → openscvx-0.3.2.dev195}/openscvx/propagation/__init__.py +0 -0
  162. {openscvx-0.3.2.dev173 → openscvx-0.3.2.dev195}/openscvx/propagation/post_processing.py +0 -0
  163. {openscvx-0.3.2.dev173 → openscvx-0.3.2.dev195}/openscvx/propagation/propagation.py +0 -0
  164. {openscvx-0.3.2.dev173 → openscvx-0.3.2.dev195}/openscvx/solvers/__init__.py +0 -0
  165. {openscvx-0.3.2.dev173 → openscvx-0.3.2.dev195}/openscvx/solvers/cvxpy.py +0 -0
  166. {openscvx-0.3.2.dev173 → openscvx-0.3.2.dev195}/openscvx/symbolic/__init__.py +0 -0
  167. {openscvx-0.3.2.dev173 → openscvx-0.3.2.dev195}/openscvx/symbolic/augmentation.py +0 -0
  168. {openscvx-0.3.2.dev173 → openscvx-0.3.2.dev195}/openscvx/symbolic/builder.py +0 -0
  169. {openscvx-0.3.2.dev173 → openscvx-0.3.2.dev195}/openscvx/symbolic/constraint_set.py +0 -0
  170. {openscvx-0.3.2.dev173 → openscvx-0.3.2.dev195}/openscvx/symbolic/expr/arithmetic.py +0 -0
  171. {openscvx-0.3.2.dev173 → openscvx-0.3.2.dev195}/openscvx/symbolic/expr/array.py +0 -0
  172. {openscvx-0.3.2.dev173 → openscvx-0.3.2.dev195}/openscvx/symbolic/expr/constraint.py +0 -0
  173. {openscvx-0.3.2.dev173 → openscvx-0.3.2.dev195}/openscvx/symbolic/expr/control.py +0 -0
  174. {openscvx-0.3.2.dev173 → openscvx-0.3.2.dev195}/openscvx/symbolic/expr/expr.py +0 -0
  175. {openscvx-0.3.2.dev173 → openscvx-0.3.2.dev195}/openscvx/symbolic/expr/lie/__init__.py +0 -0
  176. {openscvx-0.3.2.dev173 → openscvx-0.3.2.dev195}/openscvx/symbolic/expr/lie/adjoint.py +0 -0
  177. {openscvx-0.3.2.dev173 → openscvx-0.3.2.dev195}/openscvx/symbolic/expr/lie/se3.py +0 -0
  178. {openscvx-0.3.2.dev173 → openscvx-0.3.2.dev195}/openscvx/symbolic/expr/lie/so3.py +0 -0
  179. {openscvx-0.3.2.dev173 → openscvx-0.3.2.dev195}/openscvx/symbolic/expr/linalg.py +0 -0
  180. {openscvx-0.3.2.dev173 → openscvx-0.3.2.dev195}/openscvx/symbolic/expr/math.py +0 -0
  181. {openscvx-0.3.2.dev173 → openscvx-0.3.2.dev195}/openscvx/symbolic/expr/spatial.py +0 -0
  182. {openscvx-0.3.2.dev173 → openscvx-0.3.2.dev195}/openscvx/symbolic/expr/state.py +0 -0
  183. {openscvx-0.3.2.dev173 → openscvx-0.3.2.dev195}/openscvx/symbolic/expr/stl.py +0 -0
  184. {openscvx-0.3.2.dev173 → openscvx-0.3.2.dev195}/openscvx/symbolic/expr/variable.py +0 -0
  185. {openscvx-0.3.2.dev173 → openscvx-0.3.2.dev195}/openscvx/symbolic/hashing.py +0 -0
  186. {openscvx-0.3.2.dev173 → openscvx-0.3.2.dev195}/openscvx/symbolic/lower.py +0 -0
  187. {openscvx-0.3.2.dev173 → openscvx-0.3.2.dev195}/openscvx/symbolic/lowerers/__init__.py +0 -0
  188. {openscvx-0.3.2.dev173 → openscvx-0.3.2.dev195}/openscvx/symbolic/lowerers/cvxpy.py +0 -0
  189. {openscvx-0.3.2.dev173 → openscvx-0.3.2.dev195}/openscvx/symbolic/preprocessing.py +0 -0
  190. {openscvx-0.3.2.dev173 → openscvx-0.3.2.dev195}/openscvx/symbolic/problem.py +0 -0
  191. {openscvx-0.3.2.dev173 → openscvx-0.3.2.dev195}/openscvx/symbolic/time.py +0 -0
  192. {openscvx-0.3.2.dev173 → openscvx-0.3.2.dev195}/openscvx/symbolic/unified.py +0 -0
  193. {openscvx-0.3.2.dev173 → openscvx-0.3.2.dev195}/openscvx/utils/__init__.py +0 -0
  194. {openscvx-0.3.2.dev173 → openscvx-0.3.2.dev195}/openscvx/utils/cache.py +0 -0
  195. {openscvx-0.3.2.dev173 → openscvx-0.3.2.dev195}/openscvx/utils/caching.py +0 -0
  196. {openscvx-0.3.2.dev173 → openscvx-0.3.2.dev195}/openscvx/utils/printing.py +0 -0
  197. {openscvx-0.3.2.dev173 → openscvx-0.3.2.dev195}/openscvx/utils/profiling.py +0 -0
  198. {openscvx-0.3.2.dev173 → openscvx-0.3.2.dev195}/openscvx/utils/utils.py +0 -0
  199. {openscvx-0.3.2.dev173 → openscvx-0.3.2.dev195}/openscvx.egg-info/dependency_links.txt +0 -0
  200. {openscvx-0.3.2.dev173 → openscvx-0.3.2.dev195}/openscvx.egg-info/requires.txt +0 -0
  201. {openscvx-0.3.2.dev173 → openscvx-0.3.2.dev195}/openscvx.egg-info/top_level.txt +0 -0
  202. {openscvx-0.3.2.dev173 → openscvx-0.3.2.dev195}/pyproject.toml +0 -0
  203. {openscvx-0.3.2.dev173 → openscvx-0.3.2.dev195}/scripts/gen_example_pages.py +0 -0
  204. {openscvx-0.3.2.dev173 → openscvx-0.3.2.dev195}/scripts/gen_ref_pages.py +0 -0
  205. {openscvx-0.3.2.dev173 → openscvx-0.3.2.dev195}/setup.cfg +0 -0
  206. {openscvx-0.3.2.dev173 → openscvx-0.3.2.dev195}/tests/__init__.py +0 -0
  207. {openscvx-0.3.2.dev173 → openscvx-0.3.2.dev195}/tests/brachistochrone_analytical.py +0 -0
  208. {openscvx-0.3.2.dev173 → openscvx-0.3.2.dev195}/tests/symbolic/__init__.py +0 -0
  209. {openscvx-0.3.2.dev173 → openscvx-0.3.2.dev195}/tests/symbolic/expr/__init__.py +0 -0
  210. {openscvx-0.3.2.dev173 → openscvx-0.3.2.dev195}/tests/symbolic/expr/test_arithmetic.py +0 -0
  211. {openscvx-0.3.2.dev173 → openscvx-0.3.2.dev195}/tests/symbolic/expr/test_array.py +0 -0
  212. {openscvx-0.3.2.dev173 → openscvx-0.3.2.dev195}/tests/symbolic/expr/test_constraint.py +0 -0
  213. {openscvx-0.3.2.dev173 → openscvx-0.3.2.dev195}/tests/symbolic/expr/test_expr.py +0 -0
  214. {openscvx-0.3.2.dev173 → openscvx-0.3.2.dev195}/tests/symbolic/expr/test_lie.py +0 -0
  215. {openscvx-0.3.2.dev173 → openscvx-0.3.2.dev195}/tests/symbolic/expr/test_linalg.py +0 -0
  216. {openscvx-0.3.2.dev173 → openscvx-0.3.2.dev195}/tests/symbolic/expr/test_math.py +0 -0
  217. {openscvx-0.3.2.dev173 → openscvx-0.3.2.dev195}/tests/symbolic/expr/test_node_reference.py +0 -0
  218. {openscvx-0.3.2.dev173 → openscvx-0.3.2.dev195}/tests/symbolic/expr/test_parameters.py +0 -0
  219. {openscvx-0.3.2.dev173 → openscvx-0.3.2.dev195}/tests/symbolic/expr/test_scaling.py +0 -0
  220. {openscvx-0.3.2.dev173 → openscvx-0.3.2.dev195}/tests/symbolic/expr/test_spatial.py +0 -0
  221. {openscvx-0.3.2.dev173 → openscvx-0.3.2.dev195}/tests/symbolic/expr/test_variable.py +0 -0
  222. {openscvx-0.3.2.dev173 → openscvx-0.3.2.dev195}/tests/symbolic/test_augmentation.py +0 -0
  223. {openscvx-0.3.2.dev173 → openscvx-0.3.2.dev195}/tests/symbolic/test_hashing.py +0 -0
  224. {openscvx-0.3.2.dev173 → openscvx-0.3.2.dev195}/tests/symbolic/test_lower_cvxpy.py +0 -0
  225. {openscvx-0.3.2.dev173 → openscvx-0.3.2.dev195}/tests/symbolic/test_lower_jax.py +0 -0
  226. {openscvx-0.3.2.dev173 → openscvx-0.3.2.dev195}/tests/symbolic/test_preprocessing.py +0 -0
  227. {openscvx-0.3.2.dev173 → openscvx-0.3.2.dev195}/tests/symbolic/test_unified.py +0 -0
  228. {openscvx-0.3.2.dev173 → openscvx-0.3.2.dev195}/tests/test_brachistochrone.py +0 -0
  229. {openscvx-0.3.2.dev173 → openscvx-0.3.2.dev195}/tests/test_cvxpygen_optional.py +0 -0
  230. {openscvx-0.3.2.dev173 → openscvx-0.3.2.dev195}/tests/test_discretization.py +0 -0
  231. {openscvx-0.3.2.dev173 → openscvx-0.3.2.dev195}/tests/test_examples.py +0 -0
  232. {openscvx-0.3.2.dev173 → openscvx-0.3.2.dev195}/tests/test_expert.py +0 -0
  233. {openscvx-0.3.2.dev173 → openscvx-0.3.2.dev195}/tests/test_integrators.py +0 -0
  234. {openscvx-0.3.2.dev173 → openscvx-0.3.2.dev195}/tests/test_plotting.py +0 -0
  235. {openscvx-0.3.2.dev173 → openscvx-0.3.2.dev195}/tests/test_propagation.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: openscvx
3
- Version: 0.3.2.dev173
3
+ Version: 0.3.2.dev195
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
@@ -116,14 +116,13 @@ for center in gate_centers:
116
116
  ### End Gate Parameters ###
117
117
 
118
118
  n_subs = 10
119
- init_poses = []
120
119
  np.random.seed(0)
121
- for i in range(n_subs):
122
- init_pose = np.array([100.0, -60.0, 20.0])
123
- init_pose[:2] = init_pose[:2] + np.random.random(2) * 20.0
124
- init_poses.append(init_pose)
125
-
126
- init_poses = init_poses
120
+ init_poses = np.array(
121
+ [
122
+ [100.0 + np.random.random() * 20.0, -60.0 + np.random.random() * 20.0, 20.0]
123
+ for _ in range(n_subs)
124
+ ]
125
+ ) # Shape: (n_subs, 3)
127
126
 
128
127
 
129
128
  # Define list of all states (needed for Problem and constraints)
@@ -142,9 +141,16 @@ constraints = []
142
141
  for state in states:
143
142
  constraints.extend([ox.ctcs(state <= state.max), ox.ctcs(state.min <= state)])
144
143
 
145
- # Add visibility constraints using symbolic expressions
146
- for pose in init_poses:
147
- constraints.append(ox.ctcs(g_vp(pose, position, attitude) <= 0.0))
144
+ # Add visibility constraints using Vmap for parallel evaluation
145
+ # Single CTCS constraint with vectorized evaluation over all target poses
146
+ visibility_constraint = ox.ctcs(
147
+ ox.Vmap(
148
+ lambda pose: g_vp(pose, position, attitude),
149
+ batch=init_poses,
150
+ )
151
+ <= 0.0
152
+ )
153
+ constraints.append(visibility_constraint)
148
154
 
149
155
  # Add gate constraints using symbolic expressions
150
156
  for node, cen in zip(gate_nodes, A_gate_cen):
@@ -207,12 +213,9 @@ for _ in range(n_gates + 1):
207
213
  # Modify attitude to point sensor at targets
208
214
  R_sb = R_sb # Sensor to body frame
209
215
  b = R_sb @ np.array([0, 1, 0])
216
+ mean_target = np.mean(init_poses, axis=0) # Average target position
210
217
  for k in range(n):
211
- kp = []
212
- for pose in init_poses:
213
- kp.append(pose)
214
- kp = np.mean(kp, axis=0)
215
- a = kp - position_bar[k]
218
+ a = mean_target - position_bar[k]
216
219
  # Determine the direction cosine matrix that aligns the z-axis of the sensor frame with the
217
220
  # relative position vector
218
221
  q_xyz = np.cross(b, a)
@@ -116,14 +116,13 @@ for center in gate_centers:
116
116
  ### End Gate Parameters ###
117
117
 
118
118
  n_subs = 10
119
- init_poses = []
120
119
  np.random.seed(5)
121
- for i in range(n_subs):
122
- init_pose = np.array([100.0, -70.0, 20.0])
123
- init_pose[:2] = init_pose[:2] + np.random.random(2) * 20.0
124
- init_poses.append(init_pose)
125
-
126
- init_poses = init_poses
120
+ init_poses = np.array(
121
+ [
122
+ [100.0 + np.random.random() * 20.0, -70.0 + np.random.random() * 20.0, 20.0]
123
+ for _ in range(n_subs)
124
+ ]
125
+ ) # Shape: (n_subs, 3)
127
126
 
128
127
 
129
128
  # Define list of all states (needed for Problem and constraints)
@@ -142,9 +141,16 @@ constraints = []
142
141
  for state in states:
143
142
  constraints.extend([ox.ctcs(state <= state.max), ox.ctcs(state.min <= state)])
144
143
 
145
- # Add visibility constraints using symbolic expressions
146
- for pose in init_poses:
147
- constraints.append((g_vp(pose, position, attitude) <= 0.0))
144
+ # Add visibility constraints using Vmap for parallel evaluation
145
+ # Single nodal constraint with vectorized evaluation over all target poses
146
+ visibility_constraint = (
147
+ ox.Vmap(
148
+ lambda pose: g_vp(pose, position, attitude),
149
+ batch=init_poses,
150
+ )
151
+ <= 0.0
152
+ )
153
+ constraints.append(visibility_constraint)
148
154
 
149
155
  # Add gate constraints using symbolic expressions
150
156
  for node, cen in zip(gate_nodes, A_gate_cen):
@@ -207,12 +213,9 @@ for _ in range(n_gates + 1):
207
213
  # Modify attitude to point sensor at targets
208
214
  R_sb = R_sb # Sensor to body frame
209
215
  b = R_sb @ np.array([0, 1, 0])
216
+ mean_target = np.mean(init_poses, axis=0) # Average target position
210
217
  for k in range(n):
211
- kp = []
212
- for pose in init_poses:
213
- kp.append(pose)
214
- kp = np.mean(kp, axis=0)
215
- a = kp - position_bar[k]
218
+ a = mean_target - position_bar[k]
216
219
  # Determine the direction cosine matrix that aligns the z-axis of the sensor frame with the
217
220
  # relative position vector
218
221
  q_xyz = np.cross(b, a)
@@ -111,10 +111,7 @@ polytope_point = np.array(
111
111
  [107.47, -50.00, 22.85],
112
112
  ]
113
113
  )
114
- init_poses = []
115
- for point in polytope_point:
116
- init_poses.append(point)
117
- init_poses = init_poses
114
+ init_poses = polytope_point # Shape: (20, 3)
118
115
  ### Gate Parameters ###
119
116
  n_gates = 10
120
117
  gate_centers = [
@@ -162,9 +159,16 @@ constraints = []
162
159
  for state in states:
163
160
  constraints.extend([ox.ctcs(state <= state.max), ox.ctcs(state.min <= state)])
164
161
 
165
- # Add visibility constraints for polytope points using symbolic expressions
166
- for pose in init_poses:
167
- constraints.append(ox.ctcs(g_vp(pose, position, attitude) <= 0.0))
162
+ # Add visibility constraints using Vmap for parallel evaluation
163
+ # Single CTCS constraint with vectorized evaluation over all polytope points
164
+ visibility_constraint = ox.ctcs(
165
+ ox.Vmap(
166
+ lambda pose: g_vp(pose, position, attitude),
167
+ batch=init_poses,
168
+ )
169
+ <= 0.0
170
+ )
171
+ constraints.append(visibility_constraint)
168
172
 
169
173
  # Add gate constraints using symbolic expressions
170
174
  for node, cen in zip(gate_nodes, A_gate_cen):
@@ -227,12 +231,9 @@ for _ in range(n_gates + 1):
227
231
  # Modify attitude to point sensor at targets
228
232
  R_sb = R_sb # Sensor to body frame
229
233
  b = R_sb @ np.array([0, 1, 0])
234
+ mean_target = np.mean(init_poses, axis=0) # Average target position
230
235
  for k in range(n):
231
- kp = []
232
- for pose in init_poses:
233
- kp.append(pose)
234
- kp = np.mean(kp, axis=0)
235
- a = kp - position_bar[k]
236
+ a = mean_target - position_bar[k]
236
237
  # Determine the direction cosine matrix that aligns the z-axis of the sensor frame with the
237
238
  # relative position vector
238
239
  q_xyz = np.cross(b, a)
@@ -0,0 +1,238 @@
1
+ """Double integrator obstacle avoidance with Vmap for parallel constraint evaluation.
2
+
3
+ This example demonstrates using ox.Vmap directly in constraints for data-parallel
4
+ obstacle avoidance with numerous spherical obstacles.
5
+
6
+ The approach:
7
+
8
+ 1. Stack all obstacle centers into a single array
9
+ 2. Use Vmap directly in the constraint to compute distances in parallel
10
+ 3. The vector-valued constraint is enforced element-wise
11
+
12
+ Compare with:
13
+ - obstacle_avoidance.py (manual loop over 3 obstacles)
14
+ """
15
+
16
+ import os
17
+ import sys
18
+
19
+ import numpy as np
20
+
21
+ # Add grandparent directory to path to import examples.plotting
22
+ current_dir = os.path.dirname(os.path.abspath(__file__))
23
+ grandparent_dir = os.path.dirname(os.path.dirname(current_dir))
24
+ sys.path.append(grandparent_dir)
25
+
26
+ import openscvx as ox
27
+ from examples.plotting_viser import (
28
+ create_animated_plotting_server,
29
+ create_scp_animated_plotting_server,
30
+ )
31
+ from openscvx import Problem
32
+
33
+ n = 6 # Number of nodes
34
+ total_time = 10.0 # Total time for the simulation
35
+
36
+ # =============================================================================
37
+ # State and Control Definitions
38
+ # =============================================================================
39
+
40
+ # 3D position
41
+ position = ox.State("position", shape=(3,))
42
+ position.max = np.array([15.0, 15.0, 15.0])
43
+ position.min = np.array([-15.0, -15.0, 0.0])
44
+ position.initial = np.array([-10.0, -10.0, 2.0])
45
+ position.final = np.array([10.0, 10.0, 2.0])
46
+
47
+ # 3D velocity
48
+ velocity = ox.State("velocity", shape=(3,))
49
+ velocity.max = np.array([10.0, 10.0, 10.0])
50
+ velocity.min = np.array([-10.0, -10.0, -10.0])
51
+ velocity.initial = np.array([0.0, 0.0, 0.0])
52
+ velocity.final = [("free", 0.0), ("free", 0.0), ("free", 0.0)]
53
+
54
+ # Control force
55
+ force = ox.Control("force", shape=(3,))
56
+ f_max = 20.0
57
+ force.max = np.array([f_max, f_max, f_max])
58
+ force.min = np.array([-f_max, -f_max, -f_max])
59
+
60
+ # Physical parameters
61
+ m = 1.0 # Mass
62
+ g = -9.81 # Gravity
63
+
64
+ # =============================================================================
65
+ # Obstacle Configuration (3D grid)
66
+ # =============================================================================
67
+
68
+ obstacle_radius_min, obstacle_radius_max = 1.0, 2.5
69
+
70
+ # Generate obstacle positions in a 3D grid pattern between start and goal
71
+ np.random.seed(42)
72
+ obstacle_centers = []
73
+
74
+ # Tweak number of obstacles by changing the grid sizes
75
+ n_rows = 4
76
+ n_cols = 4
77
+ n_lays = 4
78
+
79
+ # Create a 3D field of obstacles: rows (x) x columns (y) x layers (z)
80
+ for i in range(n_rows):
81
+ for j in range(n_cols):
82
+ for k in range(n_lays):
83
+ # Base grid position
84
+ x = -6.0 + i * 6.0
85
+ y = -7.5 + j * 5.0
86
+ z = 1.0 + k * 2.5 # Layers at z = 1.0, 3.5, 6.0
87
+ # Add some randomness
88
+ x += np.random.uniform(-1.0, 1.0)
89
+ y += np.random.uniform(-1.0, 1.0)
90
+ z += np.random.uniform(-0.5, 0.5)
91
+ obstacle_centers.append([x, y, z])
92
+
93
+ n_obstacles = len(obstacle_centers) # 36 obstacles
94
+
95
+ obstacle_centers = np.array(obstacle_centers) # Shape: (n_obstacles, 3)
96
+ obstacle_radii = np.random.uniform(obstacle_radius_min, obstacle_radius_max, size=n_obstacles)
97
+
98
+ print(f"Created {n_obstacles} obstacles")
99
+ print(f"Obstacle centers shape: {obstacle_centers.shape}")
100
+
101
+ # =============================================================================
102
+ # Dynamics (simple double integrator)
103
+ # =============================================================================
104
+
105
+ dynamics = {
106
+ "position": velocity,
107
+ "velocity": (1.0 / m) * force + np.array([0.0, 0.0, g]),
108
+ }
109
+
110
+ # =============================================================================
111
+ # Constraints
112
+ # =============================================================================
113
+
114
+ states = [position, velocity]
115
+ controls = [force]
116
+
117
+ constraints = []
118
+
119
+ # Box constraints on states
120
+ for state in states:
121
+ constraints.extend(
122
+ [
123
+ ox.ctcs(state <= state.max),
124
+ ox.ctcs(state.min <= state),
125
+ ]
126
+ )
127
+
128
+ # Box constraints on controls
129
+ constraints.extend(
130
+ [
131
+ force <= force.max,
132
+ force.min <= force,
133
+ ]
134
+ )
135
+
136
+ # =============================================================================
137
+ # Obstacle Avoidance
138
+ # =============================================================================
139
+ # Two approaches are shown below for benchmarking. Comment/uncomment to toggle.
140
+
141
+ # --- APPROACH 1: Vmap (single constraint, vectorized) ---
142
+ # - Single CTCS constraint with vectorized evaluation
143
+ # - Vmap computes distance to all obstacles in parallel
144
+
145
+ obstacle_avoidance = ox.ctcs(
146
+ obstacle_radii
147
+ <= ox.Vmap(
148
+ lambda obs_center: ox.linalg.Norm(position - obs_center),
149
+ batch=obstacle_centers,
150
+ )
151
+ )
152
+ constraints.append(obstacle_avoidance)
153
+
154
+ # --- APPROACH 2: Individual constraints (loop, no vmap) ---
155
+ # - Creates n_obstacles separate CTCS constraints
156
+ # - Each constraint is lowered and traced independently
157
+
158
+ # for i in range(n_obstacles):
159
+ # obs_center = obstacle_centers[i]
160
+ # radius = obstacle_radii[i]
161
+ # obstacle_constraint = ox.ctcs(
162
+ # radius <= ox.linalg.Norm(position - obs_center)
163
+ # )
164
+ # constraints.append(obstacle_constraint)
165
+
166
+ # =============================================================================
167
+ # Initial Guesses
168
+ # =============================================================================
169
+
170
+ straight_line = np.linspace(position.initial, position.final, n)
171
+ position.guess = straight_line
172
+ velocity.guess = np.zeros((n, 3))
173
+ force.guess = np.tile([0.0, 0.0, -m * g], (n, 1)) # Hover thrust
174
+
175
+ # =============================================================================
176
+ # Problem Setup
177
+ # =============================================================================
178
+
179
+ time = ox.Time(
180
+ initial=0.0,
181
+ final=("minimize", total_time),
182
+ min=0.0,
183
+ max=total_time,
184
+ )
185
+
186
+ problem = Problem(
187
+ dynamics=dynamics,
188
+ states=states,
189
+ controls=controls,
190
+ time=time,
191
+ constraints=constraints,
192
+ N=n,
193
+ )
194
+
195
+ # SCP settings
196
+ problem.settings.prp.dt = 0.01
197
+ problem.settings.scp.w_tr = 5e0
198
+ problem.settings.scp.lam_cost = 1e0
199
+ problem.settings.scp.lam_vc = 1e2
200
+ problem.settings.scp.ep_tr = 1e-3
201
+ problem.settings.scp.ep_vb = 1e-4
202
+ problem.settings.scp.ep_vc = 1e-8
203
+ problem.settings.scp.cost_drop = 5
204
+ problem.settings.scp.cost_relax = 0.7
205
+ problem.settings.scp.w_tr_adapt = 1.5
206
+
207
+ # =============================================================================
208
+ # Solve and Visualize
209
+ # =============================================================================
210
+
211
+ if __name__ == "__main__":
212
+ problem.initialize()
213
+ results = problem.solve()
214
+ results = problem.post_process()
215
+
216
+ # Store obstacle info for visualization
217
+ results.update(
218
+ {
219
+ "obstacles_centers": [c for c in obstacle_centers],
220
+ "obstacles_radii": [[1 / r, 1 / r, 1 / r] for r in obstacle_radii],
221
+ "obstacles_axes": [np.eye(3) for _ in range(n_obstacles)],
222
+ }
223
+ )
224
+
225
+ # Create viser visualization servers
226
+ traj_server = create_animated_plotting_server(
227
+ results,
228
+ thrust_key="force",
229
+ viewcone_scale=5.0,
230
+ )
231
+ scp_server = create_scp_animated_plotting_server(
232
+ results,
233
+ attitude_stride=3,
234
+ frame_duration_ms=200,
235
+ )
236
+
237
+ # Keep servers running
238
+ traj_server.sleep_forever()
@@ -58,6 +58,7 @@ def create_animated_plotting_server(
58
58
  target_radius: float = 1.0,
59
59
  show_control_plot: str | None = None,
60
60
  show_control_norm_plot: str | None = None,
61
+ show_grid: bool = True,
61
62
  ) -> viser.ViserServer:
62
63
  """Create an animated trajectory visualization server.
63
64
 
@@ -101,6 +102,7 @@ def create_animated_plotting_server(
101
102
  showing each control component vs time with animated markers
102
103
  show_control_norm_plot: If provided with a control name, displays norm plot
103
104
  showing ‖control‖₂ vs time with animated marker
105
+ show_grid: Whether to show the grid (default True)
104
106
 
105
107
  Returns:
106
108
  ViserServer instance (animation runs in background thread)
@@ -135,7 +137,7 @@ def create_animated_plotting_server(
135
137
  colors = compute_velocity_colors(vel)
136
138
 
137
139
  # Create server
138
- server = create_server(pos)
140
+ server = create_server(pos, show_grid=show_grid)
139
141
 
140
142
  # Add static elements
141
143
  if "vertices" in results:
@@ -257,6 +259,7 @@ def create_scp_animated_plotting_server(
257
259
  frame_duration_ms: int = 500,
258
260
  scene_scale: float = 1.0,
259
261
  cmap_name: str = "viridis",
262
+ show_grid: bool = True,
260
263
  ) -> viser.ViserServer:
261
264
  """Create an animated visualization of SCP iteration convergence.
262
265
 
@@ -289,6 +292,7 @@ def create_scp_animated_plotting_server(
289
292
  scene_scale: Divide all positions by this factor. Use >1 for large-scale
290
293
  trajectories (e.g., 100.0 for km-scale problems).
291
294
  cmap_name: Matplotlib colormap name for iteration coloring (default: "viridis")
295
+ show_grid: Whether to show the grid (default True)
292
296
 
293
297
  Returns:
294
298
  ViserServer instance (animation runs in background thread)
@@ -322,7 +326,7 @@ def create_scp_animated_plotting_server(
322
326
  attitudes = [X[:, attitude_slice] for X in X_history]
323
327
 
324
328
  # Create server using final iteration's positions for grid sizing
325
- server = create_server(positions[-1])
329
+ server = create_server(positions[-1], show_grid=show_grid)
326
330
 
327
331
  # Add static elements (gates, obstacles) if present
328
332
  if "vertices" in results:
@@ -0,0 +1,188 @@
1
+ """Proximity Operations (ProxOps) using Clohessy-Wiltshire dynamics.
2
+
3
+ This example demonstrates optimal trajectory generation for spacecraft
4
+ proximity operations and docking using the Clohessy-Wiltshire (CW) equations
5
+ for relative motion in a circular orbit.
6
+ See [Clohessy-Wiltshire equations](https://en.wikipedia.org/wiki/Clohessy%E2%80%93Wiltshire_equations)
7
+ for further details.
8
+ The problem includes:
9
+
10
+ - 3D relative position and velocity dynamics (CW equations)
11
+ - Fuel-optimal control (minimize delta-v)
12
+ - Thrust magnitude constraints
13
+ - Approach cone constraint for safe docking corridor
14
+ - Final docking at target (origin)
15
+
16
+ !!! tip "The CW frame convention:"
17
+ - x: radial direction (outward from Earth)
18
+ - y: along-track direction (velocity direction)
19
+ - z: cross-track direction (normal to orbit plane)
20
+ """
21
+
22
+ import os
23
+ import sys
24
+
25
+ import numpy as np
26
+
27
+ # Add grandparent directory to path to import examples.plotting
28
+ current_dir = os.path.dirname(os.path.abspath(__file__))
29
+ grandparent_dir = os.path.dirname(os.path.dirname(current_dir))
30
+ sys.path.append(grandparent_dir)
31
+
32
+ import openscvx as ox
33
+ from examples.plotting_viser import (
34
+ create_animated_plotting_server,
35
+ create_scp_animated_plotting_server,
36
+ )
37
+ from openscvx import Problem
38
+ from openscvx.plotting import plot_scp_iterations
39
+ from openscvx.plotting.viser import add_glideslope_cone
40
+
41
+ # Problem parameters
42
+ n_nodes = 5 # Number of discretization nodes
43
+ total_time = 180.0 # Total maneuver time in seconds
44
+
45
+ # Orbital parameters (ISS-like orbit at ~400 km altitude)
46
+ mu = 3.986004418e14 # Earth gravitational parameter [m^3/s^2]
47
+ a = 6.778e6 # Semi-major axis [m] (Earth radius + 400 km)
48
+ n = np.sqrt(mu / a**3) # Mean motion [rad/s] (~0.00113 rad/s)
49
+
50
+ # Define state components
51
+ # Position in CW frame [x, y, z] in meters
52
+ position = ox.State("position", shape=(3,))
53
+ position.max = np.array([100.0, 100.0, 100.0])
54
+ position.min = np.array([-100.0, -100.0, -100.0])
55
+ position.initial = np.array([0.0, -100.0, 0.0]) # Start 100m behind target (V-bar position)
56
+ position.final = np.array([0.0, 0.0, 0.0]) # Dock at origin
57
+ position.guess = np.linspace(position.initial, position.final, n_nodes)
58
+
59
+ # Velocity in CW frame [vx, vy, vz] in m/s
60
+ velocity = ox.State("velocity", shape=(3,))
61
+ v_max = 2.0 # Maximum relative velocity [m/s]
62
+ velocity.max = np.array([v_max, v_max, v_max])
63
+ velocity.min = np.array([-v_max, -v_max, -v_max])
64
+ velocity.initial = [0.0, 2.0, 0.0]
65
+ velocity.final = np.array([0.0, 0.0, 0.0]) # Zero relative velocity at docking
66
+ velocity.guess = np.zeros((n_nodes, 3))
67
+
68
+ # Define control: acceleration from thrusters [ax, ay, az] in m/s^2
69
+ accel = ox.Control("accel", shape=(3,))
70
+ a_max = 0.1 # Maximum acceleration [m/s^2] (typical for reaction control thrusters)
71
+ accel.max = np.array([a_max, a_max, a_max])
72
+ accel.min = np.array([-a_max, -a_max, -a_max])
73
+ accel.guess = np.zeros((n_nodes, 3))
74
+
75
+ # Define list of all states and controls
76
+ states = [position, velocity]
77
+ controls = [accel]
78
+
79
+ # Generate constraints
80
+ constraints = []
81
+
82
+ # Box constraints for states
83
+ for state in states:
84
+ constraints.extend(
85
+ [
86
+ ox.ctcs(state <= state.max),
87
+ ox.ctcs(state.min <= state),
88
+ ]
89
+ )
90
+
91
+ # R-bar approach cone constraint (from below, -x direction)
92
+ # Enforces sqrt(y^2 + z^2) <= tan(theta) * (-x)
93
+ # This requires the spacecraft to approach from negative x (below target)
94
+ # and stay within a cone centered on the -x axis
95
+ cone_half_angle = 20 * np.pi / 180 # 20 degree half-angle
96
+ constraints.append(
97
+ ox.ctcs(ox.linalg.Norm(position[1:]) <= np.tan(cone_half_angle) * (-position[0])).over(
98
+ (n_nodes - 3, n_nodes - 1)
99
+ )
100
+ )
101
+ # Enforce entrance to the cone at safe distance
102
+ constraints.append((-position[0] >= 20.0).at([n_nodes - 3]))
103
+
104
+ # Clohessy-Wiltshire dynamics
105
+ dynamics = {
106
+ "position": velocity,
107
+ "velocity": ox.Concat(
108
+ 3 * n**2 * position[0] + 2 * n * velocity[1] + accel[0],
109
+ -2 * n * velocity[0] + accel[1],
110
+ -(n**2) * position[2] + accel[2],
111
+ ),
112
+ }
113
+
114
+ # Time configuration (free final time to minimize fuel)
115
+ time = ox.Time(
116
+ initial=0.0,
117
+ final=("free", total_time),
118
+ min=0.0,
119
+ max=total_time,
120
+ )
121
+
122
+ # Build the problem
123
+ problem = Problem(
124
+ dynamics=dynamics,
125
+ states=states,
126
+ controls=controls,
127
+ time=time,
128
+ constraints=constraints,
129
+ N=n_nodes,
130
+ )
131
+
132
+ # Solver settings (FOH is default, no need to set explicitly)
133
+ problem.settings.dis.dis_type = "ZOH"
134
+ problem.settings.scp.k_max = 100
135
+ problem.settings.scp.w_tr = 1e0
136
+ problem.settings.scp.w_tr_adapt = 1.2
137
+ problem.settings.scp.lam_cost = 1e-1
138
+ problem.settings.scp.lam_vc = 1e1
139
+ problem.settings.scp.lam_vb = 1e0
140
+
141
+ # Plotting metadata
142
+ plotting_dict = {
143
+ "mean_motion": n,
144
+ }
145
+
146
+ if __name__ == "__main__":
147
+ problem.initialize()
148
+ results = problem.solve()
149
+ results = problem.post_process()
150
+ results.update(plotting_dict)
151
+
152
+ # Plot results
153
+ plot_scp_iterations(results).show()
154
+
155
+ # Create animation
156
+ traj_server = create_animated_plotting_server(results, thrust_key="accel", show_grid=False)
157
+
158
+ # Add R-bar approach cone (opens in -x direction)
159
+ add_glideslope_cone(
160
+ traj_server,
161
+ apex=(0, 0, 0),
162
+ height=20.0, # Cone extends 100m in -x direction
163
+ glideslope_angle_deg=cone_half_angle * 180 / np.pi,
164
+ axis=(-1, 0, 0), # R-bar: negative radial direction
165
+ color=(200, 80, 80),
166
+ opacity=0.5,
167
+ )
168
+
169
+ # Create SCP iteration visualization
170
+ scp_server = create_scp_animated_plotting_server(
171
+ results,
172
+ frame_duration_ms=200,
173
+ scene_scale=1.0,
174
+ show_grid=False,
175
+ )
176
+
177
+ # Add R-bar approach cone to SCP visualization
178
+ add_glideslope_cone(
179
+ scp_server,
180
+ apex=(0, 0, 0),
181
+ height=20.0,
182
+ glideslope_angle_deg=cone_half_angle * 180 / np.pi,
183
+ axis=(-1, 0, 0),
184
+ color=(200, 80, 80),
185
+ opacity=0.5,
186
+ )
187
+
188
+ scp_server.sleep_forever()
@@ -51,6 +51,7 @@ from openscvx.symbolic.expr import (
51
51
  Sum,
52
52
  Tan,
53
53
  Variable,
54
+ Vmap,
54
55
  Vstack,
55
56
  ctcs,
56
57
  )
@@ -113,6 +114,8 @@ __all__ = [
113
114
  "NodalConstraint",
114
115
  "CTCS",
115
116
  "ctcs",
117
+ # Data parallelism
118
+ "Vmap",
116
119
  # Submodules
117
120
  "stl",
118
121
  "spatial",
@@ -28,7 +28,7 @@ version_tuple: VERSION_TUPLE
28
28
  commit_id: COMMIT_ID
29
29
  __commit_id__: COMMIT_ID
30
30
 
31
- __version__ = version = '0.3.2.dev173'
32
- __version_tuple__ = version_tuple = (0, 3, 2, 'dev173')
31
+ __version__ = version = '0.3.2.dev195'
32
+ __version_tuple__ = version_tuple = (0, 3, 2, 'dev195')
33
33
 
34
- __commit_id__ = commit_id = 'g99c4b988b'
34
+ __commit_id__ = commit_id = 'ged5d19a8c'