视频链接:bilibili 搜 古月居
源代码:关注古月居公众号,回复ROS入门21讲

文章目录

  • 1 创建工作空间和功能包
    • 1.1 工作空间
    • 1.2 功能包
  • 2 发布者Publisher的编程实现
    • 2.1 创建功能包
    • 2.2 创建发布者代码(C++)
      • 2.2.1 代码
      • 2.2.2 配置CMakeLists.txt中的编译规则
      • 2.2.3 编译并运行发布者
    • 2.3 创建发布者代码(Python)
      • 2.3.1 代码
      • 2.3.2 运行发布者
  • 3 订阅者Subscriber的编程实现
    • 3.1 创建订阅者代码(C++)
      • 3.1.1 代码
      • 3.1.2 配置订阅者代码编译规则
    • 3.2 创建订阅者代码(python)
      • 3.2.1 代码
      • 3.2.2 运行订阅者
  • 4 话题消息的定义与使用
    • 4.1 自定义话题消息
    • 4.2 创建Publisher和Subscriber(C++)
    • 4.3 创建Publisher和Subscriber(Python)

1 创建工作空间和功能包

1.1 工作空间

  1. 工作空间(workspace)是一个存放工程开发相关文件的文件夹,包括:
    src:代码空间,存放功能包代码、配置文件、launch文件等
    build:编译空间,编译过程中产生的中间文件
    devel:开发空间,编译生成的可执行文件、库、脚本等
    install:安装空间,install指令安装的默认文件夹,包括最终生成的可执行文件

  2. 创建工作空间

1.创建工作空间
mkdir -p ~/catkin_ws/src
cd ~/catkin_ws/src
catkin_init_workspace  //将当前文件夹变成ROS工作空间的属性
2.编译工作空间
cd ~/catkin_ws/    //编译时需要造工作空间根目录相当于此处catkin_ws
catkin_make
3.设置环境变量
source devel/setup.bash  //方便系统找到编译生成的可执行文件
4.检查环境变量
echo $ROS_PACKAGE_PATH

1.2 功能包

  1. 创建功能包
    同一个工作空间下,不允许存在同名功能包
    不同工作空间下,允许存在同名功能包
catkin_create_pkg<package_name> [depend1][depend2][depend3]
//后面的depend是指编译时需要依赖ROS中其他的功能包名
1.创建功能包
cd ~/catkin_ws/src
catkin_create_pkg test_pkg std_msgs rospy roscpp
2.编译功能包
cd ~/catkin_ws
catkin_make
source ~/catkin_ws/devel/setup.bash   //添加环境变量

创建生成的功能包下有两个文件夹,以及两个功能包中必须存在的文件:
文件夹
include用于放置头文件;
src用于放功能包代码;
文件
package.xml:包括功能包基本信息,编译和运行功能包所需的依赖信息
cmakelists.txt:描述编译规则以及编译的设置

2 发布者Publisher的编程实现

通过话题的发布与订阅实现小海龟的运动控制

2.1 创建功能包

cd ~/catkin_ws/src
catkin_create_pkg learning_topic roscpp rospy std_msgs geometry_msgs turtlesim

2.2 创建发布者代码(C++)

cpp文件代码放在创建的功能包对应src目录下

2.2.1 代码

/***********************************************************************
Copyright 2020 GuYueHome (www.guyuehome.com).
***********************************************************************//*** 该例程将发布turtle1/cmd_vel话题,消息类型geometry_msgs::Twist,该消息用来控制海龟运动*/#include <ros/ros.h>
#include <geometry_msgs/Twist.h>int main(int argc, char **argv)
{// ROS节点初始化,ROS中节点不能重名ros::init(argc, argv, "velocity_publisher");// 创建节点句柄,用来管理ROS相关API资源,ros::NodeHandle n;// 创建一个Publisher,发布名为/turtle1/cmd_vel的topic,消息类型为geometry_msgs::Twist,队列长度10ros::Publisher turtle_vel_pub = n.advertise<geometry_msgs::Twist>("/turtle1/cmd_vel", 10);// 设置循环的频率ros::Rate loop_rate(10);// while循环实现:封装数据,发布数据,等待至下一次循环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[%0.2f m/s, %0.2f rad/s]", vel_msg.linear.x, vel_msg.angular.z);// 按照循环频率延时loop_rate.sleep();}return 0;
}

