ROS2自学笔记:通信接口

发布时间:2022-08-19 13:07

通信接口是任何通信(话题,服务,动作)的一个规范类型。通信时收发的数据要满足接口要求

通信接口定义方式:
1 话题为单向传输,因此只要说明要发送的数据,如:

int32 x
int32 y

话题接口类型为.msg文件
2 服务为双向传输,要说明请求和应答数据,中间用—隔开:

int64 a
int64 b
---
int64 sum

服务接口类型为.srv文件
3 动作要求三部分:目标,结果,反馈:

// 目标
bool a
---
// 结果
bool finish
---
// 反馈
int32 state

ROS2官方自带通信接口:
打开位置:computer->other location->opt->ros->foxy->share
话题接口(msg):
ROS2自学笔记:通信接口_第1张图片
更简单的办法是使用终端指令

ros2 interface list

显示所有接口
ROS2自学笔记:通信接口_第2张图片

查询接口定义

ros2 interface show (接口名称)

ROS2自学笔记:通信接口_第3张图片

查找某一个功能包里的接口

ros2 interface package (功能包名称)

ROS2自学笔记:通信接口_第4张图片

在之前学习服务的文章里有一个图像识别并获取位置信息的程序(可见https://blog.csdn.net/Raine_Yang/article/details/125359357?spm=1001.2014.3001.5501)这一程序中实现的通信接口如下:

bool get
---
int32 x
int32 y

这一接口中请求参数为bool get,应答参数为int32 x, int32 y

对于自己创建的接口,要在CMakeLists.txt中进行声明,这样编译器会自动将接口文件编译为所需的编程语言

rosidl_generate_interfaces(${PROJECT_NAME}
	"srv/GetObjectPosition.srv"
)

对于创建并声明的接口,在其他程序里只需要import就可以直接使用

from learning_interface.srv import GetObjectPosition

编译器会把接口文件编译为python文件,位置
dev_ws -> install -> learning_interface -> lib -> python3.8 ->site_packages -> learning_interface -> srv

自动生成的python文件
ROS2自学笔记:通信接口_第5张图片
C++文件位置:
dev_ws -> install -> learning_interface -> include -> learning_interface -> srv

自定义接口实现话题通信图像识别:
这一次我们修改之前图像识别的示例程序(原程序:https://blog.csdn.net/Raine_Yang/article/details/125349724?spm=1001.2014.3001.5501)

通信接口:

int32 x
int32 y

发布者:

import rclpy
from rclpy.node import Node
from sensor_msgs.msg import Image
from learning_interface.msg import ObjectPosition
from cv_bridge import CvBridge
import cv2
import numpy as np

lower_red = np.array([0, 90, 128])
upper_red = np.array([180, 255, 255])

class ImageSubscriber(Node):
	def __init__(self, name):
		super().__init__(name)
		self.sub = self.create_subscription(Image, 'image_raw', self.listener_callback, 10)
		self.cv_bridge = CvBridge()
		self.pub = self.create_publisher(ObjectPosition, 'object_position', 10)

	def object_detect(self, image):
		hsv_img = cv2.cvtColor(image, cv2.COLOR_BGR2HSV)
		mask_red = cv2.inRange(hsv_img, lower_red, upper_red)
		contours, hierarchy = cv2.findContours(mask_red, cv2.RETR_LIST, cv2.CHAIN_APPROX_NONE)

		for cnt in contours:
			 if cnt.shape[0] < 150:
			 	continue

			 (x, y, w, h) = cv2.boundingRect(cnt)
			 cv2.drawContours(image, [cnt], -1, (0, 255, 0), 2)
			 cv2.circle(image, (int(x + w / 2), int(y + h / 2), 5, (0, 255, 0), -1)
			 self.objectX = (x + w / 2)
			 self.objectY = (y + h / 2)
			 cv2.imshow("object", image)
			 cv2.waitKey(10)

	
	def listener_callback(self, data):
		self.get_logger().info('Receiving video frame')
		image = self.cv_bridge.imgmsg_to_cv2(data, 'bgr8')
		self.object_detect(image)
		position = ObjectPosition()
		position.x = int(objectX)
		position.y = int(objectY)
		self.pub.publish(position)

def main(args=None):
	rclpy.init(args=args)
	rclpy.ImageSubscriber("interface_position_pub")
	rclpy.spin(node)
	node.destroy_node()
	rclpy.shutdown()

1 from learning_interface.msg import ObjectPosition
引入接口

2 self.pub = self.create_publisher(ObjectPosition, ‘object_position’, 10)
创建发布者对象,发布消息类型为ObjectPosition

3 position = ObjectPosition()
position.x = int(objectX)
position.y = int(objectY)
self.pub.publish(position)
position实例化一个ObjectPosition接口,该接口参数为两个int值x和y,在这里进行赋值并发布

订阅者:

import rclpy
from rclpy.node import Node
from std_msgs.msg import String
from learning_interface.msg import ObjectPosition

class SubscriberNode(Node):
	def __init__(self, name):
		super().__init__(name)
		self.sub = self.create_subscription(ObjectPosition, "object_position", self.listener_callback, 10)

	def listener_callback(self, msg):
		self.get_logger().info('Target Position: "(%d, %d)"' % (msg.x, msg.y))


def main(args=None):
	rclpy.init(args=args)
	node = SubscriberNode("interface_position_sub")
	rclpy.spin(node)
	node.destroy_node()
	rclpy.shutdown()
	

1 from learning_interface.msg import ObjectPosition
引入ObjectPosition接口

2 self.sub = self.create_subscription(ObjectPosition, “object_position”, self.listener_callback, 10)
创建订阅者对象,接受消息类型为ObjectPosition

ItVuer - 免责声明 - 关于我们 - 联系我们

本网站信息来源于互联网,如有侵权请联系:561261067@qq.com

桂ICP备16001015号