python-motion-planning 2.0.dev1__py3-none-any.whl → 2.0.1__py3-none-any.whl

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 (60) hide show
  1. python_motion_planning/__init__.py +1 -1
  2. python_motion_planning/common/env/map/base_map.py +2 -8
  3. python_motion_planning/common/env/map/grid.py +456 -198
  4. python_motion_planning/common/utils/__init__.py +2 -1
  5. python_motion_planning/common/utils/child_tree.py +22 -0
  6. python_motion_planning/common/utils/geometry.py +18 -29
  7. python_motion_planning/common/visualizer/__init__.py +3 -1
  8. python_motion_planning/common/visualizer/base_visualizer.py +165 -0
  9. python_motion_planning/common/visualizer/{visualizer.py → visualizer_2d.py} +97 -220
  10. python_motion_planning/common/visualizer/visualizer_3d.py +242 -0
  11. python_motion_planning/controller/base_controller.py +37 -4
  12. python_motion_planning/controller/path_tracker/__init__.py +2 -1
  13. python_motion_planning/controller/path_tracker/apf.py +22 -23
  14. python_motion_planning/controller/path_tracker/dwa.py +14 -17
  15. python_motion_planning/controller/path_tracker/path_tracker.py +4 -1
  16. python_motion_planning/controller/path_tracker/pid.py +7 -1
  17. python_motion_planning/controller/path_tracker/pure_pursuit.py +7 -1
  18. python_motion_planning/controller/path_tracker/rpp.py +111 -0
  19. python_motion_planning/path_planner/__init__.py +2 -1
  20. python_motion_planning/path_planner/base_path_planner.py +45 -11
  21. python_motion_planning/path_planner/graph_search/__init__.py +4 -1
  22. python_motion_planning/path_planner/graph_search/a_star.py +12 -14
  23. python_motion_planning/path_planner/graph_search/dijkstra.py +15 -15
  24. python_motion_planning/path_planner/graph_search/gbfs.py +100 -0
  25. python_motion_planning/path_planner/graph_search/jps.py +199 -0
  26. python_motion_planning/path_planner/graph_search/lazy_theta_star.py +113 -0
  27. python_motion_planning/path_planner/graph_search/theta_star.py +17 -19
  28. python_motion_planning/path_planner/hybrid_search/__init__.py +1 -0
  29. python_motion_planning/path_planner/hybrid_search/voronoi_planner.py +204 -0
  30. python_motion_planning/path_planner/sample_search/__init__.py +2 -1
  31. python_motion_planning/path_planner/sample_search/rrt.py +73 -31
  32. python_motion_planning/path_planner/sample_search/rrt_connect.py +237 -0
  33. python_motion_planning/path_planner/sample_search/rrt_star.py +220 -150
  34. python_motion_planning/traj_optimizer/__init__.py +2 -0
  35. python_motion_planning/traj_optimizer/base_curve_generator.py +53 -0
  36. python_motion_planning/traj_optimizer/curve_generator/__init__.py +2 -0
  37. python_motion_planning/traj_optimizer/curve_generator/point_based/__init__.py +2 -0
  38. python_motion_planning/traj_optimizer/curve_generator/point_based/bspline.py +256 -0
  39. python_motion_planning/traj_optimizer/curve_generator/point_based/cubic_spline.py +115 -0
  40. python_motion_planning/traj_optimizer/curve_generator/pose_based/__init__.py +4 -0
  41. python_motion_planning/traj_optimizer/curve_generator/pose_based/bezier.py +121 -0
  42. python_motion_planning/traj_optimizer/curve_generator/pose_based/dubins.py +355 -0
  43. python_motion_planning/traj_optimizer/curve_generator/pose_based/polynomial.py +197 -0
  44. python_motion_planning/traj_optimizer/curve_generator/pose_based/reeds_shepp.py +606 -0
  45. {python_motion_planning-2.0.dev1.dist-info → python_motion_planning-2.0.1.dist-info}/METADATA +71 -29
  46. python_motion_planning-2.0.1.dist-info/RECORD +64 -0
  47. {python_motion_planning-2.0.dev1.dist-info → python_motion_planning-2.0.1.dist-info}/WHEEL +1 -1
  48. python_motion_planning/common/env/robot/tmp.py +0 -404
  49. python_motion_planning/curve_generator/__init__.py +0 -9
  50. python_motion_planning/curve_generator/bezier_curve.py +0 -131
  51. python_motion_planning/curve_generator/bspline_curve.py +0 -271
  52. python_motion_planning/curve_generator/cubic_spline.py +0 -128
  53. python_motion_planning/curve_generator/curve.py +0 -64
  54. python_motion_planning/curve_generator/dubins_curve.py +0 -348
  55. python_motion_planning/curve_generator/fem_pos_smooth.py +0 -114
  56. python_motion_planning/curve_generator/polynomial_curve.py +0 -226
  57. python_motion_planning/curve_generator/reeds_shepp.py +0 -736
  58. python_motion_planning-2.0.dev1.dist-info/RECORD +0 -53
  59. {python_motion_planning-2.0.dev1.dist-info → python_motion_planning-2.0.1.dist-info}/licenses/LICENSE +0 -0
  60. {python_motion_planning-2.0.dev1.dist-info → python_motion_planning-2.0.1.dist-info}/top_level.txt +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: python-motion-planning
3
- Version: 2.0.dev1
3
+ Version: 2.0.1
4
4
  Summary: Motion planning algorithms for Python
5
5
  Maintainer-email: Wu Maojia <omige@mail.nwpu.edu.cn>, Yang Haodong <913982779@qq.com>
6
6
  License: GNU GENERAL PUBLIC LICENSE
@@ -685,15 +685,21 @@ Requires-Python: >=3.6
685
685
  Description-Content-Type: text/markdown
686
686
  License-File: LICENSE
687
687
  Requires-Dist: numpy
688
+ Requires-Dist: numba
688
689
  Requires-Dist: scipy
689
690
  Requires-Dist: matplotlib
690
691
  Requires-Dist: osqp
691
692
  Requires-Dist: gymnasium
693
+ Requires-Dist: faiss-cpu
694
+ Requires-Dist: pyvista
695
+ Requires-Dist: pyvistaqt
692
696
  Dynamic: license-file
