From 36b2170b3ec70e6ab03f169226c068118a9e5f43 Mon Sep 17 00:00:00 2001 From: liufang-robot <61956285+liufang-robot@users.noreply.github.com> Date: Mon, 13 Feb 2023 20:34:42 +0800 Subject: [PATCH] =?UTF-8?q?1.0.17=E7=89=88=E6=9C=AC=20(#33)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * fix: 完善文档,添加dotnet的文档。 * fix: 修正linux_python_build.yml重复编译的问题,以及没有指定PYTHONPATH的问题。 * feat: 添加python2的构建选项 修正旋转部分数据表示x和z反了的问题 完善文档 --- CMakeLists.txt | 18 ++- Doxyfile | 2 +- README.md | 11 +- cmake/python.cmake | 2 +- cmake/python2.cmake | 246 +++++++++++++++++++++++++++++++++++++ doc/changelog.md | 6 + doc/dotnet.md | 4 + examples/example.cs | 3 +- python/setup.py.in | 2 +- sdk/CMakeLists.txt | 2 +- sdk/include/lebai/robot.hh | 48 ++++---- sdk/python/CMakeLists.txt | 29 ++++- sdk/src/robot.cc | 24 ++-- sdk/src/robot_impl.cc | 2 +- sdk/src/robot_impl.hh | 2 + sdk/test/test_robot.cc | 27 ++-- 16 files changed, 367 insertions(+), 61 deletions(-) create mode 100644 cmake/python2.cmake diff --git a/CMakeLists.txt b/CMakeLists.txt index ec97156..7150d56 100644 --- 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.16 LANGUAGES CXX) +project(lebai VERSION 1.0.17 LANGUAGES CXX) set(PROJECT_NAMESPACE lebai) message(STATUS "${PROJECT_NAME} version: ${PROJECT_VERSION}") # message(STATUS "major: ${PROJECT_VERSION_MAJOR}") @@ -82,12 +82,19 @@ message(STATUS "Build C++ library: ${BUILD_CXX}") option(BUILD_PYTHON "Build Python Library" OFF) message(STATUS "Build Python: ${BUILD_PYTHON}") +option(BUILD_PYTHON2 "Build Python2 Library" OFF) +message(STATUS "Build Python2: ${BUILD_PYTHON2}") + option(BUILD_DOTNET "Build .NET Library" OFF) message(STATUS "Build .Net: ${BUILD_DOTNET}") option(BUILD_JAVA "Build Java Library" OFF) message(STATUS "Build Java: ${BUILD_JAVA}") +if(BUILD_PYTHON AND BUILD_PYTHON2) + message(FATAL_ERROR "Can only build one of python2 and python3.") +endif() + if(BUILD_PYTHON) option(FETCH_PYTHON_DEPS "Install python required modules if not available" ON) message(STATUS "Python fetch dependencies: ${FETCH_PYTHON_DEPS}") @@ -97,6 +104,13 @@ if(BUILD_PYTHON) endif() endif() +if(BUILD_PYTHON2) + if(DEFINED PYTHONPATH) + message(STATUS "Python path: ${PYTHON2PATH}") + set(Python2_ROOT_DIR ${PYTHONPATH}) + endif() +endif() + # Disable CTest targets set_property(GLOBAL PROPERTY CTEST_TARGETS_ADDED 1) include(CTest) @@ -115,6 +129,8 @@ if(BUILD_PYTHON) endif() include(python) +include(python2) + if(BUILD_DOTNET) # .Net Core 3.1 LTS is not available for osx arm64 diff --git a/Doxyfile b/Doxyfile index 4502b16..594036a 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.16 +PROJECT_NUMBER = 1.0.17 # 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 02e1e85..ffa4abd 100755 --- a/README.md +++ b/README.md @@ -7,6 +7,8 @@ lebai-sdk的源代码仓库,可以用于控制乐白机械臂. **上图中显示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 @@ -66,8 +68,10 @@ sudo apt install build-essential python3-pip dpkg-dev sudo pip3 install -i https://pypi.tuna.tsinghua.edu.cn/simple -r requirements.txt # 如果需要生成文档,还需要安装doxygen sudo apt install doxygen graphviz -# 如果需要生成python的wrapper包 -sudo apt install python3-dev +# 如果需要生成python3的wrapper包 +sudo apt install python3-dev python3-setuptools +# 如果需要生成python2的wrapper包 +sudo apt install python-dev python-setuptools ``` @@ -100,7 +104,8 @@ cpack ## 编译选项 - - BUILD_PYTHON: 是否编译python接口 默认为OFF + - BUILD_PYTHON: 是否编译python3接口 默认为OFF + - BUILD_PYTHON2: 是否编译python2接口 默认为OFF - PYTHONPATH: PYTHON的安装目录 - BUILD_DOTNET: 是否编译.NET接口 默认为OFF(请先安装好.NET的开发环境) - BUILD_JAVA: 是否编译JAVA接口 默认为OFF(请先安装好JDK和Maven) diff --git a/cmake/python.cmake b/cmake/python.cmake index 8f78eff..45f1773 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" "-DPY3") # Find if the python module is available, # otherwise install it (PACKAGE_NAME) to the Python3 user install directory. diff --git a/cmake/python2.cmake b/cmake/python2.cmake new file mode 100644 index 0000000..414a739 --- /dev/null +++ b/cmake/python2.cmake @@ -0,0 +1,246 @@ +if(NOT BUILD_PYTHON2) + return() +endif() + +cmake_minimum_required(VERSION 3.18) + +# Will need swig +set(CMAKE_SWIG_FLAGS) +find_package(SWIG REQUIRED) +include(UseSWIG) + +if(${SWIG_VERSION} VERSION_GREATER_EQUAL 4) + list(APPEND CMAKE_SWIG_FLAGS "-doxygen") +endif() + +if(UNIX AND NOT APPLE) + list(APPEND CMAKE_SWIG_FLAGS "-DSWIGWORDSIZE64") +endif() + +# Find Python 2 +find_package(Python2 COMPONENTS Interpreter Development REQUIRED) +list(APPEND CMAKE_SWIG_FLAGS "-threads") + +# Find if the python module is available, +# otherwise install it (PACKAGE_NAME) to the Python3 user install directory. +# If CMake option FETCH_PYTHON_DEPS is OFF then issue a fatal error instead. +# e.g +# search_python_module( +# NAME +# mypy_protobuf +# PACKAGE +# mypy-protobuf +# NO_VERSION +# ) +function(search_python_module) + set(options NO_VERSION) + set(oneValueArgs NAME PACKAGE) + set(multiValueArgs "") + cmake_parse_arguments(MODULE + "${options}" + "${oneValueArgs}" + "${multiValueArgs}" + ${ARGN} + ) + message(STATUS "Searching python module: \"${MODULE_NAME}\"") + if(${MODULE_NO_VERSION}) + execute_process( + COMMAND ${Python2_EXECUTABLE} -c "import ${MODULE_NAME}" + RESULT_VARIABLE _RESULT + ERROR_QUIET + OUTPUT_STRIP_TRAILING_WHITESPACE + ) + set(MODULE_VERSION "unknown") + else() + execute_process( + COMMAND ${Python2_EXECUTABLE} -c "import ${MODULE_NAME}; print(${MODULE_NAME}.__version__)" + RESULT_VARIABLE _RESULT + OUTPUT_VARIABLE MODULE_VERSION + ERROR_QUIET + OUTPUT_STRIP_TRAILING_WHITESPACE + ) + endif() + if(${_RESULT} STREQUAL "0") + message(STATUS "Found python module: \"${MODULE_NAME}\" (found version \"${MODULE_VERSION}\")") + else() + if(FETCH_PYTHON_DEPS) + message(WARNING "Can't find python module: \"${MODULE_NAME}\", install it using pip...") + execute_process( + COMMAND ${Python2_EXECUTABLE} -m pip install --user ${MODULE_PACKAGE} + OUTPUT_STRIP_TRAILING_WHITESPACE + ) + else() + message(FATAL_ERROR "Can't find python module: \"${MODULE_NAME}\", please install it using your system package manager.") + endif() + endif() +endfunction() + +function(search_python_internal_module) + set(options "") + set(oneValueArgs NAME) + set(multiValueArgs "") + cmake_parse_arguments(MODULE + "${options}" + "${oneValueArgs}" + "${multiValueArgs}" + ${ARGN} + ) + message(STATUS "Searching python module: \"${MODULE_NAME}\"") + execute_process( + COMMAND ${Python2_EXECUTABLE} -c "import ${MODULE_NAME}" + RESULT_VARIABLE _RESULT + ERROR_QUIET + OUTPUT_STRIP_TRAILING_WHITESPACE + ) + if(${_RESULT} STREQUAL "0") + message(STATUS "Found python internal module: \"${MODULE_NAME}\"") + else() + message(FATAL_ERROR "Can't find python internal module \"${MODULE_NAME}\", please install it using your system package manager.") + endif() +endfunction() + +set(PYTHON_PROJECT lebai) +set(PYTHON_PROJECT_DIR ${PROJECT_BINARY_DIR}/python/${PYTHON_PROJECT}) +message(STATUS "Python project build path: ${PYTHON_PROJECT_DIR}") + +# Swig wrap sdk +foreach(SUBPROJECT IN ITEMS sdk) + add_subdirectory(${SUBPROJECT}/python) +endforeach() + +####################### +## Python Packaging ## +####################### +#file(MAKE_DIRECTORY python/${PYTHON_PROJECT}) +file(GENERATE OUTPUT ${PYTHON_PROJECT_DIR}/__init__.py CONTENT "__version__ = \"${PROJECT_VERSION}\"\n") +# file(GENERATE OUTPUT ${PYTHON_PROJECT_DIR}/__init__.py CONTENT "") + +configure_file( + ${PROJECT_SOURCE_DIR}/python/setup.py.in + ${PROJECT_BINARY_DIR}/python/setup.py.in + @ONLY) +file(GENERATE + OUTPUT ${PROJECT_BINARY_DIR}/python/setup.py + INPUT ${PROJECT_BINARY_DIR}/python/setup.py.in) + +#add_custom_command( +# OUTPUT python/setup.py +# DEPENDS ${PROJECT_BINARY_DIR}/python/setup.py +# COMMAND ${CMAKE_COMMAND} -E copy setup.py setup.py +# WORKING_DIRECTORY python) + +# Look for python module wheel +search_python_module( + NAME setuptools + PACKAGE setuptools) +search_python_module( + NAME wheel + PACKAGE wheel) + +add_custom_command( + OUTPUT python/dist/timestamp + COMMAND ${CMAKE_COMMAND} -E remove_directory dist + COMMAND ${CMAKE_COMMAND} -E make_directory ${PYTHON_PROJECT}/.libs + # Don't need to copy static lib on Windows. + COMMAND ${CMAKE_COMMAND} -E $,SHARED_LIBRARY>,copy,true> + $<$,SHARED_LIBRARY>:$> + ${PYTHON_PROJECT}/.libs + # COMMAND ${CMAKE_COMMAND} -E copy $ ${PYTHON_PROJECT}/ + # COMMAND ${CMAKE_COMMAND} -E copy $ ${PYTHON_PROJECT}/ + # COMMAND ${CMAKE_COMMAND} -E copy $ ${PYTHON_PROJECT}/ + COMMAND ${CMAKE_COMMAND} -E copy $ ${PYTHON_PROJECT}/ + COMMAND ${CMAKE_COMMAND} -E copy $ ${PYTHON_PROJECT}/ + # COMMAND ${Python3_EXECUTABLE} setup.py bdist_egg bdist_wheel + COMMAND ${Python2_EXECUTABLE} setup.py bdist_wheel + COMMAND ${CMAKE_COMMAND} -E touch ${PROJECT_BINARY_DIR}/python/dist/timestamp + MAIN_DEPENDENCY + python/setup.py.in + DEPENDS + python/setup.py + ${PROJECT_NAMESPACE}::lebai-cpp + # ${PROJECT_NAMESPACE}::posture + # ${PROJECT_NAMESPACE}::motion + ${PROJECT_NAMESPACE}::l_master + ${PROJECT_NAMESPACE}::zeroconf + BYPRODUCTS + python/${PYTHON_PROJECT} + python/${PYTHON_PROJECT}.egg-info + python/build + python/dist + WORKING_DIRECTORY python + COMMAND_EXPAND_LISTS) + +# Main Target +add_custom_target(python_package ALL + DEPENDS + python/dist/timestamp + WORKING_DIRECTORY python) + +################### +## Python Test ## +################### +# if(BUILD_TESTING) +# search_python_module(NAME virtualenv PACKAGE virtualenv) +# # venv not working on github windows runners +# # search_python_internal_module(NAME venv) +# # Testing using a vitual environment +# set(VENV_EXECUTABLE ${Python3_EXECUTABLE} -m virtualenv) +# #set(VENV_EXECUTABLE ${Python3_EXECUTABLE} -m venv) +# set(VENV_DIR ${CMAKE_CURRENT_BINARY_DIR}/python/venv) +# if(WIN32) +# set(VENV_Python3_EXECUTABLE ${VENV_DIR}/Scripts/python.exe) +# else() +# set(VENV_Python3_EXECUTABLE ${VENV_DIR}/bin/python) +# endif() +# # make a virtualenv to install our python package in it +# add_custom_command(TARGET python_package POST_BUILD +# # Clean previous install otherwise pip install may do nothing +# COMMAND ${CMAKE_COMMAND} -E remove_directory ${VENV_DIR} +# COMMAND ${VENV_EXECUTABLE} -p ${Python3_EXECUTABLE} ${VENV_DIR} +# #COMMAND ${VENV_EXECUTABLE} ${VENV_DIR} +# # Must NOT call it in a folder containing the setup.py otherwise pip call it +# # (i.e. "python setup.py bdist") while we want to consume the wheel package +# COMMAND ${VENV_Python3_EXECUTABLE} -m pip install --find-links=${CMAKE_CURRENT_BINARY_DIR}/python/dist ${PYTHON_PROJECT} +# BYPRODUCTS ${VENV_DIR} +# WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} +# COMMENT "Create venv and install ${PYTHON_PROJECT}" +# VERBATIM) +# endif() + +# add_python_test() +# CMake function to generate and build python test. +# Parameters: +# the python filename +# e.g.: +# add_python_test(foo.py) +# function(add_python_test FILE_NAME) +# message(STATUS "Configuring test ${FILE_NAME} ...") +# get_filename_component(EXAMPLE_NAME ${FILE_NAME} NAME_WE) + +# if(BUILD_TESTING) +# add_test( +# NAME python_test_${EXAMPLE_NAME} +# COMMAND ${VENV_Python3_EXECUTABLE} ${FILE_NAME} +# WORKING_DIRECTORY ${VENV_DIR}) +# endif() +# message(STATUS "Configuring test ${FILE_NAME} done") +# endfunction() + +# add_python_example() +# CMake function to generate and build python example. +# Parameters: +# the python filename +# e.g.: +# add_python_example(foo.py) +# function(add_python_example FILE_NAME) +# message(STATUS "Configuring example ${FILE_NAME} ...") +# get_filename_component(EXAMPLE_NAME ${FILE_NAME} NAME_WE) + +# if(BUILD_TESTING) +# add_test( +# NAME python_example_${EXAMPLE_NAME} +# COMMAND ${VENV_Python3_EXECUTABLE} ${FILE_NAME} +# WORKING_DIRECTORY ${VENV_DIR}) +# endif() +# message(STATUS "Configuring example ${FILE_NAME} done") +# endfunction() diff --git a/doc/changelog.md b/doc/changelog.md index a18b69e..d5e8ba4 100644 --- a/doc/changelog.md +++ b/doc/changelog.md @@ -1,5 +1,11 @@ # ChangeLog +## 1.0.17 + +添加python2的构建选项 +修正旋转部分数据表示x和z反了的问题 +完善文档 + ## 1.0.14 文档更新,持续集成更新,修正程序的错误 diff --git a/doc/dotnet.md b/doc/dotnet.md index d370b58..df472b6 100644 --- a/doc/dotnet.md +++ b/doc/dotnet.md @@ -1,5 +1,9 @@ # .net平台应用文档 +<<<<<<< HEAD +**目前.net仅支持linux平台,windows平台还存在问题.** +======= +>>>>>>> eaa388d5ed4303d406026c6b7d2b632bd30a6374 [Nuget包地址](https://www.nuget.org/packages/lebai/) diff --git a/examples/example.cs b/examples/example.cs index b275118..f8462d4 100644 --- a/examples/example.cs +++ b/examples/example.cs @@ -1,6 +1,5 @@ using System; using lebai.l_master; - namespace lebai.app { class Program @@ -8,7 +7,7 @@ class Program static void Main(string[] args) { Console.WriteLine($"Enter example"); - Robot robot = new Robot("192.168.1.100", true); + Robot robot = new Robot("127.0.0.1", true); robot.stop_sys(); Console.WriteLine($"stop..."); robot.start_sys(); diff --git a/python/setup.py.in b/python/setup.py.in index 8df0266..a2a0669 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", encoding='UTF-8') as fh: +with open(r"../../README.md", "r") as fh: long_description = fh.read() setup( diff --git a/sdk/CMakeLists.txt b/sdk/CMakeLists.txt index 7d7916f..51a9230 100755 --- a/sdk/CMakeLists.txt +++ b/sdk/CMakeLists.txt @@ -25,7 +25,7 @@ set_target_properties(lebai-cpp PROPERTIES ) add_library(${PROJECT_NAMESPACE}::lebai-cpp ALIAS lebai-cpp) - +option(BUILD_TESTING "Build test" ON) if(BUILD_TESTING) add_subdirectory(test) endif() diff --git a/sdk/include/lebai/robot.hh b/sdk/include/lebai/robot.hh index 2e12bfb..d3584db 100644 --- a/sdk/include/lebai/robot.hh +++ b/sdk/include/lebai/robot.hh @@ -223,11 +223,11 @@ namespace lebai * * @brief 通过关节位置发送机械臂关节移动 * @note 该接口为异步接口,仅向控制器内部的运动缓冲区写入一个关节移动即返回,不会等待运动结束. - * @param[in] joint_positions: 目标位置的关节数据,为关节的角度值构成的数组. - * @param[in] a: 加速度. - * @param[in] v: 速度. - * @param[in] t: 时间参数,如果设置时间不为零,则按照时间计算出速度,而不使用速度参数. - * @param[in] r: 交融半径,设置为0,则无交融半径. + * @param[in] joint_positions 目标位置的关节数据,为关节的角度值构成的数组. + * @param[in] a 加速度 + * @param[in] v 速度 + * @param[in] t 时间参数,如果设置时间不为零,则按照时间计算出速度,而不使用速度参数. + * @param[in] r 交融半径,设置为0,则无交融半径. * @return >0 发送成功 * @return <=0 发送失败 * @@ -241,11 +241,11 @@ namespace lebai * * @brief 通过坐标位置发送机械臂关节移动 * @note 该接口为异步接口,仅向控制器内部的运动缓冲区写入一个关节移动即返回,不会等待运动结束. - * @param[in] cart_pose: 目标位置在机器人基座标系下的坐标数据(目前不支持在其它坐标系下的坐标数据),CartesianPose = std::map,应当包括键为x,y,z,rz,ry,rx的值. - * @param[in] a: 加速度 - * @param[in] v: 速度 - * @param[in] t: 时间参数,如果设置时间不为零,则按照时间计算出速度,而不使用速度参数. - * @param[in] r: 交融半径,设置为0,则无交融半径. + * @param[in] cart_pose 目标位置在机器人基座标系下的坐标数据(目前不支持在其它坐标系下的坐标数据),CartesianPose = std::map,应当包括键为x,y,z,rz,ry,rx的值. + * @param[in] a 加速度. + * @param[in] v 速度. + * @param[in] t 时间参数,如果设置时间不为零,则按照时间计算出速度,而不使用速度参数. + * @param[in] r 交融半径,设置为0,则无交融半径. * @return >0 发送成功 * @return <=0 发送失败 */ @@ -260,10 +260,10 @@ namespace lebai * @brief 通过关节位置发送机械臂直线移动 * @note 该接口为异步接口,仅向控制器内部的运动缓冲区写入一个关节移动即返回,不会等待运动结束. * @param[in] joint_positions: 目标位置的关节数据,为关节的角度值构成的数组. - * @param[in] a: 加速度 - * @param[in] v: 速度 - * @param[in] t: 时间参数,如果设置时间不为零,则按照时间计算出速度,而不使用速度参数. - * @param[in] r: 交融半径,设置为0,则无交融半径. + * @param[in] a 加速度. + * @param[in] v 速度. + * @param[in] t 时间参数,如果设置时间不为零,则按照时间计算出速度,而不使用速度参数. + * @param[in] r 交融半径,设置为0,则无交融半径. * @return >0 发送成功 * @return <=0 发送失败 */ @@ -276,11 +276,11 @@ namespace lebai * * @brief 通过坐标位置发送机械臂直线移动 * @note 该接口为异步接口,仅向控制器内部的运动缓冲区写入一个关节移动即返回,不会等待运动结束. - * @param cart_pose: 目标位置在机器人基座标系下的坐标数据(目前不支持在其它坐标系下的坐标数据),CartesianPose = std::map,应当包括键为x,y,z,rz,ry,rx的值. - * @param a: 加速度. - * @param v: 速度. - * @param t: 时间参数,如果设置时间不为零,则按照时间计算出速度,而不使用速度参数. - * @param r: 交融半径,设置为0,则无交融半径. + * @param cart_pose 目标位置在机器人基座标系下的坐标数据(目前不支持在其它坐标系下的坐标数据),CartesianPose = std::map,应当包括键为x,y,z,rz,ry,rx的值. + * @param a 加速度. + * @param v 速度. + * @param t 时间参数,如果设置时间不为零,则按照时间计算出速度,而不使用速度参数. + * @param r 交融半径,设置为0,则无交融半径. * @return >0 发送成功. * @return <=0 发送失败. */ @@ -559,7 +559,7 @@ namespace lebai bool set_dio(unsigned int pin, bool value); /** * @brief 设置数字端口模式 - * @param pin: 端口号,从 0 开始 + * @param pin 端口号,从 0 开始 * @param value 设置的值,false为输入模式,true为输出模式 * @return 返回是否成功 */ @@ -573,8 +573,8 @@ namespace lebai std::vector get_dios(unsigned int pin, unsigned int count); /** * @brief 获取数字端口模式 - * @param pin: 端口号,从 0 开始 - * @param count:查询的连续端口数 + * @param pin 端口号,从 0 开始 + * @param count 查询的连续端口数 * @return 从pin开始的连续count个端口的当前模式 */ std::vector get_dios_mode(unsigned int pin, unsigned int count); @@ -587,8 +587,8 @@ namespace lebai /** * @brief 设置夹爪力度(力控)和幅度(位控).如果在闭合过程中抓取到物体,则不再继续闭合以避免夹坏物体,判断的准则为这里设置的力的大小. * - * @param force: 力度(0-100) - * @param amplitude: 张合幅度(0-100) + * @param force 力度(0-100) + * @param amplitude 张合幅度(0-100) */ void set_claw(double force, double amplitude); /** diff --git a/sdk/python/CMakeLists.txt b/sdk/python/CMakeLists.txt index f1da554..237c892 100755 --- a/sdk/python/CMakeLists.txt +++ b/sdk/python/CMakeLists.txt @@ -11,8 +11,19 @@ target_include_directories(l_master PRIVATE ${PROJECT_SOURCE_DIR}/sdk/include ${PROJECT_SOURCE_DIR}/sdk/src - ${Python3_INCLUDE_DIRS} +) +if(BUILD_PYTHON) + target_include_directories(l_master + PRIVATE + ${Python3_INCLUDE_DIRS} ) +elseif(BUILD_PYTHON2) + target_include_directories(l_master + PRIVATE + ${Python2_INCLUDE_DIRS} + ) +endif() + set_property(TARGET l_master PROPERTY SWIG_USE_TARGET_INCLUDE_DIRECTORIES ON) if(UNIX) @@ -27,7 +38,7 @@ target_link_libraries(l_master PRIVATE ${PROJECT_NAMESPACE}::lebai-cpp) # i.e. we can't use: $<$:${PYTHON_LIBRARIES}> # see: https://cmake.org/cmake/help/git-stage/command/target_link_libraries.html#command:target_link_libraries if(MSVC) - target_link_libraries(l_master PRIVATE ${Python3_LIBRARIES}) + target_link_libraries(l_master PRIVATE ${Python2_LIBRARIES} ${Python3_LIBRARIES}) endif() @@ -45,8 +56,18 @@ target_include_directories(zeroconf ${PROJECT_SOURCE_DIR}/sdk/include ${PROJECT_SOURCE_DIR}/sdk/include/zeroconf ${PROJECT_SOURCE_DIR}/sdk/src - ${Python3_INCLUDE_DIRS} +) +if(BUILD_PYTHON) + target_include_directories(zeroconf + PRIVATE + ${Python3_INCLUDE_DIRS} ) +elseif(BUILD_PYTHON2) + target_include_directories(zeroconf + PRIVATE + ${Python2_INCLUDE_DIRS} + ) +endif() set_property(TARGET zeroconf PROPERTY SWIG_USE_TARGET_INCLUDE_DIRECTORIES ON) if(UNIX) @@ -61,5 +82,5 @@ target_link_libraries(zeroconf PRIVATE ${PROJECT_NAMESPACE}::lebai-cpp) # i.e. we can't use: $<$:${PYTHON_LIBRARIES}> # see: https://cmake.org/cmake/help/git-stage/command/target_link_libraries.html#command:target_link_libraries if(MSVC) - target_link_libraries(zeroconf PRIVATE ${Python3_LIBRARIES}) + target_link_libraries(zeroconf PRIVATE ${Python2_LIBRARIES} ${Python3_LIBRARIES}) endif() diff --git a/sdk/src/robot.cc b/sdk/src/robot.cc index 4d36496..61bf6ec 100644 --- a/sdk/src/robot.cc +++ b/sdk/src/robot.cc @@ -145,7 +145,7 @@ int Robot::movej(const CartesianPose & cart_pose, double a, double v, double t, } if(cart_pose.find("rx") != cart_pose.end()) { - move_req.mutable_pose()->mutable_cart()->mutable_rotation()->mutable_euler_zyx()->set_z(cart_pose.at("rx")); + move_req.mutable_pose()->mutable_cart()->mutable_rotation()->mutable_euler_zyx()->set_x(cart_pose.at("rx")); } else { @@ -161,7 +161,7 @@ int Robot::movej(const CartesianPose & cart_pose, double a, double v, double t, } if(cart_pose.find("rz") != cart_pose.end()) { - move_req.mutable_pose()->mutable_cart()->mutable_rotation()->mutable_euler_zyx()->set_x(cart_pose.at("rz")); + move_req.mutable_pose()->mutable_cart()->mutable_rotation()->mutable_euler_zyx()->set_z(cart_pose.at("rz")); } else { @@ -220,7 +220,7 @@ int Robot::movel(const CartesianPose & cart_pose, double a, double v, double t, } if(cart_pose.find("rx") != cart_pose.end()) { - move_req.mutable_pose()->mutable_cart()->mutable_rotation()->mutable_euler_zyx()->set_z(cart_pose.at("rx")); + move_req.mutable_pose()->mutable_cart()->mutable_rotation()->mutable_euler_zyx()->set_x(cart_pose.at("rx")); } else { @@ -236,7 +236,7 @@ int Robot::movel(const CartesianPose & cart_pose, double a, double v, double t, } if(cart_pose.find("rz") != cart_pose.end()) { - move_req.mutable_pose()->mutable_cart()->mutable_rotation()->mutable_euler_zyx()->set_x(cart_pose.at("rz")); + move_req.mutable_pose()->mutable_cart()->mutable_rotation()->mutable_euler_zyx()->set_z(cart_pose.at("rz")); } else { @@ -299,7 +299,7 @@ int Robot::movec(const CartesianPose & cart_via, const CartesianPose & cart, dou } if(cart_via.find("rx") != cart_via.end()) { - move_req.mutable_pose_via()->mutable_cart()->mutable_rotation()->mutable_euler_zyx()->set_z(cart_via.at("rx")); + move_req.mutable_pose_via()->mutable_cart()->mutable_rotation()->mutable_euler_zyx()->set_x(cart_via.at("rx")); } else { @@ -315,7 +315,7 @@ int Robot::movec(const CartesianPose & cart_via, const CartesianPose & cart, dou } if(cart_via.find("rz") != cart_via.end()) { - move_req.mutable_pose_via()->mutable_cart()->mutable_rotation()->mutable_euler_zyx()->set_x(cart_via.at("rz")); + move_req.mutable_pose_via()->mutable_cart()->mutable_rotation()->mutable_euler_zyx()->set_z(cart_via.at("rz")); } else { @@ -347,7 +347,7 @@ int Robot::movec(const CartesianPose & cart_via, const CartesianPose & cart, dou } if(cart.find("rx") != cart.end()) { - move_req.mutable_pose()->mutable_cart()->mutable_rotation()->mutable_euler_zyx()->set_z(cart.at("rx")); + move_req.mutable_pose()->mutable_cart()->mutable_rotation()->mutable_euler_zyx()->set_x(cart.at("rx")); } else { @@ -363,7 +363,7 @@ int Robot::movec(const CartesianPose & cart_via, const CartesianPose & cart, dou } if(cart.find("rz") != cart.end()) { - move_req.mutable_pose()->mutable_cart()->mutable_rotation()->mutable_euler_zyx()->set_x(cart.at("rz")); + move_req.mutable_pose()->mutable_cart()->mutable_rotation()->mutable_euler_zyx()->set_z(cart.at("rz")); } else { @@ -478,9 +478,9 @@ CartesianPose Robot::get_actual_tcp_pose() cart_pose["z"] = pose.position().z(); if(pose.rotation().euler_zyx()) { - cart_pose["rz"] = pose.rotation().euler_zyx()->x(); + cart_pose["rx"] = pose.rotation().euler_zyx()->x(); cart_pose["ry"] = pose.rotation().euler_zyx()->y(); - cart_pose["rx"] = pose.rotation().euler_zyx()->z(); + cart_pose["rz"] = pose.rotation().euler_zyx()->z(); } return cart_pose; } @@ -493,9 +493,9 @@ CartesianPose Robot::get_target_tcp_pose() cart_pose["z"] = pose.position().z(); if(pose.rotation().euler_zyx()) { - cart_pose["rz"] = pose.rotation().euler_zyx()->x(); + cart_pose["rx"] = pose.rotation().euler_zyx()->x(); cart_pose["ry"] = pose.rotation().euler_zyx()->y(); - cart_pose["rx"] = pose.rotation().euler_zyx()->z(); + cart_pose["rz"] = pose.rotation().euler_zyx()->z(); } return cart_pose; } diff --git a/sdk/src/robot_impl.cc b/sdk/src/robot_impl.cc index 4781371..2c5fa73 100644 --- a/sdk/src/robot_impl.cc +++ b/sdk/src/robot_impl.cc @@ -26,7 +26,7 @@ namespace lebai namespace l_master { Robot::RobotImpl::RobotImpl(const ::std::string &ip, bool simulator) { - uint16_t port = simulator ? 3030 : 3031; + uint16_t port = simulator ? simulation_port_ : physical_machine_port_; json_rpc_connector_ = std::make_unique(ip, port); unsigned int i = 0; unsigned int count = timeout_ / 0.1; diff --git a/sdk/src/robot_impl.hh b/sdk/src/robot_impl.hh index 7c8b81e..760c71d 100644 --- a/sdk/src/robot_impl.hh +++ b/sdk/src/robot_impl.hh @@ -130,6 +130,8 @@ namespace lebai protected: std::unique_ptr json_rpc_connector_; double timeout_ = 1.0; + const uint16_t simulation_port_ = 3030; + const uint16_t physical_machine_port_ = 3031; // int jsonrpc_id_ = 0; // WebSocketEndPoint endpoint_; }; diff --git a/sdk/test/test_robot.cc b/sdk/test/test_robot.cc index 260bc3f..542bbac 100644 --- a/sdk/test/test_robot.cc +++ b/sdk/test/test_robot.cc @@ -85,6 +85,13 @@ namespace lebai std::this_thread::sleep_for(std::chrono::milliseconds(100)); EXPECT_EQ(7, robot_.get_robot_mode()); robot_.wait_move(); + auto tcp = robot_.get_target_tcp_pose(); + EXPECT_NEAR(tcp["x"], -0.296, 1e-3); + EXPECT_NEAR(tcp["y"], -0.162, 1e-3); + EXPECT_NEAR(tcp["z"], 0.285, 1e-3); + EXPECT_NEAR(tcp["rz"], 60.0 / 180.0 * M_PI, 1e-2); + EXPECT_NEAR(tcp["ry"], -5.0 / 180.0 * M_PI, 1e-2); + EXPECT_NEAR(tcp["rx"], 81.0 / 180.0 * M_PI, 1e-2); auto jp = robot_.get_target_joint_positions(); ASSERT_EQ(6, jp.size()); EXPECT_NEAR(jp[0], joint_positions[0], 1e-3); @@ -95,17 +102,17 @@ namespace lebai EXPECT_NEAR(jp[5], joint_positions[5], 1e-3); std::this_thread::sleep_for(std::chrono::milliseconds(200)); EXPECT_EQ(5, robot_.get_robot_mode()); - robot_.movej({{"x",-0.296},{"y",-0.295},{"z",0.285},{"rz",60.0 / 180.0 * M_PI},{"ry",-5.0 / 180.0 * M_PI},{"rx", 81.0 / 180.0 * M_PI}}, 3.0, 1.0, 0.0, 0.0); + robot_.movej({{"x",-0.296},{"y",-0.295},{"z",0.285},{"rx",60.0 / 180.0 * M_PI},{"ry",-5.0 / 180.0 * M_PI},{"rz", 81.0 / 180.0 * M_PI}}, 3.0, 1.0, 0.0, 0.0); // std::this_thread::sleep_for(std::chrono::milliseconds(100)); EXPECT_EQ(7, robot_.get_robot_mode()); robot_.wait_move(0); - auto tcp = robot_.get_target_tcp_pose(); + tcp = robot_.get_target_tcp_pose(); EXPECT_NEAR(tcp["x"], -0.296, 1e-3); EXPECT_NEAR(tcp["y"], -0.295, 1e-3); EXPECT_NEAR(tcp["z"], 0.285, 1e-3); - EXPECT_NEAR(tcp["rz"], 60.0 / 180.0 * M_PI, 1e-3); - EXPECT_NEAR(tcp["ry"], -5.0 / 180.0 * M_PI, 1e-3); - EXPECT_NEAR(tcp["rx"], 81.0 / 180.0 * M_PI, 1e-3); + EXPECT_NEAR(tcp["rx"], 60.0 / 180.0 * M_PI, 1e-2); + EXPECT_NEAR(tcp["ry"], -5.0 / 180.0 * M_PI, 1e-2); + EXPECT_NEAR(tcp["rz"], 81.0 / 180.0 * M_PI, 1e-2); joint_positions[0] = 0.0; joint_positions[1] = -60.0 / 180.0 * M_PI; joint_positions[2] = 80.0 / 180.0 * M_PI; @@ -123,7 +130,7 @@ namespace lebai EXPECT_NEAR(jp[3], joint_positions[3], 1e-3); EXPECT_NEAR(jp[4], joint_positions[4], 1e-3); EXPECT_NEAR(jp[5], joint_positions[5], 1e-3); - robot_.movel({{"x",-0.306},{"y",-0.295},{"z",0.285},{"rz",60.0 / 180.0 * M_PI},{"ry",-5.0 / 180.0 * M_PI},{"rx", 81.0 / 180.0 * M_PI}}, 1.0, 0.5, 0.0, 0.0); + robot_.movel({{"x",-0.306},{"y",-0.295},{"z",0.285},{"rx",60.0 / 180.0 * M_PI},{"ry",-5.0 / 180.0 * M_PI},{"rz", 81.0 / 180.0 * M_PI}}, 1.0, 0.5, 0.0, 0.0); // std::this_thread::sleep_for(std::chrono::milliseconds(100)); EXPECT_EQ(7, robot_.get_robot_mode()); robot_.wait_move(); @@ -131,9 +138,9 @@ namespace lebai EXPECT_NEAR(tcp["x"], -0.306, 1e-3); EXPECT_NEAR(tcp["y"], -0.295, 1e-3); EXPECT_NEAR(tcp["z"], 0.285, 1e-3); - EXPECT_NEAR(tcp["rz"], 60.0 / 180.0 * M_PI, 1e-3); - EXPECT_NEAR(tcp["ry"], -5.0 / 180.0 * M_PI, 1e-3); - EXPECT_NEAR(tcp["rx"], 81.0 / 180.0 * M_PI, 1e-3); + EXPECT_NEAR(tcp["rx"], 60.0 / 180.0 * M_PI, 1e-2); + EXPECT_NEAR(tcp["ry"], -5.0 / 180.0 * M_PI, 1e-2); + EXPECT_NEAR(tcp["rz"], 81.0 / 180.0 * M_PI, 1e-2); std::this_thread::sleep_for(std::chrono::milliseconds(200)); EXPECT_EQ(5, robot_.get_robot_mode()); robot_.movej({13.0/ 180.0 * M_PI, -52.0/ 180.0 * M_PI, 86.0/ 180.0 * M_PI, 8.0/ 180.0 * M_PI, -59.0/ 180.0 * M_PI, -11.0/ 180.0 * M_PI}, 1.0, 0.5, 0.0, 0.0); @@ -154,7 +161,7 @@ namespace lebai robot_.movej({13.0/ 180.0 * M_PI, -52.0/ 180.0 * M_PI, 86.0/ 180.0 * M_PI, 8.0/ 180.0 * M_PI, -59.0/ 180.0 * M_PI, -11.0/ 180.0 * M_PI}, 1.0, 0.5, 0.0, 0.0); robot_.movec({{"x", -0.282541}, {"y", -0.168246}, {"z", 0.265824}, {"rx", 1.27256}, {"ry", -0.206353}, {"rz", 0.937445}}, - {{"x", -0.255832}, {"y", 0.00270435}, {"z", 0.266642}, {"rx", 1.27293}, {"ry", -0.20805}, {"rz", 0.94485}}, + {{"x", -0.255832}, {"y", 0.00270435}, {"z", 0.266642}, {"rz", 1.27293}, {"ry", -0.20805}, {"rx", 0.94485}}, 0.0, 1.0, 0.5, 0.0, 0.0); robot_.wait_move(); joint_positions = robot_.get_target_joint_positions();