栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

Ros 通信方式教程 hello word 基本编程

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Ros 通信方式教程 hello word 基本编程

1.Ros通信编程之话题编程

Talker:发布者 C++创建

Listener:订阅者 C++创建

Ros master:管理节点的仓库 --- 添加编译预选 ------ 运行可执行程序

2.实现一个talker 发布者

创建talker 进入ros工作空间下的 src 文件夹 创建 talker.cpp文件 这里就不详细描述创建过程

(*)创建ros工作空间

mkdir-p ~/catkin_ws/src
cd~/catkin_ws/src
carkin_int_workspace
cd~/catkin_ws
catkin_make
source devel/setup.bash
echo $ROS_PACKAGE_PATH

(1)初始化Ros节点

(2)向Rosmaster创建注册Ros节点句柄

(3)创建Publisher告诉Rosmaster我创建的节点的名字和类型

#include 
#include "ros/ros.h"
#include "std_msgs/String.h"

int main(int argc, char **argv)
{
  // ROS节点初始化 节点的名称
  ros::init(argc, argv, "talker");
  
  // 创建节点句柄  作为管理
  ros::NodeHandle n;
  
  // 创建一个Publisher,发布名为chatter的topic,消息类型为std_msgs::String  
  ros::Publisher chatter_pub = n.advertise("chatter", 1000);

  // 设置循环的频率 循环周期
  ros::Rate loop_rate(10);

(4)创建一个whlie发布的周期

  int count = 0;
  while (ros::ok())
  {
	// 初始化std_msgs::String类型的消息
    std_msgs::String msg;
    std::stringstream ss;
    ss << "hello world " << count;
    msg.data = ss.str();

	// 发布消息publish API接口
    ROS_INFO("%s", msg.data.c_str());
    chatter_pub.publish(msg);

	// 循环等待回调函数保持程序完整性 查询一次是否有话题进来循环等待 不断循环等待
    ros::spinonce();
	
	// 按照循环频率延时休眠 降低资源
    loop_rate.sleep();
    ++count;
  }

  return 0;
}

(5)创建一个订阅者,订阅收到发布者的内容

#include "ros/ros.h"
#include "std_msgs/String.h"

// 接收到订阅的消息后,会进入消息回调函数
void chatterCallback(const std_msgs::String::ConstPtr& msg)
{
  // 将接收到的消息打印出来
  ROS_INFO("I heard: [%s]", msg->data.c_str());
}

int main(int argc, char **argv)
{
  // 初始化ROS节点
  ros::init(argc, argv, "listener");

  // 创建节点句柄
  ros::NodeHandle n;

  // 创建一个Subscriber,订阅名为chatter的topic,注册回调函数chatterCallback
  // 1000相当于15200这样的波特率
  ros::Subscriber sub = n.subscribe("chatter", 1000, chatterCallback);

  // 循环等待具体的回调函数回来
  ros::spin();

  return 0;
}

(6)使用C++编译需要配置环境   回到工作空间 打开 Cmakelist 配置编译环境  打开注释掉的内容

#希望把代码通过talk.cpp生成src的可执行文件
add_executable(talker src/talker.cpp)
#依赖上第三方的库 连接库  可以有第三方的依赖
target_link_libraries(talker ${catkin_LIBRARIES})

#以下是listener的相关
# add_dependencies(talker ${PROJECT_NAME}_generate_messages_cpp)
add_executable(listener src/listener.cpp)
target_link_libraries(listener ${catkin_LIBRARIES})
# add_dependencies(talker ${PROJECT_NAME}_generate_messages_cpp)

(7)catkin_make   无任何错误读条完成就成功了

(8)验证程序

roscore
rosrun 功能包的名字  功能包下的可执行文件talker
rosrun 功能包的名字  功能包下的可执行文件listener

3.自定义话题名称或者类型

(1)在src工作文件夹下 创建 msg 自定义话题文件夹

(2)cd msg 文件夹 创建自己话题名字的定义   xxxx.msg 文件

(3)在package.xml 中添加依赖

