Giải trăn

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 Python

từ 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

Chủ Đề