2.2.2 配置CMakeLists.txt中的编译规则

将下面两句话添加到功能包cmakelist.txt文件中对应的build位置下

1.设置需要编译的代码和生成的可执行文件
add_executable(velocity_publisher src/velocity_publisher.cpp)
// 将src/velocity_publisher.cpp代码编译成可执行文件velocity_publisher
2.将可执行文件链接到ROS相关库
target_link_libraries(velocity_publisher ${catkin_LIBRARIES})

2.2.3 编译并运行发布者

1.编译
cd ~/catkin_ws
catkin_make
2.添加路径
source devel/setup.bash
3.终端1
roscore
4.终端2
rosrun turtlesim turtle_node
5.在catkin_ws目录下打开终端3
rosrun learning_topic velocity_publisher

如果想省略输入source devel/setup.bash指令,则打开【主文件夹】,按下【ctrl+h】显示隐藏文件,打开【.bashrc】文件,将【source /home/yao/catkin_ws/devel/setup.bash】(一定要是完整路径)指令添加到bashrc的末端,保存退出,重新启动终端生效。采用该方法时,上述步骤5的终端可以在任意位置打开。

2.3 创建发布者代码(Python)

创建与功能包下src同级文件夹scripts,py文件代码放于此

2.3.1 代码

#!/usr/bin/env python
# -*- coding: utf-8 -*-########################################################################
####          Copyright 2020 GuYueHome (www.guyuehome.com).          ###
######################################################################### 该例程将发布turtle1/cmd_vel话题,消息类型geometry_msgs::Twistimport rospy
from geometry_msgs.msg import Twistdef velocity_publisher():# ROS节点初始化rospy.init_node('velocity_publisher', anonymous=True)# 创建一个Publisher,发布名为/turtle1/cmd_vel的topic,消息类型为geometry_msgs::Twist,队列长度10turtle_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.5vel_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

设置py文件属性:右击py文件,选择【属性】,点击【权限】,将【允许作为可执行文件】打勾

2.3.2 运行发布者

1.终端1
roscore
2.终端2
rosrun turtlesim turtle_node
3.在catkin_ws文件所在目录下打开终端3
source devel/setup.bash
rosrun learning_topic velocity_publisher.py

3 订阅者Subscriber的编程实现

3.1 创建订阅者代码(C++)

3.1.1 代码

/***********************************************************************
Copyright 2020 GuYueHome (www.guyuehome.com).
***********************************************************************//*** 该例程将订阅/turtle1/pose话题,消息类型turtlesim::Pose*/#include <ros/ros.h>
#include "turtlesim/Pose.h"// 接收到订阅的消息后,会进入消息回调函数,回调函数不嵌套,需高效运行
// msg以一个常指针的形式指向turtlesim::Pose的所有数据内容
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// 此处队列为10,相当于是一个缓冲器// 当订阅者发现有/turtle1/pose话题的数据进来时,调用回调函数做处理ros::Subscriber pose_sub = n.subscribe("/turtle1/pose", 10, poseCallback);// 循环等待回调函数//有消息进来时转到回调函数,无消息时spin自身做死循环ros::spin();return 0;
}

3.1.2 配置订阅者代码编译规则

将下面两句话添加到功能包cmakelist.txt文件中对应的build位置下

add_executable(pose_subscriber src/pose_subscriber.cpp)
target_link_libraries(pose_subscriber ${catkin_LIBRARIES})

编译

1.编译
cd ~/catkin_ws
catkin_make
2.添加路径
source devel/setup.bash
3.终端1
roscore
4.终端2
rosrun turtlesim turtle_node
5.在catkin_ws目录下打开终端3
rosrun learning_topic pose_subscriber
6.在catkin_ws目录下打开终端4
source devel/setup.bash
rosrun learning_topic velocity_publisher