693
697
 
694
698
 
695
699
  # Introduction
696
700
 
701
+ `Python Motion Planning` repository provides the implementations of common `Motion planning` algorithms, including path planners on N-D grid, controllers for path-tracking, trajectory optimizers, a visualizer based on matplotlib and a toy physical simulator to test controllers.
702
+
697
703
  `Motion planning` plans the state sequence of the robot without conflict between the start and goal.
698
704
 
699
705
  `Motion planning` mainly includes `Path planning` and `Trajectory planning`.
@@ -705,7 +711,7 @@ The theory analysis can be found at [motion-planning](https://blog.csdn.net/frig
705
711
 
706
712
  We also provide [ROS C++](https://github.com/ai-winter/ros_motion_planning) version and [Matlab](https://github.com/ai-winter/matlab_motion_planning) version.
707
713
 
708
- This repository provides the implementations of common `Motion planning` algorithms. **Your stars and forks are welcome**. Submitting pull requests or joining our development team are also welcome. For trivial modification, please directly contribute to `dev` branch. For big modification, please [contact](#contact) us before you contribute.
714
+ **Your stars and forks are welcome!**
709
715
 
710
716
  # Quick Start
711
717
 
@@ -725,8 +731,10 @@ python_motion_planning
725
731
  | └─path_tracker
726
732
  ├─path_planner
727
733
  | ├─graph_search
728
- | └─sample_search
729
- └─curve_generation
734
+ | ├─sample_search
735
+ | └─hybrid_search
736
+ └─traj_optimizer
737
+ └─curve_generator
730
738
  ```
731
739
 
732
740
  ## Install
@@ -740,7 +748,7 @@ conda activate pmp
740
748
  To install the repository, please run the following command in shell.
741
749
 
742
750
  ```shell
743
- pip install python-motion-planning==2.0.dev1
751
+ pip install python-motion-planning
744
752
  ```
745
753
 
746
754
  ## Run
@@ -749,29 +757,40 @@ Please refer to the Tutorials part of [online documentation](https://ai-winter.g
749
757
 
750
758
  # Demos
751
759
  ## Path Planner
752
-
760
+ ### Graph Search
753
761
  |Planner|2D Grid|3D Grid
754
762
  |-------|-------|-------
755
- **GBFS**|Implemented in [V1.1.1](https://github.com/ai-winter/python_motion_planning/tree/v1.1.1), not migrated|Not implemented
756
- **Dijkstra**|![dijkstra_2d.svg](assets/dijkstra_2d.svg)|![dijkstra_3d.svg](assets/dijkstra_3d.svg)
757
- **A\***|![a_star_2d.svg](assets/a_star_2d.svg)|![a_star_3d.svg](assets/a_star_3d.svg)
758
- **JPS**|Implemented in [V1.1.1](https://github.com/ai-winter/python_motion_planning/tree/v1.1.1), not migrated|Not implemented
763
+ **Dijkstra**|![dijkstra_2d.svg](assets/dijkstra_2d.svg)|![dijkstra_3d.png](assets/dijkstra_3d.png)
764
+ **GBFS**|![gbfs_2d.svg](assets/gbfs_2d.svg)|![gbfs_3d.png](assets/gbfs_3d.png)
765
+ **A\***|![a_star_2d.svg](assets/a_star_2d.svg)|![a_star_3d.png](assets/a_star_3d.png)
766
+ **JPS**|![jps_2d.svg](assets/jps_2d.svg)|![jps_3d.png](assets/jps_3d.png)
767
+ **Theta\***|![theta_star_2d.svg](assets/theta_star_2d.svg)|![theta_star_3d.png](assets/theta_star_3d.png)
768
+ **Lazy Theta\***|![lazy_theta_star_2d.svg](assets/lazy_theta_star_2d.svg)|![lazy_theta_star_3d.png](assets/lazy_theta_star_3d.png)
759
769
  **D\***|Implemented in [V1.1.1](https://github.com/ai-winter/python_motion_planning/tree/v1.1.1), not migrated|Not implemented
760
770
  **LPA\***|Implemented in [V1.1.1](https://github.com/ai-winter/python_motion_planning/tree/v1.1.1), not migrated|Not implemented
761
771
  **D\* Lite**|Implemented in [V1.1.1](https://github.com/ai-winter/python_motion_planning/tree/v1.1.1), not migrated|Not implemented
762
- **Theta\***|![theta_star_2d.svg](assets/theta_star_2d.svg)|![theta_star_3d.svg](assets/theta_star_3d.svg)
763
- **Lazy Theta\***|Implemented in [V1.1.1](https://github.com/ai-winter/python_motion_planning/tree/v1.1.1), not migrated|Not implemented
764
- **S-Theta\***|Implemented in [V1.1.1](https://github.com/ai-winter/python_motion_planning/tree/v1.1.1), not migrated|Not implemented
765
772
  **Anya**|Not implemented|Not implemented
766
- **Voronoi**|Implemented in [V1.1.1](https://github.com/ai-winter/python_motion_planning/tree/v1.1.1), not migrated|Not implemented
767
- **RRT**|![rrt_2d.svg](assets/rrt_2d.svg)|![rrt_3d.svg](assets/rrt_3d.svg)
768
- **RRT\***|![rrt_star_2d.svg](assets/rrt_star_2d.svg)|![rrt_star_3d.svg](assets/rrt_star_3d.svg)
773
+
774
+ ### Sample Search
775
+ |Planner|2D Grid|3D Grid
776
+ |-------|-------|-------
777
+ **RRT**|![rrt_2d.svg](assets/rrt_2d.svg)|![rrt_3d.png](assets/rrt_3d.png)
778
+ **RRT\***|![rrt_star_2d.svg](assets/rrt_star_2d.svg)|![rrt_star_3d.png](assets/rrt_star_3d.png)
779
+ **RRT-Connect**|![rrt_connect_2d.svg](assets/rrt_connect_2d.svg)|![rrt_connect_3d.png](assets/rrt_connect_3d.png)
769
780
  **Informed RRT**|Implemented in [V1.1.1](https://github.com/ai-winter/python_motion_planning/tree/v1.1.1), not migrated|Not implemented
770
- **RRT-Connect**|Implemented in [V1.1.1](https://github.com/ai-winter/python_motion_planning/tree/v1.1.1), not migrated|Not implemented
781
+ **PRM**|Not implemented|Not implemented
782
+
783
+ ### Evolutionary Search
784
+ |Planner|2D Grid|3D Grid
785
+ |-------|-------|-------
771
786
  | **ACO** |Implemented in [V1.1.1](https://github.com/ai-winter/python_motion_planning/tree/v1.1.1), not migrated|Not implemented
772
787
  | **GA** |Implemented in [V1.1.1](https://github.com/ai-winter/python_motion_planning/tree/v1.1.1), not migrated|Not implemented
773
788
  | **PSO** |Implemented in [V1.1.1](https://github.com/ai-winter/python_motion_planning/tree/v1.1.1), not migrated|Not implemented
774
789
 
790
+ ### Hybrid Search
791
+ |Planner|2D Grid|3D Grid
792
+ |-------|-------|-------
793
+ **Voronoi Planner**|![voronoi_planner_2d.svg](assets/voronoi_planner_2d.svg)|![voronoi_planner_3d.png](assets/voronoi_planner_3d.png)
775
794
 
776
795
  ## Controller
777
796
 
@@ -779,14 +798,14 @@ We provide a toy simulator with simple physical simulation to test controllers (
779
798
 
780
799
  In the following demos, the blue robot 1 is the `CircularRobot`, and the orange robot 2 is the `DiffDriveRobot`.
781
800
 
782
- |Planner|2D|3D
801
+ |Controller|2D|3D
783
802
  |-------|-------|-------
784
803
  |**Path Trakcer**|![path_tracker_2d.gif](assets/path_tracker_2d.gif)|Not implemented
785
804
  | **Pure Pursuit** |![pure_pursuit_2d.gif](assets/pure_pursuit_2d.gif)|Not implemented
786
805
  | **PID** |![pid_2d.gif](assets/pid_2d.gif)|Not implemented
787
806
  | **APF** |![apf_2d.gif](assets/apf_2d.gif)|Not implemented
788
807
  | **DWA** |![dwa_2d.gif](assets/dwa_2d.gif)|Not implemented
789
- | **RPP** |Implemented in [V1.1.1](https://github.com/ai-winter/python_motion_planning/tree/v1.1.1), not migrated|Not implemented
808
+ | **RPP** |![rpp_2d.gif](assets/rpp_2d.gif)|Not implemented
790
809
  | **LQR** |Implemented in [V1.1.1](https://github.com/ai-winter/python_motion_planning/tree/v1.1.1), not migrated|Not implemented
791
810
  | **MPC** |Implemented in [V1.1.1](https://github.com/ai-winter/python_motion_planning/tree/v1.1.1), not migrated|Not implemented
792
811
  | **MPPI** |Not implemented|Not implemented
@@ -795,19 +814,42 @@ In the following demos, the blue robot 1 is the `CircularRobot`, and the orange
795
814
  | **DQN** |Not implemented|Not implemented
796
815
  | **DDPG** |Implemented in [V1.0](https://github.com/ai-winter/python_motion_planning/tree/v1.0), not migrated|Not implemented
797
816
 
798
- ## Curve Generator
817
+ ## Trajectory Optimizer
818
+ ### Curve Generator
819
+ #### Point-based
799
820
 
800
- The visualization of the curve generators has not been implemented in current version. They can be visualized in [V1.1.1](https://github.com/ai-winter/python_motion_planning/tree/v1.1.1).
821
+ |Generator|2D|3D|
822
+ | ------- | -------------------------------------------------------- | --------------------------------------------------------
823
+ | **Cubic Spline** |![cubic_spline_2d.svg](assets/cubic_spline_2d.svg)|Not implemented
824
+ | **BSpline** |![bspline_2d.svg](assets/bspline_2d.svg)|Not implemented
801
825
 
802
- | Planner |2D|3D|
826
+ #### Pose-based
827
+ |Generator|2D|3D|
803
828
  | ------- | -------------------------------------------------------- | --------------------------------------------------------
804
- | **Polynomia** | ![polynomial_curve_python.gif](assets/polynomial_curve_python.gif)|Not implemented
805
- | **Bezier** |![bezier_curve_python.png](assets/bezier_curve_python.png)|Not implemented
806
- | **Cubic Spline** |![cubic_spline_python.png](assets/cubic_spline_python.png)|Not implemented
807
- | **BSpline** |![bspline_curve_python.png](assets/bspline_curve_python.png)|Not implemented
808
- | **Dubins** |![dubins_curve_python.png](assets/dubins_curve_python.png)|Not implemented
809
- | **Reeds-Shepp** |![reeds_shepp_python.png](assets/reeds_shepp_python.gif)|Not implemented
810
- | **Fem-Pos Smoother** |![fem_pos_smoother_python.png](assets/fem_pos_smoother_python.png)|Not implemented
829
+ | **Polynomia** | ![polynomial_2d.svg](assets/polynomial_2d.svg)|Not implemented
830
+ | **Bezier** |![bezier_2d.svg](assets/bezier_2d.svg)|Not implemented
831
+ | **Dubins** |![dubins_2d.svg](assets/dubins_2d.svg)|Not implemented
832
+ | **Reeds-Shepp** |![reeds_shepp_2d.svg](assets/reeds_shepp_2d.svg)|Not implemented
833
+
834
+ # Future Works
835
+
836
+ * N-D controllers (path-trackers).
837
+
838
+ * Path planning for robotic arms.
839
+
840
+ * Path planning on topological map.
841
+
842
+ * Sample search with Dubins or Reeds-Shepp curves.
843
+
844
+ * Application on ROS2.
845
+
846
+ * Application in mainstream robot simulation environments (e.g. Gazebo, Carla, Airsim, PyBullet, MuJoCo, Issac Sim).
847
+
848
+ * More mainstream motion planning algorithms.
849
+
850
+ * Performance optimization.
851
+
852
+ Contributors are welcome! For trivial modification, please directly contribute to `dev` branch. For big modification, please [contact](#contact) us before you contribute.
811
853
 
812
854
  # Contact
813
855
 
@@ -0,0 +1,64 @@
1
+ python_motion_planning/__init__.py,sha256=qsRVlO3n-WSdeyH6NvduCQJ_G0Yqrml7F_juvs2UnJ4,108
2
+ python_motion_planning/common/__init__.py,sha256=9CeruPgGOBOtro9EafPEhK5VKTav2OWeNbMLJCBwuNg,67
3
+ python_motion_planning/common/env/__init__.py,sha256=Q8qIUcn5fvtLrmrc3SXStQoEwwrNMF-IofKotFermBk,129
4
+ python_motion_planning/common/env/node.py,sha256=6I10JpU4tjK4aZEMWN7Dttz41QKskNFoe7gBR4aSyII,2727
5
+ python_motion_planning/common/env/types.py,sha256=h5HtPrffu5qH_F1G4V1g8eXBPTPuDW-nFFfEFECVGYo,380
6
+ python_motion_planning/common/env/map/__init__.py,sha256=5bVsJd2mrghKMj7erXfgc8V4NahXHe6zXngG9fMCjo0,44
7
+ python_motion_planning/common/env/map/base_map.py,sha256=tX-9iO3RwbdvhGUHDtPNQUj8h-HNONjopXCLyUdtfQE,3321
8
+ python_motion_planning/common/env/map/grid.py,sha256=-QDhKpKrjE4Hi-NZPWIgPiiZagJCZH_dw8QgpHgLor4,28441
9
+ python_motion_planning/common/env/robot/__init__.py,sha256=njq1_k2uWikGH2AjtxoFDdmxqsM1YY5B9nVtIheyx6Y,122
10
+ python_motion_planning/common/env/robot/base_robot.py,sha256=KEajU9iFCnrzDOFp3Vm3SMWJWQgGJAYLT4VB6IMX2Is,7913
11
+ python_motion_planning/common/env/robot/circular_robot.py,sha256=6SS3XP91WfQlccxbtyVLjmPQjgesP9cFaxXg6txkxVI,1512
12
+ python_motion_planning/common/env/robot/diff_drive_robot.py,sha256=bJgaa7sheCb62ee891vEV3KigeX4nUOtec0iw2F7Syw,4389
13
+ python_motion_planning/common/env/world/__init__.py,sha256=nC9YDBuO-8FapouUCe_relatAferP_gcgPkVQ3QCVNA,39
14
+ python_motion_planning/common/env/world/base_world.py,sha256=FSf9PQAFY6CFgCSGK8TNdGDR8_GrIEtBW8CA83jWtEo,4131
15
+ python_motion_planning/common/env/world/toy_simulator.py,sha256=J2JrZhQD-lCd4TB2X6O_wyX_NR_rIz3UjSzPrjyINEQ,9730
16
+ python_motion_planning/common/utils/__init__.py,sha256=wYzKTiyKgYfl5cTO0pUHF1zkr8Q9VhhEwKcRy1xSSdM,114
17
+ python_motion_planning/common/utils/child_tree.py,sha256=f6ypaZ-d7mJpWOaVH99KriJuzjDc6q353USsO7D5F9g,625
18
+ python_motion_planning/common/utils/frame_transformer.py,sha256=D9xaOUcxCPLvTl9oJHRSuhue84i88nMiuI-3ns0i7Ao,7609
19
+ python_motion_planning/common/utils/geometry.py,sha256=FFYM_eVAgJ3wA7H8MRXNvwXliGd6dKo4WU8fzbwdCXE,2693
20
+ python_motion_planning/common/visualizer/__init__.py,sha256=HWWbLehtqEl0q_hEO28tEMDH-v8lXqduN-EJ7mo9LEI,90
21
+ python_motion_planning/common/visualizer/base_visualizer.py,sha256=sjkH8lbyW8q9BVIEaQBTF10M27d73cpQqdTAPbEBFD0,5518
22
+ python_motion_planning/common/visualizer/visualizer_2d.py,sha256=mqaKFZEtNHOCm82I1nCbCOhDP444JSySq1BzQCnPyEM,15656
23
+ python_motion_planning/common/visualizer/visualizer_3d.py,sha256=4LklgQv9Wu7UT8hmJMLiGau_8GzrGcJpQ4Xj40m1rTA,7645
24
+ python_motion_planning/controller/__init__.py,sha256=UGFx5oND_pyovs1LIZ2HYU8Toxo0QnkTSnqKITfX28M,121
25
+ python_motion_planning/controller/base_controller.py,sha256=bSeCXHM10KosvZmGhjHyUOoC-BvxdDWW_Q2IeyGJ-yQ,6890
26
+ python_motion_planning/controller/random_controller.py,sha256=al9Az3K4K8HlfQ-BQNcoS-1T6O2v1-juu8Fw5lL3dEE,693
27
+ python_motion_planning/controller/path_tracker/__init__.py,sha256=1giXD5W8aXdTc1H_DO9P0MK8JjC6Jb_tsnrT3Gz4JDM,164
28
+ python_motion_planning/controller/path_tracker/apf.py,sha256=wV_OiPua5djMwP_i8eZP0FX8e3Y_kov-HsMOmbRGtFE,9531
29
+ python_motion_planning/controller/path_tracker/dwa.py,sha256=EyjXdU_lw_hIN6lucfaokxx8C1OxPCLk13zmcy7KLR8,9495
30
+ python_motion_planning/controller/path_tracker/path_tracker.py,sha256=5p_MhqRWpMGEsdek0IqcohmXCMTlStUrMwSoJKX14zw,9359
31
+ python_motion_planning/controller/path_tracker/pid.py,sha256=pqZggmTWaNd7XrlqfaK4wtBk9syg8PnIC7vOEnfN9S8,2403
32
+ python_motion_planning/controller/path_tracker/pure_pursuit.py,sha256=gsfiMXZx3RwHIwmI2CSu4fTZNFKbZP31cXMgKUdDjs8,2405
33
+ python_motion_planning/controller/path_tracker/rpp.py,sha256=e7qRIaUfeiVfVoiY5k797Yk9RK-Q7gnegmaOB7_BVP4,4181
34
+ python_motion_planning/path_planner/__init__.py,sha256=Y0Im0cJ3iuUOYJyAOYvA_IavaNTNowb7SE6atrdJqX0,121
35
+ python_motion_planning/path_planner/base_path_planner.py,sha256=YZcLqAIkLJtp5MWoT5zPmzxv05xUlnDpfuzN-CgPQuc,3640
36
+ python_motion_planning/path_planner/graph_search/__init__.py,sha256=ugZpHV12dY-yb8d1jx4NepdRzQKn2qNKS6yWEBlvWy0,146
37
+ python_motion_planning/path_planner/graph_search/a_star.py,sha256=s_PLSsF53xcvVM5DOnFDCW5Enp4TrkL1keuPuKWIEEA,2989
38
+ python_motion_planning/path_planner/graph_search/dijkstra.py,sha256=Z3f2KuR2dQ2VAc1jcScD9Qo05qFVUULHhSz58QlHQEk,3169
39
+ python_motion_planning/path_planner/graph_search/gbfs.py,sha256=S9MSwjNavvSiau5sQJRum-Nq0GYInFa6SmfzJfWdxNw,3261
40
+ python_motion_planning/path_planner/graph_search/jps.py,sha256=AOfGLBmSS1HMX_XjvpQKGLH3-e80MwzLGKG0_afXWrE,7657
41
+ python_motion_planning/path_planner/graph_search/lazy_theta_star.py,sha256=Gyu8F16lEqaqfZteRwYeu1UkhWQRnWL0wSJbM7H1oWw,3965
42
+ python_motion_planning/path_planner/graph_search/theta_star.py,sha256=JxxWukRTI4aZWF9pppzpsjqwRh6A6gvfB5YLZIk45w0,3846
43
+ python_motion_planning/path_planner/hybrid_search/__init__.py,sha256=RCvNhSq6nskZPCc7jo9Y5MOzrD4f7TL9RfVUCHgpeq4,30
44
+ python_motion_planning/path_planner/hybrid_search/voronoi_planner.py,sha256=sDTE-IFMf2035mUIRulEIOF0NiZSrwhW_bWrCiPetu4,7897
45
+ python_motion_planning/path_planner/sample_search/__init__.py,sha256=RYz6o_xmdsoErMGdBKvXEK4w-48P_ogi1bJsdJmUupk,71
46
+ python_motion_planning/path_planner/sample_search/rrt.py,sha256=hFBN1RaAnBn_ap7V2IPdkkKJIaMEIc7bHGALxoMkV-I,8682
47
+ python_motion_planning/path_planner/sample_search/rrt_connect.py,sha256=2GYQS5InB-jWr74c_dDGnLLCkIIeLnIrJmgfBfNNtOw,9670
48
+ python_motion_planning/path_planner/sample_search/rrt_star.py,sha256=f32G0h3_ds0cWvukNDRtDUoLZy0_KYpALcqCQcTxP1w,11223
49
+ python_motion_planning/traj_optimizer/__init__.py,sha256=0HeRril2pkNw1uUdro2HuV5z3eouQaC-kh6_uHOTzZg,69
50
+ python_motion_planning/traj_optimizer/base_curve_generator.py,sha256=m7-EZOIH5lOFiMVyvh5LYemjnWsiw0yRAvYUWG5mIFQ,1619
51
+ python_motion_planning/traj_optimizer/curve_generator/__init__.py,sha256=q40AJi09Wgv84NEU7fkdcSdNIGwoKy42Bsnt7YHaOdY,55
52
+ python_motion_planning/traj_optimizer/curve_generator/point_based/__init__.py,sha256=3V3ddQ0RfWs9oS57MUioGqzmMhPEXdVxbHkL9t_KlSM,53
53
+ python_motion_planning/traj_optimizer/curve_generator/point_based/bspline.py,sha256=GRcRHCC56Kdm74LFv96ANzHdaBxihTCfL-sk87rD3h8,9110
54
+ python_motion_planning/traj_optimizer/curve_generator/point_based/cubic_spline.py,sha256=sArmL1kLKHc-NRLFtczwpO6ATmuI3SB_FHTgSk826wI,3962
55
+ python_motion_planning/traj_optimizer/curve_generator/pose_based/__init__.py,sha256=muLe-_uENMf_btwqmVsRP0Ikbryut3Wl0_0BxNRhhbU,101
56
+ python_motion_planning/traj_optimizer/curve_generator/pose_based/bezier.py,sha256=BuLp6MzbyhuElD4qnos_nQQi9HvRVxx2AI5xPuUf2_I,4405
57
+ python_motion_planning/traj_optimizer/curve_generator/pose_based/dubins.py,sha256=76ujAOJHl3o4HkV1e5wuZEyz9wxzaGkDizDUx3M9C0w,13895
58
+ python_motion_planning/traj_optimizer/curve_generator/pose_based/polynomial.py,sha256=kjDkVskkfFHERZdJx6GU_GrRTJmrGHuX383W2s1oECI,7381
59
+ python_motion_planning/traj_optimizer/curve_generator/pose_based/reeds_shepp.py,sha256=I6KjYZvG4lOE2N9_vp1hSzJuan4SOrpuQF2L57owII4,22970
60
+ python_motion_planning-2.0.1.dist-info/licenses/LICENSE,sha256=a4N8el8H0UrdAJzCeVgj9HklpT3VkZfsy4aL1SAifJE,35793
61
+ python_motion_planning-2.0.1.dist-info/METADATA,sha256=61r3x6QoQCBJIHm1yt10khJLLdTw5P7zEXHZGkZwr7Y,49587
62
+ python_motion_planning-2.0.1.dist-info/WHEEL,sha256=aeYiig01lYGDzBgS8HxWXOg3uV61G9ijOsup-k9o1sk,91
63
+ python_motion_planning-2.0.1.dist-info/top_level.txt,sha256=VtZTYZios8VncYIkec7tOVdYqj5oMRmoeBb9RcJHluY,23
64
+ python_motion_planning-2.0.1.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: setuptools (80.9.0)
2
+ Generator: setuptools (82.0.1)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5
 
@@ -1,404 +0,0 @@
1
- """
2
- multiagent_nav.py
3
-
4
- 依赖: gymnasium, numpy, matplotlib
5
-
6
- 保存并运行后,可通过 demo_2d() / demo_3d() 运行演示。
7
- """
8
-
9
- from typing import List, Dict, Tuple, Optional
10
- import numpy as np
11
- import gymnasium as gym
12
- from gymnasium import spaces
13
- import math
14
- import matplotlib.pyplot as plt
15
- from matplotlib import animation
16
- from mpl_toolkits.mplot3d import Axes3D # noqa: F401
17
-
18
- # ---------------------------
19
- # Base classes: Agent / Controller / Environment
20
- # ---------------------------
21
-
22
- class BaseAgent:
23
- """
24
- Agent 基类:只包含物理参数和状态容器,负责定义观测格式。
25
- - dim: 空间维度(N)
26
- - mass: 质量
27
- - radius: 形状半径(用于碰撞)
28
- - pos, vel: 当前状态(numpy arrays)
29
- - acc: 当前瞬时加速度(set by controller before env.step 使用)
30
- """
31
- def __init__(self, dim: int = 2, mass: float = 1.0, radius: float = 0.1,
32
- pos: Optional[np.ndarray] = None, vel: Optional[np.ndarray] = None,
33
- action_min: Optional[np.ndarray] = None, action_max: Optional[np.ndarray] = None):
34
- self.dim = dim
35
- self.mass = float(mass)
36
- self.radius = float(radius)
37
- self.pos = np.zeros(dim) if pos is None else np.array(pos, dtype=float)
38
- self.vel = np.zeros(dim) if vel is None else np.array(vel, dtype=float)
39
- # acceleration is set externally by controller each step
40
- self.acc = np.zeros(dim)
41
- # action bounds per-dim (controller output bounds)
42
- if action_min is None:
43
- action_min = -np.ones(dim) * 1.0
44
- if action_max is None:
45
- action_max = np.ones(dim) * 1.0
46
- self.action_min = np.array(action_min, dtype=float)
47
- self.action_max = np.array(action_max, dtype=float)
48
-
49
- def observation_size(self, env) -> int:
50
- """
51
- 默认观测:自身 pos, vel (2*dim) + 所有其他 agent 的相对位置 ( (n-1)*dim )
52
- 你可以重载该函数改变观测结构。
53
- """
54
- n_agents = len(env.agents)
55
- return 2 * self.dim + (n_agents - 1) * self.dim
56
-
57
- def get_observation(self, env) -> np.ndarray:
58
- """
59
- 返回观测向量(1D numpy array)。
60
- 默认格式: [pos, vel, rel_pos_agent1, rel_pos_agent2, ...]
61
- 相对位置按照 env.agents 列表顺序(跳过 self)。
62
- """
63
- obs = []
64
- obs.extend(self.pos.tolist())
65
- obs.extend(self.vel.tolist())
66
- for a in env.agents:
67
- if a is self:
68
- continue
69
- rel = (a.pos - self.pos)
70
- obs.extend(rel.tolist())
71
- return np.array(obs, dtype=float)
72
-
73
- def clip_action(self, a: np.ndarray) -> np.ndarray:
74
- return np.minimum(np.maximum(a, self.action_min), self.action_max)
75
-
76
-
77
- class SimpleAgent(BaseAgent):
78
- """一个简单的圆/球体 agent(继承 BaseAgent)。"""
79
- pass
80
-
81
-
82
- class BaseController:
83
- """
84
- Controller 基类(与环境解耦)
85
- - 控制器只知道:observation_space, action_space(由 agent 定义)
86
- - get_action(obs) -> acceleration vector (dim,)
87
- """
88
- def __init__(self, observation_space: spaces.Space, action_space: spaces.Box):
89
- self.observation_space = observation_space
90
- self.action_space = action_space
91
-
92
- def reset(self):
93
- """可选:用于在每个 episode 开始时清理内部状态。"""
94
- pass
95
-
96
- def get_action(self, obs: np.ndarray) -> np.ndarray:
97
- """子类必须实现:返回与 action_space.shape 匹配的 ndarray(加速度)"""
98
- raise NotImplementedError
99
-
100
-
101
- class RandomController(BaseController):
102
- """默认随机控制器:在 action_space 内均匀采样。"""
103
- def get_action(self, obs: np.ndarray) -> np.ndarray:
104
- return self.action_space.sample()
105
-
106
-
107
- # ---------------------------
108
- # Environment
109
- # ---------------------------
110
-
111
- class MultiAgentNavEnv(gym.Env):
112
- """
113
- 多智能体导航环境(可 N 维)
114
- - agents: list of BaseAgent 的实例
115
- - bounds: environment boundary as (min_vec, max_vec) each of length dim
116
- - dt: 时间步长
117
- - friction: 线性阻尼系数(v * (-friction) force),模型里转成加速度影响
118
- - restitution: 边界/碰撞弹性系数 [0,1]
119
- - max_episode_steps: 可选终止步数
120
- """
121
- metadata = {"render.modes": ["human"]}
122
-
123
- def __init__(self, dim: int = 2,
124
- bounds: Tuple[np.ndarray, np.ndarray] = None,
125
- dt: float = 0.05,
126
- friction: float = 0.1,
127
- restitution: float = 0.9,
128
- max_episode_steps: int = 1000):
129
- super().__init__()
130
- self.dim = dim
131
- if bounds is None:
132
- lo = -np.ones(dim) * 5.0
133
- hi = np.ones(dim) * 5.0
134
- bounds = (lo, hi)
135
- self.bounds = (np.array(bounds[0], dtype=float), np.array(bounds[1], dtype=float))
136
- self.dt = float(dt)
137
- self.friction = float(friction)
138
- self.restitution = float(restitution)
139
- self.max_episode_steps = int(max_episode_steps)
140
-
141
- self.agents: List[BaseAgent] = []
142
- self.step_count = 0
143
- # observation_space and action_space are per-agent; environment doesn't expose global spaces
144
- # 但为了兼容 gym,提供 a dummy space
145
- self.observation_space = spaces.Box(-np.inf, np.inf, shape=(1,), dtype=float)
146
- self.action_space = spaces.Box(-np.inf, np.inf, shape=(1,), dtype=float)
147
-
148
- def add_agent(self, agent: BaseAgent):
149
- if agent.dim != self.dim:
150
- raise ValueError("Agent dimension must match environment dimension")
151
- self.agents.append(agent)
152
-
153
- def reset(self, seed: Optional[int] = None):
154
- self.step_count = 0
155
- # optionally randomize initial states or rely on agents' initial pos/vel
156
- # 返回 dict of observations keyed by agent index
157
- obs = {}
158
- for i, a in enumerate(self.agents):
159
- obs[i] = a.get_observation(self)
160
- return obs, {}
161
-
162
- def step(self, actions: Dict[int, np.ndarray]):
163
- """
164
- actions: dict mapping agent_index -> acceleration ndarray (dim,)
165
- 1) clip to agent action bounds
166
- 2) apply environment forces (friction) and integrate via semi-implicit Euler
167
- 3) handle collisions (agent-agent, agent-boundary)
168
- 返回:obs_dict, reward_dict, done_dict, info
169
- """
170
- self.step_count += 1
171
- # 1. assign actions (accelerations) to agents
172
- for i, a in enumerate(self.agents):
173
- act = actions.get(i, np.zeros(self.dim))
174
- a.acc = a.clip_action(np.array(act, dtype=float))
175
-
176
- # 2. apply environment forces -> compute net acceleration: a_net = a.acc + a_env (friction)
177
- for a in self.agents:
178
- # friction as linear damping: a_fric = -friction * v / mass
179
- a_env_acc = - self.friction * a.vel / (a.mass + 1e-12)
180
- a_net = a.acc + a_env_acc
181
- # semi-implicit Euler: v += a_net*dt, pos += v*dt
182
- a.vel = a.vel + a_net * self.dt
183
- a.pos = a.pos + a.vel * self.dt
184
-
185
- # 3. collisions: pairwise agent-agent elastic collisions (simple impulse) and boundary collisions
186
- self._resolve_agent_collisions()
187
- self._resolve_boundary_collisions()
188
-
189
- obs = {i: a.get_observation(self) for i, a in enumerate(self.agents)}
190
- # no rewards by default; you can extend
191
- rewards = {i: 0.0 for i in range(len(self.agents))}
192
- dones = {i: False for i in range(len(self.agents))}
193
- terminated = False
194
- truncated = self.step_count >= self.max_episode_steps
195
- info = {}
196
- return obs, rewards, dones, {"terminated": terminated, "truncated": truncated, **info}
197
-
198
- def _resolve_agent_collisions(self):
199
- n = len(self.agents)
200
- for i in range(n):
201
- for j in range(i + 1, n):
202
- a = self.agents[i]
203
- b = self.agents[j]
204
- delta = b.pos - a.pos
205
- dist = np.linalg.norm(delta)
206
- min_dist = a.radius + b.radius
207
- if dist < 1e-8:
208
- # numeric edge-case: jitter them slightly
209
- delta = np.random.randn(self.dim) * 1e-6
210
- dist = np.linalg.norm(delta)
211
- if dist < min_dist:
212
- # push them apart and compute elastic collision impulse
213
- # normal vector
214
- nvec = delta / dist
215
- # relative velocity along normal
216
- rel_vel = np.dot(b.vel - a.vel, nvec)
217
- # compute impulse scalar (elastic) with restitution
218
- e = self.restitution
219
- j_impulse = -(1 + e) * rel_vel / (1 / a.mass + 1 / b.mass)
220
- if j_impulse < 0:
221
- # apply impulse
222
- a.vel = a.vel - (j_impulse / a.mass) * nvec
223
- b.vel = b.vel + (j_impulse / b.mass) * nvec
224
- # positional correction (simple)
225
- overlap = min_dist - dist
226
- corr = nvec * (overlap / 2.0 + 1e-6)
227
- a.pos = a.pos - corr
228
- b.pos = b.pos + corr
229
-
230
- def _resolve_boundary_collisions(self):
231
- lo, hi = self.bounds
232
- for a in self.agents:
233
- for d in range(self.dim):
234
- if a.pos[d] - a.radius < lo[d]:
235
- a.pos[d] = lo[d] + a.radius
236
- if a.vel[d] < 0:
237
- a.vel[d] = -a.vel[d] * self.restitution
238
- elif a.pos[d] + a.radius > hi[d]:
239
- a.pos[d] = hi[d] - a.radius
240
- if a.vel[d] > 0:
241
- a.vel[d] = -a.vel[d] * self.restitution
242
-
243
- def render(self, mode="human", ax=None):
244
- # delegated to demo functions; keep signature for Gym compatibility
245
- raise NotImplementedError("render(): use provided demo_2d/demo_3d functions for visualization.")
246
-
247
- def close(self):
248
- pass
249
-
250
- # helper to build spaces per-agent
251
- def build_agent_spaces(self, agent: BaseAgent) -> Tuple[spaces.Box, spaces.Box]:
252
- """
253
- 返回 (observation_space, action_space) for given agent
254
- observation_space: shape (observation_size,)
255
- action_space: shape (dim,) bounded by agent.action_min / action_max
256
- """
257
- obs_dim = agent.observation_size(self)
258
- obs_low = -np.inf * np.ones(obs_dim)
259
- obs_high = np.inf * np.ones(obs_dim)
260
- obs_space = spaces.Box(obs_low, obs_high, dtype=float)
261
- act_low = agent.action_min
262
- act_high = agent.action_max
263
- act_space = spaces.Box(act_low, act_high, dtype=float)
264
- return obs_space, act_space
265
-
266
- # ---------------------------
267
- # Demos: 2D & 3D visualization
268
- # ---------------------------
269
-
270
- def demo_2d():
271
- """
272
- 2D 演示:生成 N 个圆形 agent,RandomController 控制,使用 matplotlib 动画绘制。
273
- """
274
- dim = 2
275
- env = MultiAgentNavEnv(dim=dim, bounds=(np.array([-5, -5]), np.array([5, 5])),
276
- dt=0.03, friction=0.2, restitution=0.8, max_episode_steps=1000)
277
-
278
- # add agents with different masses/radii and action limits per-dim
279
- agents = [
280
- SimpleAgent(dim=dim, mass=1.0, radius=0.25, pos=np.array([-3.0, -3.0]), vel=np.zeros(dim),
281
- action_min=np.array([-2.0, -2.0]), action_max=np.array([2.0, 2.0])),
282
- SimpleAgent(dim=dim, mass=2.0, radius=0.35, pos=np.array([3.0, -3.0]), vel=np.zeros(dim),
283
- action_min=np.array([-1.5, -1.5]), action_max=np.array([1.5, 1.5])),
284
- SimpleAgent(dim=dim, mass=1.2, radius=0.2, pos=np.array([0.0, 3.0]), vel=np.zeros(dim),
285
- action_min=np.array([-3.0, -3.0]), action_max=np.array([3.0, 3.0])),
286
- ]
287
- for a in agents:
288
- env.add_agent(a)
289
-
290
- # build controllers per-agent (Random by default)
291
- controllers = []
292
- for i, a in enumerate(env.agents):
293
- obs_space, act_space = env.build_agent_spaces(a)
294
- controllers.append(RandomController(obs_space, act_space))
295
-
296
- obs, _ = env.reset()
297
-
298
- # matplotlib setup
299
- fig, ax = plt.subplots(figsize=(6, 6))
300
- lo, hi = env.bounds
301
- ax.set_xlim(lo[0], hi[0])
302
- ax.set_ylim(lo[1], hi[1])
303
- ax.set_aspect('equal')
304
- patches = []
305
- texts = []
306
- colors = ['C0', 'C1', 'C2', 'C3', 'C4']
307
- for i, a in enumerate(env.agents):
308
- p = plt.Circle(tuple(a.pos), a.radius, color=colors[i % len(colors)], alpha=0.8)
309
- patches.append(p)
310
- ax.add_patch(p)
311
- t = ax.text(*a.pos, f"{i}", color='white', ha='center', va='center')
312
- texts.append(t)
313
-
314
- # animation update
315
- def update(frame):
316
- actions = {}
317
- for i, a in enumerate(env.agents):
318
- ob = a.get_observation(env)
319
- act = controllers[i].get_action(ob)
320
- actions[i] = act
321
- obs, rewards, dones, info = env.step(actions)
322
- for i, a in enumerate(env.agents):
323
- patches[i].center = tuple(a.pos)
324
- texts[i].set_position(tuple(a.pos))
325
- return patches + texts
326
-
327
- ani = animation.FuncAnimation(fig, update, frames=400, interval=30, blit=False)
328
- plt.title("Multi-Agent Navigation 2D Demo (Random Controllers)")
329
- plt.show()
330
-
331
-
332
- def demo_3d():
333
- """
334
- 3D 演示:类似 2D,但用 mpl_toolkits.mplot3d 展示球体(用 scatter 表示)。
335
- 注意:matplotlib 3D 动画较慢,但用于快速验证足够。
336
- """
337
- dim = 3
338
- env = MultiAgentNavEnv(dim=dim, bounds=(np.array([-5, -5, -2]), np.array([5, 5, 2])),
339
- dt=0.05, friction=0.15, restitution=0.85, max_episode_steps=1000)
340
-
341
- agents = [
342
- SimpleAgent(dim=dim, mass=1.0, radius=0.25, pos=np.array([-3.0, -3.0, 0.0]),
343
- action_min=np.array([-2.0, -2.0, -1.0]), action_max=np.array([2.0, 2.0, 1.0])),
344
- SimpleAgent(dim=dim, mass=1.5, radius=0.3, pos=np.array([3.0, -3.0, 0.5]),
345
- action_min=np.array([-1.5, -1.5, -1.0]), action_max=np.array([1.5, 1.5, 1.0])),
346
- SimpleAgent(dim=dim, mass=0.8, radius=0.2, pos=np.array([0.0, 3.0, -0.5]),
347
- action_min=np.array([-3.0, -3.0, -1.0]), action_max=np.array([3.0, 3.0, 1.0])),
348
- ]
349
- for a in agents:
350
- env.add_agent(a)
351
-
352
- controllers = []
353
- for i, a in enumerate(env.agents):
354
- obs_space, act_space = env.build_agent_spaces(a)
355
- controllers.append(RandomController(obs_space, act_space))
356
-
357
- obs, _ = env.reset()
358
-
359
- # matplotlib 3d setup
360
- fig = plt.figure(figsize=(8, 6))
361
- ax = fig.add_subplot(111, projection='3d')
362
- lo, hi = env.bounds
363
- ax.set_xlim(lo[0], hi[0])
364
- ax.set_ylim(lo[1], hi[1])
365
- ax.set_zlim(lo[2], hi[2])
366
- scat = ax.scatter([a.pos[0] for a in env.agents],
367
- [a.pos[1] for a in env.agents],
368
- [a.pos[2] for a in env.agents],
369
- s=[(a.radius * 1000) for a in env.agents])
370
-
371
- # annotation labels
372
- annotations = [ax.text(a.pos[0], a.pos[1], a.pos[2], str(i)) for i, a in enumerate(env.agents)]
373
-
374
- def update(frame):
375
- actions = {}
376
- for i, a in enumerate(env.agents):
377
- ob = a.get_observation(env)
378
- act = controllers[i].get_action(ob)
379
- actions[i] = act
380
- obs, rewards, dones, info = env.step(actions)
381
- xs = [a.pos[0] for a in env.agents]
382
- ys = [a.pos[1] for a in env.agents]
383
- zs = [a.pos[2] for a in env.agents]
384
- scat._offsets3d = (xs, ys, zs)
385
- for i, ann in enumerate(annotations):
386
- ann.set_position((xs[i], ys[i]))
387
- # can't directly set z of text easily; remove & redraw would be heavy
388
- return scat, *annotations
389
-
390
- ani = animation.FuncAnimation(fig, update, frames=400, interval=50, blit=False)
391
- plt.title("Multi-Agent Navigation 3D Demo (Random Controllers)")
392
- plt.show()
393
-
394
-
395
- # ---------------------------
396
- # Example usage
397
- # ---------------------------
398
-
399
- if __name__ == "__main__":
400
- # 运行 2D 或 3D demo
401
- # print("Running 2D demo...")
402
- demo_2d()
403
- # 若要运行 3D,注释上两行,解除下一行注释:
404
- # demo_3d()