一.创建工作空间
初始化工作空间(src)
catkin_init_workspace
编译工作空间(工作空间)
catkin_make
catkin_make install
创建功能包(src)
catkin_create_pkg <包名> roscpp rospy std_msgs
二.Publisher实现
来源于古月居21讲
C++例程
//该例程将发布turtle1/cmd_vel话题,消息类型geometry_msgs::Twist
#include <ros/ros.h>
#include <geometry_msgs/Twist.h>
int main(int argc,char **argv)
{
//ROS节点初始化
ros::init(argc, argv,"velocity_publisher");
//创建节点句柄
ros::NodeHandle n;
//创建一个publisher,发布名为/turtle1/cmd_vel的topic,消息类型为geometry_msgs::Twist,队列长度10
ros::Publisher turtle_vel_pub = n.advertise<geometry_msgs::Twist>("/turtle1/cmd_vel", 10);
//设置循环的频率
ros::Rate loop_rate(10);
int count=0;
while(ros::ok())
{
//初始化geometry_msgs::Twist类型的消息
geometry_msgs::Twist vel_msg;
vel_msg.linear.x = 0.5;
vel_msg.angular.z = 0.2;
//发布消息
turtle_vel_pub.publish(vel_msg);
ROS_INFO("Publsh turtle velocity command[%o.2f m/s, %0.2f rad/s]",
vel_msg.linear.x, vel_msg.angular.z);
//按照循环频率延时
loop_rate.sleep();
}
return 0;
}
在CMakelists.txt中找到Build添加
###########
## Build ##
###########
//此命令的作用是告知 CMake 要生成一个可执行文件。
//xxx_publisher:这是生成的可执行文件的名称。
//src/<文件名>.cpp:表示源文件的路径,这里需要你把<文件名>替换成实际的 C++ 源文件名
add_executable(xxx_publisher scr/<文件名>.cpp)
//该命令的目的是将可执行文件与必要的库文件进行链接。
//xxx_publisher:代表前面生成的可执行文件。
//{catkin_LIBRARIES}:这是一个 CMake 变量,它包含了 catkin 工具链自动发现的 ROS 依赖库
target_link_libraries(xxx_publisher ${catkin_LIBRARIES})
Python例程
#!/usr/bin/env python
#-*-coding:utf-8 -*-
#该例程将发布turtLle1/cmd_vel话题,消息类型geometry_msgs::Twist
import rospy
from geometry_msgs.msg import Twist
def velocity_publisher():
#ROS节点初始化
rospy.init_node('velocity_publisher', anonymous=True)
#创建一个publisher,发布名为/turtle1/cmd_vel的topic,消息类型为geometry_msgs::Twist,队列长度10
turtle_vel_pub = rospy.Publisher('/turtle1/cmd_vel',Twist, queue_size=10)
#设置循环的频率
rate = rospy.Rate(10)
while not rospy.is_shutdown():
#初始化geometry_msgs::Twist类型的消息
vel_msg = Twist()
vel_msg.linear.x = 0.5
vel_msg.angular.z = 0.2
#发布消息
turtle_vel_pub.publish(vel_msg)
rospy.loginfo("Publsh turtle velocity command[%0.2f m/s, %0.2f rad/s]",
vel_msg.linear.x, vel_msg.angular.z)
#按照循环频率延时
rate.sleep()
if __name__ == '__main__':
try:
velocity_publisher()
except rospy.ROSInterruptException:
pass
在CMakelists.txt中找到Install添加
#############
## Install ##
#############
catkin_install_python(PROGRAMS
scripts/<文件名>.py
DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION}
)
这样一来,就可以使用以下命令直接运行脚本:
rosrun <包名> <文件名>.py
Python文件需要右键->属性->权限->勾选允许文件作为程序执行