当采用【source devel/setup.bash】添加路径时,每次打开终端时都需要先链接路径,才能索引到功能包

3.2 创建订阅者代码(python)

3.2.1 代码

#!/usr/bin/env python
# -*- coding: utf-8 -*-########################################################################
####          Copyright 2020 GuYueHome (www.guyuehome.com).          ###
######################################################################### 该例程将订阅/turtle1/pose话题,消息类型turtlesim::Poseimport rospy
from turtlesim.msg import Posedef 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,注册回调函数poseCallbackrospy.Subscriber("/turtle1/pose", Pose, poseCallback)# 循环等待回调函数rospy.spin()if __name__ == '__main__':pose_subscriber()

3.2.2 运行订阅者

1.终端1
roscore
2.终端2
rosrun turtlesim turtle_node
3.在catkin_ws文件所在目录下打开终端3
source devel/setup.bash
rosrun learning_topic pose_subscriber.py

4 话题消息的定义与使用

视频第十二讲第5分钟

4.1 自定义话题消息

  1. 定义msg文件
# 在learning_topic下新建msg文件夹,文件夹内新建Person.msg文件
# 文件内输入:
string name
uint8 sex
uint8 ageuint8 unknown = 0
uint8 male = 1
uint8 female = 2
  1. 在package.xml中添加功能包依赖
    添加到末尾
<build_depend>message_generation</build_depend>
<exec_depend>message_runtime</exec_depend>
  1. cmakelist添加编译选项
find_package(... message_generation)
add_message_files(FILES Person.msg)
generate_messages(DEPENDENCIES std_mags)
catkin_package(... message_runtime)
  1. 编译
catkin_make

4.2 创建Publisher和Subscriber(C++)

Publisher代码

/***********************************************************************
Copyright 2020 GuYueHome (www.guyuehome.com).
***********************************************************************//*** 该例程将发布/person_info话题,自定义消息类型learning_topic::Person*/#include <ros/ros.h>
#include "learning_topic/Person.h"int main(int argc, char **argv)
{// ROS节点初始化ros::init(argc, argv, "person_publisher");// 创建节点句柄ros::NodeHandle n;// 创建一个Publisher,发布名为/person_info的topic,消息类型为learning_topic::Person,队列长度10ros::Publisher person_info_pub = n.advertise<learning_topic::Person>("/person_info", 10);// 设置循环的频率ros::Rate loop_rate(1);int count = 0;while (ros::ok()){// 初始化learning_topic::Person类型的消息learning_topic::Person person_msg;person_msg.name = "Tom";person_msg.age  = 18;person_msg.sex  = learning_topic::Person::male;//采用定义的宏赋值// 发布消息person_info_pub.publish(person_msg);ROS_INFO("Publish Person Info: name:%s  age:%d  sex:%d", person_msg.name.c_str(), person_msg.age, person_msg.sex);// 按照循环频率延时loop_rate.sleep();}return 0;
}

Subscriber代码

/***********************************************************************
Copyright 2020 GuYueHome (www.guyuehome.com).
***********************************************************************//*** 该例程将订阅/person_info话题,自定义消息类型learning_topic::Person*/#include <ros/ros.h>
#include "learning_topic/Person.h"
// 自己定义的头文件
// 接收到订阅的消息后,会进入消息回调函数
void personInfoCallback(const learning_topic::Person::ConstPtr& msg)
{// 将接收到的消息打印出来ROS_INFO("Subcribe Person Info: name:%s  age:%d  sex:%d", msg->name.c_str(), msg->age, msg->sex);
}int main(int argc, char **argv)
{// 初始化ROS节点ros::init(argc, argv, "person_subscriber");// 创建节点句柄ros::NodeHandle n;// 创建一个Subscriber,订阅名为/person_info的topic,注册回调函数personInfoCallbackros::Subscriber person_info_sub = n.subscribe("/person_info", 10, personInfoCallback);// 循环等待回调函数ros::spin();return 0;
}

