From 8f3c7fbf3549c19c3468cce2b2361f3d8b729cca Mon Sep 17 00:00:00 2001 From: liufang_robot Date: Mon, 15 May 2023 04:31:51 +0000 Subject: [PATCH 01/20] =?UTF-8?q?feat:=20=E6=B7=BB=E5=8A=A0LuaRobot?= =?UTF-8?q?=EF=BC=8C=E5=92=8C=E6=9C=BA=E6=A2=B0=E8=87=82=E9=87=87=E7=94=A8?= =?UTF-8?q?luasocket=E9=80=9A=E8=AE=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CMakeLists.txt | 2 +- Doxyfile | 10 ++-- README.md | 4 +- doc/changelog.md | 4 ++ examples/example_lua_robot.cc | 63 +++++++++++++++++++ examples/example_online_move.cc | 51 ++++++++++++++++ sdk/CMakeLists.txt | 4 +- sdk/dotnet/l_master.i | 2 + sdk/include/lebai/lua_robot.hh | 103 ++++++++++++++++++++++++++++++++ sdk/include/lebai/robot.hh | 45 ++++++++------ sdk/java/l_master.i | 2 + sdk/python/CMakeLists.txt | 15 ++++- sdk/python/l_master.i | 2 + sdk/src/lua_robot.cc | 60 +++++++++++++++++++ sdk/src/lua_robot_impl.cc | 63 +++++++++++++++++++ sdk/src/lua_robot_impl.hh | 63 +++++++++++++++++++ sdk/test/CMakeLists.txt | 24 ++++++++ sdk/test/test_lua_robot.cc | 72 ++++++++++++++++++++++ 18 files changed, 559 insertions(+), 30 deletions(-) create mode 100644 examples/example_lua_robot.cc create mode 100644 examples/example_online_move.cc create mode 100644 sdk/include/lebai/lua_robot.hh create mode 100644 sdk/src/lua_robot.cc create mode 100644 sdk/src/lua_robot_impl.cc create mode 100644 sdk/src/lua_robot_impl.hh create mode 100644 sdk/test/test_lua_robot.cc diff --git a/CMakeLists.txt b/CMakeLists.txt index df37fba..c206a2c 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.21 LANGUAGES CXX) +project(lebai VERSION 1.1.0 LANGUAGES CXX) set(PROJECT_NAMESPACE lebai) message(STATUS "${PROJECT_NAME} version: ${PROJECT_VERSION}") # message(STATUS "major: ${PROJECT_VERSION_MAJOR}") diff --git a/Doxyfile b/Doxyfile index 5bcacb0..7914cd9 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.21 +PROJECT_NUMBER = 1.1.0 # 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 @@ -811,7 +811,6 @@ FILE_PATTERNS = *.c \ *.cxx \ *.cpp \ *.c++ \ - *.java \ *.ii \ *.ixx \ *.ipp \ @@ -863,7 +862,9 @@ RECURSIVE = YES # Note that relative paths are relative to the directory from which doxygen is # run. -EXCLUDE = +EXCLUDE = *.py \ + *.java \ + *.cs # The EXCLUDE_SYMLINKS tag can be used to select whether or not files or # directories that are symbolic links (a Unix file system feature) are excluded @@ -885,7 +886,8 @@ EXCLUDE_PATTERNS = */cmake/* \ */sdk/python/* \ */sdk/src/* \ */sdk/third/* \ - */sdk/test/* + */sdk/test/* \ + */examples/* # The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names # (namespaces, classes, functions, etc.) that should be excluded from the diff --git a/README.md b/README.md index ffa4abd..2284a57 100755 --- a/README.md +++ b/README.md @@ -7,8 +7,6 @@ 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 @@ -18,6 +16,8 @@ lebai-sdk的源代码仓库,可以用于控制乐白机械臂. [dotnet_windows_svg]: https://github.com/lebai-robotics/lebai-sdk/actions/workflows/windows_dotnet_release.yaml/badge.svg [dotnet_windows_link]: https://github.com/lebai-robotics/lebai-sdk/actions/workflows/windows_dotnet_release.yaml +**SDK使用需要乐白机械臂的控制器软件版本大于等于`3.1.5`,您可以在机械臂WEB界面左上方查看当前版本号.** + [SDK在线文档](http://help.lebai.ltd/sdk/)中包含了lua语言的接口(本项目参考了lua语言进行接口设置,但是本项目和lua语言的接口无直接关系) # 包管理直接安装 diff --git a/doc/changelog.md b/doc/changelog.md index b7f79e2..30ac4d1 100644 --- a/doc/changelog.md +++ b/doc/changelog.md @@ -1,5 +1,9 @@ # ChangeLog +## 1.1.0 + +添加LuaRobot对象,可以向机械臂发送lua指令 + ## 1.0.21 添加is_network_connected方法。 diff --git a/examples/example_lua_robot.cc b/examples/example_lua_robot.cc new file mode 100644 index 0000000..f932753 --- /dev/null +++ b/examples/example_lua_robot.cc @@ -0,0 +1,63 @@ +/** + * Copyright 2022 lebai.ltd + * + * 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. + */ + +#include +#include +#include +#include +#include + +int main(int argc, char **argv) +{ + if (argc != 2) + { + std::cerr << "You must specify the IP address of the robot" << std::endl; + std::cerr << "Execute example as follow:" << std::endl; + std::cerr << "./example 192.168.1.200" << std::endl; + return 0; + } + std::string ip = argv[1]; + bool sim = false; + std::cout << "Connecting to robot at " << ip << std::endl; + + lebai::l_master::LuaRobot lua_robot(ip); + std::this_thread::sleep_for(std::chrono::milliseconds(1000)); + // lua_robot.call("print(start_sys())"); + // lua_robot.send("movej({j1 = 0.0, j2 = 0, j3 = 0, j4 = 0, j5 = 0, j6 = 0}, 1.2, 0.2, 0, 0)") + // lua_robot.send("movej({j1 = 1.0, j2 = 0, j3 = 0, j4 = 0, j5 = 0, j6 = 0}, 1.2, 0.2, 0, 0)"); + // lua_robot.send("get_robot_mode()"); + // auto ret = lua_robot.call("movej({j1 = 0.0, j2 = 0, j3 = 0, j4 = 0, j5 = 0, j6 = 0}, 1.5, 0.8, 0, 0)"); + // std::cerr<<"Ret is: '"< codes; + codes.push_back("start_sys()"); + codes.push_back("movej({j1 = 0.0, j2 = 0, j3 = 0, j4 = 0, j5 = 0, j6 = 0}, 1.2, 0.2, 0, 0)"); + codes.push_back("movej({j1 = 1.0, j2 = 0, j3 = 0, j4 = 0, j5 = 0, j6 = 0}, 1.2, 0.2, 0, 0)"); + codes.push_back("sync()"); + codes.push_back("stop_sys()"); + lua_robot.send(codes); + auto jps = lua_robot.call("get_target_joint_positions()"); + + return 0; +} diff --git a/examples/example_online_move.cc b/examples/example_online_move.cc new file mode 100644 index 0000000..990cab2 --- /dev/null +++ b/examples/example_online_move.cc @@ -0,0 +1,51 @@ +/** + * Copyright 2022 lebai.ltd + * + * 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. + */ + +#include +#include +#include +#include +#include + +int main(int argc, char **argv) +{ + (void)argc; + (void)argv; + lebai::l_master::Robot robot("172.17.0.4", true); + + robot.start_sys(); + auto jp = robot.get_actual_joint_positions(); + //假设有一个大臂的姿态以四元数表示 + //我们先测试简单的例子,利用大臂的四元数数据来更新机械臂第一关节和第二关节的位置 + while(1) + { + //获取传感器四元数数据 + double quat[4] = {0,0,0,0}; + // 请在这里获取四元数数据 + // quat[0] = ?; + // quat[1] = ?; + // quat[2] = ?; + // quat[3] = ?; + // 利用传感器的四元数旋转计算出新的jp[0] jp[1] + // 请在这里计算 + // jp[0] = ?; + // jp[1] = ?; + // 将新的机械臂位置发送给机械臂控制器端 + robot.towardj(jp, 3.0, 3, 0.0, 0.0); + std::this_thread::sleep_for(std::chrono::milliseconds(100)); + } + return 0; +} diff --git a/sdk/CMakeLists.txt b/sdk/CMakeLists.txt index 51a9230..453e4e7 100755 --- a/sdk/CMakeLists.txt +++ b/sdk/CMakeLists.txt @@ -1,5 +1,5 @@ add_library(lebai-cpp) -file(GLOB PROTOS_SRC RELATIVE ${CMAKE_SOURCE_DIR}/sdk "src/protos/*.cc") +file(GLOB PROTOS_SRC RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} "src/protos/*.cc") target_sources(lebai-cpp PRIVATE include/lebai/robot.hh @@ -8,6 +8,8 @@ target_sources(lebai-cpp src/jsonrpc_connector.cc src/discovery.cc src/discovery_impl.cc + src/lua_robot.cc + src/lua_robot_impl.cc ${PROTOS_SRC} ) target_include_directories(lebai-cpp diff --git a/sdk/dotnet/l_master.i b/sdk/dotnet/l_master.i index 6c22d9f..90bde2a 100644 --- a/sdk/dotnet/l_master.i +++ b/sdk/dotnet/l_master.i @@ -7,6 +7,7 @@ // #include "lebai/posture.hh" // #include "lebai/motion.hh" #include "lebai/robot.hh" +#include "lebai/lua_robot.hh" %} %extend lebai::l_master::KinematicsForwardResp { @@ -51,3 +52,4 @@ }; %include "lebai/robot.hh" +%include "lebai/lua_robot.hh" diff --git a/sdk/include/lebai/lua_robot.hh b/sdk/include/lebai/lua_robot.hh new file mode 100644 index 0000000..bc502e2 --- /dev/null +++ b/sdk/include/lebai/lua_robot.hh @@ -0,0 +1,103 @@ +/** + * Copyright 2022-2023 lebai.ltd + * + * 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. +*/ + +#pragma once + +#include +#include +#include +#include +#include + +namespace lebai +{ + namespace l_master + { + + /** + * @brief 机械臂的Lua接口,通过本对象向机械臂发送lua指令. + * + */ + class LuaRobot + { + public: + /** + * @brief 内部实现. + * @note 用户无需关注. + */ + class LuaRobotImpl; + /** + * @brief 构造LuaRobot对象.可以通过该对象向机械臂发送lua指令,并且获取返回值。 + * + * 可以参考[Lua指令说明](http://help.lebai.ltd/dev/lua.html)了解所有和机械臂相关的lua指令 + * + * + * @param ip: 机械臂IP地址. + */ + explicit LuaRobot(std::string ip); + /** + * @brief 析构LuaRobot对象. + * + */ + virtual ~LuaRobot(); + /** + * 示例代码: + * + * lua_robot.send("start_sys()"); + * + * @brief 向机械臂发送lua指令. + * @note 该函数只会发送lua指令给机械臂,不会读取机械臂的返回数据. + * + * @param lua_code: lua指令. + */ + void send(const std::string & lua_code); + /** + * 示例代码: + * + * std::vector codes; + * codes.push_back("start_sys()"); + * codes.push_back("movej({j1 = 1.0, j2 = 0, j3 = 0, j4 = 0, j5 = 0, j6 = 0}, 1.2, 0.2, 0, 0)"); + * codes.push_back("movej({j1 = 0.0, j2 = 0, j3 = 0, j4 = 0, j5 = 0, j6 = 0}, 1.2, 0.2, 0, 0)"); + * codes.push_back("sync()"); + * codes.push_back("stop_sys()"); + * lua_robot.send(codes); + * + * @brief 向机械臂发送多行lua指令.这些指令会按照顺序执行 + * @note 该函数只会发送lua指令给机械臂,不会读取机械臂的返回数据. + * + * @param lua_codes: 多个(行)lua指令. + */ + void send(const std::vector & lua_codes); + /** + * 示例代码: + * + * auto ret = lua_robot.call("get_robot_mode()"); + * + * @brief 向机械臂发送lua指令,并且获取机械臂的返回数据. + * @note 该函数会发送lua指令给机械臂,并且读取机械臂的返回数据. + * + * @param lua_code: lua指令. + * @return std::string: 机械臂返回的数据. + */ + std::string call(const std::string & lua_code); + /** @}*/ + protected: + std::unique_ptr impl_; /*!< 内部实现数据结构,用户无需关注. */ + }; + + } + +} // namespace l_master_sdk diff --git a/sdk/include/lebai/robot.hh b/sdk/include/lebai/robot.hh index ff93c72..af2a4a4 100644 --- a/sdk/include/lebai/robot.hh +++ b/sdk/include/lebai/robot.hh @@ -56,6 +56,10 @@ namespace lebai std::vector joint_positions; /*!< 机械臂关节位置的map数据,应当包括'j1','j2','j3','j4','j5','j6'六个关节的角度值. */ bool ok = false; /*!< 计算是否成功 */ }; + + + + /** * @brief 机械臂的主要接口对象,通过本对象的方法与机械臂进行数据交互. * @@ -499,24 +503,32 @@ namespace lebai */ /** * @brief 设置数字输出 - * @param device 设备类型,以字符串形式传入,包括 `ROBOT`, `FLANGE`, `EXTRA`, `SHOULDER`, `FLANGE_BTN` + * @anchor DEVICENAME + * @param device 设备名字, + * ID | 设备名字 | 说明 + * ------ | ------------- | ------------- + * 0 | ROBOT | 机箱IO + * 1 | FLANGE | 法兰IO + * 2 | EXTRA | 拓展IO + * 11 | SHOULDER | 肩部按钮DI + * 12 | FLANGE_BTN | 法兰按钮DI + * * 查看 详细信息. + * * @param pin 端口,从 0 开始 * @param value 待设置的值 */ void set_do(std::string device, unsigned int pin, unsigned int value); /** * @brief 获取数字输出 - * @param device 设备类型,以字符串形式传入,包括 `ROBOT`, `FLANGE`, `EXTRA`, `SHOULDER`, `FLANGE_BTN` - * 查看 详细信息. + * @param device 设备名字,查看 @ref DEVICENAME ,可以进一步查看 详细信息. * @param pin 端口,从 0 开始 * @return 返回数字输出数值 */ unsigned int get_do(std::string device, unsigned int pin); /** * @brief 获取多个数字输出 - * @param device 设备类型,以字符串形式传入,包括 `ROBOT`, `FLANGE`, `EXTRA`, `SHOULDER`, `FLANGE_BTN` - * 查看 详细信息. + * @param device 设备名字,查看 @ref DEVICENAME ,可以进一步查看 详细信息. * @param pin 起始数字输出端口,从 0 开始 * @param num 连续的数字输出个数 * @return 返回多个数字输出数值 @@ -524,16 +536,14 @@ namespace lebai std::vector get_dos(std::string device, unsigned int pin, unsigned int num); /** * @brief 获取数字输入 - * @param device 设备类型,以字符串形式传入,包括 `ROBOT`, `FLANGE`, `EXTRA`, `SHOULDER`, `FLANGE_BTN` - * 查看 详细信息. + * @param device 设备名字,查看 @ref DEVICENAME ,可以进一步查看 详细信息. * @param pin 端口,从 0 开始 * @return 返回输入数值 */ unsigned int get_di(std::string device, unsigned int pin); /** * @brief 获取多个数字输入 - * @param device 设备类型,以字符串形式传入,包括 `ROBOT`, `FLANGE`, `EXTRA`, `SHOULDER`, `FLANGE_BTN` - * 查看 详细信息. + * @param device 设备名字,查看 @ref DEVICENAME ,可以进一步查看 详细信息. * @param pin 起始数字输入端口,从 0 开始 * @param num 连续的数字输入个数 * @return 返回多个数字输入 @@ -542,24 +552,21 @@ namespace lebai /** * @brief 设置模拟输出 - * @param device 设备类型,以字符串形式传入,包括 `ROBOT`, `FLANGE`, `EXTRA`, `SHOULDER`, `FLANGE_BTN` - * 查看 详细信息. + * @param device 设备名字,查看 @ref DEVICENAME ,可以进一步查看 详细信息. * @param pin: 模拟输出端口,从 0 开始 * @param value: 待设置的模拟输出值 */ void set_ao(std::string device, unsigned int pin, double value); /** * @brief 获取模拟输出 - * @param device 设备类型,以字符串形式传入,包括 `ROBOT`, `FLANGE`, `EXTRA`, `SHOULDER`, `FLANGE_BTN` - * 查看 详细信息. + * @param device 设备名字,查看 @ref DEVICENAME ,可以进一步查看 详细信息. * @param pin: 端口,从 0 开始 * @return 返回模拟输入数值 */ double get_ao(std::string device, unsigned int pin); /** * @brief 获取多个模拟输出 - * @param device 设备类型,以字符串形式传入,包括 `ROBOT`, `FLANGE`, `EXTRA`, `SHOULDER`, `FLANGE_BTN` - * 查看 详细信息. + * @param device 设备名字,查看 @ref DEVICENAME ,可以进一步查看 详细信息. * @param pin: 起始模拟输出端口,从 0 开始 * @param num 连续的模拟输出个数 * @return 返回模拟输出数值 @@ -567,16 +574,14 @@ namespace lebai std::vector get_aos(std::string device, unsigned int pin, unsigned int num); /** * @brief 获取模拟输入 - * @param device 设备类型,以字符串形式传入,包括 `ROBOT`, `FLANGE`, `EXTRA`, `SHOULDER`, `FLANGE_BTN` - * 查看 详细信息. + * @param device 设备名字,查看 @ref DEVICENAME ,可以进一步查看 详细信息. * @param pin: 端口,从 0 开始 * @return 返回模拟输入数值 */ double get_ai(std::string device, unsigned int pin); /** * @brief 获取多个模拟输入 - * @param device 设备类型,以字符串形式传入,包括 `ROBOT`, `FLANGE`, `EXTRA`, `SHOULDER`, `FLANGE_BTN` - * 查看 详细信息. + * @param device 设备名字,查看 @ref DEVICENAME ,可以进一步查看 详细信息. * @param pin: 起始模拟输入端口,从 0 开始 * @param num 连续的模拟输入个数 * @return 返回多个模拟输入数值 @@ -584,6 +589,7 @@ namespace lebai std::vector get_ais(std::string device, unsigned int pin, unsigned int num); /** * @brief 设置数字端口模式 + * @param device 设备名字,查看 @ref DEVICENAME ,可以进一步查看 详细信息. * @param pin 端口号,从 0 开始 * @param value 设置的值,false为输入模式,true为输出模式 * @return 返回是否成功 @@ -591,6 +597,7 @@ namespace lebai void set_dio_mode(std::string device,unsigned int pin, bool value); /** * @brief 获取数字端口模式 + * @param device 设备名字,查看 @ref DEVICENAME ,可以进一步查看 详细信息. * @param pin 端口号,从 0 开始 * @param count 查询的连续端口数 * @return 从pin开始的连续count个端口的当前模式 diff --git a/sdk/java/l_master.i b/sdk/java/l_master.i index 6c22d9f..e082bc2 100644 --- a/sdk/java/l_master.i +++ b/sdk/java/l_master.i @@ -7,6 +7,7 @@ // #include "lebai/posture.hh" // #include "lebai/motion.hh" #include "lebai/robot.hh" +#include "lebai/lua_robot.hh" %} %extend lebai::l_master::KinematicsForwardResp { @@ -51,3 +52,4 @@ }; %include "lebai/robot.hh" +%include "lebai/lua_robot.hh" \ No newline at end of file diff --git a/sdk/python/CMakeLists.txt b/sdk/python/CMakeLists.txt index 237c892..84d2a86 100755 --- a/sdk/python/CMakeLists.txt +++ b/sdk/python/CMakeLists.txt @@ -81,6 +81,15 @@ target_link_libraries(zeroconf PRIVATE ${PROJECT_NAMESPACE}::lebai-cpp) # which won't be interpreted inside a generator expression. # 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 ${Python2_LIBRARIES} ${Python3_LIBRARIES}) -endif() +# if(MSVC) +# target_link_libraries(zeroconf PRIVATE ${Python2_LIBRARIES} ${Python3_LIBRARIES}) +# endif() +if(BUILD_PYTHON) + if(MSVC) + target_link_libraries(zeroconf PRIVATE ${Python3_LIBRARIES}) + endif() +elseif(BUILD_PYTHON2) + if(MSVC) + target_link_libraries(zeroconf PRIVATE ${Pytho2_LIBRARIES}) + endif() +endif() \ No newline at end of file diff --git a/sdk/python/l_master.i b/sdk/python/l_master.i index df2aad0..c716ecd 100755 --- a/sdk/python/l_master.i +++ b/sdk/python/l_master.i @@ -7,6 +7,7 @@ // #include "lebai/posture.hh" // #include "lebai/motion.hh" #include "lebai/robot.hh" +#include "lebai/lua_robot.hh" %} %extend lebai::l_master::KinematicsForwardResp { @@ -59,6 +60,7 @@ // %import "lebai/posture.hh" // %import "lebai/motion.hh" %include "lebai/robot.hh" +%include "lebai/lua_robot.hh" diff --git a/sdk/src/lua_robot.cc b/sdk/src/lua_robot.cc new file mode 100644 index 0000000..3c78c0f --- /dev/null +++ b/sdk/src/lua_robot.cc @@ -0,0 +1,60 @@ +/** + * Copyright 2022-2023 lebai.ltd + * + * 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. +*/ + +#include +#include "lua_robot_impl.hh" +#include + + + +namespace lebai { + +namespace l_master +{ + +LuaRobot::LuaRobot(std::string ip) +{ + impl_ = std::make_unique(ip); +} +LuaRobot::~LuaRobot() {} + + +void LuaRobot::send(const std::string & lua_code) +{ + impl_->send(lua_code); +} + + +void LuaRobot::send(const std::vector & lua_codes) +{ + std::string codes; + codes = "program_begin(0)\n"; + for(auto &&code: lua_codes) + { + codes+=code+"\n"; + } + codes += "program_end(0)\n"; + impl_->send(codes); +} + +std::string LuaRobot::call(const std::string & lua_code) +{ + return impl_->call(lua_code); +} + +} + +} // namespace l_master_sdk diff --git a/sdk/src/lua_robot_impl.cc b/sdk/src/lua_robot_impl.cc new file mode 100644 index 0000000..aad30eb --- /dev/null +++ b/sdk/src/lua_robot_impl.cc @@ -0,0 +1,63 @@ +/** + * Copyright 2022 lebai.ltd + * + * 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. +*/ + +#include "lua_robot_impl.hh" +#include +#include + +namespace lebai +{ + namespace l_master { + LuaRobot::LuaRobotImpl::LuaRobotImpl(const std::string &ip) + { + io_service_ = std::make_unique(); + connect(ip); + } + LuaRobot::LuaRobotImpl::~LuaRobotImpl() { + if(socket_) + { + socket_->close(); + } + } + int LuaRobot::LuaRobotImpl::connect(const std::string & ip) + { + asio::ip::tcp::resolver resolver(*io_service_); + auto endpoint_iterator = resolver.resolve({ip, "5180"}); + socket_ = std::make_unique(*io_service_); + doConnect(endpoint_iterator); + } + void LuaRobot::LuaRobotImpl::send(const std::string & lua_code) + { + asio::write(*socket_,asio::buffer(lua_code.c_str(), lua_code.size())); + return; + } + + std::string LuaRobot::LuaRobotImpl::call(const std::string & lua_code) + { + std::string print_lua_code = "print(" + lua_code + ")"; + asio::write(*socket_,asio::buffer(print_lua_code.c_str(), print_lua_code.size())); + std::string ret; + // Max 1000 return string size. + ret.resize(1000); + size_t len = socket_->read_some(asio::buffer(ret)); + ret = ret.substr(0, len-2); + return ret; + } + + + + } +} \ No newline at end of file diff --git a/sdk/src/lua_robot_impl.hh b/sdk/src/lua_robot_impl.hh new file mode 100644 index 0000000..e044f0c --- /dev/null +++ b/sdk/src/lua_robot_impl.hh @@ -0,0 +1,63 @@ +/** + * Copyright 2022-2023 lebai.ltd + * + * 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. +*/ + +#pragma once + + +#include +#include +#include + +namespace lebai +{ + namespace l_master + { + class LuaRobot::LuaRobotImpl + { + public: + LuaRobotImpl(const::std::string &ip); + virtual ~LuaRobotImpl(); + int connect(const std::string & ip); + void send(const std::string & lua_code); + std::string call(const std::string & lua_code); + + protected: + void doConnect(asio::ip::tcp::resolver::iterator endpoint_iterator) + { + asio::async_connect(*socket_, endpoint_iterator, + [this](std::error_code ec, asio::ip::tcp::resolver::iterator) + { + std::cerr<<"xxxxxxxx\n"; + if (!ec) + { + std::cerr<<"Connect ok.\n"; + } + else + { + std::cerr<<"Connect failed.\n"; + std::cerr<<"error code "< io_service_; + std::unique_ptr socket_; + // asio::deadline_timer deadline_; + bool connnected_ = false; + }; + } // namespace l_master +} \ No newline at end of file diff --git a/sdk/test/CMakeLists.txt b/sdk/test/CMakeLists.txt index df3122a..538105b 100755 --- a/sdk/test/CMakeLists.txt +++ b/sdk/test/CMakeLists.txt @@ -63,6 +63,30 @@ add_test(NAME TestRobot COMMAND test_robot WORKING_DIRECTORY ${PROJECT_SOURCE_DI +add_executable(test_lua_robot test_lua_robot.cc) +if(DEFINED TEST_ROBOT_IP) + target_compile_definitions(test_lua_robot PRIVATE TEST_L_MASTER_IP="${TEST_ROBOT_IP}") +else() + target_compile_definitions(test_lua_robot PRIVATE TEST_L_MASTER_IP="127.0.0.1") +endif() + + +target_include_directories(test_lua_robot PUBLIC + ${CMAKE_CURRENT_SOURCE_DIR} + ${PROJECT_SOURCE_DIR}/sdk/src +) +target_link_directories(test_lua_robot PRIVATE + ${CMAKE_BINARY_DIR}/${CMAKE_INSTALL_LIBDIR} +) +target_link_libraries(test_lua_robot PRIVATE + ${PROJECT_NAMESPACE}::lebai-cpp + gtest) +set_target_properties(test_lua_robot PROPERTIES + INSTALL_RPATH + ${CMAKE_BINARY_DIR}/${CMAKE_INSTALL_LIBDIR}) +add_test(NAME TestLuaRobot COMMAND test_lua_robot WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}/sdk/test) + + add_executable(test_discovery test_discovery.cc) diff --git a/sdk/test/test_lua_robot.cc b/sdk/test/test_lua_robot.cc new file mode 100644 index 0000000..3e093af --- /dev/null +++ b/sdk/test/test_lua_robot.cc @@ -0,0 +1,72 @@ +/** + * Copyright 2022-2023 lebai.ltd + * + * 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. +*/ +#include +#include +#include +#include +#include "lebai/lua_robot.hh" + +namespace lebai +{ + class LuaRobotTest : public ::testing::Test + { + public: + LuaRobotTest() + :lua_robot_(TEST_L_MASTER_IP) + { + // std::cout<<"TEST_L_MASTER_IP "< codes; + codes.push_back("start_sys()"); + codes.push_back("movej({j1 = 1.0, j2 = 0, j3 = 0, j4 = 0, j5 = 0, j6 = 0}, 1.2, 0.2, 0, 0)"); + codes.push_back("movej({j1 = 0.0, j2 = 0, j3 = 0, j4 = 0, j5 = 0, j6 = 0}, 1.2, 0.2, 0, 0)"); + codes.push_back("sync()"); + codes.push_back("stop_sys()"); + EXPECT_NO_THROW(lua_robot_.send(codes)); + } + TEST_F(LuaRobotTest, CallCase) + { + EXPECT_NO_THROW(lua_robot_.send("start_sys()")); + EXPECT_NO_THROW(lua_robot_.send("movej({j1 = 0.0, j2 = 0, j3 = 0, j4 = 0, j5 = 0, j6 = 0}, 1.2, 0.2, 0, 0)")); + EXPECT_NO_THROW(lua_robot_.send("movej({j1 = 1.0, j2 = 0, j3 = 0, j4 = 0, j5 = 0, j6 = 0}, 1.2, 0.2, 0, 0)")); + + std::string jps; + EXPECT_NO_THROW(jps = lua_robot_.call("get_target_joint_positions()")); + EXPECT_TRUE(jps.size()); + + } +} + +int main(int argc, char **argv) +{ + ::testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); +} From 1519ffc8c422af8db0927bc53c47f5fd04ba8aa4 Mon Sep 17 00:00:00 2001 From: liufang_robot Date: Mon, 15 May 2023 04:38:32 +0000 Subject: [PATCH 02/20] =?UTF-8?q?fix:=20=E7=A7=BB=E9=99=A4=E8=B0=83?= =?UTF-8?q?=E8=AF=95=E6=B3=A8=E9=87=8A?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sdk/src/lua_robot_impl.cc | 1 + sdk/src/lua_robot_impl.hh | 1 - 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/sdk/src/lua_robot_impl.cc b/sdk/src/lua_robot_impl.cc index aad30eb..7e42a12 100644 --- a/sdk/src/lua_robot_impl.cc +++ b/sdk/src/lua_robot_impl.cc @@ -38,6 +38,7 @@ namespace lebai auto endpoint_iterator = resolver.resolve({ip, "5180"}); socket_ = std::make_unique(*io_service_); doConnect(endpoint_iterator); + return 0; } void LuaRobot::LuaRobotImpl::send(const std::string & lua_code) { diff --git a/sdk/src/lua_robot_impl.hh b/sdk/src/lua_robot_impl.hh index e044f0c..dd62947 100644 --- a/sdk/src/lua_robot_impl.hh +++ b/sdk/src/lua_robot_impl.hh @@ -40,7 +40,6 @@ namespace lebai asio::async_connect(*socket_, endpoint_iterator, [this](std::error_code ec, asio::ip::tcp::resolver::iterator) { - std::cerr<<"xxxxxxxx\n"; if (!ec) { std::cerr<<"Connect ok.\n"; From fd99283f5f8cb61deb8a68bc2ea31312dd5b1001 Mon Sep 17 00:00:00 2001 From: liufang_robot Date: Mon, 15 May 2023 05:03:45 +0000 Subject: [PATCH 03/20] =?UTF-8?q?fix:=20=E4=BF=AE=E6=AD=A3dotnet=E4=B8=8A?= =?UTF-8?q?=E4=BC=A0nuget=E7=9A=84bug=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/linux_dotnet_release.yml | 2 +- README.md | 2 -- sdk/include/lebai/robot.hh | 1 + 3 files changed, 2 insertions(+), 3 deletions(-) diff --git a/.github/workflows/linux_dotnet_release.yml b/.github/workflows/linux_dotnet_release.yml index c82b59f..933c082 100644 --- a/.github/workflows/linux_dotnet_release.yml +++ b/.github/workflows/linux_dotnet_release.yml @@ -33,4 +33,4 @@ jobs: run: cd ./build/dotnet/packages; dotnet nuget push lebai.runtime.linux-x64.1.0.*.nupkg --api-key ${{ secrets.NUGET_KEY }} --source https://api.nuget.org/v3/index.json; - dotnet nuget push lebai.1.0.*.nupkg --api-key ${{ secrets.NUGET_KEY }} --source https://api.nuget.org/v3/index.json; + dotnet nuget push lebai.1.*.*.nupkg --api-key ${{ secrets.NUGET_KEY }} --source https://api.nuget.org/v3/index.json; diff --git a/README.md b/README.md index 2284a57..3fcdb3d 100755 --- a/README.md +++ b/README.md @@ -16,8 +16,6 @@ lebai-sdk的源代码仓库,可以用于控制乐白机械臂. [dotnet_windows_svg]: https://github.com/lebai-robotics/lebai-sdk/actions/workflows/windows_dotnet_release.yaml/badge.svg [dotnet_windows_link]: https://github.com/lebai-robotics/lebai-sdk/actions/workflows/windows_dotnet_release.yaml -**SDK使用需要乐白机械臂的控制器软件版本大于等于`3.1.5`,您可以在机械臂WEB界面左上方查看当前版本号.** - [SDK在线文档](http://help.lebai.ltd/sdk/)中包含了lua语言的接口(本项目参考了lua语言进行接口设置,但是本项目和lua语言的接口无直接关系) # 包管理直接安装 diff --git a/sdk/include/lebai/robot.hh b/sdk/include/lebai/robot.hh index af2a4a4..184ada3 100644 --- a/sdk/include/lebai/robot.hh +++ b/sdk/include/lebai/robot.hh @@ -62,6 +62,7 @@ namespace lebai /** * @brief 机械臂的主要接口对象,通过本对象的方法与机械臂进行数据交互. + * @note 使用该数据结构和机械臂交互要求机械臂软件版本>=3.1.5。 * */ class Robot From 5daa2dc401fbe0576bbc849a6d934f939f6bac4a Mon Sep 17 00:00:00 2001 From: liufang_robot Date: Mon, 15 May 2023 06:30:25 +0000 Subject: [PATCH 04/20] =?UTF-8?q?fix:=20=E4=BF=AE=E6=AD=A3dotnet=20release?= =?UTF-8?q?=E7=89=88=E6=9C=AC=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/linux_dotnet_release.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/linux_dotnet_release.yml b/.github/workflows/linux_dotnet_release.yml index 933c082..c8e60e8 100644 --- a/.github/workflows/linux_dotnet_release.yml +++ b/.github/workflows/linux_dotnet_release.yml @@ -32,5 +32,5 @@ jobs: - name: upload pacakges run: cd ./build/dotnet/packages; - dotnet nuget push lebai.runtime.linux-x64.1.0.*.nupkg --api-key ${{ secrets.NUGET_KEY }} --source https://api.nuget.org/v3/index.json; + dotnet nuget push lebai.runtime.linux-x64.1.*.*.nupkg --api-key ${{ secrets.NUGET_KEY }} --source https://api.nuget.org/v3/index.json; dotnet nuget push lebai.1.*.*.nupkg --api-key ${{ secrets.NUGET_KEY }} --source https://api.nuget.org/v3/index.json; From 68ce676a07e3ff5132d8ba72564131d6050afb8c Mon Sep 17 00:00:00 2001 From: liufang_robot Date: Mon, 19 Jun 2023 14:23:08 +0000 Subject: [PATCH 05/20] =?UTF-8?q?feat:=20=E6=B7=BB=E5=8A=A0speedl=E5=92=8C?= =?UTF-8?q?speedj=E7=9A=84=E6=94=AF=E6=8C=81=EF=BC=8C=E5=AE=8C=E5=96=84?= =?UTF-8?q?=E6=96=87=E6=A1=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CMakeLists.txt | 2 +- Doxyfile | 4 +- doc/changelog.md | 4 ++ doc/dotnet.md | 3 -- sdk/include/lebai/lebai.hh | 23 ++++++++++ sdk/include/lebai/robot.hh | 37 +++++++++++++--- sdk/src/protos/motion.cc | 87 +++++++++++++++++++++++++++++++++++++- sdk/src/protos/motion.hh | 23 ++++++++++ sdk/src/robot.cc | 70 ++++++++++++++++++++++++++++++ sdk/src/robot_impl.cc | 16 ++++++- sdk/src/robot_impl.hh | 3 +- sdk/test/test_robot.cc | 8 ++++ 12 files changed, 265 insertions(+), 15 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index c206a2c..709fe7f 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.1.0 LANGUAGES CXX) +project(lebai VERSION 1.1.1 LANGUAGES CXX) set(PROJECT_NAMESPACE lebai) message(STATUS "${PROJECT_NAME} version: ${PROJECT_VERSION}") # message(STATUS "major: ${PROJECT_VERSION_MAJOR}") diff --git a/Doxyfile b/Doxyfile index 7914cd9..560baec 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.1.0 +PROJECT_NUMBER = 1.1.1 # 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 @@ -1531,7 +1531,7 @@ FORMULA_TRANSPARENT = YES # The default value is: NO. # This tag requires that the tag GENERATE_HTML is set to YES. -USE_MATHJAX = NO +USE_MATHJAX = YES # When MathJax is enabled you can set the default output format to be used for # the MathJax output. See the MathJax site (see: diff --git a/doc/changelog.md b/doc/changelog.md index 30ac4d1..ab74cd5 100644 --- a/doc/changelog.md +++ b/doc/changelog.md @@ -1,5 +1,9 @@ # ChangeLog +## 1.1.1 + +添加speedj和speedl的实现和文档 + ## 1.1.0 添加LuaRobot对象,可以向机械臂发送lua指令 diff --git a/doc/dotnet.md b/doc/dotnet.md index df472b6..39585d4 100644 --- a/doc/dotnet.md +++ b/doc/dotnet.md @@ -1,9 +1,6 @@ # .net平台应用文档 -<<<<<<< HEAD **目前.net仅支持linux平台,windows平台还存在问题.** -======= ->>>>>>> eaa388d5ed4303d406026c6b7d2b632bd30a6374 [Nuget包地址](https://www.nuget.org/packages/lebai/) diff --git a/sdk/include/lebai/lebai.hh b/sdk/include/lebai/lebai.hh index 55e9b08..eeab707 100644 --- a/sdk/include/lebai/lebai.hh +++ b/sdk/include/lebai/lebai.hh @@ -15,6 +15,7 @@ * # ChangeLog * 查阅 \ref doc/changelog.md. * + * * # Python * 查看 \ref doc/python.md 来获取使用python开发相关的内容. * @@ -23,5 +24,27 @@ * * # Develop * 如果需要开发sdk,添加新的功能,可以参考 \ref doc/develop.md. + * + * # FAQ + * + * ## 机械臂界面上坐标系统中,Rz、Ry、Rx是如何定义的。 + * + * 乐白机械臂界面的Rz,Rz,Rz表示机械臂姿态,是由EulerZYX确定的。 + * + * 界面显示的Rz,Ry,Rx为角度,将其转换为弧度后,它和旋转矩阵的关系如下: + * + * @f$RotationMatrix = \begin{bmatrix} + * \cos(Rz) & -sin(Rz) & 0 \\ + * sin(Rz) & cos(Rz) & 0\\ + * 0 & 0 & 1 + * \end{bmatrix}\begin{bmatrix} + * cos(Ry) & 0 & sin(Ry)\\ + * 0 & 1 & 0 \\ + * -sin(Ry) & 0 & cos(Ry) + * \end{bmatrix}\begin{bmatrix} + * 1 & 0 & 0 \\ + * 0 & cos(Rx) & -sin(Rx) \\ + * 0 & sin(Rx) & cos(Rx) + * \end{bmatrix}@f$ */ diff --git a/sdk/include/lebai/robot.hh b/sdk/include/lebai/robot.hh index 184ada3..3da5f58 100644 --- a/sdk/include/lebai/robot.hh +++ b/sdk/include/lebai/robot.hh @@ -44,7 +44,7 @@ namespace lebai */ struct KinematicsForwardResp { - CartesianPose pose; /*!< 笛卡尔坐标位置,依次为 x, y, z, rz, ry, rx. */ + CartesianPose pose; /*!< 笛卡尔坐标位置,map数据,应当包括'x','y','z','rx','ry','rz'的键值. */ bool ok = false; /*!< 计算是否成功. */ }; /** @@ -53,7 +53,7 @@ namespace lebai */ struct KinematicsInverseResp { - std::vector joint_positions; /*!< 机械臂关节位置的map数据,应当包括'j1','j2','j3','j4','j5','j6'六个关节的角度值. */ + std::vector joint_positions; /*!< 机械臂关节位置数组.. */ bool ok = false; /*!< 计算是否成功 */ }; @@ -325,7 +325,7 @@ namespace lebai int movec(const std::vector & joint_via, const std::vector & joint, double rad, double a, double v, double t, double r); /** * - * @brief 通过坐标位置发送机械臂圆弧运动 * + * @brief 通过坐标位置发送机械臂圆弧运动 * @param[in] cart_via 圆弧上途径点坐标位置,应当包括键为x,y,z,rz,ry,rx的值.为圆上三点中的一点. * @param[in] cart 圆弧目标点坐标位置,应当包括键为x,y,z,rz,ry,rx的值.如果编程rad不为零,则为圆上三点中的一点. * @param[in] rad 圆弧角度值,单位为弧度,如果为零,则走到目标点,正负值用来确定圆弧方向. @@ -335,8 +335,35 @@ namespace lebai * @param[in] r: 交融半径,设置为0,则无交融半径. * @return >0 发送成功. * @return <=0 发送失败. - */ + */ int movec(const CartesianPose & cart_via, const CartesianPose & cart, double rad, double a, double v, double t, double r); + /** + * 示例代码: + * + * robot.speedj( 1.0, {0.5,0.0,0.0,0.0,0.0,0.0}, 0.0); + * + * @brief 通过关节速度矢量发送机械臂关节匀速运动 + * @param[in] a 加速度. + * @param[in] v 速度矢量 + * @param[in] t: 运动时间,默认t = 0,一直运动到限位. + * @return >0 发送成功.返回运动号 + * @return <=0 发送失败. + */ + int speedj(double a, const std::vector & v, double t = 0.0); + /** + * + * 示例代码: + * + * robot.speedl( 1.0, {{"x", 0.0}, {"y", 0.0}, {"z", 0.1}, {"rx", 0.0}, {"ry", 0.0}, {"rz", 0.0}}, 0.0); + * + * @brief 通过坐标速度矢量发送机械臂关节匀速运动 + * @param[in] a 加速度. + * @param[in] v 速度矢量 + * @param[in] t: 运动时间,默认t = 0,一直运动到限位. + * @return >0 发送成功.返回运动号 + * @return <=0 发送失败. + */ + int speedl(double a, const CartesianPose & v, double t = 0.0); /** * 示例代码: * @@ -351,7 +378,7 @@ namespace lebai * @param[in] v: 速度. * @param[in] t: 时间参数,如果设置时间不为零,则按照时间计算出速度,而不使用速度参数. * @param[in] r: 交融半径,设置为0,则无交融半径. - * @return >0 发送成功. + * @return >0 发送成功.返回运动号 * @return <=0 发送失败. * */ diff --git a/sdk/src/protos/motion.cc b/sdk/src/protos/motion.cc index e64fc53..0e41b4a 100644 --- a/sdk/src/protos/motion.cc +++ b/sdk/src/protos/motion.cc @@ -751,6 +751,7 @@ namespace lebai } return true; } + // SpeedJRequest void SpeedJRequest::set_speed(const posture::JointPose & speed) { speed_ = speed; @@ -812,6 +813,90 @@ namespace lebai } return false; } - // MoveParam end + // SpeedJRequest end + // SpeedJRequest + void SpeedLRequest::set_speed(const posture::CartesianPose & speed) + { + speed_ = speed; + } + const posture::CartesianPose & SpeedLRequest::speed() const + { + return speed_; + } + + posture::CartesianPose * SpeedLRequest::mutable_speed() + { + return &speed_; + } + void SpeedLRequest::set_param(const SpeedParam & param) + { + param_ = param; + } + const SpeedParam & SpeedLRequest::param() const + { + return param_; + } + SpeedParam * SpeedLRequest::mutable_param() + { + return ¶m_; + } + void SpeedLRequest::set_frame(const posture::CartesianFrame & frame) + { + frame_ = frame; + } + const posture::CartesianFrame & SpeedLRequest::frame() const + { + return frame_; + } + posture::CartesianFrame * SpeedLRequest::mutable_frame() + { + return &frame_; + } + bool SpeedLRequest::Deserialize(const rapidjson::Value& obj) + { + if(obj.HasMember("speed")) + { + speed_.Deserialize(obj["speed"]); + } + if(obj.HasMember("param")) + { + param_.Deserialize(obj["param"]); + } + if(obj.HasMember("frame")) + { + frame_.Deserialize(obj["frame"]); + } + return true; + } + bool SpeedLRequest::Serialize(rapidjson::Writer* writer) const + { + writer->StartObject(); + if(!speed_.IsNullJSONData()) + { + writer->String("speed"); + speed_.Serialize(writer); + } + if(!param_.IsNullJSONData()) + { + writer->String("param"); + param_.Serialize(writer); + } + if(!frame_.IsNullJSONData()) + { + writer->String("frame"); + frame_.Serialize(writer); + } + writer->EndObject(); + return true; + } + bool SpeedLRequest::IsNullJSONData() const + { + if(speed_.IsNullJSONData() && param_.IsNullJSONData()) + { + return true; + } + return false; + } + // SpeedJRequest end } } \ No newline at end of file diff --git a/sdk/src/protos/motion.hh b/sdk/src/protos/motion.hh index 18b0548..945b33e 100644 --- a/sdk/src/protos/motion.hh +++ b/sdk/src/protos/motion.hh @@ -215,5 +215,28 @@ namespace lebai virtual bool Serialize(rapidjson::Writer* writer) const; virtual bool IsNullJSONData() const; }; + + class SpeedLRequest : public JSONBase + { + public: + void set_speed(const posture::CartesianPose & speed); + const posture::CartesianPose & speed() const; + posture::CartesianPose * mutable_speed(); + void set_param(const SpeedParam & param); + const SpeedParam & param() const; + SpeedParam * mutable_param(); + void set_frame(const posture::CartesianFrame & param); + const posture::CartesianFrame & frame() const; + posture::CartesianFrame * mutable_frame(); + + protected: + posture::CartesianPose speed_; + SpeedParam param_; + posture::CartesianFrame frame_; + public: + virtual bool Deserialize(const rapidjson::Value& obj); + virtual bool Serialize(rapidjson::Writer* writer) const; + virtual bool IsNullJSONData() const; + }; } } \ No newline at end of file diff --git a/sdk/src/robot.cc b/sdk/src/robot.cc index 00eae35..374a39f 100644 --- a/sdk/src/robot.cc +++ b/sdk/src/robot.cc @@ -377,6 +377,76 @@ int Robot::movec(const CartesianPose & cart_via, const CartesianPose & cart, dou return resp.id(); } +int Robot::speedj(double a, const std::vector & v, double t) +{ + motion::SpeedJRequest req; + req.mutable_param()->set_acc(a); + req.mutable_param()->set_time(a); + for(auto && p :v) + { + req.mutable_speed()->mutable_joint()->push_back(p); + } + lebai::motion::MotionIndex resp = impl_->speedJoint(req); + return resp.id(); +} + +int Robot::speedl(double a, const CartesianPose & v, double t) +{ + motion::SpeedLRequest req; + req.mutable_param()->set_acc(a); + req.mutable_param()->set_time(a); + if(v.find("x") != v.end()) + { + req.mutable_speed()->mutable_position()->set_x(v.at("x")); + } + else + { + return -1; + } + if(v.find("y") != v.end()) + { + req.mutable_speed()->mutable_position()->set_y(v.at("y")); + } + else + { + return -1; + } + if(v.find("z") != v.end()) + { + req.mutable_speed()->mutable_position()->set_z(v.at("z")); + } + else + { + return -1; + } + if(v.find("rx") != v.end()) + { + req.mutable_speed()->mutable_rotation()->mutable_euler_zyx()->set_x(v.at("rx")); + } + else + { + return -1; + } + if(v.find("ry") != v.end()) + { + req.mutable_speed()->mutable_rotation()->mutable_euler_zyx()->set_y(v.at("ry")); + } + else + { + return -1; + } + if(v.find("rz") != v.end()) + { + req.mutable_speed()->mutable_rotation()->mutable_euler_zyx()->set_z(v.at("rz")); + } + else + { + return -1; + } + lebai::motion::MotionIndex resp = impl_->speedLinear(req); + return resp.id(); +} + int Robot::towardj(const std::vector & joint_positions, double a, double v, double t, double r) { diff --git a/sdk/src/robot_impl.cc b/sdk/src/robot_impl.cc index 04bae10..2e80470 100644 --- a/sdk/src/robot_impl.cc +++ b/sdk/src/robot_impl.cc @@ -142,9 +142,21 @@ namespace lebai motion_resp.FromJSONString(resp); return motion_resp; } - void Robot::RobotImpl::speedJoint(const motion::SpeedJRequest & req) + motion::MotionIndex Robot::RobotImpl::speedJoint(const motion::SpeedJRequest & req) { - json_rpc_connector_->CallRpc("speed_joint",req.ToJSONString(),nullptr); + std::string resp; + json_rpc_connector_->CallRpc("speed_joint",req.ToJSONString(),&resp); + motion::MotionIndex motion_resp; + motion_resp.FromJSONString(resp); + return motion_resp; + } + motion::MotionIndex Robot::RobotImpl::speedLinear(const motion::SpeedLRequest & req) + { + std::string resp; + json_rpc_connector_->CallRpc("speed_linear",req.ToJSONString(),&resp); + motion::MotionIndex motion_resp; + motion_resp.FromJSONString(resp); + return motion_resp; } void Robot::RobotImpl::movePvat(const motion::MovePvatRequest & req) { diff --git a/sdk/src/robot_impl.hh b/sdk/src/robot_impl.hh index 34f2df6..abd1667 100644 --- a/sdk/src/robot_impl.hh +++ b/sdk/src/robot_impl.hh @@ -58,7 +58,8 @@ namespace lebai motion::MotionIndex moveLinear(const motion::MoveRequest & req); motion::MotionIndex moveCircular(const motion::MovecRequest & req); motion::MotionIndex towardJoint(const motion::MoveRequest & req); - void speedJoint(const motion::SpeedJRequest & req); + motion::MotionIndex speedJoint(const motion::SpeedJRequest & req); + motion::MotionIndex speedLinear(const motion::SpeedLRequest & req); void movePvat(const motion::MovePvatRequest & req); void waitMove(const motion::MotionIndex & req); motion::MotionIndex getRunningMotion(); diff --git a/sdk/test/test_robot.cc b/sdk/test/test_robot.cc index 13b217c..5aa536b 100644 --- a/sdk/test/test_robot.cc +++ b/sdk/test/test_robot.cc @@ -179,6 +179,14 @@ namespace lebai // 0.0, 1.0, 0.5, 0.0, 0.0); // kinematics_forward: -0.282541, -0.168246, 0.265824, 1.27256, -0.206353, 0.937445 // kinematics_forward: -0.255832, 0.00270435, 0.266642, 1.27293, -0.20805, 0.94485 + robot_.speedj( 1.0, {0.5,0.0,0.0,0.0,0.0,0.0}, 0.0); + std::this_thread::sleep_for(std::chrono::seconds(2)); + robot_.stop_move(); + robot_.speedl( 1.0, {{"x", 0.0}, {"y", 0.0}, {"z", 0.1}, {"rx", 0.0}, {"ry", 0.0}, {"rz", 0.0}}, 0.0); + std::this_thread::sleep_for(std::chrono::seconds(2)); + robot_.stop_move(); + + robot_.towardj({0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, 1.0, 1.0, 0.0, 0.0); robot_.wait_move(); From 50fb86238090e518fb1936a56925c2195be5c07e Mon Sep 17 00:00:00 2001 From: liufang_robot Date: Mon, 19 Jun 2023 14:48:49 +0000 Subject: [PATCH 06/20] =?UTF-8?q?fix:=20=E4=BF=AE=E6=AD=A3=E5=90=88?= =?UTF-8?q?=E5=B9=B6=E9=94=99=E8=AF=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sdk/include/lebai/robot.hh | 4 ---- 1 file changed, 4 deletions(-) diff --git a/sdk/include/lebai/robot.hh b/sdk/include/lebai/robot.hh index 78ad598..23ed32f 100644 --- a/sdk/include/lebai/robot.hh +++ b/sdk/include/lebai/robot.hh @@ -54,11 +54,7 @@ namespace lebai */ struct KinematicsInverseResp { -<<<<<<< HEAD - std::vector joint_positions; /*!< 机械臂关节位置数组.. */ -======= DoubleVector joint_positions; /*!< 机械臂关节位置的map数据,应当包括'j1','j2','j3','j4','j5','j6'六个关节的角度值. */ ->>>>>>> f26a02b73d6e1e44a254f55c83b8be75945da501 bool ok = false; /*!< 计算是否成功 */ }; From 8932c4e2efe047e787c6483ce13f08ee4c14a525 Mon Sep 17 00:00:00 2001 From: liufang_robot Date: Tue, 20 Jun 2023 05:38:26 +0000 Subject: [PATCH 07/20] =?UTF-8?q?fix:=20=E6=9B=B4=E6=96=B0=E7=89=88?= =?UTF-8?q?=E6=9C=AC=E5=8F=B7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CMakeLists.txt | 2 +- Doxyfile | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index f0e5ec6..ac6c6bf 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -8,7 +8,7 @@ list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake") option(CMAKE_EXPORT_COMPILE_COMMANDS "Export compile command" TRUE) -project(lebai VERSION 1.1.4 LANGUAGES CXX) +project(lebai VERSION 1.1.6 LANGUAGES CXX) set(PROJECT_NAMESPACE lebai) message(STATUS "${PROJECT_NAME} version: ${PROJECT_VERSION}") # message(STATUS "major: ${PROJECT_VERSION_MAJOR}") diff --git a/Doxyfile b/Doxyfile index 3b5a80b..7d04050 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.1.4 +PROJECT_NUMBER = 1.1.6 # 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 From 46dc23c232f54df95fab4866349f5f881fa305ff Mon Sep 17 00:00:00 2001 From: liufang_robot Date: Wed, 6 Sep 2023 14:18:13 +0000 Subject: [PATCH 08/20] =?UTF-8?q?feat:=20README=E5=A4=9A=E8=AF=AD=E8=A8=80?= =?UTF-8?q?=E7=9A=84=E6=A1=86=E6=9E=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/linux_python_build.yml | 3 --- README.en.md | 3 +++ README.md | 10 ++++++++-- 3 files changed, 11 insertions(+), 5 deletions(-) create mode 100644 README.en.md diff --git a/.github/workflows/linux_python_build.yml b/.github/workflows/linux_python_build.yml index 8b70fd0..ac0fc55 100644 --- a/.github/workflows/linux_python_build.yml +++ b/.github/workflows/linux_python_build.yml @@ -3,9 +3,6 @@ run-name: ${{ github.actor }} Linux python build on: workflow_dispatch: pull_request: - push: - branches: - - master jobs: linux_python_build: runs-on: ubuntu-latest diff --git a/README.en.md b/README.en.md new file mode 100644 index 0000000..b40059b --- /dev/null +++ b/README.en.md @@ -0,0 +1,3 @@ +[![en](https://img.shields.io/badge/lang-en-green.svg)](https://github.com/lebai-robotics/lebai-sdk/blob/master/README.en.md) + +lebai-sdk's source code repository, can be used to control the Lebai robot arm. \ No newline at end of file diff --git a/README.md b/README.md index 2284a57..0a1b350 100755 --- a/README.md +++ b/README.md @@ -1,3 +1,7 @@ +# Multilanguage README Pattern +[![zh](https://img.shields.io/badge/lang-zh-red.svg)](https://github.com/lebai-robotics/lebai-sdk/blob/master/README.md) +[![en](https://img.shields.io/badge/lang-en-green.svg)](https://github.com/lebai-robotics/lebai-sdk/blob/master/README.en.md) + lebai-sdk的源代码仓库,可以用于控制乐白机械臂. | OS | C++ | Python | C# | Java | @@ -78,7 +82,9 @@ sudo apt install python-dev python-setuptools ### 编译 ```bash # 生成编译配置 -cmake -S. -Bbuild -DBUILD_PYTHON=ON -DBUILD_DEB=ON -DBUILD_TESTING=OFF +cmake -S. -Bbuild -DBUILD_PYTHON=ON -DBUILD_DEB=ON -DBUILD_EXAMPLES=OFF -DBUILD_TESTING=OFF +# 生成编译配置,只C++,同时生成DEB包 +cmake -S. -Bbuild -DBUILD_PYTHON=OFF -DBUILD_DEB=ON -DBUILD_TESTING=OFF # 编译 cmake --build build # 运行单元测试 @@ -137,7 +143,7 @@ lebai-sdk使用如下第三方软件: | 软件名 | 协议 | 官方网站 | | ----------- | ----------- |----------- | -| Asio | Boost | https://think-async.com/Asio/ | +| Asio | [MPL2](https://www.mozilla.org/en-US/MPL/2.0/FAQ/) | https://think-async.com/Asio/ | | rapidjson | MIT | https://rapidjson.org/ | | websocketpp | BSD | https://www.zaphoyd.com/websocketpp | | mdns | public domain | https://github.com/mjansson/mdns | From bed7c5be29ba6e01cf8db033b306bb7230ccb451 Mon Sep 17 00:00:00 2001 From: liufang_robot Date: Wed, 6 Sep 2023 14:20:51 +0000 Subject: [PATCH 09/20] =?UTF-8?q?fix:=20readme=E9=94=99=E8=AF=AF=E4=BF=AE?= =?UTF-8?q?=E6=AD=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 0a1b350..b166fdb 100755 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# Multilanguage README Pattern +# Languages [![zh](https://img.shields.io/badge/lang-zh-red.svg)](https://github.com/lebai-robotics/lebai-sdk/blob/master/README.md) [![en](https://img.shields.io/badge/lang-en-green.svg)](https://github.com/lebai-robotics/lebai-sdk/blob/master/README.en.md) From 77b1012ce309e5c69aa7ed1d163ff8ff01981e20 Mon Sep 17 00:00:00 2001 From: liufang_robot Date: Wed, 6 Sep 2023 14:24:42 +0000 Subject: [PATCH 10/20] =?UTF-8?q?fix:=20=E6=9B=B4=E6=96=B0=E7=89=88?= =?UTF-8?q?=E6=9C=AC=E5=8F=B7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CMakeLists.txt | 2 +- Doxyfile | 2 +- doc/changelog.md | 4 ++++ 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index ac6c6bf..1340105 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -8,7 +8,7 @@ list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake") option(CMAKE_EXPORT_COMPILE_COMMANDS "Export compile command" TRUE) -project(lebai VERSION 1.1.6 LANGUAGES CXX) +project(lebai VERSION 1.1.7 LANGUAGES CXX) set(PROJECT_NAMESPACE lebai) message(STATUS "${PROJECT_NAME} version: ${PROJECT_VERSION}") # message(STATUS "major: ${PROJECT_VERSION_MAJOR}") diff --git a/Doxyfile b/Doxyfile index 7d04050..f11def3 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.1.6 +PROJECT_NUMBER = 1.1.7 # 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/doc/changelog.md b/doc/changelog.md index ab74cd5..bb03c11 100644 --- a/doc/changelog.md +++ b/doc/changelog.md @@ -1,5 +1,9 @@ # ChangeLog +## 1.1.7 + +README添加多语言支持 + ## 1.1.1 添加speedj和speedl的实现和文档 From 0ac81e926adad9b8c54a2b8d13970e33731fd088 Mon Sep 17 00:00:00 2001 From: liufang_robot Date: Wed, 6 Sep 2023 14:32:08 +0000 Subject: [PATCH 11/20] =?UTF-8?q?fix:=20=E4=BF=AE=E6=AD=A3github=20action?= =?UTF-8?q?=20=E7=9A=84=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/linux_cpp_build.yml | 3 --- 1 file changed, 3 deletions(-) diff --git a/.github/workflows/linux_cpp_build.yml b/.github/workflows/linux_cpp_build.yml index 6d9a6c5..62d305a 100644 --- a/.github/workflows/linux_cpp_build.yml +++ b/.github/workflows/linux_cpp_build.yml @@ -5,9 +5,6 @@ on: pull_request: jobs: linux_cpp_build: - environment: - name: github-pages - url: ${{ steps.deployment.outputs.page_url }} runs-on: ubuntu-latest steps: - name: Checkout From f6096481d0cc74aa59e73189268bbd0061d23f71 Mon Sep 17 00:00:00 2001 From: liufang_robot Date: Thu, 28 Sep 2023 03:19:09 +0000 Subject: [PATCH 12/20] =?UTF-8?q?feat:=20=E4=BF=AE=E6=AD=A3=E6=96=87?= =?UTF-8?q?=E6=A1=A3=E9=94=99=E8=AF=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CMakeLists.txt | 2 +- Doxyfile | 2 +- doc/changelog.md | 6 ++++++ dotnet/lebai.runtime.csproj.in | 2 +- sdk/include/lebai/lebai.hh | 11 +++++------ sdk/include/lebai/robot.hh | 29 +++++++++++++++++------------ sdk/src/robot.cc | 4 ++-- 7 files changed, 33 insertions(+), 23 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 1340105..388ee95 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -8,7 +8,7 @@ list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake") option(CMAKE_EXPORT_COMPILE_COMMANDS "Export compile command" TRUE) -project(lebai VERSION 1.1.7 LANGUAGES CXX) +project(lebai VERSION 1.1.8 LANGUAGES CXX) set(PROJECT_NAMESPACE lebai) message(STATUS "${PROJECT_NAME} version: ${PROJECT_VERSION}") # message(STATUS "major: ${PROJECT_VERSION_MAJOR}") diff --git a/Doxyfile b/Doxyfile index f11def3..7230143 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.1.7 +PROJECT_NUMBER = 1.1.8 # 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/doc/changelog.md b/doc/changelog.md index bb03c11..4487972 100644 --- a/doc/changelog.md +++ b/doc/changelog.md @@ -1,5 +1,11 @@ # ChangeLog +## 1.1.8 + +修正.net包描述问题 + +修正注释和文档的一些bug + ## 1.1.7 README添加多语言支持 diff --git a/dotnet/lebai.runtime.csproj.in b/dotnet/lebai.runtime.csproj.in index 1b8817c..217e3c9 100644 --- a/dotnet/lebai.runtime.csproj.in +++ b/dotnet/lebai.runtime.csproj.in @@ -7,7 +7,7 @@ @PROJECT_VERSION@ - .NET native wrapper for the CMakeSwig project + .NET native wrapper for the Lebai SDK false diff --git a/sdk/include/lebai/lebai.hh b/sdk/include/lebai/lebai.hh index eeab707..916471a 100644 --- a/sdk/include/lebai/lebai.hh +++ b/sdk/include/lebai/lebai.hh @@ -14,14 +14,13 @@ * * # ChangeLog * 查阅 \ref doc/changelog.md. - * - * + * * # Python * 查看 \ref doc/python.md 来获取使用python开发相关的内容. * * # .net - * 查看 \ref doc/dotnet.md 来获取在.net中使用C#开发相关的内容. - * + * 查看 \ref doc/dotnet.md 来获取在.net中使用C\#开发相关的内容. + * * # Develop * 如果需要开发sdk,添加新的功能,可以参考 \ref doc/develop.md. * @@ -33,7 +32,7 @@ * * 界面显示的Rz,Ry,Rx为角度,将其转换为弧度后,它和旋转矩阵的关系如下: * - * @f$RotationMatrix = \begin{bmatrix} + * \f$RotationMatrix = \begin{bmatrix} * \cos(Rz) & -sin(Rz) & 0 \\ * sin(Rz) & cos(Rz) & 0\\ * 0 & 0 & 1 @@ -45,6 +44,6 @@ * 1 & 0 & 0 \\ * 0 & cos(Rx) & -sin(Rx) \\ * 0 & sin(Rx) & cos(Rx) - * \end{bmatrix}@f$ + * \end{bmatrix}\f$ */ diff --git a/sdk/include/lebai/robot.hh b/sdk/include/lebai/robot.hh index 23ed32f..3ba80fc 100644 --- a/sdk/include/lebai/robot.hh +++ b/sdk/include/lebai/robot.hh @@ -183,13 +183,13 @@ namespace lebai */ void start_sys(); /** - * @brief 停止机械臂(机械臂上使能). + * @brief 停止机械臂(机械臂下使能). * */ void stop_sys(); /** - * @brief 关闭机器人电源(关机. + * @brief 关闭机器人电源(关机). * */ void powerdown(); @@ -715,11 +715,13 @@ namespace lebai /** * @brief 调用场景 * - * @param name: 调用场景的名字 - * @param is_main: 是否以主任务方式运行(主任务会排队执行,子任务会并发执行) - * @param loop_to: 循环次数(默认0永久循环) - * @param dir: 调用场景所在的文件夹名 - * @param params: 其他参数 + * @param name 调用场景的名字 + * @param params 其他参数 + * @param dir 调用场景所在的文件夹名 + * @param is_parallel 是否并行 + * @param loop_to 循环次数(默认0永久循环) + * + * */ unsigned int start_task(const std::string &name,const std::vector & params,const std::string & dir, bool is_parallel,unsigned int loop_to); /** @@ -740,6 +742,10 @@ namespace lebai * @param wait: 是否等待 */ void pause_task(unsigned int id,unsigned long time,bool wait); + /** + * @brief 暂停任务与运动 + * @param id: 任务的ID + */ void pause_task(unsigned int id); /** * @brief 恢复任务与运动 @@ -917,18 +923,17 @@ namespace lebai */ void set_payload(double mass, std::map cog); /** - * @brief 设置机器人末端负载. + * @brief 设置机器人末端负载质量. * * @param mass 末端负载的质量(kg). */ - void set_payload(double mass); + void set_payload_mass(double mass); /** - * @brief 设置机器人末端负载. + * @brief 设置机器人末端负载重心. * - * @param mass 末端负载的质量(kg). * @param cog 质心相对于TCP坐标系的偏移. */ - void set_payload(std::map cog); + void set_payload_cog(std::map cog); /** * @brief 获取末端负载设置. * diff --git a/sdk/src/robot.cc b/sdk/src/robot.cc index 27365d4..16ae2eb 100644 --- a/sdk/src/robot.cc +++ b/sdk/src/robot.cc @@ -1390,13 +1390,13 @@ void Robot::set_payload(double mass, std::map cog) req.set_cog(c); impl_->setPayload(req); } -void Robot::set_payload(double mass) +void Robot::set_payload_mass(double mass) { dynamic::SetMassRequest req; req.set_mass(mass); impl_->setPayload(req); } -void Robot::set_payload(std::map cog) +void Robot::set_payload_cog(std::map cog) { dynamic::SetCogRequest req; posture::Position c; From db8dfea2af3384f5a3880b663095857acc4d48c6 Mon Sep 17 00:00:00 2001 From: liufang_robot Date: Thu, 28 Sep 2023 03:26:56 +0000 Subject: [PATCH 13/20] fix: update pip --- .github/workflows/linux_python_build.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/linux_python_build.yml b/.github/workflows/linux_python_build.yml index ac0fc55..7eac9f8 100644 --- a/.github/workflows/linux_python_build.yml +++ b/.github/workflows/linux_python_build.yml @@ -12,6 +12,7 @@ jobs: 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 -m pip install --upgrade pip - run: /opt/python/cp310-cp310/bin/pip install twine==2.0.0 - name: create-whl-dir From c0ec327d1ec629485a235e6a57a5eb7c01a9a819 Mon Sep 17 00:00:00 2001 From: liufang_robot Date: Thu, 28 Sep 2023 03:29:35 +0000 Subject: [PATCH 14/20] update linux_python_build.yml --- .github/workflows/linux_python_build.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/linux_python_build.yml b/.github/workflows/linux_python_build.yml index 7eac9f8..f8f995c 100644 --- a/.github/workflows/linux_python_build.yml +++ b/.github/workflows/linux_python_build.yml @@ -12,7 +12,7 @@ jobs: 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 -m pip install --upgrade pip + - run: /opt/python/cp310-cp310/bin/pip install --upgrade pip - run: /opt/python/cp310-cp310/bin/pip install twine==2.0.0 - name: create-whl-dir From a9ccd398d17068f74cb9052cda1e52c88ed65478 Mon Sep 17 00:00:00 2001 From: liufang_robot Date: Thu, 28 Sep 2023 03:49:45 +0000 Subject: [PATCH 15/20] =?UTF-8?q?fix:=20=E4=BF=AE=E6=AD=A3=E4=BE=9D?= =?UTF-8?q?=E8=B5=96=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- requirements.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/requirements.txt b/requirements.txt index df7b04d..e42537f 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,2 +1,3 @@ swig==4.0.2 cmake==3.18.2 +readme-renderer==37.3 From 2cf524f189d500f992343c9d1d0dd375bb36e724 Mon Sep 17 00:00:00 2001 From: liufang_robot Date: Thu, 28 Sep 2023 03:51:50 +0000 Subject: [PATCH 16/20] =?UTF-8?q?fix:=20=E4=BF=AE=E6=AD=A3=E4=BE=9D?= =?UTF-8?q?=E8=B5=96=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/linux_python_build.yml | 1 - requirements.txt | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/.github/workflows/linux_python_build.yml b/.github/workflows/linux_python_build.yml index f8f995c..ac0fc55 100644 --- a/.github/workflows/linux_python_build.yml +++ b/.github/workflows/linux_python_build.yml @@ -12,7 +12,6 @@ jobs: 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 --upgrade pip - run: /opt/python/cp310-cp310/bin/pip install twine==2.0.0 - name: create-whl-dir diff --git a/requirements.txt b/requirements.txt index e42537f..1c4a3f8 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,3 +1,3 @@ swig==4.0.2 cmake==3.18.2 -readme-renderer==37.3 +readme-renderer==34.0 From 83e8af5feda603766ece488a7c205c863d03d47c Mon Sep 17 00:00:00 2001 From: liufang_robot Date: Fri, 27 Oct 2023 06:49:21 +0000 Subject: [PATCH 17/20] =?UTF-8?q?feat:=20=E6=B7=BB=E5=8A=A0speedl=E6=94=AF?= =?UTF-8?q?=E6=8C=81reference=E5=9D=90=E6=A0=87=E7=B3=BB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CMakeLists.txt | 2 +- Doxyfile | 2 +- doc/changelog.md | 4 ++ examples/example_speedl.cc | 56 +++++++++++++++++++ sdk/include/lebai/robot.hh | 6 +- sdk/src/protos/system.cc | 112 ++++++++++++++++++------------------- sdk/src/protos/system.hh | 4 +- sdk/src/robot.cc | 72 +++++++++++++++++++++++- sdk/src/robot_impl.cc | 7 ++- sdk/test/test_robot.cc | 4 +- 10 files changed, 200 insertions(+), 69 deletions(-) create mode 100644 examples/example_speedl.cc diff --git a/CMakeLists.txt b/CMakeLists.txt index 388ee95..f24188e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -8,7 +8,7 @@ list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake") option(CMAKE_EXPORT_COMPILE_COMMANDS "Export compile command" TRUE) -project(lebai VERSION 1.1.8 LANGUAGES CXX) +project(lebai VERSION 1.1.9 LANGUAGES CXX) set(PROJECT_NAMESPACE lebai) message(STATUS "${PROJECT_NAME} version: ${PROJECT_VERSION}") # message(STATUS "major: ${PROJECT_VERSION_MAJOR}") diff --git a/Doxyfile b/Doxyfile index 7230143..f604157 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.1.8 +PROJECT_NUMBER = 1.1.9 # 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/doc/changelog.md b/doc/changelog.md index 4487972..6e9f06c 100644 --- a/doc/changelog.md +++ b/doc/changelog.md @@ -2,6 +2,10 @@ ## 1.1.8 +speedl添加参考坐标系 + +## 1.1.8 + 修正.net包描述问题 修正注释和文档的一些bug diff --git a/examples/example_speedl.cc b/examples/example_speedl.cc new file mode 100644 index 0000000..dd5c1a2 --- /dev/null +++ b/examples/example_speedl.cc @@ -0,0 +1,56 @@ +/** + * Copyright 2022 lebai.ltd + * + * 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. +*/ + +#include +#include +#include +#include +#include + + +int main(int argc, char ** argv) +{ + if(argc < 2) + { + std::cerr<<"You must specify the IP address of the robot"< 2) + { + std::string sim_str = argv[2]; + if(sim_str == "sim") + { + sim = true; + } + } + std::cout<<"Connecting to robot at "<0 发送成功.返回运动号 * @return <=0 发送失败. */ - int speedl(double a, const CartesianPose & v, double t = 0.0); + int speedl(double a, const CartesianPose & v, double t = 0.0, const CartesianPose & reference = {{"x", 0.0}, {"y", 0.0}, {"z", 0.0}, {"rx", 0.0}, {"ry", 0.0}, {"rz", 0.0}}); /** * 示例代码: * diff --git a/sdk/src/protos/system.cc b/sdk/src/protos/system.cc index 6ae1522..ae3da03 100755 --- a/sdk/src/protos/system.cc +++ b/sdk/src/protos/system.cc @@ -10,76 +10,76 @@ namespace lebai { state_ = state; } - const RobotState & GetRobotStateResponse::state() const + const RobotState &GetRobotStateResponse::state() const { return state_; } - RobotState * GetRobotStateResponse::mutable_state() + RobotState *GetRobotStateResponse::mutable_state() { return &state_; } - bool GetRobotStateResponse::Deserialize(const rapidjson::Value& obj) + bool GetRobotStateResponse::Deserialize(const rapidjson::Value &obj) { if (obj.HasMember("state")) { std::string state_str = std::string(obj["state"].GetString()); - if(state_str == "DISCONNECTED") + if (state_str == "ERROR") + { + state_ = ERROR; + } + else if (state_str == "DISCONNECTED") { state_ = DISCONNECTED; } - else if(state_str == "ESTOP") + else if (state_str == "ESTOP") { state_ = ESTOP; } - else if(state_str == "BOOTING") + else if (state_str == "BOOTING") { state_ = BOOTING; } - else if(state_str == "ROBOT_OFF") + else if (state_str == "ROBOT_OFF") { state_ = ROBOT_OFF; } - else if(state_str == "ROBOT_ON") + else if (state_str == "ROBOT_ON") { state_ = ROBOT_ON; } - else if(state_str == "IDLE") + else if (state_str == "IDLE") { state_ = IDLE; } - else if(state_str == "PAUSED") + else if (state_str == "PAUSED") { state_ = PAUSED; } - else if(state_str == "MOVING") + else if (state_str == "MOVING") { state_ = MOVING; } - else if(state_str == "UPDATING") + else if (state_str == "UPDATING") { state_ = UPDATING; } - else if(state_str == "STOPPING") + else if (state_str == "STOPPING") { state_ = STOPPING; } - else if(state_str == "TEACHING") + else if (state_str == "TEACHING") { state_ = TEACHING; } - else if(state_str == "STOP") + else if (state_str == "STOP") { state_ = STOP; } - else if(state_str == "FINETUNING") - { - state_ = FINETUNING; - } return true; } - return false; + return false; } - bool GetRobotStateResponse::Serialize(rapidjson::Writer* writer) const + bool GetRobotStateResponse::Serialize(rapidjson::Writer *writer) const { writer->StartObject(); writer->Key("state"); @@ -92,7 +92,6 @@ namespace lebai return false; } - void SystemInfo::set_name(const std::string &name) { name_ = name; @@ -102,7 +101,7 @@ namespace lebai return name_; } - std::string * SystemInfo::mutable_name() + std::string *SystemInfo::mutable_name() { return &name_; } @@ -148,27 +147,27 @@ namespace lebai return false; } - void PhyData::set_joint_temp(const std::vector & joint_temp) + void PhyData::set_joint_temp(const std::vector &joint_temp) { joint_temp_ = joint_temp; } - const std::vector & PhyData::joint_temp() const + const std::vector &PhyData::joint_temp() const { return joint_temp_; } - std::vector * PhyData::mutable_joint_temp() + std::vector *PhyData::mutable_joint_temp() { return &joint_temp_; } - void PhyData::set_joint_voltage(const std::vector & joint_voltage) + void PhyData::set_joint_voltage(const std::vector &joint_voltage) { joint_voltage_ = joint_voltage; } - const std::vector & PhyData::joint_voltage() const + const std::vector &PhyData::joint_voltage() const { return joint_voltage_; } - std::vector * PhyData::mutable_joint_voltage() + std::vector *PhyData::mutable_joint_voltage() { return &joint_voltage_; } @@ -181,48 +180,48 @@ namespace lebai { return flange_voltage_; } - double * PhyData::mutable_flange_voltage() + double *PhyData::mutable_flange_voltage() { return &flange_voltage_; } - bool PhyData::Deserialize(const rapidjson::Value& obj) + bool PhyData::Deserialize(const rapidjson::Value &obj) { - if(obj.HasMember("joint_temp")) + if (obj.HasMember("joint_temp")) { joint_temp_.clear(); - for(auto iter = obj["joint_temp"].GetArray().Begin(); iter != obj["joint_temp"].GetArray().End(); iter++) + for (auto iter = obj["joint_temp"].GetArray().Begin(); iter != obj["joint_temp"].GetArray().End(); iter++) { joint_temp_.push_back(iter->GetDouble()); } } - if(obj.HasMember("joint_voltage")) + if (obj.HasMember("joint_voltage")) { joint_voltage_.clear(); - for(auto iter = obj["joint_voltage"].GetArray().Begin(); iter != obj["joint_voltage"].GetArray().End(); iter++) + for (auto iter = obj["joint_voltage"].GetArray().Begin(); iter != obj["joint_voltage"].GetArray().End(); iter++) { joint_voltage_.push_back(iter->GetDouble()); - } + } } - if(obj.HasMember("flange_voltage")) + if (obj.HasMember("flange_voltage")) { flange_voltage_ = obj["flange_voltage"].GetDouble(); } return true; } - bool PhyData::Serialize(rapidjson::Writer* writer) const + bool PhyData::Serialize(rapidjson::Writer *writer) const { writer->StartObject(); writer->String("joint_temp"); writer->StartArray(); - for(auto iter = joint_temp_.begin(); iter != joint_temp_.end(); iter++) + for (auto iter = joint_temp_.begin(); iter != joint_temp_.end(); iter++) { writer->Double(*iter); } writer->EndArray(); writer->String("joint_voltage"); writer->StartArray(); - for(auto iter = joint_voltage_.begin(); iter != joint_voltage_.end(); iter++) + for (auto iter = joint_voltage_.begin(); iter != joint_voltage_.end(); iter++) { writer->Double(*iter); } @@ -237,73 +236,72 @@ namespace lebai return false; } - void GetEstopReasonResponse::set_reason(EstopReason reason) { reason_ = reason; } - const EstopReason & GetEstopReasonResponse::reason() const + const EstopReason &GetEstopReasonResponse::reason() const { return reason_; } - EstopReason * GetEstopReasonResponse::mutable_reason() + EstopReason *GetEstopReasonResponse::mutable_reason() { return &reason_; } - bool GetEstopReasonResponse::Deserialize(const rapidjson::Value& obj) + bool GetEstopReasonResponse::Deserialize(const rapidjson::Value &obj) { if (obj.HasMember("reason")) { std::string reason_str = std::string(obj["reason"].GetString()); - if(reason_str == "NONE") + if (reason_str == "NONE") { reason_ = NONE; } - else if(reason_str == "SYSTEM") + else if (reason_str == "SYSTEM") { reason_ = SYSTEM; } - else if(reason_str == "MANUAL") + else if (reason_str == "MANUAL") { reason_ = MANUAL; } - else if(reason_str == "HARD_ESTOP") + else if (reason_str == "HARD_ESTOP") { reason_ = HARD_ESTOP; } - else if(reason_str == "COLLISION") + else if (reason_str == "COLLISION") { reason_ = COLLISION; } - else if(reason_str == "JOINT_LIMIT") + else if (reason_str == "JOINT_LIMIT") { reason_ = JOINT_LIMIT; } - else if(reason_str == "EXCEED") + else if (reason_str == "EXCEED") { reason_ = EXCEED; } - else if(reason_str == "TRAJECTORY_ERROR") + else if (reason_str == "TRAJECTORY_ERROR") { reason_ = TRAJECTORY_ERROR; } - else if(reason_str == "COMM_ERROR") + else if (reason_str == "COMM_ERROR") { reason_ = COMM_ERROR; } - else if(reason_str == "CAN_ERROR") + else if (reason_str == "CAN_ERROR") { reason_ = CAN_ERROR; } - else if(reason_str == "JOINT_ERROR") + else if (reason_str == "JOINT_ERROR") { reason_ = JOINT_ERROR; } return true; } - return false; + return false; } - bool GetEstopReasonResponse::Serialize(rapidjson::Writer* writer) const + bool GetEstopReasonResponse::Serialize(rapidjson::Writer *writer) const { writer->StartObject(); writer->Key("reason"); diff --git a/sdk/src/protos/system.hh b/sdk/src/protos/system.hh index a9379ed..a65c208 100644 --- a/sdk/src/protos/system.hh +++ b/sdk/src/protos/system.hh @@ -12,6 +12,7 @@ namespace lebai { enum RobotState { + ERROR = -1, DISCONNECTED = 0, ESTOP = 1, BOOTING = 2, @@ -24,8 +25,7 @@ namespace lebai STARTING = 9, STOPPING = 10, TEACHING = 11, - STOP = 12, - FINETUNING = 13 + STOP = 12 }; class GetRobotStateResponse : public JSONBase { diff --git a/sdk/src/robot.cc b/sdk/src/robot.cc index 9c35e01..394312b 100644 --- a/sdk/src/robot.cc +++ b/sdk/src/robot.cc @@ -390,7 +390,7 @@ int Robot::speedj(double a, const std::vector & v, double t) return resp.id(); } -int Robot::speedl(double a, const CartesianPose & v, double t) +int Robot::speedl(double a, const CartesianPose & v, double t, const CartesianPose & reference) { motion::SpeedLRequest req; req.mutable_param()->set_acc(a); @@ -443,6 +443,76 @@ int Robot::speedl(double a, const CartesianPose & v, double t) { return -1; } + // if(reference == BASE) { + // req.mutable_frame()->set_position_kind(posture::CartesianFrame::Kind::BASE); + // req.mutable_frame()->set_rotation_kind(posture::CartesianFrame::Kind::BASE); + // } else if(reference == FLANGE) { + // req.mutable_frame()->set_position_kind(posture::CartesianFrame::Kind::FLANGE); + // req.mutable_frame()->set_rotation_kind(posture::CartesianFrame::Kind::FLANGE); + // } else if(reference == TCP) { + // auto tcp = get_target_tcp_pose(); + // req.mutable_frame()->mutable_position()->set_x(tcp["x"]); + // req.mutable_frame()->mutable_position()->set_y(tcp["y"]); + // req.mutable_frame()->mutable_position()->set_z(tcp["z"]); + // req.mutable_frame()->mutable_rotation()->mutable_euler_zyx()->set_x(tcp["rx"]); + // req.mutable_frame()->mutable_rotation()->mutable_euler_zyx()->set_y(tcp["ry"]); + // req.mutable_frame()->mutable_rotation()->mutable_euler_zyx()->set_z(tcp["rz"]); + // req.mutable_frame()->set_position_kind(posture::CartesianFrame::Kind::CUSTOM); + // req.mutable_frame()->set_rotation_kind(posture::CartesianFrame::Kind::CUSTOM); + // } else { + // return -1; + // } + req.mutable_frame()->set_position_kind(posture::CartesianFrame::Kind::CUSTOM); + req.mutable_frame()->set_rotation_kind(posture::CartesianFrame::Kind::CUSTOM); + + if(reference.find("x") != reference.end()) + { + req.mutable_frame()->mutable_position()->set_x(reference.at("x")); + } + else + { + return -1; + } + if(reference.find("y") != reference.end()) + { + req.mutable_frame()->mutable_position()->set_y(reference.at("y")); + } + else + { + return -1; + } + if(reference.find("z") != reference.end()) + { + req.mutable_frame()->mutable_position()->set_z(reference.at("z")); + } + else + { + return -1; + } + if(reference.find("rx") != reference.end()) + { + req.mutable_frame()->mutable_rotation()->mutable_euler_zyx()->set_x(reference.at("rx")); + } + else + { + return -1; + } + if(reference.find("ry") != reference.end()) + { + req.mutable_frame()->mutable_rotation()->mutable_euler_zyx()->set_y(reference.at("ry")); + } + else + { + return -1; + } + if(reference.find("rz") != reference.end()) + { + req.mutable_frame()->mutable_rotation()->mutable_euler_zyx()->set_z(reference.at("rz")); + } + else + { + return -1; + } lebai::motion::MotionIndex resp = impl_->speedLinear(req); return resp.id(); } diff --git a/sdk/src/robot_impl.cc b/sdk/src/robot_impl.cc index 795fbb9..1a39632 100644 --- a/sdk/src/robot_impl.cc +++ b/sdk/src/robot_impl.cc @@ -153,9 +153,14 @@ namespace lebai motion::MotionIndex Robot::RobotImpl::speedLinear(const motion::SpeedLRequest & req) { std::string resp; - json_rpc_connector_->CallRpc("speed_linear",req.ToJSONString(),&resp); + + auto req_string = req.ToJSONString(); + std::cout<<"req "<CallRpc("speed_linear",req_string,&resp); + // json_rpc_connector_->CallRpc("speed_linear",req.ToJSONString(),&resp); motion::MotionIndex motion_resp; motion_resp.FromJSONString(resp); + std::cout<<"resp "< Date: Fri, 27 Oct 2023 06:56:23 +0000 Subject: [PATCH 18/20] =?UTF-8?q?fix:=20=E7=89=88=E6=9C=AC->1.1.8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CMakeLists.txt | 2 +- Doxyfile | 2 +- doc/changelog.md | 2 -- 3 files changed, 2 insertions(+), 4 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index f24188e..388ee95 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -8,7 +8,7 @@ list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake") option(CMAKE_EXPORT_COMPILE_COMMANDS "Export compile command" TRUE) -project(lebai VERSION 1.1.9 LANGUAGES CXX) +project(lebai VERSION 1.1.8 LANGUAGES CXX) set(PROJECT_NAMESPACE lebai) message(STATUS "${PROJECT_NAME} version: ${PROJECT_VERSION}") # message(STATUS "major: ${PROJECT_VERSION_MAJOR}") diff --git a/Doxyfile b/Doxyfile index f604157..7230143 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.1.9 +PROJECT_NUMBER = 1.1.8 # 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/doc/changelog.md b/doc/changelog.md index 6e9f06c..9035e37 100644 --- a/doc/changelog.md +++ b/doc/changelog.md @@ -4,8 +4,6 @@ speedl添加参考坐标系 -## 1.1.8 - 修正.net包描述问题 修正注释和文档的一些bug From 54b62f0ba7f36976c7025f3e78810cb6a01371e0 Mon Sep 17 00:00:00 2001 From: liufang_robot Date: Fri, 27 Oct 2023 09:03:53 +0000 Subject: [PATCH 19/20] fix: --- .github/workflows/linux_cpp_release.yml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/linux_cpp_release.yml b/.github/workflows/linux_cpp_release.yml index 4945e50..2115fe3 100644 --- a/.github/workflows/linux_cpp_release.yml +++ b/.github/workflows/linux_cpp_release.yml @@ -6,11 +6,11 @@ on: tags: - v1.*.* # Sets permissions of the GITHUB_TOKEN to allow deployment to GitHub Pages -permissions: - contents: read - pages: write - id-token: write - pull-requests: read +# permissions: +# contents: read +# pages: write +# id-token: write +# pull-requests: read jobs: linux_cpp_build_and_release: From 14c875bd66b3251390eeb46ef8171d9b53dddd7d Mon Sep 17 00:00:00 2001 From: liufang_robot Date: Fri, 10 Nov 2023 02:31:47 +0000 Subject: [PATCH 20/20] =?UTF-8?q?fix:=20=E4=BF=AE=E6=AD=A3future=E4=B8=8D?= =?UTF-8?q?=E8=83=BD=E8=BF=94=E5=9B=9E=E7=9A=84=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CMakeLists.txt | 2 +- Doxyfile | 2 +- doc/changelog.md | 4 + examples/example.cc | 84 +++++---- sdk/include/lebai/robot.hh | 10 +- sdk/src/jsonrpc_connector.cc | 269 ++++++++++++++------------- sdk/src/robot_impl.cc | 1 + sdk/src/websocket.hh | 16 +- sdk/third/websocketpp/connection.hpp | 2 +- 9 files changed, 221 insertions(+), 169 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 388ee95..f24188e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -8,7 +8,7 @@ list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake") option(CMAKE_EXPORT_COMPILE_COMMANDS "Export compile command" TRUE) -project(lebai VERSION 1.1.8 LANGUAGES CXX) +project(lebai VERSION 1.1.9 LANGUAGES CXX) set(PROJECT_NAMESPACE lebai) message(STATUS "${PROJECT_NAME} version: ${PROJECT_VERSION}") # message(STATUS "major: ${PROJECT_VERSION_MAJOR}") diff --git a/Doxyfile b/Doxyfile index 7230143..f604157 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.1.8 +PROJECT_NUMBER = 1.1.9 # 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/doc/changelog.md b/doc/changelog.md index 9035e37..999ceaa 100644 --- a/doc/changelog.md +++ b/doc/changelog.md @@ -1,5 +1,9 @@ # ChangeLog +## 1.1.9 + +添加接口连接抛出异常的处理 + ## 1.1.8 speedl添加参考坐标系 diff --git a/examples/example.cc b/examples/example.cc index 534d99c..29195ae 100755 --- a/examples/example.cc +++ b/examples/example.cc @@ -1,18 +1,18 @@ /** * Copyright 2022 lebai.ltd - * + * * 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. -*/ + */ #include #include @@ -20,57 +20,77 @@ #include #include - -int main(int argc, char ** argv) +int main(int argc, char **argv) { - if(argc < 2) + if (argc < 2) { - std::cerr<<"You must specify the IP address of the robot"< 2) + if (argc > 2) { std::string sim_str = argv[2]; - if(sim_str == "sim") + if (sim_str == "sim") { sim = true; } } - std::cout<<"Connecting to robot at "< jp = {3.0/ 180.0 * M_PI, -48.0/ 180.0 * M_PI, 78.0/ 180.0 * M_PI, 9.0/ 180.0 * M_PI, -67.0/ 180.0 * M_PI, -3.0/ 180.0 * M_PI}; - //std::cout<<"jp "< jp = {3.0/ 180.0 * M_PI, -48.0/ 180.0 * M_PI, 78.0/ 180.0 * M_PI, 9.0/ 180.0 * M_PI, -67.0/ 180.0 * M_PI, -3.0/ 180.0 * M_PI}; + // std::cout<<"jp "<=3.1.5。 + * @note 接口的每一个函数都可能抛出异常std::runtime_error, 这是因为网络连接丢失或者调用的逻辑错误等。 + * * */ class Robot @@ -71,6 +73,7 @@ namespace lebai /** * @brief 内部实现. * @note 用户无需使用. + * */ class RobotImpl; @@ -80,11 +83,6 @@ namespace lebai * @brief 构造Robot对象. * @note 当你尝试创建Robot对象时,会根据传入的ip参数尝试去连接机械臂,但是可能会连接失败,当连接不成功时,对象依然会创建。 * - * 但是如果网络没有连接成功而你调用和机械臂交互的接口时,会抛出std::runtime_error异常,表示网络连接异常. - * - * 你可以通过@ref is_network_connected()方法来判断是否连接成功,如果连接不成功,你可以尝试重新创建Robot对象,或者等待网络恢复. - * - * * * @param ip: 机械臂IP地址. * @param simulator: 用于表示机械臂是否为仿真机械臂(docker仿真或控制器运行在仿真模式下)的macs标志.True表示仿真模式,False表示实物机械臂. @@ -115,7 +113,7 @@ namespace lebai /** * @brief 返回是否和机械臂的网络连接正常,如果网络连接异常,调用和机械臂交互的接口会抛出异常std::runtime_error。 - * + * @note 不建议使用,直接catch接口调用获取网络异常。 * @return true 表示网络连接正常,false表示网络连接异常. */ bool is_network_connected(); diff --git a/sdk/src/jsonrpc_connector.cc b/sdk/src/jsonrpc_connector.cc index f9a2668..c609981 100755 --- a/sdk/src/jsonrpc_connector.cc +++ b/sdk/src/jsonrpc_connector.cc @@ -1,163 +1,178 @@ /** * Copyright 2022 lebai.ltd - * + * * 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. -*/ + */ #include "jsonrpc_connector.hh" #include #include +#include #include "protos/utils.hh" namespace lebai { -JSONRpcConnector::JSONRpcConnector(const std::string & ip, uint16_t port) -{ - jsonrpc_id_ = 0; - std::string url = "ws://"+ip + ":" + std::to_string(port); - id_ = endpoint_.connect(url); -} -JSONRpcConnector::~JSONRpcConnector(){} - -// int JSONRpcConnector::Call(const std::string & method, rapidjson::Value & req_data, rapidjson::Value & resp_data) -// { -// rapidjson::Document d; -// rapidjson::Value req; -// req.SetObject(); -// req.AddMember("jsonrpc", "2.0", d.GetAllocator()); -// // req.AddMember("id", jsonrpc_id_++, d.GetAllocator()); -// rapidjson::Value method_value; -// method_value.SetString(method.c_str(), method.size(), d.GetAllocator()); -// req.AddMember("method", method_value, d.GetAllocator()); -// req.AddMember("params", req_data, d.GetAllocator()); -// rapidjson::StringBuffer buffer; -// rapidjson::Writer writer(buffer); -// req.Accept(writer); -// std::string req_str = buffer.GetString(); -// if(GetConnectionStatus() != kOpen) -// { -// return -1; -// } -// // std::cout << "req_str: " << req_str << std::endl; -// endpoint_.send(id_, req_str); -// auto const & resp_str = endpoint_.get_metadata(id_)->GetMessageStr(); -// // std::cout<<"resp_str: "<(resp_str.c_str()); -// rapidjson::Value::MemberIterator iter = d.FindMember("result"); -// if(iter == d.MemberEnd()) -// { -// return -1; -// } -// resp_data = iter->value; -// return 0; -// } - -// int JSONRpcConnector::CallString(int id, const std::string &method, const std::string & req_str, std::string * resp_str) -// { -// if(GetConnectionStatus() != kOpen) -// { -// return -1; -// } -// // std::string str_jsonrpc = "\"jsonrpc\":\"2.0\","; -// // std::string str_method = "\"method\":\"" + method + "\","; -// // std::string str_params = "\"params\":" + req_str + ","; -// // std::string str_id = "\"id\":" + std::to_string(jsonrpc_id_); -// // jsonrpc_id_++; -// std::string jsonrpc_req = "{\"jsonrpc\":\"2.0\",\"method\":\"" +method + -// "\",\"params\":"+req_str+",\"id\":"+ std::to_string(id)+ "}"; -// // str_method + str_params + str_id + "}"; -// // std::cerr<<"xxx jsonrpc_req: "<GetMessageStr(); -// *resp_str = jsonrpc_resp; + JSONRpcConnector::JSONRpcConnector(const std::string &ip, uint16_t port) + { + jsonrpc_id_ = 0; + std::string url = "ws://" + ip + ":" + std::to_string(port); + id_ = endpoint_.connect(url); + } + JSONRpcConnector::~JSONRpcConnector() {} -// // std::cerr << "jsonrpc_resp: " << *resp_str << std::endl; -// } -// // {"jsonrpc": "2.0", "error": {"code": -32600, "message": "Invalid Request"}, "id": null} + // int JSONRpcConnector::Call(const std::string & method, rapidjson::Value & req_data, rapidjson::Value & resp_data) + // { + // rapidjson::Document d; + // rapidjson::Value req; + // req.SetObject(); + // req.AddMember("jsonrpc", "2.0", d.GetAllocator()); + // // req.AddMember("id", jsonrpc_id_++, d.GetAllocator()); + // rapidjson::Value method_value; + // method_value.SetString(method.c_str(), method.size(), d.GetAllocator()); + // req.AddMember("method", method_value, d.GetAllocator()); + // req.AddMember("params", req_data, d.GetAllocator()); + // rapidjson::StringBuffer buffer; + // rapidjson::Writer writer(buffer); + // req.Accept(writer); + // std::string req_str = buffer.GetString(); + // if(GetConnectionStatus() != kOpen) + // { + // return -1; + // } + // // std::cout << "req_str: " << req_str << std::endl; + // endpoint_.send(id_, req_str); + // auto const & resp_str = endpoint_.get_metadata(id_)->GetMessageStr(); + // // std::cout<<"resp_str: "<(resp_str.c_str()); + // rapidjson::Value::MemberIterator iter = d.FindMember("result"); + // if(iter == d.MemberEnd()) + // { + // return -1; + // } + // resp_data = iter->value; + // return 0; + // } -// return 0; -// } + // int JSONRpcConnector::CallString(int id, const std::string &method, const std::string & req_str, std::string * resp_str) + // { + // if(GetConnectionStatus() != kOpen) + // { + // return -1; + // } + // // std::string str_jsonrpc = "\"jsonrpc\":\"2.0\","; + // // std::string str_method = "\"method\":\"" + method + "\","; + // // std::string str_params = "\"params\":" + req_str + ","; + // // std::string str_id = "\"id\":" + std::to_string(jsonrpc_id_); + // // jsonrpc_id_++; + // std::string jsonrpc_req = "{\"jsonrpc\":\"2.0\",\"method\":\"" +method + + // "\",\"params\":"+req_str+",\"id\":"+ std::to_string(id)+ "}"; + // // str_method + str_params + str_id + "}"; + // // std::cerr<<"xxx jsonrpc_req: "<GetMessageStr(); + // *resp_str = jsonrpc_resp; -// int JSONRpcConnector::CallRpc(const std::string & req_str, std::string * resp_str) -// { -// std::cout<<"req_str "<GetMessageStr(); -// int resp_id; -// ExtractJSONRpcRespString(*resp_str, resp_id, *resp_str); -// if(resp_id != id) -// { -// return -1; -// } -// std::cout<<"resp_str "<<*resp_str<<"\n"; -// } -// } + // // std::cerr << "jsonrpc_resp: " << *resp_str << std::endl; + // } + // // {"jsonrpc": "2.0", "error": {"code": -32600, "message": "Invalid Request"}, "id": null} + // return 0; + // } + // int JSONRpcConnector::CallRpc(const std::string & req_str, std::string * resp_str) + // { + // std::cout<<"req_str "<GetMessageStr(); + // int resp_id; + // ExtractJSONRpcRespString(*resp_str, resp_id, *resp_str); + // if(resp_id != id) + // { + // return -1; + // } + // std::cout<<"resp_str "<<*resp_str<<"\n"; + // } + // } -int JSONRpcConnector::CallRpc(const std::string & method, const std::string & req_data_str, std::string * resp_data_str) -{ - int call_jsonrpc_id = jsonrpc_id_++; - std::string jsonrpc_req; - std::string jsonrpc_resp; - jsonrpc_req = ToJSONRpcReqString(call_jsonrpc_id, method, req_data_str); - // std::cout<<"jsonrpc_req id:"<(resq_data); - if(error_code < 0) + int call_jsonrpc_id = jsonrpc_id_++; + std::string jsonrpc_req; + std::string jsonrpc_resp; + jsonrpc_req = ToJSONRpcReqString(call_jsonrpc_id, method, req_data_str); + auto future = endpoint_.createFuture(id_, call_jsonrpc_id); + if (!endpoint_.send(id_, jsonrpc_req)) { - throw std::runtime_error(std::get<1>(resq_data)); + endpoint_.deletePromise(id_, call_jsonrpc_id); + throw std::runtime_error("Send Jsonrpc request failed!"); + } + using namespace std::chrono_literals; + // TODO(@liufang) This corner case is not not good, need to be improved. + if (method != "wait_move") + { + // TODO(@liufang) Make the timeout configurable. + std::future_status status = future.wait_for(5s); + switch (status) + { + case std::future_status::deferred: + case std::future_status::timeout: + // std::cout << "timeout!\n"; + throw std::runtime_error("No response from robot controller!"); + case std::future_status::ready: + break; + } } - *resp_data_str = std::get<1>(resq_data); - } - return 0; -} -JSONRpcConnector::ConnectionStatus JSONRpcConnector::GetConnectionStatus() -{ - auto status = endpoint_.get_metadata(id_)->getStatus(); - if(status == "Open") - { - return kOpen; - } - else if(status == "Connecting") - { - return kConnecting; - } - else if(status == "Closed") - { - return kClosed; + auto resq_data = future.get(); + if (resp_data_str) + { + auto error_code = std::get<0>(resq_data); + if (error_code < 0) + { + throw std::runtime_error(std::get<1>(resq_data)); + } + *resp_data_str = std::get<1>(resq_data); + } + return 0; } - else + + JSONRpcConnector::ConnectionStatus JSONRpcConnector::GetConnectionStatus() { - return kFailed; + auto status = endpoint_.get_metadata(id_)->getStatus(); + if (status == "Open") + { + return kOpen; + } + else if (status == "Connecting") + { + return kConnecting; + } + else if (status == "Closed") + { + return kClosed; + } + else + { + return kFailed; + } } -} - }; \ No newline at end of file diff --git a/sdk/src/robot_impl.cc b/sdk/src/robot_impl.cc index 1a39632..75d1cae 100644 --- a/sdk/src/robot_impl.cc +++ b/sdk/src/robot_impl.cc @@ -57,6 +57,7 @@ namespace lebai bool Robot::RobotImpl::isNetworkConnected() { + // return json_rpc_connector_->Ping(); return json_rpc_connector_->GetConnectionStatus() == JSONRpcConnector::kOpen; } diff --git a/sdk/src/websocket.hh b/sdk/src/websocket.hh index 628b0f0..0a24a70 100644 --- a/sdk/src/websocket.hh +++ b/sdk/src/websocket.hh @@ -91,6 +91,7 @@ namespace lebai auto ret = ExtractJSONRpcRespString(message_str, callback_jsonrpc_id, error_code, resp_data_str); if(ret == JSONRpcRespParseResult::kInvalid) { + std::cout<<"invalid jsonrpc response\n"; return; } else @@ -133,7 +134,14 @@ namespace lebai promises_[rpc_id] = std::make_unique>>(); return promises_[rpc_id]->get_future();; } - + void deletePromise(int rpc_id) + { + std::lock_guard guard(promises_map_mutex_); + if(promises_.find(rpc_id) != promises_.end()) + { + promises_.erase(rpc_id); + } + } // friend std::ostream& operator<<(std::ostream& out, @@ -300,6 +308,12 @@ namespace lebai return metadata_it->second->createPromise(rpc_id); } + void deletePromise(int id, int rpc_id) + { + ConList::iterator metadata_it = connection_list_.find(id); + metadata_it->second->deletePromise(rpc_id); + } + ConnectionMetadata::ptr get_metadata(int id) const { diff --git a/sdk/third/websocketpp/connection.hpp b/sdk/third/websocketpp/connection.hpp index d019fce..e769b36 100644 --- a/sdk/third/websocketpp/connection.hpp +++ b/sdk/third/websocketpp/connection.hpp @@ -373,7 +373,7 @@ class connection m_fail_handler = h; } - /// Set ping handler + /// Set ping hangfpdler /** * The ping handler is called whenever the connection receives a ping * control frame. The ping payload is included.