【ROS21讲介绍】一讲~十二讲

本人跟着古月老师ROS入门21讲进行,汇集了本人的笔记,每一步都有代码,以及其中的代码实现和小误区,和古月老师的视频搭配观看效果最佳,b站就可以找到视频,入门下为第十三讲和二十一讲

一、ROS介绍

1、ROS学习曲线陡峭,上手不易
2、要懂C++、Python、Linux

二、Linux系统介绍

1、Linux开源
2、Linux企鹅作为标志

三、Linux系统基础操作

3.1 配置系统软件源

  • 软件源:就是后续下载软件它是从什么地方下载的
  1. 点击开ubuntu软件,点击上面,然后点击软件和更新
    在这里插入图片描述在这里插入图片描述
  • 家庭网选择aliyun镜像,如果是学校网就选择edu的后缀速度会比较快,如果实在不知道选择哪一个,就点击选择最佳服务器会自动帮你选择
    在这里插入图片描述
  • 然后点击选择服务器,输入密码,关闭,发现软件源更改要求重新载入,点击即可

3.2 终端

1、点击软件,右键打开软件与更新,在这里可以进行更改镜像,一般家里用mirrors.aliyun.com,校园网使用edu结尾的
2、命令行终端ctrl+alt+T

3.3 常用指令命令行

熟悉一些指令,首先打开终端,

1、查看当前终端所在路径:
pwd
2、切换路径到/xxx/xx,通过:
cd /xxx/xx
跳到上一级目录:cd ..
3、创建一个新的文件夹xxx:
mkdir xxx
4、查看当前路径下的文件
ls
5、在当前路径,新创建一个文件xxx_file:
touch xxx.file
6、剪切(移动)当前路径下文件文件xxx_file到路径 /xxx/xx
mv xxx.file /xxx/xx
7、copy当前路径下文件文件xxx_file到路径 /xxx/xx
cp xxx.file /xxx/xx
8、删除当前路径下文件xxx_file
rm xxx.file
9、递归的删除当前路径下文件夹xxx
rm -r xxx
10、提升用户的权限
sudo
10.1 重新载入,更新系统的软件源列表
sudo apt-get update
11、使用帮助指令,看到指令的使用方法
rm --help

四、C++/Python极简基础

4.1 安装g++编译器,指令:

sudo apt-get install g++

安装python编译器,指令为:

sudo apt-get install python

4.2 c++文件和python文件的实现

4.2.1 C++代码需要用g++对文件进行编译

首先,在对应路径下创建c++_for.cpp文件

然后编译:

g++ c++_for.cpp -o c++_for

-o后面是我们创建的可执行文件的名字,然后会发现该路径下多了我们刚才创建的一个新的可执行文件,windows可以双击执行,linux仍需要终端执行命令可使用:

./c++_for

在这里插入图片描述

4.2.2 python文件的直接指令即可:

创建python_for.py文件:
在这里插入图片描述
然后直接可以执行

python python_for.py

五、ROS是什么

1、松藕合分布式通信
2、ROS中的开发工具
3、ROS中的应用功能
4、ROS中的生态系统

六、ROS的核心理念

1、节点(Node)–执行单元

1.1、执行具体任务的进程、独立运行的可执行文件;
1.2、不同节点可使用不同的编程语言,可分布式运行在不同的主机;
1.3、节点在系统中的名称必须是唯一的。

2、节点管理器(ROS Master)

2.1、为节点提供命名和注册服务;
2.2、跟踪发和记录话题/服务通信,辅助节点相互查找、建立连接;
2.3、提供参数服务器,节点使用此服务器存储和检索运行时的参数。

3、话题(Topic)–异步通信机制

3.1、节点间用来传输数据的重要总线;
3.2、使用发布/订阅模型。数据有发布者传输到订阅者,同一个话题的订阅者或发布者可以不唯一。

4、消息(Message)–话题数据

4.1、具有一定的类型和数据结构,包括ROS提供的标准类型和用户自定义类型;
4.2、使用编程语言无关的.msg文件定义,编译过程中生成对应的代码文件

5、服务(Service)–同步通信机制

5.1、使用客户端/服务端(C/S)模型,客户端发送请求数据,服务器完成处理后返回应答数据;
5.2、使用编程语言无关的.srv文件定义请求和应答数据结构,编译过程中生成对应的代码文件。

6、参数(Parameter)–全局共享字典

