ROS开发系列(1)- ROS基础知识

1.常用指令

1.1 roscore

启动一个roscore就相当于是开启了一个rosmaster,也就是管理器

1.2 rosrun

rosrun指令的第一个参数是功能包的名字,如果这个时候双击tab按钮,则会显示这个功能包下面的所有节点

1.3 rqt_graph

这个是基于QT的可视化工具,可以直观的看到一些信息,可以显示系统计算图的一个工具

1.4 topic是单向传输的

1.5 service是双向的同步传输

1.6 rosnode

是用来显示系统所有节点相关信息的指令

  • rosnode list 用来把所有节点都列出来的指令

    在显示的节点中会出现一个rosout,这个节点在rqt中不显示,是因为这个是默认在启动roscore的时候自动启动的一个节点,用来采集ros所有节点的日志信息,用来提交给上面的界面用来显示的

  • rosnode info [节点名字]

    用来显示这个节点的具体信息,包括发布哪些话题,订阅哪些话题,提供一些service,通过这些服务完成配置

1.7 rostopic

  • list 可以打印当前所有话题的列表

  • pub 用来给制定话题发布指令,linear是线速度,angular是角速度 对应单位一般是 跟频率相关的都是米 跟角度相关的都是弧度

    • -r 参数 是rate的意思,已多少频率循环发送指令(用来连续运动)

    • 举例

      zero@zero:~$ rostopic pub -r 10 /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" 
      
      

1.8 rosmsg

  • show 可以显示具体话题的消息结构例如:

    zero@zero:~$ 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.9 rosservice

使用rosservic 加上双击tab按钮,则会显示这个指令下的所有可操作的指令

  • list 显示当前的提供的服务,这个是只针对当前海龟模拟器来说的,也就是说海龟模拟器提供了哪些服务
    ROS开发系列(1)- ROS基础知识_第1张图片

    我们作为客户端可以请求这些服务,例如生成一个新的海龟

    rosservice call /spawn "x: 10.0
    y: 10.0
    theta: 0.0
    name: 'turtle3'" 
    name: "turtle3"
    

    注意:这里面的x:后面需要有一个空格,没有空格会报错

1.10 rosbag

用于记录数据的,例如你的无人机实际飞行一次,然后使用rosbag记录下来,这样就可以在修改参数后直接用上一次记录的数据进行复现。指令如下:cmd_record是自己起的名字

rosbag record -a -O cmd_record

启动后,就会自动开始记录键盘节点上的按键数据,用于复现使用

记录的文件会放在当前终端的目录下(我这里就是home目录)

复现数据指令:

rosbag play cmd_record.bag 

使用复现的时候,不用开启键盘节点了,小海龟会自动按照之前的操作自动进行

2.工作空间

  • src:代码空间,用于存放功能包的代码、配置文件、launch文件
  • build:编译空间,存放编译过程中产生的中间文件,不太用关心
  • devel:开发空间,放置编译生成的可执行文件,一些库,包括脚本文件,编译生成的文件在这里运行
  • install:安装空间,用install指令安装的文件的结果

在ros2中,只保留了install,因为install和devel有重复的地方,但是在ros1中主要还是使用devel

install和devel文件夹的区别,install是开发后产生的可执行文件,用于给客户使用的,devel是开发中的可执行文件,用于调试用的

2.1 创建工作空间

catkin_ws可以自己定义名字,但是src必须是这个名字

mkdir -p ~/catkin_ws/src
cd ~/catkin_ws/src

初始化工作空间,将这个文件夹变成一个ros的工作空间的属性

catkin_init_workspace

2.2 编译工作空间

使用catkin_make指令会编译src文件夹下的所有功能包源码,根据你的配置进行编译,但是这样操作后只会产生build和devel两个文件夹,并没有产生install文件夹,需要单独执行catkin_make install才能产生

cd ~/catkin_ws/
# 编译工作空间
catkin_make

2.3 设置环境变量

为了让程序能找到这些可执行文件,所以需要设置环境变量

source devel/setup.bash

2.4 检查环境变量

echo $ROS_PACKAGE_PATH

