读取机器人移动轨迹并在RVIZ界面中显示

这篇具有很好参考价值的文章主要介绍了读取机器人移动轨迹并在RVIZ界面中显示。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。


前言

机器人在巡检过程中需要沿着固定路线执行任务,因此可以先把机器人的移动轨迹录制并保存下来,之后读取轨迹,方便后续操作。


一、准备

1.坐标系

巡检导航过程中,机器人需要确定好坐标系,以便进行定位与导航,在gazebo仿真下可以选择world坐标系,在实际使用中通常使用的是map坐标系,这里以map坐标系为例进行介绍。

2.ros下的路径消息格式

rosmsg show nav_msgs/Path 
std_msgs/Header header
  uint32 seq
  time stamp
  string frame_id
geometry_msgs/PoseStamped[] poses
  std_msgs/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

二、实现过程

1.轨迹保存

思路:使用/amcl_pose话题获取机器人当前的位置信息,用nav_msgs::Path格式的一个变量Path进行保存,控制机器人的运动,当机器人运动距离超过某一数值时,将当前位置pose加入该变量,直到机器人走完预设的路径。之后遍历Path中路径点保存输出CSV文本即可。

#include <fstream>
#include <tf/tf.h>
#include <ros/ros.h>
#include <nav_msgs/Path.h>
#include <std_msgs/String.h>
#include <geometry_msgs/PoseStamped.h>
#include <geometry_msgs/PoseWithCovarianceStamped.h>
#include <nav_msgs/Odometry.h>
using namespace std;

ros::Subscriber robot_pose_sub_;
ros::Subscriber save_path_sub_ ;
nav_msgs::Path curr_trajectory_;
/*
* 计算两点间距离
*/
double calculateDistanceBetweenPose(const geometry_msgs::PoseStamped& pose1,const geometry_msgs::PoseStamped& pose2)
{
    double d_x = pose2.pose.position.x - pose1.pose.position.x;
    double d_y = pose2.pose.position.y - pose1.pose.position.y;
    return sqrt(d_x* d_x + d_y * d_y);
}
/*
* 保存路径
*/
void savePathToFile(string filename)
{
    ofstream File;
	//保存文本地址
    string filePathName;
    filePathName = "/home/name/path/"+ filename +".csv";

    File.open(filePathName.c_str(),ios::out|ios::trunc);
	//遍历存储路径容器,将路径四元数转为yaw角,写入文本
    for(int i=0;i<curr_trajectory_.poses.size();i++)
    {
        float x = curr_trajectory_.poses[i].pose.position.x;
        float y = curr_trajectory_.poses[i].pose.position.y;

        tf::Quaternion quat;
        tf::quaternionMsgToTF(curr_trajectory_.poses[i].pose.orientation,quat);
        double roll, pitch, yaw;
        tf::Matrix3x3(quat).getRPY(roll,pitch,yaw);
        float th = yaw;
        File<<x<<","<<y<<","<<th<<endl;
    }
    File.close();

}
/*
* 当前位置回调,将间距超过4cm的路径点加入容器
*/
void robotPoseCallback(const geometry_msgs::PoseWithCovarianceStampedConstPtr & curr_pose)
{
    geometry_msgs::PoseStamped current_pose;
    current_pose.header.frame_id = "map";
    current_pose.header.stamp = ros::Time::now();
    current_pose.pose.position = curr_pose->pose.pose.position;
    current_pose.pose.orientation = curr_pose->pose.pose.orientation;
    if(curr_trajectory_.poses.empty())
    {
        curr_trajectory_.poses.push_back(current_pose);
        return ;
    }
    int poses_num = curr_trajectory_.poses.size();
    double dis = calculateDistanceBetweenPose(curr_trajectory_.poses[poses_num - 1],current_pose);
    if(dis > 0.04)
        curr_trajectory_.poses.push_back(current_pose);
}
/*
*  接收路径保存指令,开始保存路径点
*/
void savePathCallback(const std_msgs::String::ConstPtr& msg)
{
    string str_msgs = msg->data.c_str();

    if(str_msgs.compare("end") == 0)
    {
        if(!curr_trajectory_.poses.empty())
        {
            string file_path = "aaa";
            savePathToFile(file_path.c_str());
            curr_trajectory_.poses.clear();
            cout<<"end1!"<<endl;
        }
        cout<<"end2!"<<endl;
    }
}
int main(int argc,char** argv)
{
    ros::init(argc,argv,"save_path_node");
    ros::NodeHandle nh_;

    robot_pose_sub_ = nh_.subscribe("/amcl_pose",1,robotPoseCallback);
    save_path_sub_ = nh_.subscribe("/start_end_record", 1,savePathCallback);
    curr_trajectory_.header.frame_id = "map";
    curr_trajectory_.header.stamp = ros::Time::now();
    ros::spin();
    return 0;
}


