当前位置:   article > 正文

【日知录17】ROS初识_make -j2 -l2baozuo

make -j2 -l2baozuo

ps:在b站发现另一个学习视频更详细更清楚,且搭建环境也很友好。赵虚左老师

1.关于ROS通信机制的一些理解

ROS wiki

在这里插入图片描述
在通信机制方面,有两种通信形式,话题(Topic)和服务(Service)。

话题(Topic)

异步通信,可以理解为给别人发邮件,只能单向传输。
在这里插入图片描述

在这里插入图片描述
节点在Node

服务(Service)

在这里插入图片描述

两种通讯机制的比较

在这里插入图片描述

理解层级关系
在这里插入图片描述

2.代码实现

在这里插入图片描述

2.1话题

发布者publisher

给海龟设定运动速度,角度。Twist()

1.创建功能包 包含依赖项
2.创建发布者代码.cpp
3.配置CMakelist.txt中的编译规则

add_executable(velocity_publisher src/velocity_publisher.cpp)
target_link_libraries(velocity_publisher ${catin_LIBRARIES})
  • 1
  • 2

注意:这里的 src/velocity_publisher.cpp 就是在第二步中ubuntu中写入的.cpp文件的文件名。如果此处文件名或者路径不对,会产生CMake相关报错。

4.编译和运行发布者
一共需要运行6个指令。

$ cd ~/catkin_ws //在catkin_ws文件夹内进行操作,也可以直接找到这个文件夹后,右键,在终端打开。
$ catkin_make    //编译,十分重要的一步,也很容易产生错误。
  • 1
  • 2

简要分析一下第二步报错的解决,
1.如果是Camke错误,找到报错的对应行,然后看看文件名是否正确。
2.如果是自己手打的.cpp文件,可能存在一些名称错误,要自查。
3.在创建publisher之后,发布的topic的名称不对,如下图,括号内就是 这个topic的名称。
在之前的尝试中,我写成了

(“/turtle/cmd_vel”,10);
这个就是小海龟的对应名称。但是会报错。所以我又改成了
(“/turtle1/cmd_vel”,10); 注此处的修改时加了一个数字1。即第一个小海龟的意思。
这样之后再重新编译,即 $ catkin_make。成功

在这里插入图片描述

如果是这种错误:Invoking:"make -j2 -l2"failed 那么建议自查一遍cpp文件是否有格式,拼写错误
在这里插入图片描述

接下来继续进行指令运行

 $ source devel/setup.bash 
 $ roscore  
 $ rosrun turtlesim turtlesim_node  
 $ rosrun learning_topic velocity_publisher 
  • 1
  • 2
  • 3
  • 4

如下图所示就是成功运行的。
如果出现,代码一直跑,但小海龟不动的情况,参考上面我说的修改小海龟的名称这种方法。

在这里插入图片描述

订阅者subscriber

遇到过修改输出格式x,y坐标之后,一直没有同时显示两个坐标,之后通过重新catkin_make之后,成功输出x,y两个坐标。
订阅海龟的x.y 坐标并显示,pose()

自定义话题

即自定义话题消息类型。
如何自定义数据,此处以自定义话题消息messages,自定义服务数据services这两种情况为例分析。
1.对编译文件的创建,变成不同的C++,python,完成数据接口定义
messages就新建msg文件夹
services就新建svc文件夹

2.对编译规则的设置,即对添加功能包依赖

################################################
## Declare ROS messages, services and actions ##
################################################

## To declare and build messages, services or actions from within this           //为了声明消息,服务,动作。需要做以下操作
## package, follow these steps:
## * Let MSG_DEP_SET be the set of packages whose message types you use in        //1.确保在创建工作空间时有依赖这些包
##   your messages/services/actions (e.g. std_msgs, actionlib_msgs, ...).
## * In the file package.xml:													//2.在package.xml文件中完成以下操作
##   * add a build_depend tag for "message_generation"    
##   * add a build_depend and a exec_depend tag for each package in MSG_DEP_SET
##   * If MSG_DEP_SET isn't empty the following dependency has been pulled in
##     but can be declared for certainty nonetheless:
##     * add a exec_depend tag for "message_runtime"