ROS开发系列(1)- ROS基础知识_第2张图片

创建代码的时候一定要创建功能包,创建的代码一定要放在功能包中,不能放在src文件中。功能包的创建是要放在src文件夹中的

设置完环境变量之后,执行echo $ROS_PACKAGE_PATH 这个指令,检查下环境变量是否成功,只有设置成功环境变量之后,系统才能找到你创建的工作空间,以及工作空间下的功能包
ROS开发系列(1)- ROS基础知识_第3张图片

设置环境变量如下图,并检查是否成功

下图是在自己的电脑上测试的结果
ROS开发系列(1)- ROS基础知识_第4张图片

功能包中的两个重要文件,有这两个文件证明这个功能包创建成功了
ROS开发系列(1)- ROS基础知识_第5张图片

ROS开发系列(1)- ROS基础知识_第6张图片

如果后期需要添加依赖库的话 可以在这个文件中手动添加所需要的依赖包即可

流程:

通过功能包完成代码的组织,通过工作空间来完成功能包里的代码的编译和运行。注意在同一个工作空间中不能有同名的功能包。在不同的工作空间中,可以有同名的功能包

2.5 创建功能包

test_pkg:功能包的名字 可以自己定义

下面的参数都是这个功能包需要的一些依赖

  • std_msgs:标准消息结构
  • rospy:需要python
  • roscpp:需要C++
cd ~/catkin_ws/src
catkin_create_pkg test_pkg std_msgs rospy roscpp

2.6 编译功能包

只有设置环境变量,才能让系统找到工作空间,找到工作空间下的功能包这步很重要

可以将这句话添加到.bashrc文件中,这样就不用每次都使用这句话了,实际上就是配制下linux下的脚本的环境变量

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

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

2.7 package.xml文件

这个文件是用来描述跟这个功能包相关的信息,比如说功能包的名字,版本号,作者信息等等,开
园许可证类型,还有功能包所需要的依赖信息,如果缺少功能包的话就会报错,如果在创建功能包
的时候没有添加全依赖项,可以在这个文件中添加(build_depend\exec_depend)

2.8 CMakeList.txt文件

描述功能包的编译规则,使用的cmake语法

例如找到功能包,如何编译cpp代码,需要哪些库等等

CMakeList文件中需要添加需要build的文件信息,把哪个文件build成什么名字

添加链接库的名字

# 将cpp文件编译成名为velocity_publisher
add_executable(velocity_publisher src/velocity_publisher.cpp)

# 设置链接库  将velocity_publisher用到的相关的库链接起来
target_link_libraries(velocity_publisher ${catkin_LIBRARIES})

2.9 实现一个发布者的流程:

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

3.参数

1.这些Node可以不在同一个PC中,只要他们都在同一个ROS系统下就可以通过请求ROS Master中的Parameter Server来获取相应的参数。 可以理解为这些参数是全局变量。
ROS开发系列(1)- ROS基础知识_第7张图片

ROS开发系列(1)- ROS基础知识_第8张图片

  • RPC通信协议,
  • 在参数服务器中不适合存储动态数据,常用于存储静态数据,不进行更新的数据
  • ROS有动态参数配置的功能 是ROS的高级功能。

4.服务消息的定义

1.需要定义个srv的文件夹放在功能包的根目录下
ROS开发系列(1)- ROS基础知识_第9张图片

2.创建一个装在自定义服务消息的srv文件,放在srv文件夹下
ROS开发系列(1)- ROS基础知识_第10张图片

3.自定义数据的格式如下:
ROS开发系列(1)- ROS基础知识_第11张图片

注意:因为服务需要request和response两个 所以数据中用—来做隔离

4.在package文件下添加两个依赖包

message_generation</build_depend>
message_runtime</exec_depend>

ROS开发系列(1)- ROS基础知识_第12张图片

5.在CMakeLists.txt文件中添加如下指令 和在话题下自定义消息的步骤一样。
ROS开发系列(1)- ROS基础知识_第13张图片