6.1、可通过网络访问的共享,多变量字典;
6.2、节点使用此服务器来存储和检索运行时的参数;
6.3、适合存储静态、非二进制的配置参数,不适合存储动态配置的数据。

7、功能包(Package)

7.1、ROS软件中的基本单元,包含节点源码、配置文件、数据定义等
7.2、一般功能包是完成一些功能的,比如人脸识别,可以做成一个单独的功能包

8、功能包清单(Package manifest)

8.1、记录功能包的基本信息,包含作者信息,许可信息、依赖选项、编译标志灯。

9、元功能包(Meta Package)

9.1、很多功能包聚合在一切的大的功能包,组织多个用于同一目的功能包
在这里插入图片描述

在这里插入图片描述

10 工作空间的覆盖

  • 工作空间的路径依次在ROS_PACKAGE_PATH环境变量中记录
  • 新设置的路径在ROS_PACKAGE_PATH中会自动放置在最前端
  • 运行时,ROS会优先查找最前端的工作空间中是否存在指定的功能包
  • 如果不存在,就顺序向后查找其他工作空间
  • 可以使用env | grep ros来查看所有与ros相关的环境变量
    在这里插入图片描述
  1. 首先确保ros的一些历程安装
sudo apt-get install ros-melodic-roscpp-tutorials
  1. 安装之后看一下,ros从哪一个路径下帮我们去找到功能包(系统路径下的功能包)
bupo@bupo-vpc:~$ rospack find roscpp_traits
/opt/ros/melodic/share/roscpp_traits
  1. 如果创建一个新的工作空间catkin_ws,并且把功能包放进该新的工作空间,然后source一下,那么就会先查找到该工作空间下的同名工作包,然后停止查找(工作空间下的功能包)
bupo@bupo-vpc:~$ rospack find roscpp_traits
/home/bupo/lianxi/catkin_ws_15ke/src/roscpp_traits

  1. 这是因为查找路径是有一个顺序的,按照这个顺序进行

七、ROS命令行工具的使用

7.1常用命令:

rostopic
rosservice
rosnode
rosparam
rosmsg
rossrv

7.2 命令行演示

  1. 首先启动小海龟
    在三个不同的终端中分别执行
roscore
rosrun turtlesim turtlesim_node
rosrun turtlesim turtle_teleop_key
  1. 可视化图形指令
rqt_graph

在这里插入图片描述

  1. 显示所有节点相关的信息指令
rosnode

之后会出一些帮助
比如:系统中所有节点都列出来

rosnode list

/rosout默认的节点信息
查看某一个节点信息:

rosnode info /turtlesim

可以看到节点在发布哪些话题,服务,主机号

  1. 查看topic的一些信息,和rosnode用法相同
    可以通过指令给话题发布数据:
rostopic pub /turtle1/cmd_vel geometry_msgs/Twist "linear:
  x: 0.0
  y: 0.0
  z: 0.0
angular:
  x: 0.0
  y: 0.0
  z: 0.0" 
这里pub后面加不加 -数字 都可以

rostopic pub /话题名 发布的消息结构 “消息结构里具体数字”

在pub后面加上-r+数字是循环发布,一直发布,不停息,下面例子是1s
发布十次,10hz
rostopic pub -r 10 /turtle1/cmd_vel geometry_msgs/Twist "linear:
  x: 1.0
  y: 0.0
  z: 0.0
angular:
  x: 0.0
  y: 0.0
  z: 1.0" 
  1. 查看message的一些信息,可以查看发布消息的格式,和rosnode用法相同:
rosmsg

使用:

rosmsg show 消息名称
rosmsg show geometry_msgs/Twist (例子)

得到:

geometry_msgs/Vector3 linear
  float64 x
  float64 y
  float64 z
geometry_msgs/Vector3 angular
  float64 x
  float64 y
  float64 z
  1. 查看srevice的一些信息,和rosnode用法相同:
rosservice

这里我们可以多个海龟:

rosservice call /spawn "x: 2.0
y: 2.0
theta: 0.0
name: 'turtle2'" 

定义海龟诞生的xy和角度坐标,以及它的名字

  1. 话题记录的工具rosbag
    话题记录:
rosbag record -a -o cmd_record
-a就是all把所有的数据都保存下来
-o把保存的数据保存成压缩包,压缩包的名字就是后面的内容cmd_record,如果是小写的o,就会在名字后面加上日期时间,如果是大写的O就只会使用你给的名字
保存的路径是当前终端的路径

