Skip to content

Commit e69dbc3

Browse files
authored
1 parent 189a307 commit e69dbc3

18 files changed

+997
-0
lines changed

.github/workflows/cmake.yml

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
name: CMake
2+
3+
on:
4+
push:
5+
branches: [main]
6+
pull_request:
7+
branches: [main]
8+
workflow_dispatch:
9+
10+
env:
11+
# Customize the CMake build type here (Release, Debug, RelWithDebInfo, etc.)
12+
BUILD_TYPE: Release
13+
14+
jobs:
15+
build-ubuntu-22:
16+
# GitHub-hosted Ubuntu 22.04 runner
17+
runs-on: ubuntu-22.04
18+
# Use shared steps
19+
steps:
20+
- uses: actions/checkout@v3
21+
- uses: ./.github/workflows/shared_steps
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
name: "Shared Build Steps"
2+
runs:
3+
using: "composite"
4+
# Note: working directory will be reset to the repo root for each new step
5+
steps:
6+
# Build and install all dependencies to RDK installation directory.
7+
- name: Build and install dependencies
8+
shell: bash
9+
run: |
10+
pwd
11+
cd thirdparty
12+
bash build_and_install_dependencies.sh ~/sim_plugin_install 4
13+
14+
# Configure CMake, then build and install flexiv_rdk library to RDK installation directory.
15+
- name: Build and install library
16+
shell: bash
17+
run: |
18+
pwd
19+
mkdir -p build && cd build
20+
cmake .. -DCMAKE_INSTALL_PREFIX=~/sim_plugin_install
21+
cmake --build . --target install --config Release
22+
23+
# Find and link to flexiv_rdk library, then build all example programs.
24+
- name: Build examples
25+
shell: bash
26+
run: |
27+
pwd
28+
cd example
29+
mkdir -p build && cd build
30+
cmake .. -DCMAKE_PREFIX_PATH=~/sim_plugin_install
31+
cmake --build . --config Release -j 4