运行上述程序后,控制小车运动,当走完所需的路径后,需单独发送一个话题,从而启动路径保存

rostopic pub /start_end_record std_msgs/String "data: 'end'" 

2.轨迹读取并显示

思路:读取CSV文本并分割,将路径点发布出去。
这里也发布了路径起点和终点位置。

#include <ros/ros.h>
#include <geometry_msgs/PoseWithCovarianceStamped.h>
#include <nav_msgs/Odometry.h>
#include <std_msgs/String.h>
#include <tf/tf.h>
#include <nav_msgs/Path.h>
#include <geometry_msgs/PointStamped.h>
#include <geometry_msgs/Twist.h>
#include <ros/time.h>
#include <istream>
#include <sstream>
#include <fstream>
#include <string>
#include <vector>
#include <tf/tf.h>
using namespace std;

/**
 * 字符串分割
*/
std::vector<std::string> split(const std::string &str, const std::string &pattern) {
    char *strc = new char[strlen(str.c_str()) + 1];
    strcpy(strc, str.c_str()); // string转换成C-string
    std::vector<std::string> res;
    char *temp = strtok(strc, pattern.c_str());
    while (temp != NULL) {
        res.push_back(std::string(temp));
        temp = strtok(NULL, pattern.c_str());
    }
    delete[] strc;
    return res;
}

int main(int argc,char** argv)
{
    ros::init(argc,argv,"path_pub");
    ros::NodeHandle n;
    ros::Rate r(10);
    ros::Publisher path_pub = n.advertise<nav_msgs::Path>("/path_pub",10);
    ros::Publisher path_end_pub = n.advertise<geometry_msgs::PointStamped>("/path_end_point",10);
    ros::Publisher path_start_pub = n.advertise<geometry_msgs::PointStamped>("/path_start_point",10);

    nav_msgs::Path nav_path;
    nav_path.header.frame_id= "/map";
    nav_path.header.stamp = ros::Time::now();
    geometry_msgs::PoseStamped path_pose;


   //读取CSV文件
    std::ifstream csv_data("path/aaa.csv",std::ios::in);
    if(!csv_data)
    {
        std::cout<<"open .csv failed"<<std::endl;
        ROS_ERROR(" .csv  doesn't exisit ");
        std::exit(1);
    }
    geometry_msgs::Quaternion quat;
    std::string line;
    int line_num = 0;
    std::vector<std::string> strbuf;

    while(ros::ok())
    {
        while(std::getline(csv_data,line))
        {
            // std::cout<<line<<std::endl;
            path_pose.header.frame_id = "/map";
            path_pose.header.stamp =ros::Time::now();
            path_pose.header.seq = 0;
            line_num++;
            strbuf = split(line, ",");
            path_pose.pose.position.x = atof(strbuf[0].c_str());
            path_pose.pose.position.y = atof(strbuf[1].c_str());
            path_pose.pose.position.z = 0.0;
            float yaw = atof(strbuf[2].c_str());

            quat = tf::createQuaternionMsgFromYaw(yaw);

            path_pose.pose.orientation.x = quat.x;
            path_pose.pose.orientation.y = quat.y;
            path_pose.pose.orientation.z = quat.z;
            path_pose.pose.orientation.w = quat.w;
            nav_path.poses.push_back(path_pose);
        }
        path_pub.publish(nav_path);
        ros::Duration(1).sleep();
        path_end_pub.publish(nav_path.poses[nav_path.poses.size()-1]);
        // std::cout<<"----2-----"<<std::endl;
        path_start_pub.publish(nav_path.poses[0]);

        ros::spinOnce();
        r.sleep();
    }

    return 0;

}

在rviz中添加话题名称,结果如图:
rviz显示轨迹,机器人,linux,学习文章来源地址https://www.toymoban.com/news/detail-757138.html