注意:输入上述指令之后才开始记录

记录结束之后直接ctrl+c就可以结束并且自动保存下来了

话题复现:

rosbag play cmd_record.bag

八 、创建工作空间与工具包

8.1工作空间(workspace)是一个存放工程开发相关文件的文件夹
src:代码空间(Source Space)
build:编译空间(Build Space)
devel:开发空间(Development Space)
install:安装空间(Instal Space)
编译不会产生install,必须使用命令:

catkin_make install

8.2 创建工作空间

2.1、创建工作空间:

mkdir -p ~/catkin_ws/src
cd ~/catkin_ws/
catkin_init_workspace # 有这就一句说明当前路径是ros的编译空间啦

2.2、编译工作空间

cd ~/catkin_ws/
catkin_make

这样是没有install文件夹的,如果想要产生install文件夹,就是命令:

catkin_make install
  • src:放后面功能包的源码
  • install:安装空间,最后编译生成的可执行文件放进来
  • devel:开发空间,放开发过程中的可执行文件,包括一些库,devle和intall功能是类似的,intsall是开发后分享给别人使用的文件
  • build:编译过程中的中间文件,一般是用不到的
    2.3、设置环境变量
source devel/setup.bash

可进入.bashrc文件设置
2.4、检查环境变量

echo $ROS_PACKAGE_PATH

8.3 创建功能包

  • 放置源码的最小单元

3.1、创建功能包代码:

catkin_create_pkg <package_name> [depend1] [depend2] [depend3]

后面跟了好多依赖,也就是编译时需要依赖哪些功能包库
3.2、实操创建功能包

cd ~/catkin_make/src
catkin_create_pkg test_pkg std_msgs rospy roscpp

3.3、编译功能包

cd ~/catkin_ws
catkin_make
source ~/catkin_ws/devel/setup.bash

同一工作下,不允许存在同名功能包
不同工作空间下,允许

九、发布者Publisher的编程实现

1、创建功能包learning_topic:

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

2、创建velocity_publisher.cpp文件:

cd ~/roslianxi/catkin_wa/src/learning_topic/src/
touch velocity_publisher.cpp

然后代码为:

/**
* 该历程将发布turtle1/cmd_vel话题,消息类型geometry_msgs::Twist
*/

#include <ros/ros.h>
#include <geometry_msgs/Twist.h>

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

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

	//创建一个Publisher,发布名为/turtle1/cmd_vel的topic,消息类型为geometry_msgs::Twists,队列长度为10
	ros::Publisher turtle_vel_pub = n.advertise<geometry_msgs::Twist>("/turtle1/cmd_vel", 10);

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

	int count = 0;
	while (ros::ok())
	{
		//初始化geometry_msgs::Twists类型的消息
		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("Publish turtle velocity command[%0.2f m/s, %0.2f rad/s]",vel_msg.linear.x, vel_msg.angular.z);

		//按照循环频率延时
		loop_rate.sleep();
	}
	return 0;
}

3、创建发布者步骤-如何实现一个发布者

3.1、初始化ROS节点
3.2、向ROS Master注册节点信息,包括发布的话题名和话题中的消息类型
3.3、创建消息数据;
3.4、按照一定频率循环发布消息

4、配置发布者代码编译规则

4.1、如何配置CMakeList.txt中的编译规则
4.1.1、设置需要编译的代码和生成的可执行文件
4.1.2、设置链接库
在learning_topic下的CMakeList.txt下添加:

add_executable(velocity_publisher src/velocity_publisher.cpp)
#描述把哪一个文件编译成哪一个可执行文件的,后面的编译成前面的
target_link_libraries(velocity_publisher ${catkin_LIBRARIES})
#用来帮助把可执行文件和ros相关的库链接的

在这里插入图片描述

5、编译并运行发布者

cd ~/catkin_ws
catkin_make
source devel/setup.bash
  • 这里如果不想每次都要设置环境变量,可以把source这句话房间根目录的.bashrc文件里面

  • 可以通过在主文件夹下ctrl+h显示隐藏文件,手动添加
    在这里插入图片描述

  • 也可以使用命令vim ~/.bashrc打开./bashrc文件

roscore


新开终端
rosrun turtlesim turtlesim_node

新开终端
rosrun learning_topic velocity_publisher

6 python的实现

  • 一般把python文件放在scripts文件夹里面,这是为了区分开c++文件,这里创建了名为velocity_publisher.py的文件,内容为:
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# 该例程将发布turtle1/cmd_vel话题,消息类型geometry_msgs::Twist

