教程链接
配上官方文档食用
。。。
我们要确保msg文件能被转换为C++、Python和其他语言的源代码。 添加了2行依赖,在构建时,其实只需要message_generation,而在运行时,我们只需要message_runtime。
教程:
在CMakeLists.txt文件中,为已经存在里面的find_package调用添加message_generation依赖项,这样就能生成消息了。直接将message_generation添加到COMPONENTS列表中即可,如下所示:
#不要直接复制这一大段,只需将message_generation加在括号闭合前即可
find_package(catkin REQUIRED COMPONENTS
roscpp
rospy
std_msgs
message_generation
)
你可能注意到了,有时即使没有使用全部依赖项调用find_package,项目也可以构建。这是因为catkin把你所有的项目整合在了一起,因此如果之前的项目调用了find_package,你的依赖关系也被配置成了一样的值。但是,忘记调用意味着你的项目在单独构建时很容易崩溃。
还要确保导出消息的运行时依赖关系:
简单理解:
find_package 编译时依赖
catkin_package 运行时依赖
Ctrl + Shift + B 编译一下
Python 3 renamed the unicode type to str, the old str type has been replaced by bytes.
vscode 配置
为了方便代码提示以及避免误抛异常,需要先配置 vscode,将前面生成的 head 文件路径配置进 c_cpp_properties.json 的 includepath属性:
{
"configurations": [
{
"browse": {
"databaseFilename": "",
"limitSymbolsToIncludedHeaders": true
},
"includePath": [
"/opt/ros/noetic/include/**",
"/usr/include/**",
"/xxx/yyy工作空间/devel/include/**" //配置 head 文件的路径
],
"name": "ROS",
"intelliSenseMode": "gcc-x64",
"compilerPath": "/usr/bin/gcc",
"cStandard": "c11",
"cppStandard": "c++17"
}
],
"version": 4
}
创建一个发布方的Cpp文件
跟着教程编写如下:
#include "ros/ros.h"
#include "plumbing_pub_sub/Person.h"
int main(int argc, char *argv[])
{
setlocale(LC_ALL,"");
//初始化Ros节点
ros::init(argc,argv,"PangHu");
//创建句柄
ros::NodeHandle nh;
//创建发布者对象:
ros::Publisher pub = nh.advertise<plumbing_pub_sub::Person>("chat",10);
//编写发布逻辑,发布数据
plumbing_pub_sub::Person person;
//创建被发布的数据
person.name = "法外狂徒张三";
person.age = 1;
person.height = 1.78;
//设置发布频率
ros::Rate rate(1);
//循环发布数据
while(ros::ok())
{
//修改数据
person.age += 1;
//核心:数据发布
pub.publish(person);
rate.sleep();//让发布频率生效
ros::spinOnce();
}
return 0;
}
然后就配置一下 CMakeList.txt ,
与原来相比,使用自定义msg,还要配置一步。
修改后
突然编译出错了,。。。上午硬是找不到解决问题的办法,下午来对了一遍教程,CMakeList.txt里的
generate_messages()这一部分突然不见了,就挺离谱的,加上之后编译成功。
继续。
测试一下:
利用rostopic echo 打印消息
直接用会出错
因为无法识别我们的自定义消息类型
需要进入工作空间目录下,再刷新一下环境变量就可以了。
添加一些日志输出
ROS_INFO(“张三的一生:”);
ROS_INFO(“发布的消息:名字:%s, 年龄:%d,身高: %.2f”, person.name.c_str(), person.age, person.height);
步骤基本重复之前操作了。
很快啊
啪的一下敲完了。
#include "ros/ros.h"
#include "plumbing_pub_sub/Person.h"
void doPerson(const plumbing_pub_sub::Person::ConstPtr & person)
{
ROS_INFO("订阅到的信息:名字:%s, 年龄: %d, 身高 %.2f",person->name.c_str(), person->age, person->height);
}
int main(int argc, char *argv[])
{
setlocale(LC_ALL,"");
ROS_INFO("订阅方实现:");
//初始化Ros节点
ros::init(argc,argv,"XiaoGuang");
//创建句柄
ros::NodeHandle nh;
//创建订阅者对象:
ros::Subscriber sub= nh.subscribe("chat", 10,doPerson);
//调用spin函数
ros::spin();
return 0;
}
然后配置CMakeList.txt懂得都懂了。
Srv,有请求部分,还要有响应部分。
1.创建相关文件,编写srv文件。
请求和响应之间用 — 分割
2.配置.
新的功能包,和之前类似,修改package.xml。
修改CMakeList
编译。
#include "ros/ros.h"
#include "plumbing_server_client/AddInts.h"
bool doNums(plumbing_server_client::AddInts::Request &request,
plumbing_server_client::AddInts::Response &response)
{
//1.处理请求
int num1 = request.num1;
int num2 = request.num2;
ROS_INFO("受到的请求数据:num1 = %d, num2 = %d",num1, num2);
//2.组织响应
int sum = num1+num2;
response.sum = sum;
ROS_INFO("求和结果Sum = %d",sum);
return true;
}
int main(int argc, char* argv[])
{
setlocale(LC_ALL,"");
//初始化ros节点
ros::init(argc,argv,"Water");
//句柄
ros::NodeHandle nh;
//创建server, 服务对象
ros::ServiceServer server = nh.advertiseService("addInts", doNums);
ROS_INFO("服务端启动成功");
ros::spin();
return 0;
}
roscore
source ./devel/setup.bash
rosrun plumbing_server_client demo01_server
#include "ros/ros.h"
#include "plumbing_server_client/AddInts.h"
int main(int argc, char* argv[])
{
setlocale(LC_ALL,"");
//初始化ros节点
ros::init(argc,argv,"KeHu");
//句柄
ros::NodeHandle nh;
//创建server, 服务对象
ros::ServiceClient client = nh.serviceClient<plumbing_server_client::AddInts>("addInts");
//提交请求并处理响应
plumbing_server_client::AddInts ai;
//组织请求
ai.request.num1 = 100;
ai.request.num2 = 200;
//处理响应
bool flag = client.call(ai);
if (flag)
{
ROS_INFO("响应成功 !");
ROS_INFO("响应结果: %d",ai.response.sum);
}
else
ROS_INFO("处理失败!");
return 0;
}
再在在打开CMakeList.txt
修改一下。
编译。。。。。
今天的教程来源也都是
奥特学园
话题,服务通信的基本模板操作到这里也都实现过一遍了,对这些流程算是有了基本的把握。这些操作之间有许多相重合的过程,也对这些基本操作进一步加深了印象。基础部分走的也差不多了,下一步要结合其他教程往更大的方向走,继续学习了解更多的知识。