cmakelist.txt添加语句

add_executable(person_publisher src/person_publisher.cpp)
target_link_libraries(person_publisher ${catkin_LIBRARIES})
add_dependencies(person_publisher ${PROJECT_NAME}_generate_messages_cpp)add_executable(person_subscriber src/person_subscriber.cpp)
target_link_libraries(person_subscriber ${catkin_LIBRARIES})
add_dependencies(person_subscriber ${PROJECT_NAME}_generate_messages_cpp)
//用于和自定义生成的头文件进行链接

运行publisher和subscriber

1.打开终端1
roscore
2.catkin_ws下打开终端2
source devel/setup.bash
rosrun learning_topic person_publisher
3.catkin_ws下打开终端3
source devel/setup.bash
rosrun learning_topic person_subscriber

4.3 创建Publisher和Subscriber(Python)

Publisher代码

#!/usr/bin/env python
# -*- coding: utf-8 -*-########################################################################
####          Copyright 2020 GuYueHome (www.guyuehome.com).          ###
######################################################################### 该例程将发布/person_info话题,自定义消息类型learning_topic::Personimport rospy
from learning_topic.msg import Persondef velocity_publisher():# ROS节点初始化rospy.init_node('person_publisher', anonymous=True)# 创建一个Publisher,发布名为/person_info的topic,消息类型为learning_topic::Person,队列长度10person_info_pub = rospy.Publisher('/person_info', Person, queue_size=10)#设置循环的频率rate = rospy.Rate(10) while not rospy.is_shutdown():# 初始化learning_topic::Person类型的消息person_msg = Person()person_msg.name = "Tom";person_msg.age  = 18;person_msg.sex  = Person.male;# 发布消息person_info_pub.publish(person_msg)rospy.loginfo("Publsh person message[%s, %d, %d]", person_msg.name, person_msg.age, person_msg.sex)# 按照循环频率延时rate.sleep()if __name__ == '__main__':try:velocity_publisher()except rospy.ROSInterruptException:pass

Subscriber代码

#!/usr/bin/env python
# -*- coding: utf-8 -*-########################################################################
####          Copyright 2020 GuYueHome (www.guyuehome.com).          ###
######################################################################### 该例程将订阅/person_info话题,自定义消息类型learning_topic::Personimport rospy
from learning_topic.msg import Persondef personInfoCallback(msg):rospy.loginfo("Subcribe Person Info: name:%s  age:%d  sex:%d", msg.name, msg.age, msg.sex)def person_subscriber():# ROS节点初始化rospy.init_node('person_subscriber', anonymous=True)# 创建一个Subscriber,订阅名为/person_info的topic,注册回调函数personInfoCallbackrospy.Subscriber("/person_info", Person, personInfoCallback)# 循环等待回调函数rospy.spin()if __name__ == '__main__':person_subscriber()

运行publisher和subscriber

1.打开终端1
roscore
2.catkin_ws下打开终端2
source devel/setup.bash
rosrun learning_topic person_publisher.py
3.catkin_ws下打开终端3
source devel/setup.bash
rosrun learning_topic person_subscriber.py