import rospy
from geometry_msgs.msg import Twist

def velocity_publisher():
	# ROS节点初始化
    rospy.init_node('velocity_publisher', anonymous=True)

	# 创建一个Publisher,发布名为/turtle1/cmd_vel的topic,消息类型为geometry_msgs::Twist,队列长度10
    turtle_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.5
        vel_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执行直接执行即可

十、订阅者Subscriber的编程实现

1、创建订阅者代码

1.1、如何实现一个订阅者
a、初始化ROS节点;
b、订阅需要的话题;
c、循环等待话题消息,接收到消息后进入回调函数;
d、在回调函数中完成消息处理。
1.2、代码如下:

/**
* 该例程将订阅/turtle1/pose话题,消息类型turtlesim::Pose
*/

#include <ros/ros.h>
#include "turtlesim/Pose.h"
//#include "std_msgs/String.h"

// 接收到订阅的消息后,会进入消息回调函数
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
    ros::Subscriber pose_sub = n.subscribe("turtle1/pose", 10, poseCallback);

    //循环等待回调函数
    ros::spin();
    return 0;
}

这里出现了一个问题,搞了半天,发现是我把main写成了mian,。。。。。
1.3、编译执行
在CMakeList.txt文件下

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

然后编译执行:

cd ~/roslianxi/catkin_ws
catkin_make
source devel/setup.bash
roscore

新终端
rosrun turtlesim turtlesim_node

新终端
rosrun learning_topic velocity_publisher

2 python实现的效果

  • 在scripts文件夹中创建py文件pose_subsccriber.py文件,内容为:
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# 该例程将订阅/turtle1/pose话题,消息类型turtlesim::Pose

import rospy
from turtlesim.msg import Pose

def 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,注册回调函数poseCallback
    rospy.Subscriber("/turtle1/pose", Pose, poseCallback)

	# 循环等待回调函数
    rospy.spin()

if __name__ == '__main__':
    pose_subscriber()
  • 同样右键确认下可执行权限是对号

十一、话题消息的定义与使用

1、如何自定义话题消息(例)

1.1、定义Preson.msg文件(记得首字母大写);
在对应功能包下创建msg文件夹,必须放在该路径下,然后创建Preson.msg文件

string name
uint8 sex
uint8 age

uint8 unknown = 0
uint8 male =1
uint8 female = 2

1.2、在package.xml中添加功能包依赖

<build_depend>message_generation</build_depend>
<exec_depend>message_runtime</exec_depend>

1.3、在CMakeLists.txt添加编译选项

find_package(...... message_generation)

add_message_files(FILES Person.msg)
generate_messages(DEPENDENCIES std_msgs)

catkin_package(  CATKIN_DEPENDS geometry_msgs roscpp rospy std_msgs turtlesim message_runtime)
# 这些原文是注释掉了,我们可以选择修改注释或者直接加上

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

1.4、编译生成语言相关文件

cd ~/catkin_ws
catkin_make

然后就可以看到在catkin_ws/devel/include/learning_topic/learning_topic下有一个Preson.h
可以使用命令

bupo@bupo-vpc:~$ rosmsg show Preson
[learning_communication/Preson]:
uint8 unknown=0
uint8 male=1
uint8 female=2
string name
uint8 sex
uint8 age

1.5、进行实战
这里提供了两个cpp文件,分别是person_publisher.cpp和person_subscriber.cpp,路径在learning_topic/src下,
person_publisher.cpp代码为:

/**

 * 该例程将发布/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,队列长度10
    ros::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;
}

person_subscriber.cpp代码为:

/**
 * 该例程将订阅/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,注册回调函数personInfoCallback
    ros::Subscriber person_info_sub = n.subscribe("/person_info", 10, personInfoCallback);

    // 循环等待回调函数
    ros::spin();
    return 0;
}

同样在这里不要忘记了在CMakeLists.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)

在这里多了一个add_dependencies,有一些代码是动态生成的,可执行文件与动态生成的头文件做链接

然后进行编译执行:

cd ~/catkin_ws/
catkin_make
source devel/setup.bash
roscore

新开终端
rosrun learning_topic person_publisher

新开终端
rosrun learning_topic person_subscriber

在节点运行的时候,即使关闭了master节点,节点仍然会运行,因为rosmaster是帮助topic之间建立连接的,连接之后,就可以不需要rosmaster了

  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值