From ca8fe24d9aca776e532b16b4dc60e6052186a247 Mon Sep 17 00:00:00 2001 From: Mikhail Yurasov Date: Mon, 6 May 2024 19:44:25 -0700 Subject: [PATCH 01/27] Bump up the version --- Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Dockerfile b/Dockerfile index f7a70b4..a5276be 100644 --- a/Dockerfile +++ b/Dockerfile @@ -92,5 +92,5 @@ WORKDIR /app ENTRYPOINT [ "/bin/sh", "-c" ] -ENV VERSION="v2.3.0" +ENV VERSION="v2.3.1" From b1dc7c6788297d714a537b336a468854d5dd5115 Mon Sep 17 00:00:00 2001 From: Mikhail Yurasov Date: Tue, 14 May 2024 12:05:52 -0700 Subject: [PATCH 02/27] Add intro --- README.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/README.md b/README.md index 486203e..8c89380 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,9 @@ # Isaac Sim Automator +Isaac Sim Automator allows for quick depliyment of Isaac Sim and Isaac Sim-based applications (like Orbit and Omniverse Isaac Gym Environments), onto the public clouds (AWS, GCP, Azure, and Alibaba Cloud are currently supported). + +The result is a fully configured remote desktod cloud workstation, which can be used for development, testing robotic applications within minutes and on a budget. Isaac Sim Automator supports varierty of GPU instances and stop-start functionality to save on cloud costs and a varierty of tools to aid the workflow (like uploading and downloading data, autorun, deployment management, etc). + - [Installation](#installation) - [Installing Docker](#installing-docker) - [Obtaining NGC API Key](#obtaining-ngc-api-key) From 2cc460ff8082da5e4d3c975639451ee51c014445 Mon Sep 17 00:00:00 2001 From: Mikhail Yurasov Date: Tue, 14 May 2024 12:08:53 -0700 Subject: [PATCH 03/27] Typo --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 8c89380..af092f3 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,8 @@ # Isaac Sim Automator -Isaac Sim Automator allows for quick depliyment of Isaac Sim and Isaac Sim-based applications (like Orbit and Omniverse Isaac Gym Environments), onto the public clouds (AWS, GCP, Azure, and Alibaba Cloud are currently supported). +Isaac Sim Automator allows for quick deployment of Isaac Sim and Isaac Sim-based applications (like Orbit and Omniverse Isaac Gym Environments), onto the public clouds (AWS, GCP, Azure, and Alibaba Cloud are currently supported). -The result is a fully configured remote desktod cloud workstation, which can be used for development, testing robotic applications within minutes and on a budget. Isaac Sim Automator supports varierty of GPU instances and stop-start functionality to save on cloud costs and a varierty of tools to aid the workflow (like uploading and downloading data, autorun, deployment management, etc). +The result is a fully configured remote desktod cloud workstation, which can be used for development, testing of the robotic applications within minutes and on a budget. Isaac Sim Automator supports varierty of GPU instances and stop-start functionality to save on cloud costs and a varierty of tools to aid the workflow (like uploading and downloading data, autorun, deployment management, etc). - [Installation](#installation) - [Installing Docker](#installing-docker) From bc332f1b331a65ace06fb5ad16967eaa87e7b746 Mon Sep 17 00:00:00 2001 From: Mikhail Yurasov Date: Tue, 14 May 2024 12:37:29 -0700 Subject: [PATCH 04/27] Typo --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index af092f3..c326fa8 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ Isaac Sim Automator allows for quick deployment of Isaac Sim and Isaac Sim-based applications (like Orbit and Omniverse Isaac Gym Environments), onto the public clouds (AWS, GCP, Azure, and Alibaba Cloud are currently supported). -The result is a fully configured remote desktod cloud workstation, which can be used for development, testing of the robotic applications within minutes and on a budget. Isaac Sim Automator supports varierty of GPU instances and stop-start functionality to save on cloud costs and a varierty of tools to aid the workflow (like uploading and downloading data, autorun, deployment management, etc). +The result is a fully configured remote desktod cloud workstation, which can be used for development and testing of the robotic applications within minutes and on a budget. Isaac Sim Automator supports varierty of GPU instances and stop-start functionality to save on cloud costs and a varierty of tools to aid the workflow (like uploading and downloading data, autorun, deployment management, etc). - [Installation](#installation) - [Installing Docker](#installing-docker) From 6c6c44d51cc603137c4d15cea736fe95e5f8ea4d Mon Sep 17 00:00:00 2001 From: Shuo Wang Date: Wed, 15 May 2024 02:04:07 -0700 Subject: [PATCH 05/27] Metropolis sdg workflow changes --- .dockerignore | 2 +- .gitignore | 1 - uploads/autorun.sh | 2 +- uploads/s3_upload.py | 82 ++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 84 insertions(+), 3 deletions(-) create mode 100644 uploads/s3_upload.py diff --git a/.dockerignore b/.dockerignore index 057c696..f4ac0c1 100644 --- a/.dockerignore +++ b/.dockerignore @@ -25,4 +25,4 @@ Dockerfile .vscode/ results/* -uploads/* + diff --git a/.gitignore b/.gitignore index 11abe56..51e4a85 100644 --- a/.gitignore +++ b/.gitignore @@ -16,5 +16,4 @@ __pycache__ **/*_cache results/* -uploads/* .DS_Store diff --git a/uploads/autorun.sh b/uploads/autorun.sh index 0c0460d..e31e47f 100644 --- a/uploads/autorun.sh +++ b/uploads/autorun.sh @@ -7,4 +7,4 @@ # replace with your own command # for example: # ~ubuntu/Desktop/isaacsim.sh --cmd="/isaac-sim/kit/kit /isaac-sim/apps/omni.isaac.sim.kit --allow-root" -~ubuntu/Desktop/isaacsim.sh +~ubuntu/Desktop/isaacsim.sh --cmd="apt-get update && apt-get install -y ffmpeg && /isaac-sim/kit/kit /isaac-sim/apps/omni.isaac.sim.kit --ext-folder /isaac-sim/apps --allow-root" diff --git a/uploads/s3_upload.py b/uploads/s3_upload.py new file mode 100644 index 0000000..7602e1f --- /dev/null +++ b/uploads/s3_upload.py @@ -0,0 +1,82 @@ +import logging +import boto3 +from botocore.exceptions import ClientError +import os +import argparse +import glob +import sys + +logging.basicConfig(stream=sys.stdout, level=logging.INFO) + +def upload_file(file_name, bucket, object_name=None): + """Upload a file to an S3 bucket + + :param file_name: File to upload + :param bucket: Bucket to upload to + :param object_name: S3 object name. If not specified then file_name is used + :return: True if file was uploaded, else False + """ + + # If S3 object_name was not specified, use file_name + if not object_name: + object_name = os.path.basename(file_name) + + # Upload the file + s3_client = boto3.client('s3') + try: + response = s3_client.upload_file(file_name, bucket, object_name) + except ClientError as e: + logging.error(e) + return False + return True + + +def get_args(): + parser = argparse.ArgumentParser("SDG Utils") + parser.add_argument('-sd', '--source_directory', required=False, help='Path to source folder to copy.') + parser.add_argument('-f', '--format_to_copy', required=False, help='Format of files to match and upload, can be left empty for a single file.') + parser.add_argument('-dd', '--destination_directory', required=False, help='Destination folder in S3 folder.') + parser.add_argument('-sf', '--source_file', required=False, help='Path to source file to copy.') + parser.add_argument('-df', '--destination_file', required=False, help='Destination file in S3 folder') + parser.add_argument('-b', '--bucket', required=True, help='S3 bucket to copy data to.') + args = parser.parse_args() + return args + +def main(): + args = get_args() + + logging.info("") + # Folder copy variables + source_directory = args.source_directory + destination_directory = args.destination_directory + format_to_copy = args.format_to_copy + source_file = args.source_file + destination_file = args.destination_file + bucket = args.bucket + + + + if source_directory: + if os.path.isdir(source_directory): + files = glob.glob("{}/**/*.{}".format(source_directory, format_to_copy),recursive=True) + logging.info("Total files to copy - {}".format(len(files))) + for file in files: + logging.info("Copying file {}".format(file)) + file_name = os.path.basename(file) + destination_object = None + if destination_directory: + destination_object = destination_directory + "/" + file_name + upload_file(file, bucket, destination_object) + else: + logging.error("Invalid source_directory passed.") + + if source_file: + if os.path.isfile(source_file): + logging.info("Copying file {}".format(source_file)) + upload_file(source_file, bucket, destination_file) + else: + logging.error("Invalid source_file passed.") + + +if __name__ == "__main__": + main() \ No newline at end of file From 1d06bc0e17f7807e51ab43af458d48c5ee70d190 Mon Sep 17 00:00:00 2001 From: cailani-nv <102393832+cailani-nv@users.noreply.github.com> Date: Wed, 15 May 2024 12:19:19 -0500 Subject: [PATCH 06/27] Create install-aws-cli.sh adding install-aws-cli Signed-off-by: cailani-nv <102393832+cailani-nv@users.noreply.github.com> --- uploads/install-aws-cli.sh | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) create mode 100644 uploads/install-aws-cli.sh diff --git a/uploads/install-aws-cli.sh b/uploads/install-aws-cli.sh new file mode 100644 index 0000000..dffcd7a --- /dev/null +++ b/uploads/install-aws-cli.sh @@ -0,0 +1,25 @@ +#!/bin/bash + +# SPDX-FileCopyrightText: Copyright (c) 2024 NVIDIA CORPORATION & AFFILIATES. All rights reserved. +# SPDX-License-Identifier: LicenseRef-NvidiaProprietary +# +# NVIDIA CORPORATION, its affiliates and licensors retain all intellectual +# property and proprietary rights in and to this material, related +# documentation and any modifications thereto. Any use, reproduction, +# disclosure or distribution of this material and related documentation +# without an express license agreement from NVIDIA CORPORATION or +# its affiliates is strictly prohibited. + +if ! hash aws 2>/dev/null; then + echo "Installing awscli" + { + rm -f /tmp/awscliv2.zip + curl --silent "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o /tmp/awscliv2.zip + rm -rf /tmp/aws + if ! hash unzip 2>/dev/null; then + apt-get -y update && apt-get -y install unzip + fi + unzip /tmp/awscliv2.zip -d /tmp + /tmp/aws/install + } > /dev/null +fi From 5d1ed75f170a22d3ecf47e776bc56e4e6bfae9bb Mon Sep 17 00:00:00 2001 From: cailani-nv <102393832+cailani-nv@users.noreply.github.com> Date: Wed, 15 May 2024 13:30:09 -0500 Subject: [PATCH 07/27] Create credentials Signed-off-by: cailani-nv <102393832+cailani-nv@users.noreply.github.com> --- uploads/credentials | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 uploads/credentials diff --git a/uploads/credentials b/uploads/credentials new file mode 100644 index 0000000..948ea4b --- /dev/null +++ b/uploads/credentials @@ -0,0 +1,3 @@ +[default] +aws_access_key_id = +aws_secret_access_key = From 1639ca98b2879f9e847ec99b485616a57b2f9cdc Mon Sep 17 00:00:00 2001 From: cailani-nv <102393832+cailani-nv@users.noreply.github.com> Date: Wed, 15 May 2024 13:30:54 -0500 Subject: [PATCH 08/27] Create pass-creds-to-container.sh Signed-off-by: cailani-nv <102393832+cailani-nv@users.noreply.github.com> --- uploads/pass-creds-to-container.sh | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 uploads/pass-creds-to-container.sh diff --git a/uploads/pass-creds-to-container.sh b/uploads/pass-creds-to-container.sh new file mode 100644 index 0000000..5a3d163 --- /dev/null +++ b/uploads/pass-creds-to-container.sh @@ -0,0 +1,3 @@ +echo 'export AWS_CONFIG_FILE=/uploads/credentials' >> $HOME/.bashrc + +echo 'export AWS_SHARED_CREDENTIALS_FILE=/uploads/credentials' >> $HOME/.bashrc From 9d4e6a1a3ea0f13d955cf469350a768f6d20f387 Mon Sep 17 00:00:00 2001 From: cailani-nv <102393832+cailani-nv@users.noreply.github.com> Date: Wed, 15 May 2024 13:32:00 -0500 Subject: [PATCH 09/27] Update README.md Signed-off-by: cailani-nv <102393832+cailani-nv@users.noreply.github.com> --- README.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/README.md b/README.md index c326fa8..10ebd8d 100644 --- a/README.md +++ b/README.md @@ -111,6 +111,11 @@ If yoou have completed the above steps or already have your permissions and cred ./run # inside container: ./deploy-aws + +## To run with user filled values ## +# Please make sure fill details inside file "sdg-deploy.txt" + +cat sdg-deploy.txt | xargs ./deploy-aws ``` Tip: Run `./deploy-aws --help` to see more options. From 3cacc15d2e2b60396b362878ba36269a4d72ceba Mon Sep 17 00:00:00 2001 From: cailani-nv <102393832+cailani-nv@users.noreply.github.com> Date: Wed, 15 May 2024 13:34:31 -0500 Subject: [PATCH 10/27] Update isaacsim.sh Signed-off-by: cailani-nv <102393832+cailani-nv@users.noreply.github.com> --- src/ansible/roles/isaac/templates/isaacsim.sh | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/ansible/roles/isaac/templates/isaacsim.sh b/src/ansible/roles/isaac/templates/isaacsim.sh index b5c0327..58d88e2 100755 --- a/src/ansible/roles/isaac/templates/isaacsim.sh +++ b/src/ansible/roles/isaac/templates/isaacsim.sh @@ -3,7 +3,7 @@ # default parameter values # isaac sim startup command -CMD="/isaac-sim/kit/kit \ +CMD="bash uploads/pass-creds-to-container.sh ;apt-get update && apt-get install -y ffmpeg; /isaac-sim/kit/kit \ /isaac-sim/apps/omni.isaac.sim.kit \ --ext-folder /isaac-sim/apps \ --allow-root" @@ -142,6 +142,7 @@ docker run \ \ -v "${OUT_DIR}":/results \ -v "${UPLOADS_DIR}":/uploads \ + -v "${UPLOADS_DIR}/credentials:/root/.aws/credentials" \ -v "${WORKSPACE_DIR}":/workspace \ \ -v "/tmp/.X11-unix:/tmp/.X11-unix" \ From 2fdd2e994b8f7637ca25cfcfa7f3da42e105b96b Mon Sep 17 00:00:00 2001 From: cailani-nv <102393832+cailani-nv@users.noreply.github.com> Date: Wed, 15 May 2024 13:38:23 -0500 Subject: [PATCH 11/27] Update README.md Signed-off-by: cailani-nv <102393832+cailani-nv@users.noreply.github.com> --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 10ebd8d..70b05e0 100644 --- a/README.md +++ b/README.md @@ -104,7 +104,7 @@ for example: You will need _AWS Access Key_ and _AWS Secret Key_ for an existing account. You can obtain those in Identity and Access Management (IAM) Section in the AWS console. -If yoou have completed the above steps or already have your permissions and credentials set up, run the following command in the project root directory: +If you have completed the above steps or already have your permissions and credentials set up, run the following command in the project root directory: ```sh # enter the automator container @@ -114,6 +114,7 @@ If yoou have completed the above steps or already have your permissions and cred ## To run with user filled values ## # Please make sure fill details inside file "sdg-deploy.txt" +## update file under folder "uploads/" "credentials" with aws access and secret key to be passed to IsaacSIM container for the new data upload to S3 cat sdg-deploy.txt | xargs ./deploy-aws ``` From d548da9b64c981ae73cd8c8155e695116aa377e9 Mon Sep 17 00:00:00 2001 From: cailani-nv <102393832+cailani-nv@users.noreply.github.com> Date: Wed, 15 May 2024 14:11:25 -0500 Subject: [PATCH 12/27] Update isaacsim.sh Signed-off-by: cailani-nv <102393832+cailani-nv@users.noreply.github.com> --- src/ansible/roles/isaac/templates/isaacsim.sh | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/ansible/roles/isaac/templates/isaacsim.sh b/src/ansible/roles/isaac/templates/isaacsim.sh index 58d88e2..204813d 100755 --- a/src/ansible/roles/isaac/templates/isaacsim.sh +++ b/src/ansible/roles/isaac/templates/isaacsim.sh @@ -3,8 +3,7 @@ # default parameter values # isaac sim startup command -CMD="bash uploads/pass-creds-to-container.sh ;apt-get update && apt-get install -y ffmpeg; /isaac-sim/kit/kit \ - /isaac-sim/apps/omni.isaac.sim.kit \ +CMD="/isaac-sim/apps/omni.isaac.sim.kit \ --ext-folder /isaac-sim/apps \ --allow-root" From 522f49cfeb37c6beaa7ef4ab86b0c4cd41a8e098 Mon Sep 17 00:00:00 2001 From: cailani-nv <102393832+cailani-nv@users.noreply.github.com> Date: Wed, 15 May 2024 14:13:14 -0500 Subject: [PATCH 13/27] Update autorun.sh Signed-off-by: cailani-nv <102393832+cailani-nv@users.noreply.github.com> --- uploads/autorun.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/uploads/autorun.sh b/uploads/autorun.sh index e31e47f..60c4e30 100644 --- a/uploads/autorun.sh +++ b/uploads/autorun.sh @@ -7,4 +7,4 @@ # replace with your own command # for example: # ~ubuntu/Desktop/isaacsim.sh --cmd="/isaac-sim/kit/kit /isaac-sim/apps/omni.isaac.sim.kit --allow-root" -~ubuntu/Desktop/isaacsim.sh --cmd="apt-get update && apt-get install -y ffmpeg && /isaac-sim/kit/kit /isaac-sim/apps/omni.isaac.sim.kit --ext-folder /isaac-sim/apps --allow-root" +~ubuntu/Desktop/isaacsim.sh --cmd="bash uploads/pass-creds-to-container.sh ; apt-get update && apt-get install -y ffmpeg && /isaac-sim/kit/kit /isaac-sim/apps/omni.isaac.sim.kit --ext-folder /isaac-sim/apps --allow-root" From 7108eae1ff5d1ce56b8637517918301dde6ab0a6 Mon Sep 17 00:00:00 2001 From: cailani-nv <102393832+cailani-nv@users.noreply.github.com> Date: Wed, 15 May 2024 14:14:38 -0500 Subject: [PATCH 14/27] Update isaacsim.sh Signed-off-by: cailani-nv <102393832+cailani-nv@users.noreply.github.com> --- src/ansible/roles/isaac/templates/isaacsim.sh | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/ansible/roles/isaac/templates/isaacsim.sh b/src/ansible/roles/isaac/templates/isaacsim.sh index 204813d..97fa851 100755 --- a/src/ansible/roles/isaac/templates/isaacsim.sh +++ b/src/ansible/roles/isaac/templates/isaacsim.sh @@ -3,7 +3,8 @@ # default parameter values # isaac sim startup command -CMD="/isaac-sim/apps/omni.isaac.sim.kit \ +CMD="/isaac-sim/kit/kit \ + /isaac-sim/apps/omni.isaac.sim.kit \ --ext-folder /isaac-sim/apps \ --allow-root" From e445c9e2782054e82ffc670afa021f5d24df41ad Mon Sep 17 00:00:00 2001 From: cailani-nv <102393832+cailani-nv@users.noreply.github.com> Date: Wed, 15 May 2024 14:15:35 -0500 Subject: [PATCH 15/27] Update isaacsim.sh Signed-off-by: cailani-nv <102393832+cailani-nv@users.noreply.github.com> --- src/ansible/roles/isaac/templates/isaacsim.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ansible/roles/isaac/templates/isaacsim.sh b/src/ansible/roles/isaac/templates/isaacsim.sh index 97fa851..71d39aa 100755 --- a/src/ansible/roles/isaac/templates/isaacsim.sh +++ b/src/ansible/roles/isaac/templates/isaacsim.sh @@ -4,7 +4,7 @@ # isaac sim startup command CMD="/isaac-sim/kit/kit \ - /isaac-sim/apps/omni.isaac.sim.kit \ + /isaac-sim/apps/omni.isaac.sim.kit \ --ext-folder /isaac-sim/apps \ --allow-root" From 2eafeea45e0766a41d0b433e630a0347f609f9a6 Mon Sep 17 00:00:00 2001 From: cailani-nv <102393832+cailani-nv@users.noreply.github.com> Date: Thu, 16 May 2024 11:51:04 -0500 Subject: [PATCH 16/27] Create sdg-deploy.txt Signed-off-by: cailani-nv <102393832+cailani-nv@users.noreply.github.com> --- sdg-deploy.txt | 1 + 1 file changed, 1 insertion(+) create mode 100644 sdg-deploy.txt diff --git a/sdg-deploy.txt b/sdg-deploy.txt new file mode 100644 index 0000000..0610167 --- /dev/null +++ b/sdg-deploy.txt @@ -0,0 +1 @@ +--deployment-name= --region '' --isaac --isaac-instance-type 'g5.2xlarge' --isaac-image 'nvcr.io/nvidian/isaac-sim:latest-develop' --oige 'no' --orbit 'no' --ngc-api-key '' --ngc-api-key-check --aws-access-key-id '' --aws-secret-access-key '' --no-ovami --existing 'ask' From 8ff5131b5f303db1c436f6da9a0b1d25cf9ff8fb Mon Sep 17 00:00:00 2001 From: cailani-nv <102393832+cailani-nv@users.noreply.github.com> Date: Mon, 20 May 2024 12:44:35 -0500 Subject: [PATCH 17/27] Update sdg-deploy.txt Signed-off-by: cailani-nv <102393832+cailani-nv@users.noreply.github.com> --- sdg-deploy.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sdg-deploy.txt b/sdg-deploy.txt index 0610167..dcfb0da 100644 --- a/sdg-deploy.txt +++ b/sdg-deploy.txt @@ -1 +1 @@ ---deployment-name= --region '' --isaac --isaac-instance-type 'g5.2xlarge' --isaac-image 'nvcr.io/nvidian/isaac-sim:latest-develop' --oige 'no' --orbit 'no' --ngc-api-key '' --ngc-api-key-check --aws-access-key-id '' --aws-secret-access-key '' --no-ovami --existing 'ask' +--deployment-name= --region '' --isaac --isaac-instance-type 'g5.12xlarge' --isaac-image 'nvcr.io/nv-metropolis-dev/metropolis-analytic/isaac-sim:latest-develop-05202024' --oige 'no' --orbit 'no' --ngc-api-key '' --ngc-api-key-check --aws-access-key-id '' --aws-secret-access-key '' --no-ovami --existing 'ask' From 8a9e89df252564ea86eac73ca94a439f59f2f780 Mon Sep 17 00:00:00 2001 From: cailani-nv <102393832+cailani-nv@users.noreply.github.com> Date: Mon, 20 May 2024 12:45:36 -0500 Subject: [PATCH 18/27] Update isaacsim.sh Signed-off-by: cailani-nv <102393832+cailani-nv@users.noreply.github.com> --- src/ansible/roles/isaac/templates/isaacsim.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ansible/roles/isaac/templates/isaacsim.sh b/src/ansible/roles/isaac/templates/isaacsim.sh index 71d39aa..d9e53ff 100755 --- a/src/ansible/roles/isaac/templates/isaacsim.sh +++ b/src/ansible/roles/isaac/templates/isaacsim.sh @@ -142,7 +142,7 @@ docker run \ \ -v "${OUT_DIR}":/results \ -v "${UPLOADS_DIR}":/uploads \ - -v "${UPLOADS_DIR}/credentials:/root/.aws/credentials" \ + -v "${UPLOADS_DIR}/credentials":/root/.aws/credentials \ -v "${WORKSPACE_DIR}":/workspace \ \ -v "/tmp/.X11-unix:/tmp/.X11-unix" \ From be125676cf67074c47f6036eb99d05f7ee4dee11 Mon Sep 17 00:00:00 2001 From: Shuo Wang Date: Tue, 21 May 2024 21:11:24 -0700 Subject: [PATCH 19/27] Updated post processing script --- uploads/post_processing.py | 113 +++++++++++++++++++++++++++++++++++++ uploads/s3_upload.py | 82 --------------------------- 2 files changed, 113 insertions(+), 82 deletions(-) create mode 100644 uploads/post_processing.py delete mode 100644 uploads/s3_upload.py diff --git a/uploads/post_processing.py b/uploads/post_processing.py new file mode 100644 index 0000000..8eb8f84 --- /dev/null +++ b/uploads/post_processing.py @@ -0,0 +1,113 @@ +import logging +import boto3 +from botocore.exceptions import ClientError +import os +import argparse +import glob +import sys +from subprocess import PIPE, STDOUT, Popen +logging.basicConfig(stream=sys.stdout, level=logging.INFO) + + +def upload_file(file_name, bucket, object_name=None): + """Upload a file to an S3 bucket + + :param file_name: File to upload + :param bucket: Bucket to upload to + :param object_name: S3 object name. If not specified then file_name is used + :return: True if file was uploaded, else False + """ + + # If S3 object_name was not specified, use file_name + if not object_name: + object_name = os.path.basename(file_name) + + # Upload the file + s3_client = boto3.client('s3') + try: + response = s3_client.upload_file(file_name, bucket, object_name) + except ClientError as e: + logging.error(e) + return False + return True + + +def build_videos(source_directory): + if os.path.isdir(source_directory): + # Grab all the rgb folders in the source directory + rgb_folders = glob.glob("{}/*/rgb/".format(source_directory)) + build_process_list = [] + try: + for folder in rgb_folders: + # Get parent folder name + camer_folder_name = os.path.basename(os.path.abspath(os.path.join(folder, os.pardir))) + build_process = Popen( + "ffmpeg -r 30 -f image2 -s 1920x1080 -start_number 0 -y -i {}/%d.jpeg -vcodec libx264 -crf 23 -pix_fmt yuv420p {}/{}.mp4".format( + folder, folder, camer_folder_name + ), + shell=True, + ) + build_process_list.append(build_process) + # Wait for all ffmpeg processes to finish + for process in build_process: + process.wait() + logging.info("Finished creating videos from images.") + except Exception as e: + logging.error("Could not run ffmpeg command due to error - {}. \n Note, this operation requires ffmpeg to be installed".format(e)) + else: + logging.error("Invalid source_directory passed.") + + +def get_args(): + parser = argparse.ArgumentParser("SDG Utils") + parser.add_argument('-sd', '--source_directory', required=False, help='Path to source folder to copy.') + parser.add_argument('-bu', '--build', required=False, action='store_true', help='Build videos in source foler.') + parser.add_argument('-f', '--format_to_copy', required=False, help='Format of files to match and upload, can be left empty for a single file.') + parser.add_argument('-dd', '--destination_directory', required=False, help='Destination folder in S3 folder.') + parser.add_argument('-sf', '--source_file', required=False, help='Path to source file to copy.') + parser.add_argument('-df', '--destination_file', required=False, help='Destination file in S3 folder') + parser.add_argument('-b', '--bucket', required=False, help='S3 bucket to copy data to.') + args = parser.parse_args() + return args + +def main(): + args = get_args() + source_directory = args.source_directory + destination_directory = args.destination_directory + format_to_copy = args.format_to_copy + source_file = args.source_file + destination_file = args.destination_file + bucket = args.bucket + build = args.build + + # Build videos from images present in source directory + if build: + build_videos(source_directory) + + # If S3 bucket is provided, upload content to S3 bucket. + if bucket: + # Upload multiple files matching a specific format from a directory. + if source_directory: + if os.path.isdir(source_directory): + files = glob.glob("{}/**/*.{}".format(source_directory, format_to_copy),recursive=True) + logging.info("Total files to copy - {}".format(len(files))) + for file in files: + logging.info("Copying file {}".format(file)) + file_name = os.path.basename(file) + destination_object = None + if destination_directory: + destination_object = destination_directory + "/" + file_name + upload_file(file, bucket, destination_object) + else: + logging.error("Invalid source_directory passed.") + # Upload a single file to the s3 bucket. + if source_file: + if os.path.isfile(source_file): + logging.info("Copying file {}".format(source_file)) + upload_file(source_file, bucket, destination_file) + else: + logging.error("Invalid source_file passed.") + + +if __name__ == "__main__": + main() \ No newline at end of file diff --git a/uploads/s3_upload.py b/uploads/s3_upload.py deleted file mode 100644 index 7602e1f..0000000 --- a/uploads/s3_upload.py +++ /dev/null @@ -1,82 +0,0 @@ -import logging -import boto3 -from botocore.exceptions import ClientError -import os -import argparse -import glob -import sys - -logging.basicConfig(stream=sys.stdout, level=logging.INFO) - -def upload_file(file_name, bucket, object_name=None): - """Upload a file to an S3 bucket - - :param file_name: File to upload - :param bucket: Bucket to upload to - :param object_name: S3 object name. If not specified then file_name is used - :return: True if file was uploaded, else False - """ - - # If S3 object_name was not specified, use file_name - if not object_name: - object_name = os.path.basename(file_name) - - # Upload the file - s3_client = boto3.client('s3') - try: - response = s3_client.upload_file(file_name, bucket, object_name) - except ClientError as e: - logging.error(e) - return False - return True - - -def get_args(): - parser = argparse.ArgumentParser("SDG Utils") - parser.add_argument('-sd', '--source_directory', required=False, help='Path to source folder to copy.') - parser.add_argument('-f', '--format_to_copy', required=False, help='Format of files to match and upload, can be left empty for a single file.') - parser.add_argument('-dd', '--destination_directory', required=False, help='Destination folder in S3 folder.') - parser.add_argument('-sf', '--source_file', required=False, help='Path to source file to copy.') - parser.add_argument('-df', '--destination_file', required=False, help='Destination file in S3 folder') - parser.add_argument('-b', '--bucket', required=True, help='S3 bucket to copy data to.') - args = parser.parse_args() - return args - -def main(): - args = get_args() - - logging.info("") - # Folder copy variables - source_directory = args.source_directory - destination_directory = args.destination_directory - format_to_copy = args.format_to_copy - source_file = args.source_file - destination_file = args.destination_file - bucket = args.bucket - - - - if source_directory: - if os.path.isdir(source_directory): - files = glob.glob("{}/**/*.{}".format(source_directory, format_to_copy),recursive=True) - logging.info("Total files to copy - {}".format(len(files))) - for file in files: - logging.info("Copying file {}".format(file)) - file_name = os.path.basename(file) - destination_object = None - if destination_directory: - destination_object = destination_directory + "/" + file_name - upload_file(file, bucket, destination_object) - else: - logging.error("Invalid source_directory passed.") - - if source_file: - if os.path.isfile(source_file): - logging.info("Copying file {}".format(source_file)) - upload_file(source_file, bucket, destination_file) - else: - logging.error("Invalid source_file passed.") - - -if __name__ == "__main__": - main() \ No newline at end of file From 712c37995a0726d8d9db8bd704dec013745ca71d Mon Sep 17 00:00:00 2001 From: cailani-nv <102393832+cailani-nv@users.noreply.github.com> Date: Wed, 22 May 2024 15:04:15 -0500 Subject: [PATCH 20/27] update deploy config format to be more presentable Signed-off-by: cailani-nv <102393832+cailani-nv@users.noreply.github.com> --- sdg-deploy.txt | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/sdg-deploy.txt b/sdg-deploy.txt index dcfb0da..280efc9 100644 --- a/sdg-deploy.txt +++ b/sdg-deploy.txt @@ -1 +1,13 @@ ---deployment-name= --region '' --isaac --isaac-instance-type 'g5.12xlarge' --isaac-image 'nvcr.io/nv-metropolis-dev/metropolis-analytic/isaac-sim:latest-develop-05202024' --oige 'no' --orbit 'no' --ngc-api-key '' --ngc-api-key-check --aws-access-key-id '' --aws-secret-access-key '' --no-ovami --existing 'ask' +--deployment-name= +--region '' +--isaac +--isaac-instance-type 'g5.12xlarge' +--isaac-image 'nvcr.io/nv-metropolis-dev/metropolis-analytic/isaac-sim:latest-develop-05222024' +--oige 'no' +--orbit 'no' +--ngc-api-key '' +--ngc-api-key-check +--aws-access-key-id '' +--aws-secret-access-key '' +--no-ovami +--existing 'ask' From e4211ceeeac0eca69be91288a1f0964db7e33977 Mon Sep 17 00:00:00 2001 From: cailani-nv <102393832+cailani-nv@users.noreply.github.com> Date: Wed, 22 May 2024 21:58:26 -0500 Subject: [PATCH 21/27] Update autorun.sh Signed-off-by: cailani-nv <102393832+cailani-nv@users.noreply.github.com> --- uploads/autorun.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/uploads/autorun.sh b/uploads/autorun.sh index 60c4e30..9b34d42 100644 --- a/uploads/autorun.sh +++ b/uploads/autorun.sh @@ -7,4 +7,4 @@ # replace with your own command # for example: # ~ubuntu/Desktop/isaacsim.sh --cmd="/isaac-sim/kit/kit /isaac-sim/apps/omni.isaac.sim.kit --allow-root" -~ubuntu/Desktop/isaacsim.sh --cmd="bash uploads/pass-creds-to-container.sh ; apt-get update && apt-get install -y ffmpeg && /isaac-sim/kit/kit /isaac-sim/apps/omni.isaac.sim.kit --ext-folder /isaac-sim/apps --allow-root" +~ubuntu/Desktop/isaacsim.sh --cmd="bash uploads/pass-creds-to-container.sh ; apt-get update && apt-get install -y vim ffmpeg && /isaac-sim/kit/kit /isaac-sim/apps/omni.isaac.sim.kit --ext-folder /isaac-sim/apps --allow-root" From 68f3bc8b17df6c0722ba36b39aa15c07dc2c2e4a Mon Sep 17 00:00:00 2001 From: cailani-nv <102393832+cailani-nv@users.noreply.github.com> Date: Tue, 28 May 2024 13:31:02 -0500 Subject: [PATCH 22/27] include vim and nano as part of docker to edit files Signed-off-by: cailani-nv <102393832+cailani-nv@users.noreply.github.com> --- Dockerfile | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Dockerfile b/Dockerfile index a5276be..b7fc503 100644 --- a/Dockerfile +++ b/Dockerfile @@ -20,7 +20,9 @@ RUN apt-get update && apt-get install -qy \ curl \ wget \ gpg \ - jq + jq \ + vim \ + nano # hashicorp sources RUN wget -O- https://apt.releases.hashicorp.com/gpg | \ From 0b865b830702a05f8fd4877d7efc5e3eb9b9de52 Mon Sep 17 00:00:00 2001 From: Shuo Wang Date: Wed, 5 Jun 2024 14:49:07 -0700 Subject: [PATCH 23/27] Post processing script fixes --- uploads/post_processing.py | 30 +++++++++++++++++++++++++----- 1 file changed, 25 insertions(+), 5 deletions(-) diff --git a/uploads/post_processing.py b/uploads/post_processing.py index 8eb8f84..310a1aa 100644 --- a/uploads/post_processing.py +++ b/uploads/post_processing.py @@ -6,6 +6,7 @@ import glob import sys from subprocess import PIPE, STDOUT, Popen +from pathlib import Path logging.basicConfig(stream=sys.stdout, level=logging.INFO) @@ -33,23 +34,42 @@ def upload_file(file_name, bucket, object_name=None): def build_videos(source_directory): + """Builds video from source_directory. Source directory must be parent folder of ground truth generated using ORA extension. + + :param source_directory: Source directory containing ground truth generated using ORA extension. + :return: None + """ if os.path.isdir(source_directory): # Grab all the rgb folders in the source directory rgb_folders = glob.glob("{}/*/rgb/".format(source_directory)) build_process_list = [] + curr_dir = os.getcwd() + logging.info("Creating videos from images in source_directory - {}. This might take a while based on the length of video to be generated. Logs for video creation are at {}.".format(source_directory, os.path.join(curr_dir, "video_creation_logs"))) try: for folder in rgb_folders: # Get parent folder name - camer_folder_name = os.path.basename(os.path.abspath(os.path.join(folder, os.pardir))) + rgb_path = Path(folder) + camera_folder_name = os.path.basename(rgb_path.parent.absolute()) + + # Split till the second occurence of '_' and use the last portion of string. That is, go from World_Cameras_Camera_01 to Camera_01 + camera_folder_name = camera_folder_name.split('_', 2)[-1] + + # Create log folder and log files for video generation + log_file_path = os.path.join(curr_dir, "video_creation_logs", "{}.log".format(camera_folder_name)) + os.makedirs(os.path.dirname(log_file_path), exist_ok=True) + log_file = open(log_file_path, "w") + + # Run ffmpeg command for creating videos build_process = Popen( - "ffmpeg -r 30 -f image2 -s 1920x1080 -start_number 0 -y -i {}/%d.jpeg -vcodec libx264 -crf 23 -pix_fmt yuv420p {}/{}.mp4".format( - folder, folder, camer_folder_name + "ffmpeg -nostdin -r 30 -f image2 -s 1920x1080 -start_number 0 -y -i {}/%d.jpeg -vcodec libx264 -crf 23 -pix_fmt yuv420p {}/{}.mp4".format( + folder, folder, camera_folder_name ), - shell=True, + shell=True,stdout=log_file, stderr=log_file ) build_process_list.append(build_process) + # Wait for all ffmpeg processes to finish - for process in build_process: + for process in build_process_list: process.wait() logging.info("Finished creating videos from images.") except Exception as e: From 3697bf528836cd2884b62f279901013c4ca5cb2e Mon Sep 17 00:00:00 2001 From: cailani-nv <102393832+cailani-nv@users.noreply.github.com> Date: Wed, 5 Jun 2024 19:33:50 -0500 Subject: [PATCH 24/27] Update sdg-deploy.txt with values Signed-off-by: cailani-nv <102393832+cailani-nv@users.noreply.github.com> --- sdg-deploy.txt | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/sdg-deploy.txt b/sdg-deploy.txt index 280efc9..8ce2776 100644 --- a/sdg-deploy.txt +++ b/sdg-deploy.txt @@ -2,9 +2,10 @@ --region '' --isaac --isaac-instance-type 'g5.12xlarge' ---isaac-image 'nvcr.io/nv-metropolis-dev/metropolis-analytic/isaac-sim:latest-develop-05222024' +--isaac-image 'nvcr.io/nvidia/isaac-sim:4.0.0' --oige 'no' ---orbit 'no' +--orbit 'no' +--isaaclab 'no' --ngc-api-key '' --ngc-api-key-check --aws-access-key-id '' From ea3d20b2f5a6bab96fa227325c324d104f4ae399 Mon Sep 17 00:00:00 2001 From: cailani-nv <102393832+cailani-nv@users.noreply.github.com> Date: Wed, 5 Jun 2024 20:18:35 -0500 Subject: [PATCH 25/27] Update autorun.sh update the configs as per tool version Signed-off-by: cailani-nv <102393832+cailani-nv@users.noreply.github.com> --- uploads/autorun.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/uploads/autorun.sh b/uploads/autorun.sh index 3dff62a..2e18a1b 100644 --- a/uploads/autorun.sh +++ b/uploads/autorun.sh @@ -8,6 +8,6 @@ # for example: # ~ubuntu/Desktop/isaacsim.sh --cmd="/isaac-sim/kit/kit /isaac-sim/apps/omni.isaac.sim.kit --allow-root" -~ubuntu/Desktop/isaacsim.sh --cmd="bash uploads/pass-creds-to-container.sh ; apt-get update && apt-get install -y vim ffmpeg && /isaac-sim/kit/kit /isaac-sim/apps/omni.isaac.sim.kit --ext-folder /isaac-sim/apps --allow-root" +~/isaacsim.sh --cmd="bash uploads/pass-creds-to-container.sh ; apt-get update && apt-get install -y vim ffmpeg && /isaac-sim/kit/kit /isaac-sim/apps/omni.isaac.sim.kit --ext-folder /isaac-sim/apps --allow-root" From 8a52bde0a71fcc2f9194fb4b15ae3d686e22be73 Mon Sep 17 00:00:00 2001 From: cailani-nv <102393832+cailani-nv@users.noreply.github.com> Date: Wed, 12 Jun 2024 18:35:40 -0500 Subject: [PATCH 26/27] Update autorun.sh Signed-off-by: cailani-nv <102393832+cailani-nv@users.noreply.github.com> --- uploads/autorun.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/uploads/autorun.sh b/uploads/autorun.sh index 2e18a1b..56a5a32 100644 --- a/uploads/autorun.sh +++ b/uploads/autorun.sh @@ -8,6 +8,6 @@ # for example: # ~ubuntu/Desktop/isaacsim.sh --cmd="/isaac-sim/kit/kit /isaac-sim/apps/omni.isaac.sim.kit --allow-root" -~/isaacsim.sh --cmd="bash uploads/pass-creds-to-container.sh ; apt-get update && apt-get install -y vim ffmpeg && /isaac-sim/kit/kit /isaac-sim/apps/omni.isaac.sim.kit --ext-folder /isaac-sim/apps --allow-root" +~/isaacsim.sh --cmd="bash /uploads/pass-creds-to-container.sh ; apt-get update && apt-get install -y vim ffmpeg && /isaac-sim/kit/kit /isaac-sim/apps/omni.isaac.sim.kit --ext-folder /isaac-sim/apps --allow-root" From 83ab2bffaa424cdcee6b2e9d69eed121fa983844 Mon Sep 17 00:00:00 2001 From: Shuo Wang Date: Wed, 12 Jun 2024 20:21:31 -0700 Subject: [PATCH 27/27] Added imageMetadata.json creation script && changed ffmpeg cmd --- uploads/create_image_metadata.py | 49 ++++++++++++++++++++++++++++++++ uploads/post_processing.py | 4 +-- 2 files changed, 51 insertions(+), 2 deletions(-) create mode 100644 uploads/create_image_metadata.py diff --git a/uploads/create_image_metadata.py b/uploads/create_image_metadata.py new file mode 100644 index 0000000..36687ed --- /dev/null +++ b/uploads/create_image_metadata.py @@ -0,0 +1,49 @@ +''' +Script for generating image metadatafile 'image.json' from calibration file. + +The image.json file generated follows the schema required by the rtls app. +''' + +import json +import os +import argparse + +image_metadata_file_name = "imageMetadata.json" +metadata_dict = {"images": [{"place": "", "view": "plan-view", "fileName": "Top.png"}]} + +def generate_image_metadata(calibration_file_path, output_folder_path = None): + calibration_json = None + with open(calibration_file_path) as calibration_json_file: + calibration_json = json.load(calibration_json_file) + + location_string = '/'.join(["{}={}".format(item['name'], item['value']) for item in calibration_json["sensors"][0]['place']]) + + if not location_string: + print("Could not construct {} file from calibration file {}.".format(image_metadata_file_name, calibration_file_path)) + return + + metadata_dict["images"][0]["place"] = location_string + + # Write output to file + if output_folder_path: + output_file_path = os.path.join(output_folder_path, image_metadata_file_name) + else: + curr_dir = os.getcwd() + output_file_path = os.path.join(curr_dir, image_metadata_file_name) + + with open(output_file_path, "w") as outfile: + json.dump(metadata_dict, outfile) + +def get_args(): + parser = argparse.ArgumentParser("Image Metadata Parser") + parser.add_argument('-c', '--calibration_file_path', required=True, help='Path of calibration file to read metadata information from.') + parser.add_argument('-d', '--destination_folder', required=False, help='Destination folder to write to.') + args = parser.parse_args() + return args + +def main(): + args = get_args() + generate_image_metadata(args.calibration_file_path, args.destination_folder) + +if __name__ == "__main__": + main() diff --git a/uploads/post_processing.py b/uploads/post_processing.py index 310a1aa..a5ec696 100644 --- a/uploads/post_processing.py +++ b/uploads/post_processing.py @@ -58,10 +58,10 @@ def build_videos(source_directory): log_file_path = os.path.join(curr_dir, "video_creation_logs", "{}.log".format(camera_folder_name)) os.makedirs(os.path.dirname(log_file_path), exist_ok=True) log_file = open(log_file_path, "w") - + # Run ffmpeg command for creating videos build_process = Popen( - "ffmpeg -nostdin -r 30 -f image2 -s 1920x1080 -start_number 0 -y -i {}/%d.jpeg -vcodec libx264 -crf 23 -pix_fmt yuv420p {}/{}.mp4".format( + "ffmpeg -nostdin -r 30 -f image2 -s 1920x1080 -start_number 0 -y -i {}/%d.jpeg -vcodec libx264 -crf 23 -x264opts 'bframes=0:keyint=30' -pix_fmt yuv420p {}/{}.mp4".format( folder, folder, camera_folder_name ), shell=True,stdout=log_file, stderr=log_file