Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Comparing for eventual rebase #2039

Draft
wants to merge 93 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
93 commits
Select commit Hold shift + click to select a range
2944319
Add task config for multi-agent
Ram81 Apr 29, 2024
8c22953
changes to run barebone w/llm
zephirefaith May 1, 2024
e16ddbd
basic plumbing into hitl
zephirefaith May 1, 2024
7849ef6
fixing precommit
zephirefaith May 1, 2024
e4631d5
adding visual sensors
zephirefaith May 2, 2024
0c0ed67
config patching, remove unneeded super() calls
zephirefaith May 2, 2024
c8a9857
frankenstein hitl+llm config
zephirefaith May 2, 2024
77880a3
bandaids to get to working V0
zephirefaith May 6, 2024
eed48c1
Merge branch 'main' of github.com:facebookresearch/habitat-lab into z…
zephirefaith May 7, 2024
21ce0c4
making visual sensor changes configurable with explicit flags
zephirefaith May 8, 2024
e74a92d
delete sensors we do not need
zephirefaith May 8, 2024
8e912e4
multi-threading + partial obs
zephirefaith May 12, 2024
f62a4e9
speeding up the humanoid
zephirefaith May 15, 2024
c71b55f
logging
zephirefaith May 15, 2024
622f582
Merge branch 'main' of github.com:facebookresearch/habitat-lab into z…
zephirefaith May 15, 2024
05ac703
moving habitat-llm stuff to dedicated file/module
zephirefaith May 17, 2024
998dd6d
+header,+-logging,-llm util
zephirefaith May 17, 2024
ff0fb40
remove unused config
zephirefaith May 17, 2024
a87b1ba
optional logging, -llb-deps
zephirefaith May 17, 2024
a0ab1c2
Disable new clone protection for git lfs (#1961)
aclegg3 May 16, 2024
48fdfdb
HITL - Make client loading state available to applications. (#1955)
0mdc May 17, 2024
0963a59
Add buttons and modal dialog boxes. (#1956)
0mdc May 17, 2024
4e8650c
Add configuration to enable new connections by default. (#1960)
0mdc May 17, 2024
8a653c2
Add textboxes. (#1957)
0mdc May 17, 2024
783506e
HITL - Add picture-in-picture viewports. (#1958)
0mdc May 17, 2024
e7e76ab
HITL - Add object visbility handling and hide "self" in viewports. (#…
0mdc May 17, 2024
8a93681
Add autogenerated navmeshes to gitignore. (#1963)
0mdc May 17, 2024
74c8df7
HITL - Rearrange State Machine (#1964)
0mdc May 18, 2024
bb2167d
HITL - Rearrange session handling (#1965)
0mdc May 20, 2024
a9a2912
HITL - Data collection (#1967)
0mdc May 20, 2024
91481fd
[BE/CI] - remove auto downloads (#1962)
aclegg3 May 21, 2024
c3963a6
HITL - Add end episode form and error reporting (#1968)
0mdc May 21, 2024
1031c8d
Embodied Unoccluded Navmesh Snap util (#1949)
aclegg3 May 21, 2024
d675999
remove auto downloader from RearrangeDataset init (#1969)
aclegg3 May 22, 2024
8d0c9cf
add ignore_object_ids to snap_down API (#1971)
aclegg3 May 22, 2024
0c05761
HITL - Decouple agents from users. (#1972)
0mdc May 22, 2024
1b3e7cf
Change dataset config.
0mdc May 23, 2024
30712b0
Config updates for remote HITL sessions.
0mdc May 28, 2024
0a88ef7
Load llm extensions.
0mdc May 28, 2024
1d8f031
Update LLM config.
0mdc May 28, 2024
d981be3
Remove dead code in LLM controller.
0mdc May 28, 2024
4a8c77f
Avoid errors when loading non-llm configs.
0mdc May 29, 2024
a9e49f5
Remove superfluous dataset definition.
0mdc May 29, 2024
1965953
Avoid resetting Habitat when resetting environment_interface.
0mdc May 29, 2024
dc65e92
Fix rearrange sensor initialization.
0mdc May 29, 2024
60a08f9
Add rearrange_v2 config.
0mdc May 29, 2024
fe5504c
Set idle timer to 180s.
0mdc May 29, 2024
cebd24b
event callbacks and action-space update
zephirefaith May 31, 2024
72cb8f7
added open/close callback too; test next
zephirefaith May 31, 2024
243df21
Speed up agent action thread.
0mdc Jun 1, 2024
a9ff943
Make Unity controls smoother.
0mdc Jun 2, 2024
3ae3e3c
Code formatting and typing fixes.
0mdc Jun 2, 2024
5f07807
Skip serialization of attributes missing mendatory values.
0mdc Jun 2, 2024
9dcb6ce
Fix other agent's sensor.
0mdc Jun 2, 2024
4431ab2
Add comment.
0mdc Jun 2, 2024
61750e4
Query grasp manager to determine whether an object is picked by an ag…
0mdc Jun 3, 2024
5945cce
Move HITL output to 'data/' so that it is ignored by git.
0mdc Jun 3, 2024
0c585de
Fix place receptacle ID.
0mdc Jun 3, 2024
0d1d2fb
Use grasp manager to communicate grasp state to other systems.
0mdc Jun 4, 2024
3ac6df1
Enable humanoid model in single-learn so that the human appears in th…
0mdc Jun 4, 2024
ef49e09
forward all the actions
zephirefaith Jun 4, 2024
2d2d1c5
Merge branch '0mdc/phase3' of https://github.com/facebookresearch/hab…
zephirefaith Jun 4, 2024
38e9da2
removing unnecessary measure
zephirefaith Jun 4, 2024
e487e9f
robustifying a bit
zephirefaith Jun 4, 2024
95522f3
receptacle naming
zephirefaith Jun 5, 2024
7fa8f17
turn off magic desnapping
zephirefaith Jun 5, 2024
93ed72d
termination condition for single-learn case
zephirefaith Jun 6, 2024
2191f56
adding termination event; bypassing planning when done
zephirefaith Jun 6, 2024
3031983
clean-up
zephirefaith Jun 6, 2024
74829eb
Disable new connections by default.
0mdc Jun 7, 2024
7f3ccf1
Move agent head sensors to match GUI camera.
0mdc Jun 7, 2024
6e0cdfb
Disable RGB sensors.
0mdc Jun 7, 2024
41583e0
adding task % progress
zephirefaith Jun 7, 2024
677d971
guard each agent's obs
zephirefaith Jun 7, 2024
9b5ca88
Disable humanoid sensor auto-update.
0mdc Jun 7, 2024
3e3324e
Disable task success text. Add task success to data output.
0mdc Jun 7, 2024
b983eb3
Adjust episode termination signals for single-learn.
0mdc Jun 7, 2024
1757301
Add skip episode app state.
0mdc Jun 7, 2024
c455f7f
Fix config typo.
0mdc Jun 7, 2024
5f756d5
hot-fix for inaccessible receptacles
zephirefaith Jun 7, 2024
859c0c5
Merge branch '0mdc/phase3' of https://github.com/facebookresearch/hab…
zephirefaith Jun 7, 2024
a6021cc
guard if no fur found for rec
zephirefaith Jun 7, 2024
9bb5ec1
guards
zephirefaith Jun 7, 2024
4a0d292
typo
zephirefaith Jun 7, 2024
08f9fb3
first finish thread then reset env
zephirefaith Jun 7, 2024
fe9d887
receptacle ID can be furniture ID
zephirefaith Jun 7, 2024
de568e2
Formatting fix.
0mdc Jun 10, 2024
21aeea3
Change data collection output folder.
0mdc Jun 10, 2024
776f0c7
handle error termination from user/agent
zephirefaith Jun 11, 2024
12e4f56
sending error information
zephirefaith Jun 11, 2024
f4fe7de
Record episode status.
0mdc Jun 12, 2024
744dc38
guarding against exceptions and absence of handles
zephirefaith Jun 12, 2024
cc1584c
Merge branch '0mdc/phase3' of https://github.com/facebookresearch/hab…
Jun 12, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -203,12 +203,15 @@ jobs:
- run:
name: Download test data
command: |
# Disable clone protection for git lfs
export GIT_CLONE_PROTECTION_ACTIVE=false

sudo apt install git-lfs
export PATH=$HOME/miniconda/bin:/usr/local/cuda/bin:$PATH
. activate habitat
git lfs install
conda install -y gitpython git-lfs
python -m habitat_sim.utils.datasets_download --uids ci_test_assets franka_panda hab_spot_arm hab3_bench_assets --data-path habitat-sim/data/ --no-replace --no-prune
python -m habitat_sim.utils.datasets_download --uids ci_test_assets franka_panda hab_spot_arm hab3_bench_assets ycb rearrange_dataset_v2 --data-path habitat-sim/data/ --no-replace --no-prune
- run:
name: Run sim benchmark
command: |
Expand Down Expand Up @@ -281,6 +284,7 @@ jobs:
. activate habitat; cd habitat-lab
export PYTHONPATH=.:$PYTHONPATH
export MULTI_PROC_OFFSET=0 && export MAGNUM_LOG=quiet && export HABITAT_SIM_LOG=quiet
export GIT_CLONE_PROTECTION_ACTIVE=false
python -m habitat_sim.utils.datasets_download --uids hab3-episodes hab3_bench_assets habitat_humanoids hab_spot_arm ycb --data-path data/ --no-replace --no-prune
python -m pytest habitat-hitl/test
- run:
Expand Down
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -100,3 +100,6 @@ data
/sandbox
/plots/outputs
/wandb/

# Autogenerated navmesh files
*.navmesh
19 changes: 19 additions & 0 deletions examples/hitl/rearrange_v2/app_data.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
#!/usr/bin/env python3

# Copyright (c) Meta Platforms, Inc. and its affiliates.
# This source code is licensed under the MIT license found in the
# LICENSE file in the root directory of this source tree.

from typing import Dict

from habitat_hitl.core.types import ConnectionRecord


class AppData:
"""
RearrangeV2 application data shared by all states.
"""

def __init__(self, max_user_count: int):
self.max_user_count = max_user_count
self.connected_users: Dict[int, ConnectionRecord] = {}
71 changes: 71 additions & 0 deletions examples/hitl/rearrange_v2/app_state_base.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
#!/usr/bin/env python3

# Copyright (c) Meta Platforms, Inc. and its affiliates.
# This source code is licensed under the MIT license found in the
# LICENSE file in the root directory of this source tree.

from __future__ import annotations

from typing import Optional

from app_data import AppData

from habitat_hitl.app_states.app_service import AppService
from habitat_hitl.app_states.app_state_abc import AppState
from habitat_hitl.core.text_drawer import TextOnScreenAlignment
from habitat_hitl.core.user_mask import Mask


class AppStateBase(AppState):
def __init__(
self,
app_service: AppService,
app_data: AppData,
):
self._app_service = app_service
self._app_data = app_data
self._cancel = False
self._time_since_last_connection = 0
self._save_keyframes = True

def on_enter(self):
print(f"Entering state: {type(self)}")

def on_exit(self):
print(f"Exiting state: {type(self)}")

def try_cancel(self):
self._cancel = True

def get_next_state(self) -> Optional[AppStateBase]:
pass

def on_environment_reset(self, episode_recorder_dict):
pass

def sim_update(self, dt: float, post_sim_update_dict):
pass

def record_state(self):
pass

def _status_message(self, message: str) -> None:
"""Send a message to all users."""
if len(message) > 0:
self._app_service.text_drawer.add_text(
message,
TextOnScreenAlignment.TOP_CENTER,
text_delta_x=-280,
text_delta_y=-50,
destination_mask=Mask.ALL,
)

def _kick_all_users(self) -> None:
"Kick all users."
self._app_service.remote_client_state.kick(Mask.ALL)

def _is_server_gui_enabled(self) -> bool:
"Returns true if the local server GUI is available."
return (
not self._app_service.hitl_config.experimental.headless.do_headless
)
118 changes: 118 additions & 0 deletions examples/hitl/rearrange_v2/app_state_end_session.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
#!/usr/bin/env python3

# Copyright (c) Meta Platforms, Inc. and its affiliates.
# This source code is licensed under the MIT license found in the
# LICENSE file in the root directory of this source tree.

import os
import shutil
from typing import Optional

from app_data import AppData
from app_state_base import AppStateBase
from app_states import create_app_state_reset
from s3_upload import (
generate_unique_session_id,
make_s3_filename,
upload_file_to_s3,
)
from session import Session
from util import get_top_down_view

from habitat_hitl.app_states.app_service import AppService
from habitat_hitl.core.serialize_utils import save_as_json_gzip
from habitat_hitl.core.user_mask import Mask

# Duration of the end session message, before users are kicked.
SESSION_END_DELAY = 5.0


class AppStateEndSession(AppStateBase):
"""
* Indicate users that the session is terminated.
* Upload collected data.
"""

def __init__(
self, app_service: AppService, app_data: AppData, session: Session
):
super().__init__(app_service, app_data)
self._session = session
self._elapsed_time = 0.0
self._save_keyframes = False

self._status = "Session ended."
if len(session.error) > 0:
self._status += f"\nError: {session.error}"

def get_next_state(self) -> Optional[AppStateBase]:
if self._elapsed_time > SESSION_END_DELAY:
self._end_session()
return create_app_state_reset(self._app_service, self._app_data)
return None

def sim_update(self, dt: float, post_sim_update_dict):
# Top-down view.
cam_matrix = get_top_down_view(self._app_service.sim)
post_sim_update_dict["cam_transform"] = cam_matrix
self._app_service._client_message_manager.update_camera_transform(
cam_matrix, destination_mask=Mask.ALL
)

self._status_message(self._status)
self._elapsed_time += dt

def _end_session(self):
session = self._session
if session is None:
print("Null session. Skipping S3 upload.")
return

# Finalize session.
if self._session.error == "":
session.success = True
session.session_recorder.end_session(self._session.error)

# Get data collection parameters.
try:
config = self._app_service.config
data_collection_config = config.rearrange_v2.data_collection
s3_path = data_collection_config.s3_path
s3_subdir = "complete" if session.success else "incomplete"
s3_path = os.path.join(s3_path, s3_subdir)

# Use the port as a discriminator for when there are multiple concurrent servers.
output_folder_suffix = str(config.habitat_hitl.networking.port)
output_folder = f"data/output_{output_folder_suffix}"

output_file_name = data_collection_config.output_file_name
output_file = f"{output_file_name}.json.gz"

except Exception as e:
print(f"Invalid data collection config. Skipping S3 upload. {e}")
return

# Delete previous output directory
if os.path.exists(output_folder):
shutil.rmtree(output_folder)

# Create new output directory
os.makedirs(output_folder)
json_path = os.path.join(output_folder, output_file)
save_as_json_gzip(session.session_recorder, json_path)

# Generate unique session ID
session_id = generate_unique_session_id(
session.episode_ids, session.connection_records
)

# Upload output directory
orig_file_names = [
f
for f in os.listdir(output_folder)
if os.path.isfile(os.path.join(output_folder, f))
]
for orig_file_name in orig_file_names:
local_file_path = os.path.join(output_folder, orig_file_name)
s3_file_name = make_s3_filename(session_id, orig_file_name)
upload_file_to_s3(local_file_path, s3_file_name, s3_path)
125 changes: 125 additions & 0 deletions examples/hitl/rearrange_v2/app_state_load_episode.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
#!/usr/bin/env python3

# Copyright (c) Meta Platforms, Inc. and its affiliates.
# This source code is licensed under the MIT license found in the
# LICENSE file in the root directory of this source tree.

from typing import Optional

from app_data import AppData
from app_state_base import AppStateBase
from app_states import (
create_app_state_cancel_session,
create_app_state_end_session,
create_app_state_start_screen,
)
from session import Session
from util import get_top_down_view

from habitat_hitl.app_states.app_service import AppService
from habitat_hitl.core.user_mask import Mask


class AppStateLoadEpisode(AppStateBase):
"""
Load an episode.
A loading screen is shown while the content loads.
* If a next episode exists, launch RearrangeV2.
* If all episodes are done, end session.
* If any user disconnects, cancel the session.
"""

def __init__(
self, app_service: AppService, app_data: AppData, session: Session
):
super().__init__(app_service, app_data)
self._session = session
self._loading = True
self._session_ended = False
self._frame_number = 0
self._save_keyframes = False

def get_next_state(self) -> Optional[AppStateBase]:
if self._cancel:
return create_app_state_cancel_session(
self._app_service,
self._app_data,
self._session,
"User disconnected.",
)
if self._session_ended:
return create_app_state_end_session(
self._app_service, self._app_data, self._session
)
# When all clients finish loading, show the start screen.
if not self._loading:
return create_app_state_start_screen(
self._app_service, self._app_data, self._session
)
return None

def sim_update(self, dt: float, post_sim_update_dict):
self._status_message("Loading...")

# Skip a frame so that the status message reaches the client before the server loads the scene and blocks.
if self._frame_number == 1:
self._increment_episode()
# Once the scene loaded, show a top-down view.
elif self._frame_number > 1:
cam_matrix = get_top_down_view(self._app_service.sim)
post_sim_update_dict["cam_transform"] = cam_matrix
self._app_service._client_message_manager.update_camera_transform(
cam_matrix, destination_mask=Mask.ALL
)
# Wait for clients to signal that content finished loading on their end.
# HACK: The server isn't immediately aware that clients are loading. For now, we simply skip some frames.
# TODO: Use the keyframe ID from 'ClientMessageManager.set_server_keyframe_id()' to find the when the loading state is up-to-date.
if self._frame_number > 20:
any_client_loading = False
for user_index in range(self._app_data.max_user_count):
if self._app_service.remote_client_state._client_loading[
user_index
]:
any_client_loading = True
break
if not any_client_loading:
self._loading = False

self._frame_number += 1

def _increment_episode(self):
session = self._session
assert session.episode_ids is not None
if session.current_episode_index < len(session.episode_ids):
self._set_episode(session.current_episode_index)
session.current_episode_index += 1
else:
self._session_ended = True

def _set_episode(self, episode_index: int):
session = self._session

# Set the ID of the next episode to play in lab.
next_episode_id = session.episode_ids[episode_index]
print(f"Next episode index: {next_episode_id}.")
try:
next_episode_index = int(next_episode_id)
self._app_service.episode_helper.set_next_episode_by_index(
next_episode_index
)
except Exception as e:
print(f"ERROR: Invalid episode index {next_episode_id}. {e}")
print("Loading episode index 0.")
self._app_service.episode_helper.set_next_episode_by_index(0)

# Once an episode ID has been set, lab needs to be reset to load the episode.
self._app_service.end_episode(do_reset=True)

# Signal the clients that the scene has changed.
client_message_manager = self._app_service.client_message_manager
if client_message_manager:
client_message_manager.signal_scene_change(Mask.ALL)

# Save a keyframe. This propagates the new content to the clients, initiating client-side loading.
# Beware that the client "loading" state won't immediately be visible to the server.
self._app_service.sim.gfx_replay_manager.save_keyframe()
Loading