diff --git a/third_party/expressive_humanoid/.gitignore b/third_party/expressive_humanoid/.gitignore new file mode 100644 index 00000000..89fa257b --- /dev/null +++ b/third_party/expressive_humanoid/.gitignore @@ -0,0 +1,4 @@ +sip-4.19.3.tar.gz +fbx202032_fbxpythonbindings_linux.tar.gz +fbx202032_fbxsdk_linux.tar.gz +CMU_fbx.zip \ No newline at end of file diff --git a/third_party/expressive_humanoid/Dockerfile b/third_party/expressive_humanoid/Dockerfile new file mode 100644 index 00000000..461d2692 --- /dev/null +++ b/third_party/expressive_humanoid/Dockerfile @@ -0,0 +1,146 @@ +# docker build -t fbx_image . +# docker run -it fbx_image +ARG TARGETPLATFORM +FROM --platform=${TARGETPLATFORM:-linux/amd64} ubuntu:20.04 AS base + +# Set environment variables +ENV DEBIAN_FRONTEND=noninteractive \ + HOME="/home/user" \ + FBX_SDK_VERSION="2020.3.2" \ + SIP_VERSION="4.19.3" \ + PYTHON_VERSION="3.8" \ + FBX_SDK_PATH="$HOME/fbx_setup/fbx_sdk" \ + FBX_PYTHON_BINDING_PATH="$HOME/fbx_setup/fbx_python_bindings" \ + SIP_ROOT="$HOME/fbx_setup/sip" \ + FBXSDK_ROOT="$FBX_SDK_PATH" \ + SIP_PATH="$SIP_ROOT/sip-$SIP_VERSION" \ + PYTHON_EXECUTABLE="/home/user/miniconda/envs/humanoid/bin/python" + +# Update and install dependencies +RUN apt-get update && \ + apt-get install -y --no-install-recommends \ + build-essential \ + libxml2-dev \ + zlib1g-dev \ + wget \ + python${PYTHON_VERSION} \ + python${PYTHON_VERSION}-dev \ + python3-pip \ + libssl-dev \ + vim \ + libcurl4-openssl-dev && \ + rm -rf /var/lib/apt/lists/* + +# Create necessary directories +RUN mkdir -p $FBX_SDK_PATH $FBX_PYTHON_BINDING_PATH $SIP_ROOT + +# Install Miniconda +RUN wget -qO- https://repo.anaconda.com/miniconda/Miniconda3-latest-Linux-x86_64.sh -O miniconda.sh && \ + /bin/bash miniconda.sh -b -p $HOME/miniconda && \ + rm miniconda.sh && \ + $HOME/miniconda/bin/conda init bash + +FROM base AS install_fbx + +# Make sure the base environment is activated by default +SHELL ["/bin/bash", "-c"] + +# Install packages inside the Conda environment +RUN /bin/bash -c "source ~/.bashrc && \ + conda create -n humanoid python=3.8 -y && \ + conda activate humanoid && \ + conda install -y pytorch==1.10.0 torchvision==0.11.1 torchaudio==0.10.0 cudatoolkit=11.3 -c pytorch && \ + conda install -y 'numpy<1.24' && \ + conda install -c conda-forge gxx_linux-64=12.1.0 -y && \ + pip install pydelatin wandb tqdm opencv-python ipdb pyfqmr flask dill gdown pandas matplotlib ruamel.yaml xlrd scipy" + +FROM install_fbx AS base_conda + +# Install FBX SDK +WORKDIR $FBX_SDK_PATH +COPY fbx202032_fbxsdk_linux.tar.gz $FBX_SDK_PATH/ +RUN tar xzf fbx202032_fbxsdk_linux.tar.gz && \ + chmod +x fbx202032_fbxsdk_linux +COPY install_fbx.sh . +RUN chmod +x install_fbx.sh && ./install_fbx.sh + +FROM base_conda AS fbx_python_bindings + +# Install FBX Python Bindings +WORKDIR $FBX_PYTHON_BINDING_PATH +COPY fbx202032_fbxpythonbindings_linux.tar.gz $FBX_PYTHON_BINDING_PATH/ +RUN tar xzf fbx202032_fbxpythonbindings_linux.tar.gz && \ + chmod +x fbx202032_fbxpythonbindings_linux +COPY install_fbx_bindings.sh . +RUN chmod +x install_fbx_bindings.sh && ./install_fbx_bindings.sh + +FROM fbx_python_bindings AS sip + +# Install SIP +WORKDIR $SIP_ROOT +RUN wget "https://sourceforge.net/projects/pyqt/files/sip/sip-${SIP_VERSION}/sip-${SIP_VERSION}.tar.gz/download" -O "sip-${SIP_VERSION}.tar.gz" && \ + tar xzf "sip-${SIP_VERSION}.tar.gz" && \ + cd sip-${SIP_VERSION} && \ + $PYTHON_EXECUTABLE configure.py && \ + make && \ + make install + +ENV SIP_ROOT="$SIP_ROOT/sip-$SIP_VERSION" + +FROM sip AS build_fbx + +# Build the SDK +WORKDIR $FBX_PYTHON_BINDING_PATH +RUN $PYTHON_EXECUTABLE PythonBindings.py "Python3_x64" buildsip + +# Modify the Makefile to fix linking order +WORKDIR $FBX_PYTHON_BINDING_PATH/build/Python38_x64 +RUN make clean && \ + sed -i 's|\(LIBS = -L[^ ]*\) -lz -lxml2 \([^ ]*\)|\1 \2 -lz -lxml2|' Makefile + +# Build and install +RUN make install + +# Build the SDK +WORKDIR $FBX_PYTHON_BINDING_PATH +RUN $PYTHON_EXECUTABLE PythonBindings.py "Python3_x64" buildsip + +FROM build_fbx AS rebuild_fbx + +# Install git +WORKDIR $HOME +RUN apt-get update && apt-get install -y git unzip +RUN git clone https://github.com/Ke-Wang1017/expressive_humanoid.git expressive_humanoid + +WORKDIR $HOME/expressive_humanoid/ASE/ase/poselib/data/ +COPY CMU_fbx.zip . +RUN mkdir -p cmu_fbx_all && unzip CMU_fbx.zip -d cmu_fbx_all/ + +WORKDIR $HOME/expressive_humanoid/ASE/ase/poselib/ +COPY test_fbx.py . +RUN $PYTHON_EXECUTABLE test_fbx.py && echo "FBX works" + +# Set the default command to bash +COPY parse_cmu_mocap_all_2.py $HOME/expressive_humanoid/ASE/ase/poselib/ +COPY fbx_importer_all_2.py $HOME/expressive_humanoid/ASE/ase/poselib/ + +FROM rebuild_fbx AS final + +RUN $PYTHON_EXECUTABLE parse_cmu_mocap_all_2.py +RUN $PYTHON_EXECUTABLE fbx_importer_all_2.py +RUN mkdir -p pkl retarget_npy +RUN $PYTHON_EXECUTABLE retarget_motion_stompy_all.py + +WORKDIR $HOME/expressive_humanoid/legged_gym/legged_gym/scripts +# Train for 1 iteration and kill the program to have a dummy model to load. +RUN $PYTHON_EXECUTABLE train.py debug --task stompy_view --motion_name motions_debug.yaml --debug + +# Run the play script to visualize the motion +RUN $PYTHON_EXECUTABLE play.py debug --task stompy_view --motion_name motions_debug.yaml + +RUN $PYTHON_EXECUTABLE train.py 060-40-some_descriptions_of_run --device cuda:0 --entity WANDB_ENTITY +RUN $PYTHON_EXECUTABLE play.py 060-40 --task stompy_mimic --record_video + +FROM final AS amp + +CMD ["/bin/bash"] \ No newline at end of file diff --git a/third_party/expressive_humanoid/LICENSE b/third_party/expressive_humanoid/LICENSE new file mode 100644 index 00000000..c1829d60 --- /dev/null +++ b/third_party/expressive_humanoid/LICENSE @@ -0,0 +1,8 @@ +# This file is kept for experimental purposes. All software contained within complies with their respective licenses. +# The following software is included: +# - Expressive Humanoid (https://github.com/chengxuxin/expressive-humanoid) +# - Expressive Humanoid (https://github.com/Ke-Wang1017/expressive_humanoid) +# - CMU Motion Capture Data +# - ASE +# - FBX SDK +# - SIP \ No newline at end of file diff --git a/third_party/expressive_humanoid/download_assets.sh b/third_party/expressive_humanoid/download_assets.sh new file mode 100644 index 00000000..338657fa --- /dev/null +++ b/third_party/expressive_humanoid/download_assets.sh @@ -0,0 +1,11 @@ +echo "Starting download of CMU_fbx.zip" +aws s3 cp s3://kscale-public/expressive_humanoid/CMU_fbx.zip . & +echo "Starting download of fbx202032_fbxpythonbindings_linux.tar.gz" +aws s3 cp s3://kscale-public/expressive_humanoid/fbx202032_fbxpythonbindings_linux.tar.gz . & +echo "Starting download of fbx202032_fbxsdk_linux.tar.gz" +aws s3 cp s3://kscale-public/expressive_humanoid/fbx202032_fbxsdk_linux.tar.gz . & +echo "Starting download of sip-4.19.3.tar.gz" +aws s3 cp s3://kscale-public/expressive_humanoid/sip-4.19.3.tar.gz . & + +wait +echo "All downloads completed" \ No newline at end of file diff --git a/third_party/expressive_humanoid/fbx_importer_all_2.py b/third_party/expressive_humanoid/fbx_importer_all_2.py new file mode 100644 index 00000000..4d44d2c3 --- /dev/null +++ b/third_party/expressive_humanoid/fbx_importer_all_2.py @@ -0,0 +1,43 @@ +"""This script converts CMU Motion Capture data from FBX format to NPY format. """ +import sys +import os +from tqdm import tqdm +from poselib.skeleton.skeleton3d import SkeletonMotion +import multiprocessing + +sys.path.append("/home/user/fbx_setup/fbx_python_bindings/build/Distrib/site-packages/fbx/") + +def process_file(i, fbx_file, all_fbx_path): + if fbx_file.endswith(".fbx"): + print(i, fbx_file) + motion = SkeletonMotion.from_fbx( + fbx_file_path=os.path.join(all_fbx_path, fbx_file), + root_joint="Hips", + fps=60 + ) + motion.to_file(f"data/npy/{fbx_file[:-4]}.npy") + +def main(): + all_fbx_path = "data/cmu_fbx_all/" + all_fbx_files = sorted(os.listdir(all_fbx_path)) + + all_fbx_filtered = [] + for fbx in all_fbx_files: + npy = fbx.split(".")[0] + ".npy" + target_motion_file = os.path.join(all_fbx_path, "../npy/", npy) + if os.path.exists(target_motion_file): + print("Already exists, skip: ", fbx) + continue + all_fbx_filtered.append(fbx) + + print(len(all_fbx_filtered)) + + for fbx_file in tqdm(all_fbx_filtered): + process_file(None, fbx_file, all_fbx_path) + + n_workers = multiprocessing.cpu_count() + with multiprocessing.Pool(n_workers) as pool: + list(tqdm(pool.starmap(process_file, [(i, fbx_file, all_fbx_path) for i, fbx_file in enumerate(all_fbx_filtered)]), total=len(all_fbx_filtered))) + +if __name__ == "__main__": + main() \ No newline at end of file diff --git a/third_party/expressive_humanoid/install_fbx.sh b/third_party/expressive_humanoid/install_fbx.sh new file mode 100644 index 00000000..aee5f5b3 --- /dev/null +++ b/third_party/expressive_humanoid/install_fbx.sh @@ -0,0 +1,6 @@ +#!/bin/bash +./fbx202032_fbxsdk_linux <