ROS学习笔记(2)

目标:发布nav_msgs/Path消息,并在rviz中画出圆形轨迹(Python)

首先,用rosmsg show 命令,查看nav_msgs/Path的消息结构。

# //nav_msgs/Path数据类型
# Header header
# geometry_msgs/PoseStamped[] poses
# //类型扩展:
# Header header
#     uint32 seq
#     time stamp
#     string frame_id
# geometry_msgs/PoseStamped[] poses
#     Header header
#         uint32 seq
#         time stamp
#         string frame_id
#     geometry_msgs/Pose pose
#         geometry_msgs/Point position
#             float64 x
#             float64 y
#             float64 z
#         geometry_msgs/Quaternion orientation
#             float64 x
#             float64 y
#             float64 z
#             float64 w

 可以看到nav_msgs/Path分为两层,一层是Header,一层是geometry_msgs/PoseStamped,其中geometry_msgs/PoseStamped是以数组形式发布,因此我们在编写Python程序时应该import两个消息类型

from nav_msgs.msg import Path

from geometry_msgs.msg import PoseStamped

 以及需要用到的包

import rospy

import math

from tf.transformations import quaternion_from_euler   #欧拉转四元数

定义发布函数pub_o_path():

def pub_o_path():

    #定义发布者,应该注意的是发布的消息类型始终为Path,Path之下的消息类型geometry_msgs/PoseStamped只是用于赋值,而不是使用PoseStamped发布

    pub_path = rospy.Publisher("path_pubulisher", Path, queue_size = 10)

    msg = Path()

    #指定frame_id和stamp,frame_id是在rviz显示的时候会用到,需要在rviz中fixed frame位置输入你定义的frame_id,这里使用rviz默认的map

    #stamp是时间辍,看了很多例子一般是使用rospy.Time.now(),不知道还有没有其他的设定,挖个坑。

    msg.header.frame_id = "map"

    msg.header.stamp =  rospy.Time.now()

    rate = rospy.Rate(10)

    #由于是定义了一个做圆周的物体,因此还需要给它一些初始值

    x = 0.0

    y = 0.0

    th = 0.0

    vx = 0.1

    vy = -0.1

    vth = 0.1

    #开始循环发布消息

    while not rospy.is_shutdown():

        #定义求出圆的运动方程,并保存经过的点

        dt = 0.1

        delta_x = (vx * math.cos(th) - vy * math.sin(th)) * dt

        delta_y = (vx * math.sin(th) + vy * math.cos(th)) * dt

        delta_th = vth * dt

        x += delta_x

        y += delta_y

        th  += delta_th

        #定义一个变量对PoseStamped进行赋值

        #再次强调,应该注意的是发布的消息类型始终为Path,Path之下的消息类型geometry_msgs/PoseStamped只是用于赋值,而不是使用PoseStamped发布

        pose = PoseStamped()

        pose.pose.position.x = x

        pose.pose.position.y = y

        #由于th是用欧拉角表示,而PoseStamped中是用四元数表示角度用的,因此需要将th转换为四元数表示

        quaternion = quaternion_from_euler(0,0,th)

        pose.pose.orientation.x = quaternion[0]

        pose.pose.orientation.y = quaternion[1]

        pose.pose.orientation.z = quaternion[2]

        pose.pose.orientation.w = quaternion[3]

        #之前提到过PoseStamped消息类型是以列表的形式保存,因此需要将坐标和角度信息保存保存至msg中:

                # //nav_msgs/Path数据类型

                # Header header

                # geometry_msgs/PoseStamped[] poses

        msg.poses.append(pose)

        #发布消息

        pub_path.publish(msg)

        rospy.loginfo("x = {}, y = {}, th = {}".format(x, y, th))

        rate.sleep()

至此函数主体编写完成,再加个主函数。PS:我喜欢把init_node放在主函数中,大佬别喷。

if __name__ == "__main__":
    rospy.init_node("show_path", anonymous=True)
    try:
        pub_o_path()
    except rospy.ROSInterruptException:
        pass

程序运行后,运行rviz,在add中按Topic查找,找到你发布的Topic并添加进来即可

这里需要注意的有几点:

1、如果要对某个消息进行操作,需要将这个消息用一个变量代替,然后再进行操作,如:

msg = Path()

pose = PoseStamped()

我也不知道为啥不能直接操作,如不能使用Path.poses.pose.position.x = x ,而是用的pose.pose.position.x = x,如果直接用前者这种会报错

Traceback (most recent call last):
  File "/home/xxx/ProjectSet/Pycharm/Ros/catkin_ws/src/path/src/o.py", line 78, in <module>
    pub_o_path()
  File "/home/xxx/ProjectSet/Pycharm/Ros/catkin_ws/src/path/src/o.py", line 58, in pub_o_path
    Path.poses.pose.position.x = x
AttributeError: 'member_descriptor' object has no attribute 'pose'

2、获得的坐标以及四元数,后要其存入msg(也就是Path())的列表中

msg.poses.append(pose)

3、发布消息是发布Path(),而不是发布PoseStamped()

 pub_path.publish(msg)

 

本人刚开始学习ROS,如果有不对的地方,请大佬们不吝赐教,谢谢。

参考资料:

https://blog.csdn.net/u013834525/article/details/80447931

https://blog.csdn.net/ktigerhero3/article/details/70256437

https://www.programcreek.com/python/example/70252/geometry_msgs.msg.PoseStamped

 

 

 

 

 

 

 

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值