创建文件
mkdir -p ros_basic/src
cd ros_basic/
catkin init
catkin build
创建包
cd
cd ros_basic
cd src
conda deactivate
catkin create pkg ros_define_data --catkin-deps std_msgs roscpp rospy
返回上级目录
cd ..
创建文件夹及文件
通信代码
话题通信
grasp.msg
uint16 x
uint16 y
float64 z
float64 angle
float64 width
服务通信
grasp_.srv
# request
uint16 x
uint16 y # 键盘输入坐标点
---
# response
uint16 distance # 几何距离
修改CMakeLists.txt
find_package(catkin REQUIRED COMPONENTS
roscpp
rospy
std_msgs
# 自定义消息时添加
geometry_msgs
message_generation
)
add_message_files(
FILES
grasp.msg
# Message2.msg
)
add_service_files(
FILES
grasp_.srv
# Service2.srv
)
generate_messages(
DEPENDENCIES
std_msgs
)
catkin_package(
# INCLUDE_DIRS include
# LIBRARIES ros_define_data
CATKIN_DEPENDS roscpp rospy std_msgs geometry_msgs message_runtime
# DEPENDS system_lib
)
package.xml修改
<!-- self define some message data -->
<build_export_depend>message_generation</build_export_depend>
<exec_depend>message_runtime</exec_depend>
<build_depend>geometry_msgs</build_depend>
<exec_depend>geometry_msgs</exec_depend>
编译
catkin build ros_define_data
AttributeError: module 'em' has no attribute 'RAW_OPT'
empy版本不匹配,empy版本为4.1,但是4.0版本以上都会出现这个错误
卸载
pip uninstall empy
指定版本按装
pip install empy==3.3.4
成功编译
catkin build ros_define_data
返回上级目录
cd ..
设置变量 展示msg srv设置
source devel/setup.bash
rosmsg show grasp
rossrv show grasp_
编译得到的文件路径
复制到功能包文件夹下
src文件夹下
client.cpp
#include "ros/ros.h"
#include <cstdlib>
#include <ros_define_data/grasp_.h>
int main(int argc, char *argv[])
{
// 初始化ros节点
ros::init(argc,argv,"grasp_client");
// 从命令行获取两个数
if(argc!=3)
{
ROS_INFO("usage:grasp_client X Y");
return 1;
}
// 创建节点句柄
ros::NodeHandle n;
// 创建一个client
// 消息类型为ros_define_data::grasp_
ros::ServiceClient client=n.serviceClient<ros_define_data::grasp_>("computing_distance");
// 创建ros_define_data::grasp_类型的server消息
ros_define_data::grasp_ srv;
srv.request.x = atoll(argv[1]);
srv.request.y = atoll(argv[2]);
// 发布service消息,等待计算结果反馈回来,call表示发布服务请求了
if(client.call(srv)){
ROS_INFO("Distance:%ld",(long int)srv.response.distance);
}else{
ROS_ERROR("Failed to call service computing_distance");
return 1;
}
return 0;
}
server.cpp文件
#include "ros/ros.h"
// 当前include文件夹中为本地地址devel下的include
#include <ros_define_data/grasp_.h>
// server设置回调函数,输入req,输出res
bool addCallback(ros_define_data::grasp_::Request &req,
ros_define_data::grasp_::Response &res){
// 将输入参数中的请求数据相加,结果放到应答恢复中
res.distance = req.x * req.x + req.y * req.y;
ROS_INFO("request: x = %ld,y = %ld",(long int)req.x,(long int)req.y);
ROS_INFO("response: distance = %ld",(long int)res.distance);
return true;
}
int main(int argc, char *argv[])
{
// ros节点初始化
ros::init(argc,argv,"computing_distance_server");
// 创建节点句柄
ros::NodeHandle n;
// 创建名为computing_distance的server,注册回调函数
ros::ServiceServer service = n.advertiseService("computing_distance",addCallback);
// 循环等待回调函数
ROS_INFO("ready to computing distance");
ros::spin();
return 0;
}
进入src文件夹
cd src
修改CMakeLists.txt文件
不需要产生新文件,得注释并关了113行
#CATKIN_DEPENDS roscpp rospy std_msgs geometry_msgs message_runtime
需要包含当前功能包文件,得取消124行注释 并打开
不需要产生新的msg srv文件直接关了 76-79行 61-66行
#generate_messages(
# DEPENDENCIES
# std_msgs
#)
#add_service_files(
# FILES
# grasp_.srv
# Service1.srv
# Service2.srv
#)
添加可执行文件依赖库
add_executable(server src/server.cpp)
target_link_libraries(server ${catkin_LIBRARIES})
add_dependencies(server ${PROJECT_NAME}_gencpp)
add_executable(client src/client.cpp)
target_link_libraries(client ${catkin_LIBRARIES})
add_dependencies(client ${PROJECT_NAME}_gencpp)
编译
cd src
catkin build ros_define_data
The dependency target "ros_define_data_gencpp" of target "client" does not exist.
The dependency target "ros_define_data_gencpp" of target "server" does not exist.
解决办法修改版本为2.8.3
成功编译
catkin build ros_define_data
运行第一个窗口roscore
cd
cd ros_basic
conda deactivate
roscore
运行第二个窗口
cd
cd ros_basic
source devel/setup.bash
rosrun ros_define_data
rosrun ros_define_data server
运行第三个窗口
cd
rosrun ros_define_data client 3 9
msg话题通信
src文夹下
publisher.cpp
#include "ros/ros.h"
#include <ros_define_data/grasp.h>
int main(int argc, char *argv[])
{
//ros节点初始化
ros::init(argc,argv,"grasp_publisher");
//创建节点句柄
ros::NodeHandle n;
//创建一个publisher,发布一个话题,队列长度10
ros::Publisher grasp_info_pub = n.advertise<ros_define_data::grasp>("/grasp_info",10);
//设置循环频率1
ros::Rate loop_rate(1);
int count = 0;
while(ros::ok())
{
// 初始化ros_define_data::grasp类型的消息
ros_define_data::grasp grasp_msg;
grasp_msg.x = 100;
grasp_msg.y = 181;
grasp_msg.z = 0.324;
grasp_msg.angle = 1.252;
grasp_msg.width = 3.05;
// 发布消息
grasp_info_pub.publish(grasp_msg);
ROS_INFO("Subcribe grasp Info: pos:(%d,%d),depth:%f,angle:%f,width:%f",
grasp_msg.x,grasp_msg.y,grasp_msg.z,grasp_msg.angle,grasp_msg.width);
// 按照循环频率延时
loop_rate.sleep();
}
return 0;
}
subscriber.cpp
#include "ros/ros.h"
#include <ros_define_data/grasp.h>
// 接受到订阅的消息后,会进入消息回调函数
void GraspInfoCallback(const ros_define_data::grasp::ConstPtr& msg){
//将接受到的消息打印出来
ROS_INFO("Subcribe grasp Info: pos:(%d,%d),depth:%f,angle:%f,width:%f",
msg->x,msg->y,msg->z,msg->angle,msg->width);
}
int main(int argc, char *argv[])
{
// 初始化ros节点
ros::init(argc,argv,"grasp_subscriber");
// 创建节点句柄
ros::NodeHandle n;
ros::Subscriber grasp_info_sub = n.subscribe("/grasp_info",10,GraspInfoCallback);
// 循环等待回调函数
ros::spin();
return 0;
}
CMakeLists.txt配置
add_executable(publisher src/publisher.cpp)
add_dependencies(publisher ${PROJECT_NAME}_gencpp)
target_link_libraries(publisher ${catkin_LIBRARIES})
add_executable(subscriber src/subscriber.cpp)
add_dependencies(subscriber ${PROJECT_NAME}_gencpp)
target_link_libraries(subscriber ${catkin_LIBRARIES})
进行编译
cd ..
cd ros_basic
cd src
catkin build ros_define_data
运行第一个窗口
cd
roscore
运行第二个窗口
cd
cd ros_basic/
source devel/setup.bash
rosrun ros_define_data publisher
运行第三个窗口
cd
rosrun ros_define_data subscriber