From 2847c557fa228b2d22853e5eaa74e0bb63822a79 Mon Sep 17 00:00:00 2001 From: John Date: Tue, 27 Jan 2026 15:53:17 -0500 Subject: [PATCH 1/8] updated pegasus version, updated docker compose version. Connects robot and px4, but WIP ogn api updates --- config/isaac_sim_config.yaml | 1 - gcs/docker/gcs-base-docker-compose.yaml | 1 - robot/docker/.bashrc | 8 ++- robot/docker/docker-compose.yaml | 23 ++++++- simulation/isaac-sim/docker/.bashrc | 14 ++++- .../isaac-sim/docker/Dockerfile.isaac-ros | 60 +++++++++++-------- .../isaac-sim/docker/docker-compose.yaml | 2 +- .../isaac-sim/extensions/PegasusSimulator | 2 +- .../example_one_px4_pegasus_launch_script.py | 22 +++++-- .../simple-sim/docker/docker-compose.yaml | 2 +- 10 files changed, 92 insertions(+), 43 deletions(-) diff --git a/config/isaac_sim_config.yaml b/config/isaac_sim_config.yaml index 3fbbc3c86..daf256e22 100644 --- a/config/isaac_sim_config.yaml +++ b/config/isaac_sim_config.yaml @@ -6,7 +6,6 @@ isaac_sim: enabled_extensions: - "airlab.airstack" - "pegasus.simulator" - - "omni.physx.forcefields" # Whether to start simulation playback automatically play_on_start: true diff --git a/gcs/docker/gcs-base-docker-compose.yaml b/gcs/docker/gcs-base-docker-compose.yaml index 800fcc920..c1502d4ab 100644 --- a/gcs/docker/gcs-base-docker-compose.yaml +++ b/gcs/docker/gcs-base-docker-compose.yaml @@ -23,7 +23,6 @@ services: - capabilities: [gpu] count: 1 driver: nvidia - runtime: nvidia entrypoint: '' environment: - AUTOLAUNCH=${AUTOLAUNCH:-false} diff --git a/robot/docker/.bashrc b/robot/docker/.bashrc index 1899e5eb2..83f42a18c 100755 --- a/robot/docker/.bashrc +++ b/robot/docker/.bashrc @@ -23,8 +23,12 @@ function bws(){ COLCON_LOG_PATH="$ROS2_WS_DIR"/log colcon build --symlink-install --base-paths "$ROS2_WS_DIR"/ --build-base "$ROS2_WS_DIR"/build/ --install-base "$ROS2_WS_DIR"/install/ "$@" } function sws(){ - echo "Sourcing "$ROS2_WS_DIR"/install/local_setup.bash" - source "$ROS2_WS_DIR"/install/local_setup.bash || echo "Please make sure to build first with 'bws'" + if [ -f "$ROS2_WS_DIR/install/local_setup.bash" ]; then + echo "Sourcing $ROS2_WS_DIR/install/local_setup.bash" + source "$ROS2_WS_DIR/install/local_setup.bash" + else + echo "Workspace not built yet. Please make sure to build first with 'bws'" + fi } # Function to prompt user for confirmation diff --git a/robot/docker/docker-compose.yaml b/robot/docker/docker-compose.yaml index 350bf3690..be0aed4a8 100644 --- a/robot/docker/docker-compose.yaml +++ b/robot/docker/docker-compose.yaml @@ -39,7 +39,12 @@ services: # for multiple robots deploy: replicas: ${NUM_ROBOTS:-1} - runtime: nvidia + resources: + reservations: + devices: + - driver: nvidia + count: 1 + capabilities: [gpu] simple-robot: profiles: !override @@ -74,7 +79,13 @@ services: ipc: host command: > bash -c "ssh service restart; tmux new -d -s robot_bringup && tmux send-keys -t robot_bringup 'bws && sws && DATE=$(date | sed \"s/ /_/g\" | sed \"s/:/_/g\") ros2 launch ${ROBOT_LAUNCH_PACKAGE} ${ROBOT_LAUNCH_FILE} sim:="false" ' ENTER && sleep infinity" - runtime: nvidia + deploy: + resources: + reservations: + devices: + - driver: nvidia + count: 1 + capabilities: [gpu] # assumes network isolation via a physical router, so uses network_mode=host network_mode: host volumes: @@ -98,8 +109,14 @@ services: && tmux send-keys -t zed_driver 'bws && sws && ros2 launch zed_wrapper zed_dual_camera.launch.py pose_cam_serial:='41591402' wire_cam_serial:='44405253' camera_name:=\"robot_1/sensors\" node_name:=\"front_stereo\" ' ENTER && sleep infinity" + deploy: + resources: + reservations: + devices: + - driver: nvidia + count: 1 + capabilities: [gpu] network_mode: host - runtime: nvidia privileged: true ipc: host pid: host diff --git a/simulation/isaac-sim/docker/.bashrc b/simulation/isaac-sim/docker/.bashrc index 427f6c16f..71569b7dd 100644 --- a/simulation/isaac-sim/docker/.bashrc +++ b/simulation/isaac-sim/docker/.bashrc @@ -121,13 +121,21 @@ fi # --- ROS2 setup --- -source /opt/ros/humble/setup.bash -source /humble_ws/install/setup.bash # isaacsim ros2 package +source /opt/ros/jazzy/setup.bash +source /jazzy_ws/install/setup.bash # isaacsim ros2 package + +# Fix for Isaac Sim 4.5/5.1 on ROS 2 Jazzy: +# Remove the system ROS 2 Python 3.12 paths from PYTHONPATH to prevent them from +# leaking into Isaac Sim's internal Python 3.10 environment. +export PYTHONPATH=$(echo $PYTHONPATH | tr ':' '\n' | grep -v "ros/jazzy/lib/python3.12/site-packages" | paste -sd ':' -) +# Add internal Isaac Sim rclpy for Jazzy to PYTHONPATH +export PYTHONPATH=$PYTHONPATH:/isaac-sim/exts/isaacsim.ros2.bridge/jazzy/rclpy + # needed for communication with Isaac Sim ROS2 # https://docs.omniverse.nvidia.com/isaacsim/latest/installation/install_ros.html#enabling-the-ros-bridge-extension export FASTRTPS_DEFAULT_PROFILES_FILE="/isaac-sim/fastdds.xml" export RMW_IMPLEMENTATION=rmw_fastrtps_cpp # for local development, prevent conflict with other desktops -export ROS_LOCALHOST_ONLY=1 +export ROS_AUTOMATIC_DISCOVERY_RANGE=LOCALHOST # --- Isaac Setup --- alias runapp="/isaac-sim/runapp.sh --path omniverse://airlab-nucleus.andrew.cmu.edu/Library/Assets/Ascent_Aerosystems/Spirit_UAV/spirit_uav_red_yellow.prop.usd" diff --git a/simulation/isaac-sim/docker/Dockerfile.isaac-ros b/simulation/isaac-sim/docker/Dockerfile.isaac-ros index 269211a71..17f38f434 100644 --- a/simulation/isaac-sim/docker/Dockerfile.isaac-ros +++ b/simulation/isaac-sim/docker/Dockerfile.isaac-ros @@ -1,9 +1,11 @@ -ARG ISAAC_VERSION="4.5.0" +ARG ISAAC_VERSION="5.1.0" # expects context to be the root of the repository, i.e. AirStack/. this is so we can access AirStack/ros_ws/ FROM nvcr.io/nvidia/isaac-sim:${ISAAC_VERSION} ARG ISAAC_VERSION WORKDIR /isaac-sim +USER root + # isaac's ros2 launch run_isaacsim.launch.py hardcodes to search in this path, so we have to put the executables here RUN mkdir -p /root/.local/share/ov/pkg/ && \ ln -s /isaac-sim /root/.local/share/ov/pkg/isaac-sim-${ISAAC_VERSION} @@ -14,7 +16,7 @@ ENV OMNI_KIT_ALLOW_ROOT=1 # setup environment ENV LANG=C.UTF-8 ENV LC_ALL=C.UTF-8 -ENV ROS_DISTRO=humble +ENV ROS_DISTRO=jazzy # setup timezone RUN echo 'Etc/UTC' > /etc/timezone && \ @@ -64,32 +66,35 @@ RUN set -eux; \ rm -rf "$GNUPGHOME" # setup ros2 apt source -RUN echo "deb [ signed-by=/usr/share/keyrings/ros2-latest-archive-keyring.gpg ] http://packages.ros.org/ros2/ubuntu jammy main" > /etc/apt/sources.list.d/ros2-latest.list +RUN echo "deb [ signed-by=/usr/share/keyrings/ros2-latest-archive-keyring.gpg ] http://packages.ros.org/ros2/ubuntu noble main" > /etc/apt/sources.list.d/ros2-latest.list # Remove conflicting third-party apt sources that cause libbrotli conflicts RUN rm -f /etc/apt/sources.list.d/*deb.sury.org*.list || true && apt-get update -RUN apt-get update && \ - apt-get install -y --allow-downgrades --no-install-recommends libbrotli1=1.0.9-2build6 && \ - apt-mark hold libbrotli1 && \ - apt-get install -y --no-install-recommends \ - libfreetype6-dev \ - libfontconfig1-dev \ - ros-humble-desktop \ - ros-dev-tools \ - python3-rosdep \ - ros-humble-tf2* \ - ros-humble-mavros \ - ros-humble-ackermann-msgs \ - ros-humble-topic-tools \ - ros-humble-grid-map \ - ros-humble-domain-bridge \ - python3-colcon-common-extensions && \ - rm -rf /var/lib/apt/lists/* +RUN apt-get install -y --no-install-recommends libbrotli1 +RUN apt-mark hold libbrotli1 +RUN apt-get install -y --no-install-recommends libfreetype6-dev +RUN apt-get install -y --no-install-recommends libfontconfig1-dev +RUN apt-get install -y --no-install-recommends ros-jazzy-desktop +RUN apt-get install -y --no-install-recommends ros-dev-tools +RUN apt-get install -y --no-install-recommends python3-rosdep +RUN apt-get install -y --no-install-recommends ros-jazzy-tf2* +RUN apt-get install -y --no-install-recommends ros-jazzy-mavros +RUN apt-get install -y --no-install-recommends ros-jazzy-ackermann-msgs +RUN apt-get install -y --no-install-recommends ros-jazzy-topic-tools +RUN apt-get install -y --no-install-recommends ros-jazzy-grid-map +RUN apt-get install -y --no-install-recommends ros-jazzy-domain-bridge +RUN apt-get install -y --no-install-recommends ros-jazzy-moveit +RUN apt-get install -y --no-install-recommends python3-colcon-common-extensions +RUN rm -rf /var/lib/apt/lists/* # setup mavros dependencies -RUN /opt/ros/humble/lib/mavros/install_geographiclib_datasets.sh +RUN /opt/ros/jazzy/lib/mavros/install_geographiclib_datasets.sh + +# Update LD_LIBRARY_PATH to include ROS2 libraries (Fixes internal rclpy import) +ENV LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/opt/ros/jazzy/lib:/jazzy/lib +ENV RMW_IMPLEMENTATION=rmw_fastrtps_cpp # install python packages RUN /isaac-sim/python.sh -m pip install --upgrade pip && \ @@ -105,9 +110,9 @@ ARG isaac_dir_name="IsaacSim-ros_workspaces-IsaacSim-${ISAAC_VERSION}" RUN cd /tmp/ && \ curl -L -O https://github.com/isaac-sim/IsaacSim-ros_workspaces/archive/refs/tags/IsaacSim-${ISAAC_VERSION}.zip && \ unzip IsaacSim-${ISAAC_VERSION}.zip && \ - mv ${isaac_dir_name}/humble_ws /humble_ws && \ - cd /humble_ws && \ - . /opt/ros/humble/setup.sh && \ + mv ${isaac_dir_name}/jazzy_ws /jazzy_ws && \ + cd /jazzy_ws && \ + . /opt/ros/jazzy/setup.sh && \ colcon build --symlink-install && \ rm -rf /tmp/IsaacSim-${ISAAC_VERSION}.zip /tmp/${isaac_dir_name} @@ -133,6 +138,11 @@ WORKDIR /root/Documents/Kit/shared/exts/ RUN git clone https://github.com/castacks/PegasusSimulator-AirStack-Integration.git /tmp/PegasusSimulator && \ mv /tmp/PegasusSimulator/extensions/pegasus.simulator . +# Add extension search path configuration for Kit +# This ensures that /root/Documents/Kit/shared/exts is always searched for extensions +ARG KIT_ARGS="--ext-folder /root/Documents/Kit/shared/exts" +ENV OMNI_APP_ARGS="${KIT_ARGS}" + # rm -rf /tmp/PegasusSimulator ENV ISAACSIM_PATH=/isaac-sim ENV ACCEPT_EULA="Y" @@ -156,7 +166,7 @@ RUN git clone https://github.com/tmux-plugins/tpm /root/.tmux/plugins/tpm # copy FastDDS config COPY docker/fastdds.xml /isaac-sim/fastdds.xml -# ROS2 humble launch script seeks this +# ROS2 launch script seeks this RUN ln -s /isaac-sim /root/isaacsim # Cleanup. Prevent people accidentally doing git commits as root in Docker diff --git a/simulation/isaac-sim/docker/docker-compose.yaml b/simulation/isaac-sim/docker/docker-compose.yaml index cd7aff4d7..9ff0328bb 100644 --- a/simulation/isaac-sim/docker/docker-compose.yaml +++ b/simulation/isaac-sim/docker/docker-compose.yaml @@ -65,7 +65,7 @@ services: - $HOME/Documents/isaac_sim_data/data:/root/.local/share/ov/data:rw - $HOME/documents/isaac_sim_data/documents:/root/Documents:rw # IMPORTANT: set the version number without the trailing .0 - - ./user.config.json:/root/.local/share/ov/data/Kit/Isaac-Sim Full/4.5/user.config.json:rw + - ./user.config.json:/root/.local/share/ov/data/Kit/Isaac-Sim Full/5.1/user.config.json:rw - ./ui.py:/isaac-sim/kit/exts/omni.kit.widget.nucleus_connector/omni/kit/widget/nucleus_connector/ui.py:rw # developer stuff - .dev:/root/.dev:rw # developer config diff --git a/simulation/isaac-sim/extensions/PegasusSimulator b/simulation/isaac-sim/extensions/PegasusSimulator index f6fae8d34..6db81b519 160000 --- a/simulation/isaac-sim/extensions/PegasusSimulator +++ b/simulation/isaac-sim/extensions/PegasusSimulator @@ -1 +1 @@ -Subproject commit f6fae8d34d9f95470c5976c11ca8a670421fbfb2 +Subproject commit 6db81b519772629508b0d911c2865137d341d476 diff --git a/simulation/isaac-sim/launch_scripts/example_one_px4_pegasus_launch_script.py b/simulation/isaac-sim/launch_scripts/example_one_px4_pegasus_launch_script.py index 60c24716a..25961cace 100755 --- a/simulation/isaac-sim/launch_scripts/example_one_px4_pegasus_launch_script.py +++ b/simulation/isaac-sim/launch_scripts/example_one_px4_pegasus_launch_script.py @@ -13,6 +13,9 @@ # Start Isaac Sim's simulation environment (Must start this before importing omni modules) simulation_app = SimulationApp({"headless": False}) +import rclpy +print(f"[Launcher] SUCCESS: rclpy imported from {rclpy.__file__}") + import omni.kit.app import omni.timeline from omni.isaac.core.world import World @@ -40,9 +43,9 @@ # Explicitly enable required extensions ext_manager = omni.kit.app.get_app().get_extension_manager() + for ext in [ - # "airlab.airstack", - "omni.physx.forcefields", + "airlab.airstack", "omni.graph.core", # Core runtime for OmniGraph engine "omni.graph.action", # Action Graph framework "omni.graph.action_nodes", # Built-in Action Graph node library @@ -52,11 +55,15 @@ "omni.graph.window.action", # Action Graph editor window "omni.graph.window.generic", # Generic graph UI tools "omni.graph.ui_nodes", # UI node building helpers - "airlab.pegasus", # Airlab extension Pegasus core extension "pegasus.simulator", ]: if not ext_manager.is_extension_enabled(ext): - ext_manager.set_extension_enabled(ext, True) + print(f"[Launcher] Enabling extension: {ext}") + # Try both methods for robustness in different Kit versions + ext_manager.set_extension_enabled_immediate(ext, True) + print(f"[Launcher] Successfully enabled extension: {ext} via immediate method") + else: + print(f"[Launcher] Extension already enabled: {ext}") class PegasusApp: @@ -75,7 +82,12 @@ def __init__(self): # Load default environment. You can replace with url or file path of any desired environment. self.pg.load_environment(SIMULATION_ENVIRONMENTS["Curved Gridroom"]) - + + # Reset so physics/articulations are ready + self.world.reset() + + self.stop_sim = False + # Spawn a PX4 multirotor drone with a specified vehicle ID and domain ID # PX4 udp port = 14540 + (vehicle_id) # Domain ID is for ROS2 domain communication. As of now, it should match the vehicle id by convention. diff --git a/simulation/simple-sim/docker/docker-compose.yaml b/simulation/simple-sim/docker/docker-compose.yaml index 07b61f6a6..65b3b6981 100644 --- a/simulation/simple-sim/docker/docker-compose.yaml +++ b/simulation/simple-sim/docker/docker-compose.yaml @@ -20,7 +20,7 @@ services: tty: true ipc: host privileged: true - runtime: nvidia + # runtime: nvidia <-- Removed deprecated runtime key networks: airstack_network: ipv4_address: 172.31.0.200 From 19a56575f04264bfac230944209254bebd54c77e Mon Sep 17 00:00:00 2001 From: John Date: Wed, 28 Jan 2026 14:17:16 -0500 Subject: [PATCH 2/8] Fixed python path in isaac-sim container. Now properly publishes clock and connects to robot for basic flight --- simulation/isaac-sim/docker/.bashrc | 20 +++++---- .../isaac-sim/docker/docker-compose.yaml | 2 +- .../example_one_px4_pegasus_launch_script.py | 45 +++++++++---------- 3 files changed, 33 insertions(+), 34 deletions(-) diff --git a/simulation/isaac-sim/docker/.bashrc b/simulation/isaac-sim/docker/.bashrc index 71569b7dd..d3714e8eb 100644 --- a/simulation/isaac-sim/docker/.bashrc +++ b/simulation/isaac-sim/docker/.bashrc @@ -124,18 +124,22 @@ fi source /opt/ros/jazzy/setup.bash source /jazzy_ws/install/setup.bash # isaacsim ros2 package -# Fix for Isaac Sim 4.5/5.1 on ROS 2 Jazzy: -# Remove the system ROS 2 Python 3.12 paths from PYTHONPATH to prevent them from -# leaking into Isaac Sim's internal Python 3.10 environment. -export PYTHONPATH=$(echo $PYTHONPATH | tr ':' '\n' | grep -v "ros/jazzy/lib/python3.12/site-packages" | paste -sd ':' -) -# Add internal Isaac Sim rclpy for Jazzy to PYTHONPATH -export PYTHONPATH=$PYTHONPATH:/isaac-sim/exts/isaacsim.ros2.bridge/jazzy/rclpy - # needed for communication with Isaac Sim ROS2 # https://docs.omniverse.nvidia.com/isaacsim/latest/installation/install_ros.html#enabling-the-ros-bridge-extension export FASTRTPS_DEFAULT_PROFILES_FILE="/isaac-sim/fastdds.xml" export RMW_IMPLEMENTATION=rmw_fastrtps_cpp # for local development, prevent conflict with other desktops -export ROS_AUTOMATIC_DISCOVERY_RANGE=LOCALHOST +export ROS_AUTOMATIC_DISCOVERY_RANGE=SUBNET + +# --- Environment Separation --- +# Define the PYTHONPATH specifically for Isaac Sim (Python 3.10) +# This strips out the System ROS (Python 3.12) paths to prevent conflicts +export ISAAC_SIM_PYTHONPATH=$(echo $PYTHONPATH | tr ':' '\n' | grep -v "lib/python3.12/site-packages" | paste -sd ':' -):/isaac-sim/exts/isaacsim.ros2.bridge/jazzy/rclpy + +# Helper function to run Isaac Sim python scripts with the correct environment +run_isaac_python() { + PYTHONPATH="$ISAAC_SIM_PYTHONPATH" /isaac-sim/python.sh "$@" +} +export -f run_isaac_python # --- Isaac Setup --- alias runapp="/isaac-sim/runapp.sh --path omniverse://airlab-nucleus.andrew.cmu.edu/Library/Assets/Ascent_Aerosystems/Spirit_UAV/spirit_uav_red_yellow.prop.usd" diff --git a/simulation/isaac-sim/docker/docker-compose.yaml b/simulation/isaac-sim/docker/docker-compose.yaml index 9ff0328bb..e08f417ff 100644 --- a/simulation/isaac-sim/docker/docker-compose.yaml +++ b/simulation/isaac-sim/docker/docker-compose.yaml @@ -17,7 +17,7 @@ services: tmux new -d -s isaac; if [ $$AUTOLAUNCH = 'true' ]; then if [ \"${ISAAC_SIM_USE_STANDALONE_SCRIPT}\" = 'true' ]; then - tmux send-keys -t isaac '/isaac-sim/python.sh /root/AirStack/simulation/isaac-sim/launch_scripts/${ISAAC_SIM_SCRIPT_NAME}' ENTER + tmux send-keys -t isaac 'run_isaac_python /root/AirStack/simulation/isaac-sim/launch_scripts/${ISAAC_SIM_SCRIPT_NAME}' ENTER else tmux send-keys -t isaac 'ros2 launch isaacsim run_isaacsim.launch.py gui:=\"${ISAAC_SIM_GUI}\" play_sim_on_start:=\"${PLAY_SIM_ON_START}\" ' ENTER fi diff --git a/simulation/isaac-sim/launch_scripts/example_one_px4_pegasus_launch_script.py b/simulation/isaac-sim/launch_scripts/example_one_px4_pegasus_launch_script.py index 25961cace..42cbda91d 100755 --- a/simulation/isaac-sim/launch_scripts/example_one_px4_pegasus_launch_script.py +++ b/simulation/isaac-sim/launch_scripts/example_one_px4_pegasus_launch_script.py @@ -83,14 +83,9 @@ def __init__(self): # Load default environment. You can replace with url or file path of any desired environment. self.pg.load_environment(SIMULATION_ENVIRONMENTS["Curved Gridroom"]) - # Reset so physics/articulations are ready - self.world.reset() - - self.stop_sim = False - - # Spawn a PX4 multirotor drone with a specified vehicle ID and domain ID - # PX4 udp port = 14540 + (vehicle_id) - # Domain ID is for ROS2 domain communication. As of now, it should match the vehicle id by convention. + # # Spawn a PX4 multirotor drone with a specified vehicle ID and domain ID + # # PX4 udp port = 14540 + (vehicle_id) + # # Domain ID is for ROS2 domain communication. As of now, it should match the vehicle id by convention. graph_handle = spawn_px4_multirotor_node( pegasus_node_name="PX4Multirotor", drone_prim="/World/drone/base_link", @@ -101,23 +96,23 @@ def __init__(self): init_orient=[0.0, 0.0, 0.0, 1.0], ) - # Add a ZED stereo camera (with an associated subgraph) to the drone - add_zed_stereo_camera_subgraph( - parent_graph_handle=graph_handle, - drone_prim="/World/drone/base_link", - camera_name="ZEDCamera", - camera_offset = [0.1, 0.0, 0.0], # X, Y, Z offset from drone base_link - camera_rotation_offset = [0.0, 0.0, 0.0], # Rotation in degrees (roll, pitch, yaw) - ) - - # Add an Ouster lidar (with an associated subgraph) to the drone - add_ouster_lidar_subgraph( - parent_graph_handle=graph_handle, - drone_prim="/World/drone/base_link", - lidar_name="OS1_REV6_128_10hz___512_resolution", - lidar_offset = [0.0, 0.0, 0.025], # X, Y, Z offset from drone base_link - lidar_rotation_offset = [0.0, 0.0, 0.0], # Rotation in degrees (roll, pitch, yaw) - ) + # # Add a ZED stereo camera (with an associated subgraph) to the drone + # add_zed_stereo_camera_subgraph( + # parent_graph_handle=graph_handle, + # drone_prim="/World/drone/base_link", + # camera_name="ZEDCamera", + # camera_offset = [0.1, 0.0, 0.0], # X, Y, Z offset from drone base_link + # camera_rotation_offset = [0.0, 0.0, 0.0], # Rotation in degrees (roll, pitch, yaw) + # ) + + # # Add an Ouster lidar (with an associated subgraph) to the drone + # add_ouster_lidar_subgraph( + # parent_graph_handle=graph_handle, + # drone_prim="/World/drone/base_link", + # lidar_name="OS1_REV6_128_10hz___512_resolution", + # lidar_offset = [0.0, 0.0, 0.025], # X, Y, Z offset from drone base_link + # lidar_rotation_offset = [0.0, 0.0, 0.0], # Rotation in degrees (roll, pitch, yaw) + # ) # Reset so physics/articulations are ready self.world.reset() From 53234c4d1083eecc3af5bda4509f9ef72627a993 Mon Sep 17 00:00:00 2001 From: John Date: Fri, 30 Jan 2026 19:56:19 -0500 Subject: [PATCH 3/8] syncing to updated Pegasus Simulator with IsaacSim 5.1.0 --- simulation/isaac-sim/extensions/PegasusSimulator | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/simulation/isaac-sim/extensions/PegasusSimulator b/simulation/isaac-sim/extensions/PegasusSimulator index 6db81b519..15379fac8 160000 --- a/simulation/isaac-sim/extensions/PegasusSimulator +++ b/simulation/isaac-sim/extensions/PegasusSimulator @@ -1 +1 @@ -Subproject commit 6db81b519772629508b0d911c2865137d341d476 +Subproject commit 15379fac8d487b03af5a1b950541bab060b0b7bd From 62cff5fa78d4071c739ff07beda94d6bc03d70a3 Mon Sep 17 00:00:00 2001 From: John Date: Fri, 30 Jan 2026 19:56:48 -0500 Subject: [PATCH 4/8] uncommented example script code --- .../example_one_px4_pegasus_launch_script.py | 34 +++++++++---------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/simulation/isaac-sim/launch_scripts/example_one_px4_pegasus_launch_script.py b/simulation/isaac-sim/launch_scripts/example_one_px4_pegasus_launch_script.py index 42cbda91d..b6c12b4e3 100755 --- a/simulation/isaac-sim/launch_scripts/example_one_px4_pegasus_launch_script.py +++ b/simulation/isaac-sim/launch_scripts/example_one_px4_pegasus_launch_script.py @@ -96,23 +96,23 @@ def __init__(self): init_orient=[0.0, 0.0, 0.0, 1.0], ) - # # Add a ZED stereo camera (with an associated subgraph) to the drone - # add_zed_stereo_camera_subgraph( - # parent_graph_handle=graph_handle, - # drone_prim="/World/drone/base_link", - # camera_name="ZEDCamera", - # camera_offset = [0.1, 0.0, 0.0], # X, Y, Z offset from drone base_link - # camera_rotation_offset = [0.0, 0.0, 0.0], # Rotation in degrees (roll, pitch, yaw) - # ) - - # # Add an Ouster lidar (with an associated subgraph) to the drone - # add_ouster_lidar_subgraph( - # parent_graph_handle=graph_handle, - # drone_prim="/World/drone/base_link", - # lidar_name="OS1_REV6_128_10hz___512_resolution", - # lidar_offset = [0.0, 0.0, 0.025], # X, Y, Z offset from drone base_link - # lidar_rotation_offset = [0.0, 0.0, 0.0], # Rotation in degrees (roll, pitch, yaw) - # ) + # Add a ZED stereo camera (with an associated subgraph) to the drone + add_zed_stereo_camera_subgraph( + parent_graph_handle=graph_handle, + drone_prim="/World/drone/base_link", + camera_name="ZEDCamera", + camera_offset = [0.1, 0.0, 0.0], # X, Y, Z offset from drone base_link + camera_rotation_offset = [0.0, 0.0, 0.0], # Rotation in degrees (roll, pitch, yaw) + ) + + # Add an Ouster lidar (with an associated subgraph) to the drone + add_ouster_lidar_subgraph( + parent_graph_handle=graph_handle, + drone_prim="/World/drone/base_link", + lidar_name="OS1_REV6_128_10hz___512_resolution", + lidar_offset = [0.0, 0.0, 0.025], # X, Y, Z offset from drone base_link + lidar_rotation_offset = [0.0, 0.0, 0.0], # Rotation in degrees (roll, pitch, yaw) + ) # Reset so physics/articulations are ready self.world.reset() From f5c070e1f746c5aa66148682eb7eb9dbcad2d9a6 Mon Sep 17 00:00:00 2001 From: John Date: Fri, 30 Jan 2026 19:57:12 -0500 Subject: [PATCH 5/8] fixing lidar orientation direction in robot description --- .../urdf/iris_with_sensors.pegasus.robot.urdf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/common/ros_packages/robot_descriptions/iris_with_sensors_description/urdf/iris_with_sensors.pegasus.robot.urdf b/common/ros_packages/robot_descriptions/iris_with_sensors_description/urdf/iris_with_sensors.pegasus.robot.urdf index 7f4f5d72d..13f71262a 100644 --- a/common/ros_packages/robot_descriptions/iris_with_sensors_description/urdf/iris_with_sensors.pegasus.robot.urdf +++ b/common/ros_packages/robot_descriptions/iris_with_sensors_description/urdf/iris_with_sensors.pegasus.robot.urdf @@ -40,7 +40,7 @@ - + From 8406c5e41d90cd1a82ae62650e502635c21e083a Mon Sep 17 00:00:00 2001 From: John Date: Sat, 31 Jan 2026 00:12:36 -0500 Subject: [PATCH 6/8] updated two_example script as well --- .../example_two_px4_pegasus_launch_script.py | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/simulation/isaac-sim/launch_scripts/example_two_px4_pegasus_launch_script.py b/simulation/isaac-sim/launch_scripts/example_two_px4_pegasus_launch_script.py index 329f1170c..1b4154a0c 100755 --- a/simulation/isaac-sim/launch_scripts/example_two_px4_pegasus_launch_script.py +++ b/simulation/isaac-sim/launch_scripts/example_two_px4_pegasus_launch_script.py @@ -40,9 +40,9 @@ # Explicitly enable required extensions ext_manager = omni.kit.app.get_app().get_extension_manager() + for ext in [ - # "airlab.airstack", - "omni.physx.forcefields", + "airlab.airstack", "omni.graph.core", # Core runtime for OmniGraph engine "omni.graph.action", # Action Graph framework "omni.graph.action_nodes", # Built-in Action Graph node library @@ -52,11 +52,15 @@ "omni.graph.window.action", # Action Graph editor window "omni.graph.window.generic", # Generic graph UI tools "omni.graph.ui_nodes", # UI node building helpers - "airlab.pegasus", # Airlab extension Pegasus core extension "pegasus.simulator", ]: if not ext_manager.is_extension_enabled(ext): - ext_manager.set_extension_enabled(ext, True) + print(f"[Launcher] Enabling extension: {ext}") + # Try both methods for robustness in different Kit versions + ext_manager.set_extension_enabled_immediate(ext, True) + print(f"[Launcher] Successfully enabled extension: {ext} via immediate method") + else: + print(f"[Launcher] Extension already enabled: {ext}") class PegasusApp: From 176037607b832283d99a40f7baab484b4312e469 Mon Sep 17 00:00:00 2001 From: John Date: Sat, 31 Jan 2026 00:21:41 -0500 Subject: [PATCH 7/8] added error message for stale docker compose version --- airstack.sh | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/airstack.sh b/airstack.sh index 1497db034..0c6558a23 100755 --- a/airstack.sh +++ b/airstack.sh @@ -193,6 +193,24 @@ function check_docker { log_error "Docker daemon is not running." exit 1 fi + + # Check Docker Compose version + if command -v docker &> /dev/null && docker compose version &> /dev/null; then + local compose_version=$(docker compose version --short 2>/dev/null) + if [ -z "$compose_version" ]; then + # Fallback for parsing + compose_version=$(docker compose version | grep -oE '[0-9]+\.[0-9]+\.[0-9]+' | head -n1) + fi + + if [ -n "$compose_version" ]; then + local major_ver=$(echo "$compose_version" | cut -d. -f1) + # Check if major version is a number before comparing + if [[ "$major_ver" =~ ^[0-9]+$ ]] && [ "$major_ver" -lt 5 ]; then + log_error "Docker Compose version $compose_version is less than v5.0.0. This script requires v5.0.0 or greater." + exit 1 + fi + fi + fi } # Find container by partial name using regex From c5a6755d5d4def61c724c36d41875bd2cfbd6b92 Mon Sep 17 00:00:00 2001 From: John Date: Sat, 31 Jan 2026 00:29:38 -0500 Subject: [PATCH 8/8] fixed example script for 2 robots to properly namespace the two different robots --- .../launch_scripts/example_two_px4_pegasus_launch_script.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/simulation/isaac-sim/launch_scripts/example_two_px4_pegasus_launch_script.py b/simulation/isaac-sim/launch_scripts/example_two_px4_pegasus_launch_script.py index 1b4154a0c..768807739 100755 --- a/simulation/isaac-sim/launch_scripts/example_two_px4_pegasus_launch_script.py +++ b/simulation/isaac-sim/launch_scripts/example_two_px4_pegasus_launch_script.py @@ -87,6 +87,7 @@ def __init__(self): graph_handle = spawn_px4_multirotor_node( pegasus_node_name="PX4Multirotor", drone_prim="/World/drone1/base_link", + robot_name="robot_1", vehicle_id=1, # defines MAVLink port offset domain_id=1, # defines ROS2 domain ID usd_file="/root/Documents/Kit/shared/exts/pegasus.simulator/pegasus/simulator/assets/Robots/Iris/iris.usd", @@ -98,6 +99,7 @@ def __init__(self): add_zed_stereo_camera_subgraph( parent_graph_handle=graph_handle, drone_prim="/World/drone1/base_link", + robot_name="robot_1", camera_name="ZEDCamera", camera_offset = [0.1, 0.0, 0.0], # X, Y, Z offset from drone base_link camera_rotation_offset = [0.0, 0.0, 0.0], # Rotation in degrees (roll, pitch, yaw) @@ -107,6 +109,7 @@ def __init__(self): add_ouster_lidar_subgraph( parent_graph_handle=graph_handle, drone_prim="/World/drone1/base_link", + robot_name="robot_1", lidar_name="OS1_REV6_128_10hz___512_resolution", lidar_offset = [0.0, 0.0, 0.025], # X, Y, Z offset from drone base_link lidar_rotation_offset = [0.0, 0.0, 0.0], # Rotation in degrees (roll, pitch, yaw) @@ -130,6 +133,7 @@ def __init__(self): add_zed_stereo_camera_subgraph( parent_graph_handle=graph_handle, drone_prim="/World/drone2/base_link", + robot_name="robot_2", camera_name="ZEDCamera", camera_offset = [0.1, 0.0, 0.0], # X, Y, Z offset from drone base_link camera_rotation_offset = [0.0, 0.0, 0.0], # Rotation in degrees (roll, pitch, yaw) @@ -139,6 +143,7 @@ def __init__(self): add_ouster_lidar_subgraph( parent_graph_handle=graph_handle, drone_prim="/World/drone2/base_link", + robot_name="robot_2", lidar_name="OS1_REV6_128_10hz___512_resolution", lidar_offset = [0.0, 0.0, 0.025], # X, Y, Z offset from drone base_link lidar_rotation_offset = [0.0, 0.0, 0.0], # Rotation in degrees (roll, pitch, yaw)