-
Notifications
You must be signed in to change notification settings - Fork 20
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
7 changed files
with
187 additions
and
16 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -23,6 +23,9 @@ class Config: | |
VCPKG_EXEC = "vcpkg" | ||
VCPKG_BOOTSTRAP = "bootstrap-vcpkg.sh" | ||
VCPKG_TRIPLET = "x64-linux" | ||
TAPED_TEST_DATA_DIR = os.path.join("external", "taped_test_data") | ||
TAPED_TEST_DATA_REPO = "[email protected]:RobotecAI/RGL-blobs.git" | ||
TAPED_TEST_DATA_BRANCH = "main" | ||
|
||
def __init__(self): | ||
# Platform-dependent configuration | ||
|
@@ -69,6 +72,10 @@ def main(): | |
help="Pass arguments to make. Usage: --make=\"args...\". Defaults to \"-j <cpu count>\"") | ||
parser.add_argument("--lib-rpath", type=str, nargs='*', | ||
help="Add run-time search path(s) for RGL library. $ORIGIN (actual library path) is added by default.") | ||
parser.add_argument("--install-taped-test-deps", action='store_true', | ||
help="Install dependencies for taped test and exit (closed-source dependencies)") | ||
parser.add_argument("--build-taped-test", action='store_true', | ||
help="Build taped test") | ||
if on_windows(): | ||
parser.add_argument("--ninja", type=str, default=f"-j{os.cpu_count()}", dest="build_args", | ||
help="Pass arguments to ninja. Usage: --ninja=\"args...\". Defaults to \"-j <cpu count>\"") | ||
|
@@ -100,6 +107,17 @@ def main(): | |
print('Installed ROS2 deps, exiting...') | ||
return 0 | ||
|
||
# Install taped test dependencies | ||
if args.install_taped_test_deps: | ||
install_taped_test_deps(cfg) | ||
print('Installed dependencies for taped test, exiting...') | ||
return 0 | ||
|
||
# Check taped test requirements | ||
if args.build_taped_test and not args.with_pcl: | ||
raise RuntimeError( | ||
"Taped test requires PCL extension to be built: run this script with --with-pcl flag") | ||
|
||
# Check CUDA | ||
if not is_cuda_version_ok(cfg): | ||
raise RuntimeError( | ||
|
@@ -137,6 +155,7 @@ def main(): | |
f"-DRGL_BUILD_ROS2_EXTENSION={'ON' if args.with_ros2 else 'OFF'}", | ||
f"-DRGL_BUILD_UDP_EXTENSION={'ON' if args.with_udp else 'OFF'}", | ||
f"-DRGL_BUILD_SNOW_EXTENSION={'ON' if args.with_snow else 'OFF'}", | ||
f"-DRGL_BUILD_TAPED_TESTS={'ON' if args.build_taped_test else 'OFF'}" | ||
] | ||
|
||
if on_linux(): | ||
|
@@ -233,15 +252,15 @@ def install_pcl_deps(cfg): | |
f"{os.path.join(cfg.VCPKG_DIR, cfg.VCPKG_EXEC)} install --clean-after-build pcl[core,visualization]:{cfg.VCPKG_TRIPLET}") | ||
|
||
|
||
def has_colcon(): | ||
process = subprocess.Popen("colcon --help", shell=True, stderr=subprocess.DEVNULL, stdout=subprocess.DEVNULL) | ||
def is_command_available(command): | ||
process = subprocess.Popen(f"{command}", shell=True, stderr=subprocess.DEVNULL, stdout=subprocess.DEVNULL) | ||
process.wait() | ||
return process.returncode == 0 | ||
|
||
|
||
def install_ros2_deps(cfg): | ||
# Install colcon if needed | ||
if not has_colcon(): | ||
if not is_command_available("colcon --help"): | ||
if on_windows(): | ||
run_system_command("pip install colcon-common-extensions") | ||
elif not inside_docker(): # Linux; Inside docker already installed | ||
|
@@ -261,6 +280,47 @@ def install_ros2_deps(cfg): | |
# TODO: cyclonedds rmw may be installed here (instead of manually in readme) | ||
|
||
|
||
def ensure_git_lfs_installed(): | ||
if not is_command_available("git-lfs --help"): | ||
print("Installing git-lfs...") | ||
run_subprocess_command( | ||
"curl -s https://packagecloud.io/install/repositories/github/git-lfs/script.deb.sh | sudo bash") | ||
run_subprocess_command("sudo apt install git-lfs") | ||
|
||
|
||
def clone_taped_test_data_repo(cfg): | ||
run_subprocess_command( | ||
f"git clone -b {cfg.TAPED_TEST_DATA_BRANCH} --single-branch --depth 1 {cfg.TAPED_TEST_DATA_REPO} {cfg.TAPED_TEST_DATA_DIR}") | ||
os.chdir(cfg.TAPED_TEST_DATA_DIR) | ||
# Set up git-lfs for this repository | ||
run_subprocess_command("git-lfs install && git-lfs pull") | ||
|
||
|
||
def is_taped_data_up_to_date(cfg): | ||
result = subprocess.Popen("git fetch --dry-run --verbose", shell=True, stdout=subprocess.PIPE, | ||
stderr=subprocess.STDOUT) | ||
stdout, _ = result.communicate() | ||
return f"[up to date] {cfg.TAPED_TEST_DATA_BRANCH}" in stdout.decode() | ||
|
||
|
||
def update_taped_test_data_repo(cfg): | ||
if not is_taped_data_up_to_date(cfg): | ||
print("Updating taped test benchmark data repository...") | ||
run_subprocess_command("git pull && git-lfs pull") | ||
|
||
|
||
def install_taped_test_deps(cfg): | ||
# Cloning and updating taped test benchmark data repo requires git-lfs to be installed | ||
ensure_git_lfs_installed() | ||
if not os.path.isdir(cfg.TAPED_TEST_DATA_DIR): | ||
print("Cloning taped test benchmark data repository...") | ||
clone_taped_test_data_repo(cfg) | ||
else: | ||
print("Checking for updates in taped test benchmark data repository...") | ||
os.chdir(cfg.TAPED_TEST_DATA_DIR) | ||
update_taped_test_data_repo(cfg) | ||
|
||
|
||
# Returns a dict with env variables visible for a command after running in a system shell | ||
# Used to capture effects of sourcing file such as ros2 setup | ||
def capture_environment(command="cd ."): | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
cmake_minimum_required(VERSION 3.16) | ||
|
||
if(WIN32) | ||
message(FATAL_ERROR "Tape not supported on Windows") | ||
endif() | ||
|
||
set(RGL_TAPED_TEST_FILES | ||
src/AwsimMeshToPcdTest.cpp | ||
) | ||
|
||
include(GoogleTest) | ||
|
||
add_executable(RobotecGPULidar_taped_test ${RGL_TAPED_TEST_FILES}) | ||
|
||
target_link_libraries(RobotecGPULidar_taped_test PRIVATE | ||
gtest_main | ||
gmock_main | ||
spdlog | ||
RobotecGPULidar | ||
) | ||
|
||
target_include_directories(RobotecGPULidar_taped_test PRIVATE | ||
${CMAKE_CURRENT_SOURCE_DIR}/../include | ||
${CMAKE_CURRENT_SOURCE_DIR}/../../include | ||
) | ||
|
||
gtest_discover_tests(RobotecGPULidar_taped_test) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,63 @@ | ||
#include <helpers/commonHelpers.hpp> | ||
#include <rgl/api/extensions/tape.h> | ||
|
||
#include <filesystem> | ||
#include <spdlog/fmt/ostr.h> | ||
|
||
#if RGL_BUILD_PCL_EXTENSION | ||
#include <pcl/point_cloud.h> | ||
#include <pcl/point_types.h> | ||
#include <pcl/io/pcd_io.h> | ||
#endif | ||
|
||
class AwsimMeshToPcdTest : public RGLTest | ||
{ | ||
protected: | ||
const std::string benchmarkDataDirEnvVariableName = "RGL_TAPED_TEST_DATA_DIR"; | ||
|
||
const std::string testTapeFileName = "awsim-mesh2pcd"; | ||
const std::string expectedOutputDirName = "expected-output"; | ||
const std::string expectedOutputFileName = testTapeFileName + ".pcd"; | ||
|
||
const float epsilon = 1e-2f; | ||
}; | ||
|
||
TEST_F(AwsimMeshToPcdTest, validate_point_cloud_equivalence) | ||
{ | ||
#if RGL_BUILD_PCL_EXTENSION | ||
|
||
// It is necessary to set environment variable on benchmark data directory | ||
if (std::getenv(benchmarkDataDirEnvVariableName.c_str()) == nullptr) { | ||
const std::string msg = fmt::format( | ||
"Skipping Taped Test - benchmark data directory must be provided in environment variable '{}'", | ||
benchmarkDataDirEnvVariableName); | ||
GTEST_SKIP() << msg; | ||
} | ||
|
||
const std::string benchmarkDataDir = std::getenv(benchmarkDataDirEnvVariableName.c_str()); | ||
const std::string testTapePath{(std::filesystem::path(benchmarkDataDir) / testTapeFileName).string()}; | ||
const std::string expectedOutputPath{ | ||
(std::filesystem::path(benchmarkDataDir) / expectedOutputDirName / expectedOutputFileName).string()}; | ||
const std::string outputPath{(std::filesystem::current_path() / "output.pcd").string()}; | ||
|
||
ASSERT_RGL_SUCCESS(rgl_tape_play(testTapePath.c_str())); | ||
|
||
pcl::PointCloud<pcl::PointXYZ>::Ptr expectedCloud(new pcl::PointCloud<pcl::PointXYZ>); | ||
pcl::PointCloud<pcl::PointXYZ>::Ptr outputCloud(new pcl::PointCloud<pcl::PointXYZ>); | ||
|
||
pcl::io::loadPCDFile(expectedOutputPath, *expectedCloud); | ||
pcl::io::loadPCDFile(outputPath, *outputCloud); | ||
|
||
ASSERT_TRUE(expectedCloud->size() == outputCloud->size()); | ||
|
||
for (size_t i = 0; i < expectedCloud->size(); ++i) { | ||
EXPECT_NEAR(expectedCloud->points[i].x, outputCloud->points[i].x, epsilon); | ||
EXPECT_NEAR(expectedCloud->points[i].y, outputCloud->points[i].y, epsilon); | ||
EXPECT_NEAR(expectedCloud->points[i].z, outputCloud->points[i].z, epsilon); | ||
} | ||
|
||
#else | ||
const std::string msg = fmt::format("Skipping Taped Test - RGL compiled without PCL extension."); | ||
GTEST_SKIP() << msg; | ||
#endif | ||
} |