栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Python

Rviz路径绘制 + 三维机械臂RRT算法实例

Python 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Rviz路径绘制 + 三维机械臂RRT算法实例

任务描述:实现在Rviz中对机械臂末端轨迹的绘制
实现方法:先将路径点存在事先定义好的路径变量中,以话题的形式发布出去。在RVIZ中添加可视化组件“path”,订阅路径话题。
1.包含头文件

#include

2.以话题发布的形式发布

int main(int argc, char *argv[])
{
    ros::init(argc,argv,"showpath");
    ros::NodeHandle nh;
    ros::Publisher path_pub = nh.advertise("Path",1,true);
    double position[5][3] = {{0,0,0},{0.5,0.10,0.5},{0.7,0.6,0.15},{0.20,0.16,0.30},{0.10,0.20,0.30}};
    nav_msgs::Path path;
    path.header.frame_id = "world";
        for(int i=0;i<5;i++){
            geometry_msgs::PoseStamped point;
            point.pose.position.x = position[i][0];
            point.pose.position.y = position[i][1];
            point.pose.position.z = position[i][2];
            path.poses.push_back(point);
        }
    while(ros::ok()){
        path_pub.publish(path);
        ros::spinOnce();
    }
    return 0;
}

3.添加可视化组件

4.订阅话题

————————————————————分割线————————————————————
上面的方法虽然可以实现路径的显示,但我个人感觉大多数时候还是用在实时路径规划上比较方便,毕竟有时间戳的存在。然而,对于RRT这种离线搜索,并且在储存结构上离散的路径绘制来说很困难。下面推荐一种利用Marker的路径绘制方法

1.效果图

2.RRT算法原理

RRT算法原理很简单,参考这篇:RRT算法(快速拓展随机树)的Python实现
另外,虽然本文使用python实现的,想用C++实现,步骤基本一致,只需把一些消息定义进行修改

3.实现过程

流程概述:

  1. 定义存储随机树节点的变量(RRT_marker)
  2. 创建话题的发布者(rrtMarker_pub)用来发布RRT_marker
  3. 在RRT算法中增加节点push算法
3.1 定义存储结构RRT_marker

1.导入Marker消息类型

from visualization_msgs.msg import Marker     //树的数据类型
from geometry_msgs.msg import Point			//节点的数据类型

2.创建并初始化树

rrtMarker = Marker()
rrtMarker.header.frame_id = "world"   		//参考坐标系
rrtMarker.type = Marker.LINE_LIST			//标记样式,有序点集
rrtMarker.color.g = 1.0						//颜色RGB值
rrtMarker.color.a = 1.0						//透明度
rrtMarker.scale.x = 0.001					//标记大小
rrtMarker.pose.orientation.w = 1.0			//方向。如果是箭头,圆柱等样式的标记可能会用到
rrtMarker.lifetime = rospy.Duration()		//(没用明白)

博主在想能不能利用lifetime属性摆脱不得不使用循环发布话题的做法,但是没成功,如果有人成功可以交流交流。
关于Marker消息更详细的信息

uint8 ARROW=0
uint8 CUBE=1
uint8 SPHERE=2
uint8 CYLINDER=3
uint8 LINE_STRIP=4
uint8 LINE_LIST=5
uint8 CUBE_LIST=6
uint8 SPHERE_LIST=7
uint8 POINTS=8
uint8 TEXT_VIEW_FACING=9
uint8 MESH_RESOURCE=10
uint8 TRIANGLE_LIST=11

uint8 ADD=0
uint8 MODIFY=0
uint8 DELETE=2
uint8 DELETEALL=3

Header header                        # 时间和坐标系信息
string ns                            # 这些markers的名称空间。这给marker加上一个唯一的id
int32 id                             # 分配给marker的唯一的id。
int32 type                         # maker的类型。可用的类型在消息定义中有说明
int32 action                           # 0=add/modify an object, 1=(deprecated), 2=deletes an object, 3=deletes all objects
geometry_msgs/Pose pose                 # marker的位姿,内容是3维坐标和一组方向四元数
geometry_msgs/Vector3 scale             # marker的尺寸,在位姿/方向之前应用,[1,1,1]意思是尺寸是1m*1m*1m
std_msgs/ColorRGBA color             # 物体的颜色,由r/g/b/a指定,取值范围是[0,1]。不要忘记设置a否则它会默认是0,导致marker不可见。
duration lifetime                    # 一个区间值,在这段时间之后自动删除marker,这个向下计数器被重置,如果另一个同样namespace/id 的marker被接收到时。0的意思是不会删除这个marker
bool frame_locked                    # 告知rviz每次更新循环重新发布变换到指定坐标系的当前位置。

#Only used if the type specified has some use for them (eg. POINTS, LINE_STRIP, ...)
geometry_msgs/Point[] points  #
#Only used if the type specified has some use for them (eg. POINTS, LINE_STRIP, ...)
#number of colors must either be 0 or equal to the number of points 
#NOTE: alpha is not yet used
std_msgs/ColorRGBA[] colors  #仅限使用点成员的marker,指定每个定点颜色。

# NOTE: 仅限于text markers
string text  #文本字符串

# NOTE: only used for MESH_RESOURCE markers
string mesh_resource  #MESH_RESOURCE markers的源位置。任何rviz支持的mesh类型都可以使用。格式是被resource_retriever使用的URI-form。
bool mesh_use_embedded_materials

来源:rviz–显示类型-Marker

3.2 创建话题发布者
rrtMarker_pub = rospy.Publisher("RRT_planning_markerpath",Marker)

输入参数:

  1. 发布话题名称
  2. 数据类型
  3. 队列长度 (queue_size=)。这里不设置会报警,不过影响不大所以没设置。
3.3 RRT算法修改

直接上代码

  marker_new_point = Point()
  marker_nearest_point = Point()
  marker_new_point.x = new_node.x
  marker_new_point.y = new_node.y
  marker_new_point.z = new_node.z
  rrtMarker.points.append(marker_new_point)
  marker_nearest_point.x = nearest_node.x
  marker_nearest_point.y = nearest_node.y
  marker_nearest_point.z = nearest_node.z
  rrtMarker.points.append(marker_nearest_point)

因为在对rrtMarker初始化时,标记类型设定为有序列表。所以在push节点时必须成对添加。

4. 主函数循环
while not rospy.is_shutdown():
    rrtMarker_pub.publish(rrtMarker)

–PS:第一次正儿八经用python写代码,还挺有意思,但是用着还是感觉不太舒服,和C++比少了些什么的感觉。
此外,附上C++的参考

ROS(indigo)RRT路径规划
github案例

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/861346.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号