克隆下来必须带上正在用的视觉权重和本机 site.yaml,否则感知只能指到一台机器上的路径,别人起不来。
顶视迁臂改走厂家 MoveL,D405 框心对准后再对孔;夹爪停在 caught 时 open 不再把相同目标当成已经张开,init 会真的回零。 Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -0,0 +1,65 @@
|
||||
---
|
||||
Language: Proto
|
||||
BasedOnStyle: Google
|
||||
---
|
||||
Language: Cpp
|
||||
AccessModifierOffset: -4
|
||||
AlignAfterOpenBracket: false
|
||||
AlignConsecutiveAssignments: false
|
||||
AlignConsecutiveDeclarations: false
|
||||
AlignEscapedNewlinesLeft: false
|
||||
AlignOperands: true
|
||||
AlignTrailingComments: true
|
||||
AllowAllParametersOfDeclarationOnNextLine: false
|
||||
AllowShortBlocksOnASingleLine: false
|
||||
AllowShortCaseLabelsOnASingleLine: false
|
||||
AllowShortFunctionsOnASingleLine: Inline
|
||||
AllowShortIfStatementsOnASingleLine: false
|
||||
AllowShortLoopsOnASingleLine: false
|
||||
AlwaysBreakAfterDefinitionReturnType: None
|
||||
AlwaysBreakAfterReturnType: None
|
||||
AlwaysBreakBeforeMultilineStrings: true
|
||||
AlwaysBreakTemplateDeclarations: true
|
||||
BasedOnStyle: WebKit
|
||||
BinPackArguments: true
|
||||
BinPackParameters: true
|
||||
BreakBeforeBraces: Mozilla
|
||||
BreakBeforeTernaryOperators: true
|
||||
BreakConstructorInitializersBeforeComma: true
|
||||
ColumnLimit: 100
|
||||
CommentPragmas: "^ IWYU pragma:"
|
||||
ConstructorInitializerAllOnOneLineOrOnePerLine: false
|
||||
ConstructorInitializerIndentWidth: 0
|
||||
ContinuationIndentWidth: 4
|
||||
Cpp11BracedListStyle: true
|
||||
DerivePointerAlignment: false
|
||||
DisableFormat: false
|
||||
ExperimentalAutoDetectBinPacking: false
|
||||
ForEachMacros: [foreach, Q_FOREACH, BOOST_FOREACH]
|
||||
IndentCaseLabels: true
|
||||
IndentWidth: 4
|
||||
IndentWrappedFunctionNames: false
|
||||
KeepEmptyLinesAtTheStartOfBlocks: true
|
||||
MacroBlockBegin: ""
|
||||
MacroBlockEnd: ""
|
||||
MaxEmptyLinesToKeep: 1
|
||||
NamespaceIndentation: None
|
||||
PenaltyBreakBeforeFirstCallParameter: 100
|
||||
PenaltyBreakComment: 300
|
||||
PenaltyBreakFirstLessLess: 120
|
||||
PenaltyBreakString: 1000
|
||||
PenaltyExcessCharacter: 10000
|
||||
PointerAlignment: Left
|
||||
ReflowComments: true
|
||||
SortIncludes: false
|
||||
SpaceAfterCStyleCast: false
|
||||
SpaceBeforeAssignmentOperators: true
|
||||
SpaceBeforeParens: ControlStatements
|
||||
SpaceInEmptyParentheses: false
|
||||
SpacesInContainerLiterals: true
|
||||
SpacesInCStyleCastParentheses: false
|
||||
SpacesInParentheses: false
|
||||
SpacesInSquareBrackets: false
|
||||
Standard: Cpp11
|
||||
TabWidth: 4
|
||||
UseTab: Never
|
||||
@@ -0,0 +1,38 @@
|
||||
---
|
||||
name: Bug Report
|
||||
about: Report a bug to help us improve
|
||||
title: "[BUG] "
|
||||
type: Bug
|
||||
labels: bug
|
||||
assignees: bsoe-flexiv
|
||||
|
||||
---
|
||||
|
||||
## Version info
|
||||
|
||||
- Sim Plugin: [e.g. v1.2]
|
||||
- OS: [e.g. Ubuntu 22.04, x86_64]
|
||||
|
||||
## How urgent is this bug? Have you found any workarounds?
|
||||
|
||||
On a scale of 1 to 10.
|
||||
|
||||
## Describe the issue and expected behavior
|
||||
|
||||
The issue is ...
|
||||
The correct behavior you expect is ...
|
||||
|
||||
## Steps to reproduce
|
||||
|
||||
1. '....'
|
||||
2. '....'
|
||||
3. '....'
|
||||
4. See error
|
||||
|
||||
## Screenshots
|
||||
|
||||
If applicable, add screenshots to help explain your issue.
|
||||
|
||||
## Additional context
|
||||
|
||||
Add any other context about the issue.
|
||||
+29
@@ -0,0 +1,29 @@
|
||||
---
|
||||
name: Feature Request
|
||||
about: Suggest a new feature
|
||||
title: "[FEATURE] "
|
||||
type: Feature
|
||||
labels: enhancement
|
||||
assignees: bsoe-flexiv
|
||||
|
||||
---
|
||||
|
||||
## How urgent is this feature?
|
||||
|
||||
On a scale of 1 to 10.
|
||||
|
||||
## Is this feature related to a problem?
|
||||
|
||||
This new feature is needed so that ... can be solved.
|
||||
|
||||
## Describe the solution you'd like
|
||||
|
||||
What you want to happen.
|
||||
|
||||
## Describe alternatives you've considered
|
||||
|
||||
Any alternative solutions or workarounds you've considered.
|
||||
|
||||
## Additional context
|
||||
|
||||
Add any other context or screenshots about this feature.
|
||||
@@ -0,0 +1,25 @@
|
||||
---
|
||||
name: Question
|
||||
about: Ask a question related to Sim Plugin
|
||||
title: "[QUESTION] "
|
||||
type: Question
|
||||
labels: help wanted
|
||||
assignees: bsoe-flexiv
|
||||
|
||||
---
|
||||
|
||||
## There might already be an answer to your question
|
||||
|
||||
Someone might have asked similar questions before, you can search in the [Issues](https://github.com/flexivrobotics/flexiv_sim_plugin/issues?q=type%3AQuestion) tab.
|
||||
|
||||
## Not sure how to get started?
|
||||
|
||||
You can take a look at [Isaac Sim Workspace](https://github.com/flexivrobotics/isaac_sim_ws) which uses this plugin to build the simulation workflow.
|
||||
|
||||
## Is this related to a specific version of Sim Plugin?
|
||||
|
||||
If yes, please specify.
|
||||
|
||||
## Please describe your question
|
||||
|
||||
Texts, screenshots, links, code blocks ...
|
||||
@@ -0,0 +1,21 @@
|
||||
name: CMake
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [main]
|
||||
pull_request:
|
||||
branches: [main]
|
||||
workflow_dispatch:
|
||||
|
||||
env:
|
||||
# Customize the CMake build type here (Release, Debug, RelWithDebInfo, etc.)
|
||||
BUILD_TYPE: Release
|
||||
|
||||
jobs:
|
||||
build-ubuntu-22:
|
||||
# GitHub-hosted Ubuntu 22.04 runner
|
||||
runs-on: ubuntu-22.04
|
||||
# Use shared steps
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: ./.github/workflows/shared_steps
|
||||
+31
@@ -0,0 +1,31 @@
|
||||
name: "Shared Build Steps"
|
||||
runs:
|
||||
using: "composite"
|
||||
# Note: working directory will be reset to the repo root for each new step
|
||||
steps:
|
||||
# Build and install all dependencies to RDK installation directory.
|
||||
- name: Build and install dependencies
|
||||
shell: bash
|
||||
run: |
|
||||
pwd
|
||||
cd thirdparty
|
||||
bash build_and_install_dependencies.sh ~/sim_plugin_install 4
|
||||
|
||||
# Configure CMake, then build and install flexiv_rdk library to RDK installation directory.
|
||||
- name: Build and install library
|
||||
shell: bash
|
||||
run: |
|
||||
pwd
|
||||
mkdir -p build && cd build
|
||||
cmake .. -DCMAKE_INSTALL_PREFIX=~/sim_plugin_install
|
||||
cmake --build . --target install --config Release
|
||||
|
||||
# Find and link to flexiv_rdk library, then build all example programs.
|
||||
- name: Build examples
|
||||
shell: bash
|
||||
run: |
|
||||
pwd
|
||||
cd example
|
||||
mkdir -p build && cd build
|
||||
cmake .. -DCMAKE_PREFIX_PATH=~/sim_plugin_install
|
||||
cmake --build . --config Release -j 4
|
||||
@@ -0,0 +1,14 @@
|
||||
.vscode
|
||||
.vs
|
||||
.DS_Store
|
||||
config.h
|
||||
build*/
|
||||
install/
|
||||
cloned/
|
||||
html/
|
||||
__pycache__
|
||||
|
||||
# Pre-built static libraries are attached to GitHub releases as assets, not
|
||||
# committed. Only the .sha256 checksum is tracked; the .a is downloaded by
|
||||
# CMake at configure time.
|
||||
lib/*.a
|
||||
@@ -0,0 +1,100 @@
|
||||
cmake_minimum_required(VERSION 3.16.3)
|
||||
|
||||
# ===================================================================
|
||||
# PROJECT SETUP
|
||||
# ===================================================================
|
||||
project(flexiv_sim_plugin VERSION 1.3.0)
|
||||
|
||||
# Configure build type
|
||||
if(NOT CMAKE_BUILD_TYPE)
|
||||
set(CMAKE_BUILD_TYPE Release CACHE STRING "CMake build type" FORCE)
|
||||
endif()
|
||||
set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS "Release" "Debug" "RelWithDebInfo" "MinSizeRel")
|
||||
|
||||
# Set static library according to platform
|
||||
message(STATUS "OS: ${CMAKE_SYSTEM_NAME}")
|
||||
message(STATUS "Processor: ${CMAKE_SYSTEM_PROCESSOR}")
|
||||
if(${CMAKE_SYSTEM_NAME} MATCHES "Linux")
|
||||
if(${CMAKE_SYSTEM_PROCESSOR} MATCHES "x86_64")
|
||||
set(SIM_PLUGIN_LIB "libflexiv_sim_plugin.x86_64-linux-gnu.a")
|
||||
else()
|
||||
message(FATAL_ERROR "Linux with ${CMAKE_SYSTEM_PROCESSOR} processor is currently not supported.")
|
||||
endif()
|
||||
elseif(${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
|
||||
message(FATAL_ERROR "macOS is currently not supported.")
|
||||
elseif(${CMAKE_SYSTEM_NAME} MATCHES "Windows")
|
||||
message(FATAL_ERROR "Windows is currently not supported.")
|
||||
endif()
|
||||
|
||||
# Download the pre-built static library from the matching GitHub release and
|
||||
# verify it against the committed checksum. The .a itself is not tracked in
|
||||
# this repo, only lib/${SIM_PLUGIN_LIB}.sha256.
|
||||
file(READ ${CMAKE_CURRENT_SOURCE_DIR}/lib/${SIM_PLUGIN_LIB}.sha256 EXPECTED_HASH)
|
||||
set(SIM_PLUGIN_LIB_URL https://github.com/flexivrobotics/flexiv_sim_plugin/releases/download/v${PROJECT_VERSION}/${SIM_PLUGIN_LIB})
|
||||
set(SIM_PLUGIN_LIB_PATH ${CMAKE_CURRENT_BINARY_DIR}/${SIM_PLUGIN_LIB})
|
||||
message(STATUS "Downloading ${SIM_PLUGIN_LIB_URL} ...")
|
||||
file(DOWNLOAD ${SIM_PLUGIN_LIB_URL} ${SIM_PLUGIN_LIB_PATH}
|
||||
SHOW_PROGRESS
|
||||
TLS_VERIFY ON
|
||||
EXPECTED_HASH SHA256=${EXPECTED_HASH}
|
||||
STATUS status)
|
||||
list(GET status 0 code)
|
||||
if(code EQUAL 0)
|
||||
message(STATUS "Download finished")
|
||||
else()
|
||||
message(FATAL_ERROR "Download failed: ${status}")
|
||||
endif()
|
||||
|
||||
# ===================================================================
|
||||
# PROJECT DEPENDENCIES
|
||||
# ===================================================================
|
||||
# Threads
|
||||
set(THREADS_PREFER_PTHREAD_FLAG ON)
|
||||
find_package(Threads REQUIRED)
|
||||
message(STATUS "Found Threads")
|
||||
|
||||
# spdlog
|
||||
find_package(spdlog REQUIRED)
|
||||
message(STATUS "Found spdlog v${spdlog_VERSION}: ${spdlog_DIR}")
|
||||
|
||||
# Fast-DDS (Fast-RTPS)
|
||||
find_package(fastrtps REQUIRED)
|
||||
message(STATUS "Found fastrtps v${fastrtps_VERSION}: ${fastrtps_DIR}")
|
||||
|
||||
# Fast-CDR
|
||||
find_package(fastcdr REQUIRED)
|
||||
message(STATUS "Found fastcdr v${fastcdr_VERSION}: ${fastcdr_DIR}")
|
||||
|
||||
# ===================================================================
|
||||
# CREATE LIBRARY
|
||||
# ===================================================================
|
||||
# Create static library target with dummy source
|
||||
add_library(${PROJECT_NAME} STATIC ${CMAKE_CURRENT_SOURCE_DIR}/lib/dummy.cpp)
|
||||
|
||||
# Create an alias of the target with flexiv namespace
|
||||
add_library(flexiv::${PROJECT_NAME} ALIAS ${PROJECT_NAME})
|
||||
|
||||
# Set include directories
|
||||
target_include_directories(${PROJECT_NAME} PUBLIC
|
||||
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
|
||||
$<INSTALL_INTERFACE:include>
|
||||
)
|
||||
|
||||
# Link to dependencies
|
||||
target_link_libraries(${PROJECT_NAME} PUBLIC
|
||||
Threads::Threads
|
||||
spdlog::spdlog
|
||||
fastrtps
|
||||
fastcdr
|
||||
)
|
||||
|
||||
# Use moderate compiler warning option
|
||||
if(CMAKE_HOST_UNIX)
|
||||
target_compile_options(${PROJECT_NAME} PUBLIC -Wall -Wextra)
|
||||
else()
|
||||
target_compile_options(${PROJECT_NAME} PUBLIC /W1)
|
||||
endif()
|
||||
|
||||
# Install the library
|
||||
include(${CMAKE_CURRENT_SOURCE_DIR}/cmake/FlexivInstallLibrary.cmake)
|
||||
FlexivInstallLibrary()
|
||||
+201
@@ -0,0 +1,201 @@
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
To apply the Apache License to your work, attach the following
|
||||
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||
replaced with your own identifying information. (Don't include
|
||||
the brackets!) The text should be enclosed in the appropriate
|
||||
comment syntax for the file format. We also recommend that a
|
||||
file or class name and description of purpose be included on the
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright [yyyy] [name of copyright owner]
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
+162
@@ -0,0 +1,162 @@
|
||||
# Flexiv Sim Plugin
|
||||
|
||||

|
||||
[](https://www.apache.org/licenses/LICENSE-2.0.html)
|
||||
|
||||
|
||||
## Overview
|
||||
|
||||
Flexiv Sim Plugin is a C++/Python library that bridges **Flexiv Elements Studio** and any external physics simulator, so that simulated Flexiv robots are driven by the same high-performance force-torque controller used on real robots — without requiring you to deal with the underlying IPC.
|
||||
|
||||
```
|
||||
┌──────────────────────────────────────────┐
|
||||
│ User Program with RDK Client │
|
||||
│ (send robot commands) │
|
||||
└────────────────────┬─────────────────────┘
|
||||
│ RDK API
|
||||
▼
|
||||
┌──────────────────────────────────────────┐
|
||||
│ Flexiv Elements Studio │
|
||||
│ (simulated controller + RDK Server) │
|
||||
└────────────────────┬─────────────────────┘
|
||||
│ Flexiv Sim Plugin API
|
||||
▼
|
||||
┌────────────────────────────────────────────┐
|
||||
│ External Simulator |
|
||||
│ (Flexiv Sim Plugin API + External sim API) │
|
||||
└────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
## Supported External Simulators
|
||||
|
||||
The following external simulators are tested and known to work with Flexiv Sim Plugin:
|
||||
|
||||
- NVIDIA [Isaac Sim](https://developer.nvidia.com/isaac/sim) (a template workspace is available [here](https://github.com/flexivrobotics/isaac_sim_ws))
|
||||
- [MuJoCo](https://mujoco.org/)
|
||||
|
||||
In theory, any simulator that meets the following criteria should work:
|
||||
|
||||
1. Has a C++ or Python interface.
|
||||
2. Provides joint positions and velocities of the simulated robot.
|
||||
3. Actuates the joints of the simulated robot by torque.
|
||||
|
||||
|
||||
## Environment Compatibility
|
||||
|
||||
| **OS** | **Platform** | **C++ compiler kit** | **Python interpreter** |
|
||||
| --------------------- | ------------ | -------------------- | ---------------------- |
|
||||
| Linux (Ubuntu 20.04+) | x86_64 | GCC v9.4+ | 3.10, 3.12, 3.14 |
|
||||
|
||||
|
||||
## Quick Start - Python
|
||||
|
||||
### Install the Python package
|
||||
|
||||
On all supported platforms, the Python package of Sim Plugin for a specific Python version can be installed using the `pip` module:
|
||||
|
||||
python3 -m pip install flexivsimplugin
|
||||
|
||||
NOTE: replace python3 with a specific version (e.g. python3.10) if your default python3 is not one of the versions listed in the table above.
|
||||
|
||||
### Use the installed Python package
|
||||
|
||||
After the ``flexivsimplugin`` Python package is installed, it can be imported from any Python script. Test with the following commands in a new Terminal, which should start Flexiv Sim Plugin:
|
||||
|
||||
python3
|
||||
import flexivsimplugin
|
||||
node = flexivsimplugin.UserNode("Rizon4-123456")
|
||||
print("Connected = ", node.connected())
|
||||
|
||||
The program should print some info messages and "Connected = False" at the end.
|
||||
|
||||
### Run the example Python script
|
||||
|
||||
An example script that mocks an external simulator is provided and can be used to test the plugin with the following steps:
|
||||
|
||||
1. Setup and run Flexiv Elements Studio simulation. See [docs/elements_studio_setup.md](docs/elements_studio_setup.md).
|
||||
|
||||
2. Start the mock program:
|
||||
|
||||
cd flexiv_sim_plugin/example_py
|
||||
python3 -m pip install spdlog
|
||||
python3 ./mock_external_simulator.py [robot_serial_number]
|
||||
|
||||
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.
|
||||
|
||||
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. NOTE: 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.
|
||||
|
||||
|
||||
## Quick Start - C++
|
||||
|
||||
### Prepare build tools
|
||||
|
||||
#### Linux
|
||||
|
||||
1. Install compiler kit using package manager:
|
||||
|
||||
sudo apt install build-essential
|
||||
|
||||
2. Install CMake using package manager:
|
||||
|
||||
sudo apt install cmake
|
||||
|
||||
### Install the C++ library
|
||||
|
||||
The following steps are identical on all supported platforms.
|
||||
|
||||
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.
|
||||
|
||||
2. In a new Terminal, run the provided script to compile and install all dependencies to the installation directory chosen in step 1:
|
||||
|
||||
cd flexiv_sim_plugin/thirdparty
|
||||
bash build_and_install_dependencies.sh ~/sim_plugin_install
|
||||
|
||||
3. In a new Terminal, configure the ``flexiv_sim_plugin`` CMake project:
|
||||
|
||||
cd flexiv_sim_plugin
|
||||
mkdir build && cd build
|
||||
cmake .. -DCMAKE_INSTALL_PREFIX=~/sim_plugin_install
|
||||
|
||||
NOTE: ``-D`` followed by ``CMAKE_INSTALL_PREFIX`` sets the absolute path of the installation directory, which should be the one chosen in step 1.
|
||||
|
||||
4. Install ``flexiv_sim_plugin`` C++ library to ``CMAKE_INSTALL_PREFIX`` path, which may or may not be globally discoverable by CMake:
|
||||
|
||||
cd flexiv_sim_plugin/build
|
||||
cmake --build . --target install --config Release
|
||||
|
||||
### Use the installed C++ library
|
||||
|
||||
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:
|
||||
|
||||
cd flexiv_sim_plugin/example
|
||||
mkdir build && cd build
|
||||
cmake .. -DCMAKE_PREFIX_PATH=~/sim_plugin_install
|
||||
cmake --build . --config Release -j 4
|
||||
|
||||
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.
|
||||
|
||||
### Run the example C++ program
|
||||
|
||||
An example program that mocks an external simulator is provided and can be used to test the plugin with the following steps:
|
||||
|
||||
1. Setup and run Flexiv Elements Studio simulation. See [docs/elements_studio_setup.md](docs/elements_studio_setup.md).
|
||||
|
||||
2. Start the mock program:
|
||||
|
||||
cd flexiv_sim_plugin/example/build
|
||||
./mock_external_simulator [robot_serial_number]
|
||||
|
||||
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.
|
||||
|
||||
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. NOTE: 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.
|
||||
|
||||
## API Documentation
|
||||
|
||||
The API documentation can be generated using Doxygen. For example, on Linux:
|
||||
|
||||
sudo apt install doxygen-latex graphviz
|
||||
cd flexiv_sim_plugin
|
||||
doxygen doc/Doxyfile.in
|
||||
|
||||
Open any html file under ``flexiv_sim_plugin/doc/html/`` with your browser to view the doc.
|
||||
|
||||
@@ -0,0 +1,103 @@
|
||||
# This macro will install ${PROJECT_NAME} to ${CMAKE_INSTALL_PREFIX} when running make install
|
||||
#
|
||||
# FlexivInstallLibrary() will install all subfolders of ${CMAKE_CURRENT_SOURCE_DIR}/include
|
||||
# FlexivInstallLibrary(install_directories) will install only the specified install_directories
|
||||
#
|
||||
# Requirements:
|
||||
# 1. project structure should resemble:
|
||||
# project
|
||||
# - README.md
|
||||
# - CMakeLists.txt that calls this macro
|
||||
# - cmake/${PROJECT_NAME}-config.cmake.in
|
||||
# - include/subfolder/*.h or *.hpp
|
||||
# 2. build the library using cmake target functions
|
||||
# - add_library(${PROJECT_NAME} ...) before calling this macro
|
||||
# - target_include_directories(${PROJECT_NAME} ...)
|
||||
# - target_link_libraries(${PROJECT_NAME} ...)
|
||||
# - target_compile_features(${PROJECT_NAME} ...)
|
||||
# - target_compile_options(${PROJECT_NAME} ...)
|
||||
#
|
||||
# Installed files:
|
||||
# - include/subfolder/*.h or *.hpp
|
||||
# - lib/lib{PROJECT_NAME}
|
||||
# - lib/cmake/{PROJECT_NAME}/
|
||||
|
||||
macro(FlexivInstallLibrary)
|
||||
# copy the executables and libraries to the CMAKE_INSTALL_PREFIX DIRECTORY
|
||||
# GNUInstallDirs will set CMAKE_INSTALL* to be the standard relative paths
|
||||
include(GNUInstallDirs)
|
||||
install(TARGETS ${PROJECT_NAME}
|
||||
EXPORT "${PROJECT_NAME}-targets"
|
||||
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
|
||||
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
|
||||
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
|
||||
)
|
||||
|
||||
if(${ARGC} EQUAL 0)
|
||||
# install all subfolders of ${CMAKE_CURRENT_SOURCE_DIR}/include
|
||||
file(GLOB install_directories ${CMAKE_CURRENT_SOURCE_DIR}/include/*)
|
||||
foreach(install_directory ${install_directories})
|
||||
if(IS_DIRECTORY ${install_directory})
|
||||
install(DIRECTORY ${install_directory}
|
||||
DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}
|
||||
FILES_MATCHING
|
||||
PATTERN "*.h"
|
||||
PATTERN "*.hpp"
|
||||
)
|
||||
endif()
|
||||
endforeach()
|
||||
elseif(${ARGC} EQUAL 1)
|
||||
# install specified directories only
|
||||
foreach(install_directory ${ARGV0})
|
||||
install(DIRECTORY ${install_directory}
|
||||
DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}
|
||||
FILES_MATCHING
|
||||
PATTERN "*.h"
|
||||
PATTERN "*.hpp"
|
||||
)
|
||||
endforeach()
|
||||
else()
|
||||
message(FATAL_ERROR "FlexivInstallLibrary take 0 or 1 argument, but given ${ARGC}")
|
||||
endif()
|
||||
|
||||
# Create a *config-version.cmake file so that find_package can have a version specified
|
||||
include(CMakePackageConfigHelpers)
|
||||
write_basic_package_version_file(
|
||||
"${PROJECT_NAME}-config-version.cmake"
|
||||
VERSION ${PROJECT_VERSION}
|
||||
COMPATIBILITY AnyNewerVersion
|
||||
)
|
||||
|
||||
# Copy the *-targets.cmake file to the CMAKE_INSTALL_PREFIX directory
|
||||
install(EXPORT "${PROJECT_NAME}-targets"
|
||||
FILE "${PROJECT_NAME}-targets.cmake"
|
||||
NAMESPACE "flexiv::"
|
||||
DESTINATION "lib/cmake/${PROJECT_NAME}"
|
||||
)
|
||||
|
||||
# Copy the *.-config file to the CMAKE_INSTALL_PREFIX directory. This will specify the dependencies.
|
||||
configure_file("${CMAKE_CURRENT_SOURCE_DIR}/cmake/${PROJECT_NAME}-config.cmake.in" "${PROJECT_NAME}-config.cmake" @ONLY)
|
||||
install(FILES "${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}-config.cmake"
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}-config-version.cmake"
|
||||
DESTINATION "lib/cmake/${PROJECT_NAME}"
|
||||
)
|
||||
|
||||
# Replace the dummy static lib with the actual static lib
|
||||
install(CODE
|
||||
"file(REMOVE ${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR}/${CMAKE_STATIC_LIBRARY_PREFIX}${PROJECT_NAME}${CMAKE_STATIC_LIBRARY_SUFFIX})")
|
||||
install(FILES ${SIM_PLUGIN_LIB_PATH}
|
||||
DESTINATION ${CMAKE_INSTALL_LIBDIR}
|
||||
RENAME ${CMAKE_STATIC_LIBRARY_PREFIX}${PROJECT_NAME}${CMAKE_STATIC_LIBRARY_SUFFIX}
|
||||
)
|
||||
|
||||
# Use the CPack Package Generator
|
||||
set(CPACK_PACKAGE_VENDOR "Flexiv")
|
||||
set(CPACK_PACKAGE_CONTACT "support@flexiv.com")
|
||||
set(CPACK_PACKAGE_DESCRIPTION "Flexiv Sim Plugin")
|
||||
set(CPACK_PACKAGE_VERSION_MAJOR ${PROJECT_VERSION_MAJOR})
|
||||
set(CPACK_PACKAGE_VERSION_MINOR ${PROJECT_VERSION_MINOR})
|
||||
set(CPACK_PACKAGE_VERSION_PATCH ${PROJECT_VERSION_PATCH})
|
||||
set(CPACK_RESOURCE_FILE_LICENSE "${CMAKE_CURRENT_SOURCE_DIR}/LICENSE")
|
||||
set(CPACK_RESOURCE_FILE_README "${CMAKE_CURRENT_SOURCE_DIR}/README.md")
|
||||
include(CPack)
|
||||
endmacro()
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
include(CMakeFindDependencyMacro)
|
||||
|
||||
# Find dependency
|
||||
set(THREADS_PREFER_PTHREAD_FLAG ON)
|
||||
find_dependency(Threads REQUIRED)
|
||||
find_dependency(spdlog REQUIRED)
|
||||
find_dependency(fastrtps REQUIRED)
|
||||
find_dependency(fastcdr REQUIRED)
|
||||
|
||||
# Add targets file
|
||||
include("${CMAKE_CURRENT_LIST_DIR}/@PROJECT_NAME@-targets.cmake")
|
||||
+2666
File diff suppressed because it is too large
Load Diff
Binary file not shown.
|
After Width: | Height: | Size: 6.8 KiB |
@@ -0,0 +1,30 @@
|
||||
# Flexiv Elements Studio Setup
|
||||
|
||||
Flexiv Elements Studio runs the simulated robot controller.
|
||||
Set it up once before running any external-simulator workspace.
|
||||
|
||||
## Install Elements Studio on Ubuntu
|
||||
|
||||
1. [Contact Flexiv](https://www.flexiv.com/contact) to obtain the installation package of Elements Studio.
|
||||
2. Extract the package to a non-root directory.
|
||||
3. Install Elements Studio:
|
||||
|
||||
bash setup_FlexivElements.sh
|
||||
|
||||
4. Switch physics engine from the default built-in to external:
|
||||
|
||||
bash switch_physics_engine.sh
|
||||
|
||||
Select *External* when prompted.
|
||||
|
||||
## Create a simulated robot in Elements Studio
|
||||
|
||||
1. Start Flexiv Elements Studio from the application menu.
|
||||
2. In the Robot Connection window, select *Simulator*, and click *CREATE*.
|
||||
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.
|
||||
4. Toggle on the *Connect* button for the newly added one, then wait for loading.
|
||||
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.
|
||||
6. To enable RDK, Click Settings → Remote Mode → Select a Mode → Ethernet. In the resulting popup window, restart the simulated robot.
|
||||
7. Toggle the virtual motion bar slider button to the "auto" position. In the resulting popup window, select "AUTO (REMOTE)".
|
||||
8. 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.
|
||||
|
||||
@@ -0,0 +1,32 @@
|
||||
cmake_minimum_required(VERSION 3.16.3)
|
||||
project(flexiv_sim_plugin-examples)
|
||||
|
||||
# Show verbose build info
|
||||
SET(CMAKE_VERBOSE_MAKEFILE ON)
|
||||
|
||||
message("OS: ${CMAKE_SYSTEM_NAME}")
|
||||
message("Processor: ${CMAKE_SYSTEM_PROCESSOR}")
|
||||
|
||||
# Configure build type
|
||||
if(NOT CMAKE_BUILD_TYPE)
|
||||
set(CMAKE_BUILD_TYPE Release CACHE STRING "CMake build type" FORCE)
|
||||
endif()
|
||||
|
||||
# Minimum example list for all OS
|
||||
set(EXAMPLE_LIST
|
||||
mock_external_simulator
|
||||
)
|
||||
|
||||
# Find flexiv_sim_plugin INTERFACE library
|
||||
find_package(flexiv_sim_plugin REQUIRED)
|
||||
|
||||
# Build all selected examples
|
||||
foreach(example ${EXAMPLE_LIST})
|
||||
add_executable(${example} ${example}.cpp)
|
||||
target_link_libraries(${example} flexiv::flexiv_sim_plugin)
|
||||
|
||||
# C++17 required
|
||||
set_target_properties(${example} PROPERTIES
|
||||
CXX_STANDARD 17
|
||||
CXX_STANDARD_REQUIRED ON)
|
||||
endforeach()
|
||||
@@ -0,0 +1,135 @@
|
||||
/**
|
||||
* @example mock_external_simulator.cpp
|
||||
* A simple example demonstrating how to use Flexiv Sim Plugin in an external simulator. Please
|
||||
* refer to README on how to run this example.
|
||||
* @copyright Copyright (C) 2016-2025 Flexiv Ltd. All Rights Reserved.
|
||||
* @author Flexiv
|
||||
*/
|
||||
|
||||
#include <flexiv/sim_plugin/user_node.hpp>
|
||||
#include <spdlog/spdlog.h>
|
||||
|
||||
#include <math.h>
|
||||
#include <iostream>
|
||||
#include <iomanip>
|
||||
#include <thread>
|
||||
|
||||
using namespace flexiv;
|
||||
|
||||
namespace {
|
||||
// Frequency of the external simulator's physics loop [Hz]
|
||||
constexpr unsigned int kPhysicsFreq = 2000;
|
||||
// Period of the external simulator's physics loop [sec]
|
||||
constexpr double kPhysicsPeriod = 1.0 / kPhysicsFreq;
|
||||
|
||||
// Sine-sweep trajectory amplitude and frequency
|
||||
constexpr double kSineAmp = 0.035;
|
||||
constexpr double kSineFreq = 0.3;
|
||||
|
||||
// Initial joint positions when the robot is at home posture [rad]
|
||||
const std::vector<float> kInitQ = {0.0, -0.698132, 0.0, 1.5708, 0.0, 0.698132, 0.0};
|
||||
|
||||
// Joint degrees of freedom
|
||||
constexpr size_t kJointDof = 7;
|
||||
|
||||
// Servo cycle of the physics loop
|
||||
unsigned int g_servo_cycle = 0;
|
||||
}
|
||||
|
||||
/** @brief Print program usage help */
|
||||
void PrintHelp()
|
||||
{
|
||||
// clang-format off
|
||||
std::cout << "Required arguments: [robot_sn]" << std::endl;
|
||||
std::cout << " robot_sn: Serial number of the robot in Flexiv Elements Studio to connect. Remove any space, e.g. Rizon4s-123456" << std::endl;
|
||||
std::cout << "Optional arguments: None" << std::endl;
|
||||
std::cout << std::endl;
|
||||
// clang-format on
|
||||
}
|
||||
|
||||
/** @brief Step once the external simulator's physics loop. */
|
||||
void StepPhysics(sim_plugin::UserNode& user_node)
|
||||
{
|
||||
// Record time point at the beginning of this cycle
|
||||
auto current_time = std::chrono::steady_clock::now();
|
||||
|
||||
// Step 1: obtain robot states from the external simulator
|
||||
// =============================================================================================
|
||||
// Mocked robot states
|
||||
sim_plugin::SimRobotStates robot_states;
|
||||
robot_states.q.resize(kJointDof);
|
||||
robot_states.dq.resize(kJointDof);
|
||||
|
||||
// Set and increment servo cycle per physics step
|
||||
robot_states.servo_cycle = g_servo_cycle++;
|
||||
|
||||
// Set joint positions to sine waves
|
||||
for (size_t i = 0; i < kInitQ.size(); i++) {
|
||||
robot_states.q[i]
|
||||
= kInitQ[i] + kSineAmp * sin(2 * M_PI * kSineFreq * g_servo_cycle * kPhysicsPeriod);
|
||||
}
|
||||
|
||||
// Set joint velocities to corresponding cosine waves
|
||||
for (size_t i = 0; i < kInitQ.size(); i++) {
|
||||
robot_states.dq[i] = kSineAmp * 2 * M_PI * kSineFreq
|
||||
* cos(2 * M_PI * kSineFreq * g_servo_cycle * kPhysicsPeriod);
|
||||
}
|
||||
|
||||
// Step 2: send robot states to Flexiv Elements Studio
|
||||
// =============================================================================================
|
||||
if (!user_node.SendRobotStates(robot_states)) {
|
||||
spdlog::error("Failed to send robot states data");
|
||||
}
|
||||
|
||||
// Step 3: wait for Elements Studio to calculate and deliver new robot commands
|
||||
// =============================================================================================
|
||||
// Must set a timeout value to avoid deadlock
|
||||
constexpr unsigned int kWaitTimeoutMs = 100;
|
||||
if (!user_node.WaitForRobotCommands(kWaitTimeoutMs)) {
|
||||
spdlog::error("WaitForRobotCommands() timeout");
|
||||
}
|
||||
|
||||
// Step 4: apply joint torques command to the simulated robot in the external simulator
|
||||
// =============================================================================================
|
||||
auto target_joint_torques = user_node.robot_commands().target_drives;
|
||||
// Call the external simulator's API to apply the target joint torques
|
||||
|
||||
// End the current physics step with kPhysicsPeriod as the total loop period
|
||||
auto loop_period_us = static_cast<unsigned int>(kPhysicsPeriod * 1'000'000);
|
||||
std::this_thread::sleep_until(current_time + std::chrono::microseconds(loop_period_us));
|
||||
}
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
// Program Setup
|
||||
// =============================================================================================
|
||||
// Parse parameters
|
||||
if (argc < 2) {
|
||||
PrintHelp();
|
||||
return 1;
|
||||
}
|
||||
// Serial number of the robot to connect to. Remove any space, for example: Rizon4s-123456
|
||||
std::string robot_sn = argv[1];
|
||||
|
||||
// Print description
|
||||
spdlog::info(
|
||||
">>> Tutorial description <<<\nA simple example demonstrating how to use Flexiv Sim Plugin "
|
||||
"in an external simulator.\n");
|
||||
|
||||
// Create user node
|
||||
sim_plugin::UserNode user_node(robot_sn);
|
||||
|
||||
// Wait for connected
|
||||
while (!user_node.connected()) {
|
||||
spdlog::warn("Waiting for connection with Flexiv Elements Studio");
|
||||
std::this_thread::sleep_for(std::chrono::seconds(1));
|
||||
}
|
||||
spdlog::info("Connected with Flexiv Elements Studio, starting mocked physics loop");
|
||||
|
||||
// Run mocked physics loop
|
||||
while (user_node.connected()) {
|
||||
StepPhysics(user_node);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
+130
@@ -0,0 +1,130 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
"""mock_external_simulator.py
|
||||
|
||||
A simple example demonstrating how to use Flexiv Sim Plugin in an external simulator. Please
|
||||
refer to README on how to run this example.
|
||||
"""
|
||||
|
||||
__copyright__ = "Copyright (C) 2016-2025 Flexiv Ltd. All Rights Reserved."
|
||||
__author__ = "Flexiv"
|
||||
|
||||
import time
|
||||
import math
|
||||
import argparse
|
||||
import spdlog # pip install
|
||||
import flexivsimplugin # pip install
|
||||
|
||||
# Frequency of the external simulator's physics loop [Hz]
|
||||
PHYSICS_FREQ = 2000
|
||||
# Period of the external simulator's physics loop [sec]
|
||||
PHYSICS_PERIOD = 1.0 / PHYSICS_FREQ
|
||||
|
||||
# Sine-sweep trajectory amplitude and frequency
|
||||
SINE_AMP = 0.035
|
||||
SINE_FREQ = 0.3
|
||||
|
||||
# Initial joint positions when the robot is at home posture [rad]
|
||||
INIT_Q = [0.0, -0.698132, 0.0, 1.5708, 0.0, 0.698132, 0.0]
|
||||
|
||||
# Joint degrees of freedom
|
||||
JOINT_DOF = 7
|
||||
|
||||
# Servo cycle of the physics loop
|
||||
g_servo_cycle = 0
|
||||
|
||||
|
||||
def step_physics(user_node, logger):
|
||||
"""
|
||||
Step once the external simulator's physics loop.
|
||||
|
||||
"""
|
||||
|
||||
# Step 1: obtain robot states from the external simulator
|
||||
# =============================================================================================
|
||||
# Mocked robot states
|
||||
robot_states = flexivsimplugin.SimRobotStates()
|
||||
|
||||
# Set and increment servo cycle per physics step
|
||||
global g_servo_cycle
|
||||
g_servo_cycle += 1
|
||||
robot_states.servo_cycle = g_servo_cycle
|
||||
|
||||
# robot_states.q and dq are fixed-size tuples and don't support per-element assignment
|
||||
temp_list = [0] * JOINT_DOF
|
||||
|
||||
# Set joint positions to sine waves
|
||||
for i in range(JOINT_DOF):
|
||||
temp_list[i] = INIT_Q[i] + SINE_AMP * math.sin(
|
||||
2 * math.pi * SINE_FREQ * g_servo_cycle * PHYSICS_PERIOD
|
||||
)
|
||||
robot_states.q = temp_list
|
||||
|
||||
# Set joint velocities to corresponding cosine waves
|
||||
for i in range(JOINT_DOF):
|
||||
temp_list[i] = (
|
||||
SINE_AMP
|
||||
* 2
|
||||
* math.pi
|
||||
* SINE_FREQ
|
||||
* math.cos(2 * math.pi * SINE_FREQ * g_servo_cycle * PHYSICS_PERIOD)
|
||||
)
|
||||
robot_states.dq = temp_list
|
||||
|
||||
# Step 2: send robot states to Flexiv Elements Studio
|
||||
# =============================================================================================
|
||||
if not user_node.SendRobotStates(robot_states):
|
||||
logger.error("Failed to send robot states data")
|
||||
|
||||
# Step 3: wait for Elements Studio to calculate and deliver new robot commands
|
||||
# =============================================================================================
|
||||
# Must set a timeout value to avoid deadlock
|
||||
WAIT_TIMEOUT_MS = 100
|
||||
if not user_node.WaitForRobotCommands(WAIT_TIMEOUT_MS):
|
||||
logger.error("WaitForRobotCommands() timeout")
|
||||
|
||||
# Step 4: apply joint torques command to the simulated robot in the external simulator
|
||||
# =============================================================================================
|
||||
target_joint_torques = user_node.robot_commands().target_drives
|
||||
# Call the external simulator's API to apply the target joint torques
|
||||
|
||||
# End the current physics step with kPhysicsPeriod as roughly the total loop period
|
||||
time.sleep(PHYSICS_PERIOD)
|
||||
|
||||
|
||||
def main():
|
||||
# Program Setup
|
||||
# ==============================================================================================
|
||||
# Parse arguments
|
||||
argparser = argparse.ArgumentParser()
|
||||
argparser.add_argument(
|
||||
"robot_sn",
|
||||
help="Serial number of the robot in Flexiv Elements Studio to connect. Remove any space, e.g. Rizon4s-123456",
|
||||
)
|
||||
args = argparser.parse_args()
|
||||
|
||||
# Create logger
|
||||
logger = spdlog.ConsoleLogger("Example")
|
||||
|
||||
# Print description
|
||||
logger.info(
|
||||
">>> Tutorial description <<<\nA simple example demonstrating how to use Flexiv Sim Plugin "
|
||||
"in an external simulator.\n"
|
||||
)
|
||||
|
||||
# Create user node
|
||||
user_node = flexivsimplugin.UserNode(args.robot_sn)
|
||||
|
||||
# Wait for connected
|
||||
while not user_node.connected():
|
||||
logger.warn("Waiting for connection with Flexiv Elements Studio")
|
||||
time.sleep(1)
|
||||
logger.info("Connected with Flexiv Elements Studio, starting mocked physics loop")
|
||||
|
||||
# Run mocked physics loop
|
||||
while user_node.connected():
|
||||
step_physics(user_node, logger)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
@@ -0,0 +1,86 @@
|
||||
/**
|
||||
* @file data.hpp
|
||||
* @brief Header file containing various constant expressions and data structures.
|
||||
* @copyright Copyright (C) 2016-2025 Flexiv Ltd. All Rights Reserved.
|
||||
*/
|
||||
|
||||
#ifndef FLEXIV_SIM_PLUGIN_DATA_HPP_
|
||||
#define FLEXIV_SIM_PLUGIN_DATA_HPP_
|
||||
|
||||
#include <array>
|
||||
#include <vector>
|
||||
#include <string>
|
||||
|
||||
namespace flexiv {
|
||||
namespace sim_plugin {
|
||||
|
||||
/** Number of simulated digital IO ports */
|
||||
constexpr size_t kIOPorts = 16;
|
||||
|
||||
/** States data of a simulated robot in the external simulator */
|
||||
struct SimRobotStates
|
||||
{
|
||||
/** @brief Customized constructor */
|
||||
SimRobotStates(uint64_t _servo_cycle, const std::vector<float>& _q,
|
||||
const std::vector<float>& _dq, const std::vector<float>& _wrist_force = {},
|
||||
const std::vector<float>& _wrist_torque = {})
|
||||
: servo_cycle(_servo_cycle)
|
||||
, q(_q)
|
||||
, dq(_dq)
|
||||
, wrist_force(_wrist_force)
|
||||
, wrist_torque(_wrist_torque)
|
||||
{
|
||||
}
|
||||
|
||||
/** @brief Default constructor */
|
||||
SimRobotStates() = default;
|
||||
|
||||
/** Servo cycle incremented once per physics step of the external simulator */
|
||||
uint64_t servo_cycle = 0;
|
||||
|
||||
/** Current joint positions of the simulated robot: \f$ q \in \mathbb{R}^{n \times 1} \f$. Unit:
|
||||
* \f$ [rad] or [m] \f$.
|
||||
* @note This contains values for both the external axes (if any) and the robot manipulator. */
|
||||
std::vector<float> q = {};
|
||||
|
||||
/** Current joint velocities of the simulated robot: \f$ \dot{q} \in \mathbb{R}^{n \times 1}
|
||||
* \f$. Unit: \f$ [rad/s] or [m/s] \f$.
|
||||
* @note This contains values for both the external axes (if any) and the robot manipulator. */
|
||||
std::vector<float> dq = {};
|
||||
|
||||
/** Current wrist force sensor reading of the simulated robot: \f$ [f_x, f_y, f_z] \f$. Unit: \f$
|
||||
* [N] \f$. */
|
||||
std::vector<float> wrist_force = {};
|
||||
|
||||
/** Current wrist torque sensor reading of the simulated robot: \f$ [m_x, m_y, m_z] \f$. Unit:
|
||||
* \f$ [Nm] \f$. */
|
||||
std::vector<float> wrist_torque = {};
|
||||
};
|
||||
|
||||
/** Commands data for a simulated robot in the external simulator */
|
||||
struct SimRobotCommands
|
||||
{
|
||||
/** @brief Customized constructor */
|
||||
SimRobotCommands(const std::vector<float>& _target_drives,
|
||||
const std::array<bool, kIOPorts>& _digital_outputs)
|
||||
: target_drives(_target_drives)
|
||||
, digital_outputs(_digital_outputs)
|
||||
{
|
||||
}
|
||||
/** @brief Default constructor */
|
||||
SimRobotCommands() = default;
|
||||
|
||||
/** Target joint drives for the simulated robot, can be torques or velocities depending on the
|
||||
* drive type of the joint. Unit: \f$ [Nm] or [rad/s] or [m/s] \f$.
|
||||
* @note This contains values for both the external axes (if any) and the robot manipulator. */
|
||||
std::vector<float> target_drives = {};
|
||||
|
||||
/** Desired digital outputs for the simulated robot. The index of this boolean array corresponds
|
||||
* to that of the digital output ports. True: port high, false: port low. */
|
||||
std::array<bool, kIOPorts> digital_outputs = {};
|
||||
};
|
||||
|
||||
} /* namespace sim_plugin */
|
||||
} /* namespace flexiv */
|
||||
|
||||
#endif /* FLEXIV_SIM_PLUGIN_DATA_HPP_ */
|
||||
+68
@@ -0,0 +1,68 @@
|
||||
/**
|
||||
* @file user_node.hpp
|
||||
* @copyright Copyright (C) 2016-2025 Flexiv Ltd. All Rights Reserved.
|
||||
*/
|
||||
|
||||
#ifndef FLEXIV_SIM_PLUGIN_USER_NODE_HPP_
|
||||
#define FLEXIV_SIM_PLUGIN_USER_NODE_HPP_
|
||||
|
||||
#include "data.hpp"
|
||||
#include <memory>
|
||||
|
||||
namespace flexiv {
|
||||
namespace sim_plugin {
|
||||
|
||||
/**
|
||||
* @class UserNode
|
||||
* @brief A communication node for an external simulator to publish robot states to and receive
|
||||
* robot commands from Flexiv Elements Studio.
|
||||
*/
|
||||
class UserNode final
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* @brief Create the node.
|
||||
* @param[in] robot_sn Serial number of the simulated robot created in Flexiv Elements Studio.
|
||||
* The accepted formats are: "Rizon 4-123456" and "Rizon4-123456".
|
||||
* @param[in] debug_print Print debug info.
|
||||
*/
|
||||
UserNode(const std::string& robot_sn, bool debug_print = false);
|
||||
virtual ~UserNode();
|
||||
|
||||
/**
|
||||
* @brief Whether this node is connected with Flexiv Elements Studio.
|
||||
*/
|
||||
bool connected() const;
|
||||
|
||||
/**
|
||||
* @brief Send robot states data to Flexiv Elements Studio.
|
||||
* @param[in] robot_states States data of the simulated robot in the external simulator.
|
||||
* @return True: data sent successfully; false: failed to send data.
|
||||
*/
|
||||
bool SendRobotStates(const SimRobotStates& robot_states);
|
||||
|
||||
/**
|
||||
* @brief Blocks until the next data packet of robot commands from Flexiv Elements Studio is
|
||||
* received or timeout.
|
||||
* @param[in] timeout_ms Maximum wait time before this function returns. Must set a value to
|
||||
* avoid deadlock. Unit: [ms].
|
||||
* @return True: packet received before timeout; false: packet not received before timeout.
|
||||
*/
|
||||
bool WaitForRobotCommands(unsigned int timeout_ms);
|
||||
|
||||
/**
|
||||
* @brief Current commands data to apply to the simulated robot in the external simulator.
|
||||
* @return Value copy of SimRobotCommands struct.
|
||||
* @warning Call this function after WaitForRobotCommands() to get the latest data.
|
||||
*/
|
||||
SimRobotCommands robot_commands() const;
|
||||
|
||||
private:
|
||||
class Impl;
|
||||
std::unique_ptr<Impl> pimpl_;
|
||||
};
|
||||
|
||||
} /* namespace sim_plugin */
|
||||
} /* namespace flexiv */
|
||||
|
||||
#endif /* FLEXIV_SIM_PLUGIN_USER_NODE_HPP_ */
|
||||
@@ -0,0 +1,5 @@
|
||||
/**
|
||||
* @file dummy.cpp
|
||||
* @brief A dummy source file to add portability to the installed flexiv_rdk library
|
||||
*/
|
||||
void dummy() { }
|
||||
+1
@@ -0,0 +1 @@
|
||||
d95da285eac19eac1d64e5e953a2690f26f4791b9c03d5a9896569717fae6fc0
|
||||
+49
@@ -0,0 +1,49 @@
|
||||
#!/bin/sh
|
||||
# This script builds from source and installs all dependencies of flexiv_sim_plugin.
|
||||
|
||||
# Absolute path of this script
|
||||
SCRIPTPATH="$(dirname $(readlink -f $0))"
|
||||
set -e
|
||||
|
||||
# Check script arguments
|
||||
if [ "$#" -lt 1 ]; then
|
||||
echo "Error: invalid script argument"
|
||||
echo "Required argument: [install_directory_path]"
|
||||
echo " install_directory_path: directory to install all dependencies, should be the same as the install directory of flexiv_sim_plugin"
|
||||
echo "Optional argument: [num_parallel_jobs]"
|
||||
echo " num_parallel_jobs: number of parallel jobs used to build, use 4 if not specified"
|
||||
exit
|
||||
fi
|
||||
|
||||
# Get dependencies install directory from script argument, should be the same as the install directory of flexiv_sim_plugin
|
||||
INSTALL_DIR=$1
|
||||
echo "Dependencies will be installed to: $INSTALL_DIR"
|
||||
|
||||
# Use specified number for parallel build jobs, otherwise use 4
|
||||
if [ -n "$2" ] ;then
|
||||
export NUM_JOBS=$2
|
||||
else
|
||||
export NUM_JOBS=4
|
||||
fi
|
||||
echo "Number of parallel build jobs: $NUM_JOBS"
|
||||
|
||||
# Set shared cmake arguments
|
||||
SHARED_CMAKE_ARGS="-DCMAKE_BUILD_TYPE=Release \
|
||||
-DBUILD_SHARED_LIBS=OFF \
|
||||
-DCMAKE_POSITION_INDEPENDENT_CODE=ON \
|
||||
-DCMAKE_PREFIX_PATH=$INSTALL_DIR \
|
||||
-DCMAKE_INSTALL_PREFIX=$INSTALL_DIR \
|
||||
-DBUILD_TESTING=OFF"
|
||||
|
||||
# Clone all dependencies in a subfolder
|
||||
mkdir -p cloned && cd cloned
|
||||
export SHARED_CMAKE_ARGS
|
||||
|
||||
# Build and install all dependencies to INSTALL_DIR
|
||||
bash $SCRIPTPATH/scripts/install_spdlog.sh
|
||||
bash $SCRIPTPATH/scripts/install_tinyxml2.sh
|
||||
bash $SCRIPTPATH/scripts/install_foonathan_memory.sh
|
||||
bash $SCRIPTPATH/scripts/install_Fast-CDR.sh
|
||||
bash $SCRIPTPATH/scripts/install_Fast-DDS.sh
|
||||
|
||||
echo ">>>>>>>>>> Finished <<<<<<<<<<"
|
||||
+24
@@ -0,0 +1,24 @@
|
||||
#!/bin/bash
|
||||
set -e
|
||||
echo "Installing Fast-CDR"
|
||||
|
||||
# Use a specific version
|
||||
VER_TAG=v1.0.28
|
||||
|
||||
# Clone source code
|
||||
if [ ! -d Fast-CDR ] ; then
|
||||
git clone https://github.com/eProsima/Fast-CDR.git --branch $VER_TAG
|
||||
cd Fast-CDR
|
||||
else
|
||||
cd Fast-CDR
|
||||
git checkout $VER_TAG
|
||||
fi
|
||||
|
||||
# Configure CMake
|
||||
mkdir -p build && cd build
|
||||
cmake .. $SHARED_CMAKE_ARGS -DCOMPILE_EXAMPLES=OFF
|
||||
|
||||
# Build and install
|
||||
cmake --build . --target install --config Release -j $NUM_JOBS
|
||||
|
||||
echo "Installed Fast-CDR"
|
||||
+31
@@ -0,0 +1,31 @@
|
||||
#!/bin/bash
|
||||
# Depends on: foonathan_memory, tinyxml2, Fast-CDR
|
||||
set -e
|
||||
echo "Installing Fast-DDS"
|
||||
|
||||
# Use a specific version
|
||||
VER_TAG=v2.6.10
|
||||
|
||||
# Clone source code
|
||||
if [ ! -d Fast-DDS ] ; then
|
||||
git clone https://github.com/eProsima/Fast-DDS.git --branch $VER_TAG
|
||||
cd Fast-DDS
|
||||
else
|
||||
cd Fast-DDS
|
||||
git checkout $VER_TAG
|
||||
fi
|
||||
|
||||
# Initialize submodules
|
||||
git submodule update --init --recursive
|
||||
|
||||
# Configure CMake
|
||||
mkdir -p build && cd build
|
||||
cmake .. $SHARED_CMAKE_ARGS \
|
||||
-DTHIRDPARTY_Asio=ON \
|
||||
-DCOMPILE_EXAMPLES=OFF \
|
||||
-DSQLITE3_SUPPORT=OFF
|
||||
|
||||
# Build and install
|
||||
cmake --build . --target install --config Release -j $NUM_JOBS
|
||||
|
||||
echo "Installed Fast-DDS"
|
||||
+24
@@ -0,0 +1,24 @@
|
||||
#!/bin/bash
|
||||
set -e
|
||||
echo "Installing foonathan_memory"
|
||||
|
||||
# Use a specific version
|
||||
VER_TAG=v1.3.1
|
||||
|
||||
# Clone source code
|
||||
if [ ! -d foonathan_memory_vendor ] ; then
|
||||
git clone https://github.com/eProsima/foonathan_memory_vendor.git --branch $VER_TAG
|
||||
cd foonathan_memory_vendor
|
||||
else
|
||||
cd foonathan_memory_vendor
|
||||
git checkout $VER_TAG
|
||||
fi
|
||||
|
||||
# Configure CMake
|
||||
mkdir -p build && cd build
|
||||
cmake .. $SHARED_CMAKE_ARGS
|
||||
|
||||
# Build and install
|
||||
cmake --build . --target install --config Release -j $NUM_JOBS
|
||||
|
||||
echo "Installed foonathan_memory"
|
||||
@@ -0,0 +1,25 @@
|
||||
#!/bin/bash
|
||||
set -e
|
||||
|
||||
# Use a specific version
|
||||
VER_TAG=v1.14.1
|
||||
|
||||
# Clone source code
|
||||
if [ ! -d spdlog ] ; then
|
||||
git clone https://github.com/gabime/spdlog.git --branch $VER_TAG
|
||||
cd spdlog
|
||||
else
|
||||
cd spdlog
|
||||
git checkout $VER_TAG
|
||||
fi
|
||||
|
||||
# Configure CMake
|
||||
mkdir -p build && cd build
|
||||
cmake .. $SHARED_CMAKE_ARGS \
|
||||
-DSPDLOG_BUILD_EXAMPLE=OFF \
|
||||
-DSPDLOG_BUILD_TESTS=OFF
|
||||
|
||||
# Build and install
|
||||
cmake --build . --target install --config Release -j $NUM_JOBS
|
||||
|
||||
echo "Installed spdlog"
|
||||
+24
@@ -0,0 +1,24 @@
|
||||
#!/bin/bash
|
||||
set -e
|
||||
echo "Installing tinyxml2"
|
||||
|
||||
# Use a specific version
|
||||
VER_TAG=8.0.0
|
||||
|
||||
# Clone source code
|
||||
if [ ! -d tinyxml2 ] ; then
|
||||
git clone https://github.com/leethomason/tinyxml2.git --branch $VER_TAG
|
||||
cd tinyxml2
|
||||
else
|
||||
cd tinyxml2
|
||||
git checkout $VER_TAG
|
||||
fi
|
||||
|
||||
# Configure CMake
|
||||
mkdir -p build && cd build
|
||||
cmake .. $SHARED_CMAKE_ARGS
|
||||
|
||||
# Build and install
|
||||
cmake --build . --target install --config Release -j $NUM_JOBS
|
||||
|
||||
echo "Installed tinyxml2"
|
||||
Reference in New Issue
Block a user