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

feat: rai_sim #415

Open
wants to merge 38 commits into
base: development
Choose a base branch
from
Open

feat: rai_sim #415

wants to merge 38 commits into from

Conversation

MagdalenaKotynia
Copy link
Member

@MagdalenaKotynia MagdalenaKotynia commented Feb 10, 2025

Purpose

To implement package for running simulations with different setups.

  • EngineConnector - the interface to connect with specific engine. It is responsible for scene setup, spawning, despawning objects, etc.

  • def setup_scene logic is based on the provided SceneConfig. Currently, it is assumed that SceneConfig should be a common class for all of the engines so it should be flexible (that is why binary_path is optional because not all engines may need it to setup scene).

  • SceneSetup is going to store the initial scene setup (more info about spawned entities than SceneConfig provides etc.). It is not handled yet.

  • O3DEngineConnector - implementation of the EngineConnector for O3DE

Issues

#405 - This PR covers the part responsible for connection with simulation (EngineConnector).

Testing

  • Download binary
  • Save the following content as (adjust binary_path if needed):
    • base_config1.yaml:
entities:
  - name: apple1
    prefab_name: apple
    pose:
      translation:
        x: 0.5
        y: 0.0
        z: 0.05
      rotation:
        x: 0.0
        y: 0.0
        z: 0.0
        w: 1.0
  - name: cube1
    prefab_name: green_cube
    pose:
      translation:
        x: 0.5
        y: 0.3
        z: 0.05
      rotation:
        x: 0.0
        y: 0.0
        z: 0.0
        w: 1.0
  • base_config2.yaml:
entities:
  - name: object1
    prefab_name: carrot
    pose:
      translation:
        x: 0.5
        y: -0.3
        z: 0.05
      rotation:
        x: 0.0
        y: 0.0
        z: 0.0
        w: 1.0
  - name: object2
    prefab_name: corn
    pose:
      translation:
        x: 0.5
        y: 0.3
        z: 0.05
      rotation:
        x: 0.0
        y: 0.0
        z: 0.0
        w: 1.0
  • o3de_config.yaml
binary_path:  ros2 launch examples/manipulation-demo.launch.py game_launcher:=/home/mkotynia/repos/RAI/RAIManipulationDemoBenchmark_jammyhumble/RAIManipulationDemo/RAIManipulationDemo.GameLauncher
  • Run the following python script (adjust paths to yaml configs if needed):
import rclpy
from rai_sim.o3de.o3de_connector import O3DEngineConnector, O3DESimulationConfig
from rai.communication.ros2.connectors import ROS2ARIConnector
import time

from rai_sim.config_loader import load_simulation_config
from pathlib import Path

if __name__ == "__main__":

    try:
        rclpy.init()
        connector = ROS2ARIConnector()
        o3de = O3DEngineConnector(connector)

        scene_config  = load_simulation_config(base_config_path=Path("base_config1.yaml"), connector_config_path=Path("o3de_config.yaml"), config_type=O3DESimulationConfig)
        o3de.setup_scene(scene_config)

        time.sleep(3)

        scene_config  = load_simulation_config(base_config_path=Path("base_config2.yaml"), connector_config_path=Path("o3de_config.yaml"), config_type=O3DESimulationConfig)
        o3de.setup_scene(scene_config)

        time.sleep(5)

        o3de.shutdown()
        
        
        connector.shutdown()
        rclpy.shutdown()

    except Exception as e:
        raise e
    finally:
        o3de.shutdown()
        
        
        connector.shutdown()
        rclpy.shutdown()

Summary by CodeRabbit

  • New Features

    • Introduced a new simulation module that enhances scene configuration and entity management for a more seamless simulation experience.
    • Added improved integration with a simulation engine for robust process control and dynamic entity handling.
  • Documentation

    • Updated package metadata to include clear licensing, versioning, and dependency requirements.

@MagdalenaKotynia MagdalenaKotynia marked this pull request as ready for review February 11, 2025 21:01
@MagdalenaKotynia MagdalenaKotynia changed the title feat: benchmarking feat: rai_sim Feb 11, 2025

_, alive = psutil.wait_procs(processes, timeout=3)

# NOTE (mkotynia) kill ros2
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ros2 should never be killed
we can kill the robotic stack when sim has finished

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Call rclpy shutdown or similar, please do it standard way not brute force hacks