三.Subscriber实现
C++实现
//该例程将订阅/turtle1/pose话题,消息类型turtlesim::Pose
#include <ros/ros.h>
#include "turtlesim/Pose.h"
//接收到订阅的消息后,会进入消息回调函数
void poseCallback(const turtlesim::Pose::ConstPtr& msg)
{
//将接收到的消息打印出来
ROS_INFO("Turtle pose: x:%0.6f,y:%0.6f", msg->x,msg->y);
}
int main(int argc,char **argv)
{
//初始化ROS节点
ros::init(argc, argv,"pose_subscriber");
//创建节点句柄
ros::NodeHandle n;
//创建一个subscriber,订阅名为/turtle1/pose的topic,注册回调函数poseCallback
ros::Subscriber pose_sub = n.subscribe("/turtle1/pose", 10, poseCallback);
//循环等待回调函数
ros::spin();
return 0;
}
在CMakelists.txt中找到Build添加
add_executable(pose_subscriber src/sub.cpp)
target_link_libraries(pose_subscriber ${catkin_LIBRARIES})
Python实现
#!/usr/bin/env python
#*-coding:utf-8-*-
#该例程将订阅/turtle1/pose话题,消息类型turtlesim::Pose
import rospy
from turtlesim.msg import Pose
def poseCallback(msg):
rospy.loginfo("Turtle pose: x:%0.6f,y:%0.6f",msg.x,msg.y)
def pose_subscriber():
#ROS节点初始化
rospy.init_node('pose_subscriber', anonymous=True)
#创建一个subscriber,订阅名为/turtle1/pose的topic,注册回调函数poseCallback
rospy.Subscriber("/turtle1/pose", Pose, poseCallback)
#循环等待回调函数
rospy.spin()
if __name__ == '__main__':
pose_subscriber()
在CMakelists.txt中找到Install添加
catkin_install_python(PROGRAMS
scripts/pub.py
scripts/sub.py
DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION}
)
勾选允许文件作为程序执行
四.话题消息定义与使用
在功能包下新建文件夹msg
msg文件夹下新建Xxx.msg文件
添加参数(以Person为例)
string name
int8 sex
uint8 age
int8 unknown = 0
int8 male = 1
int8 female = 2
在package.xml中添加
<build_depend>message_generation</build_depend>
<exec_depend>message_runtime</exec_depend>
这两行代码是 ROS软件包配置文件package.xml中的依赖声明,用于支持自定义消息类型的生成和运行。
<build_depend>message_generation</build_depend>声明在编译阶段需要依赖message_generation包。
<exec_depend>message_runtime</exec_depend>声明在运行阶段需要依赖message_runtime包。
在CMakelists.txt中找到find_package添加message_generation
## Find catkin macros and libraries
## if COMPONENTS list like find_package(catkin REQUIRED COMPONENTS xyz)
## is used, also find other catkin packages
find_package(catkin REQUIRED COMPONENTS
geometry_msgs
roscpp
rospy
std_msgs
turtlesim
message_generation
)
在CMakelists.txt中找到Declare ROS messages, services and actions添加
add_message_files(
FILES
Person.msg
)
generate_messages(
DEPENDENCIES
std_msgs
)
这两行代码的作用是告诉 CMake:
- 我的包中定义了一个名为
Person.msg的自定义消息文件。 - 生成这个消息的源代码时,需要依赖
std_msgs包(比如可能会使用到std_msgs/String类型)。
在CMakelists.txt中找到catkin specific configuration添加
catkin_package(
# INCLUDE_DIRS include
# LIBRARIES learing
CATKIN_DEPENDS geometry_msgs roscpp rospy std_msgs turtlesim message_runtime
# DEPENDS system_lib
)
此命令的作用是告诉 catkin 构建系统:
- 我的包生成了哪些库、头文件和可执行文件。
- 我的包依赖于哪些其他 ROS 包。
- 其他包在依赖我时需要哪些信息。
C++实现
//该例程将请求/spawn服务,服务数据类型turtlesim::Spawn
#include <ros/ros.h>
#include <turtlesim/Spawn.h>
int main(int argc,char** argv)
{
//初始化ROS节点
ros::init(argc, argv,"turtle_spawn");
//创建节点句柄
ros::NodeHandle node;
//发现/spawn服务后,创建一个服务客户端,连接名为/spawn的service
ros::service::waitForService("/spawn");
ros::ServiceClient add_turtle=node.serviceClient<turtlesim::Spawn>("/spawn");
//初始化turtlesim::Spawn的请求数据
turtlesim::Spawn srv;
srv.request.x=2.0;
srv.request.y = 2.0;
srv.request.name = "turtle2";
//请求服务调用
ROS_INFO("call service to spwan turtle[x:%0.6f,y:%0.6f,name:%s]",
srv.request.x, srv.request.y,srv.request.name.c_str());
add_turtle.call(srv);
//显示服务调用结果
ROS_INFO("Spwan turtle successfully [name:%s]",srv.response.name.c_str());
return 0;
}
Python实现
#!/usr/bin/env python
# -*- coding: utf-8 -*-
#该例程将请求/spawn服务,服务数据类型turtlesim::Spawn
import sys
import rospy
from turtlesim.srv import Spawn
def turtle_spawn():
#ROS节点初始化
rospy.init_node('turtle_spawn')
#发现/spawn服务后,创建一个服务客户端,连接名为/spawn的service
rospy.wait_for_service('/spawn')
try:
add_turtle = rospy.ServiceProxy('/spawn',Spawn)
#请求服务调用,输入请求数据
response = add_turtle(2.0,2.0,0.0,"turtle2")
return response.name
except rospy.ServiceException as e:
print("Service call failed:%s"%e)
if __name__ == "__main__":
#服务调用并显示调用结果
print("Spwan turtle successfully [name:%s]"%(turtle_spawn()))

3万+

被折叠的 条评论
为什么被折叠?



