diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index eea1d3c..b10a5c6 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -1,9 +1,9 @@ -name: Building and checking -run-name: ${{ github.actor }} Building +name: build +run-name: ${{ github.actor }} build on: workflow_dispatch: - push: - pull_request: + # push: + # pull_request: jobs: build: @@ -31,7 +31,7 @@ jobs: run: pip3 install -r requirements.txt - name: configure - run: cmake -S. -Bbuild -DBUILD_PYTHON=ON -DBUILD_DEB=ON + run: cmake -S. -Bbuild -DBUILD_PYTHON=ON -DBUILD_DEB=ON -DBUILD_DOCUMENTATION=ON - name: build run: cmake --build build diff --git a/.github/workflows/linux_cpp_build.yml b/.github/workflows/linux_cpp_build.yml new file mode 100644 index 0000000..e65c464 --- /dev/null +++ b/.github/workflows/linux_cpp_build.yml @@ -0,0 +1,57 @@ +name: Linux cpp build +run-name: ${{ github.actor }} Linux cpp build +on: + workflow_dispatch: + pull_request: +jobs: + linux_cpp_build: + environment: + name: github-pages + url: ${{ steps.deployment.outputs.page_url }} + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v3 + + - name: install components + run: sudo apt-get install -y build-essential doxygen graphviz python3-pip python3-dev + + - name: install dependencies + run: pip3 install -r requirements.txt + + - name: configure + run: cmake -S. -Bbuild -DBUILD_DEB=ON + + - name: build + run: cmake --build build + + linux_cpp_test: + needs: linux_cpp_build + runs-on: ubuntu-latest + container: registry.cn-shanghai.aliyuncs.com/lebai/l-master:latest + steps: + - name: start nginx + run: nginx + + - name: start daemon + run: | + systemctl start l-master-rc + systemctl start l-master-ds + + - name: Checkout + uses: actions/checkout@v3 + + - name: install components + run: apt-get install -y build-essential doxygen graphviz python3-pip python3-dev + + - name: install dependencies + run: pip3 install -r requirements.txt + + - name: configure + run: cmake -S. -Bbuild -DBUILD_TESTING=ON -DBUILD_DOCUMENTATION=ON + + - name: build + run: cmake --build build + + - name: test + run: cmake --build build --target test diff --git a/.github/workflows/linux_cpp_release.yml b/.github/workflows/linux_cpp_release.yml index d308e34..80854f9 100644 --- a/.github/workflows/linux_cpp_release.yml +++ b/.github/workflows/linux_cpp_release.yml @@ -38,7 +38,7 @@ jobs: run: pip3 install -r requirements.txt - name: configure - run: cmake -S. -Bbuild -DBUILD_PYTHON=ON -DBUILD_DEB=ON + run: cmake -S. -Bbuild -DBUILD_DEB=ON -DBUILD_DOCUMENTATION=ON - name: build run: cmake --build build diff --git a/.github/workflows/linux_dotnet_build.yml b/.github/workflows/linux_dotnet_build.yml new file mode 100644 index 0000000..08a0ef8 --- /dev/null +++ b/.github/workflows/linux_dotnet_build.yml @@ -0,0 +1,28 @@ +name: Linux dotnet build +run-name: ${{ github.actor }} Linux dotnet build +on: + workflow_dispatch: + pull_request: +jobs: + linux_dotnet_build: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v1 + + - name: Setup .NET Core 3.1 + uses: actions/setup-dotnet@v3.0.3 + + - name: Setup .NET 6.0 + uses: actions/setup-dotnet@v1 + with: + dotnet-version: 6.0.x + + - name: Check dotnet + run: dotnet --info + + - name: configure + run: cmake -S. -Bbuild -DBUILD_DOTNET=ON + + - name: build + run: cmake --build build diff --git a/.github/workflows/linux_dotnet_release.yml b/.github/workflows/linux_dotnet_release.yml new file mode 100644 index 0000000..3b78853 --- /dev/null +++ b/.github/workflows/linux_dotnet_release.yml @@ -0,0 +1,35 @@ +name: Linux dotnet release +run-name: ${{ github.actor }} Linux dotnet release +on: + workflow_dispatch: + push: + tags: + - v1.*.* +jobs: + linux_dotnet_build_and_release: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v1 + + - name: Setup .NET Core 3.1 + uses: actions/setup-dotnet@v3.0.3 + + - name: Setup .NET 6.0 + uses: actions/setup-dotnet@v1 + with: + dotnet-version: 6.0.x + + - name: Check dotnet + run: dotnet --info + + - name: configure + run: cmake -S. -Bbuild -DBUILD_DOTNET=ON + + - name: build + run: cmake --build build + + - name: upload pacakges + run: + cd ./build/dotnet/packages + dotnet nuget push lebai.1.0.*.nupkg --api-key ${{ secrets.NUGET_KEY }} --source https://api.nuget.org/v3/index.json \ No newline at end of file diff --git a/.github/workflows/linux_java_build.yml b/.github/workflows/linux_java_build.yml new file mode 100644 index 0000000..44b6a5e --- /dev/null +++ b/.github/workflows/linux_java_build.yml @@ -0,0 +1,22 @@ +name: Linux java build +run-name: ${{ github.actor }} Linux java build +on: + workflow_dispatch: + pull_request: +jobs: + linux_java_build: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v1 + + - uses: actions/setup-java@v1 + with: + java-version: '11' + + - name: configure + run: cmake -S. -Bbuild -DBUILD_JAVA=ON + + - name: build + run: cmake --build build + diff --git a/.github/workflows/linux_python_build.yml b/.github/workflows/linux_python_build.yml new file mode 100644 index 0000000..0a3bd39 --- /dev/null +++ b/.github/workflows/linux_python_build.yml @@ -0,0 +1,40 @@ +name: Linux python build +run-name: ${{ github.actor }} Linux python build +on: + workflow_dispatch: + pull_request: +jobs: + linux_python_build: + runs-on: ubuntu-latest + container: quay.io/pypa/manylinux2010_x86_64 + steps: + - name: Checkout + uses: actions/checkout@v1 + + - run: for PYBIN in /opt/python/*/bin;do "${PYBIN}/pip" install -r requirements.txt; done; + - run: /opt/python/cp310-cp310/bin/pip install twine==2.0.0 + + - name: configure + run: cmake -S. -Bbuild -DBUILD_PYTHON=ON + + - name: build + run: cmake --build build + + - name: create-whl-dir + run: mkdir -p whl + + - name: build with python + run: for PY in /opt/python/*;do + rm -rf build; + cmake -S. -Bbuild -DBUILD_PYTHON=ON; + cmake --build build; + cp build/python/dist/*.whl whl/; + done; + + - name: repair + run: for PYWHL in whl/*.whl;do + auditwheel repair ${PYWHL}; + done; + + - name: list Pypi + run: ls wheelhouse/* diff --git a/.github/workflows/linux_python_release.yml b/.github/workflows/linux_python_release.yml index 0073b56..34d2442 100644 --- a/.github/workflows/linux_python_release.yml +++ b/.github/workflows/linux_python_release.yml @@ -1,5 +1,5 @@ name: Linux python release -run-name: ${{ github.actor }} released page +run-name: ${{ github.actor }} Linux python release on: workflow_dispatch: push: @@ -14,36 +14,32 @@ permissions: jobs: linux_python_build_and_release: - runs-on: ubuntu-latest - container: quay.io/pypa/manylinux2010_x86_64 - steps: - - name: Checkout - uses: actions/checkout@v1 - - - run: for PYBIN in /opt/python/*/bin;do "${PYBIN}/pip" install -r requirements.txt; done; - - run: /opt/python/cp310-cp310/bin/pip install twine==2.0.0 - - - name: configure - run: cmake -S. -Bbuild -DBUILD_PYTHON=ON - - - name: build - run: cmake --build build - - - name: create-whl-dir - run: mkdir -p whl - - - name: build with python - run: for PY in /opt/python/*;do + runs-on: ubuntu-latest + container: quay.io/pypa/manylinux2010_x86_64 + steps: + - name: Checkout + uses: actions/checkout@v1 + + - run: for PYBIN in /opt/python/*/bin;do "${PYBIN}/pip" install -r requirements.txt; done; + - run: /opt/python/cp310-cp310/bin/pip install twine==2.0. + - name: configure + run: cmake -S. -Bbuild -DBUILD_PYTHON=ON + - name: build + run: cmake --build build + - name: create-whl-dir + run: mkdir -p wh + - name: build with python + run: for PY in /opt/python/*;do rm -rf build; - cmake -S. -Bbuild -DBUILD_PYTHON=ON -DPYTHONPATH=${PY}; + cmake -S. -Bbuild -DBUILD_PYTHON=ON; cmake --build build; cp build/python/dist/*.whl whl/; done; - - - name: repair - run: for PYWHL in whl/*.whl;do + + - name: repair + run: for PYWHL in whl/*.whl;do auditwheel repair ${PYWHL}; done; - - - name: upload Pypi - run: /opt/python/cp310-cp310/bin/twine upload -u ${{ secrets.USRNAME }} -p ${{ secrets.PASSWD }} wheelhouse/*.whl \ No newline at end of file + + - name: upload Pypi + run: /opt/python/cp310-cp310/bin/twine upload -u ${{ secrets.USRNAME }} -p ${{ secrets.PASSWD }} wheelhouse/*.whl \ No newline at end of file diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index e5f7614..7ff4442 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -1,10 +1,10 @@ name: release -run-name: ${{ github.actor }} released page +run-name: ${{ github.actor }} release on: workflow_dispatch: - push: - tags: - - v1.*.* + # push: + # tags: + # - v1.*.* # Sets permissions of the GITHUB_TOKEN to allow deployment to GitHub Pages permissions: contents: read @@ -38,7 +38,7 @@ jobs: run: pip3 install -r requirements.txt - name: configure - run: cmake -S. -Bbuild -DBUILD_PYTHON=ON -DBUILD_DEB=ON + run: cmake -S. -Bbuild -DBUILD_PYTHON=ON -DBUILD_DEB=ON -DBUILD_DOCUMENTATION=ON - name: build run: cmake --build build diff --git a/.github/workflows/windows_cpp_build.yml b/.github/workflows/windows_cpp_build.yml new file mode 100644 index 0000000..cc7d259 --- /dev/null +++ b/.github/workflows/windows_cpp_build.yml @@ -0,0 +1,24 @@ +name: Windows cpp build +run-name: ${{ github.actor }} Windows cpp build +on: + workflow_dispatch: + pull_request: +# Sets permissions of the GITHUB_TOKEN to allow deployment to GitHub Pages +permissions: + contents: read + pages: write + id-token: write + pull-requests: read + +jobs: + windows_cpp_build: + runs-on: windows-latest + steps: + - name: Checkout + uses: actions/checkout@v3 + - name: Check cmake + run: cmake --version + - name: Configure + run: cmake -S. -Bbuild -G "Visual Studio 17 2022" -DBUILD_DOCUMENTATION=OFF + - name: Build + run: cmake --build build \ No newline at end of file diff --git a/.github/workflows/windows_python_build.yml b/.github/workflows/windows_python_build.yml new file mode 100644 index 0000000..a2dc0bd --- /dev/null +++ b/.github/workflows/windows_python_build.yml @@ -0,0 +1,27 @@ +name: Windows python build +run-name: ${{ github.actor }} Windows python build +on: + workflow_dispatch: + # pull_request: +# Sets permissions of the GITHUB_TOKEN to allow deployment to GitHub Pages +permissions: + contents: read + pages: write + id-token: write + pull-requests: read + +jobs: + windows_python_build: + runs-on: windows-latest + steps: + - name: Checkout + uses: actions/checkout@v3 + - uses: actions/setup-python@v4 + with: + python-version: '3.10' + - name: Check cmake + run: cmake --version + - name: Configure + run: cmake -S. -Bbuild -G "Visual Studio 17 2022" -DBUILD_PYTHON=ON -DBUILD_DOCUMENTATION=OFF + - name: Build + run: cmake --build build \ No newline at end of file diff --git a/CMakeLists.txt b/CMakeLists.txt old mode 100755 new mode 100644 index e3f11e6..173045a --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -7,7 +7,7 @@ list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake") option(CMAKE_EXPORT_COMPILE_COMMANDS "Export compile command" TRUE) -project(lebai VERSION 1.0.13 LANGUAGES CXX) +project(lebai VERSION 1.0.14 LANGUAGES CXX) set(PROJECT_NAMESPACE lebai) message(STATUS "${PROJECT_NAME} version: ${PROJECT_VERSION}") # message(STATUS "major: ${PROJECT_VERSION_MAJOR}") @@ -18,7 +18,7 @@ get_property(isMultiConfig GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG) if(isMultiConfig) if(NOT CMAKE_CONFIGURATION_TYPES) set(CMAKE_CONFIGURATION_TYPES "Release;Debug" CACHE STRING - "Choose the type of builds, options are: Debug Release RelWithDebInfo MinSizeRel. (default: Release;Debug)" + "Choose the type ofgi builds, options are: Debug Release RelWithDebInfo MinSizeRel. (default: Release;Debug)" FORCE) endif() message(STATUS "Configuration types: ${CMAKE_CONFIGURATION_TYPES}") @@ -53,6 +53,8 @@ else() add_compile_definitions(NOMINMAX) add_compile_definitions(_DEBUG) add_compile_definitions(_WEBSOCKETPP_CPP11_RANDOM_DEVICE_) + add_compile_options("$<$:/utf-8>") + add_compile_options("$<$:/utf-8>") set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/${CMAKE_INSTALL_BINDIR}) set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/${CMAKE_INSTALL_BINDIR}) set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/${CMAKE_INSTALL_BINDIR}) @@ -65,6 +67,14 @@ else() endforeach() endif() +option(ENABLE_TSAN "Enable thread sanitier" OFF) +if(UNIX) + if(ENABLE_TSAN) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=thread -g") + set(CMAKE_LINKER_FLAGS "${CMAKE_LINKER_FLAGS} -fsanitize=thread") + endif() +endif() + # By default only the C++ library is built. option(BUILD_CXX "Build C++ library" ON) message(STATUS "Build C++ library: ${BUILD_CXX}") @@ -79,10 +89,12 @@ option(BUILD_JAVA "Build Java Library" OFF) message(STATUS "Build Java: ${BUILD_JAVA}") if(BUILD_PYTHON) - if(DEFINED PYTHONPATH) - message(STATUS "Python path: ${PYTHONPATH}") - set(Python3_ROOT_DIR ${PYTHONPATH}) - endif() + option(FETCH_PYTHON_DEPS "Install python required modules if not available" ON) + message(STATUS "Python fetch dependencies: ${FETCH_PYTHON_DEPS}") + # if(DEFINED PYTHONPATH) + # message(STATUS "Python path: ${PYTHONPATH}") + # set(Python3_ROOT_DIR ${PYTHONPATH}) + # endif() endif() # Disable CTest targets @@ -132,14 +144,12 @@ message(STATUS "Build examples: ${BUILD_EXAMPLES}") add_subdirectory(examples) +find_package(Doxygen) +option(BUILD_DOCUMENTATION "Create and install the HTML based API documentation (requires Doxygen)" ON) -find_package(Doxygen QUIET) -option(BUILD_DOCUMENTATION "Create and install the HTML based API documentation (requires Doxygen)" ${DOXYGEN_FOUND}) - -if(BUILD_DOCUMENTATION) - # find_package(Doxygen) - if(NOT DOXYGEN_FOUND) - message(FATAL_ERROR "Doxygen is needed to build the documentation.") +if(BUILD_DOCUMENTATION AND DOXYGEN_FOUND) + if(NOT DOXYGEN_FOUND) + message(FATAL_ERROR "Doxygen is needed to build the documentation.") endif() set(doxyfile_in ${CMAKE_CURRENT_SOURCE_DIR}/Doxyfile ) diff --git a/CMakeSettings.json b/CMakeSettings.json index 89648ee..cf8740e 100755 --- a/CMakeSettings.json +++ b/CMakeSettings.json @@ -28,7 +28,7 @@ }, { "name": "BUILD_PYTHON", - "value": "False", + "value": "True", "type": "BOOL" }, { @@ -38,7 +38,12 @@ }, { "name": "BUILD_DOTNET", - "value": "True", + "value": "False", + "type": "BOOL" + }, + { + "name": "BUILD_DOCUMENTATION", + "value": "False", "type": "BOOL" } ] diff --git a/Doxyfile b/Doxyfile index d8b0cb6..8a0e534 100644 --- a/Doxyfile +++ b/Doxyfile @@ -38,7 +38,7 @@ PROJECT_NAME = "lebai sdk" # could be handy for archiving the generated documentation or if some version # control system is used. -PROJECT_NUMBER = 1.0.13 +PROJECT_NUMBER = 1.0.14 # Using the PROJECT_BRIEF tag one can provide an optional one line description # for a project that appears at the top of each page and should give viewer a diff --git a/README.md b/README.md index f279577..75140d7 100755 --- a/README.md +++ b/README.md @@ -1,21 +1,23 @@ -lebai-sdk的源代码仓库,可以用于控制乐白机械臂。 +lebai-sdk的源代码仓库,可以用于控制乐白机械臂. | OS | C++ | Python | C# | Java | |:-------|-----|--------|----|------| -| Linux | [![Status][cpp_linux_svg]][cpp_linux_link] | [![Status][python_linux_svg]][python_linux_link] | TODO | TODO | +| Linux | [![Status][cpp_linux_svg]][cpp_linux_link] | [![Status][python_linux_svg]][python_linux_link] | [![Status][dotnet_linux_svg]][dotnet_linux_link] | TODO | | Windows | TODO | TODO | TODO | TODO | [cpp_linux_svg]: https://github.com/lebai-robotics/lebai-sdk/actions/workflows/linux_cpp_release.yml/badge.svg [cpp_linux_link]: https://github.com/lebai-robotics/lebai-sdk/actions/workflows/linux_cpp_release.yml [python_linux_svg]: https://github.com/lebai-robotics/lebai-sdk/actions/workflows/linux_python_release.yml/badge.svg [python_linux_link]: https://github.com/lebai-robotics/lebai-sdk/actions/workflows/linux_python_release.yml +[dotnet_linux_svg]: https://github.com/lebai-robotics/lebai-sdk/actions/workflows/linux_dotnet_release.yml/badge.svg +[dotnet_linux_link]: https://github.com/lebai-robotics/lebai-sdk/actions/workflows/linux_dotnet_release.yml [SDK在线文档](http://help.lebai.ltd/sdk/) # 包管理直接安装 -python开发可以直接从[PyPI](https://pypi.org/project/pylebai/)安装。 +python开发可以直接从[PyPI](https://pypi.org/project/pylebai/)安装. ``` pip install pylebai ``` @@ -41,9 +43,9 @@ pip install pylebai ```bash sudo apt install build-essential python3-pip dpkg-dev sudo pip3 install -i https://pypi.tuna.tsinghua.edu.cn/simple -r requirements.txt -# 如果需要生成文档,还需要安装doxygen。 +# 如果需要生成文档,还需要安装doxygen sudo apt install doxygen graphviz -# 如果需要生成python的wrapper包。 +# 如果需要生成python的wrapper包 sudo apt install python3-dev ``` @@ -69,9 +71,9 @@ cpack 安装python库时,选择 `Download debug binaries` -在Visual Studio中载入CMake工程,即可以生成构建运行测试等。 +在Visual Studio中载入CMake工程,即可以生成构建运行测试等. -目前Windows平台下python的binding部分还存在问题无法工作。 +目前Windows平台下python的binding部分还存在问题无法工作. @@ -85,9 +87,10 @@ cpack - TEST_ROBOT_IP: 测试程序的机器人IP地址,正确的设置该值用于单元测试 默认为127.0.0.1 - BUILD_EXAMPLES: 是否编译示例程序 默认为ON - BUILD_DEB: 是否生成DEB包的构建 默认为OFF + - ENABLE_TSAN: 编译是否启用Thread sanitizer检查 默认为OFF ## 使用 -您可以通过docs目录下的文档了解更多各语言的信息。 +您可以通过docs目录下的文档了解更多各语言的信息. ### Python build目录下会生成python的whl包,可以直接使用: @@ -95,7 +98,7 @@ build目录下会生成python的whl包,可以直接使用: cd build/python/dist ## 安装 pip3 install pylebai-xxx.whl -### XXX取决于您的sdk版本,python版本,操作系统平台。 +### XXX取决于您的sdk版本,python版本,操作系统平台. ## 卸载 pip3 uninstall pylebai ``` diff --git a/TODO.md b/TODO.md index fb65cb1..9ab320f 100644 --- a/TODO.md +++ b/TODO.md @@ -1,13 +1,5 @@ # TODO -## v1.0.9 - -- [x] SDK版本 -- [x] 系统控制-reboot -- [x] 配置-从资源库加载TCP -- [x] 位置-从资源库加载路点位姿 -- [x] 运动-关节跟随运动 -- [x] 运动-圆弧运动 -- [x] ModBus -- [x] 把IO相关的API整合一致(类型通过参数传入) -- [x] 获取任务状态 +- [] 把workflow拆分成平台+语言的结构,分成build和release +- [] Windows平台python不能运行(GIL锁)的问题 +- [] Python, C#, C++的测试程序 diff --git a/cmake/cpp.cmake b/cmake/cpp.cmake index e8b4de7..a7983b0 100755 --- a/cmake/cpp.cmake +++ b/cmake/cpp.cmake @@ -9,6 +9,7 @@ set(CMAKE_CXX_EXTENSIONS OFF) configure_file("${PROJECT_SOURCE_DIR}/sdk/config.hh.in" "${PROJECT_SOURCE_DIR}/sdk/include/lebai/config.hh") include(GNUInstallDirs) + add_subdirectory(sdk) # Install install(EXPORT ${PROJECT_NAME}Targets diff --git a/cmake/python.cmake b/cmake/python.cmake index 337b21e..8f78eff 100755 --- a/cmake/python.cmake +++ b/cmake/python.cmake @@ -20,7 +20,7 @@ endif() # Find Python 3 find_package(Python3 REQUIRED COMPONENTS Interpreter Development.Module) -list(APPEND CMAKE_SWIG_FLAGS "-threads" "-py3" "-DPY3") +list(APPEND CMAKE_SWIG_FLAGS "-threads" "-py3" "-DPY3") # Find if the python module is available, # otherwise install it (PACKAGE_NAME) to the Python3 user install directory. diff --git a/doc/changelog.md b/doc/changelog.md index 769579c..a18b69e 100644 --- a/doc/changelog.md +++ b/doc/changelog.md @@ -1,5 +1,9 @@ # ChangeLog +## 1.0.14 + +文档更新,持续集成更新,修正程序的错误 + ## 1.0.11 文档更新,持续集成更新 diff --git a/examples/example.cs b/examples/example.cs index e419ff2..b275118 100644 --- a/examples/example.cs +++ b/examples/example.cs @@ -1,36 +1,36 @@ using System; using lebai.l_master; -namespace lebai.app -{ - class Program - { - static void Main(string[] args) - { - Console.WriteLine($"Enter example"); - Robot robot = new Robot("192.168.1.100", true); - robot.stop_sys(); - Console.WriteLine($"stop..."); - robot.start_sys(); - Console.WriteLine($"start..."); - DoubleVector jp1 = new DoubleVector(); - jp1.Add(0.0); - jp1.Add(-60.0 / 180.0 * 3.14); - jp1.Add(80.0 / 180.0 * 3.14); - jp1.Add(-10.0 / 180.0 * 3.14); - jp1.Add(-60.0 / 180.0 * 3.14); - jp1.Add(0.0); - robot.movej(jp1, 1.0, 1.0, 0.0, 0.0); - DoubleVector jp2 = new DoubleVector(); - jp2.Add(0.0); - jp2.Add(0.0); - jp2.Add(0.0); - jp2.Add(0.0); - jp2.Add(0.0); - jp2.Add(0.0); - robot.movej(jp2, 1.0, 1.0, 0.0, 0.0); - robot.wait_move(); - Console.WriteLine($"Exit example"); - } +namespace lebai.app +{ + class Program + { + static void Main(string[] args) + { + Console.WriteLine($"Enter example"); + Robot robot = new Robot("192.168.1.100", true); + robot.stop_sys(); + Console.WriteLine($"stop..."); + robot.start_sys(); + Console.WriteLine($"start..."); + DoubleVector jp1 = new DoubleVector(); + jp1.Add(0.0); + jp1.Add(-60.0 / 180.0 * 3.14); + jp1.Add(80.0 / 180.0 * 3.14); + jp1.Add(-10.0 / 180.0 * 3.14); + jp1.Add(-60.0 / 180.0 * 3.14); + jp1.Add(0.0); + robot.movej(jp1, 1.0, 1.0, 0.0, 0.0); + DoubleVector jp2 = new DoubleVector(); + jp2.Add(0.0); + jp2.Add(0.0); + jp2.Add(0.0); + jp2.Add(0.0); + jp2.Add(0.0); + jp2.Add(0.0); + robot.movej(jp2, 1.0, 1.0, 0.0, 0.0); + robot.wait_move(); + Console.WriteLine($"Exit example"); + } } } diff --git a/examples/multi_thread.cc b/examples/multi_thread.cc new file mode 100644 index 0000000..3cd9427 --- /dev/null +++ b/examples/multi_thread.cc @@ -0,0 +1,65 @@ +#include +#include +#include +#include +#include +#include + +void Thread1(lebai::l_master::Robot * robot){ + while(1) + { + robot->start_task("10017"); + robot->wait_move(); + std::cout<<"move done"<get_target_joint_speed(); + robot->get_actual_joint_positions(); + robot->get_actual_tcp_pose(); + robot->get_actual_joint_positions(); + auto jp = robot->get_actual_joint_positions(); + std::this_thread::sleep_for(std::chrono::milliseconds(100)); + } + return; +} + +int main() { + // 172.17.0.4 + lebai::l_master::Robot robot("192.168.1.100", true); + // lebai::l_master::Robot robot("172.17.0.4", true); + std::thread t1(Thread1, &robot); + std::thread t2(Thread2, &robot); + t1.join(); + t2.join(); + +} + + +// #include +// #include + +// int Global; + +// void *Thread1(void *x) { +// Global++; +// return NULL; +// } + +// void *Thread2(void *x) { +// Global--; +// return NULL; +// } + +// int main() { +// pthread_t t[2]; +// pthread_create(&t[0], NULL, Thread1, NULL); +// pthread_create(&t[1], NULL, Thread2, NULL); +// pthread_join(t[0], NULL); +// pthread_join(t[1], NULL); +// } \ No newline at end of file diff --git a/python/setup.py.in b/python/setup.py.in index a2a0669..8df0266 100644 --- a/python/setup.py.in +++ b/python/setup.py.in @@ -13,7 +13,7 @@ class InstallPlatlib(install): install.finalize_options(self) self.install_lib=self.install_platlib -with open(r"../../README.md", "r") as fh: +with open(r"../../README.md", "r", encoding='UTF-8') as fh: long_description = fh.read() setup( diff --git a/sdk/include/lebai/discovery.hh b/sdk/include/lebai/discovery.hh index 169bd50..26664c8 100755 --- a/sdk/include/lebai/discovery.hh +++ b/sdk/include/lebai/discovery.hh @@ -25,7 +25,7 @@ namespace lebai namespace zeroconf { /** - * \brief Lebai机械臂控制器的信息数据结构 + * \brief Lebai机械臂控制器的信息数据结构. * */ class ControllerInfo @@ -48,7 +48,7 @@ namespace lebai }; /** - * @brief 自动发现局域网内lebai机械臂。 + * @brief 自动发现局域网内lebai机械臂. * */ class Discovery @@ -71,14 +71,14 @@ namespace lebai virtual ~Discovery(); /** - * @brief 获取局域网内lebai机械臂的信息数据,可以用来自动发现局域网内的所有机械臂控制器 + * @brief 获取局域网内lebai机械臂的信息数据,可以用来自动发现局域网内的所有机械臂控制器. * - * @return std::vector 所有的机械臂的信息数据 + * @return std::vector 所有的机械臂的信息数据. */ std::vector resolve(); protected: - std::unique_ptr impl_; /*!< 内部实现数据结构,用户无需关注。 */ + std::unique_ptr impl_; /*!< 内部实现数据结构,用户无需关注. */ }; } diff --git a/sdk/include/lebai/lebai.hh b/sdk/include/lebai/lebai.hh index 167e9b2..0eb96d1 100644 --- a/sdk/include/lebai/lebai.hh +++ b/sdk/include/lebai/lebai.hh @@ -3,22 +3,22 @@ /*! \mainpage lebai * [TOC] * # 概述 - * Lebai机械臂All in one开发包。开发包通过C++实现和机械臂的通讯,提供和机械臂控制器交互的接口,并且通过[SWIG](https://www.swig.org/ "SWIG")生成其它各种语言的接口库。 + * Lebai机械臂All in one开发包。开发包通过C++实现和机械臂的通讯,提供和机械臂控制器交互的接口,并且通过[SWIG](https://www.swig.org/ "SWIG")生成其它各种语言的接口库. * - * 您可以通过项目的README文档来了解如何构建和安装本开发包。 + * 您可以通过项目的README文档来了解如何构建和安装本开发包. * - * 您也可以基于本开发包创建使用其它语言的开发包。 + * 您也可以基于本开发包创建使用其它语言的开发包. * * # 如何开始 - * 查阅 \ref README.md "README" 文档,了解如何构建和安装本开发包。 + * 查阅 \ref README.md "README" 文档,了解如何构建和安装本开发包. * * # ChangeLog - * 查阅 \ref doc/changelog.md 。 + * 查阅 \ref doc/changelog.md. * * # Python - * 查看 \ref doc/python.md 来获取使用python相关的内容。 + * 查看 \ref doc/python.md 来获取使用python相关的内容. * * # Develop - * 如果需要开发sdk,添加新的功能,可以参考 \ref doc/develop.md 。 + * 如果需要开发sdk,添加新的功能,可以参考 \ref doc/develop.md. */ diff --git a/sdk/include/lebai/robot.hh b/sdk/include/lebai/robot.hh index 45d8b93..17afd45 100644 --- a/sdk/include/lebai/robot.hh +++ b/sdk/include/lebai/robot.hh @@ -273,12 +273,12 @@ namespace lebai * @brief 通过坐标位置发送机械臂直线移动 * @note 该接口为异步接口,仅向控制器内部的运动缓冲区写入一个关节移动即返回,不会等待运动结束. * @param cart_pose: 目标位置在机器人基座标系下的坐标数据(目前不支持在其它坐标系下的坐标数据),CartesianPose = std::map,应当包括键为x,y,z,rz,ry,rx的值. - * @param a: 加速度 - * @param v: 速度 + * @param a: 加速度. + * @param v: 速度. * @param t: 时间参数,如果设置时间不为零,则按照时间计算出速度,而不使用速度参数. * @param r: 交融半径,设置为0,则无交融半径. - * @return >0 发送成功 - * @return <=0 发送失败 + * @return >0 发送成功. + * @return <=0 发送失败. */ int movel(const CartesianPose & cart_pose, double a, double v, double t, double r); /** @@ -288,16 +288,16 @@ namespace lebai * {-28/ 180.0 * M_PI, -59.0/ 180.0 * M_PI, 96.0/ 180.0 * M_PI, -2.0/ 180.0 * M_PI, -92.0/ 180.0 * M_PI, 16.0/ 180.0 * M_PI}, * 0.0, 1.0, 0.5, 0.0, 0.0); * - * @brief 通过关节位置发送机械臂圆弧运动 * + * @brief 通过关节位置发送机械臂圆弧运动. * @param[in] joint_via 圆弧上途径点关节位置,为关节的角度值构成的数组.为圆上三点中的一点. * @param[in] joint 圆弧目标点关节位置,为关节的角度值构成的数组.如果编程rad不为零,则为圆上三点中的一点. * @param[in] rad 圆弧角度值,单位为弧度,如果为零,则走到目标点,正负值用来确定圆弧方向. - * @param[in] a 加速度 - * @param[in] v 速度 + * @param[in] a 加速度. + * @param[in] v 速度. * @param[in] t: 时间参数,如果设置时间不为零,则按照时间计算出速度,而不使用速度参数. * @param[in] r: 交融半径,设置为0,则无交融半径. - * @return >0 发送成功 - * @return <=0 发送失败 + * @return >0 发送成功. + * @return <=0 发送失败. */ int movec(const std::vector & joint_via, const std::vector & joint, double rad, double a, double v, double t, double r); /** @@ -306,12 +306,12 @@ namespace lebai * @param[in] cart_via 圆弧上途径点坐标位置,应当包括键为x,y,z,rz,ry,rx的值.为圆上三点中的一点. * @param[in] cart 圆弧目标点坐标位置,应当包括键为x,y,z,rz,ry,rx的值.如果编程rad不为零,则为圆上三点中的一点. * @param[in] rad 圆弧角度值,单位为弧度,如果为零,则走到目标点,正负值用来确定圆弧方向. - * @param[in] a 加速度 - * @param[in] v 速度 + * @param[in] a 加速度. + * @param[in] v 速度. * @param[in] t: 时间参数,如果设置时间不为零,则按照时间计算出速度,而不使用速度参数. * @param[in] r: 交融半径,设置为0,则无交融半径. - * @return >0 发送成功 - * @return <=0 发送失败 + * @return >0 发送成功. + * @return <=0 发送失败. */ int movec(const CartesianPose & cart_via, const CartesianPose & cart, double rad, double a, double v, double t, double r); /** @@ -321,50 +321,50 @@ namespace lebai * robot.toawrdj(joint_positions, 3.0, 1.0, 0.0, 0.0); * * - * @brief 通过关节位置发送机械臂关节自由移动 + * @brief 通过关节位置发送机械臂关节自由移动. * @note 该接口为异步接口,仅向控制器内部的运动缓冲区写入一个关节自由移动即返回,不会等待运动结束. * @param[in] joint_positions: 目标位置的关节数据,为关节的角度值构成的数组. * @param[in] a: 加速度. * @param[in] v: 速度. * @param[in] t: 时间参数,如果设置时间不为零,则按照时间计算出速度,而不使用速度参数. * @param[in] r: 交融半径,设置为0,则无交融半径. - * @return >0 发送成功 - * @return <=0 发送失败 + * @return >0 发送成功. + * @return <=0 发送失败. * */ int towardj(const std::vector & joint_positions, double a, double v, double t, double r); /** * @brief 伺服运动PVAT * - * @param p 关节位置,或者坐标位置(将通过运动学反解转为关节位置) - * @param v 每个关节的速度 (rad/s)。如该值为数字,则表示所有关节速度相同。 - * @param a 每个关节的加速度 (rad/s2)。如该值为数字,则表示所有关节加速度相同。 + * @param p 关节位置,或者坐标位置(将通过运动学反解转为关节位置). + * @param v 每个关节的速度 (rad/s)。如该值为数字,则表示所有关节速度相同. + * @param a 每个关节的加速度 (rad/s2)。如该值为数字,则表示所有关节加速度相同. * @param t 运动时间 (s) */ void move_pvat(std::vector p, std::vector v, std::vector a, double t); /** - * @brief 等待运动完成 + * @brief 等待运动完成. * - * @param id 指定运动的id(0为等待全部任务) + * @param id 指定运动的id(0为等待全部任务). */ void wait_move(unsigned int id); /** - * @brief 等待所有运动完成 + * @brief 等待所有运动完成. * */ void wait_move(); /** - * @brief 查询当前正在运动的MotionId(无运动时返回上次MotionId) + * @brief 查询当前正在运动的MotionId(无运动时返回上次MotionId). */ unsigned int get_running_motion(); /** - * @brief 查询指定MotionId的运动状态 + * @brief 查询指定MotionId的运动状态. * - * @param id 指定的运动id + * @param id 指定的运动id. */ std::string get_motion_state(unsigned int id); /** - * @brief 停止所有运动 + * @brief 停止所有运动. */ void stop_move(); /** @}*/ @@ -698,15 +698,15 @@ namespace lebai */ void resume_task(unsigned int id); /** - * @brief 取消任务与运动 + * @brief 取消任务与运动. * - * @param id 任务的ID + * @param id 任务的ID. */ void cancel_task(unsigned int id); /** - * @brief 获取任务状态 + * @brief 获取任务状态. * - * @param id 任务的ID + * @param id 任务的ID. */ std::string get_task_state(unsigned int id); /** @}*/ @@ -763,10 +763,10 @@ namespace lebai /** * @brief 重命名文件 * - * @param from_dir: 源文件所在的文件夹 - * @param from_name: 源文件名称 - * @param to_dir: 目标文件文件夹 - * @param to_name: 目标文件文件名 + * @param from_dir: 源文件所在的文件夹. + * @param from_name: 源文件名称. + * @param to_dir: 目标文件文件夹. + * @param to_name: 目标文件文件名. */ void rename_file(const std::string &from_dir,const std::string &from_name,const std::string &to_dir,const std::string &to_name); @@ -781,42 +781,42 @@ namespace lebai std::tuple load_file(const std::string &dir,const std::string &name); /** - * @brief 查询文件列表 + * @brief 查询文件列表. * - * @param dir: 文件的目录 - * @param prefix: 前缀 - * @param suffix: 后缀 + * @param dir: 文件的目录. + * @param prefix: 前缀. + * @param suffix: 后缀. * - * @return 文件列表 + * @return 文件列表. */ std::vector> load_file_list(const std::string &dir,const std::string &prefix,const std::string &suffix); /** - * @brief 将文件从文件系统中压缩到zip文件 + * @brief 将文件从文件系统中压缩到zip文件. * - * @param from_dir 源文件的目录 - * @param files 源文件的文件名 - * @param to_dir 压缩后文件的路径 - * @param name 压缩后文件的名称 + * @param from_dir 源文件的目录. + * @param files 源文件的文件名. + * @param to_dir 压缩后文件的路径. + * @param name 压缩后文件的名称. */ // void zip(const std::string &from_dir, std::vector files, const std::string &to_dir, const std::string &name); // /** - // * @brief 将zip文件解压到文件系统 + // * @brief 将zip文件解压到文件系统. // * - // * @param from_dir zip文件的路径 - // * @param name zip文件的名称 - // * @param files zip文件内的文件名 - // * @param to_dir 解压到的路径 + // * @param from_dir zip文件的路径. + // * @param name zip文件的名称. + // * @param files zip文件内的文件名. + // * @param to_dir 解压到的路径. // */ // void unzip(const std::string &from_dir, const std::string &name, std::vector files, const std::string &to_dir); // /** - // * @brief 查询文件列表 + // * @brief 查询文件列表. // * - // * @brief 目标zip文件名 - // * @param dir 文件的目录 - // * @param prefix 前缀 - // * @param suffix 后缀 + // * @brief 目标zip文件名. + // * @param dir 文件的目录. + // * @param prefix 前缀. + // * @param suffix 后缀. // * - // * @return 文件列表 + // * @return 文件列表. // */ // //std::vector> load_zip_list(const std::string &zip,const std::string &dir,const std::string &prefix,const std::string &suffix); @@ -826,59 +826,59 @@ namespace lebai * @{ */ /** - * @brief 设置工具中心点(TCP)坐标,坐标值相对于工具坐标系 + * @brief 设置工具中心点(TCP)坐标,坐标值相对于工具坐标系. * - * @param tcp 参数为六元组,表示一个空间位置变换 + * @param tcp 参数为六元组,表示一个空间位置变换. */ void set_tcp(std::array tcp); /** - * @brief 获取当前机器人工具中心点设置 + * @brief 获取当前机器人工具中心点设置. * - * @return 当前机器人的工具中心点参数,为六元组 + * @return 当前机器人的工具中心点参数,为六元组. */ std::array get_tcp(); /** - * @brief 设置速度因子 + * @brief 设置速度因子. * - * @param factor 速度因子百分比,范围0-100 + * @param factor 速度因子百分比,范围0-100. */ void set_velocity_factor(int factor); /** - * @brief 获取当前的速度因子 + * @brief 获取当前的速度因子. * - * @return 速度因子百分比 + * @return 速度因子百分比. */ int get_velocity_factor(); /** - * @brief 设置机器人末端负载 + * @brief 设置机器人末端负载. * - * @param mass 末端负载的质量(kg) - * @param cog 质心相对于TCP坐标系的偏移 + * @param mass 末端负载的质量(kg). + * @param cog 质心相对于TCP坐标系的偏移. */ void set_payload(double mass, std::map cog); /** - * @brief 获取末端负载设置 + * @brief 获取末端负载设置. * - * @return 由负载质量mass和负载偏移组成的元组 + * @return 由负载质量mass和负载偏移组成的元组. */ std::tuple> get_payload(); /** - * @brief 设置机器人重力加速度方向 + * @brief 设置机器人重力加速度方向. * - * @param gravity 相对于机器人基座标的重力方向 + * @param gravity 相对于机器人基座标的重力方向. */ void set_gravity(std::map gravity); /** - * @brief 获取机器人重力加速度的方向 + * @brief 获取机器人重力加速度的方向. * - * @return 相对于机器人基座标的重力方向 + * @return 相对于机器人基座标的重力方向. */ std::map get_gravity(); /** - * @brief 从资源库加载tcp + * @brief 从资源库加载tcp. * - * @param name 点位名称 - * @param dir 点位目录 + * @param name 点位名称. + * @param dir 点位目录. */ CartesianPose load_tcp(std::string name, std::string dir = ""); /** @}*/ @@ -889,54 +889,54 @@ namespace lebai */ /** - * @brief 写单个线圈 + * @brief 写单个线圈. * - * @param device 设备名称 - * @param addr 寄存器地址 - * @param value 待设置的值 + * @param device 设备名称. + * @param addr 寄存器地址. + * @param value 待设置的值. */ void write_single_coil(std::string device, std::string addr, bool value); /** * @brief 写多个线圈 * - * @param device 设备名称 - * @param addr 寄存器地址 - * @param values 待设置的值 + * @param device 设备名称. + * @param addr 寄存器地址. + * @param values 待设置的值. */ void wirte_multiple_coils(std::string device, std::string addr, std::vector values); /** * @brief 读线圈 * - * @param device 设备名称 - * @param addr 寄存器地址 - * @param num 连续数量 + * @param device 设备名称. + * @param addr 寄存器地址. + * @param num 连续数量. */ std::vector read_coils(std::string device, std::string addr, unsigned int num); /** * @brief 读离散输入 * - * @param device 设备名称 - * @param addr 寄存器地址 - * @param num 连续数量 + * @param device 设备名称. + * @param addr 寄存器地址. + * @param num 连续数量. */ std::vector read_discrete_inputs(std::string device, std::string addr, unsigned int num); /** * @brief 写单个寄存器 * - * @param device 设备名称 - * @param addr 寄存器地址 - * @param value 待设置的值 + * @param device 设备名称. + * @param addr 寄存器地址. + * @param value 待设置的值. */ void write_single_register(std::string device, std::string addr, unsigned int value); /** * @brief 写多个寄存器 * - * @param device 设备名称 - * @param addr 寄存器地址 - * @param values 待设置的值 + * @param device 设备名称. + * @param addr 寄存器地址. + * @param values 待设置的值. */ void write_multiple_registers(std::string device, std::string addr, std::vector values); diff --git a/sdk/python/CMakeLists.txt b/sdk/python/CMakeLists.txt index 9cdd93b..f1da554 100755 --- a/sdk/python/CMakeLists.txt +++ b/sdk/python/CMakeLists.txt @@ -15,16 +15,7 @@ target_include_directories(l_master ) set_property(TARGET l_master PROPERTY SWIG_USE_TARGET_INCLUDE_DIRECTORIES ON) -# note: macOS is APPLE and also UNIX ! -if(APPLE) - set_target_properties(l_master PROPERTIES - SUFFIX ".so" - INSTALL_RPATH "@loader_path;@loader_path/../../${PYTHON_PROJECT}/.libs" - ) - set_property(TARGET l_master APPEND PROPERTY - LINK_FLAGS "-flat_namespace -undefined suppress" - ) -elseif(UNIX) +if(UNIX) set_target_properties(l_master PROPERTIES INSTALL_RPATH "$ORIGIN:$ORIGIN/../${PYTHON_PROJECT}/.libs" ) @@ -58,16 +49,7 @@ target_include_directories(zeroconf ) set_property(TARGET zeroconf PROPERTY SWIG_USE_TARGET_INCLUDE_DIRECTORIES ON) -# note: macOS is APPLE and also UNIX ! -if(APPLE) - set_target_properties(zeroconf PROPERTIES - SUFFIX ".so" - INSTALL_RPATH "@loader_path;@loader_path/../../${PYTHON_PROJECT}/.libs" - ) - set_property(TARGET zeroconf APPEND PROPERTY - LINK_FLAGS "-flat_namespace -undefined suppress" - ) -elseif(UNIX) +if(UNIX) set_target_properties(zeroconf PROPERTIES INSTALL_RPATH "$ORIGIN:$ORIGIN/../${PYTHON_PROJECT}/.libs" ) diff --git a/sdk/src/jsonrpc_connector.cc b/sdk/src/jsonrpc_connector.cc index d22ab99..f9a2668 100755 --- a/sdk/src/jsonrpc_connector.cc +++ b/sdk/src/jsonrpc_connector.cc @@ -111,6 +111,8 @@ JSONRpcConnector::~JSONRpcConnector(){} // } // } + + int JSONRpcConnector::CallRpc(const std::string & method, const std::string & req_data_str, std::string * resp_data_str) { int call_jsonrpc_id = jsonrpc_id_++; diff --git a/sdk/src/robot.cc b/sdk/src/robot.cc index f9c37de..4d36496 100644 --- a/sdk/src/robot.cc +++ b/sdk/src/robot.cc @@ -471,7 +471,7 @@ std::vector Robot::get_target_joint_speed() CartesianPose Robot::get_actual_tcp_pose() { - const auto & pose = impl_->getKinData().actual_tcp_pose(); + auto pose = impl_->getKinData().actual_tcp_pose(); CartesianPose cart_pose; cart_pose["x"] = pose.position().x(); cart_pose["y"] = pose.position().y(); @@ -486,7 +486,7 @@ CartesianPose Robot::get_actual_tcp_pose() } CartesianPose Robot::get_target_tcp_pose() { - const auto & pose = impl_->getKinData().target_tcp_pose(); + auto pose = impl_->getKinData().target_tcp_pose(); CartesianPose cart_pose; cart_pose["x"] = pose.position().x(); cart_pose["y"] = pose.position().y(); diff --git a/sdk/src/websocket.hh b/sdk/src/websocket.hh index 106abf2..628b0f0 100644 --- a/sdk/src/websocket.hh +++ b/sdk/src/websocket.hh @@ -35,6 +35,7 @@ #include #include "protos/utils.hh" + namespace lebai { typedef websocketpp::client WSClient; @@ -53,14 +54,15 @@ namespace lebai void onOpen(WSClient *c, websocketpp::connection_hdl hdl) { + std::lock_guard guard(status_mutex_); status_ = "Open"; - WSClient::connection_ptr con = c->get_con_from_hdl(hdl); server_ = con->get_response_header("Server"); } void onFail(WSClient *c, websocketpp::connection_hdl hdl) { + std::lock_guard guard(status_mutex_); status_ = "Failed"; WSClient::connection_ptr con = c->get_con_from_hdl(hdl); server_ = con->get_response_header("Server"); @@ -69,6 +71,7 @@ namespace lebai void onClose(WSClient *c, websocketpp::connection_hdl hdl) { + std::lock_guard guard(status_mutex_); status_ = "Closed"; WSClient::connection_ptr con = c->get_con_from_hdl(hdl); std::stringstream s; @@ -115,7 +118,10 @@ namespace lebai int getID() const { return id_; } - std::string getStatus() const { return status_; } + std::string getStatus() { + std::lock_guard guard(status_mutex_); + return status_; + } // void record_sent_message(std::string message) { // m_messages.push_back(">> " + message); @@ -142,6 +148,7 @@ namespace lebai std::string server_; std::string error_reason_; std::mutex promises_map_mutex_; + std::mutex status_mutex_; }; // std::ostream& operator<<(std::ostream& out, ConnectionMetadata const& data) { @@ -259,7 +266,6 @@ namespace lebai bool send(int id, std::string message) { - websocketpp::lib::error_code ec; ConList::iterator metadata_it = connection_list_.find(id);