到了这里,关于读取机器人移动轨迹并在RVIZ界面中显示的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Ubuntu18.04 Turtlebot2机器人移动控制 Rviz Gazebo仿真实现

    操作系统为ubuntu18.04 安装ROS Melodic Turtlebot2,很多大佬分享了详细的安装过程,在这里就不多赘述,安装遇到问题多百度,大部分都是可以解决的。 前期学习了赵虚左老师的ROS入门课程,结合Turtlebot2资料这里方便大家打开,放的创客制造的文档,也推荐大家去看官方文档 首先

    2023年04月25日
    浏览(56)
  • GPS学习(一):在ROS2中将GPS经纬度数据转换为机器人ENU坐标系,在RVIZ中显示坐标轨迹

    本文记录在Ubuntu22.04-Humbel中使用NMEA协议GPS模块的过程,使用国产ROS开发板鲁班猫(LubanCat )进行调试。 在淘宝找了款性价比较高的轮趣科技GPS北斗双模定位模块作为入门学习使用,支持GNSS系统(北斗、GPS、GLONASS、日本的QZSS以及卫星增强系统SBAS),定位精度在2.5m左右,属于民用

    2024年02月03日
    浏览(45)
  • kuka示教器嵌套UR界面操作ros中rviz的UR机器人

    本例展示了用QT增加一个网页视图,背景是kuka示教器界面,中间增加UR的VNC网页界面显示。本人博客中一起有写过ros2运行UR的操作。         ros2 UR10仿真包运行_基于ros的ur仿真-CSDN博客       效果如下:     背景的增加,参考这篇文件。  qt for python创建UI界面-CSDN博客   主要

    2024年02月21日
    浏览(35)
  • 【深蓝学院】移动机器人运动规划--第5章 最优轨迹生成--笔记

    Ch2讲了基于搜索的路径规划方法,Ch3讲了基于采样的路径规划方法,这些都是global methods,框架都是Exploration and Exploitation,且在算力足够大的情况下,一定能够找到全局最优解。 除了global methods,还有local methods,主要是Deterministic Optimization确定性优化。基于优化的方法,主要

    2024年02月19日
    浏览(34)
  • 【轨迹跟踪】基于自适应跟踪(EAT)方法的无人机/移动机器人轨迹跟踪(Matlab&Simulink)

    💥💥💞💞 欢迎来到本博客 ❤️❤️💥💥 🏆博主优势: 🌞🌞🌞 博客内容尽量做到思维缜密,逻辑清晰,为了方便读者。 ⛳️ 座右铭: 行百里者,半于九十。 📋📋📋 本文目录如下: 🎁🎁🎁 目录 💥1 概述 📚2 运行结果 🎉3 参考文献 🌈4 Matlab代码Simulink实现 摘

    2024年02月07日
    浏览(34)
  • rviz上不显示机器人模型(模型只有白色)

    文档中的是base_footprint,需要根据自己所设的坐标系更改,我的改为base_link 如何查看自己设的坐标系: 这些parent父坐标系就是 同时打开rviz后需要更改成base_link

    2024年04月17日
    浏览(25)
  • 【ROS 2 基础-常用工具】-7 Rviz仿真机器人

     所有内容请查看:博客学习目录_Howe_xixi的博客-CSDN博客

    2024年02月08日
    浏览(34)
  • RViz成功显示多个机器人模型以及解决显示的模型没有左右轮

    在RViz中显示多个机器人模型需要设置好几个关键的参数 首先点击Add,找到RobotModel,添加进来 Fixed Frame:选择TF树最上层的坐标系,一般是世界坐标系,即固定不动的全局坐标系 Robot Description:/robot1/robot_description,要在robot_description前加上对应的命名空间 TF Prefix:robot1,机器

    2024年01月18日
    浏览(47)
  • 机器人轨迹生成:轨迹规划与路径规划

    机器人轨迹生成涉及到轨迹规划和路径规划两个关键概念,它们是机器人运动控制中的重要组成部分。下面对轨迹规划和路径规划进行深入比较。 轨迹规划(Trajectory Planning): 定义:轨迹规划是指在机器人运动中确定机器人末端或关节的期望轨迹。它是在特定的工作空间中

    2024年02月12日
    浏览(35)
  • Matlab机器人的仿真(八):绘制机器人运动轨迹(复现)

    跑一得出运动轨迹的动图结果: 跑二得出的绘出6个关节的角度,角速度,角加速度的信息图: 跑三得出的结果:末端点轨迹(x-y-z视图)

    2024年02月11日
    浏览(34)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包