//所以有在xml文件中添加的这两行依赖
 <build_depend>message_generation</build_depend>  //编译依赖
  <exec_depend>message_runtime</exec_depend> ///执行依赖


## * In this file (CMakeLists.txt):                 //3.在Cmakelist文件中,需要做以下操作
##   * add "message_generation" and every package in MSG_DEP_SET to  //添加message_generation和每个在MSG_DEP_SET的包到find_package
##     find_package(catkin REQUIRED COMPONENTS ...)
##   * add "message_runtime" and every package in MSG_DEP_SET to//添加message_runtime和每个在MSG_DEP_SET的包到catkin_package
##     catkin_package(CATKIN_DEPENDS ...)
##   * uncomment the add_*_files sections below as needed//没有在下面add_列出的部分,需要列出每个.msg .srv .action以保证被可以执行
##     and list every .msg/.srv/.action file to be processed
##   * uncomment the generate_messages entry below
##   * add every package in MSG_DEP_SET to generate_messages(DEPENDENCIES ...)

## Generate messages in the 'msg' folder  //列出部分add定义的格式,包括 message,service,action,
# add_message_files(
#   FILES
#   Message1.msg
#   Message2.msg
# )

## Generate services in the 'srv' folder
# add_service_files(
#   FILES
#   Service1.srv
#   Service2.srv
# )

## Generate actions in the 'action' folder
# add_action_files(
#   FILES
#   Action1.action
#   Action2.action
# )

## Generate added messages and services with any dependencies listed here //创建依赖
# generate_messages(
#   DEPENDENCIES
#   geometry_msgs#   std_msgs
# )


add_message_files(
  FILES
  Person.msg
)

generate_messages(
  DEPENDENCIES
  std_msgs
)

//因此在cmakelist中进行这些操作
find_package(... message_generation)

add_message_files( FILES  Person.msg)
generate_messages( DEPENDENCIES std_msgs)
catkin_package(... message_runtime)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74

理解Cmakelist里面的 Declare ROS messages,services and actions
同理,理解自定义服务数据。

在这里插入图片描述

C++
在这里插入图片描述
遇到过的编译报错,检查Cmakelist。

add_executable cannot create target"person_publisher" because another target with the same name already exists.
the existing target is an executable created in source directory
  • 1
  • 2

原因是重复添加了add_executable(),导致重复编译。

python运行时的报错,暂未解决。应该是和数据输出格式有关系。

在这里插入图片描述

比较

在这里插入图片描述

不理解这里代码的count=0是什么意思。

在这里插入图片描述

//订阅者不知道什么时候会有消息进来,
//所以此处有回调函数poseCallback,一旦有消息进来则通过回调函数打印数据
    ros::Subscriber pose_sub = n.subscribe("/turtle1/pose", 10, poseCallback);

    // 循环等待回调函数,spin()会不断查看消息队列,是否有消息进入,有则调用poseCallback()
    ros::spin();
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
const turtlesim::Pose::ConstPtr& msg//C++常指针,类型名 turtlesim::Pose
  • 1

What is ConstPtr&?

int main( argc **argv)的理解

综合以上两点,我看到弹幕里很多在问,为什么输出的时候用的是

ROS_INFO(“Turtle pose: x:%0.6f, y:%0.6f”, msg->x, msg->y);

其中的原因主要于指针有关。
我尝试将输出直接改成 msg.x msg.y,出现报错。
在这里插入图片描述
可以看出来应该是与回调函数中的指针输出格式有关系,所以查阅了C书中“指向结构体类型数据的指针”之后,明确输出格式。C++书中解释和这个类似。