@adamdbrw adamdbrw requested a review from pijaro February 12, 2025 13:35
def __del__(self):
self.shutdown()

def get_available_spawnable_names(self) -> list[str]:
Copy link
Member

@maciejmajek maciejmajek Feb 12, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please add a try except for n_of possible retries. Same applies to other methods.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

applied in 2b4286e

process.kill()
except Exception as e:
logger.warning(f"Failed to kill process {process.pid}: {e}")
continue
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is the continue needed here?

@boczekbartek boczekbartek self-requested a review February 12, 2025 14:19
Copy link
Member

@boczekbartek boczekbartek left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@MagdalenaKotynia Thank you for this PR!

  • I left some comments to the code.
  • Also I was able to run the example from the PR description, but it didn't work in the first run - I think the binary was loading too long. See my error below. Do you check if the binary is ready to spawn objects?
  • it would be good to add an info to the description of the PR that example will only work if you setup rai-manipulation-demo first (because for e.g. this line)
(rai-framework-py3.10) robo-pc-005 ➜  rai git:(feat/benchmarking) ✗ python run.py                      
/home/bboczek/.cache/pypoetry/virtualenvs/rai-framework-2NHnaPvx-py3.10/lib/python3.10/site-packages/pydub/utils.py:170: RuntimeWarning: Couldn't find ffmpeg or avconv - defaulting to ffmpeg, but may not work
  warn("Couldn't find ffmpeg or avconv - defaulting to ffmpeg, but may not work", RuntimeWarning)
