Vui lòng hỏi về các vấn đề và câu hỏi liên quan đến hướng dẫn này về câu trả lời. hoa hồng. tổ chức. Đừng quên đưa vào câu hỏi của bạn liên kết đến trang này, các phiên bản HĐH & ROS của bạn, đồng thời thêm các thẻ thích hợp
Sự mô tả. Hướng dẫn này minh họa cách sử dụng lớp C++ với thông báo ROS trong Pythontừ khóa. C++, Python, ràng buộc
Cấp hướng dẫn. NÂNG CAO
Hướng dẫn tiếp theo. Viết Hướng dẫn
rosbuild
Hướng dẫn này minh họa cách sử dụng lớp C++ với thông báo ROS trong Python. Thư viện Boost Python được sử dụng. Khó khăn là dịch các đối tượng Python của các thông báo ROS được viết bằng Python thuần túy sang các phiên bản C++ tương đương. Bản dịch này sẽ được thực hiện thông qua serialization/deserialization. Các tập tin nguồn có thể được tìm thấy tại https. //github. com/galou/python_bindings_tutorial
Một giải pháp khác là sử dụng các dịch vụ ROS cổ điển, máy chủ được viết bằng C++ sẽ là một trình bao bọc xung quanh lớp C++ và máy khách, C++ hoặc Python, sẽ gọi dịch vụ. Giải pháp được đề xuất ở đây không tạo nút ROS, miễn là lớp được bao bọc không sử dụng ros. Xử lý nút
Một giải pháp khác là viết một trình bao bọc cho tất cả các thông báo ROS cần thiết và các phần phụ thuộc của chúng. Một số gói dường như không dùng nữa đã đề xuất một số giải pháp để tự động hóa tác vụ này. genpybindings và boost_ python_ros
Lớp không có NodeHandle
Vì roscpp không được khởi tạo khi gọi rospy. init_node. hoa hồng. Các phiên bản NodeHandle không thể được sử dụng trong lớp C++ mà không tạo ra lỗi. Nếu C++ không sử dụng hoa hồng. NodeHandle, đây không phải là vấn đề
Tạo gói và viết lớp C++
Tạo một gói và tạo lớp C++ mà chúng ta sẽ muốn tạo một liên kết Python. Lớp này sử dụng các thông báo ROS làm đối số và kiểu trả về
Nội dung của bao gồm/python_bindings_tutorial/add_two_ints. h sẽ là
Viết việc thực hiện lớp vào
roscd python_bindings_tutorial/src touch add_two_ints.cpp rosed python_bindings_tutorial add_two_ints.cpp
Nội dung của src/add_two_ints. cpp sẽ là
1 #include 2 3 using namespace python_bindings_tutorial; 4 5 std_msgs::Int64 AddTwoInts::add[const std_msgs::Int64& a, const std_msgs::Int64& b] 6 { 7 std_msgs::Int64 sum; 8 sum.data = a.data + b.data; 9 return sum; 10 }
Ràng buộc, phần C++
Liên kết xảy ra thông qua hai lớp trình bao bọc, một trong C++ và một trong Python. Trình bao bọc C++ dịch đầu vào từ nội dung được tuần tự hóa sang các phiên bản thông báo C++ và đầu ra từ các phiên bản thông báo C++ thành nội dung được tuần tự hóa
1 roscd python_bindings_tutorial/src 2 touch add_two_ints_wrapper.cpp 3 rosed python_bindings_tutorial add_two_ints_wrapper.cpp
Nội dung của src/add_two_ints_wrapper. cpp sẽ là
Lỗi dòng. Không tìm thấy code_block tạo mô-đun Python ở dạng thư viện động. Tên của mô-đun sẽ phải là tên của thư viện đã xuất trong CMakeLists. txt
Ràng buộc, phần Python
Trình bao bọc Python dịch đầu vào từ các phiên bản thông báo Python thành nội dung được tuần tự hóa và đầu ra từ nội dung được tuần tự hóa thành các phiên bản thông báo Python. Bản dịch từ nội dung tuần tự hóa Python [str] sang nội dung tuần tự hóa C++ [std. string] được xây dựng trong thư viện Boost Python
roscd python_bindings_tutorial/src mkdir python_bindings_tutorial roscd python_bindings_tutorial/src/python_bindings_tutorial touch _add_two_ints_wrapper_py.py rosed python_bindings_tutorial _add_two_ints_wrapper_py.py
Nội dung của src/python_bindings_tutorial/_add_two_ints_wrapper_py. py sẽ là
1 from StringIO import StringIO 2 3 import rospy 4 from std_msgs.msg import Int64 5 6 from python_bindings_tutorial._add_two_ints_wrapper_cpp import AddTwoIntsWrapper 7 8 9 class AddTwoInts[object]: 10 def __init__[self]: 11 self._add_two_ints = AddTwoIntsWrapper[] 12 13 def _to_cpp[self, msg]: 14 """Return a serialized string from a ROS message 15 16 Parameters 17 ---------- 18 - msg: a ROS message instance. 19 """ 20 buf = StringIO[] 21 msg.serialize[buf] 22 return buf.getvalue[] 23 24 def _from_cpp[self, str_msg, cls]: 25 """Return a ROS message from a serialized string 26 27 Parameters 28 ---------- 29 - str_msg: str, serialized message 30 - cls: ROS message class, e.g. sensor_msgs.msg.LaserScan. 31 """ 32 msg = cls[] 33 return msg.deserialize[str_msg] 34 35 def add[self, a, b]: 36 """Add two std_mgs/Int64 messages 37 38 Return a std_msgs/Int64 instance. 39 40 Parameters 41 ---------- 42 - a: a std_msgs/Int64 instance. 43 - b: a std_msgs/Int64 instance. 44 """ 45 if not isinstance[a, Int64]: 46 rospy.ROSException['Argument 1 is not a std_msgs/Int64'] 47 if not isinstance[b, Int64]: 48 rospy.ROSException['Argument 2 is not a std_msgs/Int64'] 49 str_a = self._to_cpp[a] 50 str_b = self._to_cpp[b] 51 str_sum = self._add_two_ints.add[str_a, str_b] 52 return self._from_cpp[str_sum, Int64]
Để có thể nhập lớp dưới dạng python_bindings_tutorial. AddTwoInts, chúng tôi nhập các ký hiệu trong __init__. py. Đầu tiên, chúng tôi tạo tập tin
1 roscd python_bindings_tutorial/src/python_bindings_tutorial 2 touch __init__.py 3 rosed python_bindings_tutorial __init__.py
Nội dung của src/python_bindings_tutorial/__init__. py sẽ là
1 from python_bindings_tutorial._add_two_ints_wrapper_py import AddTwoInts
Dán mọi thứ lại với nhau
Chỉnh sửa CMakeLists. txt [rosed python_bindings_tutorial CmakeLists. txt] như thế này
Adapt CMakeLists.txt from the catkin version of this page.
________số 8
Nội dung thiết lập. py sẽ là
Sau đó, chúng tôi xây dựng gói với rosmake
Kiểm tra ràng buộc
Bây giờ bạn có thể sử dụng liên kết trong tập lệnh Python hoặc trong trình bao Python
1 from std_msgs.msg import Int64 2 from python_bindings_tutorial import AddTwoInts 3 a = Int64[4] 4 b = Int64[2] 5 addtwoints = AddTwoInts[] 6 sum = addtwoints.add[a, b] 7 sum
Lớp với NodeHandle
Như đã nêu, lệnh gọi Python tới rospy. init_node không khởi tạo roscpp. Nếu roscpp không được khởi tạo, khởi tạo ros. NodeHandle sẽ dẫn đến lỗi nghiêm trọng. Một giải pháp cho vấn đề này được cung cấp bởi giao diện moveit_ros_planning_. Trong bất kỳ tập lệnh Python nào sử dụng lớp được bao bọc, cần thêm hai dòng trước khi kích hoạt AddTwoInts
1 #include 2 3 using namespace python_bindings_tutorial; 4 5 std_msgs::Int64 AddTwoInts::add[const std_msgs::Int64& a, const std_msgs::Int64& b] 6 { 7 std_msgs::Int64 sum; 8 sum.data = a.data + b.data; 9 return sum; 10 }0
Điều này sẽ tạo ra một nút ROS. Do đó, ưu điểm của phương pháp này so với việc triển khai máy chủ/máy khách dịch vụ ROS cổ điển không rõ ràng như trong trường hợp không cần ros. Xử lý nút
Lớp có chứa thông báo ROS
Nếu lớp sử dụng vùng chứa thông báo ROS, thì phải thêm một bước chuyển đổi bổ sung. Bước này không dành riêng cho ROS mà là một phần của thư viện Boost Python