message_generation 
message_runtime

(4)在cmake中添加具体的编译选项

• find_package( …… message_generation)

• catkin_package(CATKIN_DEPENDS geometry_msgs roscpprospy std_msgs message_runtime) 

• add_message_files(FILES XXXX.msg)generate_messages(DEPENDENCIES std_msgs)

#修改 xxxxx.msg 为你自己的文件


rosmsg show xxxx
#可以查看到具体消息里的东西

如果通过就是没有问题的,这样就可以用头的方式调用了

4.服务编程 (Egg:listener发布a b两个加数 发布给talker talker计算求和并还给 listener )

(1)自定义服务的文件创建a b  进入工作空间创建 srv 的文件夹

(2)创建 xxx.srv 文件 其中定义自己listener发布的内容

int64 a
int64 b       #服务端请求  把a b发送给服务端
---           #这里真的是分割线
int64 sum     #服务端应答  把结果放入sum

(3)添加package.xml 中添加功能包依赖

message_generation 
message_runtime

(4)添加cmakelist.txt中添加编译预选

• find_package( …… message_generation)
• catkin_package(CATKIN_DEPENDS geometry_msgs roscpprospy std_msgs message_runtime) 
• add_service_files(FILES AddTwoInts.srv)

(5)catkin_make  实现编译

(6)创建服务器

回到src文件夹下创建 service.cpp 服务器文件

#include "ros/ros.h"
#include "learning_communication/AddTwoInts.h"   //这里修改自己的功能包的名字

// service回调函数,输入参数req,输出参数res
bool add(learning_communication::AddTwoInts::Request  &req,
         learning_communication::AddTwoInts::Response &res)
{
  // 将输入参数中的请求数据相加,结果放到应答变量中
  res.sum = req.a + req.b;
  ROS_INFO("request: x=%ld, y=%ld", (long int)req.a, (long int)req.b);
  ROS_INFO("sending back response: [%ld]", (long int)res.sum);
  
  return true;
}

int main(int argc, char **argv)
{
  // ROS节点初始化
  ros::init(argc, argv, "add_two_ints_server");
  
  // 创建节点句柄
  ros::NodeHandle n;

  // 创建一个名为add_two_ints的server,注册回调函数add()
  ros::ServiceServer service = n.advertiseService("add_two_ints", add);
  
  // 循环等待回调函数
  ROS_INFO("Ready to add two ints.");
  ros::spin();

  return 0;
}

1.创建ros节点----2.创建server实例-----3.循环等待服务请求进入回掉-----4.在回调函数中处理反馈

(7)创建客户端

回到src文件夹下创建 client.cpp 服务器文件

 
#include 
#include "ros/ros.h"
#include "learning_communication/AddTwoInts.h"

int main(int argc, char **argv)
{
  // ROS节点初始化
  ros::init(argc, argv, "add_two_ints_client");
  
  // 从终端命令行获取两个加数
  if (argc != 3)
  {
    ROS_INFO("usage: add_two_ints_client X Y");
    return 1;
  }

  // 创建节点句柄
  ros::NodeHandle n;
  
  // 创建一个client,请求add_two_int service,service消息类型是learning_communication::AddTwoInts
  ros::ServiceClient client = n.serviceClient("add_two_ints");
  
  // 创建learning_communication::AddTwoInts类型的service消息终端的输输出有应答才能继续
  learning_communication::AddTwoInts srv;
  srv.request.a = atoll(argv[1]);
  srv.request.b = atoll(argv[2]);
  
  // 发布service请求,等待加法运算的应答结果
  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;     //结束程序
}

1.创建ros节点----2.创建Client实例-----3.发布服务请求数据-----4.等待server处理之后的应答结果

(3)添加编译选项修改Cmakelist

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)

(4)运行可执行程序

回到根目录下
catkin_make

(5)编译运行验证可执行文件

roscore
rosrun 功能包的名字  功能包下的可执行文件server
rosrun 功能包的名字  功能包下的可执行文件client

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/784436.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号