继续我们的ros初学之旅。
发布节点:
send_msg.cpp
#include "ros/ros.h"
#include "std_msgs/String.h"
#include
int main(int argc, char **argv)
{
ros::init(argc, argv, "send_msg.cpp");
ros::NodeHandle n;
ros::Publisher pub = n.advertise<std_msgs::String>("message", 1000);
ros::Rate loop_rate(10);
while (ros::ok())
{
std_msgs::String msg;
std::stringstream ss;
ss << " I am the send node ";
msg.data = ss.str();
pub.publish(msg);
ros::spinOnce();
loop_rate.sleep();
}
return 0;
}
接受节点:
//receive_msg.cpp
#include "ros/ros.h"
#include "std_msgs/String.h"
void messageCallback(const std_msgs::String::ConstPtr& msg)
{
ROS_INFO("I heard: [%s]", msg->data.c_str());
}
int main(int argc, char **argv)
{
ros::init(argc, argv, "receive_msg");
ros::NodeHandle n;
ros::Subscriber sub = n.subscribe("message", 1000, messageCallback);
ros::spin();
return 0;
}
两个节点同时运行可以得到结果。
在功能包下,新建msg文件夹,创建名为chapter2_msg1.msg的文件,在其中写入一下内容:
int32 A
int32 B
int32 C
在package.xml中修改;
<build_depend>message_generation</build_depend>
<build_export_depend>message_generation</build_export_depend>
<exec_depend>message_runtime</exec_depend>
取消这三行的注释
CMakeLists.txt中找到指定位置并修改为一下内容:
find_package(catkin REQUIRED COMPONENTS
roscpp
std_msgs
message_generation
)
add_message_files(
FILES
chapter2_msg1.msg
)
generate_messages(
DEPENDENCIES
std_msgs
)
编译,然后创建使用这种消息类型的节点
//example3_a
#include "ros/ros.h"
#include "chapter2/chapter2_msg1.h"
#include
int main(int argc, char **argv)
{
ros::init(argc, argv, "example3_a");
ros::NodeHandle n;
ros::Publisher pub = n.advertise<chapter2::chapter2_msg1>("message", 1000);
ros::Rate loop_rate(10);
while (ros::ok())
{
chapter2::chapter2_msg1 msg;
msg.A = 1;
msg.B = 2;
msg.C = 3;
pub.publish(msg);
ros::spinOnce();
loop_rate.sleep();
}
return 0;
}
example3_b
#include "ros/ros.h"
#include "chapter2/chapter2_msg1.h"
void messageCallback(const chapter2::chapter2_msg1::ConstPtr& msg)
{
ROS_INFO("I heard: [%d] [%d] [%d]", msg->A, msg->B, msg->C);
}
int main(int argc, char **argv)
{
ros::init(argc, argv, "example3_b");
ros::NodeHandle n;
ros::Subscriber sub = n.subscribe("message", 1000, messageCallback);
ros::spin();
return 0;
}
## 新建服务数据类型
在功能包下新建srv文件夹,在其下新建chapter2_srv1.srv文件,写入一下内容:
int32 A
int32 B
int32 C
---
int32 sum
在CMakeLists.txt种修改:
catkin_package(
CATKIN_DEPENDS message_runtime
)
add_service_files(
FILES
chapter2_srv1.srv
)
编译一下
//example2_a.cpp
#include "ros/ros.h"
#include "chapter2/chapter2_srv1.h"
bool add(chapter2::chapter2_srv1::Request &req,
chapter2::chapter2_srv1::Response &res)
{
res.sum = req.A + req.B + req.C;
ROS_INFO("request: A=%d, B=%d C=%d", (int)req.A, (int)req.B, (int)req.C);
ROS_INFO("sending back response: [%d]", (int)res.sum);
return true;
}
int main(int argc, char **argv)
{
ros::init(argc, argv, "add_3_ints_server");
ros::NodeHandle n;
ros::ServiceServer service = n.advertiseService("add_3_ints", add);
ROS_INFO("Ready to add 3 ints.");
ros::spin();
return 0;
}
//example2_b.cpp
#include "ros/ros.h"
#include "chapter2/chapter2_srv1.h"
#include
int main(int argc, char **argv)
{
ros::init(argc, argv, "add_3_ints_client");
if (argc != 4)
{
ROS_INFO("usage: add_3_ints_client A B C ");
return 1;
}
ros::NodeHandle n;
ros::ServiceClient client = n.serviceClient<chapter2::chapter2_srv1>("add_3_ints");
chapter2::chapter2_srv1 srv;
srv.request.A = atoll(argv[1]);
srv.request.B = atoll(argv[2]);
srv.request.C = atoll(argv[3]);
if (client.call(srv))
{
ROS_INFO("Sum: %ld", (long int)srv.response.sum);
}
else
{
ROS_ERROR("Failed to call service add_two_ints");
return 1;
}
return 0;
}
catkin_create_pkg package_name std_msgs roscpp
依赖标准消息和从C++库
catkin_make 编译当前工作区下的所有功能包
catkin_make --pkg package_name 编译制定功能包
rosnode list 列出当前工作的节点
rosnode info node_name 列出节点的具体信息
rostopic list 列出当前的主题名称
rostopic type theme_name 列出主题名对应的具体的消息类型
rosmsg show msg_name 列出消息所具体包括的基本数据类型
rosservice list 列出当前可用服务
rosservice node service_name 列出提供制定服务的节点
rosservice info service_name 查询服务的数据类型data_name
rossrv show data_name 列出服务数据类型的具体内容