古月居ROS入门21讲-编程基础(1)相关推荐

  1. 古月居 ROS 入门21讲--PA16 参数的使用与编程方法

    古月居 ROS 入门21讲--PA16 参数的使用与编程方法 1.参数模型 2.创建功能包 cd ~/catkin_ws/src catkin_create_pkg learning_paramete ...

  2. 古月居 ROS 入门21讲--PA18 tf坐标系广播与监听的编程实现笔记

    古月居 ROS 入门21讲--PA18 tf坐标系广播与监听的编程实现 1.创建功能包 cd ~/catkin_ws/src catkin_create_pkg learning_tf roscpp ...

  3. 古月居 ROS 入门21讲--PA17 ROS中坐标系管理系统笔记

    古月居 ROS 入门21讲--PA17 ROS中坐标系管理系统笔记 1.TF 功能包功能 ∙ \bullet ∙ 五秒钟之前,机器人头部坐标系相当于全局坐标系的关系是怎样的? ∙ \bullet ∙机 ...

  4. 古月居ROS入门21讲学习笔记P9

    古月居ROS入门21讲学习笔记P9 工作空间(workspace) 创建工作空间 创建功能包 实操 创建工作空间 创建功能包 老师在B站的原视频 链接: [古月居]古月·ROS入门21讲 | 一学就会 ...

  5. 古月居ROS入门21讲——9.创建工作空间与功能包

    1.工作空间 工作空间(workspace)直观的形容就是一个仓库,里面装载着ROS的各种项目工程,便于系统组织管理调用. src/: 源代码包 build/: 编译生成的中间文件 devel/: 开 ...

  6. 古月居 ROS入门21讲 第十二讲 话题消息的定义与使用

    古月居 ROS入门21讲 第十二讲 话题消息的定义与使用 Person.msg string name uint8 sex uint8 ageuint8 unknown=0 uint8 male=1 ...

  7. 古月居ROS入门21讲笔记

    ROS入门21讲笔记--古月居 1 C++&Python极简基础 1.1 安装编译/解析器 1.2 for循环 1.3 while循环 1.4 面向对象 2. ROS基础 2.1 ROS概念 ...

  8. 古月居ROS入门21讲-坐标系管理

    视频链接:bilibili 搜 古月居 源代码:关注古月居公众号,回复ROS入门21讲 文章目录 1 TF坐标变换 1.1 常用工具 2 tf坐标系广播与监听的编程实现 2.1 创建功能包 2.2 创 ...

  9. 古月居ROS入门21讲-launch文件

    视频链接:bilibili 搜 古月居 源代码:关注古月居公众号,回复ROS入门21讲 文章目录 1 launch文件语法 2 launch 示例 launch文集:通过XML文件实现多个节点的配置和 ...

最新文章

  1. 【机器学习】基于人工鱼群算法的非线性函数寻优
  2. Python+selenium 自动化-操作已启用的chrome浏览器实例演示,chrome启用调试端口方法
  3. 【控制】《最优控制理论与系统》-胡寿松老师-第1章-导论
  4. Android应用性能优化之使用SparseArray替代HashMap(转)
  5. Cpp 对象模型探索 / 外部调用私有的虚函数的方法
  6. WPF 实现3D翻转倒计时控件~
  7. 将 ASP.NET Core 2.0 项目升级至 ASP.NET Core 2.1.3X
  8. 【GPU编程】基于GPU的光线投射体绘制(GPU-Based Ray-Casting Volume Rendering)入门学习
  9. 高性能异步批量ping的golang实现
  10. 数据分类分级指南范围
  11. win10 IE内核浏览器不能上网的问题
  12. 四元数与欧拉角(数学推导)
  13. bzoj5470 / P4578 [FJOI2018]所罗门王的宝藏//(尚未修正)
  14. Flutter 利用 Hero 动效实现列表详情页的无缝切换
  15. 技术提升了,钱自然就来了:盘点这段时间我挣钱的感受
  16. 从儿时的科幻电影到spaceX的火箭回收
  17. 国家二级c语言程序设计技巧,计算机等级考试二级C语言程序设计技巧.doc
  18. linux终端下打开pdf文件
  19. 数据库安全性重要策略审计
  20. 精灵图与字体图标的区别和用法(附Icomoon字体图标的使用方法)

热门文章

  1. linux命令cd回退_cd命令退回目录的方法
  2. canary??!!
  3. Ctrl快捷键使用大全
  4. Git 如何压缩 commit
  5. html网页设计仿微信首页
  6. 计算机组成原理实验4微程序控制实验
  7. spring AOP原理分析:静态代理;JDK实现接口动态代理;Cglib继承父类代理;SpringAop的责任链模式调用
  8. 【八卦趣事】富人对穷人的平均工资影响有多大
  9. CodeForces-1379C Choosing flowers
  10. FFT造成的频谱混叠,栅栏效应,频谱泄露,谱间干扰