Halo,这里是Ppeua。平时主要更新C语言,C++,数据结构算法…感兴趣就关注我吧!你定不会失望。
roscore 启动ros核心节点
roscd 将工作空间切换到指定ros功能包
catkin_create_pkg 将工作空间切换到指定ros功能包
**rqt_graph 启动节点间的关系图
rosrun 包名 节点名称 启动节点(rosrun turtlesim turtlesim_node)roslaunch 包名 launch文件名称 启动Launch文件
比较常用的目前就这一些,之后的命令现用现学就好了
在ros中,机器人的各个部件(雷达|摄像头等部件)相互之间通信需要用到一种通信方式:话题通信,其理论模型为
这里有一个简单的定义:订阅方与发布方通过同一个话题连接起来相互,发布方提供消息,订阅方获得消息,是一个单向的过程,虽然在这过程中似乎没有出现ros master这个角色,但发布方向订阅方第一次发送消息需要经过rosmaster,再到订阅方.(从上图也可以看出),在此之后就不需要rosmaster了
订阅方与与发布方都可以有多个,启动也无先后顺序
这里我们采用python实现,在接触到的机器人二次开发中大多用的都是python
当然,二者思想差不多,且ros当中用不同语言写的各个节点之间也是可以直接互相通信的
先来分析下需求
接下来总体描述下如何写这段程序,
import rospy
from std_msgs.msg import String
rospy.init_node("pub")
pub=rospy.Publisher("che",String,queue_size=10)
msg=String()
rate=rospy.Rate(1)
i=0
while not rospy.is_shutdown():
msg.data="hello "+(str)(i)
pub.publish(msg)
i+=1
rospy.loginfo(msg.data)
rate.sleep()
最后为这个py文件加上可执行权限,在当前功能包路径下的CMakelist中将刚刚的python文件添加到这里
( 并在catkin_ws也就是ros根目录空间下执行source ./devel/setup.bash)在终端执行rosrun 包名 话题名即可运行
这就是话题通信的发布方实现,接下来我们再来看看订阅方是如何实现的
接下来总体描述下如何写这段程序,
import rospy
from std_msgs.msg import String
def callback(msg):
rospy.loginfo(msg.data)
rospy.init_node("sub")
sub=rospy.Subscriber("che",String,callback,queue_size=10)
rospy.spin()
最后为这个py文件加上可执行权限
在当前功能包路径下的CMakelist中将刚刚的python文件添加到这里(在noetic版本之前不需要执行这一步操作)
并在catkin_ws也就是ros根目录空间下执行source ./devel/setup.bash
在终端执行rosrun 包名 话题名即可运行并编译一下
我们也尝试运行下这个代码,方法与上文相同
成功啦,这就是利用标准消息参数进行话题通信。
数据载体是一个较为重要组成部分,ROS 中通过 std_msgs 封装了一些原生的数据类型,比如:String、Int32、Int64、Char、Bool、Empty… 但是,这些数据一般只包含一个 data 字段,结构的单一意味着功能上的局限性,当传输一些复杂的数据,比如: 激光雷达的信息… std_msgs 由于描述性较差而显得力不从心,这种场景下可以使用自定义的消息类型
这部分内容主要代码是与上文相同,仅将std_msgs.msg替换成了自己设定的库,所以主要是修改配置文件的过程。
创建一个.msg的消息类型,我这里的名字是Person.msg,里面有三个标准类型
string name
int32 age
float32 height
在功能包目录下的package.xml中加入这两行(54与59)
其中54行的message_generation是编译时的消息软件包
而59行message_runtime是运行时的消息软件包
在CMakeList中找到这些地方并修改
find_package(catkin REQUIRED COMPONENTS
rospy
std_msgs
message_generation
)
# 需要加入 message_generation,必须有 std_msgs
## 配置 msg 源文件
add_message_files(
FILES
Person.msg
)
# 生成消息时依赖于 std_msgs
generate_messages(
DEPENDENCIES
std_msgs
)
#执行时依赖
catkin_package(
CATKIN_DEPENDS rospy std_msgs message_runtime
)
编译一下 可以在/工作空间/devel/lib/python3/dist-packages/包名/msg找到刚刚生成的消息类型
之后要使用在这个消息包可以直接在代码中导入就可以了
# from ros包名.msg import 消息名称
from lesson2.msg import Person
实现方法与之前的标准消息类型话题通信相同,仅在消息内容定义不同,所以这里就不过多赘述。
消息类型初始化的成员名与自定义消息类型中的成员名相同似乎有点废话hhhh
import rospy
from lesson2.msg import Person
rospy.init_node("pub_person")
pub=rospy.Publisher("che",Person)
p=Person()
p.name="奥特曼"
p.age=8
p.height=1.5
rate=rospy.Rate(1)
while not rospy.is_shutdown():
pub.publish(p)
rate.sleep()
rospy.loginfo("%s,%d,%f",p.name,p.age,p.height)
from lesson2.msg import Person
import rospy
def doMsg(p):
rospy.loginfo("%s,%d,%.2f",p.name,p.age,p.height)
rospy.init_node("sub_person")
#话题通信的话题必须与发布方相同
sub=rospy.Subscriber("che",Person,doMsg)
rospy.spin()
最后配置下CMakeList就可以运行了(在noetic版本之前不需要执行这部操作)
rosrun lesson2 demo02_pub.py
rosrun lesson2 demo02_sub.py
成功啦,这就是利用自定义参数进行话题通信。