赞
踩
ps:在b站发现另一个学习视频更详细更清楚,且搭建环境也很友好。赵虚左老师
在通信机制方面,有两种通信形式,话题(Topic)和服务(Service)。
异步通信,可以理解为给别人发邮件,只能单向传输。
节点在Node
理解层级关系
给海龟设定运动速度,角度。Twist()
1.创建功能包 包含依赖项
2.创建发布者代码.cpp
3.配置CMakelist.txt中的编译规则
add_executable(velocity_publisher src/velocity_publisher.cpp)
target_link_libraries(velocity_publisher ${catin_LIBRARIES})
注意:这里的 src/velocity_publisher.cpp 就是在第二步中ubuntu中写入的.cpp文件的文件名。如果此处文件名或者路径不对,会产生CMake相关报错。
4.编译和运行发布者
一共需要运行6个指令。
$ cd ~/catkin_ws //在catkin_ws文件夹内进行操作,也可以直接找到这个文件夹后,右键,在终端打开。
$ catkin_make //编译,十分重要的一步,也很容易产生错误。
简要分析一下第二步报错的解决,
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
如下图所示就是成功运行的。
如果出现,代码一直跑,但小海龟不动的情况,参考上面我说的修改小海龟的名称这种方法。
遇到过修改输出格式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)
理解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
原因是重复添加了add_executable(),导致重复编译。
python运行时的报错,暂未解决。应该是和数据输出格式有关系。
不理解这里代码的count=0是什么意思。
//订阅者不知道什么时候会有消息进来,
//所以此处有回调函数poseCallback,一旦有消息进来则通过回调函数打印数据
ros::Subscriber pose_sub = n.subscribe("/turtle1/pose", 10, poseCallback);
// 循环等待回调函数,spin()会不断查看消息队列,是否有消息进入,有则调用poseCallback()
ros::spin();
const turtlesim::Pose::ConstPtr& msg//C++常指针,类型名 turtlesim::Pose
综合以上两点,我看到弹幕里很多在问,为什么输出的时候用的是
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)
所以修改了指针
进一步思考,如果发送的是多个人的信息要怎么实现?即topic多发
单节点的多Topic同时收发
使用了数组,字符串
在catkin_make中的错误,一般是Cmakelist里面找。
Could NOT find std_msgs geometry_msgs
百度之后说是缺少包,所以我又重新创建了一遍工作空间,估计是少依赖一个包。重新创建工作空间之后问题解决。成功创建第二个小海龟。
对于python版本实现,确实存在一些难度,比如古月居的视频是python2,而我目前是python3,在一些语法上会存在差异,总有这样那样的错误。
因为本例只对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创建和初始化一个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()。
相当于在工作空间内的参数字典
rosparam list
rosparam get param_key
rosparam set param_key param_value
rosparam dump file_name
rosparam load file_name
rosparam delete param_key
机器人坐标变换的3种可视化方法
rosrun tf view_frames
遇到bug:TypeError: cannot use a string pattern on a bytes-like object
修改办法
显示图表
rosrun tf tf-rcho turtle1 turtle2
rosrun rviz rviz -d`rospack find turtle_tf`/rviz/turtle_rviz.rviz
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。