CMakeLists.txt

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
cmake_minimum_required(VERSION 3.16.3)
2+
3+
# ===================================================================
4+
# PROJECT SETUP
5+
# ===================================================================
6+
project(flexiv_sim_plugin VERSION 1.1.0)
7+
8+
# Configure build type
9+
if(NOT CMAKE_BUILD_TYPE)
10+
set(CMAKE_BUILD_TYPE Release CACHE STRING "CMake build type" FORCE)
11+
endif()
12+
set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS "Release" "Debug" "RelWithDebInfo")
13+
14+
# Set static library according to platform
15+
message(STATUS "OS: ${CMAKE_SYSTEM_NAME}")
16+
message(STATUS "Processor: ${CMAKE_SYSTEM_PROCESSOR}")
17+
if(${CMAKE_SYSTEM_NAME} MATCHES "Linux")
18+
if(${CMAKE_SYSTEM_PROCESSOR} MATCHES "x86_64")
19+
set(SIM_PLUGIN_STATIC_LIB "libflexiv_sim_plugin.x86_64-linux-gnu.a")
20+
else()
21+
message(FATAL_ERROR "Linux with ${CMAKE_SYSTEM_PROCESSOR} processor is currently not supported.")
22+
endif()
23+
elseif(${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
24+
message(FATAL_ERROR "macOS is currently not supported.")
25+
elseif(${CMAKE_SYSTEM_NAME} MATCHES "Windows")
26+
message(FATAL_ERROR "Windows is currently not supported.")
27+
endif()
28+
29+
# ===================================================================
30+
# PROJECT DEPENDENCIES
31+
# ===================================================================
32+
# Threads
33+
set(THREADS_PREFER_PTHREAD_FLAG ON)
34+
find_package(Threads REQUIRED)
35+
if(Threads_FOUND)
36+
message(STATUS "Found Threads: HAVE_PTHREAD = ${THREADS_HAVE_PTHREAD_ARG}")
37+
endif()
38+
39+
# spdlog
40+
find_package(spdlog REQUIRED)
41+
if(spdlog_FOUND)
42+
message(STATUS "Found spdlog: ${spdlog_DIR}")
43+
endif()
44+
45+
# Fast-DDS (Fast-RTPS)
46+
find_package(fastrtps 2.6.7 REQUIRED)
47+
if(fastrtps_FOUND)
48+
message(STATUS "Found fastrtps: ${fastrtps_DIR}")
49+
endif()
50+
51+
# ===================================================================
52+
# CREATE LIBRARY
53+
# ===================================================================
54+
# Create an INTERFACE library with no source file to compile
55+
add_library(${PROJECT_NAME} INTERFACE)
56+
57+
# Create an alias of the library using flexiv namespace,
58+
# to imitate the install target which uses flexiv namespace.
59+
add_library(flexiv::${PROJECT_NAME} ALIAS ${PROJECT_NAME})
60+
61+
target_include_directories(${PROJECT_NAME} INTERFACE
62+
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
63+
$<INSTALL_INTERFACE:include>
64+
)
65+
66+
target_link_libraries(${PROJECT_NAME} INTERFACE
67+
${CMAKE_CURRENT_SOURCE_DIR}/lib/${SIM_PLUGIN_STATIC_LIB}
68+
Threads::Threads
69+
spdlog::spdlog
70+
fastrtps
71+
)
72+
73+
# Use moderate compiler warning option
74+
if(CMAKE_HOST_UNIX)
75+
target_compile_options(${PROJECT_NAME} INTERFACE -Wall -Wextra)
76+
else()
77+
target_compile_options(${PROJECT_NAME} INTERFACE /W1)
78+
endif()
79+
80+
# Install the INTERFACE library
81+
include(${CMAKE_CURRENT_SOURCE_DIR}/cmake/FlexivInstallLibrary.cmake)
82+
FlexivInstallLibrary()

README.md

Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,108 @@ A middleware plugin to connect Flexiv Elements Studio to any external simulator
1111
| --------------------- | ------------ | -------------------- | ---------------------- |
1212
| Linux (Ubuntu 20.04+) | x86_64 | GCC v9.4+ | 3.8, 3.10, 3.12 |
1313

14+
## Tested External Simulators
15+
16+
The following external simulators are tested and known to work with Flexiv Sim Plugin:
17+
18+
- NVIDIA [Isaac Sim](https://developer.nvidia.com/isaac/sim) (a template workspace is available [here](https://github.com/flexivrobotics/isaac_sim_ws))
19+
- [MuJoCo](https://mujoco.org/)
20+
21+
In theory, any simulator that meets the following criteria should work:
22+
23+
1. Has a C++ or Python interface.
24+
2. Provides joint positions and velocities of the simulated robot.
25+
3. The joints of the simulated robot are actuated by torque.
26+
27+
## Flexiv Elements Studio Setup
28+
29+
### Install Elements Studio
30+
31+
1. Prepare a Ubuntu 22.04 computer, all operations below are done on this computer.
32+
2. [Contact Flexiv](https://www.flexiv.com/contact) to obtain the installation package of Elements Studio.
33+
3. Extract the package to a non-root directory.
34+
4. Install Elements Studio:
35+
36+
bash setup_FlexivElements.sh
37+
38+
5. Switch physics engine from the default built-in to external:
39+
40+
bash switch_physics_engine.sh
41+
42+
Select *External* or *Isaac Sim* when prompted.
43+
44+
### Create a simulated robot in Elements Studio
45+
46+
1. Start Flexiv Elements Studio from the application menu.
47+
2. In the Robot Connection window, select *Simulator*, and click *CREATE*.
48+
3. Choose "Create according to the selected robot type" and select one from the list, then click *CONFIRM*. A new simulated robot will be added to the simulator list.
49+
4. Toggle on the *Connect* button for the newly added one, then wait for loading.
50+
5. When loading is finished, you'll see a robot at its upright pose, with an "Exception" error at the bottom right corner. This is expected because the external simulator is not started yet. But if you see a normally operating robot, that again means you are running the wrong version of Elements Studio that only supports the built-in physics engine.
51+
6. At the bottom of the window, click on the small robot icon with a "SIM" tag on it, then a small window will pop up, note down the displayed robot serial number.
52+
7. In the same small pop-up window, click *CHANGE CONNECTION*, then toggle off the *Connect* button to close the simulated robot. We will restart it later. Note that you do NOT need to close the whole Elements Studio program.
53+
54+
## Quick Start - C++
55+
56+
### Prepare build tools
57+
58+
#### Linux
59+
60+
1. Install compiler kit using package manager:
61+
62+
sudo apt install build-essential
63+
64+
2. Install CMake using package manager:
65+
66+
sudo apt install cmake
67+
68+
### Install the C++ library
69+
70+
The following steps are identical on all supported platforms.
71+
72+
1. Choose a directory for installing the C++ library of Sim Plugin and its dependencies. This directory can be under system path or not, depending on whether you want Sim Plugin to be globally discoverable by CMake. For example, a new folder named ``sim_plugin_install`` under the home directory.
73+
2. In a new Terminal, run the provided script to compile and install all dependencies to the installation directory chosen in step 1:
74+
75+
cd flexiv_sim_plugin/thirdparty
76+
bash build_and_install_dependencies.sh ~/sim_plugin_install
77+
78+
3. In a new Terminal, configure the ``flexiv_sim_plugin`` CMake project:
79+
80+
cd flexiv_sim_plugin
81+
mkdir build && cd build
82+
cmake .. -DCMAKE_INSTALL_PREFIX=~/sim_plugin_install
83+
84+
NOTE: ``-D`` followed by ``CMAKE_INSTALL_PREFIX`` sets the absolute path of the installation directory, which should be the one chosen in step 1.
85+
86+
4. Install ``flexiv_sim_plugin`` C++ library to ``CMAKE_INSTALL_PREFIX`` path, which may or may not be globally discoverable by CMake:
87+
88+
cd flexiv_sim_plugin/build
89+
cmake --build . --target install --config Release
90+
91+
### Use the installed C++ library
92+
93+
After the library is installed as ``flexiv_sim_plugin`` CMake target, it can be linked from any other CMake projects. Using the provided `flexiv_sim_plugin-examples` project for instance:
94+
95+
cd flexiv_sim_plugin/example
96+
mkdir build && cd build
97+
cmake .. -DCMAKE_PREFIX_PATH=~/sim_plugin_install
98+
cmake --build . --config Release -j 4
99+
100+
NOTE: ``-D`` followed by ``CMAKE_PREFIX_PATH`` tells the user project's CMake where to find the installed C++ library. This argument can be skipped if the Sim Plugin library and its dependencies are installed to a globally discoverable location.
101+
102+
### Run the example C++ program
103+
104+
An example program that mocks an external simulator is provided and can be used to test the plugin with the following steps:
105+
106+
1. Start the mock program:
107+
108+
cd flexiv_sim_plugin/example/build
109+
./mock_external_simulator [robot_serial_number]
110+
111+
NOTE: the robot serial number provided to the program is the same one you noted down when creating the simulated robot in Flexiv Elements Studio.
112+
113+
2. Go back to Elements Studio, then restart the exited simulator by toggling ON the *Connect* button.
114+
3. Wait for the connection to establish. If the connection is successful, you should see the visualized robot in Elements Studio moving every joint back and forth. A software error should occur in Elements Studio which is expected because the mock external simulator did not close the loop by applying the calculated joint torques command to the simulated robot in it. This won't happen to real external simulators.
115+
14116
## Quick Start - Python
15117

16118
### Install the Python package
@@ -32,6 +134,19 @@ After the ``flexivsimplugin`` Python package is installed, it can be imported fr
32134

33135
The program should print some info messages and "Connected = False" at the end.
34136

137+
### Run the example Python script
138+
139+
An example script that mocks an external simulator is provided and can be used to test the plugin with the following steps:
140+
141+
1. Start the mock program:
142+
143+
cd flexiv_sim_plugin/example_py
144+
python3.x ./mock_external_simulator.py [robot_serial_number]
145+
146+
NOTE: the robot serial number provided to the program is the same one you noted down when creating the simulated robot in Flexiv Elements Studio.
147+
148+
2. The remaining steps are the same as documented in [Run the example C++ program](#run-the-example-c-program).
149+
35150
## API Documentation
36151

37152
The API documentation can be generated using Doxygen. For example, on Linux:

cmake/FlexivInstallLibrary.cmake

Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
# This macro will install ${PROJECT_NAME} to ${CMAKE_INSTALL_PREFIX} when running make install
2+
#
3+
# FlexivInstallLibrary() will install all subfolders of ${CMAKE_CURRENT_SOURCE_DIR}/include
4+
# FlexivInstallLibrary(install_directories) will install only the specified install_directories
5+
#
6+
# Requirements:
7+
# 1. project structure should resemble:
8+
# project
9+
# - README.md
10+
# - CMakeLists.txt that calls this macro
11+
# - cmake/${PROJECT_NAME}-config.cmake.in
12+
# - include/subfolder/*.h or *.hpp
13+
# 2. build the library using cmake target functions
14+
# - add_library(${PROJECT_NAME} ...) before calling this macro
15+
# - target_include_directories(${PROJECT_NAME} ...)
16+
# - target_link_libraries(${PROJECT_NAME} ...)
17+
# - target_compile_features(${PROJECT_NAME} ...)
18+
# - target_compile_options(${PROJECT_NAME} ...)
19+
#
20+
# Installed files:
21+
# - include/subfolder/*.h or *.hpp
22+
# - lib/lib{PROJECT_NAME}
23+
# - lib/cmake/{PROJECT_NAME}/
24+
25+
macro(FlexivInstallLibrary)
26+
# copy the executables and libraries to the CMAKE_INSTALL_PREFIX DIRECTORY
27+
# GNUInstallDirs will set CMAKE_INSTALL* to be the standard relative paths
28+
include(GNUInstallDirs)
29+
install(TARGETS ${PROJECT_NAME}
30+
EXPORT "${PROJECT_NAME}-targets"
31+
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
32+
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
33+
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
34+
)
35+
36+
if(${ARGC} EQUAL 0)
37+
# install all subfolders of ${CMAKE_CURRENT_SOURCE_DIR}/include
38+
file(GLOB install_directories ${CMAKE_CURRENT_SOURCE_DIR}/include/*)
39+
foreach(install_directory ${install_directories})
40+
if(IS_DIRECTORY ${install_directory})
41+
install(DIRECTORY ${install_directory}
42+
DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}
43+
FILES_MATCHING
44+
PATTERN "*.h"
45+
PATTERN "*.hpp"
46+
)
47+
endif()
48+
endforeach()
49+
elseif(${ARGC} EQUAL 1)
50+
# install specified directories only
51+
foreach(install_directory ${ARGV0})
52+
install(DIRECTORY ${install_directory}
53+
DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}
54+
FILES_MATCHING
55+
PATTERN "*.h"
56+
PATTERN "*.hpp"
57+
)
58+
endforeach()
59+
else()
60+
message(FATAL_ERROR "FlexivInstallLibrary take 0 or 1 argument, but given ${ARGC}")
61+
endif()
62+
63+
# Create a *config-version.cmake file so that find_package can have a version specified
64+
include(CMakePackageConfigHelpers)
65+
write_basic_package_version_file(
66+
"${PROJECT_NAME}-config-version.cmake"
67+
VERSION ${PROJECT_VERSION}
68+
COMPATIBILITY AnyNewerVersion
69+
)
70+
71+
# copy the *-targets.cmake file to the CMAKE_INSTALL_PREFIX directory
72+
install(EXPORT "${PROJECT_NAME}-targets"
73+
FILE "${PROJECT_NAME}-targets.cmake"
74+
NAMESPACE "flexiv::"
75+
DESTINATION "lib/cmake/${PROJECT_NAME}"
76+
)
77+
78+
# copy the *.-config file to the CMAKE_INSTALL_PREFIX directory. This will specify the dependencies.
79+
configure_file("${CMAKE_CURRENT_SOURCE_DIR}/cmake/${PROJECT_NAME}-config.cmake.in" "${PROJECT_NAME}-config.cmake" @ONLY)
80+
install(FILES "${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}-config.cmake"
81+
"${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}-config-version.cmake"
82+
DESTINATION "lib/cmake/${PROJECT_NAME}"
83+
)
84+
85+
# Use the CPack Package Generator
86+
set(CPACK_PACKAGE_VENDOR "Flexiv")
87+
set(CPACK_PACKAGE_CONTACT "[email protected]")
88+
set(CPACK_PACKAGE_DESCRIPTION "Flexiv Sim Plugin")
89+
set(CPACK_PACKAGE_VERSION_MAJOR ${PROJECT_VERSION_MAJOR})
90+
set(CPACK_PACKAGE_VERSION_MINOR ${PROJECT_VERSION_MINOR})
91+
set(CPACK_PACKAGE_VERSION_PATCH ${PROJECT_VERSION_PATCH})
92+
set(CPACK_RESOURCE_FILE_LICENSE "${CMAKE_CURRENT_SOURCE_DIR}/LICENSE")
93+
set(CPACK_RESOURCE_FILE_README "${CMAKE_CURRENT_SOURCE_DIR}/README.md")
94+
include(CPack)
95+
endmacro()
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
include(CMakeFindDependencyMacro)
2+
3+
# Find dependency
4+
set(THREADS_PREFER_PTHREAD_FLAG ON)
5+
find_dependency(Threads REQUIRED)
6+
find_dependency(spdlog REQUIRED)
7+
find_dependency(fastrtps 2.6.7 REQUIRED)
8+
9+
# Add targets file
10+
include("${CMAKE_CURRENT_LIST_DIR}/@[email protected]")

0 commit comments

Comments
 (0)