├── LICENSE
├── LLM
├── .gitignore
├── .python-version
├── CMakeLists.txt
├── LICENSE
├── README.md
├── configs
│ ├── archive
│ │ └── task_planning
│ │ │ ├── context
│ │ │ ├── ic1.yaml
│ │ │ ├── ic2.yaml
│ │ │ └── ic3.yaml
│ │ │ ├── serve_apple.yaml
│ │ │ ├── shelving_bowls.yaml
│ │ │ ├── system
│ │ │ └── eRDTransformer.yaml
│ │ │ └── unpack_groceries.yaml
│ ├── models
│ │ └── pretrained
│ │ │ ├── embeddings
│ │ │ ├── bert-base-uncased.yaml
│ │ │ ├── bert-large-uncased.yaml
│ │ │ ├── llama2-7b-chat.yaml
│ │ │ ├── llama2-7b.yaml
│ │ │ ├── mistral-7b.yaml
│ │ │ ├── sentence-transformer-mpnet.yaml
│ │ │ ├── text_embedding_3_large.yaml
│ │ │ ├── text_embedding_3_small.yaml
│ │ │ └── text_embedding_ada_002.yaml
│ │ │ └── generative
│ │ │ ├── gpt_3_5_turbo.yaml
│ │ │ ├── gpt_3_5_turbo_cot.yaml
│ │ │ ├── gpt_4.yaml
│ │ │ ├── gpt_4_cot.yaml
│ │ │ └── llama2_7b_chat.yaml
│ └── prompts
│ │ ├── evaluation
│ │ └── p1
│ │ │ ├── memory_1_1.yaml
│ │ │ ├── memory_1_2.yaml
│ │ │ ├── memory_2_1.yaml
│ │ │ ├── memory_2_2.yaml
│ │ │ ├── packing_1.yaml
│ │ │ ├── packing_2.yaml
│ │ │ ├── packing_3.yaml
│ │ │ ├── packing_4.yaml
│ │ │ ├── retrieval_1_v1.yaml
│ │ │ ├── retrieval_1_v2.yaml
│ │ │ ├── retrieval_2_v1.yaml
│ │ │ ├── retrieval_2_v2.yaml
│ │ │ ├── retrieval_3_v1.yaml
│ │ │ ├── retrieval_3_v2.yaml
│ │ │ ├── retrieval_4_v1.yaml
│ │ │ ├── retrieval_4_v2.yaml
│ │ │ ├── retrieval_5_v2.yaml
│ │ │ └── retrieval_5_v3.yaml
│ │ ├── examples
│ │ ├── example_1.yaml
│ │ ├── example_2.yaml
│ │ ├── example_3.yaml
│ │ ├── example_4.yaml
│ │ ├── example_5.yaml
│ │ └── example_6.yaml
│ │ └── system
│ │ ├── geomtric_reasoning_v1.yaml
│ │ ├── goal_prediction_v1.yaml
│ │ ├── goal_prediction_v2.yaml
│ │ ├── hypothesis_generation_v1.yaml
│ │ ├── task_planning_goal_condition_v1.yaml
│ │ ├── task_planning_goal_condition_v2.yaml
│ │ ├── task_planning_hypothesis_condition_v1.yaml
│ │ └── task_planning_v1.yaml
├── fm_planning
│ ├── __init__.py
│ ├── fm_agents
│ │ ├── __init__.py
│ │ ├── base.py
│ │ └── utils.py
│ ├── models
│ │ ├── __init__.py
│ │ └── pretrained
│ │ │ ├── __init__.py
│ │ │ ├── base.py
│ │ │ ├── embeddings
│ │ │ ├── __init__.py
│ │ │ ├── hugging_face_emb.py
│ │ │ ├── openai_emb.py
│ │ │ └── utils.py
│ │ │ ├── generative
│ │ │ ├── __init__.py
│ │ │ ├── llama_gen.py
│ │ │ ├── openai_gen.py
│ │ │ └── utils.py
│ │ │ └── utils.py
│ └── utils
│ │ ├── __init__.py
│ │ ├── configs.py
│ │ ├── nest.py
│ │ ├── random.py
│ │ ├── tensors.py
│ │ ├── timing.py
│ │ └── typing.py
├── package.xml
├── pyproject.toml
├── scripts
│ ├── demos
│ │ └── llm_planner.py
│ └── llm_planner.py
└── setup.cfg
├── README.md
├── conda_env.yml
├── images
└── teaser_v1.png
└── relational_dynamics
├── .DS_Store
├── __pycache__
├── __init__.cpython-38.pyc
└── base_RD.cpython-38.pyc
├── base_RD.py
├── config
├── __pycache__
│ └── base_config.cpython-38.pyc
└── base_config.py
├── dataloader
├── __pycache__
│ ├── __init__.cpython-38.pyc
│ ├── dataloader.cpython-38.pyc
│ ├── farthest_point_sampling.cpython-38.pyc
│ └── real_robot_dataloader.cpython-38.pyc
└── dataloader.py
├── main.py
├── model
├── __pycache__
│ ├── GNN_pytorch_geometry.cpython-38.pyc
│ ├── __init__.cpython-38.pyc
│ ├── contact_model.cpython-38.pyc
│ ├── encoder_decoder.cpython-38.pyc
│ ├── losses.cpython-38.pyc
│ ├── models.cpython-38.pyc
│ └── pointconv_util_groupnorm.cpython-38.pyc
├── models.py
└── pointconv_util_groupnorm.py
└── utils
├── __pycache__
├── __init__.cpython-38.pyc
├── colors.cpython-38.pyc
├── data_utils.cpython-38.pyc
├── math_util.cpython-38.pyc
├── other_util.cpython-38.pyc
├── parse_util.cpython-38.pyc
├── tensorboardx_logger.cpython-38.pyc
├── torch_util.cpython-38.pyc
└── torch_utils.cpython-38.pyc
├── colors.py
├── data_utils.py
├── math_util.py
├── other_util.py
├── parse_util.py
├── torch_util.py
└── transformations.py
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2024 Yixuan Huang, Christopher Agia
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
--------------------------------------------------------------------------------
/LLM/.gitignore:
--------------------------------------------------------------------------------
1 | # Output directory
2 | data
3 | *.DS_Store
4 |
5 | # Byte-compiled / optimized / DLL files
6 | __pycache__/
7 | *.py[cod]
8 | *$py.class
9 |
10 | # C extensions
11 | *.so
12 |
13 | # Distribution / packaging
14 | .Python
15 | build/
16 | develop-eggs/
17 | dist/
18 | downloads/
19 | eggs/
20 | .eggs/
21 | lib/
22 | lib64/
23 | parts/
24 | sdist/
25 | var/
26 | wheels/
27 | share/python-wheels/
28 | *.egg-info/
29 | .installed.cfg
30 | *.egg
31 | MANIFEST
32 |
33 | # PyInstaller
34 | # Usually these files are written by a python script from a template
35 | # before PyInstaller builds the exe, so as to inject date/other infos into it.
36 | *.manifest
37 | *.spec
38 |
39 | # Installer logs
40 | pip-log.txt
41 | pip-delete-this-directory.txt
42 |
43 | # Unit test / coverage reports
44 | htmlcov/
45 | .tox/
46 | .nox/
47 | .coverage
48 | .coverage.*
49 | .cache
50 | nosetests.xml
51 | coverage.xml
52 | *.cover
53 | *.py,cover
54 | .hypothesis/
55 | .pytest_cache/
56 | cover/
57 |
58 | # Translations
59 | *.mo
60 | *.pot
61 |
62 | # Django stuff:
63 | *.log
64 | local_settings.py
65 | db.sqlite3
66 | db.sqlite3-journal
67 |
68 | # Flask stuff:
69 | instance/
70 | .webassets-cache
71 |
72 | # Scrapy stuff:
73 | .scrapy
74 |
75 | # Sphinx documentation
76 | docs/_build/
77 |
78 | # PyBuilder
79 | .pybuilder/
80 | target/
81 |
82 | # Jupyter Notebook
83 | .ipynb_checkpoints
84 |
85 | # IPython
86 | profile_default/
87 | ipython_config.py
88 |
89 | # pyenv
90 | # For a library or package, you might want to ignore these files since the code is
91 | # intended to run in multiple environments; otherwise, check them in:
92 | # .python-version
93 |
94 | # pipenv
95 | # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
96 | # However, in case of collaboration, if having platform-specific dependencies or dependencies
97 | # having no cross-platform support, pipenv may install dependencies that don't work, or not
98 | # install all needed dependencies.
99 | #Pipfile.lock
100 |
101 | # poetry
102 | # Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control.
103 | # This is especially recommended for binary packages to ensure reproducibility, and is more
104 | # commonly ignored for libraries.
105 | # https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control
106 | #poetry.lock
107 |
108 | # pdm
109 | # Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control.
110 | #pdm.lock
111 | # pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it
112 | # in version control.
113 | # https://pdm.fming.dev/#use-with-ide
114 | .pdm.toml
115 |
116 | # PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm
117 | __pypackages__/
118 |
119 | # Celery stuff
120 | celerybeat-schedule
121 | celerybeat.pid
122 |
123 | # SageMath parsed files
124 | *.sage.py
125 |
126 | # Environments
127 | .env
128 | .venv
129 | env/
130 | venv/
131 | ENV/
132 | env.bak/
133 | venv.bak/
134 |
135 | # Spyder project settings
136 | .spyderproject
137 | .spyproject
138 |
139 | # Rope project settings
140 | .ropeproject
141 |
142 | # mkdocs documentation
143 | /site
144 |
145 | # mypy
146 | .mypy_cache/
147 | .dmypy.json
148 | dmypy.json
149 |
150 | # Pyre type checker
151 | .pyre/
152 |
153 | # pytype static type analyzer
154 | .pytype/
155 |
156 | # Cython debug symbols
157 | cython_debug/
158 |
159 | # PyCharm
160 | # JetBrains specific template is maintained in a separate JetBrains.gitignore that can
161 | # be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
162 | # and can be added to the global gitignore or merged into this file. For a more nuclear
163 | # option (not recommended) you can uncomment the following to ignore the entire idea folder.
164 | #.idea/
165 |
--------------------------------------------------------------------------------
/LLM/.python-version:
--------------------------------------------------------------------------------
1 | 3.8.16
2 |
--------------------------------------------------------------------------------
/LLM/CMakeLists.txt:
--------------------------------------------------------------------------------
1 | cmake_minimum_required(VERSION 3.0.2)
2 | project(fm_planning)
3 |
4 | ## Compile as C++11, supported in ROS Kinetic and newer
5 | # add_compile_options(-std=c++11)
6 |
7 | ## Find catkin macros and libraries
8 | ## if COMPONENTS list like find_package(catkin REQUIRED COMPONENTS xyz)
9 | ## is used, also find other catkin packages
10 | find_package(catkin REQUIRED COMPONENTS
11 | rospy
12 | std_msgs
13 | message_generation
14 | )
15 |
16 | ## System dependencies are found with CMake's conventions
17 | # find_package(Boost REQUIRED COMPONENTS system)
18 |
19 |
20 | ## Uncomment this if the package has a setup.py. This macro ensures
21 | ## modules and global scripts declared therein get installed
22 | ## See http://ros.org/doc/api/catkin/html/user_guide/setup_dot_py.html
23 | # catkin_python_setup()
24 |
25 | ################################################
26 | ## Declare ROS messages, services and actions ##
27 | ################################################
28 |
29 | ## To declare and build messages, services or actions from within this
30 | ## package, follow these steps:
31 | ## * Let MSG_DEP_SET be the set of packages whose message types you use in
32 | ## your messages/services/actions (e.g. std_msgs, actionlib_msgs, ...).
33 | ## * In the file package.xml:
34 | ## * add a build_depend tag for "message_generation"
35 | ## * add a build_depend and a exec_depend tag for each package in MSG_DEP_SET
36 | ## * If MSG_DEP_SET isn't empty the following dependency has been pulled in
37 | ## but can be declared for certainty nonetheless:
38 | ## * add a exec_depend tag for "message_runtime"
39 | ## * In this file (CMakeLists.txt):
40 | ## * add "message_generation" and every package in MSG_DEP_SET to
41 | ## find_package(catkin REQUIRED COMPONENTS ...)
42 | ## * add "message_runtime" and every package in MSG_DEP_SET to
43 | ## catkin_package(CATKIN_DEPENDS ...)
44 | ## * uncomment the add_*_files sections below as needed
45 | ## and list every .msg/.srv/.action file to be processed
46 | ## * uncomment the generate_messages entry below
47 | ## * add every package in MSG_DEP_SET to generate_messages(DEPENDENCIES ...)
48 |
49 | ## Generate messages in the 'msg' folder
50 | # add_message_files(
51 | # FILES
52 | # Message1.msg
53 | # Message2.msg
54 | # )
55 |
56 | ## Generate services in the 'srv' folder
57 | add_service_files(
58 | FILES
59 | InitObjects.srv
60 | Goals.srv
61 | TaskPlans.srv
62 | TaskPlansFromGoals.srv
63 | )
64 |
65 | ## Generate actions in the 'action' folder
66 | # add_action_files(
67 | # FILES
68 | # Action1.action
69 | # Action2.action
70 | # )
71 |
72 | ## Generate added messages and services with any dependencies listed here
73 | generate_messages(
74 | DEPENDENCIES
75 | std_msgs
76 | )
77 |
78 | ################################################
79 | ## Declare ROS dynamic reconfigure parameters ##
80 | ################################################
81 |
82 | ## To declare and build dynamic reconfigure parameters within this
83 | ## package, follow these steps:
84 | ## * In the file package.xml:
85 | ## * add a build_depend and a exec_depend tag for "dynamic_reconfigure"
86 | ## * In this file (CMakeLists.txt):
87 | ## * add "dynamic_reconfigure" to
88 | ## find_package(catkin REQUIRED COMPONENTS ...)
89 | ## * uncomment the "generate_dynamic_reconfigure_options" section below
90 | ## and list every .cfg file to be processed
91 |
92 | ## Generate dynamic reconfigure parameters in the 'cfg' folder
93 | # generate_dynamic_reconfigure_options(
94 | # cfg/DynReconf1.cfg
95 | # cfg/DynReconf2.cfg
96 | # )
97 |
98 | ###################################
99 | ## catkin specific configuration ##
100 | ###################################
101 | ## The catkin_package macro generates cmake config files for your package
102 | ## Declare things to be passed to dependent projects
103 | ## INCLUDE_DIRS: uncomment this if your package contains header files
104 | ## LIBRARIES: libraries you create in this project that dependent projects also need
105 | ## CATKIN_DEPENDS: catkin_packages dependent projects also need
106 | ## DEPENDS: system dependencies of this project that dependent projects also need
107 | catkin_package(
108 | # INCLUDE_DIRS include
109 | # LIBRARIES fm_planning
110 | # CATKIN_DEPENDS rospy std_msgs
111 | # DEPENDS system_lib
112 | )
113 |
114 | ###########
115 | ## Build ##
116 | ###########
117 |
118 | ## Specify additional locations of header files
119 | ## Your package locations should be listed before other locations
120 | include_directories(
121 | # include
122 | ${catkin_INCLUDE_DIRS}
123 | )
124 |
125 | ## Declare a C++ library
126 | # add_library(${PROJECT_NAME}
127 | # src/${PROJECT_NAME}/fm_planning.cpp
128 | # )
129 |
130 | ## Add cmake target dependencies of the library
131 | ## as an example, code may need to be generated before libraries
132 | ## either from message generation or dynamic reconfigure
133 | # add_dependencies(${PROJECT_NAME} ${${PROJECT_NAME}_EXPORTED_TARGETS} ${catkin_EXPORTED_TARGETS})
134 |
135 | ## Declare a C++ executable
136 | ## With catkin_make all packages are built within a single CMake context
137 | ## The recommended prefix ensures that target names across packages don't collide
138 | # add_executable(${PROJECT_NAME}_node src/fm_planning_node.cpp)
139 |
140 | ## Rename C++ executable without prefix
141 | ## The above recommended prefix causes long target names, the following renames the
142 | ## target back to the shorter version for ease of user use
143 | ## e.g. "rosrun someones_pkg node" instead of "rosrun someones_pkg someones_pkg_node"
144 | # set_target_properties(${PROJECT_NAME}_node PROPERTIES OUTPUT_NAME node PREFIX "")
145 |
146 | ## Add cmake target dependencies of the executable
147 | ## same as for the library above
148 | # add_dependencies(${PROJECT_NAME}_node ${${PROJECT_NAME}_EXPORTED_TARGETS} ${catkin_EXPORTED_TARGETS})
149 |
150 | ## Specify libraries to link a library or executable target against
151 | # target_link_libraries(${PROJECT_NAME}_node
152 | # ${catkin_LIBRARIES}
153 | # )
154 |
155 | #############
156 | ## Install ##
157 | #############
158 |
159 | # all install targets should use catkin DESTINATION variables
160 | # See http://ros.org/doc/api/catkin/html/adv_user_guide/variables.html
161 |
162 | ## Mark executable scripts (Python etc.) for installation
163 | ## in contrast to setup.py, you can choose the destination
164 | catkin_install_python(PROGRAMS
165 | scripts/ros/llm_planning_node.py
166 | DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION}
167 | )
168 |
169 | ## Mark executables for installation
170 | ## See http://docs.ros.org/melodic/api/catkin/html/howto/format1/building_executables.html
171 | # install(TARGETS ${PROJECT_NAME}_node
172 | # RUNTIME DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION}
173 | # )
174 |
175 | ## Mark libraries for installation
176 | ## See http://docs.ros.org/melodic/api/catkin/html/howto/format1/building_libraries.html
177 | # install(TARGETS ${PROJECT_NAME}
178 | # ARCHIVE DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION}
179 | # LIBRARY DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION}
180 | # RUNTIME DESTINATION ${CATKIN_GLOBAL_BIN_DESTINATION}
181 | # )
182 |
183 | ## Mark cpp header files for installation
184 | # install(DIRECTORY include/${PROJECT_NAME}/
185 | # DESTINATION ${CATKIN_PACKAGE_INCLUDE_DESTINATION}
186 | # FILES_MATCHING PATTERN "*.h"
187 | # PATTERN ".svn" EXCLUDE
188 | # )
189 |
190 | ## Mark other files for installation (e.g. launch and bag files, etc.)
191 | # install(FILES
192 | # # myfile1
193 | # # myfile2
194 | # DESTINATION ${CATKIN_PACKAGE_SHARE_DESTINATION}
195 | # )
196 |
197 | #############
198 | ## Testing ##
199 | #############
200 |
201 | ## Add gtest based cpp test target and link libraries
202 | # catkin_add_gtest(${PROJECT_NAME}-test test/test_fm_planning.cpp)
203 | # if(TARGET ${PROJECT_NAME}-test)
204 | # target_link_libraries(${PROJECT_NAME}-test ${PROJECT_NAME})
205 | # endif()
206 |
207 | ## Add folders to be run by python nosetests
208 | # catkin_add_nosetests(test)
209 |
--------------------------------------------------------------------------------
/LLM/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2024 Christopher Agia
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/LLM/README.md:
--------------------------------------------------------------------------------
1 | # fm-planning
2 | Planning with Foundation Models (FMs): Language Models and Vision-Language Models
3 |
--------------------------------------------------------------------------------
/LLM/configs/archive/task_planning/context/ic1.yaml:
--------------------------------------------------------------------------------
1 | - role: user
2 | content:
3 | "Objects: [cup, sink, kitchen_table]\n
4 |
5 | Object Relationships: [Above(cup, kitchen_table), Contact(cup, kitchen_table)]\n
6 |
7 | Instruction: Place the cup in the sink.\n
8 |
9 | Goals: [[Inside(cup, sink), Contact(cup, sink)]]\n
10 |
11 | Plans: [[Pick(cup, kitchen_table), Place(cup, sink)]]\n"
--------------------------------------------------------------------------------
/LLM/configs/archive/task_planning/context/ic2.yaml:
--------------------------------------------------------------------------------
1 | - role: user
2 | content:
3 | "Objects: [socks, jacket, drawer, closet, bed]\n
4 |
5 | Object Relationships: [Inside(socks, drawer),
6 | Contact(socks, drawer),
7 | Inside(jacket, closet),
8 | Closed(drawer),
9 | Closed(cloest)]\n
10 |
11 | Instruction: Fetch me a pair of socks. I'm in the bedroom. \n
12 |
13 | Goals: [[Above(socks, bed), Contact(socks, bed)]]\n
14 |
15 | Plans: [[Open(drawer), Pick(socks, drawer), Place(socks, bed), Close(drawer)]]\n"
--------------------------------------------------------------------------------
/LLM/configs/archive/task_planning/context/ic3.yaml:
--------------------------------------------------------------------------------
1 | - role: user
2 | content:
3 | "Objects: [book_1, book_2, bookshelf, reading_chair, coffee_table]\n
4 |
5 | Object Relationships: [Above(book_1, book_2), Above(book_2, bookshelf),
6 | Contact(book_1, book_2), Contact(book_2, bookshelf)]\n
7 |
8 | Instruction: Bring me book_2.\n
9 |
10 | Goals: [[Above(book_2, reading_chair), Contact(book_2, reading_chair)],
11 | [Above(book_2, coffee_table), Contact(book_2, coffee_table)]]\n
12 |
13 | Plans: [[Pick(book_1, book_2), Place(book_1, bookshelf), Pick(book_2, bookshelf), Place(book_2, reading_chair)],
14 | [Pick(book_1, book_2), Place(book_1, bookshelf), Pick(book_2, bookshelf), Place(book_2, coffee_table)]\n"
--------------------------------------------------------------------------------
/LLM/configs/archive/task_planning/serve_apple.yaml:
--------------------------------------------------------------------------------
1 | # System prompt.
2 | - configs/prompts/task_planning/system/eRDTransformer.yaml
3 |
4 | # In-context prompts.
5 | - configs/prompts/task_planning/context/ic1.yaml
6 | - configs/prompts/task_planning/context/ic2.yaml
7 | - configs/prompts/task_planning/context/ic3.yaml
8 |
9 | # Task prompt.
10 | - role: user
11 | content:
12 | "Objects: [apple, onion, grocery_box, fruit_bowl, garbage_bin, kitchen_cabinet]\n
13 |
14 | Object Relationships: [Inside(apple, kitchen_cabinet),
15 | Contact(apple, kitchen_cabinet),
16 | Inside(onion, kitchen_cabinet),
17 | Contact(onion, kitchen_cabinet),
18 | Opened(grocery_box),
19 | Opened(garbage_bin),
20 | Closed(kitchen_cabinet)]\n
21 |
22 | Instruction: Serve the apple in the fruit bowl.\n"
--------------------------------------------------------------------------------
/LLM/configs/archive/task_planning/shelving_bowls.yaml:
--------------------------------------------------------------------------------
1 | # System prompt.
2 | - configs/prompts/task_planning/system/eRDTransformer.yaml
3 |
4 | # In-context prompts.
5 | - configs/prompts/task_planning/context/ic1.yaml
6 | - configs/prompts/task_planning/context/ic2.yaml
7 | - configs/prompts/task_planning/context/ic3.yaml
8 |
9 | # Task prompt.
10 | - role: user
11 | content:
12 | "Objects: [small_bowl, large_bowl, medium_bowl, dishwasher, shelf]\n
13 |
14 | Object Relationships: [Inside(small_bowl, dishwasher),
15 | Inside(large_bowl, dishwasher),
16 | Inside(medium_bowl, dishwasher),
17 | Front(small_bowl, large_bowl),
18 | Front(large_bowl, medium_bowl)]\n
19 |
20 | Instruction: Put all the bowls back on the shelf and sort them by increasing size.\n"
--------------------------------------------------------------------------------
/LLM/configs/archive/task_planning/system/eRDTransformer.yaml:
--------------------------------------------------------------------------------
1 | - role: system
2 | content:
3 | "I am the task planning system of a mobile manipulator robot operating in a household environment.
4 | My job is to analyze the user's instruction and the state of the environment, then 1) predict goals
5 | that the robot should achieve to fulfill the user's instruction and 2) plan candidate sequences of
6 | actions that the robot should execute to satisfy the predicted goals.\n
7 |
8 | The robot can perceive the following information about the environment:\n
9 | - The objects in the environment\n
10 | - The relationships among objects (e.g., above, below)\n
11 | - The state of objects (e.g., open or closed)\n
12 |
13 | The robot can detect the following relationships among objects:\n
14 | - Left(a, b): Object a is to the left of object b\n
15 | - Right(a, b): Object a is to the right of object b\n
16 | - Front(a, b): Object a is in front of object b\n
17 | - Behind(a, b): Object a is behind object b\n
18 | - Above(a, b): Object a is above object b\n
19 | - Below(a, b): Object a is below object b\n
20 | - Contact(a, b): Object a is in contact with object b\n
21 | - Boundary(a, b): Object a is within the boundary of object b\n
22 | - Inside(a, b): Object a is inside object b\n
23 | - Opened(a): Object a is opened\n
24 | - Closed(a): Object a is closed\n
25 |
26 | The robot can execute the following actions:\n
27 | - Pick(a, b): The robot picks object a from object b. The robot must NOT already be holding an object\n
28 | - Place(a, b): The robot places object a on or in object b\n
29 | - Open(a): The robot opens object a. The robot must NOT already be holding an object\n
30 | - Close(a): The robot closes object a. The robot must NOT already be holding an object\n
31 |
32 | There may be one or multiple ways to fulfill the user's instruction. Therefore, I will consider the
33 | most likely goals and plans, if there are multiple, and output them in the following format:\n
34 | Rules:\n
35 | - I will output goals as a list of lists after 'Goals:'. Each nested list represents one goal\n
36 | - I will output plans as a list of lists after 'Plans:'. Each nested list represents one plan\n
37 | - I will output one plan for each goal. Hence, each goal and its corresponding plan will be located
38 | at the same index in the 'Goals' and 'Plans' lists\n
39 | - I will not output all possible goals and plans, but the most likely ones to fulfill the user's instruction\n
40 | - If there are multiple ways to fulfill the instruction, I will output the simplest goals and plans first\n
41 | - I will consider the feasibility of the plans based on the the defined actions and their preconditions.
42 | For example, the actions Pick(a), Open(a), Close(a) cannot be executed in the robot is already holding an object\n
43 |
44 | Examples:\n"
--------------------------------------------------------------------------------
/LLM/configs/archive/task_planning/unpack_groceries.yaml:
--------------------------------------------------------------------------------
1 | # System prompt.
2 | - configs/prompts/task_planning/system/eRDTransformer.yaml
3 |
4 | # In-context prompts.
5 | - configs/prompts/task_planning/context/ic1.yaml
6 | - configs/prompts/task_planning/context/ic2.yaml
7 | - configs/prompts/task_planning/context/ic3.yaml
8 |
9 | # Task prompt.
10 | - role: user
11 | content:
12 | "Objects: [apple, onion, grocery_box, fruit_bowl, garbage_bin, kitchen_cabinet]\n
13 |
14 | Object Relationships: [Inside(apple, grocery_box),
15 | Contact(apple, grocery_box),
16 | Inside(onion, grocery_box),
17 | Contact(onion, grocery_box),
18 | Opened(grocery_box),
19 | Opened(garbage_bin),
20 | Closed(kitchen_cabinet)]\n
21 |
22 | Instruction: Unpack the grocery box into the kitchen cabinet. Start by opening the cabinet.\n"
--------------------------------------------------------------------------------
/LLM/configs/models/pretrained/embeddings/bert-base-uncased.yaml:
--------------------------------------------------------------------------------
1 | model: HuggingFaceEmbeddingModel
2 | model_kwargs:
3 | model: "bert-base-uncased"
--------------------------------------------------------------------------------
/LLM/configs/models/pretrained/embeddings/bert-large-uncased.yaml:
--------------------------------------------------------------------------------
1 | model: HuggingFaceEmbeddingModel
2 | model_kwargs:
3 | model: "bert-large-uncased"
4 |
--------------------------------------------------------------------------------
/LLM/configs/models/pretrained/embeddings/llama2-7b-chat.yaml:
--------------------------------------------------------------------------------
1 | model: HuggingFaceEmbeddingModel
2 | model_kwargs:
3 | model: "meta-llama/Llama-2-7b-chat-hf"
4 |
--------------------------------------------------------------------------------
/LLM/configs/models/pretrained/embeddings/llama2-7b.yaml:
--------------------------------------------------------------------------------
1 | model: HuggingFaceEmbeddingModel
2 | model_kwargs:
3 | model: "meta-llama/Llama-2-7b-hf"
4 |
--------------------------------------------------------------------------------
/LLM/configs/models/pretrained/embeddings/mistral-7b.yaml:
--------------------------------------------------------------------------------
1 | model: HuggingFaceEmbeddingModel
2 | model_kwargs:
3 | model: "intfloat/e5-mistral-7b-instruct"
4 |
--------------------------------------------------------------------------------
/LLM/configs/models/pretrained/embeddings/sentence-transformer-mpnet.yaml:
--------------------------------------------------------------------------------
1 | model: HuggingFaceEmbeddingModel
2 | model_kwargs:
3 | model: "sentence-transformers/all-mpnet-base-v2"
4 |
--------------------------------------------------------------------------------
/LLM/configs/models/pretrained/embeddings/text_embedding_3_large.yaml:
--------------------------------------------------------------------------------
1 | model: OpenAIEmbeddingModel
2 | model_kwargs:
3 | model: "text-embedding-3-large"
--------------------------------------------------------------------------------
/LLM/configs/models/pretrained/embeddings/text_embedding_3_small.yaml:
--------------------------------------------------------------------------------
1 | model: OpenAIEmbeddingModel
2 | model_kwargs:
3 | model: "text-embedding-3-small"
--------------------------------------------------------------------------------
/LLM/configs/models/pretrained/embeddings/text_embedding_ada_002.yaml:
--------------------------------------------------------------------------------
1 | model: OpenAIEmbeddingModel
2 | model_kwargs:
3 | model: "text-embedding-ada-002"
--------------------------------------------------------------------------------
/LLM/configs/models/pretrained/generative/gpt_3_5_turbo.yaml:
--------------------------------------------------------------------------------
1 | model: OpenAIGenerativeModel
2 | model_kwargs:
3 | model: "gpt-3.5-turbo"
4 | logprobs: True
5 | max_tokens: 10
6 | temperature: 0.0
--------------------------------------------------------------------------------
/LLM/configs/models/pretrained/generative/gpt_3_5_turbo_cot.yaml:
--------------------------------------------------------------------------------
1 | model: OpenAIGenerativeModel
2 | model_kwargs:
3 | model: "gpt-3.5-turbo"
4 | logprobs: True
5 | temperature: 0.0
--------------------------------------------------------------------------------
/LLM/configs/models/pretrained/generative/gpt_4.yaml:
--------------------------------------------------------------------------------
1 | model: OpenAIGenerativeModel
2 | model_kwargs:
3 | model: "gpt-4-0125-preview"
4 | logprobs: True
5 | max_tokens: 10
6 | temperature: 0.0
--------------------------------------------------------------------------------
/LLM/configs/models/pretrained/generative/gpt_4_cot.yaml:
--------------------------------------------------------------------------------
1 | model: OpenAIGenerativeModel
2 | model_kwargs:
3 | model: "gpt-4-0125-preview"
4 | logprobs: True
5 | temperature: 0.0
--------------------------------------------------------------------------------
/LLM/configs/models/pretrained/generative/llama2_7b_chat.yaml:
--------------------------------------------------------------------------------
1 | model: LlamaGenerativeModel
2 | model_kwargs:
3 | model: "meta-llama/Llama-2-7b-chat-hf"
4 | do_sample: False
--------------------------------------------------------------------------------
/LLM/configs/prompts/evaluation/p1/memory_1_1.yaml:
--------------------------------------------------------------------------------
1 | prompt: BehaviorPromptManager
2 | prompt_kwargs:
3 | # Task prompt
4 | task_prompt:
5 | # Task
6 | task: memory_1_1
7 | instruction: "Put object_1 in the low drawer, then close the drawer."
8 | objects:
9 | # - "object_1"
10 | # - "bowl"
11 | # - "low_drawer"
12 | # - "high_drawer"
13 | # - "ground"
14 | - "object_1"
15 | - "object_2"
16 | - "low_drawer"
17 | - "high_drawer"
18 | - "ground"
19 | predicates:
20 | # - "On(object_1, ground)"
21 | # - "On(bowl, ground)"
22 | # - "Closed(low_drawer)"
23 | # - "Closed(high_drawer)"
24 | - "On(object_1, ground)"
25 | - "On(object_2, ground)"
26 | - "Closed(low_drawer)"
27 | - "Closed(high_drawer)"
28 |
29 | # Behaviors
30 | goals: Null
31 | plans: Null
32 | hypotheses: Null
33 | geometric: Null
34 |
35 | # OpenAI
36 | role: user
37 | name: Null
38 | name_query: Null
39 | name_response: Null
40 |
41 | # System prompts
42 | system_prompts:
43 | - LLM/configs/prompts/system/goal_prediction_v2.yaml
44 | - LLM/configs/prompts/system/task_planning_goal_condition_v2.yaml
45 |
46 | # Example prompts
47 | example_prompts:
48 | - LLM/configs/prompts/examples/example_1.yaml
49 | - LLM/configs/prompts/examples/example_2.yaml
50 | - LLM/configs/prompts/examples/example_3.yaml
51 |
52 | # Event prompts
53 | event_prompts: Null
--------------------------------------------------------------------------------
/LLM/configs/prompts/evaluation/p1/memory_1_2.yaml:
--------------------------------------------------------------------------------
1 | prompt: BehaviorPromptManager
2 | prompt_kwargs:
3 | # Task prompt
4 | task_prompt:
5 | # Task
6 | task: memory_1_2
7 | instruction: "Place object_1 on object_2. Don't forget to close the drawer."
8 | objects:
9 | - "object_1"
10 | - "object_2"
11 | - "low_drawer"
12 | - "high_drawer"
13 | - "ground"
14 | predicates:
15 | - "Inside(object_1, low_drawer)"
16 | - "On(object_2, ground)"
17 | - "Closed(low_drawer)"
18 | - "Closed(high_drawer)"
19 |
20 | # Behaviors
21 | goals: Null
22 | plans: Null
23 | hypotheses: Null
24 | geometric: Null
25 |
26 | # OpenAI
27 | role: user
28 | name: Null
29 | name_query: Null
30 | name_response: Null
31 |
32 | # System prompts
33 | system_prompts:
34 | - LLM/configs/prompts/system/goal_prediction_v2.yaml
35 | - LLM/configs/prompts/system/task_planning_goal_condition_v2.yaml
36 |
37 | # Example prompts
38 | example_prompts:
39 | - LLM/configs/prompts/examples/example_1.yaml
40 | - LLM/configs/prompts/examples/example_2.yaml
41 | - LLM/configs/prompts/examples/example_3.yaml
42 |
43 | # Event prompts
44 | event_prompts: Null
--------------------------------------------------------------------------------
/LLM/configs/prompts/evaluation/p1/memory_2_1.yaml:
--------------------------------------------------------------------------------
1 | prompt: BehaviorPromptManager
2 | prompt_kwargs:
3 | # Task prompt
4 | task_prompt:
5 | # Task
6 | task: memory_2_1
7 | instruction: "Put object_1 and object_2 in the low drawer, then close the drawer."
8 | objects:
9 | - "object_1"
10 | - "object_2"
11 | - "object_3"
12 | - "object_4"
13 | - "low_drawer"
14 | - "high_drawer"
15 | - "ground"
16 | predicates:
17 | - "On(object_1, ground)"
18 | - "On(object_2, ground)"
19 | - "On(object_3, ground)"
20 | - "On(object_4, ground)"
21 | - "Closed(low_drawer)"
22 | - "Closed(high_drawer)"
23 |
24 | # Behaviors
25 | goals: Null
26 | plans: Null
27 | hypotheses: Null
28 | geometric: Null
29 |
30 | # OpenAI
31 | role: user
32 | name: Null
33 | name_query: Null
34 | name_response: Null
35 |
36 | # System prompts
37 | system_prompts:
38 | - LLM/configs/prompts/system/goal_prediction_v2.yaml
39 | - LLM/configs/prompts/system/task_planning_goal_condition_v2.yaml
40 |
41 | # Example prompts
42 | example_prompts:
43 | - LLM/configs/prompts/examples/example_1.yaml
44 | - LLM/configs/prompts/examples/example_2.yaml
45 | - LLM/configs/prompts/examples/example_3.yaml
46 |
47 | # Event prompts
48 | event_prompts: Null
--------------------------------------------------------------------------------
/LLM/configs/prompts/evaluation/p1/memory_2_2.yaml:
--------------------------------------------------------------------------------
1 | prompt: BehaviorPromptManager
2 | prompt_kwargs:
3 | # Task prompt
4 | task_prompt:
5 | # Task
6 | task: memory_2_2
7 | # instruction: "Place object_1 on the bowl. Don't forget to close the drawer."
8 | instruction: "Place object_1 on object_3. Don't forget to close the drawer."
9 | objects:
10 | - "object_1"
11 | - "object_2"
12 | - "object_3"
13 | - "object_4"
14 | - "low_drawer"
15 | - "high_drawer"
16 | - "ground"
17 | predicates:
18 | - "Inside(object_1, low_drawer)"
19 | - "Inside(object_2, low_drawer)"
20 | - "On(object_3, ground)"
21 | - "On(object_4, ground)"
22 | - "Closed(low_drawer)"
23 | - "Closed(high_drawer)"
24 |
25 | # Behaviors
26 | goals: Null
27 | plans: Null
28 | hypotheses: Null
29 | geometric: Null
30 |
31 | # OpenAI
32 | role: user
33 | name: Null
34 | name_query: Null
35 | name_response: Null
36 |
37 | # System prompts
38 | system_prompts:
39 | - LLM/configs/prompts/system/goal_prediction_v2.yaml
40 | - LLM/configs/prompts/system/task_planning_goal_condition_v2.yaml
41 |
42 | # Example prompts
43 | example_prompts:
44 | - LLM/configs/prompts/examples/example_1.yaml
45 | - LLM/configs/prompts/examples/example_2.yaml
46 | - LLM/configs/prompts/examples/example_3.yaml
47 |
48 | # Event prompts
49 | event_prompts: Null
--------------------------------------------------------------------------------
/LLM/configs/prompts/evaluation/p1/packing_1.yaml:
--------------------------------------------------------------------------------
1 | prompt: BehaviorPromptManager
2 | prompt_kwargs:
3 | # Task prompt
4 | task_prompt:
5 | # Task
6 | task: packing_1
7 | instruction: "Put all the objects on the counter."
8 | objects:
9 | - "object_1"
10 | - "object_2"
11 | - "object_3"
12 | - "object_4"
13 | - "ground"
14 | - "counter"
15 | predicates:
16 | - "On(object_1, ground)"
17 | - "On(object_2, ground)"
18 | - "On(object_3, ground)"
19 | - "On(object_4, ground)"
20 |
21 | # Behaviors
22 | goals: Null
23 | plans: Null
24 | hypotheses: Null
25 | geometric: Null
26 |
27 | # OpenAI
28 | role: user
29 | name: Null
30 | name_query: Null
31 | name_response: Null
32 |
33 | # System prompts
34 | system_prompts:
35 | - LLM/configs/prompts/system/goal_prediction_v1.yaml
36 | - LLM/configs/prompts/system/task_planning_goal_condition_v1.yaml
37 |
38 | # Example prompts
39 | example_prompts:
40 | - LLM/configs/prompts/examples/example_1.yaml
41 | - LLM/configs/prompts/examples/example_2.yaml
42 | - LLM/configs/prompts/examples/example_3.yaml
43 |
44 | # Event prompts
45 | event_prompts: Null
--------------------------------------------------------------------------------
/LLM/configs/prompts/evaluation/p1/packing_2.yaml:
--------------------------------------------------------------------------------
1 | prompt: BehaviorPromptManager
2 | prompt_kwargs:
3 | # Task prompt
4 | task_prompt:
5 | # Task
6 | task: packing_2
7 | instruction: "Put all the objects on the shelf."
8 | objects:
9 | - "object_1"
10 | - "object_2"
11 | - "object_3"
12 | - "ground"
13 | - "shelf"
14 | predicates:
15 | - "On(object_1, ground)"
16 | - "On(object_2, ground)"
17 | - "On(object_3, ground)"
18 |
19 | # Behaviors
20 | goals: Null
21 | plans: Null
22 | hypotheses: Null
23 | geometric: Null
24 |
25 | # OpenAI
26 | role: user
27 | name: Null
28 | name_query: Null
29 | name_response: Null
30 |
31 | # System prompts
32 | system_prompts:
33 | - LLM/configs/prompts/system/goal_prediction_v1.yaml
34 | - LLM/configs/prompts/system/task_planning_goal_condition_v1.yaml
35 |
36 | # Example prompts
37 | example_prompts:
38 | - LLM/configs/prompts/examples/example_1.yaml
39 | - LLM/configs/prompts/examples/example_2.yaml
40 | - LLM/configs/prompts/examples/example_3.yaml
41 |
42 | # Event prompts
43 | event_prompts: Null
--------------------------------------------------------------------------------
/LLM/configs/prompts/evaluation/p1/packing_3.yaml:
--------------------------------------------------------------------------------
1 | prompt: BehaviorPromptManager
2 | prompt_kwargs:
3 | # Task prompt
4 | task_prompt:
5 | # Task
6 | task: packing_3
7 | instruction: "Put all the objects on the shelf."
8 | objects:
9 | - "object_1"
10 | - "object_2"
11 | - "object_3"
12 | - "object_4"
13 | - "ground"
14 | - "shelf"
15 | predicates:
16 | - "On(object_1, ground)"
17 | - "On(object_2, ground)"
18 | - "On(object_3, ground)"
19 | - "On(object_4, ground)"
20 |
21 | # Behaviors
22 | goals: Null
23 | plans: Null
24 | hypotheses: Null
25 | geometric: Null
26 |
27 | # OpenAI
28 | role: user
29 | name: Null
30 | name_query: Null
31 | name_response: Null
32 |
33 | # System prompts
34 | system_prompts:
35 | - LLM/configs/prompts/system/goal_prediction_v1.yaml
36 | - LLM/configs/prompts/system/task_planning_goal_condition_v1.yaml
37 |
38 | # Example prompts
39 | example_prompts:
40 | - LLM/configs/prompts/examples/example_1.yaml
41 | - LLM/configs/prompts/examples/example_2.yaml
42 | - LLM/configs/prompts/examples/example_3.yaml
43 |
44 | # Event prompts
45 | event_prompts: Null
--------------------------------------------------------------------------------
/LLM/configs/prompts/evaluation/p1/packing_4.yaml:
--------------------------------------------------------------------------------
1 | prompt: BehaviorPromptManager
2 | prompt_kwargs:
3 | # Task prompt
4 | task_prompt:
5 | # Task
6 | task: packing_4
7 | instruction: "Put all the objects on the shelf."
8 | objects:
9 | - "object_1"
10 | - "object_2"
11 | - "object_3"
12 | - "object_4"
13 | - "object_5"
14 | - "ground"
15 | - "shelf"
16 | predicates:
17 | - "On(object_1, ground)"
18 | - "On(object_2, ground)"
19 | - "On(object_3, ground)"
20 | - "On(object_4, ground)"
21 | - "On(object_5, ground)"
22 |
23 | # Behaviors
24 | goals: Null
25 | plans: Null
26 | hypotheses: Null
27 | geometric: Null
28 |
29 | # OpenAI
30 | role: user
31 | name: Null
32 | name_query: Null
33 | name_response: Null
34 |
35 | # System prompts
36 | system_prompts:
37 | - LLM/configs/prompts/system/goal_prediction_v1.yaml
38 | - LLM/configs/prompts/system/task_planning_goal_condition_v1.yaml
39 |
40 | # Example prompts
41 | example_prompts:
42 | - LLM/configs/prompts/examples/example_1.yaml
43 | - LLM/configs/prompts/examples/example_2.yaml
44 | - LLM/configs/prompts/examples/example_3.yaml
45 |
46 | # Event prompts
47 | event_prompts: Null
--------------------------------------------------------------------------------
/LLM/configs/prompts/evaluation/p1/retrieval_1_v1.yaml:
--------------------------------------------------------------------------------
1 | prompt: BehaviorPromptManager
2 | prompt_kwargs:
3 | # Task prompt
4 | task_prompt:
5 | # Task
6 | task: retrieval_1_v1
7 | instruction: "Retrieve object_1."
8 | objects:
9 | - "object_1"
10 | - "object_2"
11 | - "object_3"
12 | - "shelf"
13 | - "ground"
14 | predicates:
15 | - "On(object_1, shelf)"
16 | - "On(object_2, shelf)"
17 | - "On(object_3, shelf)"
18 |
19 | # Behaviors
20 | goals: Null
21 | plans: Null
22 | hypotheses: Null
23 | geometric: Null
24 |
25 | # OpenAI
26 | role: user
27 | name: Null
28 | name_query: Null
29 | name_response: Null
30 |
31 | # System prompts
32 | system_prompts:
33 | - LLM/configs/prompts/system/goal_prediction_v2.yaml
34 | - LLM/configs/prompts/system/task_planning_goal_condition_v2.yaml
35 |
36 | # Example prompts
37 | example_prompts:
38 | - LLM/configs/prompts/examples/example_4.yaml
39 | - LLM/configs/prompts/examples/example_5.yaml
40 |
41 | # Event prompts
42 | event_prompts: Null
--------------------------------------------------------------------------------
/LLM/configs/prompts/evaluation/p1/retrieval_1_v2.yaml:
--------------------------------------------------------------------------------
1 | prompt: BehaviorPromptManager
2 | prompt_kwargs:
3 | # Task prompt
4 | task_prompt:
5 | # Task
6 | task: retrieval_1_v2
7 | instruction: "Retrieve object_1."
8 | objects:
9 | - "object_1"
10 | - "object_2"
11 | - "object_3"
12 | - "shelf"
13 | - "ground"
14 | predicates:
15 | - "On(object_1, shelf)"
16 | - "On(object_2, shelf)"
17 | - "On(object_3, shelf)"
18 | - "Blocking(object_2, object_1)"
19 | - "Blocking(object_3, object_1)"
20 | - "Blocking(object_3, object_2)"
21 |
22 | # Behaviors
23 | goals: [["On(object_1, ground)"]]
24 | plans: Null
25 | hypotheses: Null
26 | geometric: Null
27 |
28 | # OpenAI
29 | role: user
30 | name: Null
31 | name_query: Null
32 | name_response: Null
33 |
34 | # System prompts
35 | system_prompts:
36 | - LLM/configs/prompts/system/goal_prediction_v2.yaml
37 | - LLM/configs/prompts/system/task_planning_goal_condition_v2.yaml
38 |
39 | # Example prompts
40 | example_prompts:
41 | - LLM/configs/prompts/examples/example_4.yaml
42 | - LLM/configs/prompts/examples/example_5.yaml
43 |
44 | # Event prompts
45 | event_prompts: Null
--------------------------------------------------------------------------------
/LLM/configs/prompts/evaluation/p1/retrieval_2_v1.yaml:
--------------------------------------------------------------------------------
1 | prompt: BehaviorPromptManager
2 | prompt_kwargs:
3 | # Task prompt
4 | task_prompt:
5 | # Task
6 | task: retrieval_2_v1
7 | instruction: "Retrieve object_1."
8 | objects:
9 | - "object_1"
10 | - "object_2"
11 | - "object_3"
12 | - "object_4"
13 | - "shelf"
14 | - "ground"
15 | predicates:
16 | - "On(object_1, shelf)"
17 | - "On(object_2, shelf)"
18 | - "On(object_3, shelf)"
19 | - "On(object_4, shelf)"
20 |
21 | # Behaviors
22 | goals: Null
23 | plans: Null
24 | hypotheses: Null
25 | geometric: Null
26 |
27 | # OpenAI
28 | role: user
29 | name: Null
30 | name_query: Null
31 | name_response: Null
32 |
33 | # System prompts
34 | system_prompts:
35 | - LLM/configs/prompts/system/goal_prediction_v2.yaml
36 | - LLM/configs/prompts/system/task_planning_goal_condition_v2.yaml
37 |
38 | # Example prompts
39 | example_prompts:
40 | - LLM/configs/prompts/examples/example_4.yaml
41 | - LLM/configs/prompts/examples/example_5.yaml
42 |
43 | # Event prompts
44 | event_prompts: Null
--------------------------------------------------------------------------------
/LLM/configs/prompts/evaluation/p1/retrieval_2_v2.yaml:
--------------------------------------------------------------------------------
1 | prompt: BehaviorPromptManager
2 | prompt_kwargs:
3 | # Task prompt
4 | task_prompt:
5 | # Task
6 | task: retrieval_2_v2
7 | instruction: "Retrieve object_1."
8 | objects:
9 | - "object_1"
10 | - "object_2"
11 | - "object_3"
12 | - "object_4"
13 | - "shelf"
14 | - "ground"
15 | predicates:
16 | - "On(object_1, shelf)"
17 | - "On(object_2, shelf)"
18 | - "On(object_3, shelf)"
19 | - "On(object_4, shelf)"
20 | - "Blocking(object_3, object_4)"
21 | - "Blocking(object_3, object_1)"
22 | - "Blocking(object_2, object_1)"
23 | - "Blocking(object_4, object_1)"
24 |
25 | # Behaviors
26 | goals: [["On(object_1, ground)"]]
27 | plans: Null
28 | hypotheses: Null
29 | geometric: Null
30 |
31 | # OpenAI
32 | role: user
33 | name: Null
34 | name_query: Null
35 | name_response: Null
36 |
37 | # System prompts
38 | system_prompts:
39 | - LLM/configs/prompts/system/goal_prediction_v2.yaml
40 | - LLM/configs/prompts/system/task_planning_goal_condition_v2.yaml
41 |
42 | # Example prompts
43 | example_prompts:
44 | - LLM/configs/prompts/examples/example_4.yaml
45 | - LLM/configs/prompts/examples/example_5.yaml
46 |
47 | # Event prompts
48 | event_prompts: Null
--------------------------------------------------------------------------------
/LLM/configs/prompts/evaluation/p1/retrieval_3_v1.yaml:
--------------------------------------------------------------------------------
1 | prompt: BehaviorPromptManager
2 | prompt_kwargs:
3 | # Task prompt
4 | task_prompt:
5 | # Task
6 | task: retrieval_3_v1
7 | instruction: "Retrieve object_1."
8 | objects:
9 | - "object_1"
10 | - "object_2"
11 | - "object_3"
12 | - "object_4"
13 | - "object_5"
14 | - "shelf"
15 | - "ground"
16 | predicates:
17 | - "On(object_1, shelf)"
18 | - "On(object_2, shelf)"
19 | - "On(object_3, shelf)"
20 | - "On(object_4, shelf)"
21 | - "On(object_5, shelf)"
22 |
23 | # Behaviors
24 | goals: Null
25 | plans: Null
26 | hypotheses: Null
27 | geometric: Null
28 |
29 | # OpenAI
30 | role: user
31 | name: Null
32 | name_query: Null
33 | name_response: Null
34 |
35 | # System prompts
36 | system_prompts:
37 | - LLM/configs/prompts/system/goal_prediction_v2.yaml
38 | - LLM/configs/prompts/system/task_planning_goal_condition_v2.yaml
39 |
40 | # Example prompts
41 | example_prompts:
42 | - LLM/configs/prompts/examples/example_4.yaml
43 | - LLM/configs/prompts/examples/example_5.yaml
44 |
45 | # Event prompts
46 | event_prompts: Null
--------------------------------------------------------------------------------
/LLM/configs/prompts/evaluation/p1/retrieval_3_v2.yaml:
--------------------------------------------------------------------------------
1 | prompt: BehaviorPromptManager
2 | prompt_kwargs:
3 | # Task prompt
4 | task_prompt:
5 | # Task
6 | task: retrieval_3_v2
7 | instruction: |
8 | "Retrieve object_1 and put it on the ground.
9 |
10 | Remember to pay close attention to the 'Blocking' predicates, which indicate
11 | what objects are preventing other objects from being accessible by the robot.
12 | For example, Blocking(object_1, object_2) means that object_1 is blocking object_2;
13 | hence, object_1 can be retrieved directly. However, in the following case, object_1
14 | might be blocked by other objects as well.
15 |
16 | Rule: Restrict your output to the format in the examples."
17 | objects:
18 | - "object_1"
19 | - "object_2"
20 | - "object_3"
21 | - "object_4"
22 | - "object_5"
23 | - "shelf"
24 | - "ground"
25 | predicates:
26 | - "On(object_1, shelf)"
27 | - "On(object_2, shelf)"
28 | - "On(object_3, shelf)"
29 | - "On(object_4, shelf)"
30 | - "On(object_5, shelf)"
31 | - "Blocking(object_3, object_4)"
32 | - "Blocking(object_2, object_5)"
33 | - "Blocking(object_3, object_1)"
34 | - "Blocking(object_2, object_1)"
35 | - "Blocking(object_5, object_1)"
36 | - "Blocking(object_4, object_1)"
37 |
38 | # Behaviors
39 | goals: [["On(object_1, ground)"]]
40 | plans: Null
41 | hypotheses: Null
42 | geometric: Null
43 |
44 | # OpenAI
45 | role: user
46 | name: Null
47 | name_query: Null
48 | name_response: Null
49 |
50 | # System prompts
51 | system_prompts:
52 | - LLM/configs/prompts/system/goal_prediction_v2.yaml
53 | - LLM/configs/prompts/system/task_planning_goal_condition_v2.yaml
54 |
55 | # Example prompts
56 | example_prompts:
57 | - LLM/configs/prompts/examples/example_4.yaml
58 | - LLM/configs/prompts/examples/example_5.yaml
59 |
60 | # Event prompts
61 | event_prompts: Null
--------------------------------------------------------------------------------
/LLM/configs/prompts/evaluation/p1/retrieval_4_v1.yaml:
--------------------------------------------------------------------------------
1 | prompt: BehaviorPromptManager
2 | prompt_kwargs:
3 | # Task prompt
4 | task_prompt:
5 | # Task
6 | task: retrieval_4_v1
7 | instruction: "Retrieve object_1 and place it on the shelf."
8 | objects:
9 | - "object_1"
10 | - "object_2"
11 | - "shelf"
12 | - "ground"
13 | predicates:
14 | - "Inside(object_1, object_2)"
15 | - "On(object_2, shelf)"
16 |
17 | # Behaviors
18 | goals: Null
19 | plans: Null
20 | hypotheses: Null
21 | geometric: Null
22 |
23 | # OpenAI
24 | role: user
25 | name: Null
26 | name_query: Null
27 | name_response: Null
28 |
29 | # System prompts
30 | system_prompts:
31 | - LLM/configs/prompts/system/goal_prediction_v2.yaml
32 | - LLM/configs/prompts/system/task_planning_goal_condition_v2.yaml
33 |
34 | # Example prompts
35 | example_prompts:
36 | - LLM/configs/prompts/examples/example_4.yaml
37 | - LLM/configs/prompts/examples/example_5.yaml
38 | - LLM/configs/prompts/examples/example_6.yaml
39 |
40 | # Event prompts
41 | event_prompts: Null
--------------------------------------------------------------------------------
/LLM/configs/prompts/evaluation/p1/retrieval_4_v2.yaml:
--------------------------------------------------------------------------------
1 | prompt: BehaviorPromptManager
2 | prompt_kwargs:
3 | # Task prompt
4 | task_prompt:
5 | # Task
6 | task: retrieval_4_v2
7 | instruction: "Retrieve object_1 and place it on the shelf."
8 | objects:
9 | - "object_1"
10 | - "object_2"
11 | - "shelf"
12 | - "ground"
13 | predicates:
14 | - "Inside(object_1, object_2)"
15 | - "On(object_2, shelf)"
16 | - "Blocking(object_2, object_1)"
17 |
18 | # Behaviors
19 | goals: Null
20 | plans: Null
21 | hypotheses: Null
22 | geometric: Null
23 |
24 | # OpenAI
25 | role: user
26 | name: Null
27 | name_query: Null
28 | name_response: Null
29 |
30 | # System prompts
31 | system_prompts:
32 | - LLM/configs/prompts/system/goal_prediction_v2.yaml
33 | - LLM/configs/prompts/system/task_planning_goal_condition_v2.yaml
34 |
35 | # Example prompts
36 | example_prompts:
37 | - LLM/configs/prompts/examples/example_4.yaml
38 | - LLM/configs/prompts/examples/example_5.yaml
39 | - LLM/configs/prompts/examples/example_6.yaml
40 |
41 | # Event prompts
42 | event_prompts: Null
--------------------------------------------------------------------------------
/LLM/configs/prompts/evaluation/p1/retrieval_5_v2.yaml:
--------------------------------------------------------------------------------
1 | prompt: BehaviorPromptManager
2 | prompt_kwargs:
3 | # Task prompt
4 | task_prompt:
5 | # Task
6 | task: retrieval_5_v2
7 | instruction: "Retrieve object_1 and place it on the shelf."
8 | objects:
9 | - "object_1"
10 | - "object_2"
11 | - "object_3"
12 | - "shelf"
13 | - "ground"
14 | predicates:
15 | - "Inside(object_1, object_2)"
16 | - "On(object_2, shelf)"
17 | - "Blocking(object_2, object_1)"
18 | - "Blocking(object_3, object_2)"
19 | - "Blocking(object_3, object_1)"
20 | - "On(object_3, shelf)"
21 |
22 | # Behaviors
23 | goals: Null
24 | plans: Null
25 | hypotheses: Null
26 | geometric: Null
27 |
28 | # OpenAI
29 | role: user
30 | name: Null
31 | name_query: Null
32 | name_response: Null
33 |
34 | # System prompts
35 | system_prompts:
36 | - LLM/configs/prompts/system/goal_prediction_v2.yaml
37 | - LLM/configs/prompts/system/task_planning_goal_condition_v2.yaml
38 |
39 | # Example prompts
40 | example_prompts:
41 | - LLM/configs/prompts/examples/example_4.yaml
42 | - LLM/configs/prompts/examples/example_5.yaml
43 | - LLM/configs/prompts/examples/example_6.yaml
44 |
45 | # Event prompts
46 | event_prompts: Null
--------------------------------------------------------------------------------
/LLM/configs/prompts/evaluation/p1/retrieval_5_v3.yaml:
--------------------------------------------------------------------------------
1 | prompt: BehaviorPromptManager
2 | prompt_kwargs:
3 | # Task prompt
4 | task_prompt:
5 | # Task
6 | task: retrieval_5_v3
7 | instruction: "Retrieve object_1 and place it on the sofa."
8 | objects:
9 | - "object_1"
10 | - "object_2"
11 | - "object_3"
12 | - "shelf"
13 | - "ground"
14 | - "sofa"
15 | predicates:
16 | - "Inside(object_1, object_2)"
17 | - "On(object_2, shelf)"
18 | - "Blocking(object_2, object_1)"
19 | - "Blocking(object_3, object_2)"
20 | - "Blocking(object_3, object_1)"
21 | - "On(object_3, shelf)"
22 |
23 | # Behaviors
24 | goals: Null
25 | plans: Null
26 | hypotheses: Null
27 | geometric: Null
28 |
29 | # OpenAI
30 | role: user
31 | name: Null
32 | name_query: Null
33 | name_response: Null
34 |
35 | # System prompts
36 | system_prompts:
37 | - LLM/configs/prompts/system/goal_prediction_v2.yaml
38 | - LLM/configs/prompts/system/task_planning_goal_condition_v2.yaml
39 |
40 | # Example prompts
41 | example_prompts:
42 | - LLM/configs/prompts/examples/example_4.yaml
43 | - LLM/configs/prompts/examples/example_5.yaml
44 | - LLM/configs/prompts/examples/example_6.yaml
45 |
46 | # Event prompts
47 | event_prompts: Null
--------------------------------------------------------------------------------
/LLM/configs/prompts/examples/example_1.yaml:
--------------------------------------------------------------------------------
1 | # Task
2 | task: example_1
3 | instruction: "Put object_1 on the sink."
4 | objects:
5 | - "object_1"
6 | - "sink"
7 | - "kitchen_table"
8 | predicates:
9 | - "On(object_1, kitchen_table)"
10 |
11 | # Behaviors
12 | goals: [["On(object_1, sink)"]]
13 | plans: [["Pick(object_1, kitchen_table)", "Place(object_1, sink)"]]
14 | hypotheses: Null
15 | geometric: Null
16 |
17 | # OpenAI
18 | role: system
19 | name: Null
20 | name_query: example_user
21 | name_response: example_assistant
--------------------------------------------------------------------------------
/LLM/configs/prompts/examples/example_2.yaml:
--------------------------------------------------------------------------------
1 | # Task
2 | task: example_2
3 | instruction: "Get me object_1 from the drawer. I'm in the bedroom. Don't leave the drawer open."
4 | objects:
5 | - "object_1"
6 | - "object_2"
7 | - "drawer"
8 | - "closet"
9 | - "bed"
10 | predicates:
11 | - "Inside(object_1, drawer)"
12 | - "Inside(object_2, closet)"
13 | - "Closed(drawer)"
14 | - "Closed(closet)"
15 |
16 | # Behaviors
17 | goals: [["On(object_1, bed)", "Closed(drawer)"]]
18 | plans: [["Open(drawer)", "Pick(object_1, drawer)", "Place(object_1, bed)", "Close(drawer)"]]
19 | hypotheses: Null
20 | geometric: Null
21 |
22 | # OpenAI
23 | role: system
24 | name: Null
25 | name_query: example_user
26 | name_response: example_assistant
--------------------------------------------------------------------------------
/LLM/configs/prompts/examples/example_3.yaml:
--------------------------------------------------------------------------------
1 | # Task
2 | task: example_3
3 | instruction: "Bring me object_2. I'm sitting on the reading_chair by the coffee_table."
4 | objects:
5 | - "object_1"
6 | - "object_2"
7 | - "bookshelf"
8 | - "reading_chair"
9 | - "coffee_table"
10 | predicates:
11 | - "On(object_1, object_2)"
12 | - "On(object_2, bookshelf)"
13 |
14 | # Behaviors
15 | goals: [
16 | ["On(object_2, coffee_table)"],
17 | ["On(object_2, reading_chair)"]
18 | ]
19 | plans: [
20 | ["Pick(object_1, object_2)", "Place(object_1, bookshelf)", "Pick(object_2, bookshelf)", "Place(object_2, coffee_table)"],
21 | ["Pick(object_1, object_2)", "Place(object_1, bookshelf)", "Pick(object_2, bookshelf)", "Place(object_2, reading_chair)"]
22 | ]
23 | hypotheses: Null
24 | geometric: Null
25 |
26 | # OpenAI
27 | role: system
28 | name: Null
29 | name_query: example_user
30 | name_response: example_assistant
--------------------------------------------------------------------------------
/LLM/configs/prompts/examples/example_4.yaml:
--------------------------------------------------------------------------------
1 | # Task
2 | task: example_4
3 | instruction: "Please retrieve object_1."
4 | objects:
5 | - "object_1"
6 | - "object_2"
7 | - "shelf"
8 | - "ground"
9 | predicates:
10 | - "On(object_1, shelf)"
11 | - "On(object_2, shelf)"
12 |
13 | # Behaviors
14 | goals: [
15 | ["On(object_1, ground)"],
16 | ["On(object_2, ground)", "On(object_1, ground)"],
17 | ]
18 | plans: [
19 | ["Pick(object_1, shelf)", "Place(object_1, ground)"],
20 | ["Pick(object_2, shelf)", "Place(object_2, ground)", "Pick(object_1, shelf)", "Place(object_1, ground)"],
21 | ]
22 | hypotheses: Null
23 | geometric: Null
24 |
25 | # OpenAI
26 | role: system
27 | name: Null
28 | name_query: example_user
29 | name_response: example_assistant
--------------------------------------------------------------------------------
/LLM/configs/prompts/examples/example_5.yaml:
--------------------------------------------------------------------------------
1 | # Task
2 | task: example_5
3 | instruction: "Please retrieve object_1."
4 | objects:
5 | - "object_1"
6 | - "object_2"
7 | - "shelf"
8 | - "ground"
9 | predicates:
10 | - "On(object_1, shelf)"
11 | - "On(object_2, shelf)"
12 | - "Blocking(object_2, object_1)"
13 |
14 | # Behaviors
15 | goals: [
16 | ["On(object_2, ground)", "On(object_1, ground)"],
17 | ]
18 | plans: [
19 | ["Pick(object_2, shelf)", "Place(object_2, ground)", "Pick(object_1, shelf)", "Place(object_1, ground)"],
20 | ]
21 | hypotheses: Null
22 | geometric: Null
23 |
24 | # OpenAI
25 | role: system
26 | name: Null
27 | name_query: example_user
28 | name_response: example_assistant
--------------------------------------------------------------------------------
/LLM/configs/prompts/examples/example_6.yaml:
--------------------------------------------------------------------------------
1 | # Task
2 | task: example_6
3 | instruction: "Please retrieve object_1."
4 | objects:
5 | - "object_1"
6 | - "box"
7 | - "ground"
8 | predicates:
9 | - "Inside(object_1, box)"
10 | - "On(box, ground)"
11 |
12 | # Behaviors
13 | goals: [
14 | ["On(object_1, ground)"]
15 | ]
16 | plans: [
17 | ["Pick(object_1, box)", "Place(object_1, ground)"]
18 | ]
19 | hypotheses: Null
20 | geometric: Null
21 |
22 | # OpenAI
23 | role: system
24 | name: Null
25 | name_query: example_user
26 | name_response: example_assistant
--------------------------------------------------------------------------------
/LLM/configs/prompts/system/geomtric_reasoning_v1.yaml:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yixuanhuang98/Points2Plans/78c0b0f0a23d2a352022584d369398741c553772/LLM/configs/prompts/system/geomtric_reasoning_v1.yaml
--------------------------------------------------------------------------------
/LLM/configs/prompts/system/goal_prediction_v1.yaml:
--------------------------------------------------------------------------------
1 | behavior: goal_prediction
2 | behavior_kwargs: Null
3 |
4 | role: system
5 | name: Null
6 | content:
7 | "I am the reasoning system of a mobile manipulator robot operating in a household environment.
8 | Given 1) an instruction from a human user and 2) the current symbolic state of the environment, I will
9 | predict a set of possible symbolic goals that the robot could achieve to fulfill the user's instruction.\n
10 |
11 | Definitions:\n
12 | - Symbolic states and symbolic goals are defined as a set of predicates expressed over specific objects.\n
13 | - The term 'predicate' refers to an object state (e.g., Opened(cabinet)) or a relationship among objects (e.g., On(cup, shelf)).\n
14 |
15 | The robot can perceive the following information about the environment:\n
16 | - The objects in the environment\n
17 | - The states of individual objects\n
18 | - The relationships among objects\n
19 |
20 | The robot can detect the following states of individual objects:\n
21 | - Opened(a): Object a is opened\n
22 | - Closed(a): Object a is closed\n
23 |
24 | The robot can detect the following relationships among objects:\n
25 | - On(a, b): Object a is on object b\n
26 | - Inside(a, b): Object a is in object b\n
27 |
28 | There may be multiple symbolic goals that fulfill the user's instruction.
29 | Therefore, I will format my output in the following form:\n
30 |
31 | Goals: List[List[str]]\n
32 |
33 | Rules:\n
34 | - I will output a set of symbolic goals as a list of lists after 'Goals:'. Each nested list represents one goal\n
35 | - I will not output all possible symbolic goals, but the most likely goals that fulfill the user's instruction\n
36 | - If there are multiple symbolic goals that fulfill the instruction, I will output the simplest goals first"
--------------------------------------------------------------------------------
/LLM/configs/prompts/system/goal_prediction_v2.yaml:
--------------------------------------------------------------------------------
1 | behavior: goal_prediction
2 | behavior_kwargs: Null
3 |
4 | role: system
5 | name: Null
6 | content:
7 | "I am the reasoning system of a mobile manipulator robot operating in a household environment.
8 | Given 1) an instruction from a human user and 2) the current symbolic state of the environment, I will
9 | predict a set of possible symbolic goals that the robot could achieve to fulfill the user's instruction.\n
10 |
11 | Definitions:\n
12 | - Symbolic states and symbolic goals are defined as a set of predicates expressed over specific objects.\n
13 | - The term 'predicate' refers to an object state (e.g., Opened(cabinet)) or a relationship among objects (e.g., On(cup, shelf)).\n
14 |
15 | The robot can perceive the following information about the environment:\n
16 | - The objects in the environment\n
17 | - The states of individual objects\n
18 | - The relationships among objects\n
19 |
20 | The robot can detect the following states of individual objects:\n
21 | - Opened(a): Object a is opened\n
22 | - Closed(a): Object a is closed\n
23 |
24 | The robot can detect the following relationships among objects:\n
25 | - On(a, b): Object a is on object b\n
26 | - Inside(a, b): Object a is in object b\n
27 | - Blocking(a, b): Object a is blocking object b\n
28 |
29 | There may be multiple symbolic goals that fulfill the user's instruction.
30 | Therefore, I will format my output in the following form:\n
31 |
32 | Goals: List[List[str]]\n
33 |
34 | Rules:\n
35 | - I will output a set of symbolic goals as a list of lists after 'Goals:'. Each nested list represents one goal\n
36 | - I will not output all possible symbolic goals, but the most likely goals that fulfill the user's instruction\n
37 | - If there are multiple symbolic goals that fulfill the instruction, I will output the simplest goals first"
--------------------------------------------------------------------------------
/LLM/configs/prompts/system/hypothesis_generation_v1.yaml:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yixuanhuang98/Points2Plans/78c0b0f0a23d2a352022584d369398741c553772/LLM/configs/prompts/system/hypothesis_generation_v1.yaml
--------------------------------------------------------------------------------
/LLM/configs/prompts/system/task_planning_goal_condition_v1.yaml:
--------------------------------------------------------------------------------
1 | behavior: task_planning
2 | behavior_kwargs:
3 | goal_condition: True
4 |
5 | role: system
6 | name: Null
7 | content:
8 | "I am the task planning system of a mobile manipulator robot operating in a household environment.
9 | Given 1) an instruction from a human user, 2) the current symbolic state of the environment, and 3)
10 | a set of possible symbolic goals that the robot could achieve to fulfill the user's instruction, I will
11 | predict a set of task plans that the robot should execute to satisfy the symbolic goals.\n
12 |
13 | Definitions:\n
14 | - Symbolic states and symbolic goals are defined as a set of predicates expressed over specific objects.\n
15 | - The term 'predicate' refers to an object state (e.g., Opened(cabinet)) or a relationship among objects (e.g., On(cup, shelf)).\n
16 | - A task plan is a sequence of actions that the robot can execute (e.g., Pick(cup, table), Place(cup, shelf))\n
17 |
18 | The robot can perceive the following information about the environment:\n
19 | - The objects in the environment\n
20 | - The states of individual objects\n
21 | - The relationships among objects\n
22 |
23 | The robot can detect the following states of individual objects:\n
24 | - Opened(a): Object a is opened\n
25 | - Closed(a): Object a is closed\n
26 |
27 | The robot can detect the following relationships among objects:\n
28 | - On(a, b): Object a is on object b\n
29 | - Inside(a, b): Object a is in object b\n
30 |
31 | The robot can execute the following actions:\n
32 | - Pick(a, b): The robot picks object a from object b\n
33 | - Place(a, b): The robot places object a on or in object b\n
34 | - Open(a): The robot opens object a\n
35 | - Close(a): The robot closes object a\n
36 |
37 | Action preconditions:\n
38 | - If the robot is already holding an object, it CANNOT Pick, Open, or Close another object\n
39 | - The robot CAN ONLY Place an object that it is already holding\n
40 |
41 | There may be multiple symbolic goals that fulfill the user's instruction.
42 | Therefore, I will format my output in the following form:\n
43 |
44 | Plans: List[List[str]]\n
45 |
46 | Rules:\n
47 | - I will output a set of task plans as a list of lists after 'Plans:'. Each nested list represents one task plan\n
48 | - I will output one task plan for each symbolic goal. Hence, each goal and its corresponding plan will be located
49 | at the same index in the 'Goals' and 'Plans' lists\n
50 | - I will only output task plans that are feasible with respect to the defined action preconditions."
51 |
--------------------------------------------------------------------------------
/LLM/configs/prompts/system/task_planning_goal_condition_v2.yaml:
--------------------------------------------------------------------------------
1 | behavior: task_planning
2 | behavior_kwargs:
3 | goal_condition: True
4 |
5 | role: system
6 | name: Null
7 | content:
8 | "I am the task planning system of a mobile manipulator robot operating in a household environment.
9 | Given 1) an instruction from a human user, 2) the current symbolic state of the environment, and 3)
10 | a set of possible symbolic goals that the robot could achieve to fulfill the user's instruction, I will
11 | predict a set of task plans that the robot should execute to satisfy the symbolic goals.\n
12 |
13 | Definitions:\n
14 | - Symbolic states and symbolic goals are defined as a set of predicates expressed over specific objects.\n
15 | - The term 'predicate' refers to an object state (e.g., Opened(cabinet)) or a relationship among objects (e.g., On(cup, shelf)).\n
16 | - A task plan is a sequence of actions that the robot can execute (e.g., Pick(cup, table), Place(cup, shelf))\n
17 |
18 | The robot can perceive the following information about the environment:\n
19 | - The objects in the environment\n
20 | - The states of individual objects\n
21 | - The relationships among objects\n
22 |
23 | The robot can detect the following states of individual objects:\n
24 | - Opened(a): Object a is opened\n
25 | - Closed(a): Object a is closed\n
26 |
27 | The robot can detect the following relationships among objects:\n
28 | - On(a, b): Object a is on object b\n
29 | - Inside(a, b): Object a is in object b\n
30 | - Blocking(a, b): Object a is blocking object b\n
31 |
32 | The robot can execute the following actions:\n
33 | - Pick(a, b): The robot picks object a from object b\n
34 | - Place(a, b): The robot places object a on or in object b\n
35 | - Open(a): The robot opens object a\n
36 | - Close(a): The robot closes object a\n
37 |
38 | Action preconditions:\n
39 | - If the robot is already holding an object, it CANNOT Pick, Open, or Close another object\n
40 | - The robot CAN ONLY Place an object that it is already holding\n
41 | - The robot CANNOT Pick an object if it is blocked by another object\n
42 |
43 | There may be multiple symbolic goals that fulfill the user's instruction.
44 | Therefore, I will format my output in the following form:\n
45 |
46 | Plans: List[List[str]]\n
47 |
48 | Rules:\n
49 | - I will output a set of task plans as a list of lists after 'Plans:'. Each nested list represents one task plan\n
50 | - I will output one task plan for each symbolic goal. Hence, each goal and its corresponding plan will be located
51 | at the same index in the 'Goals' and 'Plans' lists\n
52 | - I will only output task plans that are feasible with respect to the defined action preconditions."
53 |
--------------------------------------------------------------------------------
/LLM/configs/prompts/system/task_planning_hypothesis_condition_v1.yaml:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yixuanhuang98/Points2Plans/78c0b0f0a23d2a352022584d369398741c553772/LLM/configs/prompts/system/task_planning_hypothesis_condition_v1.yaml
--------------------------------------------------------------------------------
/LLM/configs/prompts/system/task_planning_v1.yaml:
--------------------------------------------------------------------------------
1 | behavior: task_planning
2 | behavior_kwargs: Null
3 |
4 | role: system
5 | name: Null
6 | content:
7 | "I am the task planning system of a mobile manipulator robot operating in a household environment.
8 | Given 1) an instruction from a human user and 2) the current symbolic state of the environment, I will
9 | predict a set of possible task plans that the robot could execute to fulfill the user's instruction.\n
10 |
11 | Definitions:\n
12 | - Symbolic states and symbolic goals are defined as a set of predicates expressed over specific objects.\n
13 | - The term 'predicate' refers to an object state (e.g., Opened(cabinet)) or a relationship among objects (e.g., On(cup, shelf)).\n
14 | - A task plan is a sequence of actions that the robot can execute (e.g., Pick(cup, table), Place(cup, shelf))\n
15 |
16 | The robot can perceive the following information about the environment:\n
17 | - The objects in the environment\n
18 | - The states of individual objects\n
19 | - The relationships among objects\n
20 |
21 | The robot can detect the following states of individual objects:\n
22 | - Opened(a): Object a is opened\n
23 | - Closed(a): Object a is closed\n
24 |
25 | The robot can detect the following relationships among objects:\n
26 | - On(a, b): Object a is on object b\n
27 | - Inside(a, b): Object a is in object b\n
28 |
29 | The robot can execute the following actions:\n
30 | - Pick(a, b): The robot picks object a from object b\n
31 | - Place(a, b): The robot places object a on or in object b\n
32 | - Open(a): The robot opens object a\n
33 | - Close(a): The robot closes object a\n
34 |
35 | Action preconditions:\n
36 | - If the robot is already holding an object, it CANNOT Pick, Open, or Close another object\n
37 | - The robot CAN ONLY Place an object that it is already holding\n
38 |
39 | There may be multiple task plans that fulfill the user's instruction.
40 | Therefore, I will format my output in the following form:\n
41 |
42 | Plans: List[List[str]]\n
43 |
44 | Rules:\n
45 | - I will output a set of task plans as a list of lists after 'Plans:'. Each nested list represents one task plan\n
46 | - I will not output all possible task plans, but the most likely plans that fulfill the user's instruction\n
47 | - If there are multiple task plans that fulfill the instruction, I will output the simplest plans first\n
48 | - I will only output task plans that are feasible with respect to the defined action preconditions."
49 |
--------------------------------------------------------------------------------
/LLM/fm_planning/__init__.py:
--------------------------------------------------------------------------------
1 | from . import models
2 | from . import utils
3 |
--------------------------------------------------------------------------------
/LLM/fm_planning/fm_agents/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yixuanhuang98/Points2Plans/78c0b0f0a23d2a352022584d369398741c553772/LLM/fm_planning/fm_agents/__init__.py
--------------------------------------------------------------------------------
/LLM/fm_planning/fm_agents/base.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yixuanhuang98/Points2Plans/78c0b0f0a23d2a352022584d369398741c553772/LLM/fm_planning/fm_agents/base.py
--------------------------------------------------------------------------------
/LLM/fm_planning/fm_agents/utils.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yixuanhuang98/Points2Plans/78c0b0f0a23d2a352022584d369398741c553772/LLM/fm_planning/fm_agents/utils.py
--------------------------------------------------------------------------------
/LLM/fm_planning/models/__init__.py:
--------------------------------------------------------------------------------
1 | from .pretrained import *
2 |
--------------------------------------------------------------------------------
/LLM/fm_planning/models/pretrained/__init__.py:
--------------------------------------------------------------------------------
1 | from .base import PretrainedModel
2 | from .generative import *
3 | from .embeddings import *
4 | from .utils import *
5 |
--------------------------------------------------------------------------------
/LLM/fm_planning/models/pretrained/base.py:
--------------------------------------------------------------------------------
1 | from typing import Generic, Any, TypeVar
2 |
3 | import abc
4 |
5 | from LLM.fm_planning.utils.typing import ModelBatchType
6 |
7 |
8 | class PretrainedModel(abc.ABC, Generic[ModelBatchType]):
9 | """Abstract base class for pretrained models."""
10 |
11 | @abc.abstractmethod
12 | def forward(self, x: ModelBatchType) -> Any:
13 | """Compute forward pass."""
14 | pass
15 |
16 |
17 | PretrainedModelType = TypeVar("PretrainedModelType", bound=PretrainedModel)
18 |
--------------------------------------------------------------------------------
/LLM/fm_planning/models/pretrained/embeddings/__init__.py:
--------------------------------------------------------------------------------
1 | from .openai_emb import OpenAIEmbeddingModel
2 |
--------------------------------------------------------------------------------
/LLM/fm_planning/models/pretrained/embeddings/hugging_face_emb.py:
--------------------------------------------------------------------------------
1 | from typing import Any
2 |
3 | import torch
4 | import torch.nn.functional as F
5 |
6 | from transformers import AutoTokenizer, AutoModel # type: ignore
7 |
8 | from LLM.fm_planning.utils import typing, tensors
9 | from LLM.fm_planning.models.pretrained.base import PretrainedModel
10 | from .utils import mean_pooling
11 |
12 |
13 | class HuggingFaceEmbeddingModel(PretrainedModel[str]):
14 | def __init__(self, model: str, device: str = "auto", **kwargs: Any):
15 | super().__init__()
16 | self._model_name = model
17 | self._device = tensors.device(device)
18 | self._model = AutoModel.from_pretrained(model).to(self._device)
19 | self._tokenizer = AutoTokenizer.from_pretrained(model, use_fast=True)
20 |
21 | @torch.no_grad()
22 | def forward(self, x: str) -> typing.Tensor:
23 | """Compute embeddings for a prompt."""
24 |
25 | # BERT models.
26 | if self._model_name in ["bert-base-uncased", "bert-large-uncased"]:
27 | encoded_input = self._tokenizer(x, return_tensors="pt").to(self._device)
28 | output = self._model(**encoded_input)
29 | embedding = output[1]
30 |
31 | # MPNet model.
32 | elif self._model_name == "sentence-transformers/all-mpnet-base-v2":
33 | encoded_input = self._tokenizer(
34 | x, padding=True, truncation=True, return_tensors="pt"
35 | ).to(self._device)
36 | output = self._model(**encoded_input)
37 | embedding = mean_pooling(output, encoded_input["attention_mask"])
38 |
39 | # Mistral (7B) model.
40 | elif self._model_name == "intfloat/e5-mistral-7b-instruct":
41 | encoded_input = self._tokenizer(
42 | [x], return_attention_mask=False, padding=False, truncation=True
43 | )
44 | encoded_input["input_ids"][0] += [self._tokenizer.eos_token_id]
45 | encoded_input = self._tokenizer.pad(
46 | encoded_input,
47 | padding=True,
48 | return_attention_mask=True,
49 | return_tensors="pt",
50 | ).to(self._device)
51 | output = self._model(**encoded_input)
52 | embedding = output.last_hidden_state[:, -1, :]
53 |
54 | # Llama 2 (7B) models.
55 | elif self._model_name in [
56 | "meta-llama/Llama-2-7b-hf",
57 | "meta-llama/Llama-2-7b-chat-hf",
58 | ]:
59 | encoded_input = self._tokenizer(x, return_tensors="pt").to(self._device)
60 | output = self._model(**encoded_input)
61 | embedding = mean_pooling(output, encoded_input["attention_mask"])
62 |
63 | embedding = embedding.squeeze()
64 | embedding = F.normalize(embedding, dim=0).cpu().numpy()
65 | return embedding
66 |
--------------------------------------------------------------------------------
/LLM/fm_planning/models/pretrained/embeddings/openai_emb.py:
--------------------------------------------------------------------------------
1 | from typing import Optional, List, Any
2 |
3 | import os
4 | import time
5 | import openai
6 | from openai.types.embedding import Embedding
7 |
8 | from LLM.fm_planning.models.pretrained.base import PretrainedModel
9 |
10 |
11 | class OpenAIEmbeddingModel(PretrainedModel[List[str]]):
12 | def __init__(self, model: str, api_key: Optional[str] = None, **kwargs: Any):
13 | super().__init__()
14 | self._model = model
15 | self._api_key = (
16 | api_key if api_key is not None else os.environ.get("OPENAI_API_KEY")
17 | )
18 | if api_key is None:
19 | raise ValueError("API key must be provided.")
20 | self._api_key = api_key
21 | self._client = openai.OpenAI(api_key=self._api_key)
22 |
23 | def forward(self, x: List[str]) -> List[Embedding]:
24 | """Compute embeddings for a prompt."""
25 | success = False
26 | while not success:
27 | try:
28 | response = self._client.embeddings.create(input=x, model=self._model)
29 | success = True
30 | except:
31 | time.sleep(1)
32 | continue
33 |
34 | embeddings = [embedding for embedding in response.data]
35 | return embeddings
36 |
--------------------------------------------------------------------------------
/LLM/fm_planning/models/pretrained/embeddings/utils.py:
--------------------------------------------------------------------------------
1 | import torch
2 |
3 |
4 | def mean_pooling(model_output, attention_mask: torch.Tensor) -> torch.Tensor:
5 | """Perform mean pooling on the model output.
6 |
7 | Args:
8 | model_output: Output from the HuggingFace model.
9 | attention_mask (torch.Tensor): Attention mask tensor.
10 |
11 | Returns:
12 | torch.Tensor: Mean pooled tensor.
13 | """
14 | token_embeddings = model_output[0]
15 | input_mask_expanded = (
16 | attention_mask.unsqueeze(-1).expand(token_embeddings.size()).float()
17 | )
18 | mean_pool = torch.sum(token_embeddings * input_mask_expanded, 1) / torch.clamp(
19 | input_mask_expanded.sum(1), min=1e-9
20 | )
21 | return mean_pool
22 |
--------------------------------------------------------------------------------
/LLM/fm_planning/models/pretrained/generative/__init__.py:
--------------------------------------------------------------------------------
1 | from .openai_gen import OpenAIGenerativeModel
2 | from .utils import BehaviorPromptManager
3 |
--------------------------------------------------------------------------------
/LLM/fm_planning/models/pretrained/generative/llama_gen.py:
--------------------------------------------------------------------------------
1 | from typing import Dict, Any
2 |
3 | import torch
4 |
5 | from transformers import AutoModelForCausalLM, AutoTokenizer # type: ignore
6 |
7 | from LLM.fm_planning.models.pretrained.base import PretrainedModel
8 |
9 |
10 | class LlamaGenerativeModel(PretrainedModel[str]):
11 | """Llama generative model."""
12 |
13 | def __init__(self, model: str, device: str = "auto", **kwargs: Any):
14 | """Construct Llama generative model."""
15 | super().__init__()
16 | self._tokenizer = AutoTokenizer.from_pretrained(model, use_fast=True)
17 | self._model = AutoModelForCausalLM.from_pretrained(
18 | pretrained_model_name_or_path=model,
19 | torch_dtype=torch.float16,
20 | device_map=device,
21 | **kwargs,
22 | )
23 | self.device: torch.device = self._model.device
24 |
25 | def forward(self, x: str) -> str:
26 | """Compute completion for a prompt."""
27 | # Send request.
28 | input_ids: torch.Tensor = self._tokenizer.encode(
29 | x, add_special_tokens=True, return_tensors="pt"
30 | )
31 | response_ids = self._model.generate(input_ids.to(self.device))[0]
32 | response = self._tokenizer.decode(
33 | response_ids[input_ids.shape[-1] :], skip_special_tokens=True
34 | )
35 |
36 | return response
37 |
--------------------------------------------------------------------------------
/LLM/fm_planning/models/pretrained/generative/openai_gen.py:
--------------------------------------------------------------------------------
1 | from typing import Any, Optional, List, Dict
2 |
3 | import os
4 | import time
5 | import openai
6 | from openai.types.chat.chat_completion import ChatCompletion
7 |
8 | from LLM.fm_planning.models.pretrained.base import PretrainedModel
9 |
10 |
11 | class OpenAIGenerativeModel(PretrainedModel[List[Dict[str, Any]]]):
12 | """OpenAI generative model."""
13 |
14 | def __init__(self, model: str, api_key: Optional[str] = None, **kwargs: Any):
15 | """Construct OpenAI generative model."""
16 | super().__init__()
17 | self._model = model
18 | self._api_key = (
19 | api_key if api_key is not None else os.environ.get("OPENAI_API_KEY")
20 | )
21 | if api_key is None:
22 | raise ValueError("API key must be provided.")
23 | self._api_key = api_key
24 | self._client = openai.OpenAI(api_key=self._api_key)
25 | self._kwargs = kwargs
26 |
27 | def forward(self, x: List[Dict[str, Any]]) -> Dict[str, Any]:
28 | """Compute completion for a prompt."""
29 | # Send request.
30 | success = False
31 | while not success:
32 | try:
33 | response: ChatCompletion = self._client.chat.completions.create(
34 | messages=x,
35 | model=self._model,
36 | **self._kwargs,
37 | )
38 | success = True
39 | except:
40 | time.sleep(1)
41 | continue
42 |
43 | response = response.model_dump()
44 | return response
45 |
--------------------------------------------------------------------------------
/LLM/fm_planning/models/pretrained/generative/utils.py:
--------------------------------------------------------------------------------
1 | from typing import Union, List, Dict, Optional, Any, Tuple, Set
2 |
3 | import yaml
4 | import pathlib
5 | import dataclasses
6 |
7 |
8 | def format_openai(
9 | role: str,
10 | content: str,
11 | name: Optional[str] = None,
12 | ) -> Dict[str, Any]:
13 | """Format a prompt for OpenAI."""
14 | prompt = {"role": role, "content": content}
15 | if name is not None:
16 | prompt["name"] = name
17 | return prompt
18 |
19 |
20 | @dataclasses.dataclass
21 | class SystemPrompt:
22 | content: str
23 | # Behavior
24 | behavior: str
25 | behavior_kwargs: Optional[Dict[str, Any]] = None
26 | # OpenAI
27 | role: Optional[str] = None
28 | name: Optional[str] = None
29 |
30 | @classmethod
31 | def from_config(cls, config: Dict[str, Any]) -> "SystemPrompt":
32 | """Create a behavior prompt from a config."""
33 | return cls(**config)
34 |
35 | @classmethod
36 | def from_yaml(cls, file: Union[str, pathlib.Path]) -> "SystemPrompt":
37 | """Create a behavior prompt from a YAML file."""
38 | if isinstance(file, str):
39 | file = pathlib.Path(file)
40 |
41 | with file.open("r") as f:
42 | config = yaml.safe_load(f)
43 |
44 | return cls.from_config(config)
45 |
46 | def prompt(self, openai: bool = True) -> Union[str, Dict[str, Any]]:
47 | """Return the prompt."""
48 | if openai:
49 | assert self.role is not None
50 | prompt = format_openai(role=self.role, content=self.content, name=self.name)
51 | else:
52 | prompt = self.content
53 |
54 | return prompt
55 |
56 |
57 | @dataclasses.dataclass
58 | class BehaviorPrompt:
59 | # Task
60 | task: Optional[str] = None
61 | instruction: Optional[str] = None
62 | objects: Optional[List[str]] = None
63 | predicates: Optional[List[str]] = None
64 | # Behaviors
65 | goals: Optional[List[List[str]]] = None
66 | plans: Optional[List[List[str]]] = None
67 | hypotheses: Optional[List[List[str]]] = None
68 | geometric: Optional[bool] = None
69 | # OpenAI
70 | role: Optional[str] = None
71 | name: Optional[str] = None
72 | name_query: Optional[str] = None
73 | name_response: Optional[str] = None
74 |
75 | @classmethod
76 | def from_config(cls, config: Dict[str, Any]) -> "BehaviorPrompt":
77 | """Create a behavior prompt from a config."""
78 | return cls(**config)
79 |
80 | @classmethod
81 | def from_yaml(cls, file: Union[str, pathlib.Path]) -> "BehaviorPrompt":
82 | """Create a behavior prompt from a YAML file."""
83 | if isinstance(file, str):
84 | file = pathlib.Path(file)
85 |
86 | with file.open("r") as f:
87 | config = yaml.safe_load(f)
88 |
89 | return cls.from_config(config)
90 |
91 | def _prefix(self) -> str:
92 | """Return the prefix of the task prompt."""
93 | assert (
94 | self.objects is not None
95 | and self.predicates is not None
96 | and self.instruction is not None
97 | )
98 | prefix = ""
99 | prefix += f"Objects: {self.objects}\n\n"
100 | prefix += f"Object Relationships: {self.predicates}\n\n"
101 | prefix += f"User Instruction: {self.instruction}"
102 | return prefix
103 |
104 | def _goal_prediction(self) -> Tuple[str, Optional[str]]:
105 | """Return the goal prediction prompt."""
106 | query = self._prefix() + "\n\n" + "Goals: "
107 | response = str(self.goals) if self.goals else None
108 | return query, response
109 |
110 | def _task_planning(self, goal_condition: bool = False) -> Tuple[str, Optional[str]]:
111 | """Return the task planning prompt."""
112 | if goal_condition:
113 | query, goals = self._goal_prediction()
114 | assert goals is not None
115 | query += goals + "\n\n" + "Plans: "
116 | else:
117 | query = self._prefix() + "\n\n" + "Plans: "
118 |
119 | response = str(self.plans) if self.plans else None
120 | return query, response
121 |
122 | def _hypothesis_generation(self) -> str:
123 | """Return the hypothesis generation prompt."""
124 | assert self.hypotheses is not None
125 | raise NotImplementedError
126 |
127 | def _geometric_reasoning(self) -> str:
128 | """Return the geometric reasoning prompt."""
129 | assert self.geometric is not None
130 | raise NotImplementedError
131 |
132 | def prompt(
133 | self,
134 | behavior: str,
135 | behavior_kwargs: Optional[Dict[str, Any]] = None,
136 | example: bool = False,
137 | openai: bool = True,
138 | ) -> Union[str, List[Dict[str, Any]]]:
139 | """Return the prompt for the behavior."""
140 | behaviors = {
141 | "goal_prediction": self._goal_prediction,
142 | "task_planning": self._task_planning,
143 | "hypothesis_generation": self._hypothesis_generation,
144 | "geometric_reasoning": self._geometric_reasoning,
145 | }
146 |
147 | if behavior in behaviors:
148 | behavior_kwargs = behavior_kwargs if behavior_kwargs is not None else {}
149 | query, response = behaviors[behavior](**behavior_kwargs)
150 | if example and response is None:
151 | raise ValueError(
152 | f"Example response not provided for Behavior '{behavior}'."
153 | )
154 | else:
155 | raise ValueError(f"Behavior '{behavior}' is not supported.")
156 |
157 | if openai:
158 | assert self.role is not None
159 | if self.name_query is not None and self.name_response is not None:
160 | query_prompt = format_openai(
161 | role=self.role, content=query, name=self.name_query
162 | )
163 | prompt = [query_prompt]
164 | if example:
165 | response_prompt = format_openai(
166 | role=self.role, content=response, name=self.name_response
167 | )
168 | prompt.append(response_prompt)
169 | else:
170 | prompt = format_openai(
171 | role=self.role,
172 | content=query + response if example else query,
173 | name=self.name,
174 | )
175 | prompt = [prompt]
176 | else:
177 | prompt = query + response if example else query
178 |
179 | return prompt
180 |
181 |
182 | class BehaviorPromptManager:
183 |
184 | def __init__(
185 | self,
186 | task_prompt: Dict[str, Any],
187 | system_prompts: Union[List[str], List[pathlib.Path]],
188 | example_prompts: Optional[Union[List[str], List[pathlib.Path]]] = None,
189 | event_prompts: Optional[Union[List[str], List[pathlib.Path]]] = None,
190 | openai: bool = True,
191 | ) -> None:
192 | """Initialize behavior prompt manager."""
193 | # Instantiate prompts.
194 | self._task_prompt = BehaviorPrompt.from_config(task_prompt)
195 | system_prompts = [SystemPrompt.from_yaml(prompt) for prompt in system_prompts]
196 | self._system_prompts: Dict[str, SystemPrompt] = {
197 | prompt.behavior: prompt for prompt in system_prompts
198 | }
199 | self._example_prompts: List[BehaviorPrompt] = (
200 | [BehaviorPrompt.from_yaml(prompt) for prompt in example_prompts]
201 | if example_prompts is not None
202 | else []
203 | )
204 | self._event_prompts: List[BehaviorPrompt] = (
205 | [BehaviorPrompt.from_yaml(prompt) for prompt in event_prompts]
206 | if event_prompts is not None
207 | else []
208 | )
209 | self._openai = openai
210 |
211 | @classmethod
212 | def from_config(cls, config: Dict[str, Any]) -> "BehaviorPromptManager":
213 | """Create a behavior prompt manager from a config."""
214 | return cls(**config)
215 |
216 | @classmethod
217 | def from_yaml(cls, file: Union[str, pathlib.Path]) -> "BehaviorPromptManager":
218 | """Create a behavior prompt manager from a YAML file."""
219 | if isinstance(file, str):
220 | file = pathlib.Path(file)
221 |
222 | with file.open("r") as f:
223 | config = yaml.safe_load(f)
224 |
225 | assert config["prompt"] == "BehaviorPromptManager"
226 | config = config["prompt_kwargs"]
227 |
228 | return cls.from_config(config)
229 |
230 | @property
231 | def task_prompt(self) -> BehaviorPrompt:
232 | """Get the task prompt."""
233 | return self._task_prompt
234 |
235 | @property
236 | def event_prompts(self) -> List[BehaviorPrompt]:
237 | """Get the event prompts."""
238 | return self._event_prompts
239 |
240 | @event_prompts.setter
241 | def event_prompts(self, event_prompts: List[BehaviorPrompt]) -> None:
242 | """Set the event prompts."""
243 | self._event_prompts = event_prompts
244 |
245 | @property
246 | def behaviors(self) -> Set[str]:
247 | """Return the behaviors."""
248 | return set(self._system_prompts.keys())
249 |
250 | def generate_prompt(
251 | self,
252 | behavior: str,
253 | use_examples: bool = True,
254 | use_events: bool = False,
255 | openai: Optional[bool] = None,
256 | ) -> Union[str, List[Dict[str, Any]]]:
257 | """Generate a prompt for the behavior."""
258 | openai = self._openai if openai is None else openai
259 | prompts = []
260 |
261 | # System prompt.
262 | if behavior in self._system_prompts:
263 | system_prompt = self._system_prompts[behavior]
264 | prompts.append(system_prompt.prompt(openai=openai))
265 | else:
266 | raise ValueError(f"Behavior '{behavior}' is not supported.")
267 |
268 | # Example prompts.
269 | if use_examples:
270 | for example_prompt in self._example_prompts:
271 | prompt = example_prompt.prompt(
272 | behavior,
273 | behavior_kwargs=system_prompt.behavior_kwargs,
274 | example=True,
275 | openai=openai,
276 | )
277 | prompts.append(prompt)
278 |
279 | # Event history prompts.
280 | if use_events:
281 | raise NotImplementedError
282 |
283 | # Current task prompt.
284 | task_prompt = self._task_prompt.prompt(
285 | behavior, behavior_kwargs=system_prompt.behavior_kwargs, openai=openai
286 | )
287 | prompts.append(task_prompt)
288 |
289 | if openai:
290 | temp = []
291 | for p in prompts:
292 | if isinstance(p, list):
293 | temp.extend(p)
294 | else:
295 | temp.append(p)
296 | prompts = temp
297 | else:
298 | prompts = "\n\n".join(prompts)
299 |
300 | return prompts
301 |
302 |
303 | class Llama2Prompt:
304 |
305 | SYSTEM_PROMPT = """[INST] <>
306 | {SYSTEM_MESSAGE}
307 | <>
308 |
309 | """
310 |
311 | def __init__(self, system_message: str):
312 | """Initialize Llama 2 prompt."""
313 | self._system_message = system_message
314 | self._messages = []
315 | self._responses = []
316 |
317 | def add_message(self, message: str):
318 | """Add a message to the prompt."""
319 | self._messages.append(message)
320 |
321 | def add_response(self, response: str):
322 | """Add a response to the prompt."""
323 | self._responses.append(response)
324 |
325 | def __str__(self) -> str:
326 | """Return the prompt as a string."""
327 | prompt = self.SYSTEM_PROMPT.replace("{SYSTEM_MESSAGE}", self._system_message)
328 | for i in range(len(self._messages + self._responses)):
329 | if i % 2 == 0:
330 | if i == 0:
331 | prompt += f"{self._messages[i]} [/INST]"
332 | else:
333 | prompt += f" {self._messages[i]} [/INST]"
334 | else:
335 | prompt += f" {self._responses[i]} [INST]"
336 |
337 | return prompt
338 |
--------------------------------------------------------------------------------
/LLM/fm_planning/models/pretrained/utils.py:
--------------------------------------------------------------------------------
1 | from typing import Any, Dict, Union, Optional
2 |
3 | import pathlib
4 |
5 | from LLM.fm_planning import models
6 | from LLM.fm_planning.models.pretrained import PretrainedModel
7 | from LLM.fm_planning.models.pretrained.generative import *
8 | from LLM.fm_planning.models.pretrained.embeddings import *
9 | from LLM.fm_planning.utils import configs
10 |
11 |
12 | class PretrainedModelFactory(configs.Factory[PretrainedModel]):
13 | """Pretrained model factory."""
14 |
15 | def __init__(
16 | self,
17 | config: Union[str, pathlib.Path, Dict[str, Any]],
18 | api_key: Optional[str] = None,
19 | device: str = "auto",
20 | ):
21 | """Creates the pretrained model factory from a config.
22 |
23 | Args:
24 | config: Config path or dict.
25 | api_key: Pretrained model API key.
26 | device: Torch device.
27 | """
28 | super().__init__(config, "model", models)
29 |
30 | if issubclass(self.cls, OpenAIGenerativeModel):
31 | if "api_key" not in self.kwargs:
32 | assert api_key is not None, "OpenAI API key must be provided."
33 | self.kwargs["api_key"] = api_key
34 |
35 | elif issubclass(self.cls, LlamaGenerativeModel):
36 | self.kwargs["device"] = device
37 |
38 | elif issubclass(self.cls, OpenAIEmbeddingModel):
39 | if "api_key" not in self.kwargs:
40 | assert api_key is not None, "OpenAI API key must be provided."
41 | self.kwargs["api_key"] = api_key
42 |
43 | elif issubclass(self.cls, HuggingFaceEmbeddingModel):
44 | self.kwargs["device"] = device
45 |
46 | else:
47 | raise ValueError(f"Invalid model type: {self.cls}")
48 |
49 |
50 | def load(
51 | config: Union[str, pathlib.Path, Dict[str, Any]],
52 | device: str = "auto",
53 | **kwargs,
54 | ) -> PretrainedModel:
55 | """Loads the pretrained model factory from a config.
56 |
57 | Args:
58 | config: Config path or dict.
59 | device: Torch device.
60 | **kwargs: Optional model constructor kwargs.
61 |
62 | Returns:
63 | Pretrained model instance.
64 | """
65 | pretrained_model_factory = PretrainedModelFactory(
66 | config=config,
67 | device=device,
68 | )
69 | return pretrained_model_factory(**kwargs)
70 |
71 |
72 | def load_config(path: Union[str, pathlib.Path]) -> Dict[str, Any]:
73 | """Loads a pretrained model config from path.
74 |
75 | Args:
76 | path: Path to the config, config directory.
77 |
78 | Returns:
79 | Pretrained model config dict.
80 | """
81 | return configs.load_config(path, "model")
82 |
--------------------------------------------------------------------------------
/LLM/fm_planning/utils/__init__.py:
--------------------------------------------------------------------------------
1 | from . import configs
2 | from . import nest
3 | from . import random
4 | from . import tensors
5 | from . import timing
6 | from . import typing
7 |
--------------------------------------------------------------------------------
/LLM/fm_planning/utils/configs.py:
--------------------------------------------------------------------------------
1 | import pathlib
2 | import subprocess
3 | import types
4 | from typing import Any, Callable, Dict, Generic, List, Optional, Type, TypeVar, Union
5 |
6 | import yaml # type: ignore
7 |
8 |
9 | T = TypeVar("T")
10 |
11 |
12 | def save_git_hash(path: pathlib.Path) -> None:
13 | """Saves the current git hash to the given path.
14 |
15 | Args:
16 | path: Path to save git hash.
17 | """
18 | process = subprocess.Popen(
19 | ["git", "rev-parse", "HEAD"], shell=False, stdout=subprocess.PIPE
20 | )
21 | git_head_hash = process.communicate()[0].strip()
22 | with open(path / "git_hash.txt", "wb") as f:
23 | f.write(git_head_hash)
24 |
25 |
26 | def get_class(classname: Union[str, Type[T]], module: types.ModuleType) -> Type[T]:
27 | """Gets the class from the given module.
28 |
29 | Returns classname directly if it is already a class.
30 |
31 | Args:
32 | classname: Class name with '.' denoting submodules.
33 | module: Python module to search.
34 |
35 | Returns:
36 | Class.
37 | """
38 |
39 | def _get_submodule(module, submodules: List[str]) -> Type[T]:
40 | if not submodules:
41 | return module
42 | return _get_submodule(vars(module)[submodules[0]], submodules[1:])
43 |
44 | if isinstance(classname, str):
45 | submodules = classname.split(".")
46 |
47 | try:
48 | return _get_submodule(module, submodules)
49 | except KeyError as e:
50 | raise KeyError(f"Cannot find {classname} in {module.__name__}:\n{e}")
51 | else:
52 | return classname
53 |
54 |
55 | def get_instance(
56 | classname: Union[str, T], kwargs: Dict[str, Any], module: types.ModuleType
57 | ) -> T:
58 | """Creates an instance of the given class with kwargs.
59 |
60 | Returns classname directly if it is already an instance.
61 |
62 | Args:
63 | classname: Class name with '.' denoting submodules.
64 | kwargs: Class constructor kwargs .
65 | module: Python module to search.
66 |
67 | Returns:
68 | Class instance.
69 | """
70 | if isinstance(classname, str):
71 | cls: Type[T] = get_class(classname, module)
72 | return cls(**kwargs)
73 | else:
74 | return classname
75 |
76 |
77 | def parse_class(config: Dict[str, Any], key: str, module: types.ModuleType) -> Type:
78 | """Parses the class from a config.
79 |
80 | Args:
81 | config: Config dict.
82 | key: Dict key containing class name as its value.
83 | module: Python module to search.
84 |
85 | Returns:
86 | Class.
87 | """
88 | if key not in config:
89 | raise KeyError(f"{key} missing from config")
90 | return get_class(config[key], module)
91 |
92 |
93 | def parse_kwargs(config: Dict[str, Any], key: str) -> Dict:
94 | """Parses the kwargs from a config.
95 |
96 | Args:
97 | config: Config dict.
98 | key: Dict key containing kwargs as its value.
99 |
100 | Returns:
101 | Kwargs or empty dict.
102 | """
103 | try:
104 | kwargs = config[key]
105 | except KeyError:
106 | return {}
107 | return {} if kwargs is None else kwargs
108 |
109 |
110 | def load_config(
111 | path: Union[str, pathlib.Path], config_prefix: Optional[str] = None
112 | ) -> Dict[str, Any]:
113 | """Loads a config from path.
114 |
115 | Args:
116 | path: Path to the config, config directory, or checkpoint.
117 | config_prefix: Prefix of config file to search: "{config_prefix}_config.yaml".
118 |
119 | Returns:
120 | Config dict.
121 | """
122 | if isinstance(path, str):
123 | path = pathlib.Path(path)
124 |
125 | if path.suffix == ".yaml":
126 | config_path = path
127 | else:
128 | if path.suffix == ".pt":
129 | path = path.parent
130 |
131 | config_name = "config.yaml"
132 | if config_prefix is not None:
133 | config_name = f"{config_prefix}_{config_name}"
134 |
135 | config_path = path / config_name
136 |
137 | with open(config_path, "r") as f:
138 | config = yaml.safe_load(f)
139 |
140 | return config
141 |
142 |
143 | class Factory(Generic[T]):
144 | """Base factory class."""
145 |
146 | def __init__(
147 | self,
148 | config: Union[str, pathlib.Path, Dict[str, Any]],
149 | key: str,
150 | module: types.ModuleType,
151 | ):
152 | """Parses the config.
153 |
154 | Args:
155 | config: Config path or dict.
156 | key: Key of class definition in the config dict.
157 | module: Python module of class.
158 | """
159 | if not isinstance(config, dict):
160 | with open(config, "r") as f:
161 | config = yaml.safe_load(f)
162 | assert isinstance(config, dict)
163 |
164 | self._config = config
165 | self._cls = parse_class(config, key, module)
166 | self._kwargs = dict(parse_kwargs(config, f"{key}_kwargs"))
167 | self._key = key
168 | self._last_instance: Optional[T] = None
169 | self._post_hooks: List[Callable[[T], None]] = []
170 |
171 | @property
172 | def config(self) -> Dict[str, Any]:
173 | """Loaded config dict."""
174 | return self._config
175 |
176 | @property
177 | def cls(self) -> Type:
178 | """Parsed class name."""
179 | return self._cls
180 |
181 | @property
182 | def kwargs(self) -> Dict[str, Any]:
183 | """Parsed class kwargs."""
184 | return self._kwargs
185 |
186 | @property
187 | def last_instance(self) -> Optional[T]:
188 | """Last created instance."""
189 | return self._last_instance
190 |
191 | def save_config(self, path: Union[str, pathlib.Path]) -> None:
192 | """Saves the config to path.
193 |
194 | Args:
195 | path: Directory where config will be saved.
196 | """
197 | path = pathlib.Path(path)
198 | with open(path / f"{self._key}_config.yaml", "w") as f:
199 | yaml.dump(self.config, f)
200 |
201 | def get_instance(self, *args, **kwargs) -> T:
202 | """Gets the last created instance or creates a new one with the given args.
203 |
204 | Args:
205 | *args: Constructor args.
206 | **kwargs: Constructor kwargs.
207 |
208 | Returns:
209 | Last created instance.
210 | """
211 | if self.last_instance is None:
212 | self.__call__(*args, **kwargs)
213 | assert self.last_instance is not None
214 | return self.last_instance
215 |
216 | def add_post_hook(self, post_hook: Callable[[T], Any]) -> None:
217 | """Adds a callback function to call when this factory is called.
218 |
219 | Args:
220 | post_hook: Function to call.
221 | """
222 | self._post_hooks.append(post_hook)
223 |
224 | def run_post_hooks(self, instance: T) -> None:
225 | """Runs the post hooks.
226 |
227 | Args:
228 | instance: Instance to pass to the post hooks.
229 | """
230 | self._last_instance = instance
231 | for post_hook in self._post_hooks:
232 | post_hook(instance)
233 |
234 | def __call__(self, *args, **kwargs) -> T:
235 | """Creates an instance of the class.
236 |
237 | Args:
238 | *args: Constructor args.
239 | **kwargs: Constructor kwargs.
240 |
241 | Returns:
242 | Class instance.
243 | """
244 | merged_kwargs = dict(self.kwargs)
245 | merged_kwargs.update(kwargs)
246 | instance = self.cls(*args, **merged_kwargs)
247 |
248 | self.run_post_hooks(instance)
249 |
250 | return instance
251 |
--------------------------------------------------------------------------------
/LLM/fm_planning/utils/nest.py:
--------------------------------------------------------------------------------
1 | from typing import Callable, Generator, Iterator, Optional, Tuple, Type, Union
2 |
3 | import numpy as np
4 | import torch
5 |
6 | from LLM.fm_planning.utils import typing
7 |
8 |
9 | def map_structure(
10 | func: Callable,
11 | *args,
12 | atom_type: Union[Type, Tuple[Type, ...]] = (
13 | torch.Tensor,
14 | np.ndarray,
15 | *typing.scalars,
16 | type(None),
17 | ),
18 | skip_type: Optional[Union[Type, Tuple[Type, ...]]] = None,
19 | ):
20 | """Applies the function over the nested structure atoms.
21 |
22 | Works like tensorflow.nest.map_structure():
23 | https://www.tensorflow.org/api_docs/python/tf/nest/map_structure
24 |
25 | Args:
26 | func: Function applied to the atoms of *args.
27 | *args: Nested structure arguments of `func`.
28 | atom_type: Types considered to be atoms in the nested structure.
29 | skip_type: Types to be skipped and returned as-is in the nested structure.
30 |
31 | Returns:
32 | Results of func(*args_atoms) in the same nested structure as *args.
33 | """
34 | arg_0 = args[0]
35 | if isinstance(arg_0, atom_type):
36 | return func(*args)
37 | elif skip_type is not None and isinstance(arg_0, skip_type):
38 | return arg_0 if len(args) == 1 else args
39 | elif isinstance(arg_0, dict):
40 | return {
41 | key: map_structure(
42 | func,
43 | *(arg[key] for arg in args),
44 | atom_type=atom_type,
45 | skip_type=skip_type,
46 | )
47 | for key in arg_0
48 | }
49 | elif hasattr(arg_0, "__iter__"):
50 | iterable_class = type(arg_0)
51 | return iterable_class(
52 | map_structure(func, *args_i, atom_type=atom_type, skip_type=skip_type)
53 | for args_i in zip(*args)
54 | )
55 | else:
56 | return arg_0 if len(args) == 1 else args
57 |
58 |
59 | def structure_iterator(
60 | structure,
61 | atom_type: Union[Type, Tuple[Type, ...]] = (
62 | torch.Tensor,
63 | np.ndarray,
64 | *typing.scalars,
65 | type(None),
66 | ),
67 | skip_type: Optional[Union[Type, Tuple[Type, ...]]] = None,
68 | ) -> Iterator:
69 | """Provides an iterator over the atom values in the flattened nested structure.
70 |
71 | Args:
72 | structure: Nested structure.
73 | atom_type: Types considered to be atoms in the nested structure.
74 | skip_type: Types to be skipped and returned as-is in the nested structure.
75 |
76 | Returns:
77 | Iterator over the atom values in the flattened nested structure.
78 | """
79 |
80 | def iterate_structure(
81 | structure,
82 | ) -> Generator:
83 | if isinstance(structure, atom_type):
84 | yield structure
85 | elif skip_type is not None and isinstance(structure, skip_type):
86 | pass
87 | elif isinstance(structure, dict):
88 | for val in structure.values():
89 | for elem in iterate_structure(val):
90 | yield elem
91 | elif hasattr(structure, "__iter__"):
92 | for val in structure:
93 | for elem in iterate_structure(val):
94 | yield elem
95 | else:
96 | pass
97 |
98 | return iter(iterate_structure(structure))
99 |
--------------------------------------------------------------------------------
/LLM/fm_planning/utils/random.py:
--------------------------------------------------------------------------------
1 | from typing import Optional
2 |
3 | import random
4 | import numpy as np
5 | import torch
6 |
7 |
8 | def seed(n: Optional[int]) -> None:
9 | """Sets the random seed.
10 |
11 | Args:
12 | n: Optional seed. If None, no seed is set.
13 | """
14 | if n is None:
15 | return
16 |
17 | torch.manual_seed(n)
18 | np.random.seed(n)
19 | random.seed(n)
20 |
--------------------------------------------------------------------------------
/LLM/fm_planning/utils/tensors.py:
--------------------------------------------------------------------------------
1 | import math
2 | from typing import Any, Callable, Iterator, List, Optional, Sequence, Tuple, Type, Union
3 |
4 | import numpy as np
5 | import torch
6 |
7 | from LLM.fm_planning.utils import nest, typing
8 |
9 |
10 | def device(device: Union[str, torch.device] = "auto") -> torch.device:
11 | """Gets the torch device.
12 |
13 | Args:
14 | device: "cpu", "gpu", or "auto".
15 |
16 | Returns:
17 | Torch device.
18 | """
19 | if isinstance(device, torch.device):
20 | return device
21 |
22 | if device == "auto":
23 | device = "cuda" if torch.cuda.is_available() else "cpu"
24 | return torch.device(device)
25 |
26 |
27 | def to_tensor(
28 | x: Union[torch.Tensor, np.ndarray, Sequence[float], Sequence[int], typing.Scalar]
29 | ) -> torch.Tensor:
30 | """Converts the scalar or array to a tensor.
31 |
32 | Args:
33 | x: Scalar or array.
34 |
35 | Returns:
36 | Tensor.
37 | """
38 | if isinstance(x, torch.Tensor):
39 | return x
40 | elif isinstance(x, np.ndarray):
41 | return torch.from_numpy(x)
42 | else:
43 | return torch.tensor(x)
44 |
45 |
46 | def dim(
47 | x: Union[torch.Tensor, np.ndarray, Sequence[float], Sequence[int], typing.Scalar]
48 | ) -> int:
49 | """Gets the number of dimensions of x.
50 |
51 | Args:
52 | x: Scalar or array.
53 |
54 | Returns:
55 | Number of dimensions.
56 | """
57 | if isinstance(x, torch.Tensor):
58 | return x.dim()
59 | elif isinstance(x, np.ndarray):
60 | return x.ndim
61 | elif isinstance(x, (float, int)):
62 | return 0
63 | else:
64 | return 1
65 |
66 |
67 | def map_structure(
68 | func: Callable,
69 | *args,
70 | atom_type: Union[Type, Tuple[Type, ...]] = (torch.Tensor, np.ndarray),
71 | ):
72 | """Maps the function over the structure containing either Torch tensors or Numpy
73 | arrays.
74 |
75 | Args:
76 | func: Function to be mapped.
77 | *args: Nested structure arguments of `func`.
78 | atom_type: Type to which the function should be applied.
79 | """
80 | return nest.map_structure(
81 | func,
82 | *args,
83 | atom_type=atom_type,
84 | skip_type=(np.ndarray, torch.Tensor, *typing.scalars, str, type(None)),
85 | )
86 |
87 |
88 | def structure_iterator(
89 | structure, atom_type: Union[Type, Tuple[Type, ...]] = (torch.Tensor, np.ndarray)
90 | ) -> Iterator:
91 | """Provides an iterator over the Torch tensors or Numpy arrays in the nested
92 | structure.
93 |
94 | Args:
95 | structure: Nested structure
96 | atom_type: Types considered to be atoms in the nested structure.
97 |
98 | Returns:
99 | Iterator over the atom values in the flattened nested structure.
100 | """
101 | return nest.structure_iterator(
102 | structure,
103 | atom_type=atom_type,
104 | skip_type=(np.ndarray, torch.Tensor, *typing.scalars, str, type(None)),
105 | )
106 |
107 |
108 | def to(structure, device: torch.device):
109 | """Moves the nested structure to the given device.
110 |
111 | Numpy arrays are converted to Torch tensors first.
112 |
113 | Args:
114 | structure: Nested structure.
115 | device: Torch device.
116 |
117 | Returns:
118 | Transferred structure.
119 | """
120 |
121 | def _to(x):
122 | if isinstance(x, torch.Tensor):
123 | return x.to(device)
124 |
125 | try:
126 | return torch.from_numpy(x).to(device)
127 | except TypeError:
128 | return x
129 |
130 | return map_structure(_to, structure)
131 |
132 |
133 | def numpy(structure):
134 | """Converts the nested structure to Numpy arrays.
135 |
136 | Args:
137 | structure: Nested structure.
138 |
139 | Returns:
140 | Numpy structure.
141 | """
142 | return map_structure(
143 | lambda x: x.cpu().detach().numpy(), structure, atom_type=torch.Tensor
144 | )
145 |
146 |
147 | def from_numpy(structure, device: Optional[torch.device] = None):
148 | """Converts the nested structure to Torch tensors.
149 |
150 | Args:
151 | structure: Nested structure.
152 |
153 | Returns:
154 | Tensor structure.
155 | """
156 | if device is None:
157 | return map_structure(
158 | lambda x: torch.from_numpy(x), structure, atom_type=np.ndarray
159 | )
160 | return map_structure(
161 | lambda x: torch.from_numpy(x).to(device), structure, atom_type=np.ndarray
162 | )
163 |
164 |
165 | def unsqueeze(structure, dim: int):
166 | def _unsqueeze(
167 | x: Union[torch.Tensor, np.ndarray]
168 | ) -> Union[torch.Tensor, np.ndarray]:
169 | if isinstance(x, np.ndarray):
170 | return np.expand_dims(x, dim)
171 | elif isinstance(x, torch.Tensor):
172 | return x.unsqueeze(dim)
173 | return x
174 |
175 | return map_structure(_unsqueeze, structure)
176 |
177 |
178 | # TODO: Handle device.
179 | def numpy_wrap(func: Callable) -> Callable:
180 | """Decorator that creates a wrapper around Torch functions to be compatible
181 | with Numpy inputs and outputs.
182 |
183 | Args:
184 | func: Torch function.
185 |
186 | Returns:
187 | Function compatible with Torch or Numpy.
188 | """
189 |
190 | def numpy_func(*args, **kwargs):
191 | try:
192 | next(structure_iterator((args, kwargs), atom_type=np.ndarray))
193 | except StopIteration:
194 | is_numpy = False
195 | else:
196 | is_numpy = True
197 | args, kwargs = from_numpy((args, kwargs))
198 |
199 | result = func(*args, **kwargs)
200 |
201 | if is_numpy:
202 | result = numpy(result)
203 |
204 | return result
205 |
206 | return numpy_func
207 |
208 |
209 | def torch_wrap(func: Callable) -> Callable:
210 | """Decorator that creates a wrapper around Numpy functions to be compatible
211 | with Torch inputs and outputs.
212 |
213 | Args:
214 | func: Numpy function.
215 |
216 | Returns:
217 | Function compatible with Torch or Numpy.
218 | """
219 |
220 | def torch_func(*args, **kwargs):
221 | try:
222 | tensor = next(structure_iterator((args, kwargs)))
223 | except StopIteration:
224 | device = None
225 | else:
226 | device = tensor.device
227 | args, kwargs = numpy((args, kwargs))
228 |
229 | result = func(*args, **kwargs)
230 |
231 | if device is not None:
232 | result = to(result, device)
233 |
234 | return result
235 |
236 | return torch_func
237 |
238 |
239 | def vmap(dims: int) -> Callable:
240 | """Decorator that vectorizes functions.
241 |
242 | Args:
243 | dims: Number of dimensions of the first tensor function input.
244 | func: Function to vectorize.
245 |
246 | Returns:
247 | Vectorized function.
248 | """
249 |
250 | def append(x: Any, xs: List[Any]) -> None:
251 | xs.append(x)
252 |
253 | def stack(x: Any, xs: List[Any]) -> Union[torch.Tensor, np.ndarray]:
254 | if isinstance(x, torch.Tensor):
255 | return torch.stack(xs, dim=0)
256 | else:
257 | return np.array(xs)
258 |
259 | def _vmap(func: Callable) -> Callable:
260 | def vectorized_func(*args, **kwargs):
261 | try:
262 | arr = next(structure_iterator((args, kwargs)))
263 | except StopIteration:
264 | is_batch = False
265 | else:
266 | arr_dim = arr.dim() if isinstance(arr, torch.Tensor) else arr.ndim
267 | is_batch = arr_dim != dims
268 |
269 | if not is_batch:
270 | return func(*args, **kwargs)
271 |
272 | # Flatten batch dims.
273 | batch_shape = arr.shape[:-dims] if dims > 0 else arr.shape
274 | batch_dims = len(batch_shape)
275 | batch_size = np.prod(batch_shape)
276 | args, kwargs = map_structure(
277 | lambda x: x.reshape(batch_size, *x.shape[batch_dims:]), (args, kwargs)
278 | )
279 |
280 | # Call func for each batch element.
281 | results = None
282 | for i in range(batch_size):
283 | args_i, kwargs_i = map_structure(lambda x: x[i], (args, kwargs))
284 | result = func(*args_i, **kwargs_i)
285 | if i == 0:
286 | results = map_structure(lambda x: [x], result)
287 | else:
288 | map_structure(append, result, results)
289 | results = map_structure(stack, result, results)
290 |
291 | # Restore batch dims.
292 | results = map_structure(
293 | lambda x: x.reshape(*batch_shape, *x.shape[1:]), results
294 | )
295 |
296 | return results
297 |
298 | return vectorized_func
299 |
300 | return _vmap
301 |
302 |
303 | def batch(dims: int) -> Callable:
304 | """Decorator that ensures function inputs have at least one batch dimension.
305 |
306 | If original arguments are not batched, returned results will also not have a batch.
307 |
308 | Args:
309 | dims: Number of dimensions of the first tensor function input.
310 | func: Function to vectorize.
311 |
312 | Returns:
313 | Flexible batch function.
314 | """
315 |
316 | def _vmap(func: Callable) -> Callable:
317 | def batched_func(*args, **kwargs):
318 | try:
319 | arr = next(structure_iterator((args, kwargs)))
320 | except StopIteration:
321 | is_batch = False
322 | else:
323 | arr_dim = arr.dim() if isinstance(arr, torch.Tensor) else arr.ndim
324 | is_batch = arr_dim != dims
325 |
326 | if is_batch:
327 | return func(*args, **kwargs)
328 |
329 | args, kwargs = map_structure(lambda x: x.unsqueeze(0), (args, kwargs))
330 | results = func(*args, **kwargs)
331 | results = map_structure(lambda x: x.squeeze(0), results)
332 |
333 | return results
334 |
335 | return batched_func
336 |
337 | return _vmap
338 |
339 |
340 | def rgb_to_cnn(img_rgb: torch.Tensor, contiguous: bool = False) -> torch.Tensor:
341 | if contiguous:
342 | return img_rgb.moveaxis(-1, -3).contiguous().float() / 255
343 | else:
344 | return img_rgb.moveaxis(-1, -3).float() / 255
345 |
346 |
347 | def cnn_to_rgb(img_cnn: torch.Tensor, contiguous: bool = False) -> torch.Tensor:
348 | img_rgb = (255 * img_cnn.clip(0, 1).moveaxis(-3, -1) + 0.5).to(torch.uint8)
349 | if contiguous:
350 | return img_rgb.contiguous()
351 | else:
352 | return img_rgb
353 |
354 |
355 | def get_num_free_bytes() -> int:
356 | cuda_device = torch.cuda.current_device()
357 | num_unreserved_bytes: int = torch.cuda.mem_get_info(cuda_device)[0] # type: ignore
358 | num_reserved_bytes = torch.cuda.memory_reserved(cuda_device)
359 | num_allocated_bytes = torch.cuda.memory_allocated(cuda_device)
360 | num_free_bytes = num_unreserved_bytes + num_reserved_bytes - num_allocated_bytes
361 |
362 | return num_free_bytes
363 |
364 |
365 | def compute_minibatch(batch_size: int, element_size: int) -> Tuple[int, int]:
366 | num_free_bytes = get_num_free_bytes()
367 | max_minibatch_size = int(num_free_bytes / (2 * element_size))
368 |
369 | # Redistribute batch size equally across all iterations.
370 | num_batches = int(math.ceil(batch_size / max_minibatch_size) + 0.5)
371 | minibatch_size = int(math.ceil(batch_size / num_batches) + 0.5)
372 |
373 | return minibatch_size, num_batches
374 |
--------------------------------------------------------------------------------
/LLM/fm_planning/utils/timing.py:
--------------------------------------------------------------------------------
1 | import collections
2 | import time
3 | from typing import Dict, List, Sequence
4 |
5 | import numpy as np
6 |
7 |
8 | class Timer:
9 | """Timer to keep track of timing intervals for different keys."""
10 |
11 | def __init__(self):
12 | self._tics = {}
13 |
14 | def keys(self) -> Sequence[str]:
15 | """Timer keys."""
16 | return self._tics.keys()
17 |
18 | def tic(self, key: str) -> float:
19 | """Starts timing for the given key.
20 |
21 | Args:
22 | key: Time interval key.
23 |
24 | Returns:
25 | Current time.
26 | """
27 | self._tics[key] = time.time()
28 | return self._tics[key]
29 |
30 | def toc(self, key: str, set_tic: bool = False) -> float:
31 | """Returns the time elapsed since the last tic for the given key.
32 |
33 | Args:
34 | key: Time interval key.
35 | set_tic: Reset the tic to the current time.
36 |
37 | Returns:
38 | Time elapsed since the last tic.
39 | """
40 | toc = time.time()
41 | tic = self._tics[key]
42 | if set_tic:
43 | self._tics[key] = toc
44 | return toc - tic
45 |
46 |
47 | class Profiler(Timer):
48 | """Profiler to keep track of average time interval for different keys."""
49 |
50 | class ProfilerContext:
51 | """Context manager for timing code inside a `with` block."""
52 |
53 | def __init__(self, profiler: "Profiler", key: str):
54 | self.profiler = profiler
55 | self.key = key
56 |
57 | def __enter__(self) -> float:
58 | return self.profiler.tic(self.key)
59 |
60 | def __exit__(self, type, value, traceback) -> None:
61 | self.profiler.toc(self.key)
62 |
63 | def __init__(self, disabled: bool = False):
64 | """Initializes the profiler with the given status.
65 |
66 | Args:
67 | disabled: Disable the profiler.
68 | """
69 | super().__init__()
70 | self._disabled = disabled
71 | self._tictocs: Dict[str, List[float]] = collections.defaultdict(list)
72 |
73 | def disable(self) -> None:
74 | """Disables the profiler so that tic and toc do nothing."""
75 | self._disabled = True
76 |
77 | def enable(self) -> None:
78 | """Enables the profiler."""
79 | self._disabled = False
80 |
81 | def tic(self, key: str) -> float:
82 | """Starts timing for the given key.
83 |
84 | Args:
85 | key: Time interval key.
86 |
87 | Returns:
88 | Current time.
89 | """
90 | if self._disabled:
91 | return 0.0
92 | return super().tic(key)
93 |
94 | def toc(self, key: str, set_tic: bool = False) -> float:
95 | """Returns the time elapsed since the last tic for the given key.
96 |
97 | Args:
98 | key: Time interval key.
99 | set_tic: Reset the tic to the current time.
100 |
101 | Returns:
102 | Time elapsed since the last tic.
103 | """
104 | if self._disabled:
105 | return 0.0
106 | tictoc = super().toc(key, set_tic)
107 | self._tictocs[key].append(tictoc)
108 | return tictoc
109 |
110 | def profile(self, key: str) -> ProfilerContext:
111 | """Times the code inside a `with` block for the given key.
112 |
113 | Args:
114 | key: Time interval key.
115 |
116 | Returns:
117 | Profiler context.
118 | """
119 | return Profiler.ProfilerContext(self, key)
120 |
121 | def compute_average(self, key: str, reset: bool = False) -> float:
122 | """Computes the average time interval for the given key.
123 |
124 | Args:
125 | key: Time interval key.
126 | reset: Reset the collected time intervals.
127 |
128 | Returns:
129 | Average time interval.
130 | """
131 | mean = float(np.mean(self._tictocs[key]))
132 | if reset:
133 | self._tictocs[key] = []
134 | return mean
135 |
136 | def compute_sum(self, key: str, reset: bool = False) -> float:
137 | """Computes the total time interval for the given key.
138 |
139 | Args:
140 | key: Time interval key.
141 | reset: Reset the collected time intervals.
142 |
143 | Returns:
144 | Total time interval.
145 | """
146 | sum = float(np.sum(self._tictocs[key]))
147 | if reset:
148 | self._tictocs[key] = []
149 | return sum
150 |
151 | def collect_profiles(self) -> Dict[str, float]:
152 | """Collects and resets the average time intervals for all keys.
153 |
154 | Returns:
155 | Dict mapping from key to average time interval.
156 | """
157 | return {
158 | key: self.compute_average(key, reset=True)
159 | for key, tictoc in self._tictocs.items()
160 | if len(tictoc) > 0
161 | }
162 |
--------------------------------------------------------------------------------
/LLM/fm_planning/utils/typing.py:
--------------------------------------------------------------------------------
1 | from typing import TypeVar, Union, Mapping
2 |
3 | import numpy as np
4 | import torch
5 |
6 |
7 | Scalar = Union[float, int, bool]
8 | scalars = (float, int, bool)
9 | Tensor = Union[np.ndarray, torch.Tensor]
10 | ArrayType = TypeVar("ArrayType", np.ndarray, torch.Tensor)
11 | StateType = TypeVar("StateType")
12 | ObsType = TypeVar("ObsType")
13 | ActType = TypeVar("ActType")
14 | ModelBatchType = TypeVar("ModelBatchType")
15 | DatasetBatchType = TypeVar("DatasetBatchType", bound=Mapping)
16 |
--------------------------------------------------------------------------------
/LLM/package.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | fm_planning
4 | 0.0.0
5 | Planning with Foundation Models (FMs): Language Models and Vision-Language Models
6 |
7 |
8 |
9 |
10 | Christopher Agia
11 |
12 |
13 |
14 |
15 |
16 | MIT
17 |
18 |
19 |
20 |
21 |
22 | https://github.com/agiachris/fm-planning
23 |
24 |
25 |
26 |
27 |
28 | Christopher Agia
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 | catkin
52 |
53 | rospy
54 | std_msgs
55 | message_generation
56 |
57 | rospy
58 | std_msgs
59 |
60 | rospy
61 | std_msgs
62 | message_runtime
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
--------------------------------------------------------------------------------
/LLM/pyproject.toml:
--------------------------------------------------------------------------------
1 | [project]
2 | name = "fm-planning"
3 | version = "0.1.0"
4 | description = "Planning with Foundation Models (FMs): Language Models and Vision-Language Models"
5 | authors = [
6 | { name = "Christopher Agia", email = "cagia@cs.stanford.edu" },
7 | ]
8 | license = { file = "LICENSE" }
9 | readme = "README.md"
10 | requires-python = ">=3.8"
11 | classifiers = [
12 | "Programming Language :: Python :: 3",
13 | "License :: OSI Approved :: MIT License",
14 | "Operating System :: OS Independent",
15 | ]
16 | dependencies = [
17 | "numpy",
18 | "torch",
19 | "matplotlib",
20 | "torchvision",
21 | "hydra-core",
22 | "openai",
23 | "black",
24 | "mypy",
25 | "pyyaml",
26 | "transformers",
27 | "pysymbolic",
28 | ]
29 |
30 | [tool.setuptools.packages.find]
31 | include = ["fm_planning*"]
--------------------------------------------------------------------------------
/LLM/scripts/demos/llm_planner.py:
--------------------------------------------------------------------------------
1 | from typing import Union, Optional
2 |
3 | import ast
4 | import argparse
5 | import pathlib
6 | import sys
7 | import os
8 | sys.path.append(os.getcwd())
9 | from LLM.fm_planning import models, utils
10 |
11 |
12 | def demo(
13 | model_config: Union[str, pathlib.Path],
14 | prompt_config: Union[str, pathlib.Path],
15 | api_key: Optional[str] = None,
16 | device: str = "auto",
17 | seed: int = 0,
18 | ) -> None:
19 | """Run a demo."""
20 | # Set seed.
21 | utils.random.seed(seed)
22 |
23 | # Load model.
24 | model_factory = models.PretrainedModelFactory(
25 | model_config, api_key=api_key, device=device
26 | )
27 | model = model_factory()
28 |
29 | # Load prompt.
30 | prompt_manager = models.BehaviorPromptManager.from_yaml(prompt_config)
31 |
32 | # Predict goals.
33 | goal_prediction_prompt = prompt_manager.generate_prompt(
34 | behavior="goal_prediction",
35 | use_examples=True,
36 | )
37 | response = model.forward(goal_prediction_prompt)
38 | predicted_goals = ast.literal_eval(response["choices"][0]["message"]["content"])
39 |
40 | # Update prompts with predicted goals.
41 | prompt_manager.task_prompt.goals = predicted_goals
42 |
43 | # Predict plans.
44 | task_planning_prompt = prompt_manager.generate_prompt(
45 | behavior="task_planning",
46 | use_examples=True,
47 | )
48 | response = model.forward(task_planning_prompt)
49 | predicted_plans = ast.literal_eval(response["choices"][0]["message"]["content"])
50 |
51 | print(f"Predicted goals: {predicted_goals}")
52 | print(f"Predicted plans: {predicted_plans}")
53 |
54 |
55 | def main(args: argparse.Namespace) -> None:
56 | demo(**vars(args))
57 |
58 |
59 | if __name__ == "__main__":
60 | parser = argparse.ArgumentParser()
61 | parser.add_argument("--model-config", type=str, required=True)
62 | parser.add_argument("--prompt-config", type=str, required=True)
63 | parser.add_argument("--api-key", type=str)
64 | parser.add_argument("--device", type=str, default="auto")
65 | parser.add_argument("--seed", type=int, default=0)
66 | main(parser.parse_args())
67 |
--------------------------------------------------------------------------------
/LLM/scripts/llm_planner.py:
--------------------------------------------------------------------------------
1 | from typing import Union, Optional
2 |
3 | import ast
4 | import argparse
5 | import pathlib
6 | import sys
7 | import os
8 | sys.path.append(os.getcwd())
9 | from LLM.fm_planning import models, utils
10 |
11 |
12 | def demo(
13 | model_config: Union[str, pathlib.Path],
14 | prompt_config: Union[str, pathlib.Path],
15 | api_key: Optional[str] = None,
16 | device: str = "auto",
17 | seed: int = 0,
18 | ) -> None:
19 | """Run a demo."""
20 | # Set seed.
21 | utils.random.seed(seed)
22 |
23 | # Load model.
24 | model_factory = models.PretrainedModelFactory(
25 | model_config, api_key=api_key, device=device
26 | )
27 | model = model_factory()
28 |
29 | # Load prompt.
30 | prompt_manager = models.BehaviorPromptManager.from_yaml(prompt_config)
31 |
32 | # Predict goals.
33 | goal_prediction_prompt = prompt_manager.generate_prompt(
34 | behavior="goal_prediction",
35 | use_examples=True,
36 | )
37 | response = model.forward(goal_prediction_prompt)
38 | predicted_goals = ast.literal_eval(response["choices"][0]["message"]["content"])
39 |
40 | # Update prompts with predicted goals.
41 | prompt_manager.task_prompt.goals = predicted_goals
42 |
43 | # Predict plans.
44 | task_planning_prompt = prompt_manager.generate_prompt(
45 | behavior="task_planning",
46 | use_examples=True,
47 | )
48 | response = model.forward(task_planning_prompt)
49 | predicted_plans = ast.literal_eval(response["choices"][0]["message"]["content"])
50 |
51 | print(f"Predicted goals: {predicted_goals}")
52 | print(f"Predicted plans: {predicted_plans}")
53 |
54 |
55 | def main(args: argparse.Namespace) -> None:
56 | demo(**vars(args))
57 |
58 |
59 | if __name__ == "__main__":
60 | parser = argparse.ArgumentParser()
61 | parser.add_argument("--model-config", type=str, required=True)
62 | parser.add_argument("--prompt-config", type=str, required=True)
63 | parser.add_argument("--api-key", type=str)
64 | parser.add_argument("--device", type=str, default="auto")
65 | parser.add_argument("--seed", type=int, default=0)
66 | main(parser.parse_args())
67 |
--------------------------------------------------------------------------------
/LLM/setup.cfg:
--------------------------------------------------------------------------------
1 | # Dummy setup.cfg for editable installs until setuptools supports PEP 660.
2 |
3 | [options]
4 | packages = fm_planning
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Points2Plans: From Point Clouds to Long-Horizon Plans with Composable Relational Dynamics
2 | Code to accompany our ICRA 2025 paper: _Points2Plans: From Point Clouds to Long-Horizon Plans with Composable Relational Dynamics_. [[PDF]](https://arxiv.org/pdf/2408.14769) [[Website]](https://sites.google.com/stanford.edu/points2plans)
3 |
4 | ## Approach Overview
5 | 
6 |
7 | This repository includes:
8 |
9 | * :hammer_and_wrench: A relational dynamics model that excels at long-horizon prediction of point cloud states without the need to train on multi-step data
10 | * :rocket: A latent-geometric space dynamics rollout strategy that significantly increases the horizons over which predicted point cloud states are reliable for planning
11 | * 🦾 A task planning and goal prediction module using Large Language Models (LLMs)
12 |
13 | ## Setup
14 | ### System Requirements
15 | This codebase is primarily tested on Ubuntu 20.04, an NVIDIA GeForce RTX 3090 Ti, and CUDA 11.7.
16 |
17 | ### Virtual Env Installation
18 | ```
19 | conda env create -f conda_env.yml
20 | ```
21 |
22 | ## Task Planning and Goal Prediction Module with LLMs
23 | ```bash
24 | python LLM/scripts/llm_planner.py \
25 | --model-config LLM/configs/models/pretrained/generative/$Model \
26 | --prompt-config LLM/configs/prompts/evaluation/p1/$Task \
27 | --api-key $YourAPIKey
28 | ```
29 |
30 | ## Relational Dynamics
31 | ### Quick Start with Pretrained Models
32 | - Download pretrained models from [this link](https://huggingface.co/datasets/ll4ma-lab/Points2Plans/tree/main/pretrained_model)
33 | - Download test data for [constrained packing task](https://huggingface.co/datasets/ll4ma-lab/Points2Plans/tree/main/test)
34 |
35 | ```bash
36 | python relational_dynamics/main.py \
37 | --result_dir $PretrainedModelDir \
38 | --checkpoint_path $PretrainedModelDir/checkpoint/pretrained.pth \
39 | --test_dir $TestDataDir \
40 | --test_max_size $TestSize
41 | ```
42 |
43 | ### Training
44 |
45 | - Download [training datasets](https://huggingface.co/datasets/ll4ma-lab/Points2Plans/tree/main/train)
46 |
47 | To generate your own data, please refer to our simulation repository using [[isaacgym]](https://bitbucket.org/robot-learning/ll4ma_isaac/src/CoRL_2024/).
48 |
49 | ```bash
50 | python relational_dynamics/main.py \
51 | --result_dir $YourResultDir \
52 | --train_dir $TrainingDataDir \
53 | --batch_size $BatchSize \
54 | --num_epochs $TrainingEpochs \
55 | --max_size $TrainingSize
56 | ```
57 |
58 | ## Baseline: [eRDTransformer](https://sites.google.com/view/erelationaldynamics)
59 |
60 | ### Training
61 | ```bash
62 | python relational_dynamics/main.py \
63 | --result_dir $YourResultDir \
64 | --train_dir $TrainingDataDir \
65 | --batch_size $BatchSize \
66 | --num_epochs $TrainingEpochs \
67 | --delta_forward False \
68 | --latent_forward True \
69 | --max_size $TrainingSize
70 | ```
71 |
72 | ### Test
73 | - Download pretrained models from [this link](https://huggingface.co/datasets/ll4ma-lab/Points2Plans/tree/main/baseline_pretrained)
74 |
75 | ```bash
76 | python relational_dynamics/main.py \
77 | --result_dir $PretrainedModelDir \
78 | --checkpoint_path $PretrainedModelDir/checkpoint/baseline_pretrained.pth \
79 | --test_dir $TestDataDir \
80 | --delta_forward False \
81 | --latent_forward True \
82 | --test_max_size $TestSize
83 | ```
84 |
85 |
86 | ## Citation
87 | If you find our work useful in your research, please cite:
88 | ```
89 | @InProceedings{huang-icra2025-p2p,
90 | title = {{Points2Plans: From Point Clouds to Long-Horizon Plans with Composable Relational Dynamics}},
91 | author = {Yixuan Huang and Christopher Agia and Jimmy Wu and Tucker Hermans and Jeannette Bohg},
92 | booktitle = {IEEE International Conference on Robotics and Automation (ICRA)},
93 | year = {2025},
94 | url = {https://sites.google.com/stanford.edu/points2plans}
95 | }
96 | ```
--------------------------------------------------------------------------------
/conda_env.yml:
--------------------------------------------------------------------------------
1 | name: points2plans
2 | channels:
3 | - pytorch
4 | - pyg
5 | - nvidia
6 | - conda-forge
7 | - defaults
8 | dependencies:
9 | - _libgcc_mutex=0.1=conda_forge
10 | - _openmp_mutex=4.5=2_gnu
11 | - absl-py=1.3.0=py38h06a4308_0
12 | - aiohttp=3.8.3=py38h5eee18b_0
13 | - aiosignal=1.2.0=pyhd3eb1b0_0
14 | - alsa-lib=1.2.8=h166bdaf_0
15 | - anyio=3.5.0=py38h06a4308_0
16 | - aom=3.5.0=h27087fc_0
17 | - argon2-cffi=21.3.0=pyhd3eb1b0_0
18 | - argon2-cffi-bindings=21.2.0=py38h7f8727e_0
19 | - asttokens=2.0.5=pyhd3eb1b0_0
20 | - async-timeout=4.0.2=py38h06a4308_0
21 | - attr=2.5.1=h166bdaf_1
22 | - attrs=22.1.0=py38h06a4308_0
23 | - babel=2.9.1=pyhd3eb1b0_0
24 | - backcall=0.2.0=pyhd3eb1b0_0
25 | - beautifulsoup4=4.11.1=py38h06a4308_0
26 | - blas=1.0=mkl
27 | - bleach=4.1.0=pyhd3eb1b0_0
28 | - blinker=1.4=py38h06a4308_0
29 | - boost-cpp=1.78.0=h75c5d50_1
30 | - bottleneck=1.3.5=py38h7deecbd_0
31 | - brotli=1.0.9=h5eee18b_7
32 | - brotli-bin=1.0.9=h5eee18b_7
33 | - brotlipy=0.7.0=py38h0a891b7_1005
34 | - bzip2=1.0.8=h7f98852_4
35 | - c-ares=1.18.1=h7f8727e_0
36 | - ca-certificates=2022.12.7=ha878542_0
37 | - cached-property=1.5.2=py_0
38 | - cachetools=4.2.2=pyhd3eb1b0_0
39 | - catkin_pkg=0.5.2=pyhd8ed1ab_0
40 | - catkin_tools=0.9.3=pyhd8ed1ab_0
41 | - certifi=2022.12.7=pyhd8ed1ab_0
42 | - cffi=1.15.1=py38h4a40e3a_3
43 | - chainer=7.8.0=pyhd3eb1b0_0
44 | - charset-normalizer=2.1.1=pyhd8ed1ab_0
45 | - click=8.0.4=py38h06a4308_0
46 | - cmake=3.16.3=h28c56e5_0
47 | - coreutils=9.2=h0b41bf4_0
48 | - cuda=11.7.1=0
49 | - cuda-cccl=11.7.91=0
50 | - cuda-command-line-tools=11.7.1=0
51 | - cuda-compiler=11.7.1=0
52 | - cuda-cudart=11.7.99=0
53 | - cuda-cudart-dev=11.7.99=0
54 | - cuda-cuobjdump=11.7.91=0
55 | - cuda-cupti=11.7.101=0
56 | - cuda-cuxxfilt=11.7.91=0
57 | - cuda-demo-suite=12.0.76=0
58 | - cuda-documentation=12.0.76=0
59 | - cuda-driver-dev=11.7.99=0
60 | - cuda-gdb=12.0.90=0
61 | - cuda-libraries=11.7.1=0
62 | - cuda-libraries-dev=11.7.1=0
63 | - cuda-memcheck=11.8.86=0
64 | - cuda-nsight=12.0.78=0
65 | - cuda-nsight-compute=12.0.0=0
66 | - cuda-nvcc=11.7.99=0
67 | - cuda-nvdisasm=12.0.76=0
68 | - cuda-nvml-dev=11.7.91=0
69 | - cuda-nvprof=12.0.90=0
70 | - cuda-nvprune=11.7.91=0
71 | - cuda-nvrtc=11.7.99=0
72 | - cuda-nvrtc-dev=11.7.99=0
73 | - cuda-nvtx=11.7.91=0
74 | - cuda-nvvp=12.0.90=0
75 | - cuda-runtime=11.7.1=0
76 | - cuda-sanitizer-api=12.0.90=0
77 | - cuda-toolkit=11.7.1=0
78 | - cuda-tools=11.7.1=0
79 | - cuda-visual-tools=11.7.1=0
80 | - curl=7.88.1=hdc1c0ab_1
81 | - cycler=0.11.0=pyhd3eb1b0_0
82 | - dbus=1.13.18=hb2f20db_0
83 | - debugpy=1.5.1=py38h295c915_0
84 | - decorator=5.1.1=pyhd3eb1b0_0
85 | - defusedxml=0.7.1=pyhd3eb1b0_0
86 | - docutils=0.19=py38h578d9bd_1
87 | - double-conversion=3.2.0=h27087fc_1
88 | - eigen=3.3.7=hd09550d_1
89 | - entrypoints=0.4=py38h06a4308_0
90 | - executing=0.8.3=pyhd3eb1b0_0
91 | - expat=2.5.0=h27087fc_0
92 | - ffmpeg=5.1.2=gpl_h8dda1f0_105
93 | - fftw=3.3.10=nompi_hf0379b8_106
94 | - filelock=3.6.0=pyhd3eb1b0_0
95 | - flann=1.9.1=he05ef13_1011
96 | - font-ttf-dejavu-sans-mono=2.37=hd3eb1b0_0
97 | - font-ttf-inconsolata=2.001=hcb22688_0
98 | - font-ttf-source-code-pro=2.030=hd3eb1b0_0
99 | - font-ttf-ubuntu=0.83=h8b1ccd4_0
100 | - fontconfig=2.14.1=hc2a2eb6_0
101 | - fonts-anaconda=1=h8fa9717_0
102 | - fonts-conda-ecosystem=1=hd3eb1b0_0
103 | - fonttools=4.25.0=pyhd3eb1b0_0
104 | - freetype=2.12.1=hca18f0e_1
105 | - frozenlist=1.3.3=py38h5eee18b_0
106 | - gds-tools=1.5.0.59=0
107 | - gettext=0.21.1=h27087fc_0
108 | - giflib=5.2.1=h7b6447c_0
109 | - gl2ps=1.4.2=h70c0345_1
110 | - glew=2.1.0=h295c915_3
111 | - glib=2.74.1=h6239696_1
112 | - glib-tools=2.74.1=h6239696_1
113 | - gmp=6.2.1=h58526e2_0
114 | - gnutls=3.7.8=hf3e180e_0
115 | - google-auth=2.6.0=pyhd3eb1b0_0
116 | - google-auth-oauthlib=0.4.4=pyhd3eb1b0_0
117 | - grpcio=1.52.1=py38h8dc9893_1
118 | - gst-plugins-base=1.21.3=h4243ec0_1
119 | - gstreamer=1.21.3=h25f0c4b_1
120 | - gstreamer-orc=0.4.33=h166bdaf_0
121 | - h5py=3.7.0=nompi_py38h7927eab_102
122 | - hdf4=4.2.15=h9772cbc_5
123 | - hdf5=1.12.2=nompi_h4df4325_101
124 | - icu=70.1=h27087fc_0
125 | - idna=3.4=pyhd8ed1ab_0
126 | - importlib-metadata=4.11.3=py38h06a4308_0
127 | - importlib_resources=5.2.0=pyhd3eb1b0_1
128 | - intel-openmp=2022.1.0=h9e868ea_3769
129 | - ipdb=0.13.9=pyhd8ed1ab_0
130 | - ipykernel=6.15.2=py38h06a4308_0
131 | - ipython=8.7.0=py38h06a4308_0
132 | - ipython_genutils=0.2.0=pyhd3eb1b0_1
133 | - ipywidgets=7.6.5=pyhd3eb1b0_1
134 | - jack=1.9.21=h583fa2b_2
135 | - jedi=0.18.1=py38h06a4308_1
136 | - jinja2=3.1.2=py38h06a4308_0
137 | - joblib=1.1.1=py38h06a4308_0
138 | - jpeg=9e=h166bdaf_2
139 | - json5=0.9.6=pyhd3eb1b0_0
140 | - jsoncpp=1.9.5=h4bd325d_1
141 | - jsonschema=4.16.0=py38h06a4308_0
142 | - jupyter=1.0.0=py38h06a4308_8
143 | - jupyter_client=7.4.8=py38h06a4308_0
144 | - jupyter_console=6.4.4=py38h06a4308_0
145 | - jupyter_core=4.11.2=py38h06a4308_0
146 | - jupyter_server=1.23.4=py38h06a4308_0
147 | - jupyterlab=3.5.0=py38h06a4308_0
148 | - jupyterlab_pygments=0.1.2=py_0
149 | - jupyterlab_server=2.16.3=py38h06a4308_0
150 | - jupyterlab_widgets=1.0.0=pyhd3eb1b0_1
151 | - keyutils=1.6.1=h166bdaf_0
152 | - kiwisolver=1.4.2=py38h295c915_0
153 | - krb5=1.20.1=h81ceb04_0
154 | - lame=3.100=h166bdaf_1003
155 | - lcms2=2.12=h3be6417_0
156 | - ld_impl_linux-64=2.39=hcc3a1bd_1
157 | - lerc=4.0.0=h27087fc_0
158 | - libabseil=20230125.0=cxx17_hcb278e6_1
159 | - libaec=1.0.6=h9c3ff4c_0
160 | - libblas=3.9.0=16_linux64_mkl
161 | - libbrotlicommon=1.0.9=h5eee18b_7
162 | - libbrotlidec=1.0.9=h5eee18b_7
163 | - libbrotlienc=1.0.9=h5eee18b_7
164 | - libcap=2.66=ha37c62d_0
165 | - libcblas=3.9.0=16_linux64_mkl
166 | - libclang=15.0.6=default_h2e3cab8_0
167 | - libclang13=15.0.6=default_h3a83d3e_0
168 | - libcublas=11.10.3.66=0
169 | - libcublas-dev=11.10.3.66=0
170 | - libcufft=10.7.2.124=h4fbf590_0
171 | - libcufft-dev=10.7.2.124=h98a8f43_0
172 | - libcufile=1.5.0.59=0
173 | - libcufile-dev=1.5.0.59=0
174 | - libcups=2.3.3=h36d4200_3
175 | - libcurand=10.3.1.50=0
176 | - libcurand-dev=10.3.1.50=0
177 | - libcurl=7.88.1=hdc1c0ab_1
178 | - libcusolver=11.4.0.1=0
179 | - libcusolver-dev=11.4.0.1=0
180 | - libcusparse=11.7.4.91=0
181 | - libcusparse-dev=11.7.4.91=0
182 | - libdb=6.2.32=h6a678d5_1
183 | - libdeflate=1.14=h166bdaf_0
184 | - libdrm=2.4.114=h166bdaf_0
185 | - libedit=3.1.20221030=h5eee18b_0
186 | - libev=4.33=h7f8727e_1
187 | - libevent=2.1.10=h28343ad_4
188 | - libffi=3.4.2=h7f98852_5
189 | - libflac=1.4.2=h27087fc_0
190 | - libgcc-ng=12.2.0=h65d4601_19
191 | - libgcrypt=1.10.1=h166bdaf_0
192 | - libgfortran-ng=11.2.0=h00389a5_1
193 | - libgfortran5=11.2.0=h1234567_1
194 | - libglib=2.74.1=h606061b_1
195 | - libglu=9.0.0=hf484d3e_1
196 | - libgomp=12.2.0=h65d4601_19
197 | - libgpg-error=1.45=hc0c96e0_0
198 | - libgrpc=1.52.1=hcf146ea_1
199 | - libiconv=1.17=h166bdaf_0
200 | - libidn2=2.3.2=h7f8727e_0
201 | - liblapack=3.9.0=16_linux64_mkl
202 | - libllvm15=15.0.6=h63197d8_0
203 | - libnetcdf=4.8.1=nompi_h261ec11_106
204 | - libnghttp2=1.52.0=h61bc06f_0
205 | - libnpp=11.7.4.75=0
206 | - libnpp-dev=11.7.4.75=0
207 | - libnsl=2.0.0=h7f98852_0
208 | - libnvjpeg=11.8.0.2=0
209 | - libnvjpeg-dev=11.8.0.2=0
210 | - libogg=1.3.5=h27cfd23_1
211 | - libopus=1.3.1=h7b6447c_0
212 | - libpciaccess=0.17=h166bdaf_0
213 | - libpng=1.6.39=h753d276_0
214 | - libpq=15.2=hb675445_0
215 | - libprotobuf=3.21.12=h3eb15da_0
216 | - libsndfile=1.1.0=hcb278e6_1
217 | - libsodium=1.0.18=h7b6447c_0
218 | - libsqlite=3.40.0=h753d276_0
219 | - libssh2=1.10.0=hf14f497_3
220 | - libstdcxx-ng=12.2.0=h46fd767_19
221 | - libsystemd0=252=h2a991cd_0
222 | - libtasn1=4.19.0=h166bdaf_0
223 | - libtheora=1.1.1=h7f8727e_3
224 | - libtiff=4.4.0=h82bc61c_5
225 | - libtool=2.4.6=h6a678d5_1009
226 | - libudev1=252=h166bdaf_0
227 | - libunistring=0.9.10=h27cfd23_0
228 | - libuuid=2.32.1=h7f98852_1000
229 | - libuv=1.40.0=h7b6447c_0
230 | - libva=2.16.0=h166bdaf_0
231 | - libvorbis=1.3.7=h7b6447c_0
232 | - libvpx=1.11.0=h295c915_0
233 | - libwebp=1.2.4=h11a3e52_0
234 | - libwebp-base=1.2.4=h166bdaf_0
235 | - libxcb=1.13=h7f98852_1004
236 | - libxkbcommon=1.0.3=he3ba5ed_0
237 | - libxml2=2.10.3=h7463322_0
238 | - libxslt=1.1.37=h873f0b0_0
239 | - libzip=1.9.2=hc929e4a_1
240 | - libzlib=1.2.13=h166bdaf_4
241 | - loguru=0.5.3=py38h06a4308_3
242 | - lxml=4.9.2=py38h215a2d7_0
243 | - lz4-c=1.9.4=h6a678d5_0
244 | - make=4.3=hd18ef5c_1
245 | - markdown=3.4.1=py38h06a4308_0
246 | - markupsafe=2.1.1=py38h7f8727e_0
247 | - matplotlib=3.5.1=py38h06a4308_1
248 | - matplotlib-base=3.5.1=py38ha18d171_1
249 | - matplotlib-inline=0.1.6=py38h06a4308_0
250 | - mistune=0.8.4=py38h7b6447c_1000
251 | - mkl=2022.1.0=hc2b9512_224
252 | - mpg123=1.31.1=h27087fc_0
253 | - multidict=6.0.2=py38h5eee18b_0
254 | - munkres=1.1.4=py_0
255 | - mysql-common=8.0.32=ha901b37_1
256 | - mysql-libs=8.0.32=hd7da12d_1
257 | - nbclassic=0.4.8=py38h06a4308_0
258 | - nbclient=0.5.13=py38h06a4308_0
259 | - nbconvert=6.5.4=py38h06a4308_0
260 | - ncurses=6.3=h27087fc_1
261 | - nest-asyncio=1.5.5=py38h06a4308_0
262 | - nettle=3.8.1=hc379101_1
263 | - nlohmann_json=3.10.5=h295c915_0
264 | - notebook=6.5.2=py38h06a4308_0
265 | - notebook-shim=0.2.2=py38h06a4308_0
266 | - nsight-compute=2022.4.0.15=0
267 | - nspr=4.35=h27087fc_0
268 | - nss=3.82=he02c5a1_0
269 | - numexpr=2.7.3=py38h43a58ef_1
270 | - numpy=1.24.0=py38hab0fcb9_0
271 | - oauthlib=3.2.1=py38h06a4308_0
272 | - openh264=2.3.1=h27087fc_1
273 | - openjpeg=2.4.0=h3ad879b_0
274 | - openssl=3.1.0=h0b41bf4_0
275 | - osrf_pycommon=0.2.1=pyhd8ed1ab_0
276 | - p11-kit=0.24.1=hc5aa10d_0
277 | - packaging=22.0=py38h06a4308_0
278 | - pandas=1.5.2=py38h417a72b_0
279 | - pandocfilters=1.5.0=pyhd3eb1b0_0
280 | - parso=0.8.3=pyhd3eb1b0_0
281 | - pcl=1.13.0=h4f734b3_0
282 | - pcre2=10.40=hc3806b6_0
283 | - pexpect=4.8.0=pyhd3eb1b0_3
284 | - pickleshare=0.7.5=pyhd3eb1b0_1003
285 | - pillow=9.3.0=py38hace64e9_1
286 | - pip=22.3.1=pyhd8ed1ab_0
287 | - pkgutil-resolve-name=1.3.10=py38h06a4308_0
288 | - ply=3.11=py38_0
289 | - proj=9.1.0=h93bde94_0
290 | - prometheus_client=0.14.1=py38h06a4308_0
291 | - prompt-toolkit=3.0.20=pyhd3eb1b0_0
292 | - prompt_toolkit=3.0.20=hd3eb1b0_0
293 | - protobuf=4.21.12=py38h8dc9893_0
294 | - psutil=5.9.0=py38h5eee18b_0
295 | - pthread-stubs=0.4=h36c2ea0_1001
296 | - ptyprocess=0.7.0=pyhd3eb1b0_2
297 | - pugixml=1.11.4=h295c915_1
298 | - pulseaudio=16.1=h126f2b6_0
299 | - pure_eval=0.2.2=pyhd3eb1b0_0
300 | - pyasn1=0.4.8=pyhd3eb1b0_0
301 | - pyasn1-modules=0.2.8=py_0
302 | - pycparser=2.21=pyhd8ed1ab_0
303 | - pyg=2.2.0=py38_torch_1.13.0_cu117
304 | - pygments=2.11.2=pyhd3eb1b0_0
305 | - pyjwt=2.4.0=py38h06a4308_0
306 | - pyopenssl=22.1.0=pyhd8ed1ab_0
307 | - pyparsing=3.0.9=py38h06a4308_0
308 | - pyqt=5.15.7=py38h7492b6b_2
309 | - pyqt5-sip=12.11.0=py38hfa26641_2
310 | - pyrsistent=0.18.0=py38heee7806_0
311 | - pysocks=1.7.1=py38h578d9bd_5
312 | - python=3.8.16=he550d4f_1_cpython
313 | - python-dateutil=2.8.2=pyhd3eb1b0_0
314 | - python-fastjsonschema=2.16.2=py38h06a4308_0
315 | - python_abi=3.8=2_cp38
316 | - pytorch=1.13.1=py3.8_cuda11.7_cudnn8.5.0_0
317 | - pytorch-cluster=1.6.0=py38_torch_1.13.0_cu117
318 | - pytorch-cuda=11.7=h67b0de4_1
319 | - pytorch-mutex=1.0=cuda
320 | - pytorch-scatter=2.1.0=py38_torch_1.13.0_cu117
321 | - pytorch-sparse=0.6.16=py38_torch_1.13.0_cu117
322 | - pytz=2022.7=py38h06a4308_0
323 | - pyyaml=6.0=py38h5eee18b_1
324 | - pyzmq=23.2.0=py38h6a678d5_0
325 | - qhull=2020.2=hdb19cb5_2
326 | - qt-main=5.15.6=hf6cd601_5
327 | - qtconsole=5.3.2=py38h06a4308_0
328 | - qtpy=2.2.0=py38h06a4308_0
329 | - re2=2023.02.02=hcb278e6_0
330 | - readline=8.1.2=h0f457ee_0
331 | - requests=2.28.1=pyhd8ed1ab_1
332 | - requests-oauthlib=1.3.0=py_0
333 | - rhash=1.4.3=h166bdaf_0
334 | - rsa=4.7.2=pyhd3eb1b0_1
335 | - scikit-learn=1.1.3=py38h6a678d5_0
336 | - scipy=1.9.3=py38h8ce737c_2
337 | - seaborn=0.12.1=py38h06a4308_0
338 | - send2trash=1.8.0=pyhd3eb1b0_1
339 | - setuptools=65.6.3=pyhd8ed1ab_0
340 | - sip=6.7.5=py38hfa26641_0
341 | - six=1.16.0=pyhd3eb1b0_1
342 | - sniffio=1.2.0=py38h06a4308_1
343 | - soupsieve=2.3.2.post1=py38h06a4308_0
344 | - sqlite=3.40.0=h5082296_0
345 | - stack_data=0.2.0=pyhd3eb1b0_0
346 | - svt-av1=1.4.1=hcb278e6_0
347 | - tbb=2021.6.0=hdb19cb5_0
348 | - tbb-devel=2021.6.0=hdb19cb5_0
349 | - tensorboard=2.10.0=py38h06a4308_0
350 | - tensorboard-data-server=0.6.1=py38h52d8a92_0
351 | - tensorboard-plugin-wit=1.8.1=py38h06a4308_0
352 | - tensorboardx=2.2=pyhd3eb1b0_0
353 | - terminado=0.13.1=py38h06a4308_0
354 | - threadpoolctl=2.2.0=pyh0d69192_0
355 | - tinycss2=1.2.1=py38h06a4308_0
356 | - tk=8.6.12=h27826a3_0
357 | - toml=0.10.2=pyhd3eb1b0_0
358 | - tomli=2.0.1=py38h06a4308_0
359 | - torchaudio=0.13.1=py38_cu117
360 | - torchvision=0.14.1=py38_cu117
361 | - tornado=6.2=py38h5eee18b_0
362 | - tqdm=4.64.1=py38h06a4308_0
363 | - traitlets=5.7.1=py38h06a4308_0
364 | - urllib3=1.26.13=pyhd8ed1ab_0
365 | - utfcpp=3.2.1=h06a4308_0
366 | - vtk=9.2.2=qt_py38he961636_204
367 | - wcwidth=0.2.5=pyhd3eb1b0_0
368 | - webencodings=0.5.1=py38_1
369 | - websocket-client=0.58.0=py38h06a4308_4
370 | - werkzeug=2.2.2=py38h06a4308_0
371 | - wheel=0.38.4=pyhd8ed1ab_0
372 | - widgetsnbextension=3.5.2=py38h06a4308_0
373 | - wslink=1.10.0=pyhd8ed1ab_0
374 | - x264=1!164.3095=h166bdaf_2
375 | - x265=3.5=h924138e_3
376 | - xcb-util=0.4.0=h516909a_0
377 | - xcb-util-image=0.4.0=h166bdaf_0
378 | - xcb-util-keysyms=0.4.0=h516909a_0
379 | - xcb-util-renderutil=0.3.9=h166bdaf_0
380 | - xcb-util-wm=0.4.1=h516909a_0
381 | - xorg-fixesproto=5.0=h7f98852_1002
382 | - xorg-kbproto=1.0.7=h7f98852_1002
383 | - xorg-libice=1.0.10=h7f98852_0
384 | - xorg-libsm=1.2.3=hd9c2040_1000
385 | - xorg-libx11=1.7.2=h7f98852_0
386 | - xorg-libxau=1.0.9=h7f98852_0
387 | - xorg-libxdmcp=1.1.3=h7f98852_0
388 | - xorg-libxext=1.3.4=h7f98852_1
389 | - xorg-libxfixes=5.0.3=h7f98852_1004
390 | - xorg-libxt=1.2.1=h7f98852_2
391 | - xorg-xextproto=7.3.0=h7f98852_1002
392 | - xorg-xproto=7.0.31=h27cfd23_1007
393 | - xz=5.2.6=h166bdaf_0
394 | - yaml=0.2.5=h7b6447c_0
395 | - yarl=1.8.1=py38h5eee18b_0
396 | - zeromq=4.3.4=h2531618_0
397 | - zipp=3.8.0=py38h06a4308_0
398 | - zlib=1.2.13=h166bdaf_4
399 | - zstd=1.5.2=h6239696_4
400 | - pip:
401 | - addict==2.4.0
402 | - annotated-types==0.7.0
403 | - astroid==2.15.0
404 | - configargparse==1.5.3
405 | - dash==2.7.1
406 | - dash-core-components==2.0.0
407 | - dash-html-components==2.0.0
408 | - dash-table==5.0.0
409 | - dgl==0.9.1
410 | - dill==0.3.6
411 | - distro==1.9.0
412 | - flask==2.2.2
413 | - freetype-py==2.3.0
414 | - h11==0.14.0
415 | - httpcore==1.0.5
416 | - httpx==0.27.0
417 | - imageio==2.23.0
418 | - isort==5.12.0
419 | - itsdangerous==2.1.2
420 | - lazy-object-proxy==1.9.0
421 | - nbformat==5.5.0
422 | - networkx==2.2
423 | - open3d==0.16.0
424 | - openai==1.36.1
425 | - opencv-python==4.10.0.84
426 | - plotly==5.11.0
427 | - pycollada==0.6
428 | - pydantic==2.8.2
429 | - pydantic-core==2.20.1
430 | - pyglet==2.0.2.1
431 | - pylint==2.17.0
432 | - pyopengl==3.1.0
433 | - pyquaternion==0.9.9
434 | - pyrender==0.1.45
435 | - tenacity==8.1.0
436 | - tomlkit==0.11.6
437 | - trimesh==3.17.1
438 | - typing-extensions==4.12.2
439 | - urdfpy==0.0.22
440 | - wrapt==1.15.0
441 |
--------------------------------------------------------------------------------
/images/teaser_v1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yixuanhuang98/Points2Plans/78c0b0f0a23d2a352022584d369398741c553772/images/teaser_v1.png
--------------------------------------------------------------------------------
/relational_dynamics/.DS_Store:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yixuanhuang98/Points2Plans/78c0b0f0a23d2a352022584d369398741c553772/relational_dynamics/.DS_Store
--------------------------------------------------------------------------------
/relational_dynamics/__pycache__/__init__.cpython-38.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yixuanhuang98/Points2Plans/78c0b0f0a23d2a352022584d369398741c553772/relational_dynamics/__pycache__/__init__.cpython-38.pyc
--------------------------------------------------------------------------------
/relational_dynamics/__pycache__/base_RD.cpython-38.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yixuanhuang98/Points2Plans/78c0b0f0a23d2a352022584d369398741c553772/relational_dynamics/__pycache__/base_RD.cpython-38.pyc
--------------------------------------------------------------------------------
/relational_dynamics/config/__pycache__/base_config.cpython-38.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yixuanhuang98/Points2Plans/78c0b0f0a23d2a352022584d369398741c553772/relational_dynamics/config/__pycache__/base_config.cpython-38.pyc
--------------------------------------------------------------------------------
/relational_dynamics/config/base_config.py:
--------------------------------------------------------------------------------
1 | import numpy as np
2 |
3 | import torch
4 | import os
5 |
6 | class BaseConfig(object):
7 | def __init__(self, args, dtype=torch.FloatTensor, **kwargs):
8 | self.args = args
9 | self.result_dir = args.result_dir
10 | self.dtype = dtype
11 |
12 | def get_device(self):
13 | if self.dtype == torch.FloatTensor:
14 | return torch.device("cpu")
15 | else:
16 | return torch.device("cuda")
17 |
18 | def get_logger_dir(self):
19 | return os.path.join(self.result_dir, 'logs')
20 |
21 | def get_test_logger_dir(self):
22 | return os.path.join(self.result_dir, 'test_logs')
23 |
24 | def get_model_checkpoint_dir(self):
25 | return os.path.join(self.result_dir, 'checkpoint')
--------------------------------------------------------------------------------
/relational_dynamics/dataloader/__pycache__/__init__.cpython-38.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yixuanhuang98/Points2Plans/78c0b0f0a23d2a352022584d369398741c553772/relational_dynamics/dataloader/__pycache__/__init__.cpython-38.pyc
--------------------------------------------------------------------------------
/relational_dynamics/dataloader/__pycache__/dataloader.cpython-38.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yixuanhuang98/Points2Plans/78c0b0f0a23d2a352022584d369398741c553772/relational_dynamics/dataloader/__pycache__/dataloader.cpython-38.pyc
--------------------------------------------------------------------------------
/relational_dynamics/dataloader/__pycache__/farthest_point_sampling.cpython-38.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yixuanhuang98/Points2Plans/78c0b0f0a23d2a352022584d369398741c553772/relational_dynamics/dataloader/__pycache__/farthest_point_sampling.cpython-38.pyc
--------------------------------------------------------------------------------
/relational_dynamics/dataloader/__pycache__/real_robot_dataloader.cpython-38.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yixuanhuang98/Points2Plans/78c0b0f0a23d2a352022584d369398741c553772/relational_dynamics/dataloader/__pycache__/real_robot_dataloader.cpython-38.pyc
--------------------------------------------------------------------------------
/relational_dynamics/main.py:
--------------------------------------------------------------------------------
1 | import numpy as np
2 | import argparse
3 | import pickle
4 | import sys
5 | import os
6 | import pprint
7 | import torch
8 | import torch.nn as nn
9 | import torch.optim as optim
10 | import time
11 | import json
12 | import copy
13 | import random
14 | import torch.nn.functional as F
15 |
16 | sys.path.append(os.getcwd())
17 | from relational_dynamics.utils.colors import bcolors
18 | from relational_dynamics.utils.other_util import create_log_dirs
19 | from relational_dynamics.utils import parse_util
20 | from relational_dynamics.config.base_config import BaseConfig
21 | from relational_dynamics.base_RD import RelationalDynamics
22 |
23 | def main(args):
24 | dtype = torch.FloatTensor
25 | if args.cuda:
26 | dtype = torch.cuda.FloatTensor
27 |
28 | config = BaseConfig(args, dtype=dtype)
29 | create_log_dirs(config)
30 |
31 | if len(args.checkpoint_path) > 0:
32 | planner = RelationalDynamics(config)
33 | planner.load_checkpoint(args.checkpoint_path)
34 | result_dict = planner.RD(train=False, threshold = 0)
35 | else:
36 | trainer = RelationalDynamics(config)
37 | result_dict = trainer.RD()
38 |
39 | if __name__ == '__main__':
40 | parser = parse_util.get_parser()
41 | args = parser.parse_args()
42 | np.set_printoptions(precision=4, linewidth=120)
43 | if args.set_random_seed:
44 | seed = args.seed
45 | random.seed(args.seed)
46 | np.random.seed(seed)
47 | torch.manual_seed(seed)
48 | torch.cuda.manual_seed_all(seed)
49 | torch.backends.cudnn.deterministic = True
50 | torch.backends.cudnn.benchmark = False
51 |
52 | main(args)
53 |
--------------------------------------------------------------------------------
/relational_dynamics/model/__pycache__/GNN_pytorch_geometry.cpython-38.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yixuanhuang98/Points2Plans/78c0b0f0a23d2a352022584d369398741c553772/relational_dynamics/model/__pycache__/GNN_pytorch_geometry.cpython-38.pyc
--------------------------------------------------------------------------------
/relational_dynamics/model/__pycache__/__init__.cpython-38.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yixuanhuang98/Points2Plans/78c0b0f0a23d2a352022584d369398741c553772/relational_dynamics/model/__pycache__/__init__.cpython-38.pyc
--------------------------------------------------------------------------------
/relational_dynamics/model/__pycache__/contact_model.cpython-38.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yixuanhuang98/Points2Plans/78c0b0f0a23d2a352022584d369398741c553772/relational_dynamics/model/__pycache__/contact_model.cpython-38.pyc
--------------------------------------------------------------------------------
/relational_dynamics/model/__pycache__/encoder_decoder.cpython-38.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yixuanhuang98/Points2Plans/78c0b0f0a23d2a352022584d369398741c553772/relational_dynamics/model/__pycache__/encoder_decoder.cpython-38.pyc
--------------------------------------------------------------------------------
/relational_dynamics/model/__pycache__/losses.cpython-38.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yixuanhuang98/Points2Plans/78c0b0f0a23d2a352022584d369398741c553772/relational_dynamics/model/__pycache__/losses.cpython-38.pyc
--------------------------------------------------------------------------------
/relational_dynamics/model/__pycache__/models.cpython-38.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yixuanhuang98/Points2Plans/78c0b0f0a23d2a352022584d369398741c553772/relational_dynamics/model/__pycache__/models.cpython-38.pyc
--------------------------------------------------------------------------------
/relational_dynamics/model/__pycache__/pointconv_util_groupnorm.cpython-38.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yixuanhuang98/Points2Plans/78c0b0f0a23d2a352022584d369398741c553772/relational_dynamics/model/__pycache__/pointconv_util_groupnorm.cpython-38.pyc
--------------------------------------------------------------------------------
/relational_dynamics/model/models.py:
--------------------------------------------------------------------------------
1 | import numpy as np
2 | import torch
3 | import torch.nn as nn
4 | import torch.nn.functional as F
5 |
6 | from torch.nn import TransformerEncoder, TransformerEncoderLayer
7 | from relational_dynamics.model.pointconv_util_groupnorm import PointConvDensitySetAbstraction
8 |
9 | class EmbeddingNetTorch(nn.Module):
10 | def __init__(
11 | self, n_objects: int,
12 | width: int, layers: int, heads: int, input_feature_num: int,
13 | d_hidden: int, n_unary: int, n_binary: int,
14 | dim_feedforward: int,
15 | use_discrete_place = False,
16 | latent_discrete_continuous = False,
17 | seperate_discrete_continuous = False,
18 | simple_encoding = False,
19 | transformer_dynamics = False,
20 | torch_embedding = False,
21 | complicated_pre_dynamics = False,
22 | train_env_identity = False,
23 | total_env_identity = 1,
24 | one_bit_env = False,
25 | direct_transformer = False,
26 | enable_high_push = False,
27 | enable_place_inside = False,
28 | seperate_place = False,
29 | use_seperate_latent_embedding = True,
30 | seperate_action_emb = False,
31 | use_mlp_encoder = False,
32 | ):
33 | super(EmbeddingNetTorch, self).__init__()
34 | d_input = width
35 |
36 | self.use_seperate_latent_embedding = use_seperate_latent_embedding
37 |
38 | self.train_env_identity = train_env_identity
39 |
40 | self.direct_transformer = direct_transformer
41 |
42 | self.enable_high_push = enable_high_push
43 |
44 | self.enable_place_inside = enable_place_inside
45 |
46 | self.seperate_place = seperate_place
47 |
48 | self.seperate_action_emb = seperate_action_emb
49 |
50 | self.seperate_discrete_continuous = seperate_discrete_continuous
51 |
52 | self.simple_encoding = simple_encoding
53 |
54 | self.transformer_dynamics = transformer_dynamics
55 |
56 | self.torch_embedding = torch_embedding
57 |
58 | self.complicated_pre_dynamics = complicated_pre_dynamics
59 |
60 | encoder_layers = TransformerEncoderLayer(width, heads, batch_first = True, dim_feedforward = dim_feedforward)
61 |
62 | self.transformer = TransformerEncoder(encoder_layers, layers)
63 |
64 | self.one_hot_encoding_dim = (int)(width/2)
65 |
66 | self.one_hot_encoding_embed = nn.Sequential(
67 | nn.Embedding(n_objects, self.one_hot_encoding_dim)
68 | )
69 |
70 | self.continuous_action_emb = nn.Sequential(
71 | nn.Linear(2, self.one_hot_encoding_dim),
72 | nn.ReLU(),
73 | nn.Linear(self.one_hot_encoding_dim, self.one_hot_encoding_dim)
74 | )
75 | self.continuous_action_emb_1 = nn.Sequential(
76 | nn.Linear(2, self.one_hot_encoding_dim),
77 | nn.ReLU(),
78 | nn.Linear(self.one_hot_encoding_dim, self.one_hot_encoding_dim)
79 | )
80 |
81 | encoder_layers_1 = TransformerEncoderLayer(width, heads, batch_first = True, dim_feedforward = dim_feedforward)
82 | self.graph_dynamics_0 = TransformerEncoder(encoder_layers_1, layers)
83 | encoder_layers_2 = TransformerEncoderLayer(width, heads, batch_first = True, dim_feedforward = dim_feedforward)
84 | self.graph_dynamics_1 = TransformerEncoder(encoder_layers_2, layers)
85 |
86 | self.n_unary = n_unary
87 | self.n_binary = n_binary
88 | self.d_hidden = d_hidden
89 |
90 | self.f_unary = self.get_head_unary(d_input, d_hidden, 1, n_unary)
91 | self.f_binary = self.get_head(d_input, d_hidden, 2, n_binary)
92 |
93 |
94 | self.ln_post = nn.LayerNorm(width)
95 |
96 | def get_head(self, d_input, d_hidden, n_args, n_binary):
97 | if d_hidden > 1:
98 | head = nn.Sequential(
99 | nn.Linear(d_input * n_args, d_hidden),
100 | nn.ReLU(),
101 | nn.Linear(d_hidden, d_hidden),
102 | nn.ReLU(),
103 | nn.Linear(d_hidden, n_binary),
104 | nn.Sigmoid()
105 | )
106 | else:
107 | head = nn.Sequential(
108 | nn.Linear(d_input * n_args, d_hidden),
109 | nn.Sigmoid()
110 | )
111 | return head
112 |
113 | def get_head_unary(self, d_input, d_hidden, n_args, n_unary):
114 | if d_hidden > 1:
115 | head = nn.Sequential(
116 | nn.Linear(d_input * n_args, d_hidden),
117 | nn.ReLU(),
118 | nn.Linear(d_hidden, n_unary)
119 | )
120 | else:
121 | head = nn.Sequential(
122 | nn.Linear(d_input * n_args, d_hidden)
123 | )
124 | return head
125 |
126 | class QuickReadoutNet(nn.Module):
127 | def __init__(
128 | self, n_objects: int,
129 | width: int, layers: int, heads: int, input_feature_num: int,
130 | d_hidden: int, n_unary: int, n_binary: int,
131 | dim_feedforward: int,
132 | pose_num: int,
133 | train_env_identity = False, total_env_identity = 2,
134 | train_grasp_identity = False,
135 | train_inside_feasibility = False,
136 | binary_grasp = False,
137 | open_close_drawer = False,
138 | softmax_identity = False,
139 | seperate_identity = False,
140 | train_obj_boundary = False,
141 | train_obj_move = False,
142 | one_bit_env = False,
143 | pe = False,
144 | transformer_decoder = False,
145 | remove_orientation = False,
146 | pose_trans_decoder = False,
147 | ):
148 | super(QuickReadoutNet, self).__init__()
149 | d_input = width
150 |
151 | self.train_env_identity = train_env_identity
152 | self.train_grasp_identity = train_grasp_identity
153 | self.train_inside_feasibility = train_inside_feasibility
154 | self.binary_grasp = binary_grasp
155 |
156 | self.open_close_drawer = open_close_drawer
157 | self.softmax_identity = softmax_identity
158 | self.seperate_identity = seperate_identity
159 | self.train_obj_boundary = train_obj_boundary
160 | self.train_obj_move = train_obj_move
161 | self.pe = pe
162 | self.transformer_decoder = transformer_decoder
163 | self.pose_trans_decoder = pose_trans_decoder
164 | self.remove_orientation = remove_orientation
165 |
166 | total_env_identity = 3
167 |
168 |
169 | self.one_hot_encoding_dim = (int)(width/2)
170 |
171 | self.one_hot_encoding_embed = nn.Sequential(
172 | nn.Linear(n_objects, self.one_hot_encoding_dim),
173 | nn.ReLU(inplace=True),
174 | nn.Linear(self.one_hot_encoding_dim, self.one_hot_encoding_dim)
175 | )
176 |
177 | self.action_emb = nn.Sequential(
178 | nn.Linear(input_feature_num, width),
179 | nn.ReLU(),
180 | nn.Linear(width, width)
181 | )
182 |
183 | self.env_output_identity = nn.Sequential(
184 | nn.Linear(d_input, d_hidden),
185 | nn.ReLU(),
186 | nn.Linear(d_hidden, total_env_identity),
187 | nn.Sigmoid()
188 | )
189 |
190 |
191 | self.grasp_output_identity = self.get_head(d_input, d_hidden, 2, 2)
192 |
193 |
194 | self.pose_estimation = nn.Sequential(
195 | nn.Linear(d_input, d_hidden),
196 | nn.ReLU(),
197 | nn.Linear(d_hidden, pose_num)
198 | )
199 |
200 | self.n_unary = n_unary
201 | self.n_binary = n_binary
202 | self.d_hidden = d_hidden
203 |
204 | self.f_unary = self.get_head_unary(d_input, d_hidden, 1, n_unary)
205 | self.f_binary = self.get_head(d_input, d_hidden, 2, n_binary)
206 | self.ln_post = nn.LayerNorm(width)
207 |
208 | def get_head(self, d_input, d_hidden, n_args, n_binary):
209 | if d_hidden > 1:
210 | head = nn.Sequential(
211 | nn.Linear(d_input * n_args, d_hidden),
212 | nn.ReLU(),
213 | nn.Linear(d_hidden, d_hidden),
214 | nn.ReLU(),
215 | nn.Linear(d_hidden, n_binary),
216 | nn.Sigmoid()
217 | )
218 | else:
219 | head = nn.Sequential(
220 | nn.Linear(d_input * n_args, d_hidden),
221 | nn.Sigmoid()
222 | )
223 | return head
224 |
225 | def get_head_unary(self, d_input, d_hidden, n_args, n_unary):
226 | if d_hidden > 1:
227 | head = nn.Sequential(
228 | nn.Linear(d_input * n_args, d_hidden),
229 | nn.ReLU(),
230 | nn.Linear(d_hidden, n_unary)
231 | )
232 | else:
233 | head = nn.Sequential(
234 | nn.Linear(d_input * n_args, d_hidden)
235 | )
236 | return head
237 |
238 |
239 | def forward(self, objs, edge_index):
240 |
241 | batch_size, n_obj = objs.shape[:2] # # shape = [*, n_obj, width]
242 |
243 | x = objs # x = (pointconv feature + one hot encoding(128)) *
244 |
245 |
246 | z = self.f_unary(x)
247 |
248 | self.env_identity = self.env_output_identity(x)
249 |
250 | self.predicted_pose = self.pose_estimation(x)
251 |
252 | x1 = x[:, edge_index[0, :], :]
253 |
254 | x2 = x[:, edge_index[1, :], :]
255 |
256 | concat_x = torch.cat([x1, x2], dim=-1)
257 | y = self.f_binary(concat_x)
258 |
259 | self.binary_grasp_identity = self.grasp_output_identity(concat_x)
260 |
261 | return_dict = {'pred': z,
262 | 'current_embed': x,
263 | 'pred_sigmoid': y,
264 | 'env_identity': self.env_identity,
265 | 'grasp_identity': self.binary_grasp_identity,
266 | 'predicted_pose': self.predicted_pose}
267 |
268 | return return_dict
269 |
270 |
271 | class PointConv(nn.Module):
272 | def __init__(self, normal_channel=False, use_rgb=False, output_dim = 128):
273 | super(PointConv, self).__init__()
274 |
275 | if normal_channel:
276 | additional_channel = 3
277 | else:
278 | additional_channel = 0
279 |
280 | if use_rgb:
281 | rgb_channel = 3
282 | else:
283 | rgb_channel = 0
284 | self.output_dim = output_dim
285 | self.normal_channel = normal_channel
286 |
287 | self.sa1 = PointConvDensitySetAbstraction(npoint=128, nsample=8, in_channel=6+additional_channel+rgb_channel, mlp=[32], bandwidth = 0.1, group_all=False)
288 | self.sa2 = PointConvDensitySetAbstraction(npoint=64, nsample=16, in_channel= 32 + 3, mlp=[64], bandwidth = 0.2, group_all=False)
289 | self.sa3 = PointConvDensitySetAbstraction(npoint=1, nsample=None, in_channel= 64 + 3, mlp=[output_dim], bandwidth = 0.4, group_all=True)
290 |
291 | def forward(self, xyz):
292 | # Set Abstraction layers
293 | B,C,N = xyz.shape
294 | if self.normal_channel:
295 | l0_points = xyz
296 | l0_xyz = xyz[:,:3,:]
297 | else:
298 | l0_points = xyz
299 | l0_xyz = xyz[:, :3, :]
300 |
301 | l1_xyz, l1_points = self.sa1(l0_xyz, l0_points)
302 | l2_xyz, l2_points = self.sa2(l1_xyz, l1_points)
303 | l3_xyz, l3_points = self.sa3(l2_xyz, l2_points)
304 | x = l3_points.view(B, self.output_dim)
305 |
306 | return x
307 |
--------------------------------------------------------------------------------
/relational_dynamics/model/pointconv_util_groupnorm.py:
--------------------------------------------------------------------------------
1 | """
2 | Utility function for PointConv
3 | Originally from : https://github.com/yanx27/Pointnet_Pointnet2_pytorch/blob/master/utils.py
4 | Modify by Wenxuan Wu
5 | Date: September 2019
6 | """
7 | import torch
8 | import torch.nn as nn
9 | import torch.nn.functional as F
10 | from time import time
11 | import numpy as np
12 | # from sklearn.neighbors.kde import KernelDensity
13 |
14 | def timeit(tag, t):
15 | print("{}: {}s".format(tag, time() - t))
16 | return time()
17 |
18 | def square_distance(src, dst):
19 | """
20 | Calculate Euclid distance between each two points.
21 | src^T * dst = xn * xm + yn * ym + zn * zm;
22 | sum(src^2, dim=-1) = xn*xn + yn*yn + zn*zn;
23 | sum(dst^2, dim=-1) = xm*xm + ym*ym + zm*zm;
24 | dist = (xn - xm)^2 + (yn - ym)^2 + (zn - zm)^2
25 | = sum(src**2,dim=-1)+sum(dst**2,dim=-1)-2*src^T*dst
26 | Input:
27 | src: source points, [B, N, C]
28 | dst: target points, [B, M, C]
29 | Output:
30 | dist: per-point square distance, [B, N, M]
31 | """
32 | B, N, _ = src.shape
33 | _, M, _ = dst.shape
34 | dist = -2 * torch.matmul(src, dst.permute(0, 2, 1))
35 | dist += torch.sum(src ** 2, -1).view(B, N, 1)
36 | dist += torch.sum(dst ** 2, -1).view(B, 1, M)
37 | return dist
38 |
39 | def index_points(points, idx):
40 | """
41 | Input:
42 | points: input points data, [B, N, C]
43 | idx: sample index data, [B, S]
44 | Return:
45 | new_points:, indexed points data, [B, S, C]
46 | """
47 | device = points.device
48 | B = points.shape[0]
49 | view_shape = list(idx.shape)
50 | view_shape[1:] = [1] * (len(view_shape) - 1)
51 | repeat_shape = list(idx.shape)
52 | repeat_shape[0] = 1
53 | batch_indices = torch.arange(B, dtype=torch.long).to(device).view(view_shape).repeat(repeat_shape)
54 | new_points = points[batch_indices, idx, :]
55 | return new_points
56 |
57 | def farthest_point_sample(xyz, npoint):
58 | """
59 | Input:
60 | xyz: pointcloud data, [B, N, C]
61 | npoint: number of samples
62 | Return:
63 | centroids: sampled pointcloud index, [B, npoint]
64 | """
65 | #import ipdb; ipdb.set_trace()
66 | device = xyz.device
67 | B, N, C = xyz.shape
68 | centroids = torch.zeros(B, npoint, dtype=torch.long).to(device)
69 | distance = torch.ones(B, N).to(device) * 1e10
70 | #farthest = torch.randint(0, N, (B,), dtype=torch.long).to(device)
71 | farthest = torch.zeros(B, dtype=torch.long).to(device)
72 | batch_indices = torch.arange(B, dtype=torch.long).to(device)
73 | for i in range(npoint):
74 | centroids[:, i] = farthest
75 | centroid = xyz[batch_indices, farthest, :].view(B, 1, 3)
76 | dist = torch.sum((xyz - centroid) ** 2, -1)
77 | mask = dist < distance
78 | distance[mask] = dist[mask]
79 | farthest = torch.max(distance, -1)[1]
80 | return centroids
81 |
82 | def query_ball_point(radius, nsample, xyz, new_xyz):
83 | """
84 | Input:
85 | radius: local region radius
86 | nsample: max sample number in local region
87 | xyz: all points, [B, N, C]
88 | new_xyz: query points, [B, S, C]
89 | Return:
90 | group_idx: grouped points index, [B, S, nsample]
91 | """
92 | device = xyz.device
93 | B, N, C = xyz.shape
94 | _, S, _ = new_xyz.shape
95 | group_idx = torch.arange(N, dtype=torch.long).to(device).view(1, 1, N).repeat([B, S, 1])
96 | sqrdists = square_distance(new_xyz, xyz)
97 | group_idx[sqrdists > radius ** 2] = N
98 | group_idx = group_idx.sort(dim=-1)[0][:, :, :nsample]
99 | group_first = group_idx[:, :, 0].view(B, S, 1).repeat([1, 1, nsample])
100 | mask = group_idx == N
101 | group_idx[mask] = group_first[mask]
102 | return group_idx
103 |
104 | def knn_point(nsample, xyz, new_xyz):
105 | """
106 | Input:
107 | nsample: max sample number in local region
108 | xyz: all points, [B, N, C]
109 | new_xyz: query points, [B, S, C]
110 | Return:
111 | group_idx: grouped points index, [B, S, nsample]
112 | """
113 | sqrdists = square_distance(new_xyz, xyz)
114 | _, group_idx = torch.topk(sqrdists, nsample, dim = -1, largest=False, sorted=False)
115 | return group_idx
116 |
117 | def sample_and_group(npoint, nsample, xyz, points, density_scale = None):
118 | """
119 | Input:
120 | npoint:
121 | nsample:
122 | xyz: input points position data, [B, N, C]
123 | points: input points data, [B, N, D]
124 | Return:
125 | new_xyz: sampled points position data, [B, 1, C]
126 | new_points: sampled points data, [B, 1, N, C+D]
127 | """
128 | B, N, C = xyz.shape
129 | S = npoint
130 | fps_idx = farthest_point_sample(xyz, npoint) # [B, npoint, C]
131 | new_xyz = index_points(xyz, fps_idx)
132 | idx = knn_point(nsample, xyz, new_xyz)
133 | grouped_xyz = index_points(xyz, idx) # [B, npoint, nsample, C]
134 | grouped_xyz_norm = grouped_xyz - new_xyz.view(B, S, 1, C)
135 | if points is not None:
136 | grouped_points = index_points(points, idx)
137 | new_points = torch.cat([grouped_xyz_norm, grouped_points], dim=-1) # [B, npoint, nsample, C+D]
138 | else:
139 | new_points = grouped_xyz_norm
140 |
141 | if density_scale is None:
142 | return new_xyz, new_points, grouped_xyz_norm, idx
143 | else:
144 | grouped_density = index_points(density_scale, idx)
145 | return new_xyz, new_points, grouped_xyz_norm, idx, grouped_density
146 |
147 | def sample_and_group_all(xyz, points, density_scale = None):
148 | """
149 | Input:
150 | xyz: input points position data, [B, N, C]
151 | points: input points data, [B, N, D]
152 | Return:
153 | new_xyz: sampled points position data, [B, 1, C]
154 | new_points: sampled points data, [B, 1, N, C+D]
155 | """
156 | device = xyz.device
157 | B, N, C = xyz.shape
158 | #new_xyz = torch.zeros(B, 1, C).to(device)
159 | new_xyz = xyz.mean(dim = 1, keepdim = True)
160 | grouped_xyz = xyz.view(B, 1, N, C) - new_xyz.view(B, 1, 1, C)
161 | if points is not None:
162 | new_points = torch.cat([grouped_xyz, points.view(B, 1, N, -1)], dim=-1)
163 | else:
164 | new_points = grouped_xyz
165 | if density_scale is None:
166 | return new_xyz, new_points, grouped_xyz
167 | else:
168 | grouped_density = density_scale.view(B, 1, N, 1)
169 | return new_xyz, new_points, grouped_xyz, grouped_density
170 |
171 | def group(nsample, xyz, points):
172 | """
173 | Input:
174 | npoint:
175 | nsample:
176 | xyz: input points position data, [B, N, C]
177 | points: input points data, [B, N, D]
178 | Return:
179 | new_xyz: sampled points position data, [B, 1, C]
180 | new_points: sampled points data, [B, 1, N, C+D]
181 | """
182 | B, N, C = xyz.shape
183 | S = N
184 | new_xyz = xyz
185 | idx = knn_point(nsample, xyz, new_xyz)
186 | grouped_xyz = index_points(xyz, idx) # [B, npoint, nsample, C]
187 | grouped_xyz_norm = grouped_xyz - new_xyz.view(B, S, 1, C)
188 | if points is not None:
189 | grouped_points = index_points(points, idx)
190 | new_points = torch.cat([grouped_xyz_norm, grouped_points], dim=-1) # [B, npoint, nsample, C+D]
191 | else:
192 | new_points = grouped_xyz_norm
193 |
194 | return new_points, grouped_xyz_norm
195 |
196 | def compute_density(xyz, bandwidth):
197 | '''
198 | xyz: input points position data, [B, N, C]
199 | '''
200 | #import ipdb; ipdb.set_trace()
201 | B, N, C = xyz.shape
202 | sqrdists = square_distance(xyz, xyz)
203 | gaussion_density = torch.exp(- sqrdists / (2.0 * bandwidth * bandwidth)) / (2.5 * bandwidth)
204 | xyz_density = gaussion_density.mean(dim = -1)
205 |
206 | return xyz_density
207 |
208 | class DensityNet(nn.Module):
209 | def __init__(self, hidden_unit = [16, 8]):
210 | super(DensityNet, self).__init__()
211 | self.mlp_convs = nn.ModuleList()
212 | self.mlp_bns = nn.ModuleList()
213 |
214 | self.mlp_convs.append(nn.Conv2d(1, hidden_unit[0], 1))
215 | self.mlp_bns.append(nn.GroupNorm(1, hidden_unit[0]))
216 | for i in range(1, len(hidden_unit)):
217 | self.mlp_convs.append(nn.Conv2d(hidden_unit[i - 1], hidden_unit[i], 1))
218 | self.mlp_bns.append(nn.GroupNorm(1, hidden_unit[i]))
219 | self.mlp_convs.append(nn.Conv2d(hidden_unit[-1], 1, 1))
220 | self.mlp_bns.append(nn.GroupNorm(1, 1))
221 |
222 | def forward(self, density_scale):
223 | for i, conv in enumerate(self.mlp_convs):
224 | bn = self.mlp_bns[i]
225 | density_scale = bn(conv(density_scale))
226 | if i == len(self.mlp_convs):
227 | density_scale = F.sigmoid(density_scale)
228 | else:
229 | density_scale = F.relu(density_scale)
230 |
231 | return density_scale
232 |
233 | class WeightNet(nn.Module):
234 |
235 | def __init__(self, in_channel, out_channel, hidden_unit = [8, 8]):
236 | super(WeightNet, self).__init__()
237 |
238 | self.mlp_convs = nn.ModuleList()
239 | self.mlp_bns = nn.ModuleList()
240 | if hidden_unit is None or len(hidden_unit) == 0:
241 | self.mlp_convs.append(nn.Conv2d(in_channel, out_channel, 1))
242 | self.mlp_bns.append(nn.GroupNorm(1, out_channel))
243 | else:
244 | self.mlp_convs.append(nn.Conv2d(in_channel, hidden_unit[0], 1))
245 | self.mlp_bns.append(nn.GroupNorm(1, hidden_unit[0]))
246 | for i in range(1, len(hidden_unit)):
247 | self.mlp_convs.append(nn.Conv2d(hidden_unit[i - 1], hidden_unit[i], 1))
248 | self.mlp_bns.append(nn.GroupNorm(1, hidden_unit[i]))
249 | self.mlp_convs.append(nn.Conv2d(hidden_unit[-1], out_channel, 1))
250 | self.mlp_bns.append(nn.GroupNorm(1, out_channel))
251 |
252 | def forward(self, localized_xyz):
253 | #xyz : BxCxKxN
254 |
255 | weights = localized_xyz
256 | for i, conv in enumerate(self.mlp_convs):
257 | bn = self.mlp_bns[i]
258 | weights = F.relu(bn(conv(weights)))
259 |
260 | return weights
261 |
262 | class PointConvSetAbstraction(nn.Module):
263 | def __init__(self, npoint, nsample, in_channel, mlp, group_all):
264 | super(PointConvSetAbstraction, self).__init__()
265 | self.npoint = npoint
266 | self.nsample = nsample
267 | self.mlp_convs = nn.ModuleList()
268 | self.mlp_bns = nn.ModuleList()
269 | last_channel = in_channel
270 | for out_channel in mlp:
271 | self.mlp_convs.append(nn.Conv2d(last_channel, out_channel, 1))
272 | self.mlp_bns.append(nn.GroupNorm(1, out_channel))
273 | last_channel = out_channel
274 |
275 | self.weightnet = WeightNet(3, 16)
276 | self.linear = nn.Linear(16 * mlp[-1], mlp[-1])
277 | self.bn_linear = nn.GroupNorm(1, mlp[-1])
278 | self.group_all = group_all
279 |
280 | def forward(self, xyz, points):
281 | """
282 | Input:
283 | xyz: input points position data, [B, C, N]
284 | points: input points data, [B, D, N]
285 | Return:
286 | new_xyz: sampled points position data, [B, C, S]
287 | new_points_concat: sample points feature data, [B, D', S]
288 | """
289 | B = xyz.shape[0]
290 | xyz = xyz.permute(0, 2, 1)
291 | if points is not None:
292 | points = points.permute(0, 2, 1)
293 |
294 | if self.group_all:
295 | new_xyz, new_points, grouped_xyz_norm = sample_and_group_all(xyz, points)
296 | else:
297 | new_xyz, new_points, grouped_xyz_norm, _ = sample_and_group(self.npoint, self.nsample, xyz, points)
298 | # new_xyz: sampled points position data, [B, npoint, C]
299 | # new_points: sampled points data, [B, npoint, nsample, C+D]
300 | new_points = new_points.permute(0, 3, 2, 1) # [B, C+D, nsample,npoint]
301 | for i, conv in enumerate(self.mlp_convs):
302 | bn = self.mlp_bns[i]
303 | new_points = F.relu(bn(conv(new_points)))
304 |
305 | grouped_xyz = grouped_xyz_norm.permute(0, 3, 2, 1)
306 | weights = self.weightnet(grouped_xyz)
307 | new_points = torch.matmul(input=new_points.permute(0, 3, 1, 2), other = weights.permute(0, 3, 2, 1)).view(B, self.npoint, -1)
308 | new_points = self.linear(new_points)
309 | new_points = self.bn_linear(new_points.permute(0, 2, 1))
310 | new_points = F.relu(new_points)
311 | new_xyz = new_xyz.permute(0, 2, 1)
312 |
313 | return new_xyz, new_points
314 |
315 | class PointConvDensitySetAbstraction(nn.Module):
316 | def __init__(self, npoint, nsample, in_channel, mlp, bandwidth, group_all):
317 | super(PointConvDensitySetAbstraction, self).__init__()
318 | self.npoint = npoint
319 | self.nsample = nsample
320 | self.mlp_convs = nn.ModuleList()
321 | self.mlp_bns = nn.ModuleList()
322 | last_channel = in_channel
323 | for out_channel in mlp:
324 | self.mlp_convs.append(nn.Conv2d(last_channel, out_channel, 1))
325 | self.mlp_bns.append(nn.GroupNorm(1, out_channel))
326 | last_channel = out_channel
327 |
328 | self.weightnet = WeightNet(3, 16)
329 | self.linear = nn.Linear(16 * mlp[-1], mlp[-1])
330 | self.bn_linear = nn.GroupNorm(1, mlp[-1])
331 | self.densitynet = DensityNet()
332 | self.group_all = group_all
333 | self.bandwidth = bandwidth
334 |
335 | def forward(self, xyz, points):
336 | """
337 | Input:
338 | xyz: input points position data, [B, C, N]
339 | points: input points data, [B, D, N]
340 | Return:
341 | new_xyz: sampled points position data, [B, C, S]
342 | new_points_concat: sample points feature data, [B, D', S]
343 | """
344 | B = xyz.shape[0]
345 | N = xyz.shape[2]
346 | xyz = xyz.permute(0, 2, 1)
347 | if points is not None:
348 | points = points.permute(0, 2, 1)
349 |
350 | xyz_density = compute_density(xyz, self.bandwidth)
351 | inverse_density = 1.0 / xyz_density
352 |
353 | if self.group_all:
354 | new_xyz, new_points, grouped_xyz_norm, grouped_density = sample_and_group_all(xyz, points, inverse_density.view(B, N, 1))
355 | else:
356 | new_xyz, new_points, grouped_xyz_norm, _, grouped_density = sample_and_group(self.npoint, self.nsample, xyz, points, inverse_density.view(B, N, 1))
357 | # new_xyz: sampled points position data, [B, npoint, C]
358 | # new_points: sampled points data, [B, npoint, nsample, C+D]
359 | new_points = new_points.permute(0, 3, 2, 1) # [B, C+D, nsample,npoint]
360 | for i, conv in enumerate(self.mlp_convs):
361 | bn = self.mlp_bns[i]
362 | new_points = F.relu(bn(conv(new_points)))
363 |
364 | inverse_max_density = grouped_density.max(dim = 2, keepdim=True)[0]
365 | density_scale = grouped_density / inverse_max_density
366 | density_scale = self.densitynet(density_scale.permute(0, 3, 2, 1))
367 | new_points = new_points * density_scale
368 |
369 | grouped_xyz = grouped_xyz_norm.permute(0, 3, 2, 1)
370 | weights = self.weightnet(grouped_xyz)
371 | new_points = torch.matmul(input=new_points.permute(0, 3, 1, 2), other = weights.permute(0, 3, 2, 1)).view(B, self.npoint, -1)
372 | new_points = self.linear(new_points)
373 | new_points = self.bn_linear(new_points.permute(0, 2, 1))
374 | new_points = F.relu(new_points)
375 | new_xyz = new_xyz.permute(0, 2, 1)
376 |
377 | return new_xyz, new_points
--------------------------------------------------------------------------------
/relational_dynamics/utils/__pycache__/__init__.cpython-38.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yixuanhuang98/Points2Plans/78c0b0f0a23d2a352022584d369398741c553772/relational_dynamics/utils/__pycache__/__init__.cpython-38.pyc
--------------------------------------------------------------------------------
/relational_dynamics/utils/__pycache__/colors.cpython-38.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yixuanhuang98/Points2Plans/78c0b0f0a23d2a352022584d369398741c553772/relational_dynamics/utils/__pycache__/colors.cpython-38.pyc
--------------------------------------------------------------------------------
/relational_dynamics/utils/__pycache__/data_utils.cpython-38.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yixuanhuang98/Points2Plans/78c0b0f0a23d2a352022584d369398741c553772/relational_dynamics/utils/__pycache__/data_utils.cpython-38.pyc
--------------------------------------------------------------------------------
/relational_dynamics/utils/__pycache__/math_util.cpython-38.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yixuanhuang98/Points2Plans/78c0b0f0a23d2a352022584d369398741c553772/relational_dynamics/utils/__pycache__/math_util.cpython-38.pyc
--------------------------------------------------------------------------------
/relational_dynamics/utils/__pycache__/other_util.cpython-38.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yixuanhuang98/Points2Plans/78c0b0f0a23d2a352022584d369398741c553772/relational_dynamics/utils/__pycache__/other_util.cpython-38.pyc
--------------------------------------------------------------------------------
/relational_dynamics/utils/__pycache__/parse_util.cpython-38.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yixuanhuang98/Points2Plans/78c0b0f0a23d2a352022584d369398741c553772/relational_dynamics/utils/__pycache__/parse_util.cpython-38.pyc
--------------------------------------------------------------------------------
/relational_dynamics/utils/__pycache__/tensorboardx_logger.cpython-38.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yixuanhuang98/Points2Plans/78c0b0f0a23d2a352022584d369398741c553772/relational_dynamics/utils/__pycache__/tensorboardx_logger.cpython-38.pyc
--------------------------------------------------------------------------------
/relational_dynamics/utils/__pycache__/torch_util.cpython-38.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yixuanhuang98/Points2Plans/78c0b0f0a23d2a352022584d369398741c553772/relational_dynamics/utils/__pycache__/torch_util.cpython-38.pyc
--------------------------------------------------------------------------------
/relational_dynamics/utils/__pycache__/torch_utils.cpython-38.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yixuanhuang98/Points2Plans/78c0b0f0a23d2a352022584d369398741c553772/relational_dynamics/utils/__pycache__/torch_utils.cpython-38.pyc
--------------------------------------------------------------------------------
/relational_dynamics/utils/colors.py:
--------------------------------------------------------------------------------
1 | import numpy as np
2 |
3 | class bcolors:
4 | HEADER = '\033[95m'
5 | OKBLUE = '\033[94m'
6 | OKGREEN = '\033[92m'
7 | WARNING = '\033[93m'
8 | FAIL = '\033[91m'
9 | ENDC = '\033[0m'
10 |
11 | Black = '\033[30m'
12 | Red = '\033[31m'
13 | Green = '\033[32m'
14 | Yellow = '\033[33m'
15 | Blue = '\033[34m'
16 | Purple = '\033[35m'
17 | Cyan = '\033[36m'
18 | LightGray = '\033[37m'
19 | DarkGray = '\033[30m'
20 | LightRed = '\033[31m'
21 | LightGreen = '\033[32m'
22 | LightYellow = '\033[93m'
23 | LightBlue = '\033[34m'
24 | LightPurple = '\033[35m'
25 | LightCyan = '\033[36m'
26 | White = '\033[97m'
27 |
28 | BckgrDefault = '\033[49m'
29 | BckgrBlack = '\033[40m'
30 | BckgrRed = '\033[41m'
31 | BckgrGreen = '\033[42m'
32 | BckgrYellow = '\033[43m'
33 | BckgrBlue = '\033[44m'
34 | BckgrPurple = '\033[45m'
35 | BckgrCyan = '\033[46m'
36 | BckgrLightGray = '\033[47m'
37 | BckgrDarkGray = '\033[100m'
38 | BckgrLightRed = '\033[101m'
39 | BckgrLightGreen = '\033[102m'
40 | BckgrLightYellow = '\033[103m'
41 | BckgrLightBlue = '\033[104m'
42 | BckgrLightPurple = '\033[105m'
43 |
44 |
45 | @staticmethod
46 | def header(msg):
47 | return bcolors.HEADER + msg + bcolors.ENDC
48 |
49 | @staticmethod
50 | def okblue(msg):
51 | return bcolors.OKBLUE + msg + bcolors.ENDC
52 |
53 | @staticmethod
54 | def okgreen(msg):
55 | return bcolors.OKGREEN + msg + bcolors.ENDC
56 |
57 | @staticmethod
58 | def warning(msg):
59 | return bcolors.WARNING + msg + bcolors.ENDC
60 |
61 | @staticmethod
62 | def fail(msg):
63 | return bcolors.FAIL + msg + bcolors.ENDC
64 |
65 | @staticmethod
66 | def c_cyan(msg):
67 | return bcolors.Cyan + msg + bcolors.ENDC
68 |
69 | @staticmethod
70 | def c_red(msg):
71 | return bcolors.Red + msg + bcolors.ENDC
72 |
73 | @staticmethod
74 | def c_yellow(msg):
75 | return bcolors.Yellow + msg + bcolors.ENDC
76 |
77 | @staticmethod
78 | def c_blue(msg):
79 | return bcolors.Blue + msg + bcolors.ENDC
80 |
81 | @staticmethod
82 | def c_purple(msg):
83 | return bcolors.Purple + msg + bcolors.ENDC
84 |
85 | @staticmethod
86 | def c_green(msg):
87 | return bcolors.Green + msg + bcolors.ENDC
88 |
--------------------------------------------------------------------------------
/relational_dynamics/utils/data_utils.py:
--------------------------------------------------------------------------------
1 | import numpy as np
2 |
3 | import os
4 | import pickle
5 | import time
6 | import h5py
7 |
8 | import torch.nn as nn
9 |
10 | def scale_min_max(x, x_min, x_max, desired_min, desired_max):
11 | """
12 | Applies min/max scaling on one data instance.
13 |
14 | Args:
15 | x (ndarray): Data to be scaled.
16 | x_min (flt): Minimum value of data (over full dataset).
17 | x_max (flt): Maximum value of data (over full dataset).
18 | desired_min (flt): Desired minimum value.
19 | desired_max (flt): Desired maximum value.
20 | """
21 | return ((desired_max - desired_min) * (x - x_min) / (x_max - x_min)) + desired_min
22 |
23 | def rotate_2d(x, theta):
24 | """ Rotate x by theta degrees (counter clockwise)
25 |
26 | @param x: a 2D vector (numpy array with shape 2)
27 | @param theta: a scalar representing radians
28 | """
29 |
30 | rot_mat = np.array([
31 | [np.cos(theta), -np.sin(theta)],
32 | [np.sin(theta), np.cos(theta)]
33 | ], dtype=np.float32)
34 |
35 | return rot_mat.dot(x)
36 |
37 |
38 | def save_emb_data_to_h5(result_dir, result_dict):
39 | emb_h5_path = os.path.join(result_dir, 'train_result_emb.h5')
40 | emb_h5_f = h5py.File(emb_h5_path, 'w')
41 |
42 | # Create a new dictionary so that each scene emb which can have different
43 | # number of objects as compared to other scenes will be stored separately.
44 | result_h5_dict = {'emb': {}}
45 | for k, v in result_dict['emb'].items():
46 | if k != 'train_img_emb' and k != 'test_img_emb':
47 | result_h5_dict['emb'][k] = v
48 | else:
49 | assert type(v) is list
50 | result_h5_dict['emb'][k] = dict()
51 | for scene_i, scene_emb in enumerate(v):
52 | result_h5_dict['emb'][k][f'{scene_i:05d}'] = np.copy(scene_emb)
53 |
54 | result_h5_dict = {'emb': result_h5_dict['emb'] }
55 | recursively_save_dict_contents_to_group(emb_h5_f, '/', result_h5_dict)
56 | emb_h5_f.flush()
57 | emb_h5_f.close()
58 | pkl_path = os.path.join(result_dir, 'train_result_info.pkl')
59 | with open(pkl_path, 'wb') as pkl_f:
60 | pkl_output_dict = {'output': result_dict['output']}
61 | pickle.dump(pkl_output_dict, pkl_f, protocol=2)
62 |
63 | print(bcolors.c_blue("Did save emb data: {}".format(emb_h5_path)))
64 |
65 |
66 | def get_activation(activation):
67 | """
68 | Returns specified activation function. Note this is preferable to functional
69 | interface since these can be added to ModuleList.
70 | """
71 | if activation == 'relu':
72 | return nn.ReLU()
73 | elif activation == 'leaky_relu':
74 | return nn.LeakyReLU(0.2, inplace=True)
75 | elif activation == 'prelu':
76 | return nn.PReLU()
77 | elif activation == 'sigmoid':
78 | return nn.Sigmoid()
79 | elif activation == 'tanh':
80 | return nn.Tanh()
81 | elif activation == 'softplus':
82 | return nn.Softplus()
83 | else:
84 | raise ValueError(f"Unknown activation type: {activation}")
85 |
86 |
87 | def get_norm(norm, out_size):
88 | if norm == 'layer2d':
89 | # Using 1 group is equivalent to layer norm, but seems you need
90 | # to do it this way with groupnorm for convolution layers
91 | return nn.GroupNorm(1, out_size)
92 | elif norm == 'layer':
93 | return nn.LayerNorm((out_size,))
94 | elif norm == 'batch':
95 | return nn.BatchNorm2d(num_features=out_size)
96 | else:
97 | raise ValueError(f"Unknown normalization type: {norm}")
98 |
99 |
100 | def get_delta_pose_for_data_info(info):
101 | before_pose = info['before']['other_pos'] + info['before']['other_q']
102 | after_pose = info['after']['other_pos'] + info['after']['other_q']
103 | delta_pose = [after_pose[i]-before_pose[i] for i in range(len(before_pose))]
104 | return delta_pose
105 |
106 |
107 | def get_euclid_dist_matrix_for_data(data_arr, squared=True):
108 | '''Get euclidean distance matrix for data.'''
109 | data_dot_prod = np.dot(data_arr, data_arr.T)
110 | sq_norm = np.diagonal(data_dot_prod)
111 | dist = sq_norm[None, :] - 2*data_dot_prod + sq_norm[:, None]
112 | dist = np.maximum(dist, 1e-8)
113 | if not squared:
114 | dist = np.sqrt(dist)
115 | return dist
116 |
117 |
118 | def get_dist_matrix_for_data(data_list,
119 | save_inter_scene_dist_dir=None,
120 | save_inter_scene_dist_file_prefix='',
121 | top_K=100,
122 | bottom_K=100):
123 | inter_scene_dist_by_path_dict = {'path': {}, 'idx': {}}
124 |
125 | get_dist_start_time = time.time()
126 | pos_list = []
127 |
128 | has_info = data_list[0].get('info') is not None
129 | for i in range(len(data_list)):
130 | data_i = data_list[i]
131 | if has_info:
132 | pos_list.append(get_delta_pose_for_data_info(data_i['info']))
133 | else:
134 | pos_list.append(data_i['delta_pose'])
135 |
136 | pos_arr = np.array(pos_list)[:, :3]
137 | for i in range(len(data_list)):
138 | data_i = data_list[i]
139 | if has_info:
140 | data_i_pos = np.array(
141 | get_delta_pose_for_data_info(data_i['info']))[:3]
142 | else:
143 | data_i_pos = np.array(data_i['delta_pose'])[:3]
144 | data_i_dist = np.linalg.norm(pos_arr - data_i_pos, axis=1)
145 |
146 | top_k_idxs = np.argpartition(data_i_dist, top_K + 1)[:top_K]
147 | bottom_k_idxs = np.argpartition(-data_i_dist, bottom_K)[:bottom_K]
148 |
149 | assert len(top_k_idxs) == top_K
150 | assert len(bottom_k_idxs) == bottom_K
151 |
152 | inter_scene_dist_by_path_dict['path'][data_i['path']] = {
153 | 'top': [(data_i_dist[idx], idx, data_list[idx]['path'])
154 | for idx in top_k_idxs],
155 | 'bottom': [(data_i_dist[idx], idx, data_list[idx]['path'])
156 | for idx in bottom_k_idxs],
157 | }
158 | inter_scene_dist_by_path_dict['idx'][i] = \
159 | inter_scene_dist_by_path_dict['path'][data_i['path']]
160 |
161 | get_dist_end_time = time.time()
162 | print("Get dist time: {:.4f}".format(get_dist_end_time - get_dist_start_time))
163 |
164 | # Save the file only if required.
165 | if save_inter_scene_dist_dir is not None:
166 | if save_inter_scene_dist_file_prefix is not None:
167 | if len(save_inter_scene_dist_file_prefix) > 0:
168 | file_name = '{}_inter_scene_dist.pkl'.format(
169 | save_inter_scene_dist_file_prefix)
170 | else:
171 | file_name = 'inter_scene_dist.pkl'
172 | pkl_path = os.path.join(save_inter_scene_dist_dir, file_name)
173 | with open(pkl_path, 'wb') as pkl_f:
174 | pickle.dump(inter_scene_dist_by_path_dict, pkl_f, protocol=2)
175 | print("Did save inter_scene_dist: {}".format(pkl_path))
176 |
177 | return inter_scene_dist_by_path_dict
178 |
179 |
180 | def str2bool(v):
181 | if isinstance(v, bool):
182 | return v
183 | if v.lower() in ('yes', 'true', 't', 'y', '1'):
184 | return True
185 | elif v.lower() in ('no', 'false', 'f', 'n', '0'):
186 | return False
187 | else:
188 | raise argparse.ArgumentTypeError('Boolean value expected.')
189 |
190 |
191 | def recursively_get_dict_from_group(group_or_data):
192 | d = {}
193 | if type(group_or_data) == h5py.Dataset:
194 | return np.array(group_or_data)
195 |
196 | # Else it's still a group
197 | for k in group_or_data.keys():
198 | v = recursively_get_dict_from_group(group_or_data[k])
199 | d[k] = v
200 | return d
201 |
202 | def convert_list_of_array_to_dict_of_array_for_hdf5(arr_list):
203 | arr_dict = {}
204 | for i, a in enumerate(arr_list):
205 | arr_dict[str(i)] = a
206 | return arr_dict
207 |
208 | def recursively_save_dict_contents_to_group(h5file, path, dic):
209 | """
210 | Take an already open HDF5 file and insert the contents of a dictionary
211 | at the current path location. Can call itself recursively to fill
212 | out HDF5 files with the contents of a dictionary.
213 | """
214 | assert type(dic) is type({}), "must provide a dictionary"
215 | assert type(path) is type(''), "path must be a string"
216 | assert type(h5file) is h5py._hl.files.File, "must be an open h5py file"
217 |
218 | for key in dic:
219 | assert type(key) is type(''), 'dict keys must be strings to save to hdf5'
220 | did_save_key = False
221 |
222 | if type(dic[key]) in (np.int64, np.float64, type(''), int, float):
223 | h5file[path + key] = dic[key]
224 | did_save_key = True
225 | assert h5file[path + key].value == dic[key], \
226 | 'The data representation in the HDF5 file does not match the ' \
227 | 'original dict.'
228 | if type(dic[key]) is type([]):
229 | h5file[path + key] = np.array(dic[key])
230 | did_save_key = True
231 | if type(dic[key]) is np.ndarray:
232 | h5file[path + key] = dic[key]
233 | did_save_key = True
234 | # assert np.array_equal(h5file[path + key].value, dic[key]), \
235 | # 'The data representation in the HDF5 file does not match the ' \
236 | # 'original dict.'
237 | if type(dic[key]) is type({}):
238 | recursively_save_dict_contents_to_group(h5file,
239 | path + key + '/',
240 | dic[key])
241 | did_save_key = True
242 | if not did_save_key:
243 | print("Dropping key from h5 file: {}".format(path + key))
--------------------------------------------------------------------------------
/relational_dynamics/utils/math_util.py:
--------------------------------------------------------------------------------
1 | import torch
2 | import numpy as np
3 | from pyquaternion import Quaternion
4 |
5 |
6 | def rotation_to_quat(R):
7 | T = np.eye(4)
8 | T[:3,:3] = R
9 | return homogeneous_to_quat(T)
10 |
11 |
12 | def homogeneous_to_position(T):
13 | return T[:3, 3]
14 |
15 |
16 | def homogeneous_to_rotation(T):
17 | return T[:3, :3]
18 |
19 |
20 | def homogeneous_to_quat(T):
21 | """
22 | Converts rotation matrix from homogeneous TF matrix to quaternion.
23 | """
24 | q = Quaternion(matrix=T) # w, x, y, z
25 | return np.array([q.x, q.y, q.z, q.w]) # Need to switch to x, y, z, w
26 |
27 |
28 | def homogeneous_to_pose(T):
29 | """
30 | Converts homogeneous TF matrix to a 3D position and quaternion.
31 | """
32 | return homogeneous_to_position(T), homogeneous_to_quat(T)
33 |
34 |
35 | def quat_to_homogeneous(q):
36 | """
37 | Converts quaternion to homogeneous TF matrix. Assumes (x, y, z, w) quaternion input.
38 | """
39 | return Quaternion(q[3], q[0], q[1], q[2]).transformation_matrix # Quaternion is (w, x, y, z)
40 |
41 |
42 | def quat_to_rotation(q):
43 | """
44 | Converts quaternion to rotation matrix. Assumes (x, y, z, w) quaternion input.
45 | """
46 | return quat_to_homogeneous(q)[:3,:3]
47 |
48 |
49 | def pose_to_homogeneous(p, q):
50 | """
51 | Converts position and quaternion to a homogeneous TF matrix.
52 | """
53 | T = quat_to_homogeneous(q)
54 | T[:3, 3] = p
55 | return T
56 |
57 |
58 | def homogeneous_transpose(T):
59 | """
60 | Converts TF to TF inverse, also use np.matmul instead of np.dot
61 | """
62 | new_T = np.eye(4)
63 | new_T[:3,:3] = T[:3,:3].T
64 | new_T[:3,3] = -np.matmul(new_T[:3,:3], T[:3,3])
65 | return new_T
66 |
67 |
68 | def random_quat():
69 | q = Quaternion.random()
70 | return np.array([q.x, q.y, q.z, q.w])
71 |
72 |
73 | def random_rotation():
74 | return quat_to_rotation(random_quat())
75 |
76 |
77 | def get_x_axis_rotation(theta):
78 | return np.array([[1, 0, 0],
79 | [0, np.cos(theta), -np.sin(theta)],
80 | [0, np.sin(theta), np.cos(theta)]])
81 |
82 |
83 | def get_y_axis_rotation(theta):
84 | return np.array([[ np.cos(theta), 0, np.sin(theta)],
85 | [ 0, 1, 0],
86 | [-np.sin(theta), 0, np.cos(theta)]])
87 |
88 |
89 | def get_z_axis_rotation(theta):
90 | return np.array([[np.cos(theta), -np.sin(theta), 0],
91 | [np.sin(theta), np.cos(theta), 0],
92 | [ 0, 0, 1]])
93 |
94 |
95 | def quat_mul(a, b):
96 | assert a.shape == b.shape
97 | shape = a.shape
98 | a = a.reshape(-1, 4)
99 | b = b.reshape(-1, 4)
100 |
101 | x1, y1, z1, w1 = a[:, 0], a[:, 1], a[:, 2], a[:, 3]
102 | x2, y2, z2, w2 = b[:, 0], b[:, 1], b[:, 2], b[:, 3]
103 | ww = (z1 + x1) * (x2 + y2)
104 | yy = (w1 - y1) * (w2 + z2)
105 | zz = (w1 + y1) * (w2 - z2)
106 | xx = ww + yy + zz
107 | qq = 0.5 * (xx + (z1 - x1) * (x2 - y2))
108 | w = qq - ww + (z1 - y1) * (y2 - z2)
109 | x = qq - xx + (x1 + w1) * (x2 + w2)
110 | y = qq - yy + (w1 - x1) * (y2 + z2)
111 | z = qq - zz + (z1 + y1) * (w2 - x2)
112 |
113 | quat = torch.stack([x, y, z, w], dim=-1).view(shape)
114 |
115 | return quat
116 |
117 |
118 | def quat_conjugate(a):
119 | shape = a.shape
120 | a = a.reshape(-1, 4)
121 | return torch.cat((-a[:, :3], a[:, -1:]), dim=-1).view(shape)
122 |
123 |
124 | def quaternion_error(desired, current, square=False, numpy=False, flatten=False):
125 | q_c = quat_conjugate(current)
126 | q_r = quat_mul(desired, q_c)
127 | error = q_r[:, 0:3] * torch.sign(q_r[:, 3]).unsqueeze(-1)
128 | if square:
129 | error = error**2
130 | if numpy:
131 | error = error.cpu().numpy()
132 | if flatten:
133 | error = error.flatten()
134 | return error
135 |
136 |
137 | def position_error(desired, current, square=False, numpy=False, flatten=False):
138 | error = desired - current
139 | if square:
140 | error = error**2
141 | if numpy:
142 | error = error.cpu().numpy()
143 | if flatten:
144 | error = error.flatten()
145 | return error
146 |
147 |
148 | def geodesic_error(R1, R2):
149 | return np.arccos(np.clip((np.trace(np.dot(R1, R2.T)) - 1.) / 2., -1, 1))
150 |
151 |
152 |
153 | if __name__ == '__main__':
154 | R1 = random_rotation()
155 | R2 = random_rotation()
156 |
157 | print(geodesic_error(R1, R2))
158 |
--------------------------------------------------------------------------------
/relational_dynamics/utils/other_util.py:
--------------------------------------------------------------------------------
1 | import numpy as np
2 | import torch
3 | import torch.nn as nn
4 | import os
5 |
6 | from relational_dynamics.utils import torch_util
7 | from relational_dynamics.utils.data_utils import get_norm, get_activation, scale_min_max
8 |
9 | def rotate_2d(x, theta):
10 | """ Rotate x by theta degrees (counter clockwise)
11 |
12 | @param x: a 2D vector (numpy array with shape 2)
13 | @param theta: a scalar representing radians
14 | """
15 |
16 | rot_mat = np.array([
17 | [np.cos(theta), -np.sin(theta)],
18 | [np.sin(theta), np.cos(theta)]
19 | ], dtype=np.float32)
20 |
21 | return rot_mat.dot(x)
22 |
23 | def create_log_dirs(config):
24 | args = config.args
25 | # Create logger directory if required
26 | if not os.path.exists(args.result_dir):
27 | os.makedirs(args.result_dir)
28 | if not os.path.exists(config.get_logger_dir()):
29 | os.makedirs(config.get_logger_dir())
30 | if not os.path.exists(config.get_model_checkpoint_dir()):
31 | os.makedirs(config.get_model_checkpoint_dir())
32 |
33 | class LinearBlock(nn.Module):
34 |
35 | def __init__(self, in_size, out_size, activation=None, norm=None):
36 | super(LinearBlock, self).__init__()
37 |
38 | self.layers = nn.ModuleList()
39 | self.layers.append(nn.Linear(in_size, out_size))
40 | if activation:
41 | self.layers.append(get_activation(activation))
42 | if norm is not None:
43 | self.layers.append(get_norm(norm, out_size))
44 |
45 | def forward(self, x):
46 | for layer in self.layers:
47 | x = layer(x)
48 | return x
49 |
50 | class MLP(nn.Module):
51 |
52 | def __init__(self, in_size, out_size, hidden_sizes=[], activation='relu',
53 | norm=None, out_activation=None, out_norm=None, vae=False):
54 | """
55 | Multi-layer perception module. Stacks linear layers with customizable sizes,
56 | activations, and normalization.
57 |
58 | Args:
59 | in_size (int): Size of input tensor
60 | out_size (int): Size of output tensor
61 | hidden_sizes (List[int]): Output sizes of each hidden layer
62 | activation (str): Activations to apply to each hidden layer
63 | layer_norms (bool): Apply layer norm to hidden layers if true
64 | out_activation (str): Activation to apply to output layer (default is none)
65 | out_layer_norm (bool): Apply layer norm to output layer if true
66 | vae (bool): Sample output as VAE
67 | Returns:
68 | Output of last layer; if vae=True, returns sample of output as well as mean and std
69 |
70 | TODO right now only layer norm supported, can make more general
71 | """
72 | super(MLP, self).__init__()
73 |
74 | self.vae = vae
75 | if self.vae:
76 | out_size *= 2
77 |
78 | self.layers = nn.ModuleList()
79 | prev_size = in_size
80 | for size in hidden_sizes:
81 | self.layers.append(LinearBlock(prev_size, size, activation, norm))
82 | prev_size = size
83 | self.layers.append(LinearBlock(prev_size, out_size, out_activation, out_norm))
84 |
85 | def forward(self, x):
86 | for layer in self.layers:
87 | x = layer(x)
88 |
89 | if self.vae:
90 | mu, log_std = torch.chunk(x, 2, dim=-1)
91 | std = torch.exp(log_std)
92 | noise = torch.randn_like(mu)
93 | if self.training:
94 | return mu + std * noise
95 | else:
96 | return mu
97 | else:
98 | return x
99 |
--------------------------------------------------------------------------------
/relational_dynamics/utils/torch_util.py:
--------------------------------------------------------------------------------
1 | from math import pi
2 |
3 | import torch
4 | import torch.nn.functional as F
5 |
6 | def convert_to_float_tensors(tensor_dict, keys=[]):
7 | keys = keys if keys else tensor_dict.keys()
8 | for k in keys:
9 | if torch.is_tensor(tensor_dict[k]):
10 | tensor_dict[k] = tensor_dict[k].float()
11 | else:
12 | tensor_dict[k] = torch.FloatTensor(tensor_dict[k])
13 |
14 |
15 | def convert_to_long_tensors(tensor_dict, keys=[]):
16 | keys = keys if keys else tensor_dict.keys()
17 | for k in keys:
18 | if torch.is_tensor(tensor_dict[k]):
19 | tensor_dict[k] = tensor_dict[k].long()
20 | else:
21 | tensor_dict[k] = torch.LongTensor(tensor_dict[k])
22 |
23 |
24 | def make_batch(x, n_batch=1):
25 | """
26 | Batchifies a tensor by adding a batch dim and repeating it over that
27 | dimension n_batch times.
28 | """
29 | if not isinstance(x, torch.Tensor):
30 | x = torch.tensor(x)
31 | ndim = x.dim()
32 | x = x.unsqueeze(0)
33 | if n_batch > 1:
34 | x = x.repeat(n_batch, *[1]*ndim) # unrolls list of 1's of length ndim
35 | return x
36 |
37 |
38 | def move_batch_to_device(batch_dict, device):
39 | """
40 | Recursive function that moves a (nested) dictionary of tensors to the specified device.
41 | """
42 | for k, v in batch_dict.items():
43 | if isinstance(v, torch.Tensor):
44 | batch_dict[k] = v.to(device)
45 | elif isinstance(v, dict):
46 | move_batch_to_device(v, device)
47 |
48 |
49 | def move_models_to_device(models_dict, device):
50 | """
51 | Assuming flat dictionary where values are all type torch.nn.Module.
52 | """
53 | for k, v in models_dict.items():
54 | models_dict[k] = v.to(device)
55 |
56 |
57 | def set_models_to_train(models_dict):
58 | for v in models_dict.values():
59 | v.train()
60 |
61 |
62 | def set_models_to_eval(models_dict):
63 | for v in models_dict.values():
64 | v.eval()
65 |
66 |
67 | def load_state_dicts(models_dict, state_dicts):
68 | for k, v in models_dict.items():
69 | if k not in state_dicts:
70 | print(f"Model {k} does not have state to load")
71 | #ui_util.print_warning(f"Model {k} does not have state to load")
72 | continue
73 | v.load_state_dict(state_dicts[k])
74 |
75 |
76 | def accumulate_parameters(models_dict):
77 | params = []
78 | for v in models_dict.values():
79 | params += list(v.parameters())
80 | return params
81 |
82 |
83 |
84 |
85 | # torch quaternion functions from NVIDIA:
86 |
87 | def quat_mul(a, b):
88 | assert a.shape == b.shape
89 | shape = a.shape
90 | a = a.reshape(-1, 4)
91 | b = b.reshape(-1, 4)
92 |
93 | x1, y1, z1, w1 = a[:, 0], a[:, 1], a[:, 2], a[:, 3]
94 | x2, y2, z2, w2 = b[:, 0], b[:, 1], b[:, 2], b[:, 3]
95 | ww = (z1 + x1) * (x2 + y2)
96 | yy = (w1 - y1) * (w2 + z2)
97 | zz = (w1 + y1) * (w2 - z2)
98 | xx = ww + yy + zz
99 | qq = 0.5 * (xx + (z1 - x1) * (x2 - y2))
100 | w = qq - ww + (z1 - y1) * (y2 - z2)
101 | x = qq - xx + (x1 + w1) * (x2 + w2)
102 | y = qq - yy + (w1 - x1) * (y2 + z2)
103 | z = qq - zz + (z1 + y1) * (w2 - x2)
104 |
105 | quat = torch.stack([x, y, z, w], dim=-1).view(shape)
106 |
107 | return quat
108 |
109 |
110 | def quat_conjugate(a):
111 | shape = a.shape
112 | a = a.reshape(-1, 4)
113 | return torch.cat((-a[:, :3], a[:, -1:]), dim=-1).view(shape)
114 |
115 |
116 | def quaternion_error(desired, current, square=False, numpy=False, flatten=False):
117 | q_c = quat_conjugate(current)
118 | q_r = quat_mul(desired, q_c)
119 | error = q_r[:, 0:3] * torch.sign(q_r[:, 3]).unsqueeze(-1)
120 | if square:
121 | error = error**2
122 | if numpy:
123 | error = error.cpu().numpy()
124 | if flatten:
125 | error = error.flatten()
126 | return error
127 |
128 |
129 | def position_error(desired, current, square=False, numpy=False, flatten=False):
130 | error = desired - current
131 | if square:
132 | error = error**2
133 | if numpy:
134 | error = error.cpu().numpy()
135 | if flatten:
136 | error = error.flatten()
137 | return error
138 |
139 | def random_quat(batch_size=1, device='cuda'):
140 | """
141 | Computes a random quaternion sampled uniformly from the unit sphere.
142 |
143 | Note this is primarily implemented so that it uses torch random generator
144 | instead of numpy to avoid issues with how torch/np random generators
145 | interact when training with randomization:
146 | https://tanelp.github.io/posts/a-bug-that-plagues-thousands-of-open-source-ml-projects/
147 |
148 | See: https://github.com/KieranWynn/pyquaternion/blob/master/pyquaternion/quaternion.py#L261
149 | """
150 | r1 = torch.rand(batch_size).to(device).view(-1, 1)
151 | r2 = torch.rand(batch_size).to(device).view(-1, 1)
152 | r3 = torch.rand(batch_size).to(device).view(-1, 1)
153 |
154 | w = torch.sqrt(1.0 - r1) * (torch.sin(2.0 * pi * r2))
155 | x = torch.sqrt(1.0 - r1) * (torch.cos(2.0 * pi * r2))
156 | y = torch.sqrt(r1) * (torch.sin(2.0 * pi * r3))
157 | z = torch.sqrt(r1) * (torch.cos(2.0 * pi * r3))
158 | # Normalize just to be sure since there can be slight numerical differences from pure unit
159 | return F.normalize(torch.cat([x, y, z, w], dim=-1))
160 |
161 |
162 | def random_rotation(batch_size=1, device='cuda'):
163 | return quat_to_rotation(random_quat(batch_size, device))
164 |
165 |
166 | def quat_to_rotation(q):
167 | batch = q.size(0)
168 | qx = q[:,0].view(batch, 1)
169 | qy = q[:,1].view(batch, 1)
170 | qz = q[:,2].view(batch, 1)
171 | qw = q[:,3].view(batch, 1)
172 |
173 | # Unit quaternion rotation matrices computatation
174 | xx = qx*qx
175 | yy = qy*qy
176 | zz = qz*qz
177 | xy = qx*qy
178 | xz = qx*qz
179 | yz = qy*qz
180 | xw = qx*qw
181 | yw = qy*qw
182 | zw = qz*qw
183 |
184 | row0 = torch.cat((1-2*yy-2*zz, 2*xy - 2*zw, 2*xz + 2*yw), 1)
185 | row1 = torch.cat((2*xy+ 2*zw, 1-2*xx-2*zz, 2*yz-2*xw ), 1)
186 | row2 = torch.cat((2*xz-2*yw, 2*yz+2*xw, 1-2*xx-2*yy), 1)
187 |
188 | matrix = torch.cat((row0.view(batch,1,3), row1.view(batch,1,3), row2.view(batch,1,3)),1)
189 | return matrix
190 |
191 |
192 | if __name__ == '__main__':
193 | # print(random_rotation(1))
194 |
195 | a = torch.tensor([[1,2,3],
196 | [4,5,6],
197 | [7,8,9]])
198 | print(make_batch(a, 11).shape)
199 |
--------------------------------------------------------------------------------