古月居ROS入门21讲-编程基础(1)
视频链接: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 工作空间
工作空间(workspace)是一个存放工程开发相关文件的文件夹,包括:
src:代码空间,存放功能包代码、配置文件、launch文件等
build:编译空间,编译过程中产生的中间文件
devel:开发空间,编译生成的可执行文件、库、脚本等
install:安装空间,install指令安装的默认文件夹,包括最终生成的可执行文件创建工作空间
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 功能包
- 创建功能包
同一个工作空间下,不允许存在同名功能包
不同工作空间下,允许存在同名功能包
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 自定义话题消息
- 定义msg文件
# 在learning_topic下新建msg文件夹,文件夹内新建Person.msg文件
# 文件内输入:
string name
uint8 sex
uint8 ageuint8 unknown = 0
uint8 male = 1
uint8 female = 2
- 在package.xml中添加功能包依赖
添加到末尾
<build_depend>message_generation</build_depend>
<exec_depend>message_runtime</exec_depend>
- cmakelist添加编译选项
find_package(... message_generation)
add_message_files(FILES Person.msg)
generate_messages(DEPENDENCIES std_mags)
catkin_package(... message_runtime)
- 编译
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)相关推荐
- 古月居 ROS 入门21讲--PA16 参数的使用与编程方法
古月居 ROS 入门21讲--PA16 参数的使用与编程方法 1.参数模型 2.创建功能包 cd ~/catkin_ws/src catkin_create_pkg learning_paramete ...
- 古月居 ROS 入门21讲--PA18 tf坐标系广播与监听的编程实现笔记
古月居 ROS 入门21讲--PA18 tf坐标系广播与监听的编程实现 1.创建功能包 cd ~/catkin_ws/src catkin_create_pkg learning_tf roscpp ...
- 古月居 ROS 入门21讲--PA17 ROS中坐标系管理系统笔记
古月居 ROS 入门21讲--PA17 ROS中坐标系管理系统笔记 1.TF 功能包功能 ∙ \bullet ∙ 五秒钟之前,机器人头部坐标系相当于全局坐标系的关系是怎样的? ∙ \bullet ∙机 ...
- 古月居ROS入门21讲学习笔记P9
古月居ROS入门21讲学习笔记P9 工作空间(workspace) 创建工作空间 创建功能包 实操 创建工作空间 创建功能包 老师在B站的原视频 链接: [古月居]古月·ROS入门21讲 | 一学就会 ...
- 古月居ROS入门21讲——9.创建工作空间与功能包
1.工作空间 工作空间(workspace)直观的形容就是一个仓库,里面装载着ROS的各种项目工程,便于系统组织管理调用. src/: 源代码包 build/: 编译生成的中间文件 devel/: 开 ...
- 古月居 ROS入门21讲 第十二讲 话题消息的定义与使用
古月居 ROS入门21讲 第十二讲 话题消息的定义与使用 Person.msg string name uint8 sex uint8 ageuint8 unknown=0 uint8 male=1 ...
- 古月居ROS入门21讲笔记
ROS入门21讲笔记--古月居 1 C++&Python极简基础 1.1 安装编译/解析器 1.2 for循环 1.3 while循环 1.4 面向对象 2. ROS基础 2.1 ROS概念 ...
- 古月居ROS入门21讲-坐标系管理
视频链接:bilibili 搜 古月居 源代码:关注古月居公众号,回复ROS入门21讲 文章目录 1 TF坐标变换 1.1 常用工具 2 tf坐标系广播与监听的编程实现 2.1 创建功能包 2.2 创 ...
- 古月居ROS入门21讲-launch文件
视频链接:bilibili 搜 古月居 源代码:关注古月居公众号,回复ROS入门21讲 文章目录 1 launch文件语法 2 launch 示例 launch文集:通过XML文件实现多个节点的配置和 ...
最新文章
- 【机器学习】基于人工鱼群算法的非线性函数寻优
- Python+selenium 自动化-操作已启用的chrome浏览器实例演示,chrome启用调试端口方法
- 【控制】《最优控制理论与系统》-胡寿松老师-第1章-导论
- Android应用性能优化之使用SparseArray替代HashMap(转)
- Cpp 对象模型探索 / 外部调用私有的虚函数的方法
- WPF 实现3D翻转倒计时控件~
- 将 ASP.NET Core 2.0 项目升级至 ASP.NET Core 2.1.3X
- 【GPU编程】基于GPU的光线投射体绘制(GPU-Based Ray-Casting Volume Rendering)入门学习
- 高性能异步批量ping的golang实现
- 数据分类分级指南范围
- win10 IE内核浏览器不能上网的问题
- 四元数与欧拉角(数学推导)
- bzoj5470 / P4578 [FJOI2018]所罗门王的宝藏//(尚未修正)
- Flutter 利用 Hero 动效实现列表详情页的无缝切换
- 技术提升了,钱自然就来了:盘点这段时间我挣钱的感受
- 从儿时的科幻电影到spaceX的火箭回收
- 国家二级c语言程序设计技巧,计算机等级考试二级C语言程序设计技巧.doc
- linux终端下打开pdf文件
- 数据库安全性重要策略审计
- 精灵图与字体图标的区别和用法(附Icomoon字体图标的使用方法)