Skip to content

Commit 7435de4

Browse files
AIRO-1431 Add ros integration tests (#329)
1 parent 395066a commit 7435de4

File tree

13 files changed

+479
-57
lines changed

13 files changed

+479
-57
lines changed

.yamato/PickAndPlaceTests/ros.bash

Lines changed: 146 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,146 @@
1+
#!/bin/bash
2+
# Assuming this script is invoked from the root of the repository...
3+
help() {
4+
echo "usage: $0 [COMMAND] [ROS]"
5+
echo "COMMAND:"
6+
echo " - stop"
7+
echo " - build_pick_and_place"
8+
echo " - start_pick_and_place"
9+
echo " - build_ros"
10+
echo " - start_ros"
11+
echo " - run_ros_color_publisher"
12+
echo " - run_ros_pose_service_client"
13+
echo " - run_ros_position_service"
14+
echo "ROS"
15+
echo " - ros1"
16+
echo " - ros2"
17+
}
18+
19+
COMMAND=$1
20+
ROS=$2
21+
22+
if [ "$COMMAND" == "stop" ]; then
23+
echo "Terminating process $3"
24+
pkill -15 -P $3
25+
sleep 10
26+
27+
elif [ "$COMMAND" == "build_pick_and_place" ]; then
28+
source /opt/ros/noetic/setup.bash
29+
pushd $PWD
30+
cd tutorials/pick_and_place/ROS
31+
catkin_make
32+
source devel/setup.bash
33+
popd
34+
35+
elif [ "$COMMAND" == "start_pick_and_place" ]; then
36+
echo "Starting ROS for Pick and Place"
37+
source tutorials/pick_and_place/ROS/devel/setup.bash
38+
roslaunch niryo_moveit part_3.launch
39+
40+
elif [ "$COMMAND" == "build_ros" ]; then
41+
if [ "$ROS" == "ros1" ]; then
42+
export ROS_WORKSPACE=$(pwd)/ros1_ws
43+
mkdir -p $ROS_WORKSPACE/src
44+
cp -r tutorials/ros_unity_integration/ros_packages/ $ROS_WORKSPACE/src/
45+
git clone https://github.com/Unity-Technologies/ROS-TCP-Endpoint $ROS_WORKSPACE/src/ros_tcp_endpoint -b main
46+
/bin/bash tutorials/ros_unity_integration/ros_docker/set-up-workspace
47+
chmod +x $ROS_WORKSPACE/src/ros_tcp_endpoint/src/ros_tcp_endpoint/*.py
48+
elif [ "$ROS" == "ros2" ]; then
49+
export ROS_WORKSPACE=$(pwd)/ros2_ws
50+
mkdir -p $ROS_WORKSPACE/src
51+
cp -r tutorials/ros_unity_integration/ros2_packages/ $ROS_WORKSPACE/src/
52+
git clone https://github.com/Unity-Technologies/ROS-TCP-Endpoint $ROS_WORKSPACE/src/ros_tcp_endpoint -b main-ros2
53+
source /opt/ros/$ROS_DISTRO/setup.sh
54+
pushd $(pwd)
55+
cd $ROS_WORKSPACE
56+
colcon build
57+
popd
58+
else
59+
help
60+
fi
61+
62+
elif [ "$COMMAND" == "start_ros" ]; then
63+
if [ "$ROS" == "ros1" ]; then
64+
source ros1_ws/devel/setup.bash
65+
echo "Starting ROS1 master"
66+
roscore &
67+
sleep 5 # Wait ROS master to stand up
68+
rosparam set ROS_IP 127.0.0.1
69+
echo "Starting ROS1 default server endpoint"
70+
rosrun ros_tcp_endpoint default_server_endpoint.py
71+
elif [ "$ROS" == "ros2" ]; then
72+
source ros2_ws/install/setup.bash
73+
echo "Starting ROS2 default server endpoint"
74+
ros2 run ros_tcp_endpoint default_server_endpoint --ros-args -p ROS_IP:=127.0.0.1
75+
else
76+
help
77+
fi
78+
79+
elif [ "$COMMAND" == "run_ros_color_publisher" ]; then
80+
if [ "$ROS" == "ros1" ]; then
81+
source ros1_ws/devel/setup.bash
82+
elif [ "$ROS" == "ros2" ]; then
83+
source ros2_ws/install/setup.bash
84+
else
85+
help
86+
fi
87+
echo "Starting to run $ROS color publisher every 30 seconds"
88+
count=0
89+
while [[ $count -le 6 ]]
90+
do
91+
sleep 5
92+
if [ "$ROS" == "ros1" ]; then
93+
rosrun unity_robotics_demo color_publisher.py
94+
elif [ "$ROS" == "ros2" ]; then
95+
ros2 run unity_robotics_demo color_publisher
96+
else
97+
help
98+
fi
99+
count=$(( $count + 1 ))
100+
done
101+
echo "Completed run: $ROS color publisher"
102+
103+
elif [ "$COMMAND" == "run_ros_pose_service_client" ]; then
104+
if [ "$ROS" == "ros1" ]; then
105+
source ros1_ws/devel/setup.bash
106+
elif [ "$ROS" == "ros2" ]; then
107+
source ros2_ws/install/setup.bash
108+
else
109+
help
110+
fi
111+
echo "Starting to run $ROS pose service client and send requests every 30 seconds"
112+
count=0
113+
while [[ $count -le 6 ]]
114+
do
115+
sleep 5
116+
if [ "$ROS" == "ros1" ]; then
117+
rosservice call /obj_pose_srv Cube
118+
elif [ "$ROS" == "ros2" ]; then
119+
ros2 service call obj_pose_srv unity_robotics_demo_msgs/ObjectPoseService "{object_name: Cube}"
120+
else
121+
help
122+
fi
123+
count=$(( $count + 1 ))
124+
done
125+
echo "Completed run: $ROS pose service client"
126+
127+
elif [ "$COMMAND" == "run_ros_position_service" ]; then
128+
if [ "$ROS" == "ros1" ]; then
129+
source ros1_ws/devel/setup.bash
130+
elif [ "$ROS" == "ros2" ]; then
131+
source ros2_ws/install/setup.bash
132+
else
133+
help
134+
fi
135+
echo "Starting $ROS position service"
136+
if [ "$ROS" == "ros1" ]; then
137+
rosrun unity_robotics_demo position_service.py
138+
elif [ "$ROS" == "ros2" ]; then
139+
ros2 run unity_robotics_demo position_service
140+
else
141+
help
142+
fi
143+
144+
else
145+
help
146+
fi

.yamato/PickAndPlaceTests/set-up-integration-tests.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
external_scripts_dir = os.path.join(root_dir, "Scripts")
1818
project_dir = os.path.join(root_dir, "PickAndPlaceProject")
1919
project_scripts_dir = os.path.join(project_dir, "Assets", "Scripts")
20+
external_ros_scripts_dir = os.path.join(script_dir, "..", "..", "tutorials", "ros_unity_integration", "unity_scripts")
2021
# project_settings_file = os.path.join(project_dir, "ProjectSettings", "ProjectSettings.asset")
2122

2223
scripts_to_move = glob.glob(os.path.join(external_scripts_dir, "*.cs"))
@@ -26,6 +27,13 @@
2627
print(f">>> Copying {external_script} to {script_destination}")
2728
shutil.copyfile(external_script, script_destination)
2829

30+
scripts_to_move = glob.glob(os.path.join(external_ros_scripts_dir, "*.cs"))
31+
for external_script in scripts_to_move:
32+
script_name = os.path.basename(external_script)
33+
script_destination = os.path.join(project_scripts_dir, script_name)
34+
print(f">>> Copying {external_script} to {script_destination}")
35+
shutil.copyfile(external_script, script_destination)
36+
2937
files_to_cat = []
3038
message_dir = os.path.join(project_dir, "Assets", "RosMessages")
3139
print(f">>> Files in {message_dir}:")
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
from unityparser import UnityDocument
2+
3+
import argparse
4+
import os
5+
6+
parser = argparse.ArgumentParser(description='Add ROS define symbols')
7+
parser.add_argument('ros', type=str, help='ROS version: ros1 or ros2')
8+
9+
project_settings_filepath = os.path.join(".", "tutorials", "pick_and_place", "PickAndPlaceProject", "ProjectSettings", "ProjectSettings.asset")
10+
if not os.path.exists(project_settings_filepath):
11+
raise FileNotFoundError("Not found %s".format(project_settings_filepath))
12+
settings = UnityDocument.load_yaml(project_settings_filepath)
13+
symbols = settings.entries[0].scriptingDefineSymbols
14+
15+
args = parser.parse_args()
16+
if args.ros == "ros1":
17+
if symbols[1] is None:
18+
symbols[1] = "ROS1"
19+
else:
20+
symbols[1] += ";ROS1"
21+
elif args.ros == "ros2":
22+
if symbols[1] is None:
23+
symbols[1] = "ROS2"
24+
else:
25+
symbols[1] += ";ROS2"
26+
else:
27+
raise ValueError("Invalid input ROS version. Must be either ros1 or ros2")
28+
settings.dump_yaml(project_settings_filepath)
29+

.yamato/PickAndPlaceTests/start-ros.bash

Lines changed: 0 additions & 11 deletions
This file was deleted.

.yamato/yamato-config.yml

Lines changed: 142 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -1,41 +1,144 @@
1-
name: Robotics Hub Tests
2-
agent:
3-
type: Unity::VM
4-
image: robotics/ci-ubuntu20:v0.1.0pnp-796097
5-
flavor: i1.large
6-
variables:
7-
PATH: /root/.local/bin:/home/bokken/bin:/home/bokken/.local/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin:/sbin:/home/bokken/.npm-global/bin
8-
commands:
9-
- git submodule update --init --recursive
10-
# We must remove the Demo.cs script because the System.CodeDom assembly is not in the bokken .NET sdk
11-
- rm ./tutorials/pick_and_place/PickAndPlaceProject/Assets/DemoScripts/Demo.*
12-
# Ensure audio is disabled. Unity built-in audio fails to initialize in our Bokken image.
13-
- "sed -i -e '/m_DisableAudio/ s/: .*/: 1/' ./tutorials/pick_and_place/PickAndPlaceProject/ProjectSettings/AudioManager.asset"
14-
- python3 -m pip install unity-downloader-cli --index-url https://artifactory.prd.it.unity3d.com/artifactory/api/pypi/pypi/simple --upgrade
15-
- unity-downloader-cli -u 2020.3.11f1 -c editor -c StandaloneSupport-IL2CPP -c Linux --wait --published
16-
- git clone git@github.cds.internal.unity3d.com:unity/utr.git utr
17-
# Explicitly run MessageGeneration tests first to generate dependencies
18-
- utr/utr --testproject=./tutorials/pick_and_place/PickAndPlaceProject --editor-location=.Editor --reruncount=0
19-
--artifacts_path=test-results --suite=editor --platform=Editor --editorTestsCategories
20-
MessageGeneration
21-
# Run each category of tests in its own process, in order of increasing complexity
22-
- utr/utr --testproject=./tutorials/pick_and_place/PickAndPlaceProject --editor-location=.Editor --reruncount=0
23-
--artifacts_path=test-results --suite=playmode --suite=editor --platform=Editor --editorTestCategories UnitTests
1+
pick_and_place:
2+
name: Robotics Hub Pick and Place Tests
3+
agent:
4+
type: Unity::VM
5+
image: robotics/ci-ubuntu20:v0.1.0pnp-796097
6+
flavor: i1.large
7+
variables:
8+
PATH: /root/.local/bin:/home/bokken/bin:/home/bokken/.local/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin:/sbin:/home/bokken/.npm-global/bin
9+
commands:
10+
- sudo ln -s $(which python3) /usr/bin/python
11+
- git submodule update --init --recursive
12+
13+
# We must remove the Demo.cs script because the System.CodeDom assembly is not in the bokken .NET sdk
14+
- rm ./tutorials/pick_and_place/PickAndPlaceProject/Assets/DemoScripts/Demo.*
15+
16+
# Ensure audio is disabled. Unity built-in audio fails to initialize in our Bokken image.
17+
- "sed -i -e '/m_DisableAudio/ s/: .*/: 1/' ./tutorials/pick_and_place/PickAndPlaceProject/ProjectSettings/AudioManager.asset"
18+
- python3 -m pip install unity-downloader-cli --index-url https://artifactory.prd.it.unity3d.com/artifactory/api/pypi/pypi/simple --upgrade
19+
- unity-downloader-cli -u 2020.3.11f1 -c editor -c StandaloneSupport-IL2CPP -c Linux --wait --published
20+
- git clone git@github.cds.internal.unity3d.com:unity/utr.git utr
21+
22+
# Explicitly run MessageGeneration tests first to generate dependencies
23+
- utr/utr --testproject=./tutorials/pick_and_place/PickAndPlaceProject --editor-location=.Editor --reruncount=0
24+
--artifacts_path=test-results --suite=editor --platform=Editor --extra-editor-arg="-nographics"
25+
--category=MessageGeneration
26+
27+
# Run each category of tests in its own process, in order of increasing complexity
28+
- utr/utr --testproject=./tutorials/pick_and_place/PickAndPlaceProject --editor-location=.Editor --reruncount=0
29+
--artifacts_path=test-results --suite=playmode --suite=editor --platform=Editor --category=UnitTests
30+
2431
# - utr/utr --testproject=./tutorials/pick_and_place/PickAndPlaceProject --editor-location=.Editor --reruncount=0
2532
#--artifacts_path=test-results --suite=editor --platform=Editor --testfilter BuildTests.PlayerBuilder.BuildPlayerLinux
26-
- python3 .yamato/PickAndPlaceTests/set-up-integration-tests.py
27-
#TODO: Determine how best to capture ROS logging as test artifacts
28-
- sudo ln -s $(which python3) /usr/bin/python && /bin/bash .yamato/PickAndPlaceTests/start-ros.bash
29-
# NOTE: Simply specifying the testCategory is not enough to get a test marked with [Explicit] to run
30-
- utr/utr --testproject=./tutorials/pick_and_place/PickAndPlaceProject --editor-location=.Editor --reruncount=0
31-
--artifacts_path=test-results --suite=editor --platform=Editor --testfilter IntegrationTests.RosIntegrationTests
32-
#TODO: Determine when it would be prudent to run BuildTests and add them here or in a new config
33-
triggers:
34-
cancel_old_ci: true
35-
expression: |
36-
(pull_request.target in ["main", "dev"] AND
37-
NOT pull_request.changes.all match ["**/*.md","**/*.jpg","**/*.jpeg","**/*.gif","**/*.pdf"])
38-
artifacts:
39-
logs:
40-
paths:
41-
- "test-results/**/*"
33+
34+
- python3 .yamato/PickAndPlaceTests/set-up-integration-tests.py
35+
36+
# Run Pick and Place Test
37+
# NOTE: Simply specifying the testCategory is not enough to get a test marked with [Explicit] to run
38+
# TODO: Determine how best to capture ROS logging as test artifacts
39+
# TODO: Determine when it would be prudent to run BuildTests and add them here or in a new config
40+
- |
41+
/bin/bash .yamato/PickAndPlaceTests/ros.bash build_pick_and_place
42+
/bin/bash .yamato/PickAndPlaceTests/ros.bash start_pick_and_place &
43+
export PID=$!
44+
utr/utr --testproject=./tutorials/pick_and_place/PickAndPlaceProject --editor-location=.Editor --reruncount=0 --artifacts_path=test-results --suite=editor --platform=Editor --extra-editor-arg="-nographics" --testfilter IntegrationTests.PickAndPlaceIntegrationTests
45+
/bin/bash .yamato/PickAndPlaceTests/ros.bash stop ros1 $PID
46+
47+
triggers:
48+
cancel_old_ci: true
49+
expression: |
50+
(pull_request.target in ["main", "dev"] AND
51+
NOT pull_request.changes.all match ["**/*.md","**/*.jpg","**/*.jpeg","**/*.gif","**/*.pdf"])
52+
artifacts:
53+
logs:
54+
paths:
55+
- "test-results/**/*"
56+
57+
{% assign rosDistros = "noetic galactic" | split: " " %}
58+
59+
{% for rosDistro in rosDistros %}
60+
ros_{{rosDistro}}_integration:
61+
name: Robotics Hub ROS {{rosDistro}} Integration Tests
62+
agent:
63+
type: Unity::VM
64+
{% if rosDistro == "noetic" %}
65+
image: robotics/ci-ubuntu20:v0.1.0-795910
66+
{% elsif rosDistro == "galactic" %}
67+
image: robotics/ci-ros2-galactic-ubuntu20:v0.0.2-916903
68+
{% endif %}
69+
flavor: i1.large
70+
variables:
71+
PATH: /root/.local/bin:/home/bokken/bin:/home/bokken/.local/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin:/sbin:/home/bokken/.npm-global/bin
72+
commands:
73+
# TODO: move to image builders
74+
- sudo ln -s $(which python3) /usr/bin/python
75+
# TODO: move to galactic image builder
76+
- sudo apt update && sudo apt install -y build-essential
77+
78+
- git submodule update --init --recursive
79+
80+
# We must remove the Demo.cs script because the System.CodeDom assembly is not in the bokken .NET sdk
81+
- rm ./tutorials/pick_and_place/PickAndPlaceProject/Assets/DemoScripts/Demo.*
82+
83+
# Ensure audio is disabled. Unity built-in audio fails to initialize in our Bokken image.
84+
- "sed -i -e '/m_DisableAudio/ s/: .*/: 1/' ./tutorials/pick_and_place/PickAndPlaceProject/ProjectSettings/AudioManager.asset"
85+
- python3 -m pip install unity-downloader-cli --index-url https://artifactory.prd.it.unity3d.com/artifactory/api/pypi/pypi/simple --upgrade
86+
- unity-downloader-cli -u 2020.3.11f1 -c editor -c StandaloneSupport-IL2CPP -c Linux --wait --published
87+
- git clone git@github.cds.internal.unity3d.com:unity/utr.git utr
88+
89+
# Explicitly run MessageGeneration tests first to generate dependencies
90+
- utr/utr --testproject=./tutorials/pick_and_place/PickAndPlaceProject --editor-location=.Editor --reruncount=0
91+
--artifacts_path=test-results --suite=editor --platform=Editor --extra-editor-arg="-nographics"
92+
--category=MessageGeneration
93+
94+
- python3 .yamato/PickAndPlaceTests/set-up-integration-tests.py
95+
96+
# Run ROS Integration Tests
97+
# This step requires to execute set-up-integration-tests.py
98+
# TODO: move ROS_DISTRO exporting to image builder
99+
- |
100+
export ROS_DISTRO=$(ls -1 /opt/ros | head -n1)
101+
if [ $ROS_DISTRO == "noetic" ]; then
102+
ROS=ros1
103+
elif [ $ROS_DISTRO == "galactic" ]; then
104+
ROS=ros2
105+
fi
106+
107+
python3 .yamato/PickAndPlaceTests/set-up-ros-define.py $ROS
108+
109+
/bin/bash .yamato/PickAndPlaceTests/ros.bash build_ros $ROS
110+
/bin/bash .yamato/PickAndPlaceTests/ros.bash start_ros $ROS &
111+
export PID=$!
112+
sleep 10 # Wait for ROS endpoint to stand up
113+
114+
utr/utr --testproject=./tutorials/pick_and_place/PickAndPlaceProject --editor-location=.Editor --reruncount=0 --artifacts_path=test-results --suite=editor --platform=Editor --extra-editor-arg="-nographics" --testfilter IntegrationTests.RosIntegrationTests.RosIntegration_Publisher_Success
115+
116+
/bin/bash .yamato/PickAndPlaceTests/ros.bash run_ros_position_service $ROS &
117+
export POSITION_SERVICE_PID=$!
118+
utr/utr --testproject=./tutorials/pick_and_place/PickAndPlaceProject --editor-location=.Editor --reruncount=0 --artifacts_path=test-results --suite=editor --platform=Editor --extra-editor-arg="-nographics" --testfilter IntegrationTests.RosIntegrationTests.RosIntegration_ServiceClient_Success
119+
/bin/bash .yamato/PickAndPlaceTests/ros.bash stop $ROS $POSITION_SERVICE_PID
120+
121+
/bin/bash .yamato/PickAndPlaceTests/ros.bash run_ros_color_publisher $ROS &
122+
export COLOR_PUBLISHER_PID=$!
123+
utr/utr --testproject=./tutorials/pick_and_place/PickAndPlaceProject --editor-location=.Editor --reruncount=0 --artifacts_path=test-results --suite=editor --platform=Editor --extra-editor-arg="-nographics" --testfilter IntegrationTests.RosIntegrationTests.RosIntegration_Subscriber_Success
124+
/bin/bash .yamato/PickAndPlaceTests/ros.bash stop $ROS $COLOR_PUBLISHER_PID
125+
126+
/bin/bash .yamato/PickAndPlaceTests/ros.bash run_ros_pose_service_client $ROS &
127+
export POSE_SERVICE_PID=$!
128+
utr/utr --testproject=./tutorials/pick_and_place/PickAndPlaceProject --editor-location=.Editor --reruncount=0 --artifacts_path=test-results --suite=editor --platform=Editor --extra-editor-arg="-nographics" --testfilter IntegrationTests.RosIntegrationTests.RosIntegration_ServiceServer_Success
129+
/bin/bash .yamato/PickAndPlaceTests/ros.bash stop $ROS $POSE_SERVICE_PID
130+
131+
/bin/bash .yamato/PickAndPlaceTests/ros.bash stop $ROS $PID
132+
133+
triggers:
134+
cancel_old_ci: true
135+
expression: |
136+
(pull_request.target in ["main", "dev"] AND
137+
NOT pull_request.changes.all match ["**/*.md","**/*.jpg","**/*.jpeg","**/*.gif","**/*.pdf"])
138+
OR (push.branch in ["main", "dev"])
139+
artifacts:
140+
logs:
141+
paths:
142+
- "test-results/**/*"
143+
{% endfor %}
144+

0 commit comments

Comments
 (0)