this->height 
(*this).height  //.的优先级高于*,因此*this.height 相当于*(this.height)
  • 1
  • 2

在这里插入图片描述
所以修改了指针
在这里插入图片描述
进一步思考,如果发送的是多个人的信息要怎么实现?即topic多发
单节点的多Topic同时收发
使用了数组,字符串

2.2服务

在catkin_make中的错误,一般是Cmakelist里面找。

Could NOT find std_msgs geometry_msgs
  • 1

百度之后说是缺少包,所以我又重新创建了一遍工作空间,估计是少依赖一个包。重新创建工作空间之后问题解决。成功创建第二个小海龟。

client

对于python版本实现,确实存在一些难度,比如古月居的视频是python2,而我目前是python3,在一些语法上会存在差异,总有这样那样的错误。

在这里插入图片描述
在这里插入图片描述
如何生成多个小海龟

server

在这里插入图片描述

因为本例只对server端进行编译,所以在最后程序实现时,通过rosservice call命令来调用服务
理解服务端的工作流程,初始化ROS节点,创建server实例/turtle_command ,创建publisher,通过发布消息使小海龟运动。显示“Ready to receive turtlr command”。在while循环中通过spinOnce()查看回调函数队列。
此时在终端通过rosservice call命令来调用/turtle_command服务,服务器开始调用回调函数,先将pubCommad标志位取反,显示“publish turtle velocity command [yes/no]”,返回显示“change turtle command state ”“success:true”
if判断,是否将话题消息发布给海龟仿真器,是则小海龟运动,否则小海龟停止。

在这里插入图片描述

自定义

在这里插入图片描述

理解一下这个客户端与服务端的工作流程。
服务端程序中,先执行创建服务端中的show_person服务,显示“Ready to show person information”之后循环等待回调函数,请求服务调用。
此时客户端程序中,ros::service::waitForService(“/show_person”)发现了/show_person服务,此时创建客户端名为/show_person,对数据进行初始化,之后请求/show_person服务调用,并显示“Call service to show person[name:Tom,age:20,sex=11]”,通过add_turtle.call(srv)将封装好的数据发送出去,并且一直在等待回复。
此时服务端的ros::spin()检查到队列中的数据,调用回调函数personCallback(),显示"Person: name :Tom age:20 sex:1",并将结果res.result=“OK"返回给客户端中的add_turtle.call(srv)。
客户端继续运行,显示"Show person result:OK”

在这里插入图片描述

比较

在这里插入图片描述

rospy

借鉴某博主对于rospy库的一些理解

rospy创建和初始化一个node,不再需要NodeHandle(rospy没有设计NodeHandle这个句柄),创建topic、service等操作都直接用rospy里对应的方法即可。
rospy节点的初始化补衣服ing必须放在开头,在Publisher建立后再初始化也可以。
消息的创建更加简单,例如gps类型的消息可以直接用类似与构造函数的方式gps(state,x,y)创建。
日志的输出方式不同,C++是ROS_INFO(),Python中为rospy.loginfo()。
判断节点是否关闭的函数不同,C++为ros::ok(),Python为rospy.is_shutdown()。

在这里插入图片描述

2.3参数使用

相当于在工作空间内的参数字典

rosparam list
rosparam get param_key
rosparam set param_key param_value
rosparam dump file_name
rosparam load file_name
rosparam delete param_key
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

2.4 tf

机器人坐标变换的3种可视化方法

rosrun tf view_frames
  • 1

遇到bug:TypeError: cannot use a string pattern on a bytes-like object
修改办法
显示图表
在这里插入图片描述

rosrun tf tf-rcho turtle1 turtle2
  • 1

在这里插入图片描述

rosrun rviz rviz -d`rospack find turtle_tf`/rviz/turtle_rviz.rviz
  • 1
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/你好赵伟/article/detail/665990
推荐阅读
相关标签
  

闽ICP备14008679号