Skip to content

Commit d4ac769

Browse files
jmatejczmaciejmajekboczekbartekMagdalenaKotynia
authored
feat: O3DE test benchmark (#426)
Co-authored-by: Maciej Majek <[email protected]> Co-authored-by: Bartłomiej Boczek <[email protected]> Co-authored-by: MagdalenaKotynia <[email protected]>
1 parent 702bb00 commit d4ac769

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

58 files changed

+1283
-203
lines changed

.gitignore

+2
Original file line numberDiff line numberDiff line change
@@ -172,3 +172,5 @@ logs/
172172

173173
src/examples/*-demo
174174
artifact_database.pkl
175+
176+
imgui.ini

examples/agriculture-demo.py

+6-6
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,12 @@
1515
import argparse
1616

1717
import rclpy
18+
from rclpy.action import ActionClient
19+
from rclpy.callback_groups import ReentrantCallbackGroup
20+
from rclpy.executors import MultiThreadedExecutor
21+
from rclpy.node import Node
22+
from std_srvs.srv import Trigger
23+
1824
from rai.node import RaiStateBasedLlmNode, describe_ros_image
1925
from rai.tools.ros.native import (
2026
GetCameraImage,
@@ -24,12 +30,6 @@
2430
Ros2ShowMsgInterfaceTool,
2531
)
2632
from rai.tools.time import WaitForSecondsTool
27-
from rclpy.action import ActionClient
28-
from rclpy.callback_groups import ReentrantCallbackGroup
29-
from rclpy.executors import MultiThreadedExecutor
30-
from rclpy.node import Node
31-
from std_srvs.srv import Trigger
32-
3333
from rai_interfaces.action import Task
3434

3535

examples/manipulation-demo-streamlit.py

+1
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616

1717
import streamlit as st
1818
from langchain_core.messages import AIMessage, HumanMessage, ToolMessage
19+
1920
from rai.agents.integrations.streamlit import get_streamlit_cb, streamlit_invoke
2021
from rai.messages import HumanMultimodalMessage
2122

examples/manipulation-demo.launch.py

+5-44
Original file line numberDiff line numberDiff line change
@@ -12,22 +12,16 @@
1212
# See the License for the specific language governing permissions and
1313
# limitations under the License.
1414

15-
import rclpy
16-
from launch import LaunchContext, LaunchDescription
15+
from launch import LaunchDescription
1716
from launch.actions import (
1817
DeclareLaunchArgument,
1918
ExecuteProcess,
2019
IncludeLaunchDescription,
21-
OpaqueFunction,
22-
RegisterEventHandler,
2320
)
24-
from launch.event_handlers import OnExecutionComplete, OnProcessStart
2521
from launch.launch_description_sources import PythonLaunchDescriptionSource
2622
from launch.substitutions import LaunchConfiguration
2723
from launch_ros.actions import Node
2824
from launch_ros.substitutions import FindPackageShare
29-
from rclpy.qos import QoSProfile, ReliabilityPolicy
30-
from rosgraph_msgs.msg import Clock
3125

3226

3327
def generate_launch_description():
@@ -46,21 +40,6 @@ def generate_launch_description():
4640
output="screen",
4741
)
4842

49-
def wait_for_clock_message(context: LaunchContext, *args, **kwargs):
50-
rclpy.init()
51-
node = rclpy.create_node("wait_for_game_launcher")
52-
node.create_subscription(
53-
Clock,
54-
"/clock",
55-
lambda msg: rclpy.shutdown(),
56-
QoSProfile(depth=1, reliability=ReliabilityPolicy.BEST_EFFORT),
57-
)
58-
rclpy.spin(node)
59-
return None
60-
61-
# Game launcher will start publishing the clock message after loading the simulation
62-
wait_for_game_launcher = OpaqueFunction(function=wait_for_clock_message)
63-
6443
launch_moveit = IncludeLaunchDescription(
6544
PythonLaunchDescriptionSource(
6645
[
@@ -72,7 +51,7 @@ def wait_for_clock_message(context: LaunchContext, *args, **kwargs):
7251
launch_robotic_manipulation = Node(
7352
package="robotic_manipulation",
7453
executable="robotic_manipulation",
75-
name="robotic_manipulation_node",
54+
# name="robotic_manipulation_node",
7655
output="screen",
7756
parameters=[
7857
{"use_sim_time": True},
@@ -90,28 +69,10 @@ def wait_for_clock_message(context: LaunchContext, *args, **kwargs):
9069

9170
return LaunchDescription(
9271
[
93-
# Include the game_launcher argument
9472
game_launcher_arg,
95-
# Launch the game launcher and wait for it to load
9673
launch_game_launcher,
97-
RegisterEventHandler(
98-
event_handler=OnProcessStart(
99-
target_action=launch_game_launcher,
100-
on_start=[
101-
wait_for_game_launcher,
102-
],
103-
)
104-
),
105-
# Launch the MoveIt node after loading the simulation
106-
RegisterEventHandler(
107-
event_handler=OnExecutionComplete(
108-
target_action=wait_for_game_launcher,
109-
on_completion=[
110-
launch_openset,
111-
launch_moveit,
112-
launch_robotic_manipulation,
113-
],
114-
)
115-
),
74+
launch_openset,
75+
launch_moveit,
76+
launch_robotic_manipulation,
11677
]
11778
)

examples/manipulation-demo.py

+11-10
Original file line numberDiff line numberDiff line change
@@ -12,37 +12,38 @@
1212
# See the License for the specific language goveself.rning permissions and
1313
# limitations under the License.
1414

15-
import threading
1615

1716
import rclpy
1817
import rclpy.qos
1918
from langchain_core.messages import HumanMessage
19+
from rai_open_set_vision.tools import GetGrabbingPointTool
20+
2021
from rai.agents.conversational_agent import create_conversational_agent
21-
from rai.node import RaiBaseNode
22+
from rai.communication.ros2.connectors import ROS2ARIConnector
2223
from rai.tools.ros.manipulation import GetObjectPositionsTool, MoveToPointTool
23-
from rai.tools.ros.native import GetCameraImage, Ros2GetTopicsNamesAndTypesTool
24+
from rai.tools.ros2.topics import GetROS2ImageTool, GetROS2TopicsNamesAndTypesTool
2425
from rai.utils.model_initialization import get_llm_model
2526

2627

2728
def create_agent():
2829
rclpy.init()
29-
node = RaiBaseNode(node_name="manipulation_demo")
30+
connector = ROS2ARIConnector()
31+
node = connector.node
3032
node.declare_parameter("conversion_ratio", 1.0)
3133

32-
threading.Thread(target=node.spin).start()
33-
3434
tools = [
3535
GetObjectPositionsTool(
36-
node=node,
36+
connector=connector,
3737
target_frame="panda_link0",
3838
source_frame="RGBDCamera5",
3939
camera_topic="/color_image5",
4040
depth_topic="/depth_image5",
4141
camera_info_topic="/color_camera_info5",
42+
get_grabbing_point_tool=GetGrabbingPointTool(connector=connector),
4243
),
43-
MoveToPointTool(node=node, manipulator_frame="panda_link0"),
44-
GetCameraImage(node=node),
45-
Ros2GetTopicsNamesAndTypesTool(node=node),
44+
MoveToPointTool(connector=connector, manipulator_frame="panda_link0"),
45+
GetROS2ImageTool(connector=connector),
46+
GetROS2TopicsNamesAndTypesTool(connector=connector),
4647
]
4748

4849
llm = get_llm_model(model_type="complex_model", streaming=True)

examples/rosbot-xl-demo.py

+2-1
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@
1818
import rclpy
1919
import rclpy.executors
2020
import rclpy.logging
21+
from rai_open_set_vision.tools import GetDetectionTool, GetDistanceToObjectsTool
22+
2123
from rai.node import RaiStateBasedLlmNode
2224
from rai.tools.ros.native import (
2325
GetMsgFromTopic,
@@ -33,7 +35,6 @@
3335
Ros2RunActionAsync,
3436
)
3537
from rai.tools.time import WaitForSecondsTool
36-
from rai_open_set_vision.tools import GetDetectionTool, GetDistanceToObjectsTool
3738

3839
p = argparse.ArgumentParser()
3940
p.add_argument("--allowlist", type=Path, required=False, default=None)

examples/taxi-demo.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -20,12 +20,12 @@
2020
from langchain_community.tools.tavily_search import TavilySearchResults
2121
from langchain_core.messages import BaseMessage, HumanMessage
2222
from langchain_core.tools import tool
23+
from std_msgs.msg import String
24+
2325
from rai.agents.conversational_agent import create_conversational_agent
2426
from rai.tools.ros.cli import Ros2ServiceTool
2527
from rai.tools.ros.native import Ros2PubMessageTool
2628
from rai.utils.model_initialization import get_llm_model, get_tracing_callbacks
27-
from std_msgs.msg import String
28-
2929
from rai_hmi.api import GenericVoiceNode, split_message
3030

3131
system_prompt = """

poetry.lock

+14-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

pyproject.toml

+2-1
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ rai = {path = "src/rai_core", develop = true}
1818
rai_asr = {path = "src/rai_asr", develop = true}
1919
rai_tts = {path = "src/rai_tts", develop = true}
2020
rai_sim = {path = "src/rai_sim", develop = true}
21+
rai_bench = {path = "src/rai_bench", develop = true}
2122

2223
langchain-core = "^0.3"
2324
langchain = "*"
@@ -30,7 +31,6 @@ requests = "^2.32.2"
3031
pre-commit = "^3.7.0"
3132
openai = "^1.23.3"
3233
coloredlogs = "^15.0.1"
33-
opencv-python = "^4.9.0.80"
3434
markdown = "^3.6"
3535
boto3 = "^1.34.98"
3636
tqdm = "^4.66.4"
@@ -62,6 +62,7 @@ pytest-timeout = "^2.3.1"
6262
tomli-w = "^1.1.0"
6363
faster-whisper = "^1.1.1"
6464
pydub = "^0.25.1"
65+
opencv-python = "^4.11.0.86"
6566
[tool.poetry.group.dev.dependencies]
6667
ipykernel = "^6.29.4"
6768

setup_shell.sh

+3
Original file line numberDiff line numberDiff line change
@@ -30,3 +30,6 @@ esac
3030

3131
export PYTHONPATH
3232
PYTHONPATH="$(dirname "$(dirname "$(poetry run which python)")")/lib/python$(poetry run python --version | awk '{print $2}' | cut -d. -f1,2)/site-packages:$PYTHONPATH"
33+
PYTHONPATH="src/rai_core:$PYTHONPATH"
34+
PYTHONPATH="src/rai_asr:$PYTHONPATH"
35+
PYTHONPATH="src/rai_tts:$PYTHONPATH"

src/examples/turtlebot4/turtlebot_demo.py

+1
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
import rclpy.qos
2424
import rclpy.subscription
2525
import rclpy.task
26+
2627
from rai.node import RaiStateBasedLlmNode
2728
from rai.tools.ros.native import (
2829
GetCameraImage,

src/rai_bench/README.md

+60
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
## RAI Benchmark
2+
3+
## Description
4+
5+
The RAI Bench is a package including benchmarks and providing frame for creating new benchmarks
6+
7+
## Frame Components
8+
9+
Frame components can be found in `src/rai_bench/rai_bench/benchmark_model.py`
10+
11+
- `Task` - abstract class for creating specific task. It introduces helper funtions that make it easier to calculate metrics/scores. Your custom tasks must implement a prompt got agent to do, a way to calculate a result and a validation if given scene config suits the task.
12+
-
13+
- `Scenario` - class defined by a Scene and Task. Can be created manually like:
14+
15+
```python
16+
17+
```
18+
19+
- `Benchmark` - class responsible for running and logging scenarios.
20+
21+
### O3DE TEST BENCHMARK
22+
23+
O3DE Test Benchmark (src/rai_bench/rai_bench/o3de_test_bench/), contains 2 Tasks(tasks/) - GrabCarrotTask and PlaceCubesTask (these tasks implement calculating scores) and 4 scene_configs(configs/) for O3DE robotic arm simulation.
24+
25+
Both tasks calculate score, taking into consideration 4 values:
26+
27+
- initially_misplaced_now_correct - when the object which was in the incorrect place at the start, is in a correct place at the end
28+
- initially_misplaced_still_incorrect - when the object which was in the incorrect place at the start, is in a incorrect place at the end
29+
- initially_correct_still_correct - when the object which was in the correct place at the start, is in a correct place at the end
30+
- initially_correct_now_incorrect - when the object which was in the correct place at the start, is in a incorrect place at the end
31+
32+
The result is a value between 0 and 1, calculated like (initially_misplaced_now_correct + initially_correct_still_correct) / number_of_initial_objects.
33+
This score is calculated at the beggining and at the end of each scenario.
34+
35+
### Example usage
36+
37+
Example of how to load scenes, define scenarios and run benchmark can be found in `src/rai_bench/rai_bench/benchmark_main.py`
38+
39+
Scenarios can be loaded manually like:
40+
41+
```python
42+
one_carrot_simulation_config = O3DExROS2SimulationConfig.load_config(
43+
base_config_path=Path("path_to_scene.yaml"),
44+
connector_config_path=Path("path_to_o3de_config.yaml"),
45+
)
46+
47+
Scenario(task=GrabCarrotTask(logger=some_logger), simulation_config=one_carrot_simulation_config)
48+
```
49+
50+
or automatically like:
51+
52+
```python
53+
scenarios = Benchmark.create_scenarios(
54+
tasks=tasks, simulation_configs=simulations_configs
55+
)
56+
```
57+
58+
which will result in list of scenarios with combination of every possible task and scene(task decides if scene config is suitable for it).
59+
60+
Both approaches can be found in `main.py`

src/rai_bench/pyproject.toml

+17
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
[tool.poetry]
2+
name = "rai-bench"
3+
version = "0.1.0"
4+
description = ""
5+
authors = ["jmatejcz <[email protected]>"]
6+
readme = "README.md"
7+
8+
packages = [
9+
{ include = "rai_bench", from = "." },
10+
]
11+
[tool.poetry.dependencies]
12+
python = "^3.10"
13+
14+
15+
[build-system]
16+
requires = ["poetry-core"]
17+
build-backend = "poetry.core.masonry.api"

0 commit comments

Comments
 (0)