//在Find catkin macros and libraries处 添加message_generation
find_package(catkin REQUIRED COMPONENTS
  geometry_msgs
  roscpp
  rospy
  std_msgs
  turtlesim
  message_generation
)
//在Declare ROS messages, services and actions部分 添加如下两行代码
add_service_files(FILES Person.srv)
generate_messages(DEPENDENCIES std_msgs)
//在catkin specific configuration部分 将注释的第三行打开 并添加message_runtime
catkin_package(
#  INCLUDE_DIRS include
#  LIBRARIES learning_service
   CATKIN_DEPENDS geometry_msgs roscpp rospy std_msgs turtlesim message_runtime
#  DEPENDS system_lib

6.在catkin_ws工作空间目录下打开终端,编译一下

catkin_make

编译过后会生成自定义消息对应C++语言和python等语言的相关源代码文件

7.编译过后会生成三个代码 在路径:/home/zerospace/catkin_ws/devel/include/learning_service
ROS开发系列(1)- ROS基础知识_第14张图片

跟对话消息产生的文件不太一样,那个只产生了一个文件,因为服务消息有请求和回复,在Person中包含另外两个文件的内容,因此在调用的时候只需要加载Person.h文件即可。

8.创建两个文件,一个客户端一个服务端程序

9.修改编译规则文件,添加如下代码:

add_executable(person_server src/person_server.cpp)
target_link_libraries(person_server ${catkin_LIBRARIES})
add_dependencies(person_server ${PROJECT_NAME}_gencpp)

add_executable(person_client src/person_client.cpp)
target_link_libraries(person_client ${catkin_LIBRARIES})
add_dependencies(person_client ${PROJECT_NAME}_gencpp)

注意:这里面的添加动态依赖使用的是_gencpp和之前topic中使用的_generate_messages_cpp不一样

10.编译运行程序即可。编译成功后会在路径:/home/zerospace/catkin_ws/devel/lib/learning_service
下生成对应的文件。如果编译失败的话在devel下的lib文件夹下是不会有文件生成的。

ROS开发系列(1)- ROS基础知识_第15张图片

5.语法

5.1 spin指令

在C++下有spin和spinones,可以监听一次队列信息也可以一直监听队列信息,当有回调函数的时候一定要使用这个指令,否则回调函数是接收不到数据的 在ROS中,是当spin这个指令执行的时候才会去检查队列,检查到有数据才会进入回调函数,不像中断那样直接进入回调。也就是说并不是有数据了就能立刻处理的 而是程序执行到spin的时候才执行。并且这个指令之后的程序都不执行了,因此用这个指令的时候不会放在循环while之类的语法中,因为有循环也不会执行。但使用spinone的指令的时候是会执行后面的指令的 可以放在循环中。当刷新速度是10HZ时,spin的刷新频率为5HZ时,队列必须至少有2个,这样才能保证不丢数据。

5.2 在Python中没有spinone这个指令

因此需要在单独开启一个线程来实现回调函数中对标志位等变量的处理。在21讲的视频server端代码实现中在回调函数中对标志位做了取反的指令,但是由于Python中没有执行一次回调的指令,导致不能在主函数加入循环 这时候就可以采用添加一个线程的方法实现。

5.3 固定的消息格式

geometry_msgs::Twist 是关于海龟的线速度和角速度

std_srvs::Trigger : 是关于出发的信号

pose : 是发送关于海龟的位置信号

6.客户端client实现

1.创建功能包

catkin_create_pkg learning_service roscpp rospy std_msgs geometry_msgs turtlesim

2.编写程序
ROS开发系列(1)- ROS基础知识_第16张图片

3.更改编译配置规则

add_executable(turtle_spawn src/turtle_spawn.cpp)   # 将cpp文件编译为可执行文件
target_link_libraries(turtle_spawn ${catkin_LIBRARIES}) # 连接可执行文件所需的库文件

4.在catkin_ws下编译工作空间

catkin_make

编译后在/home/zerospace/catkin_ws/devel/lib/learning_service下生成一个可执行文件。
ROS开发系列(1)- ROS基础知识_第17张图片

5.由于设置过环境变量了,这里就不用检查环境变量了

6.在终端运行程序观察程序输出

7.话题消息的定义与使用

1. 创建一个msg的文件夹,跟消息相关的都放在这里面
ROS开发系列(1)- ROS基础知识_第18张图片

2.创建一个Person.msg的文件(文件名自己定义
ROS开发系列(1)- ROS基础知识_第19张图片

3.在Person.msg文件中输入自己定义的消息信息
ROS开发系列(1)- ROS基础知识_第20张图片

这里面的uint8 string等并不是C语言中的真实代码,会在编译的时候根据c++和python生成对应的真实数据格式代码,例如在c++中uint8生成为char格式,python生成为对应的数据格式(python中没有char型数据)

4.在package.xml文件中添加如下指令:生成功能包的依赖关系

message_generation</build_depend>
message_runtime</exec_depend>

ROS开发系列(1)- ROS基础知识_第21张图片

5.在CMakeLists.txt文件中添加功能包的依赖,以及将消息结构生成对应源代码的功能。并且添加运行依赖 message_runtime (这都是为了生成自定义的消息结构而做的工作)
ROS开发系列(1)- ROS基础知识_第22张图片

message_runtime这个依赖包在catkin_package中添加。
ROS开发系列(1)- ROS基础知识_第23张图片

ROS开发系列(1)- ROS基础知识_第24张图片

6.在catkin_ws文件夹下编译(编译过后仅仅是将自己定义的消息结构生成完成了)
ROS开发系列(1)- ROS基础知识_第25张图片

7.编译后在/home/zerospace/catkin_ws/devel/include/learning_topic这个文件夹下会有一个Person.h的文件,这个就是将我们自定义的消息结构生成了对应的代码。感兴趣可以看一下

8.编译后编写发布者和订阅者代码,将代码放在/home/zerospace/catkin_ws/src/learning_topic/src下

9.配置代码编译规则

在build的地方添加如下六行代码:

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)

其中第三行代码的作用:在使用自定义消息的时候必须要添加这行代码,是因为我们的自定义消息很多代码是动态生成的。使可执行文件(person_publisher)和动态生成的代码产生依赖关系。
ROS开发系列(1)- ROS基础知识_第26张图片

10.分别在三个终端中执行下列代码

roscore
rosrun learning_topic person_publisher
rosrun learning_topic person_subscriber

11.这时候就可以在发布者和订阅者的终端中看到消息了

注意:这时候如果将roscore的终端关闭会有什么效果呢?

关闭后发布者和订阅者终端仍然可以相互传递消息。这是因为roscore相当于rosmaster,只是用来给发布者和订阅者建立连接关系的,就像婚姻中介所,只是给不认识的一男一女安排个见面的机会而已。等见面后就可以不需要中介所了。但是当这时候添加另一个节点的话 这个发布者和订阅者是不可以和新添加的节点进行通信的,因为这时候已经没有了rosmaster了。

8.发布者程序的编写方法及流程

创建一个发布者程序:
ROS开发系列(1)- ROS基础知识_第27张图片

创建一个自动执行小海龟的程序的流程

  1. 创建一个功能包 在src文件夹下使用指令:catkin_create_pkg learning_topic roscpp rospy std_msgs geometry_msgs turtlesim

  2. 创建发布者代码,使用c++或者python语言编写代码

  3. 编译代码之前需要先配置发布者代码编译规则
    ROS开发系列(1)- ROS基础知识_第28张图片

    在src下的功能包文件夹下的CMakeLists.txt文件中修改编译规则
    ROS开发系列(1)- ROS基础知识_第29张图片
    第一句指令是:把.CPP程序文件编译成哪个可执行文件的

    第二句指令是:帮助我们把可执行文件和ROS的相关库建立链接的,将可执行文件和catkin_libraries建立连接

  4. 在工作空间文件夹下(注意不能再src文件夹下)编译工作空间

  5. 编译后检查环境变量,这里有两种方法实现:1.通过指令:source devel/setup.bash来建立,然后使用指令:echo $ROS_PACKAGE_PATH来检查 2.通过使用一劳永逸的方法,在主目录下按CTRL+H 显示隐藏文件,打开.bashrc文件,在文件的最后加上sourc /home/zerospace/catkin_ws/devel/setup.bash,这时需要重新启动终端才生效

  6. 在终端中运行learning_topic velocity_publisher这个指令就可以将发布者程序执行了 相当于是运行在功能包learning_topic下的velocity_publisher这个程序

9.ROS技巧

9.1 查找资料的几个方法

  • 善用搜索工具(google)

  • wiki.ros

  • ros QQ群,社区等资源

  • 博客

9.2 rqt开头的都是一些用QT开发的可视化的工具。

ROS开发系列(1)- ROS基础知识_第30张图片

9.3 rosnode是查看节点相关的命令行的工具,用于观察ROSnode的相关信息。都以ROS开头

ROS开发系列(1)- ROS基础知识_第31张图片

注意这里面的三个节点和上图的QT可视化出来的节点不太一样 多了一个rosout,这个节点是启动roscore之后就会开启的,默认开启的 用于输出日志信息的,用于ros显示使用的,不用管。

9.4 使用rosnode info 指令实现信息查看

ROS开发系列(1)- ROS基础知识_第32张图片

9.5 rostopic 查看关于话题相关的信息

ROS开发系列(1)- ROS基础知识_第33张图片

pub指令是发布命令给话题,主动发送数据

注意:这条指令只是发布一次数据

9.6 以一定的速率发送数据

ROS开发系列(1)- ROS基础知识_第34张图片

9.7 rosmsg的使用

ROS开发系列(1)- ROS基础知识_第35张图片

9.8 rosservice的使用

ROS开发系列(1)- ROS基础知识_第36张图片

通过这个指令之后生成了一个新的海龟,这个时候可以用topic指令操作新的海龟。
ROS开发系列(1)- ROS基础知识_第37张图片

9.9 rosbag的操作:

用于存储数据,进行数据回放功能,例如一个无人机飞一次之后就可以调用这个数据包来复现无人机的状态了

指令:rosbag record -a -O cmd_record

指令的参数详细介绍可以使用 rosbag record -help来查看

参数介绍:-a 记录所有数据

-O 大写的字母o 将数据保存到一个压缩包,后面跟压缩包的名字。 文件存储在主目录中

下图记录了小乌龟的数据
ROS开发系列(1)- ROS基础知识_第38张图片

将键盘控制及小乌龟都关掉,重新打开小乌龟的节点,然后使用 rosbag play cmd_record

就可以复现刚才用键盘控制小乌龟的路径了。
ROS开发系列(1)- ROS基础知识_第39张图片

9.10 话题与服务的区别

ROS开发系列(1)- ROS基础知识_第40张图片

当需要配置一些参数时,用服务的方式进行。

当传输数据信息的时候使用话题的方式进行

9.11 ROS命令行工具

ROS开发系列(1)- ROS基础知识_第41张图片

10 注意事项:

  1. 在ros中运行python文件的时候需要注意python的可执行权限,必须具有可执行权限才能运行。
  2. 编译完程序后,在catkin_ws/devel/lib/功能包的名字/有一个可执行文件, 这个文件就是编译生成的可执行的文件,相当于window下的exe文件
  3. 在每次执行一个新的程序的时候重新启动下roscore,因为roscore中存有很多参数,容易两个程序的参数名相同或者其他的原因,导致程序原来好使现在不好使的情况。因此需要重启下roscore
  4. 在python库中没有rosspinone这个指令,因此想要监听server的话,当server中有变化的时候进行按照一定频率更新发布者节点的话 就需要创建一个线程来实现在C++中的rospinones的功能。有rosspinone的话就可以在主函数中进行按照一定频率进行循环的操作了。
  5. 在运行新的程序的时候最好将roscore关闭重新打开一下,因为roscore中有很多参数,如果运行多个程序时候可能容易由于参数名相同或者其他一些原因使得原来好使的程序也变得不好使了。
  6. 执行服务时,只有启动了的服务在执行rosservice call指令的之后才能找到与启动的服务相对应的命令。
    ROS开发系列(1)- ROS基础知识_第42张图片

参考

ROS调试常用命令
古月居21讲

你可能感兴趣的:(ROS开发系列,linux)