2025-02-12 16:21:02 robo-pc-005 rai_sim.o3de.o3de_connector[159409] INFO Running command: ['ros2', 'launch', 'examples/manipulation-demo.launch.py', 'game_launcher:=/home/bboczek/Downloads/RAIManipulationDemo/RAIManipulationDemo.GameLauncher']
Traceback (most recent call last):
  File "/u24/home/bboczek/projects_u24/01_internal/01_repos/rai/run.py", line 16, in <module>
    o3de.setup_scene(scene_config)
  File "/u24/home/bboczek/projects_u24/01_internal/01_repos/rai/src/rai_sim/rai_sim/o3de/o3de_connector.py", line 161, in setup_scene
    self._spawn_entity(entity)
  File "/u24/home/bboczek/projects_u24/01_internal/01_repos/rai/src/rai_sim/rai_sim/o3de/o3de_connector.py", line 90, in _spawn_entity
    entity.pose, self.connector.get_transform("odom", "world")
  File "/u24/home/bboczek/projects_u24/01_internal/01_repos/rai/src/rai_core/rai/communication/ros2/connectors.py", line 176, in get_transform
    raise LookupException(
tf2.LookupException: Could not find transform from world to odom in 5.0 seconds
Exception in thread Thread-1 (spin):
Traceback (most recent call last):
  File "/usr/lib/python3.10/threading.py", line 1016, in _bootstrap_inner
    self.run()
  File "/usr/lib/python3.10/threading.py", line 953, in run
    self._target(*self._args, **self._kwargs)
  File "/opt/ros/humble/local/lib/python3.10/dist-packages/rclpy/executors.py", line 294, in spin
    self.spin_once()
  File "/opt/ros/humble/local/lib/python3.10/dist-packages/rclpy/executors.py", line 794, in spin_once
    self._spin_once_impl(timeout_sec)
  File "/opt/ros/humble/local/lib/python3.10/dist-packages/rclpy/executors.py", line 786, in _spin_once_impl
    self._executor.submit(handler)
  File "/usr/lib/python3.10/concurrent/futures/thread.py", line 169, in submit
    raise RuntimeError('cannot schedule new futures after '
RuntimeError: cannot schedule new futures after interpreter shutdown
Exception ignored in: <function O3DEngineConnector.__del__ at 0x7e176e350790>
Traceback (most recent call last):
  File "/u24/home/bboczek/projects_u24/01_internal/01_repos/rai/src/rai_sim/rai_sim/o3de/o3de_connector.py", line 75, in __del__
  File "/u24/home/bboczek/projects_u24/01_internal/01_repos/rai/src/rai_sim/rai_sim/o3de/o3de_connector.py", line 64, in shutdown
AttributeError: 'NoneType' object has no attribute 'warning'

from typing import Any, Dict, List, Optional

import yaml
from geometry_msgs.msg import Point, Pose, Quaternion
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wouldn't rely on ros2 messages on this abstraction level.
As I understand this is a generic interface to connect to simulation engines.
Some simulation engines have a build-in ros2 support (o3de, gazebo, isaacsim through bridge), but some don't (Mujoco, Genesis).

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

applied in db35adb and 0c3ea02


@field_validator("pose", mode="after")
@classmethod
def convert_to_pose(cls, value: Dict[str, Any]) -> Pose:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this workaround is not needed if we skip using geometry_msgs.Pose

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Correct, the pose/orientation should not depend on ros2.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

applied in db35adb and 0c3ea02

Setup of scene - arrangmenet of objects, interactions, environment etc.
"""

binary_path: Optional[str]
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

binary_path seem to be restrictive. How about allowing a command or script.
Looking at the implementation it seems like the rest of the code should handle it, but variable name suggests that only a binary file is supported

src/rai_sim/rai_sim/engine_connector.py Outdated Show resolved Hide resolved

class SceneConfig(BaseModel):
"""
Setup of scene - arrangmenet of objects, interactions, environment etc.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't know if I understand the purpose of adding both SceneSetup and SceneConfig. This is what I assume based on the implementation:

  • SceneConfig contains initial objects arrangement
  • SceneSetup contains current objects arrangement

For example in a basic benchmark as a part of task (so initial state) we would have SceneConfig and some language instruction.
Then we run the rai agent and check if SceneSetup is as expected. If it's fine, then benchmark is passed.

I am not sure what are interactions.

If my understanding is correct I propose to:

  • Rename SceneConfig to SimulationConfig
  • Adjust docs - Setup of scene - set initial arrangement of objects in the environment
    • be aware of typos
  • Rename SceneSetup to SceneState

return SceneSetup(entities=scene_config.entities)

def launch_binary(self, binary_path: str):
# NOTE (mkotynia) ros2 launch command with binary path, to be refactored
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Connected to my previous comments

Comment on lines 96 to 97
except Exception as e:
raise e
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this code has no effect. It catches exceptions and then raises them again

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

true, removed in: d09cbbd

Comment on lines 53 to 84
class SceneSetup(BaseModel):
"""
Info about entities in the scene (positions, collisions, etc.)
"""
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consider renaming to SceneState (more info in previous comment).
As for collisions, I think they are not included in the current implementation. How about adding a NOTE that they are meant to be added here?

@maciejmajek
Copy link
Member

@coderabbitai full review

Copy link
Contributor

coderabbitai bot commented Feb 12, 2025

Walkthrough

The pull request introduces the new rai_sim module into the project. It adds a dependency entry in the root pyproject.toml pointing to the local module and creates a dedicated pyproject.toml within src/rai_sim with package metadata and dependency declarations. Additionally, it enhances the module’s documentation by adding license information and a version variable. New classes and methods are implemented for simulation engine connection, including an abstract EngineConnector and its O3DE-specific extension that manages scene setup, entity spawning, and process control.

Changes

File(s) Change Summary
pyproject.toml Added dependency for rai_sim with {path = "src/rai_sim", develop = true}.
src/rai_sim/pyproject.toml Introduced package metadata for rai-sim including version 0.0.1, dependency declarations (python "^3.10, <3.13", PyYAML), classifiers, and build system configuration.
src/rai_sim/.../__init__.py Added copyright notice, module-level docstring, and defined __version__ = "0.0.1".
src/rai_sim/.../engine_connector.py Introduced simulation engine abstractions: classes Entity, SceneConfig, SceneSetup, abstract EngineConnector (with methods for scene setup, spawning/despawning entities, and object position retrieval) and a load_config function.
src/rai_sim/.../o3de_connector.py Added O3DEngineConnector class extending EngineConnector with methods for shutdown, retrieving spawnable names, spawning/despawning entities, launching binaries, process monitoring, and comprehensive scene setup.

Sequence Diagram(s)

sequenceDiagram
    participant U as User/Application
    participant O3D as O3DEngineConnector
    participant ROS as ROS2 Service
    participant PM as Process Manager

    U->>O3D: load_config(file_path)
    U->>O3D: setup_scene(scene_config)
    alt Binary path has changed
        O3D->>PM: shutdown previous process
        O3D->>PM: launch_binary(binary_path)
        O3D->>PM: has_process_started(timeout)
    end
    loop For each entity in scene_config
        O3D->>ROS: _spawn_entity(entity)
    end
    O3D-->>U: return SceneSetup
Loading
✨ Finishing Touches
  • 📝 Generate Docstrings (Beta)

Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media?

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR. (Beta)
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (5)
src/rai_sim/rai_sim/engine_connector.py (3)

46-46: Fix typo in docstring.

“arrangmenet” should be corrected to “arrangement.”

-    Setup of scene - arrangmenet of objects, interactions, environment etc.
+    Setup of scene - arrangement of objects, interactions, environment etc.

66-67: Remove or annotate the empty constructor.

A constructor that does nothing in an abstract base class can be removed or marked as abstract if future child classes are expected to handle initialization themselves.

-class EngineConnector(ABC):
-    def __init__(self):
-        pass
+class EngineConnector(ABC):
+    @abstractmethod
+    def __init__(self):
+        """Child classes should perform specialized initialization."""
🧰 Tools
🪛 Ruff (0.8.2)

66-67: EngineConnector.__init__ is an empty method in an abstract base class, but has no abstract decorator

(B027)


96-97: Avoid re-raising the same exception directly.

Having an empty except block that simply re-raises the same exception is redundant. Either remove the try-except entirely or add additional exception handling logic.

-    except Exception as e:
-        raise e
+    except Exception:
+        logger.error("Failed to load config file.", exc_info=True)
+        raise
src/rai_sim/rai_sim/o3de/o3de_connector.py (2)

40-65: Consider a more graceful shutdown strategy.

The current approach forcefully kills processes and children, which may abruptly terminate ROS2. A more elegant solution would be to invoke ROS2 shutdown procedures or use graceful signals with retries before forcing termination.


167-168: Flatten nested if statements.

Combine the nested conditions into a single check to enhance readability.

-if self.current_process is not None:
-    if self.current_process.poll() is None:
-        return True
+if self.current_process is not None and self.current_process.poll() is None:
+    return True
🧰 Tools
🪛 Ruff (0.8.2)

167-168: Use a single if statement instead of nested if statements

(SIM102)

📜 Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between ce4885c and ff3e445.

⛔ Files ignored due to path filters (1)
  • poetry.lock is excluded by !**/*.lock
📒 Files selected for processing (5)
  • pyproject.toml (1 hunks)
  • src/rai_sim/pyproject.toml (1 hunks)
  • src/rai_sim/rai_sim/__init__.py (1 hunks)
  • src/rai_sim/rai_sim/engine_connector.py (1 hunks)
  • src/rai_sim/rai_sim/o3de/o3de_connector.py (1 hunks)
🧰 Additional context used
🪛 Ruff (0.8.2)
src/rai_sim/rai_sim/engine_connector.py

66-67: EngineConnector.__init__ is an empty method in an abstract base class, but has no abstract decorator

(B027)

src/rai_sim/rai_sim/o3de/o3de_connector.py

167-168: Use a single if statement instead of nested if statements

(SIM102)

🔇 Additional comments (6)
src/rai_sim/rai_sim/engine_connector.py (1)

20-20: Use a more generic data structure to avoid ROS2 dependency.

Relying on geometry_msgs.msg at this abstraction level prevents the EngineConnector from being engine-neutral. This concern was previously raised and remains relevant.

src/rai_sim/rai_sim/o3de/o3de_connector.py (1)

69-75: Verify service usage mismatch.

Using gazebo_msgs/srv/GetWorldProperties to retrieve spawnable names in O3DE might be unintended. Confirm that the target engine and message types correspond correctly, and ensure the backend is actually O3DE-compatible.

src/rai_sim/rai_sim/__init__.py (1)

1-17: No issues found.

The file is well-documented, and versioning is clearly defined.

src/rai_sim/pyproject.toml (2)

1-14: LGTM! Well-structured package metadata.

The package metadata is well-defined with appropriate name, version, description, authors, and classifiers.


21-23: LGTM! Standard build system configuration.

The build system configuration follows Poetry's best practices.

pyproject.toml (1)

20-20: LGTM! Consistent dependency declaration.

The rai_sim dependency is correctly declared following the same pattern as other local modules.


[tool.poetry.dependencies]
python = "^3.10, <3.13"
PyYAML = "*"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Add version constraint for PyYAML dependency.

Using an unconstrained version (*) for dependencies can lead to compatibility issues when new versions are released. Consider adding a version constraint to ensure compatibility.

-PyYAML = "*"
+PyYAML = "^6.0.1"
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
PyYAML = "*"
PyYAML = "^6.0.1"

Setup of scene - arrangmenet of objects, interactions, environment etc.
"""

binary_path: Optional[str]
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consider using pathlib to store paths.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

applied in 8ed84b3

logger.debug(f"Terminating child process {child.pid}, {child.name()}")
child.terminate()

_, alive = psutil.wait_procs(children, timeout=3)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Increase the timeout, some applications might take up considerable amount of time to clean itself and shutdown.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.


def launch_binary(self, binary_path: str):
# NOTE (mkotynia) ros2 launch command with binary path, to be refactored
command = shlex.split(binary_path)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks like you allow the binary_path to have the start arguments as well.

Is it safe? Shouldn't we treat binary path and arguments separately?

binary_path should be just a path. Otherwise, more appropriate name should be used, like command or something similar.

for entity in self.entity_ids:
self._despawn_entity_by_id(self.entity_ids[entity])
self.entity_ids = {}
time.sleep(3)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hard coded sleep looks so wrong. We should be able to detect somehow that the binary has started and is ready to receive commands

I can guarantee that some sims will need more than N seconds to start.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please fill the readme. At least some core information.

@@ -0,0 +1,17 @@
# Copyright (C) 2024 Robotec.AI
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Uber nit: shouldn't we change the date to 2025? :)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

applied in ac7fd21


"""RAI Simulations package."""

__version__ = "0.0.1"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just a thought: can we grab this from .toml file? Or should we keep track version number in two different places?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

+1, track with pyproject.toml only

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

applied in 1ca1203

Comment on lines 92 to 93
def __init__(self):
pass
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There are no shared attributes across the connectors, therefore this can be removed.

Suggested change
def __init__(self):
pass

Translation,
)

logger = logging.getLogger(__name__)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this consistent across all rai packages? Looks a bit too barebone to me.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@maciejmajek do you have some convention about logging handling? I see that some classes have their logger attribute but some don't.

for child in alive:
logger.warning(f"Force killing child process PID: {child.pid}")
child.kill()
# NOTE (mkotynia) terminating ros2 launch
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is engine connector, why do you mention ros2 launch? what do ros2 launch have to do with O3DEngineConnector?

msg = ROS2ARIMessage(payload=msg_content)

response = self.connector.service_call(
msg, target="spawn_entity", msg_type="gazebo_msgs/srv/SpawnEntity"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not feeling coupling the ROS 2 interface with O3DEngineConnector. Semantically, talking about "o3de connector" - shouldn't we care about connecting rai with o3de only (o3de interfaces, launch arguments, parameters, configuration)?

We assumed here that the O3DE comes with ROS 2 interface and the simulation follows certain standard/implementation.

What if someone have different API to control O3DE simulation?

Maybe we should make a distinguish between engine, and provided simulation interface?

If we bring a concrete implementation of the "connector" (in this case, an O3DE based sim that follows a standard and uses ROS 2 gem), then we should consider changing a name to something more concrete.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we should consider changing a name to something more concrete

Right. We have discussed this topic outside of git, our O3DE + ROS2 combo relies on a specific O3DE setup. @knicked is currently working on a o3de requirements document.

command,
)
if not self.has_process_started():
raise RuntimeError("Process did not start in time.")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Inconsistent use of exception types. setup_scene throws an Exception, but here we are using RuntimeError. Both are "on the same level":

if scene_config.binary_path:
    self.launch_binary(scene_config.binary_path) # can raise RuntimeError
else:
    raise Exception("No binary path provided")

Copy link
Member Author

@MagdalenaKotynia MagdalenaKotynia Feb 14, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I added the check if scene_config.binary_path outside the launch_binary method because it seemed for me to be a clearer solution than allowing the call of the launch_binary method with an optional binary_path argument and checking it inside this method. Currently the problem is outdated because after yesterday discussion with @maciejmajek we decided to separate common config attributes to base SimulationConfig class and to define other attributes in custom classes for each connector (implemented in ab5bf1f). As a result, the binary_path is now mandatory for this connector and there is no need to check it inside the connector (it is handled when loading config content to pydantic model).

…converting pose to ros2 pose and in inverse direction
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants